{"version":3,"file":"api-versioning.mjs","sources":["../../../../src/lib/api/advanced/api-versioning.ts"],"sourcesContent":["/**\n * API Versioning\n *\n * Comprehensive API version management with support for multiple\n * versioning strategies and migration helpers.\n *\n * @module api/advanced/api-versioning\n */\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * API versioning strategy.\n */\nexport type VersioningStrategy = 'url' | 'header' | 'query' | 'accept';\n\n/**\n * Version format configuration.\n */\nexport interface VersionFormat {\n  /** Version prefix (e.g., 'v') */\n  prefix?: string;\n  /** Version separator for header-based (e.g., '.') */\n  separator?: string;\n  /** Date format for date-based versioning */\n  dateFormat?: string;\n}\n\n/**\n * Version compatibility status.\n */\nexport type VersionStatus = 'current' | 'supported' | 'deprecated' | 'unsupported';\n\n/**\n * API version definition.\n */\nexport interface APIVersion {\n  /** Version identifier */\n  version: string;\n  /** Semantic version number */\n  semver?: string;\n  /** Version status */\n  status: VersionStatus;\n  /** Release date */\n  releasedAt?: string;\n  /** Deprecation date */\n  deprecatedAt?: string;\n  /** Sunset date (when version will be removed) */\n  sunsetAt?: string;\n  /** Breaking changes in this version */\n  breakingChanges?: string[];\n  /** New features in this version */\n  features?: string[];\n  /** Migration notes */\n  migrationNotes?: string;\n  /** Changelog URL */\n  changelogUrl?: string;\n}\n\n/**\n * Version manager configuration.\n */\nexport interface VersionManagerConfig {\n  /** Versioning strategy */\n  strategy: VersioningStrategy;\n  /** Current/default version */\n  currentVersion: string;\n  /** Supported versions */\n  supportedVersions: APIVersion[];\n  /** Header name for header-based versioning */\n  headerName?: string;\n  /** Query parameter name for query-based versioning */\n  queryParam?: string;\n  /** Accept header media type prefix */\n  acceptPrefix?: string;\n  /** Version format configuration */\n  format?: VersionFormat;\n  /** Callback when using deprecated version */\n  onDeprecatedVersion?: (version: string, info: APIVersion) => void;\n  /** Callback when using unsupported version */\n  onUnsupportedVersion?: (version: string) => void;\n}\n\n/**\n * Version transform function for request migration.\n */\nexport type VersionTransform<T = unknown> = (data: T, fromVersion: string, toVersion: string) => T;\n\n/**\n * Response migration configuration.\n */\nexport interface ResponseMigration<T = unknown> {\n  /** Source version */\n  fromVersion: string;\n  /** Target version */\n  toVersion: string;\n  /** Transform function */\n  transform: VersionTransform<T>;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nconst DEFAULT_HEADER_NAME = 'X-API-Version';\nconst DEFAULT_QUERY_PARAM = 'api-version';\nconst DEFAULT_ACCEPT_PREFIX = 'application/vnd.api';\n\n// =============================================================================\n// Version Manager Class\n// =============================================================================\n\n/**\n * API Version Manager for handling API versioning.\n *\n * @example\n * ```typescript\n * const versionManager = new VersionManager({\n *   strategy: 'header',\n *   currentVersion: 'v2',\n *   supportedVersions: [\n *     { version: 'v2', status: 'current' },\n *     { version: 'v1', status: 'deprecated', sunsetAt: '2024-12-31' },\n *   ],\n * });\n *\n * // Apply version to request\n * const headers = versionManager.getVersionHeaders('v2');\n * const url = versionManager.getVersionedUrl('/users', 'v2');\n *\n * // Check version status\n * if (versionManager.isDeprecated('v1')) {\n *   console.warn('Please upgrade to v2');\n * }\n * ```\n */\nexport class VersionManager {\n  private config: VersionManagerConfig;\n  private migrations: Map<string, ResponseMigration[]>;\n\n  /**\n   * Create a new version manager.\n   *\n   * @param config - Version manager configuration\n   */\n  constructor(config: VersionManagerConfig) {\n    this.config = {\n      headerName: DEFAULT_HEADER_NAME,\n      queryParam: DEFAULT_QUERY_PARAM,\n      acceptPrefix: DEFAULT_ACCEPT_PREFIX,\n      format: { prefix: 'v', separator: '.' },\n      ...config,\n    };\n    this.migrations = new Map();\n  }\n\n  // ===========================================================================\n  // Version Headers & URLs\n  // ===========================================================================\n\n  /**\n   * Get headers for the specified version.\n   *\n   * @param version - API version\n   * @returns Headers object\n   */\n  getVersionHeaders(version?: string): Record<string, string> {\n    const ver = version ?? this.config.currentVersion;\n    this.checkVersion(ver);\n\n    switch (this.config.strategy) {\n      case 'header': {\n        const headerName = this.config.headerName ?? DEFAULT_HEADER_NAME;\n        return { [headerName]: ver };\n      }\n\n      case 'accept':\n        return {\n          Accept: `${this.config.acceptPrefix}.${ver}+json`,\n        };\n\n      case 'url':\n      case 'query':\n      default:\n        return {};\n    }\n  }\n\n  /**\n   * Get versioned URL.\n   *\n   * @param path - API path\n   * @param version - API version\n   * @param baseUrl - Base URL\n   * @returns Versioned URL\n   */\n  getVersionedUrl(path: string, version?: string, baseUrl = ''): string {\n    const ver = version ?? this.config.currentVersion;\n    this.checkVersion(ver);\n\n    const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n\n    switch (this.config.strategy) {\n      case 'url':\n        return `${baseUrl}/${ver}${normalizedPath}`;\n\n      case 'query': {\n        const separator = path.includes('?') ? '&' : '?';\n        const queryParam = this.config.queryParam ?? DEFAULT_QUERY_PARAM;\n        return `${baseUrl}${normalizedPath}${separator}${queryParam}=${ver}`;\n      }\n\n      case 'header':\n      case 'accept':\n      default:\n        return `${baseUrl}${normalizedPath}`;\n    }\n  }\n\n  /**\n   * Extract version from request/response.\n   *\n   * @param headers - Response headers\n   * @param url - Request URL\n   * @returns Detected version or null\n   */\n  extractVersion(headers?: Record<string, string>, url?: string): string | null {\n    // Check header\n    if (headers != null && this.config.headerName != null && this.config.headerName !== '') {\n      const headerVersion = headers[this.config.headerName];\n      if (headerVersion != null && headerVersion !== '') return headerVersion;\n    }\n\n    // Check URL for path-based versioning\n    if (url != null && url !== '' && this.config.strategy === 'url') {\n      const match = url.match(/\\/v(\\d+(?:\\.\\d+)*)\\//);\n      const matchGroup = match?.[1];\n      if (matchGroup != null) return `v${matchGroup}`;\n    }\n\n    // Check URL for query-based versioning\n    if (url != null && url !== '' && this.config.strategy === 'query') {\n      const urlObj = new URL(url, 'http://localhost');\n      const queryParam = this.config.queryParam ?? DEFAULT_QUERY_PARAM;\n      const queryVersion = urlObj.searchParams.get(queryParam);\n      if (queryVersion != null && queryVersion !== '') return queryVersion;\n    }\n\n    return null;\n  }\n\n  // ===========================================================================\n  // Version Status Checking\n  // ===========================================================================\n\n  /**\n   * Get version information.\n   *\n   * @param version - Version to check\n   * @returns Version info or undefined\n   */\n  getVersionInfo(version: string): APIVersion | undefined {\n    return this.config.supportedVersions.find((v) => v.version === version);\n  }\n\n  /**\n   * Check if version is supported.\n   *\n   * @param version - Version to check\n   * @returns Whether version is supported\n   */\n  isSupported(version: string): boolean {\n    const info = this.getVersionInfo(version);\n    return info !== undefined && info.status !== 'unsupported';\n  }\n\n  /**\n   * Check if version is deprecated.\n   *\n   * @param version - Version to check\n   * @returns Whether version is deprecated\n   */\n  isDeprecated(version: string): boolean {\n    const info = this.getVersionInfo(version);\n    return info?.status === 'deprecated';\n  }\n\n  /**\n   * Check if version is current.\n   *\n   * @param version - Version to check\n   * @returns Whether version is current\n   */\n  isCurrent(version: string): boolean {\n    const info = this.getVersionInfo(version);\n    return info?.status === 'current';\n  }\n\n  /**\n   * Get the current version.\n   */\n  getCurrentVersion(): string {\n    return this.config.currentVersion;\n  }\n\n  /**\n   * Get all supported versions.\n   */\n  getSupportedVersions(): APIVersion[] {\n    return this.config.supportedVersions.filter((v) => v.status !== 'unsupported');\n  }\n\n  /**\n   * Get deprecated versions.\n   */\n  getDeprecatedVersions(): APIVersion[] {\n    return this.config.supportedVersions.filter((v) => v.status === 'deprecated');\n  }\n\n  /**\n   * Compare two versions.\n   *\n   * @param a - First version\n   * @param b - Second version\n   * @returns Negative if a < b, positive if a > b, 0 if equal\n   */\n  compareVersions(a: string, b: string): number {\n    const normalize = (v: string): number[] => {\n      const match = v.match(/(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?/);\n      if (!match) return [0, 0, 0];\n      return [\n        parseInt(match[1] ?? '0', 10),\n        parseInt(match[2] ?? '0', 10),\n        parseInt(match[3] ?? '0', 10),\n      ];\n    };\n\n    const aParts = normalize(a);\n    const bParts = normalize(b);\n\n    for (let i = 0; i < 3; i++) {\n      const aPart = aParts[i] ?? 0;\n      const bPart = bParts[i] ?? 0;\n      if (aPart !== bPart) {\n        return aPart - bPart;\n      }\n    }\n\n    return 0;\n  }\n\n  // ===========================================================================\n  // Version Comparison\n  // ===========================================================================\n\n  /**\n   * Check if version is newer than another.\n   */\n  isNewerThan(version: string, other: string): boolean {\n    return this.compareVersions(version, other) > 0;\n  }\n\n  /**\n   * Check if version is older than another.\n   */\n  isOlderThan(version: string, other: string): boolean {\n    return this.compareVersions(version, other) < 0;\n  }\n\n  /**\n   * Get the latest version.\n   */\n  getLatestVersion(): string {\n    const sorted = [...this.config.supportedVersions].sort((a, b) =>\n      this.compareVersions(b.version, a.version)\n    );\n    return sorted[0]?.version ?? this.config.currentVersion;\n  }\n\n  /**\n   * Register a response migration.\n   *\n   * @param migration - Migration configuration\n   */\n  registerMigration<T = unknown>(migration: ResponseMigration<T>): void {\n    const key = `${migration.fromVersion}->${migration.toVersion}`;\n    const existing = this.migrations.get(key) ?? [];\n    existing.push(migration as ResponseMigration);\n    this.migrations.set(key, existing);\n  }\n\n  // ===========================================================================\n  // Response Migration\n  // ===========================================================================\n\n  /**\n   * Migrate response data from one version to another.\n   *\n   * @param data - Response data\n   * @param fromVersion - Source version\n   * @param toVersion - Target version\n   * @returns Migrated data\n   */\n  migrateResponse<T>(data: T, fromVersion: string, toVersion: string): T {\n    if (fromVersion === toVersion) {\n      return data;\n    }\n\n    // Find direct migration\n    const key = `${fromVersion}->${toVersion}`;\n    const migrations = this.migrations.get(key);\n\n    if (migrations) {\n      let result = data;\n      for (const migration of migrations) {\n        result = migration.transform(result, fromVersion, toVersion) as T;\n      }\n      return result;\n    }\n\n    // Find migration path\n    const path = this.findMigrationPath(fromVersion, toVersion);\n\n    if (path.length === 0) {\n      console.warn(`No migration path from ${fromVersion} to ${toVersion}`);\n      return data;\n    }\n\n    let result = data;\n    for (let i = 0; i < path.length - 1; i++) {\n      const fromVer = path[i];\n      const toVer = path[i + 1];\n      if (fromVer != null && toVer != null) {\n        result = this.migrateResponse(result, fromVer, toVer);\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Get days until version sunset.\n   *\n   * @param version - Version to check\n   * @returns Days until sunset, -1 if no sunset date, Infinity if already past\n   */\n  getDaysUntilSunset(version: string): number {\n    const info = this.getVersionInfo(version);\n\n    if (info?.sunsetAt == null || info.sunsetAt === '') {\n      return -1;\n    }\n\n    const sunsetDate = new Date(info.sunsetAt);\n    const today = new Date();\n    const diffTime = sunsetDate.getTime() - today.getTime();\n\n    return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n  }\n\n  /**\n   * Check if version has sunset.\n   */\n  hasSunset(version: string): boolean {\n    const days = this.getDaysUntilSunset(version);\n    return days >= 0 && days <= 0;\n  }\n\n  // ===========================================================================\n  // Sunset Checking\n  // ===========================================================================\n\n  /**\n   * Get versions approaching sunset.\n   *\n   * @param daysThreshold - Days before sunset to warn\n   * @returns Versions within threshold\n   */\n  getVersionsApproachingSunset(daysThreshold = 30): APIVersion[] {\n    return this.config.supportedVersions.filter((v) => {\n      const days = this.getDaysUntilSunset(v.version);\n      return days >= 0 && days <= daysThreshold;\n    });\n  }\n\n  /**\n   * Add a new version.\n   */\n  addVersion(version: APIVersion): void {\n    const existing = this.config.supportedVersions.findIndex((v) => v.version === version.version);\n\n    if (existing >= 0) {\n      this.config.supportedVersions[existing] = version;\n    } else {\n      this.config.supportedVersions.push(version);\n    }\n  }\n\n  /**\n   * Update version status.\n   */\n  updateVersionStatus(version: string, status: VersionStatus): void {\n    const info = this.getVersionInfo(version);\n    if (info != null) {\n      info.status = status;\n      if (status === 'deprecated' && (info.deprecatedAt == null || info.deprecatedAt === '')) {\n        info.deprecatedAt = new Date().toISOString();\n      }\n    }\n  }\n\n  // ===========================================================================\n  // Configuration Updates\n  // ===========================================================================\n\n  /**\n   * Set current version.\n   */\n  setCurrentVersion(version: string): void {\n    if (!this.isSupported(version)) {\n      throw new Error(`Version ${version} is not supported`);\n    }\n\n    // Update old current to supported\n    const oldCurrent = this.config.supportedVersions.find((v) => v.status === 'current');\n    if (oldCurrent) {\n      oldCurrent.status = 'supported';\n    }\n\n    // Update new current\n    const newCurrent = this.getVersionInfo(version);\n    if (newCurrent) {\n      newCurrent.status = 'current';\n    }\n\n    this.config.currentVersion = version;\n  }\n\n  /**\n   * Check version status and trigger callbacks.\n   */\n  private checkVersion(version: string): void {\n    const info = this.getVersionInfo(version);\n\n    if (!info) {\n      this.config.onUnsupportedVersion?.(version);\n      return;\n    }\n\n    if (info.status === 'deprecated') {\n      this.config.onDeprecatedVersion?.(version, info);\n    }\n\n    if (info.status === 'unsupported') {\n      this.config.onUnsupportedVersion?.(version);\n    }\n  }\n\n  /**\n   * Find migration path between versions.\n   */\n  private findMigrationPath(from: string, to: string): string[] {\n    const versions = this.config.supportedVersions.map((v) => v.version);\n    const fromIndex = versions.indexOf(from);\n    const toIndex = versions.indexOf(to);\n\n    if (fromIndex === -1 || toIndex === -1) {\n      return [];\n    }\n\n    // Return path in order\n    if (fromIndex < toIndex) {\n      return versions.slice(fromIndex, toIndex + 1);\n    } else {\n      return versions.slice(toIndex, fromIndex + 1).reverse();\n    }\n  }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a new version manager.\n *\n * @param config - Configuration options\n * @returns VersionManager instance\n */\nexport function createVersionManager(config: VersionManagerConfig): VersionManager {\n  return new VersionManager(config);\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Parse semantic version string.\n */\nexport function parseSemver(version: string): {\n  major: number;\n  minor: number;\n  patch: number;\n  prerelease?: string;\n} | null {\n  const match = version.match(\n    /^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-(.+))?$/\n  );\n\n  if (!match) return null;\n\n  const [, majorStr, minorStr, patchStr, prerelease] = match;\n  if (majorStr == null) return null;\n\n  return {\n    major: parseInt(majorStr, 10),\n    minor: parseInt(minorStr ?? '0', 10),\n    patch: parseInt(patchStr ?? '0', 10),\n    prerelease,\n  };\n}\n\n/**\n * Format version string.\n */\nexport function formatVersion(\n  major: number,\n  minor?: number,\n  patch?: number,\n  options?: { prefix?: string }\n): string {\n  const prefix = options?.prefix ?? 'v';\n  let version = `${prefix}${major}`;\n\n  if (minor !== undefined) {\n    version += `.${minor}`;\n    if (patch !== undefined) {\n      version += `.${patch}`;\n    }\n  }\n\n  return version;\n}\n"],"names":["DEFAULT_HEADER_NAME","DEFAULT_QUERY_PARAM","DEFAULT_ACCEPT_PREFIX","VersionManager","config","version","ver","path","baseUrl","normalizedPath","separator","queryParam","headers","url","headerVersion","matchGroup","urlObj","queryVersion","v","info","a","b","normalize","match","aParts","bParts","aPart","bPart","other","migration","key","existing","data","fromVersion","toVersion","migrations","result","i","fromVer","toVer","sunsetDate","today","diffTime","days","daysThreshold","status","oldCurrent","newCurrent","from","to","versions","fromIndex","toIndex","createVersionManager","parseSemver","majorStr","minorStr","patchStr","prerelease","formatVersion","major","minor","patch","options"],"mappings":"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"}