UNPKG

6 kBTypeScriptView Raw
1import { RouteGenericInterface } from './route'
2import { FastifySchema } from './schema'
3import { RecordKeysToLowercase } from './utils'
4
5// -----------------------------------------------------------------------------------------------
6// TypeProvider
7// -----------------------------------------------------------------------------------------------
8
9export interface FastifyTypeProvider {
10 readonly input: unknown,
11 readonly output: unknown,
12}
13
14// eslint-disable-next-line @typescript-eslint/no-empty-interface
15export interface FastifyTypeProviderDefault extends FastifyTypeProvider {}
16
17export type CallTypeProvider<F extends FastifyTypeProvider, I> = (F & { input: I })['output']
18
19// -----------------------------------------------------------------------------------------------
20// FastifyRequestType
21// -----------------------------------------------------------------------------------------------
22
23// Used to map undefined SchemaCompiler properties to unknown
24// Without brackets, UndefinedToUnknown<undefined | null> => unknown
25type UndefinedToUnknown<T> = [T] extends [undefined] ? unknown : T
26
27// union-aware keyof operator
28// keyof ({ a: number} | { b: number}) => never
29// KeysOf<{a: number} | {b: number}> => "a" | "b"
30// this exists to allow users to override faulty type-provider logic.
31type KeysOf<T> = T extends any ? keyof T : never
32
33// Resolves Request types either from generic argument or Type Provider.
34type ResolveRequestParams<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
35 UndefinedToUnknown<KeysOf<RouteGeneric['Params']> extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['params']> : RouteGeneric['Params']>
36type ResolveRequestQuerystring<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
37 UndefinedToUnknown<KeysOf<RouteGeneric['Querystring']> extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['querystring']> : RouteGeneric['Querystring']>
38type ResolveRequestHeaders<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
39 UndefinedToUnknown<KeysOf<RouteGeneric['Headers']> extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['headers']> : RouteGeneric['Headers']>
40type ResolveRequestBody<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
41 UndefinedToUnknown<KeysOf<RouteGeneric['Body']> extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['body']> : RouteGeneric['Body']>
42
43// The target request type. This type is inferenced on fastify 'requests' via generic argument assignment
44export interface FastifyRequestType<Params = unknown, Querystring = unknown, Headers = unknown, Body = unknown> {
45 params: Params,
46 query: Querystring,
47 headers: Headers,
48 body: Body
49}
50
51// Resolves the FastifyRequest generic parameters
52export interface ResolveFastifyRequestType<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> extends FastifyRequestType {
53 params: ResolveRequestParams<TypeProvider, SchemaCompiler, RouteGeneric>,
54 query: ResolveRequestQuerystring<TypeProvider, SchemaCompiler, RouteGeneric>,
55 headers: RecordKeysToLowercase<ResolveRequestHeaders<TypeProvider, SchemaCompiler, RouteGeneric>>,
56 body: ResolveRequestBody<TypeProvider, SchemaCompiler, RouteGeneric>
57}
58
59// -----------------------------------------------------------------------------------------------
60// FastifyReplyType
61// -----------------------------------------------------------------------------------------------
62
63// Resolves the Reply type by taking a union of response status codes and content-types
64type ResolveReplyFromSchemaCompiler<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema> = {
65 [K1 in keyof SchemaCompiler['response']]: SchemaCompiler['response'][K1] extends { content: { [keyof: string]: { schema: unknown } } } ? ({
66 [K2 in keyof SchemaCompiler['response'][K1]['content']]: CallTypeProvider<TypeProvider, SchemaCompiler['response'][K1]['content'][K2]['schema']>
67 } extends infer Result ? Result[keyof Result] : unknown) : CallTypeProvider<TypeProvider, SchemaCompiler['response'][K1]>
68} extends infer Result ? Result[keyof Result] : unknown;
69
70// The target reply type. This type is inferenced on fastify 'replies' via generic argument assignment
71export type FastifyReplyType<Reply = unknown> = Reply
72
73// Resolves the Reply type either via generic argument or from response schema. This type uses a different
74// resolution strategy to Requests where the Reply will infer a union of each status code type specified
75// by the user. The Reply can be explicitly overridden by users providing a generic Reply type on the route.
76export type ResolveFastifyReplyType<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> = UndefinedToUnknown<KeysOf<RouteGeneric['Reply']> extends never ? ResolveReplyFromSchemaCompiler<TypeProvider, SchemaCompiler> : RouteGeneric['Reply']>
77
78// -----------------------------------------------------------------------------------------------
79// FastifyReplyReturnType
80// -----------------------------------------------------------------------------------------------
81
82// The target reply return type. This type is inferenced on fastify 'routes' via generic argument assignment
83export type ResolveFastifyReplyReturnType<
84 TypeProvider extends FastifyTypeProvider,
85 SchemaCompiler extends FastifySchema,
86 RouteGeneric extends RouteGenericInterface,
87> = ResolveFastifyReplyType<
88TypeProvider,
89SchemaCompiler,
90RouteGeneric
91> extends infer Return ?
92 (Return | void | Promise<Return | void>)
93// review: support both async and sync return types
94// (Promise<Return> | Return | Promise<void> | void)
95 : unknown