fastify 3.27.2 → 4.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +5 -4
  2. package/build/build-error-serializer.js +27 -0
  3. package/build/build-validation.js +47 -35
  4. package/docs/Migration-Guide-V4.md +12 -0
  5. package/docs/Reference/ContentTypeParser.md +4 -0
  6. package/docs/Reference/Errors.md +51 -6
  7. package/docs/Reference/Hooks.md +4 -7
  8. package/docs/Reference/LTS.md +5 -4
  9. package/docs/Reference/Reply.md +23 -22
  10. package/docs/Reference/Request.md +1 -3
  11. package/docs/Reference/Routes.md +17 -10
  12. package/docs/Reference/Server.md +48 -63
  13. package/docs/Reference/TypeScript.md +11 -13
  14. package/docs/Reference/Validation-and-Serialization.md +28 -53
  15. package/docs/Type-Providers.md +257 -0
  16. package/examples/hooks.js +1 -1
  17. package/examples/simple-stream.js +18 -0
  18. package/fastify.d.ts +34 -22
  19. package/fastify.js +37 -35
  20. package/lib/configValidator.js +902 -1023
  21. package/lib/contentTypeParser.js +6 -16
  22. package/lib/context.js +36 -10
  23. package/lib/decorate.js +3 -1
  24. package/lib/error-handler.js +158 -0
  25. package/lib/error-serializer.js +257 -0
  26. package/lib/errors.js +43 -9
  27. package/lib/fourOhFour.js +31 -20
  28. package/lib/handleRequest.js +10 -13
  29. package/lib/hooks.js +14 -9
  30. package/lib/pluginOverride.js +0 -3
  31. package/lib/pluginUtils.js +3 -2
  32. package/lib/reply.js +28 -157
  33. package/lib/request.js +13 -10
  34. package/lib/route.js +131 -138
  35. package/lib/schema-controller.js +2 -2
  36. package/lib/schemas.js +27 -1
  37. package/lib/server.js +219 -116
  38. package/lib/symbols.js +4 -3
  39. package/lib/validation.js +2 -1
  40. package/lib/warnings.js +2 -12
  41. package/lib/wrapThenable.js +4 -11
  42. package/package.json +31 -35
  43. package/test/404s.test.js +243 -110
  44. package/test/500s.test.js +2 -2
  45. package/test/async-await.test.js +13 -69
  46. package/test/content-parser.test.js +32 -0
  47. package/test/context-config.test.js +52 -0
  48. package/test/custom-http-server.test.js +14 -7
  49. package/test/custom-parser-async.test.js +0 -65
  50. package/test/custom-parser.test.js +54 -121
  51. package/test/decorator.test.js +1 -3
  52. package/test/delete.test.js +5 -5
  53. package/test/encapsulated-error-handler.test.js +50 -0
  54. package/test/esm/index.test.js +0 -14
  55. package/test/fastify-instance.test.js +4 -4
  56. package/test/fluent-schema.test.js +4 -4
  57. package/test/get.test.js +3 -3
  58. package/test/helper.js +18 -3
  59. package/test/hooks-async.test.js +14 -47
  60. package/test/hooks.on-ready.test.js +9 -4
  61. package/test/hooks.test.js +58 -99
  62. package/test/http2/closing.test.js +5 -11
  63. package/test/http2/unknown-http-method.test.js +3 -9
  64. package/test/https/custom-https-server.test.js +12 -6
  65. package/test/input-validation.js +2 -2
  66. package/test/internals/handleRequest.test.js +3 -40
  67. package/test/internals/initialConfig.test.js +33 -12
  68. package/test/internals/reply.test.js +245 -3
  69. package/test/internals/request.test.js +13 -7
  70. package/test/internals/server.test.js +88 -0
  71. package/test/listen.test.js +84 -1
  72. package/test/logger.test.js +80 -40
  73. package/test/maxRequestsPerSocket.test.js +6 -4
  74. package/test/middleware.test.js +2 -25
  75. package/test/nullable-validation.test.js +51 -14
  76. package/test/plugin.test.js +31 -5
  77. package/test/pretty-print.test.js +22 -10
  78. package/test/reply-error.test.js +123 -12
  79. package/test/request-error.test.js +2 -5
  80. package/test/route-hooks.test.js +17 -17
  81. package/test/route-prefix.test.js +2 -1
  82. package/test/route.test.js +204 -20
  83. package/test/router-options.test.js +1 -1
  84. package/test/schema-examples.test.js +11 -5
  85. package/test/schema-feature.test.js +24 -19
  86. package/test/schema-serialization.test.js +9 -9
  87. package/test/schema-special-usage.test.js +14 -81
  88. package/test/schema-validation.test.js +9 -9
  89. package/test/skip-reply-send.test.js +1 -1
  90. package/test/stream.test.js +23 -12
  91. package/test/throw.test.js +8 -5
  92. package/test/type-provider.test.js +20 -0
  93. package/test/types/fastify.test-d.ts +10 -18
  94. package/test/types/import.js +2 -0
  95. package/test/types/import.ts +1 -0
  96. package/test/types/instance.test-d.ts +35 -14
  97. package/test/types/logger.test-d.ts +44 -15
  98. package/test/types/route.test-d.ts +8 -2
  99. package/test/types/schema.test-d.ts +2 -39
  100. package/test/types/type-provider.test-d.ts +417 -0
  101. package/test/validation-error-handling.test.js +8 -8
  102. package/test/versioned-routes.test.js +28 -16
  103. package/test/wrapThenable.test.js +7 -6
  104. package/types/content-type-parser.d.ts +17 -8
  105. package/types/hooks.d.ts +102 -59
  106. package/types/instance.d.ts +124 -104
  107. package/types/logger.d.ts +18 -104
  108. package/types/plugin.d.ts +10 -4
  109. package/types/reply.d.ts +16 -11
  110. package/types/request.d.ts +10 -5
  111. package/types/route.d.ts +42 -31
  112. package/types/schema.d.ts +1 -1
  113. package/types/type-provider.d.ts +99 -0
  114. package/types/utils.d.ts +1 -1
  115. package/lib/schema-compilers.js +0 -12
  116. package/test/emit-warning.test.js +0 -166
