UNPKG

@whook/whook

Version:

Build strong and efficient REST web services.

163 lines (150 loc) 4.52 kB
import { type ExpressiveJSONSchema } from 'ya-json-schema-types'; import { type OpenAPIExtension, type OpenAPIOperation, PATH_ITEM_METHODS, } from 'ya-open-api-types'; import { type WhookRequestBody, type WhookResponse } from './http.js'; import { type Dependencies, type ServiceInitializer, type ProviderInitializer, } from 'knifecycle'; import { type WhookHandlerWrapper } from './wrappers.js'; import { type WhookEnvironmentsConfig } from '../libs/environments.js'; import { type WhookModuleAsideComponents, type WhookModuleAsideSchemas, } from '../index.js'; export const DEFAULT_ROUTE_CONFIG: WhookRouteConfig = { environments: 'all', private: false, }; export interface WhookBaseRouteConfig { environments?: WhookEnvironmentsConfig; private?: boolean; targetHandler?: string; } // eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface WhookRouteConfig extends WhookBaseRouteConfig {} export interface WhookRouteDefinition { path: `/${string}`; method: (typeof PATH_ITEM_METHODS)[number]; operation: OpenAPIOperation<ExpressiveJSONSchema, OpenAPIExtension> & { operationId: string; }; config?: WhookRouteConfig; } // eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface WhookRouteHandlerExtraParameters {} export type WhookRouteHandlerParameters = ( | object | { body: WhookRequestBody; } ) & { path: Record<string, unknown>; query: Record<string, unknown>; cookies: Record<string, unknown>; headers: Record<string, unknown>; } & WhookRouteHandlerExtraParameters; export type WhookRouteHandler< P extends WhookRouteHandlerParameters = WhookRouteHandlerParameters, D extends WhookRouteDefinition = WhookRouteDefinition, > = (parameters: P, definition?: D) => Promise<WhookResponse>; export type WhookRouteHandlerInitializer< D extends Dependencies = Record<string, unknown>, S extends WhookRouteHandler = WhookRouteHandler, > = ServiceInitializer<D, S> | ProviderInitializer<D, S>; export const ROUTE_ASIDE_COMPONENTS_MAP = { schemas: 'Schema', parameters: 'Parameter', headers: 'Header', requestBodies: 'RequestBody', responses: 'Response', callbacks: 'Callback', } as const; // May allow to type routes files later // https://github.com/nfroidure/whook/issues/196 export interface WhookRouteModule extends WhookModuleAsideSchemas, WhookModuleAsideComponents { default: WhookRouteHandlerInitializer; definition: WhookRouteDefinition; } export type WhookRouteHandlerWrapper<T extends WhookRouteHandler> = WhookHandlerWrapper<T>; export interface WhookRouteTypeDefinition { requestBody?: unknown; responses?: { default?: { headers?: unknown; body?: unknown; }; [key: number]: { headers?: unknown; body?: unknown; }; }; parameters?: { path?: object; query?: object; headers?: object; cookies?: object; }; } export type WhookRouteTypedHandler< T extends WhookRouteTypeDefinition, D extends WhookRouteDefinition, O extends object = object, > = ( parameters: (Partial< NonNullable<T['parameters']>['path'] > extends NonNullable<T['parameters']>['path'] ? { path?: NonNullable<T['parameters']>['path']; } : { path: NonNullable<T['parameters']>['path']; }) & (Partial<NonNullable<T['parameters']>['query']> extends NonNullable< T['parameters'] >['query'] ? { query?: NonNullable<T['parameters']>['query']; } : { query: NonNullable<T['parameters']>['query']; }) & (Partial<NonNullable<T['parameters']>['headers']> extends NonNullable< T['parameters'] >['headers'] ? { headers?: NonNullable<T['parameters']>['headers']; } : { headers: NonNullable<T['parameters']>['headers']; }) & (Partial<NonNullable<T['parameters']>['cookies']> extends NonNullable< T['parameters'] >['cookies'] ? { cookies?: NonNullable<T['parameters']>['cookies']; } : { cookies: NonNullable<T['parameters']>['cookies']; }) & WhookRouteHandlerExtraParameters & (T['requestBody'] extends object | string | number | boolean ? { body: T['requestBody']; options?: O; } : { options?: O }), definition?: D, ) => Promise< { [Status in keyof T['responses']]: { status: Status; } & T['responses'][Status]; }[keyof T['responses']] >;