import { RouteGenericInterface } from './route' import { FastifySchema } from './schema' import { RecordKeysToLowercase } from './utils' // ----------------------------------------------------------------------------------------------- // TypeProvider // ----------------------------------------------------------------------------------------------- export interface FastifyTypeProvider { readonly schema: unknown, readonly validator: unknown, readonly serializer: unknown, } export interface FastifyTypeProviderDefault extends FastifyTypeProvider {} export type CallValidatorTypeProvider = (F & { schema: S })['validator'] export type CallSerializerTypeProvider = (F & { schema: S })['serializer'] // ----------------------------------------------------------------------------------------------- // FastifyRequestType // ----------------------------------------------------------------------------------------------- // Used to map undefined SchemaCompiler properties to unknown // Without brackets, UndefinedToUnknown => unknown type UndefinedToUnknown = [T] extends [undefined] ? unknown : T // union-aware keyof operator // keyof ({ a: number} | { b: number}) => never // KeysOf<{a: number} | {b: number}> => "a" | "b" // this exists to allow users to override faulty type-provider logic. type KeysOf = T extends any ? keyof T : never // Resolves Request types either from generic argument or Type Provider. type ResolveRequestParams = UndefinedToUnknown extends never ? CallValidatorTypeProvider : RouteGeneric['Params']> type ResolveRequestQuerystring = UndefinedToUnknown extends never ? CallValidatorTypeProvider : RouteGeneric['Querystring']> type ResolveRequestHeaders = UndefinedToUnknown extends never ? CallValidatorTypeProvider : RouteGeneric['Headers']> type ResolveRequestBody = UndefinedToUnknown extends never ? CallValidatorTypeProvider : RouteGeneric['Body']> // The target request type. This type is inferenced on fastify 'requests' via generic argument assignment export interface FastifyRequestType { params: Params, query: Querystring, headers: Headers, body: Body } // Resolves the FastifyRequest generic parameters export interface ResolveFastifyRequestType extends FastifyRequestType { params: ResolveRequestParams, query: ResolveRequestQuerystring, headers: RecordKeysToLowercase>, body: ResolveRequestBody } // ----------------------------------------------------------------------------------------------- // FastifyReplyType // ----------------------------------------------------------------------------------------------- // Resolves the Reply type by taking a union of response status codes and content-types type ResolveReplyFromSchemaCompiler = { [K1 in keyof SchemaCompiler['response']]: SchemaCompiler['response'][K1] extends { content: { [keyof: string]: { schema: unknown } } } ? ({ [K2 in keyof SchemaCompiler['response'][K1]['content']]: CallSerializerTypeProvider } extends infer Result ? Result[keyof Result] : unknown) : CallSerializerTypeProvider } extends infer Result ? Result[keyof Result] : unknown // The target reply type. This type is inferenced on fastify 'replies' via generic argument assignment export type FastifyReplyType = Reply // Resolves the Reply type either via generic argument or from response schema. This type uses a different // resolution strategy to Requests where the Reply will infer a union of each status code type specified // by the user. The Reply can be explicitly overridden by users providing a generic Reply type on the route. export type ResolveFastifyReplyType = UndefinedToUnknown extends never ? ResolveReplyFromSchemaCompiler : RouteGeneric['Reply']> // ----------------------------------------------------------------------------------------------- // FastifyReplyReturnType // ----------------------------------------------------------------------------------------------- // The target reply return type. This type is inferenced on fastify 'routes' via generic argument assignment export type ResolveFastifyReplyReturnType< TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface > = ResolveFastifyReplyType< TypeProvider, SchemaCompiler, RouteGeneric > extends infer Return ? (Return | void | Promise) // review: support both async and sync return types // (Promise | Return | Promise | void) : unknown /** * This branded type is needed to indicate APIs that return Promise-likes which can * safely "float" (not have rejections handled by calling code). * * Please refer to the following Github issue for more info: * https://github.com/fastify/fastify/issues/5498 */ export type SafePromiseLike = PromiseLike & { __linterBrands: 'SafePromiseLike' }