node-fastify 5.8.3

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 (354) hide show
  1. package/.borp.yaml +3 -0
  2. package/.markdownlint-cli2.yaml +22 -0
  3. package/.prettierignore +1 -0
  4. package/GOVERNANCE.md +4 -0
  5. package/LICENSE +21 -0
  6. package/PROJECT_CHARTER.md +126 -0
  7. package/README.md +423 -0
  8. package/SECURITY.md +220 -0
  9. package/SPONSORS.md +24 -0
  10. package/build/build-error-serializer.js +35 -0
  11. package/build/build-validation.js +169 -0
  12. package/build/sync-version.js +11 -0
  13. package/docs/Guides/Benchmarking.md +60 -0
  14. package/docs/Guides/Database.md +321 -0
  15. package/docs/Guides/Delay-Accepting-Requests.md +608 -0
  16. package/docs/Guides/Detecting-When-Clients-Abort.md +172 -0
  17. package/docs/Guides/Ecosystem.md +726 -0
  18. package/docs/Guides/Fluent-Schema.md +127 -0
  19. package/docs/Guides/Getting-Started.md +620 -0
  20. package/docs/Guides/Index.md +43 -0
  21. package/docs/Guides/Migration-Guide-V3.md +287 -0
  22. package/docs/Guides/Migration-Guide-V4.md +267 -0
  23. package/docs/Guides/Migration-Guide-V5.md +727 -0
  24. package/docs/Guides/Plugins-Guide.md +520 -0
  25. package/docs/Guides/Prototype-Poisoning.md +383 -0
  26. package/docs/Guides/Recommendations.md +378 -0
  27. package/docs/Guides/Serverless.md +604 -0
  28. package/docs/Guides/Style-Guide.md +246 -0
  29. package/docs/Guides/Testing.md +481 -0
  30. package/docs/Guides/Write-Plugin.md +103 -0
  31. package/docs/Guides/Write-Type-Provider.md +34 -0
  32. package/docs/Reference/ContentTypeParser.md +271 -0
  33. package/docs/Reference/Decorators.md +436 -0
  34. package/docs/Reference/Encapsulation.md +194 -0
  35. package/docs/Reference/Errors.md +377 -0
  36. package/docs/Reference/HTTP2.md +94 -0
  37. package/docs/Reference/Hooks.md +958 -0
  38. package/docs/Reference/Index.md +73 -0
  39. package/docs/Reference/LTS.md +86 -0
  40. package/docs/Reference/Lifecycle.md +99 -0
  41. package/docs/Reference/Logging.md +268 -0
  42. package/docs/Reference/Middleware.md +79 -0
  43. package/docs/Reference/Plugins.md +245 -0
  44. package/docs/Reference/Principles.md +73 -0
  45. package/docs/Reference/Reply.md +1001 -0
  46. package/docs/Reference/Request.md +295 -0
  47. package/docs/Reference/Routes.md +802 -0
  48. package/docs/Reference/Server.md +2389 -0
  49. package/docs/Reference/Type-Providers.md +256 -0
  50. package/docs/Reference/TypeScript.md +1729 -0
  51. package/docs/Reference/Validation-and-Serialization.md +1130 -0
  52. package/docs/Reference/Warnings.md +58 -0
  53. package/docs/index.md +24 -0
  54. package/docs/resources/encapsulation_context.drawio +1 -0
  55. package/docs/resources/encapsulation_context.svg +3 -0
  56. package/eslint.config.js +35 -0
  57. package/examples/asyncawait.js +38 -0
  58. package/examples/benchmark/body.json +3 -0
  59. package/examples/benchmark/hooks-benchmark-async-await.js +44 -0
  60. package/examples/benchmark/hooks-benchmark.js +52 -0
  61. package/examples/benchmark/parser.js +47 -0
  62. package/examples/benchmark/simple.js +30 -0
  63. package/examples/benchmark/webstream.js +27 -0
  64. package/examples/hooks.js +91 -0
  65. package/examples/http2.js +39 -0
  66. package/examples/https.js +38 -0
  67. package/examples/parser.js +53 -0
  68. package/examples/plugin.js +12 -0
  69. package/examples/route-prefix.js +38 -0
  70. package/examples/shared-schema.js +38 -0
  71. package/examples/simple-stream.js +20 -0
  72. package/examples/simple.js +32 -0
  73. package/examples/simple.mjs +27 -0
  74. package/examples/typescript-server.ts +79 -0
  75. package/examples/use-plugin.js +29 -0
  76. package/fastify.d.ts +253 -0
  77. package/fastify.js +985 -0
  78. package/integration/server.js +29 -0
  79. package/integration/test.sh +23 -0
  80. package/lib/config-validator.js +1266 -0
  81. package/lib/content-type-parser.js +413 -0
  82. package/lib/content-type.js +160 -0
  83. package/lib/context.js +98 -0
  84. package/lib/decorate.js +152 -0
  85. package/lib/error-handler.js +173 -0
  86. package/lib/error-serializer.js +134 -0
  87. package/lib/error-status.js +14 -0
  88. package/lib/errors.js +516 -0
  89. package/lib/four-oh-four.js +190 -0
  90. package/lib/handle-request.js +195 -0
  91. package/lib/head-route.js +45 -0
  92. package/lib/hooks.js +429 -0
  93. package/lib/initial-config-validation.js +37 -0
  94. package/lib/logger-factory.js +136 -0
  95. package/lib/logger-pino.js +68 -0
  96. package/lib/noop-set.js +10 -0
  97. package/lib/plugin-override.js +90 -0
  98. package/lib/plugin-utils.js +169 -0
  99. package/lib/promise.js +23 -0
  100. package/lib/reply.js +1030 -0
  101. package/lib/req-id-gen-factory.js +52 -0
  102. package/lib/request.js +391 -0
  103. package/lib/route.js +686 -0
  104. package/lib/schema-controller.js +164 -0
  105. package/lib/schemas.js +207 -0
  106. package/lib/server.js +441 -0
  107. package/lib/symbols.js +71 -0
  108. package/lib/validation.js +280 -0
  109. package/lib/warnings.js +57 -0
  110. package/lib/wrap-thenable.js +84 -0
  111. package/package.json +225 -0
  112. package/scripts/validate-ecosystem-links.js +179 -0
  113. package/test/404s.test.js +2035 -0
  114. package/test/500s.test.js +422 -0
  115. package/test/allow-unsafe-regex.test.js +92 -0
  116. package/test/als.test.js +65 -0
  117. package/test/async-await.test.js +705 -0
  118. package/test/async-dispose.test.js +20 -0
  119. package/test/async_hooks.test.js +52 -0
  120. package/test/body-limit.test.js +224 -0
  121. package/test/buffer.test.js +74 -0
  122. package/test/build/error-serializer.test.js +36 -0
  123. package/test/build/version.test.js +14 -0
  124. package/test/build-certificate.js +109 -0
  125. package/test/bundler/README.md +29 -0
  126. package/test/bundler/esbuild/bundler-test.js +32 -0
  127. package/test/bundler/esbuild/package.json +10 -0
  128. package/test/bundler/esbuild/src/fail-plugin-version.js +14 -0
  129. package/test/bundler/esbuild/src/index.js +9 -0
  130. package/test/bundler/webpack/bundler-test.js +32 -0
  131. package/test/bundler/webpack/package.json +11 -0
  132. package/test/bundler/webpack/src/fail-plugin-version.js +14 -0
  133. package/test/bundler/webpack/src/index.js +9 -0
  134. package/test/bundler/webpack/webpack.config.js +15 -0
  135. package/test/case-insensitive.test.js +102 -0
  136. package/test/chainable.test.js +40 -0
  137. package/test/child-logger-factory.test.js +128 -0
  138. package/test/client-timeout.test.js +38 -0
  139. package/test/close-pipelining.test.js +78 -0
  140. package/test/close.test.js +706 -0
  141. package/test/conditional-pino.test.js +47 -0
  142. package/test/connection-timeout.test.js +42 -0
  143. package/test/constrained-routes.test.js +1138 -0
  144. package/test/content-length.test.js +174 -0
  145. package/test/content-parser.test.js +739 -0
  146. package/test/content-type.test.js +181 -0
  147. package/test/context-config.test.js +164 -0
  148. package/test/custom-http-server.test.js +118 -0
  149. package/test/custom-parser-async.test.js +59 -0
  150. package/test/custom-parser.0.test.js +701 -0
  151. package/test/custom-parser.1.test.js +266 -0
  152. package/test/custom-parser.2.test.js +91 -0
  153. package/test/custom-parser.3.test.js +208 -0
  154. package/test/custom-parser.4.test.js +218 -0
  155. package/test/custom-parser.5.test.js +130 -0
  156. package/test/custom-querystring-parser.test.js +129 -0
  157. package/test/decorator.test.js +1330 -0
  158. package/test/delete.test.js +344 -0
  159. package/test/diagnostics-channel/404.test.js +49 -0
  160. package/test/diagnostics-channel/async-delay-request.test.js +65 -0
  161. package/test/diagnostics-channel/async-request.test.js +64 -0
  162. package/test/diagnostics-channel/error-before-handler.test.js +35 -0
  163. package/test/diagnostics-channel/error-request.test.js +53 -0
  164. package/test/diagnostics-channel/error-status.test.js +123 -0
  165. package/test/diagnostics-channel/init.test.js +50 -0
  166. package/test/diagnostics-channel/sync-delay-request.test.js +49 -0
  167. package/test/diagnostics-channel/sync-request-reply.test.js +51 -0
  168. package/test/diagnostics-channel/sync-request.test.js +54 -0
  169. package/test/encapsulated-child-logger-factory.test.js +69 -0
  170. package/test/encapsulated-error-handler.test.js +237 -0
  171. package/test/esm/errorCodes.test.mjs +10 -0
  172. package/test/esm/esm.test.mjs +13 -0
  173. package/test/esm/index.test.js +8 -0
  174. package/test/esm/named-exports.mjs +14 -0
  175. package/test/esm/other.mjs +8 -0
  176. package/test/esm/plugin.mjs +8 -0
  177. package/test/fastify-instance.test.js +300 -0
  178. package/test/find-route.test.js +152 -0
  179. package/test/fluent-schema.test.js +209 -0
  180. package/test/genReqId.test.js +426 -0
  181. package/test/handler-context.test.js +45 -0
  182. package/test/handler-timeout.test.js +367 -0
  183. package/test/has-route.test.js +88 -0
  184. package/test/header-overflow.test.js +55 -0
  185. package/test/helper.js +496 -0
  186. package/test/hooks-async.test.js +1099 -0
  187. package/test/hooks.on-listen.test.js +1162 -0
  188. package/test/hooks.on-ready.test.js +421 -0
  189. package/test/hooks.test.js +3578 -0
  190. package/test/http-methods/copy.test.js +35 -0
  191. package/test/http-methods/custom-http-methods.test.js +114 -0
  192. package/test/http-methods/get.test.js +412 -0
  193. package/test/http-methods/head.test.js +263 -0
  194. package/test/http-methods/lock.test.js +108 -0
  195. package/test/http-methods/mkcalendar.test.js +143 -0
  196. package/test/http-methods/mkcol.test.js +35 -0
  197. package/test/http-methods/move.test.js +42 -0
  198. package/test/http-methods/propfind.test.js +136 -0
  199. package/test/http-methods/proppatch.test.js +105 -0
  200. package/test/http-methods/report.test.js +142 -0
  201. package/test/http-methods/search.test.js +233 -0
  202. package/test/http-methods/trace.test.js +21 -0
  203. package/test/http-methods/unlock.test.js +38 -0
  204. package/test/http2/closing.test.js +270 -0
  205. package/test/http2/constraint.test.js +109 -0
  206. package/test/http2/head.test.js +34 -0
  207. package/test/http2/plain.test.js +68 -0
  208. package/test/http2/secure-with-fallback.test.js +113 -0
  209. package/test/http2/secure.test.js +67 -0
  210. package/test/http2/unknown-http-method.test.js +34 -0
  211. package/test/https/custom-https-server.test.js +58 -0
  212. package/test/https/https.test.js +136 -0
  213. package/test/imports.test.js +17 -0
  214. package/test/inject.test.js +502 -0
  215. package/test/input-validation.js +335 -0
  216. package/test/internals/all.test.js +38 -0
  217. package/test/internals/content-type-parser.test.js +111 -0
  218. package/test/internals/context.test.js +31 -0
  219. package/test/internals/decorator.test.js +156 -0
  220. package/test/internals/errors.test.js +982 -0
  221. package/test/internals/handle-request.test.js +270 -0
  222. package/test/internals/hook-runner.test.js +449 -0
  223. package/test/internals/hooks.test.js +96 -0
  224. package/test/internals/initial-config.test.js +383 -0
  225. package/test/internals/logger.test.js +163 -0
  226. package/test/internals/plugin.test.js +170 -0
  227. package/test/internals/promise.test.js +63 -0
  228. package/test/internals/reply-serialize.test.js +714 -0
  229. package/test/internals/reply.test.js +1920 -0
  230. package/test/internals/req-id-gen-factory.test.js +133 -0
  231. package/test/internals/request-validate.test.js +1402 -0
  232. package/test/internals/request.test.js +506 -0
  233. package/test/internals/schema-controller-perf.test.js +40 -0
  234. package/test/internals/server.test.js +91 -0
  235. package/test/internals/validation.test.js +352 -0
  236. package/test/issue-4959.test.js +118 -0
  237. package/test/keep-alive-timeout.test.js +42 -0
  238. package/test/listen.1.test.js +154 -0
  239. package/test/listen.2.test.js +113 -0
  240. package/test/listen.3.test.js +83 -0
  241. package/test/listen.4.test.js +168 -0
  242. package/test/listen.5.test.js +122 -0
  243. package/test/logger/instantiation.test.js +341 -0
  244. package/test/logger/logger-test-utils.js +47 -0
  245. package/test/logger/logging.test.js +460 -0
  246. package/test/logger/options.test.js +579 -0
  247. package/test/logger/request.test.js +292 -0
  248. package/test/logger/response.test.js +183 -0
  249. package/test/logger/tap-parallel-not-ok +0 -0
  250. package/test/max-requests-per-socket.test.js +113 -0
  251. package/test/middleware.test.js +37 -0
  252. package/test/noop-set.test.js +19 -0
  253. package/test/nullable-validation.test.js +187 -0
  254. package/test/options.error-handler.test.js +5 -0
  255. package/test/options.test.js +5 -0
  256. package/test/output-validation.test.js +140 -0
  257. package/test/patch.error-handler.test.js +5 -0
  258. package/test/patch.test.js +5 -0
  259. package/test/plugin.1.test.js +230 -0
  260. package/test/plugin.2.test.js +314 -0
  261. package/test/plugin.3.test.js +287 -0
  262. package/test/plugin.4.test.js +504 -0
  263. package/test/plugin.helper.js +8 -0
  264. package/test/plugin.name.display.js +10 -0
  265. package/test/post-empty-body.test.js +38 -0
  266. package/test/pretty-print.test.js +366 -0
  267. package/test/promises.test.js +125 -0
  268. package/test/proto-poisoning.test.js +145 -0
  269. package/test/put.error-handler.test.js +5 -0
  270. package/test/put.test.js +5 -0
  271. package/test/register.test.js +184 -0
  272. package/test/reply-code.test.js +148 -0
  273. package/test/reply-early-hints.test.js +100 -0
  274. package/test/reply-error.test.js +815 -0
  275. package/test/reply-trailers.test.js +445 -0
  276. package/test/reply-web-stream-locked.test.js +37 -0
  277. package/test/request-error.test.js +624 -0
  278. package/test/request-header-host.test.js +339 -0
  279. package/test/request-id.test.js +118 -0
  280. package/test/request-timeout.test.js +53 -0
  281. package/test/route-hooks.test.js +635 -0
  282. package/test/route-prefix.test.js +904 -0
  283. package/test/route-shorthand.test.js +48 -0
  284. package/test/route.1.test.js +259 -0
  285. package/test/route.2.test.js +100 -0
  286. package/test/route.3.test.js +213 -0
  287. package/test/route.4.test.js +127 -0
  288. package/test/route.5.test.js +211 -0
  289. package/test/route.6.test.js +306 -0
  290. package/test/route.7.test.js +406 -0
  291. package/test/route.8.test.js +225 -0
  292. package/test/router-options.test.js +1108 -0
  293. package/test/same-shape.test.js +124 -0
  294. package/test/schema-examples.test.js +661 -0
  295. package/test/schema-feature.test.js +2198 -0
  296. package/test/schema-serialization.test.js +1171 -0
  297. package/test/schema-special-usage.test.js +1348 -0
  298. package/test/schema-validation.test.js +1572 -0
  299. package/test/scripts/validate-ecosystem-links.test.js +339 -0
  300. package/test/serialize-response.test.js +186 -0
  301. package/test/server.test.js +347 -0
  302. package/test/set-error-handler.test.js +69 -0
  303. package/test/skip-reply-send.test.js +317 -0
  304. package/test/stream-serializers.test.js +40 -0
  305. package/test/stream.1.test.js +94 -0
  306. package/test/stream.2.test.js +129 -0
  307. package/test/stream.3.test.js +198 -0
  308. package/test/stream.4.test.js +176 -0
  309. package/test/stream.5.test.js +188 -0
  310. package/test/sync-routes.test.js +32 -0
  311. package/test/throw.test.js +359 -0
  312. package/test/toolkit.js +63 -0
  313. package/test/trust-proxy.test.js +162 -0
  314. package/test/type-provider.test.js +22 -0
  315. package/test/types/content-type-parser.test-d.ts +72 -0
  316. package/test/types/decorate-request-reply.test-d.ts +18 -0
  317. package/test/types/dummy-plugin.ts +9 -0
  318. package/test/types/errors.test-d.ts +90 -0
  319. package/test/types/fastify.test-d.ts +352 -0
  320. package/test/types/hooks.test-d.ts +550 -0
  321. package/test/types/import.ts +2 -0
  322. package/test/types/instance.test-d.ts +588 -0
  323. package/test/types/logger.test-d.ts +277 -0
  324. package/test/types/plugin.test-d.ts +97 -0
  325. package/test/types/register.test-d.ts +237 -0
  326. package/test/types/reply.test-d.ts +254 -0
  327. package/test/types/request.test-d.ts +188 -0
  328. package/test/types/route.test-d.ts +553 -0
  329. package/test/types/schema.test-d.ts +135 -0
  330. package/test/types/serverFactory.test-d.ts +37 -0
  331. package/test/types/type-provider.test-d.ts +1213 -0
  332. package/test/types/using.test-d.ts +17 -0
  333. package/test/upgrade.test.js +52 -0
  334. package/test/url-rewriting.test.js +122 -0
  335. package/test/use-semicolon-delimiter.test.js +168 -0
  336. package/test/validation-error-handling.test.js +900 -0
  337. package/test/versioned-routes.test.js +603 -0
  338. package/test/web-api.test.js +616 -0
  339. package/test/wrap-thenable.test.js +30 -0
  340. package/types/content-type-parser.d.ts +75 -0
  341. package/types/context.d.ts +22 -0
  342. package/types/errors.d.ts +92 -0
  343. package/types/hooks.d.ts +875 -0
  344. package/types/instance.d.ts +609 -0
  345. package/types/logger.d.ts +107 -0
  346. package/types/plugin.d.ts +44 -0
  347. package/types/register.d.ts +42 -0
  348. package/types/reply.d.ts +81 -0
  349. package/types/request.d.ts +95 -0
  350. package/types/route.d.ts +199 -0
  351. package/types/schema.d.ts +61 -0
  352. package/types/server-factory.d.ts +19 -0
  353. package/types/type-provider.d.ts +130 -0
  354. package/types/utils.d.ts +98 -0
