{"version":3,"file":"api-gateway.mjs","sources":["../../../../src/lib/api/advanced/api-gateway.ts"],"sourcesContent":["/**\n * API Gateway\n *\n * Enterprise-grade API gateway pattern implementation.\n * Provides a unified interface for API communication with\n * middleware support, request/response interception, and routing.\n *\n * @module api/advanced/api-gateway\n */\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * HTTP methods supported by the gateway.\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';\n\n/**\n * Request configuration for the gateway.\n */\nexport interface GatewayRequest<TBody = unknown> {\n  /** API endpoint path */\n  path: string;\n  /** HTTP method */\n  method: HttpMethod;\n  /** Request body */\n  body?: TBody;\n  /** Query parameters */\n  params?: Record<string, string | number | boolean | undefined>;\n  /** Request headers */\n  headers?: Record<string, string>;\n  /** Request timeout in milliseconds */\n  timeout?: number;\n  /** Whether to skip authentication */\n  skipAuth?: boolean;\n  /** API version to use */\n  apiVersion?: string;\n  /** Retry configuration */\n  retry?: RetryConfig;\n  /** Cache configuration */\n  cache?: CacheConfig;\n  /** Request metadata for middleware */\n  metadata?: Record<string, unknown>;\n  /** Abort signal for request cancellation */\n  signal?: AbortSignal;\n}\n\n/**\n * Response from the gateway.\n */\nexport interface GatewayResponse<TData = unknown> {\n  /** Response data */\n  data: TData;\n  /** HTTP status code */\n  status: number;\n  /** Status text */\n  statusText: string;\n  /** Response headers */\n  headers: Record<string, string>;\n  /** Request duration in milliseconds */\n  duration: number;\n  /** Whether response was from cache */\n  fromCache?: boolean;\n  /** Request metadata */\n  metadata?: Record<string, unknown>;\n}\n\n/**\n * Gateway error structure.\n */\nexport interface GatewayError extends Error {\n  /** Error code */\n  code: string;\n  /** HTTP status code */\n  status?: number;\n  /** Original response */\n  response?: GatewayResponse;\n  /** Whether error is retryable */\n  retryable: boolean;\n  /** Request that caused the error */\n  request?: GatewayRequest;\n}\n\n/**\n * Retry configuration.\n */\nexport interface RetryConfig {\n  /** Maximum number of retries */\n  maxRetries: number;\n  /** Initial delay in milliseconds */\n  initialDelay?: number;\n  /** Maximum delay in milliseconds */\n  maxDelay?: number;\n  /** Backoff multiplier */\n  backoffMultiplier?: number;\n  /** Status codes to retry on */\n  retryStatusCodes?: number[];\n  /** Custom retry condition */\n  shouldRetry?: (error: GatewayError, attempt: number) => boolean;\n}\n\n/**\n * Cache configuration.\n */\nexport interface CacheConfig {\n  /** Cache key (auto-generated if not provided) */\n  key?: string;\n  /** Time-to-live in milliseconds */\n  ttl?: number;\n  /** Whether to use stale-while-revalidate */\n  staleWhileRevalidate?: boolean;\n  /** Cache storage type */\n  storage?: 'memory' | 'session' | 'local';\n}\n\n/**\n * Middleware function type.\n */\nexport type GatewayMiddleware = (\n  request: GatewayRequest,\n  next: () => Promise<GatewayResponse>\n) => Promise<GatewayResponse>;\n\n/**\n * Request interceptor.\n */\nexport type RequestInterceptor = (\n  request: GatewayRequest\n) => GatewayRequest | Promise<GatewayRequest>;\n\n/**\n * Response interceptor.\n */\nexport type ResponseInterceptor<T = unknown> = (\n  response: GatewayResponse<T>,\n  request: GatewayRequest\n) => GatewayResponse<T> | Promise<GatewayResponse<T>>;\n\n/**\n * Error interceptor.\n */\nexport type ErrorInterceptor = (\n  error: GatewayError,\n  request: GatewayRequest\n) => GatewayError | Promise<never>;\n\n/**\n * Gateway configuration.\n */\nexport interface GatewayConfig {\n  /** Base URL for all requests */\n  baseUrl: string;\n  /** Default timeout in milliseconds */\n  timeout?: number;\n  /** Default headers for all requests */\n  defaultHeaders?: Record<string, string>;\n  /** Default API version */\n  defaultApiVersion?: string;\n  /** Authentication token getter */\n  getAuthToken?: () => string | null | Promise<string | null>;\n  /** Default retry configuration */\n  defaultRetry?: RetryConfig;\n  /** Request interceptors */\n  requestInterceptors?: RequestInterceptor[];\n  /** Response interceptors */\n  responseInterceptors?: ResponseInterceptor[];\n  /** Error interceptors */\n  errorInterceptors?: ErrorInterceptor[];\n  /** Middleware stack */\n  middleware?: GatewayMiddleware[];\n  /** Enable debug logging */\n  debug?: boolean;\n}\n\n// =============================================================================\n// Default Configuration\n// =============================================================================\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n  maxRetries: 3,\n  initialDelay: 1000,\n  maxDelay: 10000,\n  backoffMultiplier: 2,\n  retryStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nconst DEFAULT_TIMEOUT = 30000;\n\n// =============================================================================\n// API Gateway Class\n// =============================================================================\n\n/**\n * API Gateway for centralized API communication.\n *\n * Provides a unified interface for making API requests with support for\n * middleware, interceptors, retries, caching, and versioning.\n *\n * @example\n * ```typescript\n * const gateway = new APIGateway({\n *   baseUrl: 'https://api.example.com',\n *   defaultApiVersion: 'v1',\n *   getAuthToken: () => localStorage.getItem('token'),\n * });\n *\n * // Add middleware\n * gateway.use(loggingMiddleware);\n * gateway.use(metricsMiddleware);\n *\n * // Make requests\n * const users = await gateway.get('/users');\n * const user = await gateway.post('/users', { name: 'John' });\n * ```\n */\nexport class APIGateway {\n  private config: GatewayConfig;\n  private middleware: GatewayMiddleware[] = [];\n  private requestInterceptors: RequestInterceptor[] = [];\n  private responseInterceptors: ResponseInterceptor[] = [];\n  private errorInterceptors: ErrorInterceptor[] = [];\n  private cache: Map<string, { data: GatewayResponse; expiresAt: number }>;\n\n  /**\n   * Create a new API Gateway instance.\n   *\n   * @param config - Gateway configuration\n   */\n  constructor(config: GatewayConfig) {\n    this.config = config;\n    this.cache = new Map();\n\n    // Initialize interceptors from config\n    if (config.requestInterceptors) {\n      this.requestInterceptors.push(...config.requestInterceptors);\n    }\n    if (config.responseInterceptors) {\n      this.responseInterceptors.push(...config.responseInterceptors);\n    }\n    if (config.errorInterceptors) {\n      this.errorInterceptors.push(...config.errorInterceptors);\n    }\n    if (config.middleware) {\n      this.middleware.push(...config.middleware);\n    }\n  }\n\n  // ===========================================================================\n  // HTTP Methods\n  // ===========================================================================\n\n  /**\n   * Make a GET request.\n   */\n  async get<T = unknown>(\n    path: string,\n    options?: Partial<Omit<GatewayRequest, 'path' | 'method' | 'body'>>\n  ): Promise<GatewayResponse<T>> {\n    return this.request<T>({ ...options, path, method: 'GET' });\n  }\n\n  /**\n   * Make a POST request.\n   */\n  async post<T = unknown, B = unknown>(\n    path: string,\n    body?: B,\n    options?: Partial<Omit<GatewayRequest<B>, 'path' | 'method' | 'body'>>\n  ): Promise<GatewayResponse<T>> {\n    return this.request<T>({ ...options, path, method: 'POST', body });\n  }\n\n  /**\n   * Make a PUT request.\n   */\n  async put<T = unknown, B = unknown>(\n    path: string,\n    body?: B,\n    options?: Partial<Omit<GatewayRequest<B>, 'path' | 'method' | 'body'>>\n  ): Promise<GatewayResponse<T>> {\n    return this.request<T>({ ...options, path, method: 'PUT', body });\n  }\n\n  /**\n   * Make a PATCH request.\n   */\n  async patch<T = unknown, B = unknown>(\n    path: string,\n    body?: B,\n    options?: Partial<Omit<GatewayRequest<B>, 'path' | 'method' | 'body'>>\n  ): Promise<GatewayResponse<T>> {\n    return this.request<T>({ ...options, path, method: 'PATCH', body });\n  }\n\n  /**\n   * Make a DELETE request.\n   */\n  async delete<T = unknown>(\n    path: string,\n    options?: Partial<Omit<GatewayRequest, 'path' | 'method'>>\n  ): Promise<GatewayResponse<T>> {\n    return this.request<T>({ ...options, path, method: 'DELETE' });\n  }\n\n  // ===========================================================================\n  // Core Request Method\n  // ===========================================================================\n\n  /**\n   * Make an API request.\n   */\n  async request<T = unknown>(request: GatewayRequest): Promise<GatewayResponse<T>> {\n    const startTime = Date.now();\n\n    // Apply request interceptors\n    let processedRequest = request;\n    for (const interceptor of this.requestInterceptors) {\n      processedRequest = await interceptor(processedRequest);\n    }\n\n    // Check cache for GET requests\n    if (processedRequest.method === 'GET' && processedRequest.cache) {\n      const cached = this.getCachedResponse<T>(processedRequest);\n      if (cached) {\n        return cached;\n      }\n    }\n\n    try {\n      // Build middleware chain\n      const executeRequest = async (): Promise<GatewayResponse<T>> =>\n        this.executeRequest<T>(processedRequest, startTime);\n      const chain = this.buildMiddlewareChain(processedRequest, executeRequest);\n\n      // Execute request through middleware\n      let response = await chain();\n\n      // Apply response interceptors\n      for (const interceptor of this.responseInterceptors) {\n        response = await interceptor(response, processedRequest);\n      }\n\n      // Cache response if configured\n      if (processedRequest.method === 'GET' && processedRequest.cache) {\n        this.cacheResponse(processedRequest, response);\n      }\n\n      return response as GatewayResponse<T>;\n    } catch (error) {\n      const gatewayError = this.normalizeError(error, processedRequest);\n\n      // Apply error interceptors\n      for (const interceptor of this.errorInterceptors) {\n        await interceptor(gatewayError, processedRequest);\n      }\n\n      throw gatewayError;\n    }\n  }\n\n  /**\n   * Add middleware to the gateway.\n   */\n  use(middleware: GatewayMiddleware): this {\n    this.middleware.push(middleware);\n    return this;\n  }\n\n  /**\n   * Add a request interceptor.\n   */\n  addRequestInterceptor(interceptor: RequestInterceptor): () => void {\n    this.requestInterceptors.push(interceptor);\n    return () => {\n      const index = this.requestInterceptors.indexOf(interceptor);\n      if (index > -1) this.requestInterceptors.splice(index, 1);\n    };\n  }\n\n  // ===========================================================================\n  // Middleware & Interceptors\n  // ===========================================================================\n\n  /**\n   * Add a response interceptor.\n   */\n  addResponseInterceptor(interceptor: ResponseInterceptor): () => void {\n    this.responseInterceptors.push(interceptor);\n    return () => {\n      const index = this.responseInterceptors.indexOf(interceptor);\n      if (index > -1) this.responseInterceptors.splice(index, 1);\n    };\n  }\n\n  /**\n   * Add an error interceptor.\n   */\n  addErrorInterceptor(interceptor: ErrorInterceptor): () => void {\n    this.errorInterceptors.push(interceptor);\n    return () => {\n      const index = this.errorInterceptors.indexOf(interceptor);\n      if (index > -1) this.errorInterceptors.splice(index, 1);\n    };\n  }\n\n  /**\n   * Clear the cache.\n   */\n  clearCache(pattern?: string): void {\n    if (pattern == null || pattern === '') {\n      this.cache.clear();\n      return;\n    }\n\n    const regex = new RegExp(pattern);\n    for (const key of this.cache.keys()) {\n      if (regex.test(key)) {\n        this.cache.delete(key);\n      }\n    }\n  }\n\n  /**\n   * Log debug message.\n   * @internal Used for debug logging when config.debug is enabled\n   */\n  protected log(message: string, ...args: unknown[]): void {\n    if (this.config.debug === true) {\n      // eslint-disable-next-line no-console\n      console.log(`[APIGateway] ${message}`, ...args);\n    }\n  }\n\n  /**\n   * Execute the actual HTTP request.\n   */\n  private async executeRequest<T>(\n    request: GatewayRequest,\n    startTime: number\n  ): Promise<GatewayResponse<T>> {\n    const url = this.buildUrl(request);\n    const headers = await this.buildHeaders(request);\n    const timeout = request.timeout ?? this.config.timeout ?? DEFAULT_TIMEOUT;\n\n    // Create abort controller for timeout\n    const controller = new AbortController();\n    const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n    // Merge abort signals\n    const signal = request.signal\n      ? this.mergeAbortSignals(request.signal, controller.signal)\n      : controller.signal;\n\n    try {\n      const fetchOptions: RequestInit = {\n        method: request.method,\n        headers,\n        signal,\n        body: request.body != null ? JSON.stringify(request.body) : undefined,\n      };\n\n      const response = await this.fetchWithRetry<T>(url, fetchOptions, request);\n      const duration = Date.now() - startTime;\n\n      return {\n        ...response,\n        duration,\n        metadata: request.metadata,\n      };\n    } finally {\n      clearTimeout(timeoutId);\n    }\n  }\n\n  // ===========================================================================\n  // URL & Header Building\n  // ===========================================================================\n\n  /**\n   * Fetch with retry logic.\n   *\n   * Note: This method intentionally uses raw fetch() because:\n   * 1. The API Gateway IS the low-level HTTP layer that apiClient builds upon\n   * 2. This provides the foundation for retry, routing, and error handling\n   * 3. Using apiClient here would create circular dependencies\n   *\n   * Applications should use apiClient or this gateway, not raw fetch.\n   * @see {@link @/lib/api/api-client} for the high-level API client\n   */\n  private async fetchWithRetry<T>(\n    url: string,\n    options: RequestInit,\n    request: GatewayRequest\n  ): Promise<GatewayResponse<T>> {\n    const retryConfig = request.retry ?? this.config.defaultRetry ?? DEFAULT_RETRY_CONFIG;\n    let lastError: GatewayError | null = null;\n\n    for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n      try {\n        // Raw fetch is intentional - this IS the gateway implementation layer\n        const response = await fetch(url, options);\n        const responseHeaders = this.parseHeaders(response.headers);\n\n        if (!response.ok) {\n          const error = await this.createErrorFromResponse(response, request);\n\n          // Check if should retry\n          if (attempt < retryConfig.maxRetries && this.shouldRetry(error, attempt, retryConfig)) {\n            lastError = error;\n            await this.delay(this.calculateDelay(attempt, retryConfig));\n            continue;\n          }\n\n          throw error;\n        }\n\n        const data = await this.parseResponse<T>(response);\n\n        return {\n          data,\n          status: response.status,\n          statusText: response.statusText,\n          headers: responseHeaders,\n          duration: 0, // Will be set by caller\n        };\n      } catch (error) {\n        if (error instanceof Error && error.name === 'AbortError') {\n          throw this.createError('REQUEST_TIMEOUT', 'Request timed out', request, false);\n        }\n\n        const gatewayError = this.normalizeError(error, request);\n\n        if (\n          attempt < retryConfig.maxRetries &&\n          this.shouldRetry(gatewayError, attempt, retryConfig)\n        ) {\n          lastError = gatewayError;\n          await this.delay(this.calculateDelay(attempt, retryConfig));\n          continue;\n        }\n\n        throw gatewayError;\n      }\n    }\n\n    throw lastError ?? this.createError('MAX_RETRIES', 'Max retries exceeded', request, false);\n  }\n\n  /**\n   * Build middleware chain.\n   */\n  private buildMiddlewareChain(\n    request: GatewayRequest,\n    execute: () => Promise<GatewayResponse>\n  ): () => Promise<GatewayResponse> {\n    const middleware = [...this.middleware];\n\n    return middleware.reduceRight<() => Promise<GatewayResponse>>(\n      (next, mw) => async () => mw(request, next),\n      execute\n    );\n  }\n\n  // ===========================================================================\n  // Cache Management\n  // ===========================================================================\n\n  /**\n   * Build the full request URL.\n   */\n  private buildUrl(request: GatewayRequest): string {\n    const version = request.apiVersion ?? this.config.defaultApiVersion ?? '';\n    const versionPrefix = version ? `/${version}` : '';\n    const path = request.path.startsWith('/') ? request.path : `/${request.path}`;\n    let url = `${this.config.baseUrl}${versionPrefix}${path}`;\n\n    // Add query parameters\n    if (request.params) {\n      const searchParams = new URLSearchParams();\n      Object.entries(request.params).forEach(([key, value]) => {\n        if (value !== undefined) {\n          searchParams.append(key, String(value));\n        }\n      });\n      const queryString = searchParams.toString();\n      if (queryString) {\n        url += `?${queryString}`;\n      }\n    }\n\n    return url;\n  }\n\n  /**\n   * Build request headers.\n   */\n  private async buildHeaders(request: GatewayRequest): Promise<Record<string, string>> {\n    const headers: Record<string, string> = {\n      'Content-Type': 'application/json',\n      ...this.config.defaultHeaders,\n      ...request.headers,\n    };\n\n    // Add authentication header\n    if (request.skipAuth !== true && this.config.getAuthToken != null) {\n      const token = await this.config.getAuthToken();\n      if (token != null && token !== '') {\n        headers['Authorization'] = `Bearer ${token}`;\n      }\n    }\n\n    return headers;\n  }\n\n  /**\n   * Get cached response.\n   */\n  private getCachedResponse<T>(request: GatewayRequest): GatewayResponse<T> | null {\n    const cacheKey = this.getCacheKey(request);\n    const cached = this.cache.get(cacheKey);\n\n    if (!cached) return null;\n\n    // Check if expired\n    if (Date.now() > cached.expiresAt) {\n      // Stale-while-revalidate\n      if (request.cache?.staleWhileRevalidate === true) {\n        // Return stale data and trigger revalidation in background\n        void this.revalidateCache(request);\n        return { ...cached.data, fromCache: true } as GatewayResponse<T>;\n      }\n      this.cache.delete(cacheKey);\n      return null;\n    }\n\n    return { ...cached.data, fromCache: true } as GatewayResponse<T>;\n  }\n\n  /**\n   * Cache a response.\n   */\n  private cacheResponse(request: GatewayRequest, response: GatewayResponse): void {\n    const cacheKey = this.getCacheKey(request);\n    const ttl = request.cache?.ttl ?? 300000; // 5 minutes default\n\n    this.cache.set(cacheKey, {\n      data: response,\n      expiresAt: Date.now() + ttl,\n    });\n  }\n\n  /**\n   * Revalidate cached data in background.\n   */\n  private async revalidateCache(request: GatewayRequest): Promise<void> {\n    try {\n      const response = await this.executeRequest(request, Date.now());\n      this.cacheResponse(request, response);\n    } catch {\n      // Silent fail for background revalidation\n    }\n  }\n\n  // ===========================================================================\n  // Helper Methods\n  // ===========================================================================\n\n  /**\n   * Get cache key for a request.\n   */\n  private getCacheKey(request: GatewayRequest): string {\n    if (request.cache?.key != null && request.cache.key !== '') return request.cache.key;\n\n    const params =\n      request.params != null ? JSON.stringify(Object.entries(request.params).sort()) : '';\n    return `${request.method}:${request.path}:${params}`;\n  }\n\n  /**\n   * Parse response based on content type.\n   */\n  private async parseResponse<T>(response: Response): Promise<T> {\n    const contentType = response.headers.get('content-type') ?? '';\n\n    if (contentType.includes('application/json')) {\n      return (await response.json()) as Promise<T>;\n    }\n\n    if (contentType.includes('text/')) {\n      return (await response.text()) as unknown as T;\n    }\n\n    return (await response.blob()) as unknown as T;\n  }\n\n  /**\n   * Parse response headers to plain object.\n   */\n  private parseHeaders(headers: Headers): Record<string, string> {\n    const result: Record<string, string> = {};\n    headers.forEach((value, key) => {\n      result[key] = value;\n    });\n    return result;\n  }\n\n  /**\n   * Normalize errors to GatewayError.\n   */\n  private normalizeError(error: unknown, request: GatewayRequest): GatewayError {\n    if (this.isGatewayError(error)) {\n      return error;\n    }\n\n    const message = error instanceof Error ? error.message : 'Unknown error';\n    return this.createError('UNKNOWN_ERROR', message, request, true);\n  }\n\n  /**\n   * Create error from response.\n   */\n  private async createErrorFromResponse(\n    response: Response,\n    request: GatewayRequest\n  ): Promise<GatewayError> {\n    let message = response.statusText;\n    let code = `HTTP_${response.status}`;\n\n    try {\n      const body = (await response.json()) as { message?: string; error?: string; code?: string };\n      message = body.message ?? body.error ?? message;\n      code = body.code ?? code;\n    } catch {\n      // Use default message\n    }\n\n    const retryable = (\n      request.retry?.retryStatusCodes ??\n      DEFAULT_RETRY_CONFIG.retryStatusCodes ??\n      []\n    ).includes(response.status);\n\n    return this.createError(code, message, request, retryable, response.status);\n  }\n\n  /**\n   * Create a GatewayError.\n   */\n  private createError(\n    code: string,\n    message: string,\n    request: GatewayRequest,\n    retryable: boolean,\n    status?: number\n  ): GatewayError {\n    const error = new Error(message) as GatewayError;\n    error.code = code;\n    error.status = status;\n    error.retryable = retryable;\n    error.request = request;\n    return error;\n  }\n\n  /**\n   * Check if error is a GatewayError.\n   */\n  private isGatewayError(error: unknown): error is GatewayError {\n    return error instanceof Error && 'code' in error && 'retryable' in error;\n  }\n\n  /**\n   * Check if request should be retried.\n   */\n  private shouldRetry(error: GatewayError, attempt: number, config: RetryConfig): boolean {\n    if (config.shouldRetry != null) {\n      return config.shouldRetry(error, attempt);\n    }\n\n    if (!error.retryable) return false;\n\n    if (error.status != null && config.retryStatusCodes != null) {\n      return config.retryStatusCodes.includes(error.status);\n    }\n\n    return true;\n  }\n\n  /**\n   * Calculate retry delay with exponential backoff.\n   */\n  private calculateDelay(attempt: number, config: RetryConfig): number {\n    const initialDelay = config.initialDelay ?? 1000;\n    const maxDelay = config.maxDelay ?? 10000;\n    const multiplier = config.backoffMultiplier ?? 2;\n\n    const delay = initialDelay * Math.pow(multiplier, attempt);\n    return Math.min(delay, maxDelay);\n  }\n\n  /**\n   * Delay helper.\n   */\n  private async delay(ms: number): Promise<void> {\n    return new Promise((resolve) => setTimeout(resolve, ms));\n  }\n\n  /**\n   * Merge multiple abort signals.\n   */\n  private mergeAbortSignals(...signals: AbortSignal[]): AbortSignal {\n    const controller = new AbortController();\n\n    for (const signal of signals) {\n      if (signal.aborted) {\n        controller.abort();\n        break;\n      }\n      signal.addEventListener('abort', () => controller.abort());\n    }\n\n    return controller.signal;\n  }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a new API Gateway instance.\n *\n * @param config - Gateway configuration\n * @returns Configured APIGateway\n */\nexport function createAPIGateway(config: GatewayConfig): APIGateway {\n  return new APIGateway(config);\n}\n\n// =============================================================================\n// Built-in Middleware\n// =============================================================================\n\n/**\n * Logging middleware for debugging.\n */\nexport const loggingMiddleware: GatewayMiddleware = async (request, next) => {\n  const startTime = Date.now();\n  // eslint-disable-next-line no-console\n  console.log(`[Request] ${request.method} ${request.path}`);\n\n  try {\n    const response = await next();\n    // eslint-disable-next-line no-console\n    console.log(\n      `[Response] ${request.method} ${request.path} - ${response.status} (${Date.now() - startTime}ms)`\n    );\n    return response;\n  } catch (error) {\n    console.error(`[Error] ${request.method} ${request.path}`, error);\n    throw error;\n  }\n};\n\n/**\n * Correlation ID middleware.\n */\nexport const correlationIdMiddleware: GatewayMiddleware = async (request, next) => {\n  const correlationId = crypto.randomUUID();\n\n  request.headers = {\n    ...request.headers,\n    'X-Correlation-ID': correlationId,\n  };\n\n  request.metadata = {\n    ...request.metadata,\n    correlationId,\n  };\n\n  return next();\n};\n"],"names":["DEFAULT_RETRY_CONFIG","DEFAULT_TIMEOUT","APIGateway","config","path","options","body","request","startTime","processedRequest","interceptor","cached","executeRequest","response","error","gatewayError","middleware","index","pattern","regex","key","message","args","url","headers","timeout","controller","timeoutId","signal","fetchOptions","duration","retryConfig","lastError","attempt","responseHeaders","execute","next","mw","version","versionPrefix","searchParams","value","queryString","token","cacheKey","ttl","params","contentType","result","code","retryable","status","initialDelay","maxDelay","multiplier","delay","ms","resolve","signals","createAPIGateway","loggingMiddleware","correlationIdMiddleware","correlationId"],"mappings":"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"}