import { Adapter, ConfigOf, ContextOf } from "@decaf-ts/core"; import { Constructor } from "@decaf-ts/decoration"; import { ExecutionContext, Type } from "@nestjs/common"; import { RequestToContextTransformer, type ModelControllerFactoryConfig, type AuthHandler as AuthHandlerBase } from "@decaf-ts/for-http/server"; import { DecafRequestContext } from "./request/index.d.mts"; export interface DecafRequestHandler { handle(context: C, req: Request, res: Response): Promise; } export interface ObserverEventsOptions { /** * Enables or disables SSE stream events globally */ enableObserverEvents?: boolean; /** * Enables explicit subscription registration and per-subscriber filtering. * Broadcast remains the default when omitted or false. */ subscriptionMode?: boolean; /** * Runs the registered auth handler (AuthInterceptor) on the SSE stream and on * the subscribe/unsubscribe endpoints. The authenticated user then scopes the * requester fingerprint (`user::`). A rejected stream * gets the auth handler's HTTP error (e.g. 401). */ authenticate?: boolean; /** * List of adapter flavours that will emit stream events * If omitted, all registered flavours may be used */ observerFlavours?: any[]; /** * SSE endpoint path * @default "/events" */ observerApiPath?: string; } /** * @publicApi */ export type DecafModuleOptions = Adapter> = { conf: [ Constructor, ConfigOf, ...args: any[] | [ ...any[], (RequestToContextTransformer> | Constructor>>) ] ][]; alias?: string; autoControllers: boolean; autoServices?: boolean; controllerExposure?: Record; controllerConfig?: Record; observerOptions?: ObserverEventsOptions; aggregations?: boolean; handlers?: Type[]; initialization?: () => Promise; }; /** * NestJS-narrowed alias for the base {@link AuthHandlerBase} class from * `@decaf-ts/for-http/server`, specializing the execution context to * `ExecutionContext` and the request context to {@link DecafRequestContext}. * * Concrete handlers extend this class and override `extractFromRequest`. * * @example * export class CustomAuthHandler extends AuthHandler { * protected extractFromRequest(request: any) { * const req = ctx.switchToHttp().getRequest(); * const userRole = req.headers.authorization?.split(" ")[1] as string; * if (!userRole) throw new AuthorizationError("Unauthenticated"); * return { user: userRole, roles: [userRole] }; * } * } * * // auth.module.ts * @Global() * @Module({ * providers: [ * AuthInterceptor, * CustomAuthHandler, * { provide: AUTH_HANDLER, useClass: CustomAuthHandler }, * ], * exports: [AUTH_HANDLER, AuthInterceptor], * }) * export class AuthModule {} */ export type AuthHandler = AuthHandlerBase;