@@ -0,0 +1,103 @@
1
+ <h1 style="text-align: center;">Fastify</h1>
2
+
3
+ # How to write a good plugin
4
+ First, thank you for deciding to write a plugin for Fastify. Fastify is a
5
+ minimal framework and plugins are its strength, so thank you.
6
+
7
+ The core principles of Fastify are performance, low overhead, and providing a
8
+ good experience to our users. When writing a plugin, it is important to keep
9
+ these principles in mind. Therefore, in this document, we will analyze what
10
+ characterizes a quality plugin.
11
+
12
+ *Need some inspiration? You can use the label ["plugin
13
+ suggestion"](https://github.com/fastify/fastify/issues?q=is%3Aissue+is%3Aopen+label%3A%22plugin+suggestion%22)
14
+ in our issue tracker!*
15
+
16
+ ## Code
17
+ Fastify uses different techniques to optimize its code, many of which are
18
+ documented in our Guides. We highly recommend you read [the hitchhiker's guide
19
+ to plugins](./Plugins-Guide.md) to discover all the APIs you can use to build
20
+ your plugin and learn how to use them.
21
+
22
+ Do you have a question or need some advice? We are more than happy to help you!
23
+ Just open an issue in our [help repository](https://github.com/fastify/help).
24
+
25
+ Once you submit a plugin to our [ecosystem list](./Ecosystem.md), we will review
26
+ your code and help you improve it if necessary.
27
+
28
+ ## Documentation
29
+ Documentation is extremely important. If your plugin is not well documented we
30
+ will not accept it to the ecosystem list. Lack of quality documentation makes it
31
+ more difficult for people to use your plugin, and will likely result in it going
32
+ unused.
33
+
34
+ If you want to see some good examples of how to document a plugin take a look
35
+ at:
36
+ - [`@fastify/caching`](https://github.com/fastify/fastify-caching)
37
+ - [`@fastify/compress`](https://github.com/fastify/fastify-compress)
38
+ - [`@fastify/cookie`](https://github.com/fastify/fastify-cookie)
39
+ - [`@fastify/under-pressure`](https://github.com/fastify/under-pressure)
40
+ - [`@fastify/view`](https://github.com/fastify/point-of-view)
41
+
42
+ ## License
43
+ You can license your plugin as you prefer, we do not enforce any kind of
44
+ license.
45
+
46
+ We prefer the [MIT license](https://choosealicense.com/licenses/mit/) because we
47
+ think it allows more people to use the code freely. For a list of alternative
48
+ licenses see the [OSI list](https://opensource.org/licenses) or GitHub's
49
+ [choosealicense.com](https://choosealicense.com/).
50
+
51
+ ## Examples
52
+ Always put an example file in your repository. Examples are very helpful for
53
+ users and give a very fast way to test your plugin. Your users will be grateful.
54
+
55
+ ## Test
56
+ A plugin **must** be thoroughly tested to verify that is working properly.
57
+
58
+ A plugin without tests will not be accepted to the ecosystem list. A lack of
59
+ tests does not inspire trust nor guarantee that the code will continue to work
60
+ among different versions of its dependencies.
61
+
62
+ We do not enforce any testing library. We use [`node:test`](https://nodejs.org/api/test.html)
63
+ since it offers out-of-the-box parallel testing and code coverage, but it is up
64
+ to you to choose your library of preference.
65
+ We highly recommend you read the [Plugin Testing](./Testing.md#plugins) to
66
+ learn about how to test your plugins.
67
+
68
+ ## Code Linter
69
+ It is not mandatory, but we highly recommend you use a code linter in your
70
+ plugin. It will ensure a consistent code style and help you to avoid many
71
+ errors.
72
+
73
+ We use [`standard`](https://standardjs.com/) since it works without the need to
74
+ configure it and is very easy to integrate into a test suite.
75
+
76
+ ## Continuous Integration
77
+ It is not mandatory, but if you release your code as open source, it helps to
78
+ use Continuous Integration to ensure contributions do not break your plugin and
79
+ to show that the plugin works as intended. Both
80
+ [CircleCI](https://circleci.com/) and [GitHub
81
+ Actions](https://github.com/features/actions) are free for open source projects
82
+ and easy to set up.
83
+
84
+ In addition, you can enable services like [Dependabot](https://github.com/dependabot),
85
+ which will help you keep your dependencies up to date and discover if a new
86
+ release of Fastify has some issues with your plugin.
87
+
88
+ ## Let's start!
89
+ Awesome, now you know everything you need to know about how to write a good
90
+ plugin for Fastify! After you have built one (or more!) let us know! We will add
91
+ it to the [ecosystem](https://github.com/fastify/fastify#ecosystem) section of
92
+ our documentation!
93
+
94
+ If you want to see some real world examples, check out:
95
+ - [`@fastify/view`](https://github.com/fastify/point-of-view) Templates
96
+ rendering (*ejs, pug, handlebars, marko*) plugin support for Fastify.
97
+ - [`@fastify/mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
98
+ MongoDB connection plugin, with this you can share the same MongoDB connection
99
+ pool in every part of your server.
100
+ - [`@fastify/multipart`](https://github.com/fastify/fastify-multipart) Multipart
101
+ support for Fastify.
102
+ - [`@fastify/helmet`](https://github.com/fastify/fastify-helmet) Important
103
+ security headers for Fastify.
@@ -0,0 +1,34 @@
1
+ <h1 align="center">Fastify</h1>
2
+
3
+ ## How to write your own type provider
4
+
5
+ Things to keep in mind when implementing a custom [type provider](../Reference/Type-Providers.md):
6
+
7
+ ### Type Contravariance
8
+
9
+ Whereas exhaustive type narrowing checks normally rely on `never` to represent
10
+ an unreachable state, reduction in type provider interfaces should only be done
11
+ up to `unknown`.
12
+
13
+ The reasoning is that certain methods of `FastifyInstance` are
14
+ contravariant on `TypeProvider`, which can lead to TypeScript surfacing
15
+ assignability issues unless the custom type provider interface is
16
+ substitutable with `FastifyTypeProviderDefault`.
17
+
18
+ For example, `FastifyTypeProviderDefault` will not be assignable to the following:
19
+ ```ts
20
+ export interface NotSubstitutableTypeProvider extends FastifyTypeProvider {
21
+ // bad, nothing is assignable to `never` (except for itself)
22
+ validator: this['schema'] extends /** custom check here**/ ? /** narrowed type here **/ : never;
23
+ serializer: this['schema'] extends /** custom check here**/ ? /** narrowed type here **/ : never;
24
+ }
25
+ ```
26
+
27
+ Unless changed to:
28
+ ```ts
29
+ export interface SubstitutableTypeProvider extends FastifyTypeProvider {
30
+ // good, anything can be assigned to `unknown`
31
+ validator: this['schema'] extends /** custom check here**/ ? /** narrowed type here **/ : unknown;
32
+ serializer: this['schema'] extends /** custom check here**/ ? /** narrowed type here **/ : unknown;
33
+ }
34
+ ```
@@ -0,0 +1,271 @@
1
+ <h1 align="center">Fastify</h1>
2
+
3
+ ## `Content-Type` Parser
4
+ Fastify natively supports `'application/json'` and `'text/plain'` content types
5
+ with a default charset of `utf-8`. These default parsers can be changed or
6
+ removed.
7
+
8
+ Unsupported content types will throw an `FST_ERR_CTP_INVALID_MEDIA_TYPE` error.
9
+
10
+ To support other content types, use the `addContentTypeParser` API or an
11
+ existing [plugin](https://fastify.dev/ecosystem/).
12
+
13
+ As with other APIs, `addContentTypeParser` is encapsulated in the scope in which
14
+ it is declared. If declared in the root scope, it is available everywhere; if
15
+ declared in a plugin, it is available only in that scope and its children.
16
+
17
+ Fastify automatically adds the parsed request payload to the [Fastify
18
+ request](./Request.md) object, accessible via `request.body`.
19
+
20
+ > **Important:** When using a body schema with the
21
+ > [`content`](./Validation-and-Serialization.md#body-content-type-validation)
22
+ > property to validate per content type, only content types listed in the schema
23
+ > will be validated. If you add a custom content type parser but do not include
24
+ > its content type in the body schema's `content` property, the incoming data
25
+ > will be parsed but **not validated**.
26
+
27
+ Note that for `GET` and `HEAD` requests, the payload is never parsed. For
28
+ `OPTIONS` and `DELETE` requests, the payload is parsed only if a valid
29
+ `content-type` header is provided. Unlike `POST`, `PUT`, and `PATCH`, the
30
+ [catch-all](#catch-all) parser is not executed, and the payload is simply not
31
+ parsed.
32
+
33
+ > ⚠ Warning:
34
+ > When using regular expressions to detect `Content-Type`, it is important to
35
+ > ensure proper detection. For example, to match `application/*`, use
36
+ > `/^application\/([\w-]+);?/` to match the
37
+ > [essence MIME type](https://mimesniff.spec.whatwg.org/#mime-type-miscellaneous)
38
+ > only.
39
+ >
40
+ > Additionally, if the route uses per-content-type body validation via
41
+ > `schema.body.content`, the schema is selected by an **exact match** on the
42
+ > essence MIME type, not by the parser's regex. A regex parser that accepts
43
+ > content types with no matching key in the `content` schema map will result
44
+ > in those requests **not being validated**. Ensure every content type matched
45
+ > by the regex has a corresponding entry in the schema's `content` map. See
46
+ > [Validation and Serialization](./Validation-and-Serialization.md) for details.
47
+
48
+ ### Usage
49
+ ```js
50
+ fastify.addContentTypeParser('application/jsoff', function (request, payload, done) {
51
+ jsoffParser(payload, function (err, body) {
52
+ done(err, body)
53
+ })
54
+ })
55
+
56
+ // Handle multiple content types with the same function
57
+ fastify.addContentTypeParser(['text/xml', 'application/xml'], function (request, payload, done) {
58
+ xmlParser(payload, function (err, body) {
59
+ done(err, body)
60
+ })
61
+ })
62
+
63
+ // Async is also supported in Node versions >= 8.0.0
64
+ fastify.addContentTypeParser('application/jsoff', async function (request, payload) {
65
+ const res = await jsoffParserAsync(payload)
66
+
67
+ return res
68
+ })
69
+
70
+ // Handle all content types that matches RegExp
71
+ fastify.addContentTypeParser(/^image\/([\w-]+);?/, function (request, payload, done) {
72
+ imageParser(payload, function (err, body) {
73
+ done(err, body)
74
+ })
75
+ })
76
+
77
+ // Can use default JSON/Text parser for different content Types
78
+ fastify.addContentTypeParser('text/json', { parseAs: 'string' }, fastify.getDefaultJsonParser('ignore', 'ignore'))
79
+ ```
80
+
81
+ Fastify first tries to match a content-type parser with a `string` value before
82
+ trying to find a matching `RegExp`. For overlapping content types, it starts
83
+ with the last one configured and ends with the first (last in, first out).
84
+ To specify a general content type more precisely, first specify the general
85
+ type, then the specific one, as shown below.
86
+
87
+ ```js
88
+ // Here only the second content type parser is called because its value also matches the first one
89
+ fastify.addContentTypeParser('application/vnd.custom+xml', (request, body, done) => {} )
90
+ fastify.addContentTypeParser('application/vnd.custom', (request, body, done) => {} )
91
+
92
+ // Here the desired behavior is achieved because fastify first tries to match the
93
+ // `application/vnd.custom+xml` content type parser
94
+ fastify.addContentTypeParser('application/vnd.custom', (request, body, done) => {} )
95
+ fastify.addContentTypeParser('application/vnd.custom+xml', (request, body, done) => {} )
96
+ ```
97
+
98
+ ### Using addContentTypeParser with fastify.register
99
+ When using `addContentTypeParser` with `fastify.register`, avoid `await`
100
+ when registering routes. Using `await` makes route registration asynchronous,
101
+ potentially registering routes before `addContentTypeParser` is set.
102
+
103
+ #### Correct Usage
104
+ ```js
105
+ const fastify = require('fastify')();
106
+
107
+
108
+ fastify.register((fastify, opts) => {
109
+ fastify.addContentTypeParser('application/json', function (request, payload, done) {
110
+ jsonParser(payload, function (err, body) {
111
+ done(err, body)
112
+ })
113
+ })
114
+
115
+ fastify.get('/hello', async (req, res) => {});
116
+ });
117
+ ```
118
+
119
+ In addition to `addContentTypeParser`, the `hasContentTypeParser`,
120
+ `removeContentTypeParser`, and `removeAllContentTypeParsers` APIs are available.
121
+
122
+ #### hasContentTypeParser
123
+
124
+ Use the `hasContentTypeParser` API to check if a specific content type parser
125
+ exists.
126
+
127
+ ```js
128
+ if (!fastify.hasContentTypeParser('application/jsoff')){
129
+ fastify.addContentTypeParser('application/jsoff', function (request, payload, done) {
130
+ jsoffParser(payload, function (err, body) {
131
+ done(err, body)
132
+ })
133
+ })
134
+ }
135
+ ```
136
+
137
+ #### removeContentTypeParser
138
+
139
+ `removeContentTypeParser` can remove a single content type or an array of
140
+ content types, supporting both `string` and `RegExp`.
141
+
142
+ ```js
143
+ fastify.addContentTypeParser('text/xml', function (request, payload, done) {
144
+ xmlParser(payload, function (err, body) {
145
+ done(err, body)
146
+ })
147
+ })
148
+
149
+ // Removes the both built-in content type parsers so that only the content type parser for text/html is available
150
+ fastify.removeContentTypeParser(['application/json', 'text/plain'])
151
+ ```
152
+
153
+ #### removeAllContentTypeParsers
154
+ The `removeAllContentTypeParsers` API removes all existing content type parsers
155
+ eliminating the need to specify each one individually. This API supports
156
+ encapsulation and is useful for registering a
157
+ [catch-all content type parser](#catch-all) that should be executed for every
158
+ content type, ignoring built-in parsers.
159
+
160
+ ```js
161
+ fastify.removeAllContentTypeParsers()
162
+
163
+ fastify.addContentTypeParser('text/xml', function (request, payload, done) {
164
+ xmlParser(payload, function (err, body) {
165
+ done(err, body)
166
+ })
167
+ })
168
+ ```
169
+
170
+ > ℹ️ Note:
171
+ > `function(req, done)` and `async function(req)` are
172
+ > still supported but deprecated.
173
+
174
+ #### Body Parser
175
+ The request body can be parsed in two ways. First, add a custom content type
176
+ parser and handle the request stream. Or second, use the `parseAs` option in the
177
+ `addContentTypeParser` API, specifying `'string'` or `'buffer'`. Fastify will
178
+ handle the stream, check the [maximum size](./Server.md#factory-body-limit) of
179
+ the body, and the content length. If the limit is exceeded, the custom parser
180
+ will not be invoked.
181
+ ```js
182
+ fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function (req, body, done) {
183
+ try {
184
+ const json = JSON.parse(body)
185
+ done(null, json)
186
+ } catch (err) {
187
+ err.statusCode = 400
188
+ done(err, undefined)
189
+ }
190
+ })
191
+ ```
192
+
193
+ See
194
+ [`example/parser.js`](https://github.com/fastify/fastify/blob/main/examples/parser.js)
195
+ for an example.
196
+
197
+ ##### Custom Parser Options
198
+ + `parseAs` (string): `'string'` or `'buffer'` to designate how the incoming
199
+ data should be collected. Default: `'buffer'`.
200
+ + `bodyLimit` (number): The maximum payload size, in bytes, that the custom
201
+ parser will accept. Defaults to the global body limit passed to the [`Fastify
202
+ factory function`](./Server.md#bodylimit).
203
+
204
+ #### Catch-All
205
+ To catch all requests regardless of content type, use the `'*'` content type:
206
+ ```js
207
+ fastify.addContentTypeParser('*', function (request, payload, done) {
208
+ let data = ''
209
+ payload.on('data', chunk => { data += chunk })
210
+ payload.on('end', () => {
211
+ done(null, data)
212
+ })
213
+ })
214
+ ```
215
+ All requests without a corresponding content type parser will be handled by
216
+ this function.
217
+
218
+ This is also useful for piping the request stream. Define a content parser like:
219
+
220
+ ```js
221
+ fastify.addContentTypeParser('*', function (request, payload, done) {
222
+ done()
223
+ })
224
+ ```
225
+
226
+ And then access the core HTTP request directly for piping:
227
+
228
+ ```js
229
+ app.post('/hello', (request, reply) => {
230
+ reply.send(request.raw)
231
+ })
232
+ ```
233
+
234
+ Here is a complete example that logs incoming [json
235
+ line](https://jsonlines.org/) objects:
236
+
237
+ ```js
238
+ const split2 = require('split2')
239
+ const pump = require('pump')
240
+
241
+ fastify.addContentTypeParser('*', (request, payload, done) => {
242
+ done(null, pump(payload, split2(JSON.parse)))
243
+ })
244
+
245
+ fastify.route({
246
+ method: 'POST',
247
+ url: '/api/log/jsons',
248
+ handler: (req, res) => {
249
+ req.body.on('data', d => console.log(d)) // log every incoming object
250
+ }
251
+ })
252
+ ```
253
+
254
+ For piping file uploads, check out
255
+ [`@fastify/multipart`](https://github.com/fastify/fastify-multipart).
256
+
257
+ To execute the content type parser on all content types, call
258
+ `removeAllContentTypeParsers` first.
259
+
260
+ ```js
261
+ // Without this call, the request body with the content type application/json would be processed by the built-in JSON parser
262
+ fastify.removeAllContentTypeParsers()
263
+
264
+ fastify.addContentTypeParser('*', function (request, payload, done) {
265
+ const data = ''
266
+ payload.on('data', chunk => { data += chunk })
267
+ payload.on('end', () => {
268
+ done(null, data)
269
+ })
270
+ })
271
+ ```