package/types/plugin.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { FastifyInstance } from './instance'
2
2
  import { RawServerBase, RawRequestDefaultExpression, RawReplyDefaultExpression, RawServerDefault } from './utils'
3
+ import { FastifyTypeProvider, FastifyTypeProviderDefault } from './type-provider'
4
+ import { FastifyLoggerInstance } from './logger'
3
5
 
4
6
  export type FastifyPluginOptions = Record<string, any>
5
7
 
@@ -8,8 +10,8 @@ export type FastifyPluginOptions = Record<string, any>
8
10
  *
9
11
  * Fastify allows the user to extend its functionalities with plugins. A plugin can be a set of routes, a server decorator or whatever. To activate plugins, use the `fastify.register()` method.
10
12
  */
11
- export type FastifyPluginCallback<Options extends FastifyPluginOptions = Record<never, never>, Server extends RawServerBase = RawServerDefault> = (
12
- instance: FastifyInstance<Server, RawRequestDefaultExpression<Server>, RawReplyDefaultExpression<Server>>,
13
+ export type FastifyPluginCallback<Options extends FastifyPluginOptions = Record<never, never>, Server extends RawServerBase = RawServerDefault, TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault> = (
14
+ instance: FastifyInstance<Server, RawRequestDefaultExpression<Server>, RawReplyDefaultExpression<Server>, FastifyLoggerInstance, TypeProvider>,
13
15
  opts: Options,
14
16
  done: (err?: Error) => void
15
17
  ) => void
@@ -19,8 +21,12 @@ export type FastifyPluginCallback<Options extends FastifyPluginOptions = Record<
19
21
  *
20
22
  * Fastify allows the user to extend its functionalities with plugins. A plugin can be a set of routes, a server decorator or whatever. To activate plugins, use the `fastify.register()` method.
21
23
  */
22
- export type FastifyPluginAsync<Options extends FastifyPluginOptions = Record<never, never>, Server extends RawServerBase = RawServerDefault> = (
23
- instance: FastifyInstance<Server, RawRequestDefaultExpression<Server>, RawReplyDefaultExpression<Server>>,
24
+ export type FastifyPluginAsync<
25
+ Options extends FastifyPluginOptions = Record<never, never>,
26
+ Server extends RawServerBase = RawServerDefault,
27
+ TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
28
+ > = (
29
+ instance: FastifyInstance<Server, RawRequestDefaultExpression<Server>, RawReplyDefaultExpression<Server>, FastifyLoggerInstance, TypeProvider>,
24
30
  opts: Options
25
31
  ) => Promise<void>;
26
32
 
package/types/reply.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import { RawReplyDefaultExpression, RawServerBase, RawServerDefault, ContextConfigDefault, RawRequestDefaultExpression, ReplyDefault } from './utils'
2
+ import { FastifyReplyType, ResolveFastifyReplyType, FastifyTypeProvider, FastifyTypeProviderDefault } from './type-provider'
2
3
  import { FastifyContext } from './context'
3
4
  import { FastifyLoggerInstance } from './logger'
4
5
  import { FastifyRequest } from './request'
5
6
  import { RouteGenericInterface } from './route'
6
7
  import { FastifyInstance } from './instance'
8
+ import { FastifySchema } from './schema'
7
9
 
8
10
  export interface ReplyGenericInterface {
9
11
  Reply?: ReplyDefault;
@@ -19,19 +21,22 @@ export interface FastifyReply<
19
21
  RawReply extends RawReplyDefaultExpression<RawServer> = RawReplyDefaultExpression<RawServer>,
20
22
  RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
21
23
  ContextConfig = ContextConfigDefault,
24
+ SchemaCompiler extends FastifySchema = FastifySchema,
25
+ TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
26
+ ReplyType extends FastifyReplyType = ResolveFastifyReplyType<TypeProvider, SchemaCompiler, RouteGeneric>
22
27
  > {
23
28
  raw: RawReply;
24
29
  context: FastifyContext<ContextConfig>;
25
30
  log: FastifyLoggerInstance;
26
- request: FastifyRequest<RouteGeneric, RawServer, RawRequest>;
31
+ request: FastifyRequest<RouteGeneric, RawServer, RawRequest, SchemaCompiler, TypeProvider>;
27
32
  server: FastifyInstance;
28
- code(statusCode: number): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
29
- status(statusCode: number): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
33
+ code(statusCode: number): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
34
+ status(statusCode: number): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
30
35
  statusCode: number;
31
36
  sent: boolean;
32
- send(payload?: RouteGeneric['Reply']): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
33
- header(key: string, value: any): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
34
- headers(values: {[key: string]: any}): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
37
+ send(payload?: ReplyType): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
38
+ header(key: string, value: any): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
39
+ headers(values: {[key: string]: any}): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
35
40
  getHeader(key: string): string | undefined;
36
41
  getHeaders(): {
37
42
  // Node's `getHeaders()` can return numbers and arrays, so they're included here as possible types.
@@ -40,13 +45,13 @@ export interface FastifyReply<
40
45
  removeHeader(key: string): void;
41
46
  hasHeader(key: string): boolean;
42
47
  // Note: should consider refactoring the argument order for redirect. statusCode is optional so it should be after the required url param
43
- redirect(statusCode: number, url: string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
44
- redirect(url: string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
45
- hijack(): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
48
+ redirect(statusCode: number, url: string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
49
+ redirect(url: string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
50
+ hijack(): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
46
51
  callNotFound(): void;
47
52
  getResponseTime(): number;
48
- type(contentType: string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
49
- serializer(fn: (payload: any) => string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
53
+ type(contentType: string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
54
+ serializer(fn: (payload: any) => string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
50
55
  serialize(payload: any): string;
51
56
  then(fulfilled: () => void, rejected: (err: Error) => void): void;
52
57
  }
@@ -2,6 +2,8 @@ import { FastifyLoggerInstance } from './logger'
2
2
  import { ContextConfigDefault, RawServerBase, RawServerDefault, RawRequestDefaultExpression, RequestBodyDefault, RequestQuerystringDefault, RequestParamsDefault, RequestHeadersDefault } from './utils'
3
3
  import { RouteGenericInterface } from './route'
4
4
  import { FastifyInstance } from './instance'
5
+ import { FastifyTypeProvider, FastifyTypeProviderDefault, FastifyRequestType, ResolveFastifyRequestType } from './type-provider'
6
+ import { FastifySchema } from './schema'
5
7
  import { FastifyContext } from './context'
6
8
 
7
9
  export interface RequestGenericInterface {
@@ -19,16 +21,19 @@ export interface FastifyRequest<
19
21
  RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
20
22
  RawServer extends RawServerBase = RawServerDefault,
21
23
  RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
24
+ SchemaCompiler extends FastifySchema = FastifySchema,
25
+ TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
22
26
  ContextConfig = ContextConfigDefault,
27
+ RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>
23
28
  > {
24
29
  id: any;
25
- params: RouteGeneric['Params'];
30
+ params: RequestType['params'];
26
31
  raw: RawRequest;
27
- query: RouteGeneric['Querystring'];
28
- headers: RawRequest['headers'] & RouteGeneric['Headers']; // this enables the developer to extend the existing http(s|2) headers list
32
+ query: RequestType['query'];
33
+ headers: RawRequest['headers'] & RequestType['headers']; // this enables the developer to extend the existing http(s|2) headers list
29
34
  log: FastifyLoggerInstance;
30
35
  server: FastifyInstance;
31
- body: RouteGeneric['Body'];
36
+ body: RequestType['body'];
32
37
  context: FastifyContext<ContextConfig>;
33
38
 
34
39
  /** in order for this to be used the user should ensure they have set the attachValidation option. */
@@ -37,7 +42,7 @@ export interface FastifyRequest<
37
42
  /**
38
43
  * @deprecated Use `raw` property
39
44
  */
40
- readonly req: RawRequest;
45
+ readonly req: RawRequest & RouteGeneric['Headers']; // this enables the developer to extend the existing http(s|2) headers list
41
46
  readonly ip: string;
42
47
  readonly ips?: string[];
43
48
  readonly hostname: string;
package/types/route.d.ts CHANGED
@@ -3,10 +3,11 @@ import { FastifyRequest, RequestGenericInterface } from './request'
3
3
  import { FastifyReply, ReplyGenericInterface } from './reply'
4
4
  import { FastifySchema, FastifySchemaCompiler, FastifySchemaValidationError, FastifySerializerCompiler } from './schema'
5
5
  import { HTTPMethods, RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, ContextConfigDefault } from './utils'
6
- import { LogLevel } from './logger'
7
6
  import { preValidationHookHandler, preHandlerHookHandler, preSerializationHookHandler, onRequestHookHandler, preParsingHookHandler, onResponseHookHandler, onSendHookHandler, onErrorHookHandler, onTimeoutHookHandler } from './hooks'
8
7
  import { FastifyError } from 'fastify-error'
9
8
  import { FastifyContext } from './context'
9
+ import { FastifyTypeProvider, FastifyTypeProviderDefault, ResolveFastifyReplyReturnType } from './type-provider'
10
+ import { FastifyLoggerInstance, LogLevel } from './logger'
10
11
 
11
12
  export interface RouteGenericInterface extends RequestGenericInterface, ReplyGenericInterface {}
12
13
 
@@ -20,10 +21,12 @@ export interface RouteShorthandOptions<
20
21
  RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
21
22
  ContextConfig = ContextConfigDefault,
22
23
  SchemaCompiler = FastifySchema,
24
+ TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
23
25
  > {
24
- schema?: FastifySchema;
26
+ schema?: SchemaCompiler, // originally FastifySchema
25
27
  attachValidation?: boolean;
26
28
  exposeHeadRoute?: boolean;
29
+
27
30
  validatorCompiler?: FastifySchemaCompiler<SchemaCompiler>;
28
31
  serializerCompiler?: FastifySerializerCompiler<SchemaCompiler>;
29
32
  bodyLimit?: number;
@@ -37,15 +40,15 @@ export interface RouteShorthandOptions<
37
40
  schemaErrorFormatter?: (errors: FastifySchemaValidationError[], dataVar: string) => Error;
38
41
 
39
42
  // hooks
40
- onRequest?: onRequestHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig> | onRequestHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>[];
41
- preParsing?: preParsingHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig> | preParsingHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>[];
42
- preValidation?: preValidationHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig> | preValidationHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>[];
43
- preHandler?: preHandlerHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig> | preHandlerHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>[];
44
- preSerialization?: preSerializationHookHandler<unknown, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig> | preSerializationHookHandler<unknown, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>[];
45
- onSend?: onSendHookHandler<unknown, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig> | onSendHookHandler<unknown, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>[];
46
- onResponse?: onResponseHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig> | onResponseHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>[];
47
- onTimeout?: onTimeoutHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig> | onTimeoutHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>[];
48
- onError?: onErrorHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig> | onErrorHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>[];
43
+ onRequest?: onRequestHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> | onRequestHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>[];
44
+ preParsing?: preParsingHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> | preParsingHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>[];
45
+ preValidation?: preValidationHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> | preValidationHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>[];
46
+ preHandler?: preHandlerHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> | preHandlerHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>[];
47
+ preSerialization?: preSerializationHookHandler<unknown, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> | preSerializationHookHandler<unknown, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>[];
48
+ onSend?: onSendHookHandler<unknown, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> | onSendHookHandler<unknown, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>[];
49
+ onResponse?: onResponseHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> | onResponseHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>[];
50
+ onTimeout?: onTimeoutHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> | onTimeoutHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>[];
51
+ onError?: onErrorHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, FastifyError, SchemaCompiler, TypeProvider> | onErrorHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, FastifyError, SchemaCompiler, TypeProvider>[];
49
52
  }
50
53
 
51
54
  /**
@@ -56,12 +59,15 @@ export type RouteHandlerMethod<
56
59
  RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
57
60
  RawReply extends RawReplyDefaultExpression<RawServer> = RawReplyDefaultExpression<RawServer>,
58
61
  RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
59
- ContextConfig = ContextConfigDefault
62
+ ContextConfig = ContextConfigDefault,
63
+ SchemaCompiler extends FastifySchema = FastifySchema,
64
+ TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
65
+ ReturnType = ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>
60
66
  > = (
61
- this: FastifyInstance<RawServer, RawRequest, RawReply>,
62
- request: FastifyRequest<RouteGeneric, RawServer, RawRequest, ContextConfig>,
63
- reply: FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>
64
- ) => void | Promise<RouteGeneric['Reply'] | void>
67
+ this: FastifyInstance<RawServer, RawRequest, RawReply, FastifyLoggerInstance, TypeProvider>,
68
+ request: FastifyRequest<RouteGeneric, RawServer, RawRequest, SchemaCompiler, TypeProvider, ContextConfig>,
69
+ reply: FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>
70
+ ) => ReturnType
65
71
 
66
72
  /**
67
73
  * Shorthand options including the handler function property
@@ -73,8 +79,9 @@ export interface RouteShorthandOptionsWithHandler<
73
79
  RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
74
80
  ContextConfig = ContextConfigDefault,
75
81
  SchemaCompiler = FastifySchema,
76
- > extends RouteShorthandOptions<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler> {
77
- handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
82
+ TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
83
+ > extends RouteShorthandOptions<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> {
84
+ handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
78
85
  }
79
86
 
80
87
  /**
@@ -84,20 +91,21 @@ export interface RouteShorthandMethod<
84
91
  RawServer extends RawServerBase = RawServerDefault,
85
92
  RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
86
93
  RawReply extends RawReplyDefaultExpression<RawServer> = RawReplyDefaultExpression<RawServer>,
94
+ TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
87
95
  > {
88
96
  <RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault, SchemaCompiler = FastifySchema>(
89
97
  path: string,
90
- opts: RouteShorthandOptions<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler>,
91
- handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>
92
- ): FastifyInstance<RawServer, RawRequest, RawReply>;
98
+ opts: RouteShorthandOptions<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>,
99
+ handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>
100
+ ): FastifyInstance<RawServer, RawRequest, RawReply, FastifyLoggerInstance, TypeProvider>;
93
101
  <RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault>(
94
102
  path: string,
95
- handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>
96
- ): FastifyInstance<RawServer, RawRequest, RawReply>;
103
+ handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, FastifySchema, TypeProvider>
104
+ ): FastifyInstance<RawServer, RawRequest, RawReply, FastifyLoggerInstance, TypeProvider>;
97
105
  <RouteGeneric extends RouteGenericInterface = RouteGenericInterface, ContextConfig = ContextConfigDefault, SchemaCompiler = FastifySchema>(
98
106
  path: string,
99
- opts: RouteShorthandOptionsWithHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler>
100
- ): FastifyInstance<RawServer, RawRequest, RawReply>;
107
+ opts: RouteShorthandOptionsWithHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>
108
+ ): FastifyInstance<RawServer, RawRequest, RawReply, FastifyLoggerInstance, TypeProvider>;
101
109
  }
102
110
 
103
111
  /**
@@ -110,10 +118,11 @@ export interface RouteOptions<
110
118
  RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
111
119
  ContextConfig = ContextConfigDefault,
112
120
  SchemaCompiler = FastifySchema,
113
- > extends RouteShorthandOptions<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler> {
121
+ TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
122
+ > extends RouteShorthandOptions<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider> {
114
123
  method: HTTPMethods | HTTPMethods[];
115
124
  url: string;
116
- handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>;
125
+ handler: RouteHandlerMethod<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
117
126
  }
118
127
 
119
128
  export type RouteHandler<
@@ -121,11 +130,13 @@ export type RouteHandler<
121
130
  RawServer extends RawServerBase = RawServerDefault,
122
131
  RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
123
132
  RawReply extends RawReplyDefaultExpression<RawServer> = RawReplyDefaultExpression<RawServer>,
124
- ContextConfig = ContextConfigDefault
133
+ ContextConfig = ContextConfigDefault,
134
+ SchemaCompiler extends FastifySchema = FastifySchema,
135
+ TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
125
136
  > = (
126
- this: FastifyInstance<RawServer, RawRequest, RawReply>,
127
- request: FastifyRequest<RouteGeneric, RawServer, RawRequest>,
128
- reply: FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig>
137
+ this: FastifyInstance<RawServer, RawRequest, RawReply, FastifyLoggerInstance, TypeProvider>,
138
+ request: FastifyRequest<RouteGeneric, RawServer, RawRequest, SchemaCompiler, TypeProvider, ContextConfig>,
139
+ reply: FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>
129
140
  ) => void | Promise<RouteGeneric['Reply'] | void>
130
141
 
131
142
  export type DefaultRoute<Request, Reply> = (
package/types/schema.d.ts CHANGED
@@ -24,7 +24,7 @@ export interface FastifyRouteSchemaDef<T> {
24
24
 
25
25
  export interface FastifySchemaValidationError {
26
26
  message?: string;
27
- dataPath: string;
27
+ instancePath: string;
28
28
  }
29
29
 
30
30
  export interface FastifyValidationResult {
@@ -0,0 +1,99 @@
1
+
2
+ import { RouteGenericInterface } from './route'
3
+ import { FastifySchema } from './schema'
4
+
5
+ // -----------------------------------------------------------------------------------------------
6
+ // TypeProvider
7
+ // -----------------------------------------------------------------------------------------------
8
+
9
+ export interface FastifyTypeProvider {
10
+ readonly input: unknown,
11
+ readonly output: unknown,
12
+ }
13
+
14
+ export interface FastifyTypeProviderDefault extends FastifyTypeProvider {
15
+ output: unknown
16
+ }
17
+
18
+ export type CallTypeProvider<F extends FastifyTypeProvider, I> = (F & { input: I })['output']
19
+
20
+ // -----------------------------------------------------------------------------------------------
21
+ // FastifyRequestType
22
+ // -----------------------------------------------------------------------------------------------
23
+
24
+ // Used to map undefined SchemaCompiler properties to unknown
25
+ type UndefinedToUnknown<T> = T extends undefined ? unknown : T
26
+
27
+ // Resolves Request types either from generic argument or Type Provider.
28
+ type ResolveRequestParams<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
29
+ UndefinedToUnknown<keyof RouteGeneric['Params'] extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['params']> : RouteGeneric['Params']>
30
+ type ResolveRequestQuerystring<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
31
+ UndefinedToUnknown<keyof RouteGeneric['Querystring'] extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['querystring']> : RouteGeneric['Querystring']>
32
+ type ResolveRequestHeaders<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
33
+ UndefinedToUnknown<keyof RouteGeneric['Headers'] extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['headers']> : RouteGeneric['Headers']>
34
+ type ResolveRequestBody<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> =
35
+ UndefinedToUnknown<keyof RouteGeneric['Body'] extends never ? CallTypeProvider<TypeProvider, SchemaCompiler['body']> : RouteGeneric['Body']>
36
+
37
+ // The target request type. This type is inferenced on fastify 'requests' via generic argument assignment
38
+ export interface FastifyRequestType<Params = unknown, Querystring = unknown, Headers = unknown, Body = unknown> {
39
+ params: Params,
40
+ query: Querystring,
41
+ headers: Headers,
42
+ body: Body
43
+ }
44
+
45
+ export type ResolveFastifyRequestType<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> = FastifyRequestType<
46
+ ResolveRequestParams<TypeProvider, SchemaCompiler, RouteGeneric>,
47
+ ResolveRequestQuerystring<TypeProvider, SchemaCompiler, RouteGeneric>,
48
+ ResolveRequestHeaders<TypeProvider, SchemaCompiler, RouteGeneric>,
49
+ ResolveRequestBody<TypeProvider, SchemaCompiler, RouteGeneric>
50
+ >
51
+
52
+ // -----------------------------------------------------------------------------------------------
53
+ // FastifyReplyType
54
+ // -----------------------------------------------------------------------------------------------
55
+
56
+ // Tests if the user has specified a generic argument for Reply
57
+ type UseReplyFromRouteGeneric<RouteGeneric extends RouteGenericInterface> = keyof RouteGeneric['Reply'] extends never ? false : true
58
+
59
+ // Tests if the user has specified a response schema.
60
+ type UseReplyFromSchemaCompiler<SchemaCompiler extends FastifySchema> = keyof SchemaCompiler['response'] extends never ? false : true
61
+
62
+ // Resolves the Reply type from the generic argument
63
+ type ResolveReplyFromRouteGeneric<RouteGeneric extends RouteGenericInterface> = RouteGeneric['Reply']
64
+
65
+ // Resolves the Reply type by taking a union of response status codes
66
+ type ResolveReplyFromSchemaCompiler<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema> = {
67
+ [K in keyof SchemaCompiler['response']]: CallTypeProvider<TypeProvider, SchemaCompiler['response'][K]>
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
71
+ export 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 overriden by users providing a generic Reply type on the route.
76
+ export type ResolveFastifyReplyType<TypeProvider extends FastifyTypeProvider, SchemaCompiler extends FastifySchema, RouteGeneric extends RouteGenericInterface> = FastifyReplyType<
77
+ UseReplyFromRouteGeneric<RouteGeneric> extends true ? ResolveReplyFromRouteGeneric<RouteGeneric> :
78
+ UseReplyFromSchemaCompiler<SchemaCompiler> extends true ? ResolveReplyFromSchemaCompiler<TypeProvider, SchemaCompiler> :
79
+ unknown
80
+ >
81
+
82
+ // -----------------------------------------------------------------------------------------------
83
+ // FastifyReplyReturnType
84
+ // -----------------------------------------------------------------------------------------------
85
+
86
+ // The target reply return type. This type is inferenced on fastify 'routes' via generic argument assignment
87
+ export type ResolveFastifyReplyReturnType<
88
+ TypeProvider extends FastifyTypeProvider,
89
+ SchemaCompiler extends FastifySchema,
90
+ RouteGeneric extends RouteGenericInterface,
91
+ > = ResolveFastifyReplyType<
92
+ TypeProvider,
93
+ SchemaCompiler,
94
+ RouteGeneric
95
+ > extends infer Return ?
96
+ (void | Promise<Return | void>)
97
+ // review: support both async and sync return types
98
+ // (Promise<Return> | Return | Promise<void> | void)
99
+ : unknown
package/types/utils.d.ts CHANGED
@@ -21,7 +21,7 @@ export type RawServerDefault = http.Server
21
21
  * The default request type based on the server type. Utilizes generic constraining.
22
22
  */
23
23
  export type RawRequestDefaultExpression<
24
- RawServer extends RawServerBase = RawServerDefault
24
+ RawServer extends RawServerBase = RawServerDefault,
25
25
  > = RawServer extends http.Server | https.Server ? http.IncomingMessage
26
26
  : RawServer extends http2.Http2Server | http2.Http2SecureServer ? http2.Http2ServerRequest
27
27
  : never
@@ -1,12 +0,0 @@
1
- 'use strict'
2
-
3
- const fastJsonStringify = require('fast-json-stringify')
4
-
5
- function serializerFactory (externalSchemas, serializerOpts) {
6
- const opts = Object.assign({}, serializerOpts, { schema: externalSchemas })
7
- return function responseSchemaCompiler ({ schema /* method, url, httpStatus */ }) {
8
- return fastJsonStringify(schema, opts)
9
- }
10
- }
11
-
12
- module.exports.serializerCompiler = serializerFactory
@@ -1,166 +0,0 @@
1
- 'use strict'
2
-
3
- const sget = require('simple-get').concat
4
- const { test } = require('tap')
5
- const Fastify = require('..')
6
- const semver = require('semver')
7
-
8
- process.removeAllListeners('warning')
9
-
10
- test('Should emit a warning when accessing request.req instead of request.raw', t => {
11
- t.plan(4)
12
-
13
- process.on('warning', onWarning)
14
- function onWarning (warning) {
15
- t.equal(warning.name, 'FastifyDeprecation')
16
- t.equal(warning.code, 'FSTDEP001')
17
- t.equal(warning.message, 'You are accessing the Node.js core request object via "request.req", Use "request.raw" instead.')
18
- }
19
-
20
- const fastify = Fastify()
21
-
22
- fastify.get('/', (request, reply) => {
23
- reply.send(request.req.method + request.req.method)
24
- })
25
-
26
- fastify.inject({
27
- method: 'GET',
28
- path: '/'
29
- }, (err, res) => {
30
- t.error(err)
31
- process.removeListener('warning', onWarning)
32
- })
33
- })
34
-
35
- test('Should emit a warning when accessing reply.res instead of reply.raw', t => {
36
- t.plan(4)
37
-
38
- process.on('warning', onWarning)
39
- function onWarning (warning) {
40
- t.equal(warning.name, 'FastifyDeprecation')
41
- t.equal(warning.code, 'FSTDEP002')
42
- t.equal(warning.message, 'You are accessing the Node.js core response object via "reply.res", Use "reply.raw" instead.')
43
- }
44
-
45
- const fastify = Fastify()
46
-
47
- fastify.get('/', (request, reply) => {
48
- reply.send(reply.res.statusCode + reply.res.statusCode)
49
- })
50
-
51
- fastify.inject({
52
- method: 'GET',
53
- path: '/'
54
- }, (err, res) => {
55
- t.error(err)
56
- process.removeListener('warning', onWarning)
57
- })
58
- })
59
-
60
- test('Should emit a warning when using two arguments Content Type Parser instead of three arguments', t => {
61
- t.plan(7)
62
-
63
- process.on('warning', onWarning)
64
- function onWarning (warning) {
65
- t.equal(warning.name, 'FastifyDeprecation')
66
- t.equal(warning.code, 'FSTDEP003')
67
- t.equal(warning.message, 'You are using the legacy Content Type Parser function signature. Use the one suggested in the documentation instead.')
68
- }
69
-
70
- const fastify = Fastify()
71
-
72
- fastify.addContentTypeParser('x/foo', function (req, done) {
73
- done(null, 'OK')
74
- })
75
-
76
- fastify.post('/', (request, reply) => {
77
- reply.send(request.body)
78
- })
79
-
80
- fastify.listen(0, err => {
81
- t.error(err)
82
-
83
- sget({
84
- method: 'POST',
85
- url: 'http://localhost:' + fastify.server.address().port,
86
- headers: { 'Content-Type': 'x/foo' },
87
- body: '{"hello":"world"}'
88
- }, (err, response, body) => {
89
- t.error(err)
90
- t.equal(response.statusCode, 200)
91
- t.equal(body.toString(), 'OK')
92
- process.removeListener('warning', onWarning)
93
- fastify.close()
94
- })
95
- })
96
- })
97
-
98
- test('Should emit a warning when using payload less preParsing hook', t => {
99
- t.plan(7)
100
-
101
- process.on('warning', onWarning)
102
- function onWarning (warning) {
103
- t.equal(warning.name, 'FastifyDeprecation')
104
- t.equal(warning.code, 'FSTDEP004')
105
- t.equal(warning.message, 'You are using the legacy preParsing hook signature. Use the one suggested in the documentation instead.')
106
- }
107
-
108
- const fastify = Fastify()
109
-
110
- fastify.addHook('preParsing', function (request, reply, done) {
111
- done()
112
- })
113
-
114
- fastify.get('/', (request, reply) => {
115
- reply.send('OK')
116
- })
117
-
118
- fastify.listen(0, err => {
119
- t.error(err)
120
-
121
- sget({
122
- method: 'GET',
123
- url: 'http://localhost:' + fastify.server.address().port
124
- }, (err, response, body) => {
125
- t.error(err)
126
- t.equal(response.statusCode, 200)
127
- t.equal(body.toString(), 'OK')
128
- process.removeListener('warning', onWarning)
129
- fastify.close()
130
- })
131
- })
132
- })
133
-
134
- test('Should emit a warning when accessing request.connection instead of request.socket on Node process greater than 13.0.0', t => {
135
- t.plan(4)
136
-
137
- process.on('warning', onWarning)
138
- function onWarning (warning) {
139
- if (semver.gte(process.versions.node, '13.0.0')) {
140
- t.equal(warning.name, 'FastifyDeprecation')
141
- t.equal(warning.code, 'FSTDEP005')
142
- t.equal(warning.message, 'You are accessing the deprecated "request.connection" property. Use "request.socket" instead.')
143
- } else {
144
- t.equal(warning.name, 'FastifyDeprecationLightMyRequest')
145
- t.equal(warning.code, 'FST_LIGHTMYREQUEST_DEP01')
146
- t.equal(warning.message, 'You are accessing "request.connection", use "request.socket" instead.')
147
- }
148
-
149
- // removed listener before light-my-request emit second warning
150
- process.removeListener('warning', onWarning)
151
- }
152
-
153
- const fastify = Fastify()
154
-
155
- fastify.get('/', (request, reply) => {
156
- reply.send(request.connection)
157
- })
158
-
159
- fastify.inject({
160
- method: 'GET',
161
- path: '/'
162
- }, (err, res) => {
163
- t.error(err)
164
- process.removeListener('warning', onWarning)
165
- })
166
- })