"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