/** * API Key Management Utility * * Provides centralized functions for managing API keys in headers and requests. * This utility can be used across different components that need to handle API keys. */ import type { ApiKey } from '../types'; export type { ApiKey }; export interface HeadersWithApiKey { [key: string]: string; } /** * Add API key to request headers * @param headers - Existing headers object * @param apiKey - API key object or string * @returns Headers with API key added */ export function addApiKeyToHeaders(headers: HeadersWithApiKey, apiKey: ApiKey | string | null): HeadersWithApiKey { if (!apiKey) { return headers; } // ``secret`` is the raw key that goes in the X-API-Key header. // Falls back to ``id`` for backwards compatibility — older callers // only had ``id`` and used it as both selector and secret. const keyValue = typeof apiKey === 'string' ? apiKey : (apiKey.secret || apiKey.id || ''); return { ...headers, 'X-API-Key': keyValue, }; } /** * Remove API key from headers object * @param headers - Headers object * @returns Headers without API key */ export function removeApiKeyFromHeaders(headers: HeadersWithApiKey): HeadersWithApiKey { const { 'X-API-Key': removed, ...remainingHeaders } = headers; return remainingHeaders; } /** * Remove API key from headers JSON string * @param headersJson - JSON string of headers * @returns JSON string without API key */ export function removeApiKeyFromHeadersJson(headersJson: string): string { try { const headers = JSON.parse(headersJson); const updatedHeaders = removeApiKeyFromHeaders(headers); return JSON.stringify(updatedHeaders, null, 2); } catch (error) { console.error('Error parsing headers JSON:', error); return headersJson; } } /** * Update headers JSON string with API key * @param headersJson - JSON string of headers * @param apiKey - API key object or string * @returns Updated JSON string */ export function updateHeadersJsonWithApiKey(headersJson: string, apiKey: ApiKey | string | null): string { try { const headers = JSON.parse(headersJson); const updatedHeaders = addApiKeyToHeaders(headers, apiKey); return JSON.stringify(updatedHeaders, null, 2); } catch (error) { console.error('Error parsing headers JSON:', error); return headersJson; } } /** * Find API key by ID in a list of API keys * @param apiKeys - Array of API keys * @param keyId - ID of the API key to find * @returns API key object or null */ export function findApiKeyById(apiKeys: ApiKey[], keyId: string): ApiKey | null { return apiKeys.find((key) => key.id === keyId) || null; } /** * Validate API key format * @param apiKey - API key string to validate * @returns Whether the API key format is valid */ export function validateApiKeyFormat(apiKey: string): boolean { // Basic validation - adjust based on your API key format requirements return typeof apiKey === 'string' && apiKey.length > 0 && apiKey.trim() !== ''; } /** * Create default headers with API key * @param apiKey - API key object or string * @returns Default headers with API key */ export function createDefaultHeaders(apiKey?: ApiKey | string): HeadersWithApiKey { const defaultHeaders: HeadersWithApiKey = { 'Content-Type': 'application/json', }; if (apiKey) { return addApiKeyToHeaders(defaultHeaders, apiKey); } return defaultHeaders; } /** * Merge headers with API key * @param baseHeaders - Base headers object * @param additionalHeaders - Additional headers to merge * @param apiKey - API key to add * @returns Merged headers with API key */ export function mergeHeadersWithApiKey(baseHeaders: HeadersWithApiKey, additionalHeaders: HeadersWithApiKey, apiKey?: ApiKey | string): HeadersWithApiKey { const mergedHeaders = { ...baseHeaders, ...additionalHeaders }; if (apiKey) { return addApiKeyToHeaders(mergedHeaders, apiKey); } return mergedHeaders; } /** * Log API key usage (for debugging/analytics) * @param apiKey - API key that was used * @param endpoint - Endpoint that was called * @param success - Whether the request was successful */ export function logApiKeyUsage(apiKey: ApiKey | string, endpoint: string, success: boolean): void { const keyValue = typeof apiKey === 'string' ? apiKey : (apiKey.secret || apiKey.id || ''); const keyName = typeof apiKey === 'string' ? 'Unknown' : apiKey.name; console.log(`API Key Usage:`, { keyName, keyValue: keyValue.substring(0, 8) + '...', endpoint, success, timestamp: new Date().toISOString(), }); }