77 lines
2.8 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.representApiClient = void 0;
const env_1 = require("../../../config/env");
const logger_1 = require("../../../utils/logger");
// --- In-memory sliding window rate limiter (55/min, under 60/min API limit) ---
const RATE_LIMIT = 55;
const RATE_WINDOW_MS = 60_000;
const requestTimestamps = [];
function checkRateLimit() {
const now = Date.now();
// Remove timestamps outside the window
while (requestTimestamps.length > 0 && requestTimestamps[0] < now - RATE_WINDOW_MS) {
requestTimestamps.shift();
}
return requestTimestamps.length < RATE_LIMIT;
}
function recordRequest() {
requestTimestamps.push(Date.now());
}
// --- API Client ---
class RepresentApiClient {
baseUrl;
constructor() {
this.baseUrl = env_1.env.REPRESENT_API_URL;
}
async getByPostalCode(code) {
if (!checkRateLimit()) {
throw new Error('Represent API rate limit reached. Please try again in a minute.');
}
const url = `${this.baseUrl}/postcodes/${code}/`;
logger_1.logger.debug(`Represent API request: ${url}`);
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10_000);
try {
recordRequest();
const response = await fetch(url, {
signal: controller.signal,
headers: { Accept: 'application/json' },
});
if (!response.ok) {
const text = await response.text().catch(() => '');
throw new Error(`Represent API error ${response.status}: ${text}`);
}
return (await response.json());
}
finally {
clearTimeout(timeout);
}
}
async testConnection() {
try {
const url = `${this.baseUrl}/boundary-sets/?limit=1`;
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10_000);
try {
const response = await fetch(url, {
signal: controller.signal,
headers: { Accept: 'application/json' },
});
if (!response.ok) {
return { ok: false, message: `HTTP ${response.status}` };
}
return { ok: true, message: 'Represent API is reachable' };
}
finally {
clearTimeout(timeout);
}
}
catch (err) {
const message = err instanceof Error ? err.message : 'Unknown error';
return { ok: false, message };
}
}
}
exports.representApiClient = new RepresentApiClient();
//# sourceMappingURL=represent-api.client.js.map