All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 17m56s
184 lines
5.4 KiB
TypeScript
184 lines
5.4 KiB
TypeScript
// src/config/apiVersions.ts
|
|
/**
|
|
* @file API version constants, types, and configuration.
|
|
* Implements ADR-008 Phase 2: API Versioning Infrastructure.
|
|
*
|
|
* This module provides centralized version definitions used by:
|
|
* - Version detection middleware (apiVersion.middleware.ts)
|
|
* - Deprecation headers middleware (deprecation.middleware.ts)
|
|
* - Versioned router factory (versioned.ts)
|
|
*
|
|
* @see docs/architecture/api-versioning-infrastructure.md
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* import {
|
|
* CURRENT_API_VERSION,
|
|
* VERSION_CONFIGS,
|
|
* isValidApiVersion,
|
|
* } from './apiVersions';
|
|
*
|
|
* // Check if a version is supported
|
|
* if (isValidApiVersion('v1')) {
|
|
* const config = VERSION_CONFIGS.v1;
|
|
* console.log(`v1 status: ${config.status}`);
|
|
* }
|
|
* ```
|
|
*/
|
|
|
|
// --- Type Definitions ---
|
|
|
|
/**
|
|
* All API versions as a const tuple for type derivation.
|
|
* Add new versions here when introducing them.
|
|
*/
|
|
export const API_VERSIONS = ['v1', 'v2'] as const;
|
|
|
|
/**
|
|
* Union type of supported API versions.
|
|
* Currently: 'v1' | 'v2'
|
|
*/
|
|
export type ApiVersion = (typeof API_VERSIONS)[number];
|
|
|
|
/**
|
|
* Version lifecycle status.
|
|
* - 'active': Version is fully supported and recommended
|
|
* - 'deprecated': Version works but clients should migrate (deprecation headers sent)
|
|
* - 'sunset': Version is scheduled for removal or already removed
|
|
*/
|
|
export type VersionStatus = 'active' | 'deprecated' | 'sunset';
|
|
|
|
/**
|
|
* Deprecation information for an API version.
|
|
* Follows RFC 8594 (Sunset Header) and draft-ietf-httpapi-deprecation-header.
|
|
*
|
|
* Used by deprecation middleware to set appropriate HTTP headers:
|
|
* - `Deprecation: true` (draft-ietf-httpapi-deprecation-header)
|
|
* - `Sunset: <date>` (RFC 8594)
|
|
* - `Link: <url>; rel="successor-version"` (RFC 8288)
|
|
*/
|
|
export interface VersionDeprecation {
|
|
/** Indicates if this version is deprecated (maps to Deprecation header) */
|
|
deprecated: boolean;
|
|
/** ISO 8601 date string when the version will be sunset (maps to Sunset header) */
|
|
sunsetDate?: string;
|
|
/** The version clients should migrate to (maps to Link rel="successor-version") */
|
|
successorVersion?: ApiVersion;
|
|
/** Human-readable message explaining the deprecation (for documentation/logs) */
|
|
message?: string;
|
|
}
|
|
|
|
/**
|
|
* Complete configuration for an API version.
|
|
* Combines version identifier, lifecycle status, and deprecation details.
|
|
*/
|
|
export interface VersionConfig {
|
|
/** The version identifier (e.g., 'v1') */
|
|
version: ApiVersion;
|
|
/** Current lifecycle status of this version */
|
|
status: VersionStatus;
|
|
/** ISO 8601 date when the version will be sunset (RFC 8594) - convenience field */
|
|
sunsetDate?: string;
|
|
/** The version clients should migrate to - convenience field */
|
|
successorVersion?: ApiVersion;
|
|
}
|
|
|
|
// --- Constants ---
|
|
|
|
/**
|
|
* The current/latest stable API version.
|
|
* New clients should use this version.
|
|
*/
|
|
export const CURRENT_API_VERSION: ApiVersion = 'v1';
|
|
|
|
/**
|
|
* The default API version for requests without explicit version.
|
|
* Used when version cannot be detected from the request path.
|
|
*/
|
|
export const DEFAULT_VERSION: ApiVersion = 'v1';
|
|
|
|
/**
|
|
* Array of all supported API versions.
|
|
* Used for validation and enumeration.
|
|
*/
|
|
export const SUPPORTED_VERSIONS: readonly ApiVersion[] = API_VERSIONS;
|
|
|
|
/**
|
|
* Configuration map for all API versions.
|
|
* Provides lifecycle status and deprecation information for each version.
|
|
*
|
|
* To mark v1 as deprecated (example for future use):
|
|
* @example
|
|
* ```typescript
|
|
* VERSION_CONFIGS.v1 = {
|
|
* version: 'v1',
|
|
* status: 'deprecated',
|
|
* sunsetDate: '2027-01-01T00:00:00Z',
|
|
* successorVersion: 'v2',
|
|
* };
|
|
* ```
|
|
*/
|
|
export const VERSION_CONFIGS: Record<ApiVersion, VersionConfig> = {
|
|
v1: {
|
|
version: 'v1',
|
|
status: 'active',
|
|
// No deprecation info - v1 is the current active version
|
|
},
|
|
v2: {
|
|
version: 'v2',
|
|
status: 'active',
|
|
// v2 is defined for infrastructure readiness but not yet implemented
|
|
},
|
|
};
|
|
|
|
// --- Utility Functions ---
|
|
|
|
/**
|
|
* Type guard to check if a string is a valid ApiVersion.
|
|
*
|
|
* @param value - The string to check
|
|
* @returns True if the string is a valid API version
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* const userInput = 'v1';
|
|
* if (isValidApiVersion(userInput)) {
|
|
* // userInput is now typed as ApiVersion
|
|
* const config = VERSION_CONFIGS[userInput];
|
|
* }
|
|
* ```
|
|
*/
|
|
export function isValidApiVersion(value: string): value is ApiVersion {
|
|
return API_VERSIONS.includes(value as ApiVersion);
|
|
}
|
|
|
|
/**
|
|
* Check if a version is deprecated.
|
|
*
|
|
* @param version - The API version to check
|
|
* @returns True if the version status is 'deprecated'
|
|
*/
|
|
export function isVersionDeprecated(version: ApiVersion): boolean {
|
|
return VERSION_CONFIGS[version].status === 'deprecated';
|
|
}
|
|
|
|
/**
|
|
* Get deprecation information for a version.
|
|
* Constructs a VersionDeprecation object from the version config.
|
|
*
|
|
* @param version - The API version to get deprecation info for
|
|
* @returns VersionDeprecation object with current deprecation state
|
|
*/
|
|
export function getVersionDeprecation(version: ApiVersion): VersionDeprecation {
|
|
const config = VERSION_CONFIGS[version];
|
|
return {
|
|
deprecated: config.status === 'deprecated',
|
|
sunsetDate: config.sunsetDate,
|
|
successorVersion: config.successorVersion,
|
|
message:
|
|
config.status === 'deprecated'
|
|
? `API ${version} is deprecated${config.sunsetDate ? ` and will be sunset on ${config.sunsetDate}` : ''}${config.successorVersion ? `. Please migrate to ${config.successorVersion}.` : '.'}`
|
|
: undefined,
|
|
};
|
|
}
|