import { NestMiddleware } from '@nestjs/common'; import { FeatureFlagService } from '@domain/featureFlags'; import type { FeatureFlagKey } from '@domain/types'; import type { CoreFeatureFlagRequest } from '@plyaz/types/core'; /** * FeatureFlagMiddleware - Evaluates and attaches feature flags to every request * * @description This middleware runs early in the request lifecycle to evaluate feature flags * and attach them to the request object. It allows controllers and services to access * pre-evaluated flags without making additional service calls, improving performance. * * **Execution Flow:** * 1. Middleware executes first for every incoming HTTP request * 2. Extracts flag key from query params, headers, or uses default * 3. Calls FeatureFlagService to evaluate the specified flag * 4. Attaches evaluated flags to `req.featureFlags` object * 5. Passes control to next middleware/interceptor/controller * * **Flag Key Priority:** * 1. Query parameter: `?flag=FEATURE_NAME` * 2. HTTP header: `X-Feature-Flag: FEATURE_NAME` * 3. Default: `AUTH_GOOGLE` * * **Use Cases:** * - Global feature flag evaluation for all requests * - Performance optimization (evaluate once, use many times) * - Request-scoped feature flag context * - Dynamic flag selection via client parameters * * @example Setup - Register middleware globally * ```typescript * // app.module.ts * import { MiddlewareConsumer, Module } from '@nestjs/common'; * import { FeatureFlagMiddleware } from './middleware/feature-flag-middleware'; * * @Module({ * // ... other config * }) * export class AppModule { * configure(consumer: MiddlewareConsumer) { * consumer * .apply(FeatureFlagMiddleware) * .forRoutes('*'); // Apply to all routes * } * } * ``` * * @example Client Usage - Query Parameter * ```bash * # Client specifies which flag to evaluate * curl "https://api.example.com/users?flag=PREMIUM_FEATURES" * * # Middleware evaluates PREMIUM_FEATURES and attaches to request * # req.featureFlags = { PREMIUM_FEATURES: true } * ``` * * @example Client Usage - HTTP Header * ```bash * # Alternative: Use HTTP header * curl -H "X-Feature-Flag: NEW_DASHBOARD" "https://api.example.com/dashboard" * * # Middleware evaluates NEW_DASHBOARD * # req.featureFlags = { NEW_DASHBOARD: false } * ``` * * @example Controller Access - Use pre-evaluated flags * ```typescript * @Controller('api') * export class ApiController { * @Get('dashboard') * async getDashboard(@Req() req: Request) { * // Access pre-evaluated flags (no service call needed) * const flags = req.featureFlags; * * if (flags?.NEW_DASHBOARD) { * return this.dashboardService.getNewDashboard(); * } else { * return this.dashboardService.getLegacyDashboard(); * } * } * } * ``` * * @example Service Access - Inject flags into services * ```typescript * @Injectable() * export class UserService { * async getUsers(@Req() req: Request) { * const flags = req.featureFlags; * * // Use flags to modify service behavior * if (flags?.ENHANCED_USER_DATA) { * return this.getUsersWithEnhancedData(); * } * * return this.getBasicUsers(); * } * } * ``` * * @example Error Handling - Invalid flag keys * ```typescript * // Request with invalid flag: * // GET /api/users?flag=INVALID_FLAG * // * // Response: * // HTTP 404 Not Found * // { * // "error": "Invalid feature flag key: INVALID_FLAG", * // "statusCode": 404 * // } * ``` * * @example Multiple Flags - Accumulate flags across requests * ```typescript * // First request adds AUTH_GOOGLE: true * // Second request adds PREMIUM_FEATURES: false * // req.featureFlags = { * // AUTH_GOOGLE: true, * // PREMIUM_FEATURES: false * // } * ``` */ export declare class FeatureFlagMiddleware implements NestMiddleware { private readonly featureFlagService; private readonly logger; constructor(featureFlagService: FeatureFlagService); /** * Main middleware execution method * * @description Processes incoming requests to evaluate and attach feature flags. * Handles flag key extraction from multiple sources and graceful error handling. * * @param {CoreFeatureFlagRequest} req - Express request object with feature flag extensions * @param {unknown} res - Express response object (not used in this middleware) * @param {Function} next - Next middleware function in the chain * * @throws {BaseError} When flag key is invalid or evaluation fails * * @example Request Processing Flow * ```typescript * // 1. Extract flag key from request * const flagKey = req.query.flag || req.headers['x-feature-flag'] || 'AUTH_GOOGLE'; * * // 2. Validate flag key exists in system * if (!isFeatureFlagKey(flagKey)) { * throw new Error('Invalid flag key'); * } * * // 3. Evaluate flag using service * const evaluation = await this.featureFlagService.evaluateFlag(flagKey); * * // 4. Attach to request object * req.featureFlags = { [flagKey]: evaluation.isEnabled }; * * // 5. Continue to next middleware * next(); * ``` */ use(req: CoreFeatureFlagRequest, res: unknown, next: (...args: unknown[]) => void): Promise; } //# sourceMappingURL=feature-flag-middleware.d.ts.map