{"version":3,"file":"api-versioning.mjs","sources":["../../../src/lib/services/api-versioning.ts"],"sourcesContent":["/**\n * @file API Versioning\n * @description Comprehensive API versioning with multiple strategies,\n * version negotiation, deprecation warnings, transformers, and migration support.\n * Designed for seamless API evolution in microservices.\n *\n * **MIGRATION NOTICE**: This module is transitioning from `httpClient` to `apiClient`\n * from `@/lib/api`. The `httpClient` import is maintained for backward compatibility\n * but new code should use `apiClient` directly.\n *\n * @see {@link @/lib/api} for the recommended API client\n */\n\n/**\n * @deprecated Use `apiClient` from `@/lib/api` instead.\n * This import is maintained for backward compatibility with existing versioning code.\n */\nimport { type HttpRequestConfig } from './http';\nimport { apiClient } from '@/lib/api';\n\n// =============================================================================\n// TYPE DEFINITIONS\n// =============================================================================\n\n/**\n * API version format\n */\nexport type ApiVersion = `v${number}` | `v${number}.${number}` | `v${number}.${number}.${number}`;\n\n/**\n * Versioning strategies\n */\nexport enum VersioningStrategy {\n  /** URL path versioning: /v1/users */\n  URL_PATH = 'url-path',\n  /** Accept header versioning: Accept: application/vnd.api+json; version=1 */\n  ACCEPT_HEADER = 'accept-header',\n  /** Query parameter: /users?version=1 */\n  QUERY_PARAM = 'query-param',\n  /** Custom header: X-API-Version: 1 */\n  CUSTOM_HEADER = 'custom-header',\n  /** Media type versioning: application/vnd.api.v1+json */\n  MEDIA_TYPE = 'media-type',\n}\n\n/**\n * Version deprecation info\n */\nexport interface VersionDeprecation {\n  /** Sunset date (ISO 8601) */\n  sunsetDate: string;\n  /** Migration guide URL */\n  migrationGuide?: string;\n  /** Replacement version */\n  replacementVersion?: ApiVersion;\n  /** Additional warning message */\n  message?: string;\n}\n\n/**\n * Version transformer for request/response adaptation\n */\nexport interface VersionTransformer {\n  /** Transform request to target version format */\n  transformRequest?: (config: HttpRequestConfig) => HttpRequestConfig;\n  /** Transform response from target version format */\n  transformResponse?: <T>(data: T, originalVersion: ApiVersion) => T;\n  /** Map endpoint paths for version differences */\n  mapEndpoint?: (path: string) => string;\n  /** Transform request body */\n  transformBody?: (body: unknown) => unknown;\n  /** Transform response data shape */\n  transformData?: <T>(data: T) => T;\n}\n\n/**\n * Version configuration\n */\nexport interface VersionConfig {\n  /** Current/default version */\n  current: ApiVersion;\n  /** Minimum supported version */\n  minimum: ApiVersion;\n  /** Deprecated versions with sunset info */\n  deprecated: Map<ApiVersion, VersionDeprecation>;\n  /** Version-specific transformers */\n  transformers: Map<ApiVersion, VersionTransformer>;\n  /** Supported versions */\n  supported: ApiVersion[];\n}\n\n/**\n * Version negotiation result\n */\nexport interface VersionNegotiationResult {\n  /** Requested version */\n  requestedVersion: ApiVersion;\n  /** Actually negotiated version */\n  negotiatedVersion: ApiVersion;\n  /** Whether version is deprecated */\n  isDeprecated: boolean;\n  /** Deprecation info if applicable */\n  deprecation?: VersionDeprecation | undefined;\n  /** Whether version is supported */\n  isSupported: boolean;\n}\n\n/**\n * Versioned API client configuration\n */\nexport interface VersionedApiClientConfig {\n  /** Base URL for API */\n  baseUrl: string;\n  /** Versioning strategy */\n  strategy: VersioningStrategy;\n  /** Version configuration */\n  versionConfig: VersionConfig;\n  /** Custom header name for CUSTOM_HEADER strategy */\n  headerName?: string;\n  /** Media type template for MEDIA_TYPE strategy */\n  mediaTypeTemplate?: string;\n  /** Callback for deprecation warnings */\n  onDeprecationWarning?: (info: VersionNegotiationResult) => void;\n  /** Callback for version mismatch */\n  onVersionMismatch?: (requested: ApiVersion, actual: ApiVersion) => void;\n  /** Callback for unsupported version */\n  onUnsupportedVersion?: (version: ApiVersion, minimum: ApiVersion) => void;\n  /** Default request timeout */\n  timeout?: number;\n  /** Default headers */\n  defaultHeaders?: Record<string, string>;\n}\n\n// =============================================================================\n// ERRORS\n// =============================================================================\n\n/**\n * Version not supported error\n */\nexport class VersionNotSupportedError extends Error {\n  readonly isVersionError = true;\n  readonly requestedVersion: ApiVersion;\n  readonly minimumVersion: ApiVersion;\n  readonly supportedVersions: ApiVersion[];\n\n  constructor(requested: ApiVersion, minimum: ApiVersion, supported: ApiVersion[]) {\n    super(`API version ${requested} is not supported. Minimum: ${minimum}, Supported: ${supported.join(', ')}`);\n    this.name = 'VersionNotSupportedError';\n    this.requestedVersion = requested;\n    this.minimumVersion = minimum;\n    this.supportedVersions = supported;\n  }\n}\n\n/**\n * Version deprecated error (when using sunset version)\n */\nexport class VersionDeprecatedError extends Error {\n  readonly isVersionError = true;\n  readonly version: ApiVersion;\n  readonly deprecation: VersionDeprecation;\n\n  constructor(version: ApiVersion, deprecation: VersionDeprecation) {\n    super(`API version ${version} is deprecated and will be removed on ${deprecation.sunsetDate}`);\n    this.name = 'VersionDeprecatedError';\n    this.version = version;\n    this.deprecation = deprecation;\n  }\n}\n\n// =============================================================================\n// UTILITY FUNCTIONS\n// =============================================================================\n\n/**\n * Parse version string to comparable components\n */\nexport function parseVersion(version: ApiVersion): { major: number; minor: number; patch: number } {\n  const match = version.match(/^v(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?$/);\n  if (!match) {\n    return { major: 0, minor: 0, patch: 0 };\n  }\n  return {\n    major: parseInt(match[1] ?? '0', 10),\n    minor: parseInt(match[2] ?? '0', 10),\n    patch: parseInt(match[3] ?? '0', 10),\n  };\n}\n\n/**\n * Convert version to numeric value for comparison\n */\nexport function versionToNumber(version: ApiVersion): number {\n  const { major, minor, patch } = parseVersion(version);\n  return major * 1000000 + minor * 1000 + patch;\n}\n\n/**\n * Compare two versions\n * Returns: negative if a < b, 0 if equal, positive if a > b\n */\nexport function compareVersions(a: ApiVersion, b: ApiVersion): number {\n  return versionToNumber(a) - versionToNumber(b);\n}\n\n/**\n * Check if version is within range\n */\nexport function isVersionInRange(version: ApiVersion, min: ApiVersion, max?: ApiVersion): boolean {\n  const v = versionToNumber(version);\n  const minV = versionToNumber(min);\n  const maxV = (max !== null && max !== undefined) ? versionToNumber(max) : Infinity;\n  return v >= minV && v <= maxV;\n}\n\n/**\n * Get latest version from array\n */\nexport function getLatestVersion(versions: ApiVersion[]): ApiVersion | undefined {\n  if (versions.length === 0) return undefined;\n  return versions.reduce((latest, current) => (compareVersions(current, latest) > 0 ? current : latest));\n}\n\n// =============================================================================\n// VERSIONED API CLIENT\n// =============================================================================\n\n/**\n * Versioned API client with full version management\n */\nexport class VersionedApiClient {\n  private readonly config: VersionedApiClientConfig;\n  private currentVersion: ApiVersion;\n  private deprecationWarned: Set<ApiVersion> = new Set();\n\n  constructor(config: VersionedApiClientConfig) {\n    this.config = config;\n    this.currentVersion = config.versionConfig.current;\n  }\n\n  /**\n   * Get current version\n   */\n  getVersion(): ApiVersion {\n    return this.currentVersion;\n  }\n\n  /**\n   * Get all supported versions\n   */\n  getSupportedVersions(): ApiVersion[] {\n    return [...this.config.versionConfig.supported];\n  }\n\n  /**\n   * Check if version is supported\n   */\n  isVersionSupported(version: ApiVersion): boolean {\n    return (\n      compareVersions(version, this.config.versionConfig.minimum) >= 0 &&\n      this.config.versionConfig.supported.includes(version)\n    );\n  }\n\n  /**\n   * Set target version with validation\n   */\n  setVersion(version: ApiVersion): VersionNegotiationResult {\n    const { versionConfig } = this.config;\n\n    // Check if version is supported\n    if (compareVersions(version, versionConfig.minimum) < 0) {\n      this.config.onUnsupportedVersion?.(version, versionConfig.minimum);\n      throw new VersionNotSupportedError(version, versionConfig.minimum, versionConfig.supported);\n    }\n\n    // Check deprecation status\n    const deprecation = versionConfig.deprecated.get(version);\n    const isDeprecated = !!deprecation;\n\n    // Check if sunset date has passed\n    if (deprecation) {\n      const sunsetDate = new Date(deprecation.sunsetDate);\n      if (sunsetDate < new Date()) {\n        throw new VersionDeprecatedError(version, deprecation);\n      }\n    }\n\n    const result: VersionNegotiationResult = {\n      requestedVersion: version,\n      negotiatedVersion: version,\n      isDeprecated,\n      deprecation,\n      isSupported: this.isVersionSupported(version),\n    };\n\n    // Warn about deprecation (once per version)\n    if (isDeprecated && !this.deprecationWarned.has(version)) {\n      this.deprecationWarned.add(version);\n      this.config.onDeprecationWarning?.(result);\n\n      console.warn(\n        `[API Version] Version ${version} is deprecated. ` +\n          `Will be removed on ${deprecation?.sunsetDate}. ${\n          (deprecation?.migrationGuide !== null && deprecation?.migrationGuide !== undefined && deprecation?.migrationGuide !== '') ? `See ${deprecation.migrationGuide} for migration guide.` : ''}`\n      );\n    }\n\n    this.currentVersion = version;\n    return result;\n  }\n\n  /**\n   * Execute versioned request using apiClient\n   * @throws {ApiError} When the request fails\n   */\n  async request<T>(config: HttpRequestConfig): Promise<T> {\n    const transformer = this.config.versionConfig.transformers.get(this.currentVersion);\n\n    // Transform request for version\n    let processedConfig: HttpRequestConfig = {\n      ...config,\n      url: this.buildUrl(config.url),\n      headers: {\n        ...this.buildHeaders(),\n        ...this.config.defaultHeaders,\n        ...config.headers,\n      },\n      ...((): { timeout?: number } => {\n        if (config.timeout !== undefined) {\n          return { timeout: config.timeout };\n        } else if (this.config.timeout !== undefined) {\n          return { timeout: this.config.timeout };\n        } else {\n          return {};\n        }\n      })(),\n    };\n\n    // Apply body transformation\n    if (transformer?.transformBody !== null && transformer?.transformBody !== undefined && typeof transformer.transformBody === 'function' && config.body !== null && config.body !== undefined) {\n      processedConfig.body = transformer.transformBody(config.body);\n    }\n\n    // Apply request transformation\n    if (transformer?.transformRequest) {\n      processedConfig = transformer.transformRequest(processedConfig);\n    }\n\n    // Execute request using apiClient\n    const response = await apiClient.request<T>({\n      url: processedConfig.url,\n      method: processedConfig.method ?? 'GET',\n      headers: processedConfig.headers,\n      body: processedConfig.body,\n      timeout: processedConfig.timeout,\n      signal: processedConfig.signal,\n    });\n\n    // Check for version mismatch in response\n    const responseVersion = response.headers['x-api-version'] as ApiVersion | undefined;\n    if (responseVersion !== null && responseVersion !== undefined && responseVersion !== this.currentVersion) {\n      this.config.onVersionMismatch?.(this.currentVersion, responseVersion);\n    }\n\n    // Transform response for version\n    let {data} = response;\n    if (transformer?.transformResponse) {\n      data = transformer.transformResponse(data, this.currentVersion);\n    }\n    if (transformer?.transformData) {\n      data = transformer.transformData(data);\n    }\n\n    return data;\n  }\n\n  /**\n   * GET request using apiClient\n   * @throws {ApiError} When the request fails\n   */\n  async get<T>(path: string, config?: Partial<HttpRequestConfig>): Promise<T> {\n    return this.request({ ...config, url: path, method: 'GET' });\n  }\n\n  /**\n   * POST request using apiClient\n   * @throws {ApiError} When the request fails\n   */\n  async post<T>(path: string, body?: unknown, config?: Partial<HttpRequestConfig>): Promise<T> {\n    return this.request({ ...config, url: path, method: 'POST', body });\n  }\n\n  /**\n   * PUT request using apiClient\n   * @throws {ApiError} When the request fails\n   */\n  async put<T>(path: string, body?: unknown, config?: Partial<HttpRequestConfig>): Promise<T> {\n    return this.request({ ...config, url: path, method: 'PUT', body });\n  }\n\n  /**\n   * PATCH request using apiClient\n   * @throws {ApiError} When the request fails\n   */\n  async patch<T>(path: string, body?: unknown, config?: Partial<HttpRequestConfig>): Promise<T> {\n    return this.request({ ...config, url: path, method: 'PATCH', body });\n  }\n\n  /**\n   * DELETE request using apiClient\n   * @throws {ApiError} When the request fails\n   */\n  async delete<T>(path: string, config?: Partial<HttpRequestConfig>): Promise<T> {\n    return this.request({ ...config, url: path, method: 'DELETE' });\n  }\n\n  /**\n   * Create a version-specific client\n   */\n  withVersion(version: ApiVersion): VersionedApiClient {\n    const client = new VersionedApiClient(this.config);\n    client.setVersion(version);\n    return client;\n  }\n\n  /**\n   * Build versioned URL\n   */\n  private buildUrl(path: string): string {\n    const { strategy, baseUrl } = this.config;\n    const transformer = this.config.versionConfig.transformers.get(this.currentVersion);\n\n    // Apply endpoint mapping if available\n    const mappedPath = transformer?.mapEndpoint?.(path) ?? path;\n\n    switch (strategy) {\n      case VersioningStrategy.URL_PATH:\n        return `${baseUrl}/${this.currentVersion}${mappedPath}`;\n\n      case VersioningStrategy.QUERY_PARAM: {\n        const separator = mappedPath.includes('?') ? '&' : '?';\n        return `${baseUrl}${mappedPath}${separator}version=${this.currentVersion}`;\n      }\n\n      default:\n        return `${baseUrl}${mappedPath}`;\n    }\n  }\n\n  /**\n   * Build versioned headers\n   */\n  private buildHeaders(): Record<string, string> {\n    const { strategy, headerName = 'X-API-Version', mediaTypeTemplate = 'application/vnd.api.{version}+json' } =\n      this.config;\n\n    const versionNumber = this.currentVersion.slice(1); // Remove 'v' prefix\n\n    switch (strategy) {\n      case VersioningStrategy.ACCEPT_HEADER:\n        return {\n          Accept: `application/vnd.api+json; version=${versionNumber}`,\n        };\n\n      case VersioningStrategy.CUSTOM_HEADER:\n        return {\n          [headerName]: this.currentVersion,\n        };\n\n      case VersioningStrategy.MEDIA_TYPE:\n        return {\n          Accept: mediaTypeTemplate.replace('{version}', this.currentVersion),\n          'Content-Type': mediaTypeTemplate.replace('{version}', this.currentVersion),\n        };\n\n      default:\n        return {};\n    }\n  }\n}\n\n// =============================================================================\n// FACTORY FUNCTIONS\n// =============================================================================\n\n/**\n * Create a versioned API client with sensible defaults\n */\nexport function createVersionedApi(config: {\n  baseUrl: string;\n  currentVersion?: ApiVersion;\n  minimumVersion?: ApiVersion;\n  supportedVersions?: ApiVersion[];\n  strategy?: VersioningStrategy;\n  deprecated?: Record<ApiVersion, VersionDeprecation>;\n  transformers?: Record<ApiVersion, VersionTransformer>;\n  onDeprecationWarning?: (info: VersionNegotiationResult) => void;\n}): VersionedApiClient {\n  const {\n    baseUrl,\n    currentVersion = 'v1',\n    minimumVersion = 'v1',\n    supportedVersions = [currentVersion],\n    strategy = VersioningStrategy.URL_PATH,\n    deprecated = {},\n    transformers = {},\n    onDeprecationWarning,\n  } = config;\n\n  return new VersionedApiClient({\n    baseUrl,\n    strategy,\n    versionConfig: {\n      current: currentVersion,\n      minimum: minimumVersion,\n      supported: supportedVersions,\n      deprecated: new Map(Object.entries(deprecated) as [ApiVersion, VersionDeprecation][]),\n      transformers: new Map(Object.entries(transformers) as [ApiVersion, VersionTransformer][]),\n    },\n    onDeprecationWarning: onDeprecationWarning ?? ((info): void => {\n      console.warn('[API Deprecation]', info);\n    }),\n  });\n}\n\n// =============================================================================\n// VERSION TRANSFORMER HELPERS\n// =============================================================================\n\n/**\n * Create a field renaming transformer\n */\nexport function createFieldRenamingTransformer(\n  requestMappings: Record<string, string>,\n  responseMappings: Record<string, string>\n): VersionTransformer {\n  function renameFields<T>(obj: T, mappings: Record<string, string>): T {\n    if (typeof obj !== 'object' || obj === null) return obj;\n\n    if (Array.isArray(obj)) {\n      const mapped: unknown[] = obj.map((item: unknown) => renameFields(item, mappings));\n      return mapped as T;\n    }\n\n    const result: Record<string, unknown> = {};\n    for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n      const newKey = mappings[key] ?? key;\n      result[newKey] = typeof value === 'object' ? renameFields(value, mappings) as unknown : value;\n    }\n    return result as T;\n  }\n\n  return {\n    transformBody: (body) => renameFields(body, requestMappings),\n    transformData: <T>(data: T) => renameFields(data, responseMappings),\n  };\n}\n\n/**\n * Create an endpoint mapping transformer\n */\nexport function createEndpointMappingTransformer(mappings: Record<string, string>): VersionTransformer {\n  return {\n    mapEndpoint: (path) => {\n      for (const [pattern, replacement] of Object.entries(mappings)) {\n        if (path.startsWith(pattern)) {\n          return path.replace(pattern, replacement);\n        }\n        // Support regex patterns\n        const regex = new RegExp(pattern);\n        if (regex.test(path)) {\n          return path.replace(regex, replacement);\n        }\n      }\n      return path;\n    },\n  };\n}\n\n/**\n * Compose multiple transformers\n */\nexport function composeTransformers(...transformers: VersionTransformer[]): VersionTransformer {\n  return {\n    transformRequest: (config) => {\n      let result = config;\n      for (const transformer of transformers) {\n        if (transformer.transformRequest) {\n          result = transformer.transformRequest(result);\n        }\n      }\n      return result;\n    },\n    transformResponse: <T>(data: T, version: ApiVersion) => {\n      let result = data;\n      for (const transformer of transformers) {\n        if (transformer.transformResponse) {\n          result = transformer.transformResponse(result, version);\n        }\n      }\n      return result;\n    },\n    mapEndpoint: (path) => {\n      let result = path;\n      for (const transformer of transformers) {\n        if (transformer.mapEndpoint) {\n          result = transformer.mapEndpoint(result);\n        }\n      }\n      return result;\n    },\n    transformBody: (body) => {\n      let result = body;\n      for (const transformer of transformers) {\n        if (transformer.transformBody) {\n          result = transformer.transformBody(result);\n        }\n      }\n      return result;\n    },\n    transformData: <T>(data: T) => {\n      let result = data;\n      for (const transformer of transformers) {\n        if (transformer.transformData) {\n          result = transformer.transformData(result);\n        }\n      }\n      return result;\n    },\n  };\n}\n\n// =============================================================================\n// EXAMPLE USAGE\n// =============================================================================\n\n/**\n * Example: Create versioned API with v1 to v2 migration\n */\nexport const exampleVersionedApi = createVersionedApi({\n  baseUrl: '/api',\n  currentVersion: 'v2',\n  minimumVersion: 'v1',\n  supportedVersions: ['v1', 'v2'],\n  strategy: VersioningStrategy.URL_PATH,\n  deprecated: {\n    v1: {\n      sunsetDate: '2025-06-01',\n      migrationGuide: 'https://docs.example.com/migrate-v1-to-v2',\n      replacementVersion: 'v2',\n      message: 'Please migrate to v2 for improved performance and new features.',\n    },\n  },\n  transformers: {\n    v1: composeTransformers(\n      // Field renaming: v1 uses 'username', v2 uses 'name'\n      createFieldRenamingTransformer({ name: 'username' }, { username: 'name' }),\n      // Endpoint mapping: v1 uses /user/:id, v2 uses /users/:id\n      createEndpointMappingTransformer({\n        '/users/': '/user/',\n      })\n    ),\n  },\n});\n\n// Usage:\n// const api = createVersionedApi({ baseUrl: '/api', currentVersion: 'v2' });\n// const users = await api.get('/users');\n// api.setVersion('v1'); // Switch to v1 with automatic transformations\n// const oldUsers = await api.get('/users'); // Automatically transformed\n"],"names":["VersioningStrategy","VersionNotSupportedError","requested","minimum","supported","VersionDeprecatedError","version","deprecation","parseVersion","match","versionToNumber","major","minor","patch","compareVersions","a","b","isVersionInRange","min","max","v","minV","maxV","getLatestVersion","versions","latest","current","VersionedApiClient","config","versionConfig","isDeprecated","result","transformer","processedConfig","response","apiClient","responseVersion","data","path","body","client","strategy","baseUrl","mappedPath","separator","headerName","mediaTypeTemplate","versionNumber","createVersionedApi","currentVersion","minimumVersion","supportedVersions","deprecated","transformers","onDeprecationWarning","info","createFieldRenamingTransformer","requestMappings","responseMappings","renameFields","obj","mappings","item","key","value","newKey","createEndpointMappingTransformer","pattern","replacement","regex","composeTransformers","exampleVersionedApi"],"mappings":"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"}