fastify 4.28.0 → 5.0.0-alpha.2

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 (328) hide show
  1. package/.markdownlint-cli2.yaml +1 -1
  2. package/.tap/processinfo/{86b9786f-4a98-43b8-882a-5f936b876f08.json → 09002e93-10ad-430c-bc86-c0576928b0ed.json} +60 -60
  3. package/.tap/processinfo/{70168912-9bb2-4334-bb89-041f1764cddf.json → ee66c5ab-635d-48b5-8be6-3dc3ceea5bfc.json} +71 -71
  4. package/.tap/test-results/test/build/error-serializer.test.js.tap +6 -2
  5. package/.tap/test-results/test/build/version.test.js.tap +1 -1
  6. package/.taprc +4 -8
  7. package/README.md +3 -6
  8. package/build/build-error-serializer.js +4 -1
  9. package/build/build-validation.js +5 -4
  10. package/docs/Guides/Database.md +1 -1
  11. package/docs/Guides/Delay-Accepting-Requests.md +3 -3
  12. package/docs/Guides/Ecosystem.md +2 -0
  13. package/docs/Guides/Migration-Guide-V5.md +20 -0
  14. package/docs/Guides/Write-Type-Provider.md +4 -2
  15. package/docs/Reference/ContentTypeParser.md +30 -1
  16. package/docs/Reference/Decorators.md +42 -16
  17. package/docs/Reference/Errors.md +10 -2
  18. package/docs/Reference/Hooks.md +48 -14
  19. package/docs/Reference/Logging.md +5 -5
  20. package/docs/Reference/Reply.md +23 -18
  21. package/docs/Reference/Request.md +5 -1
  22. package/docs/Reference/Routes.md +24 -28
  23. package/docs/Reference/Server.md +14 -53
  24. package/docs/Reference/Type-Providers.md +21 -26
  25. package/docs/Reference/TypeScript.md +46 -29
  26. package/docs/Reference/Warnings.md +0 -8
  27. package/eslint.config.js +27 -0
  28. package/examples/typescript-server.ts +14 -14
  29. package/fastify.d.ts +15 -14
  30. package/fastify.js +41 -15
  31. package/lib/configValidator.js +94 -76
  32. package/lib/contentTypeParser.js +54 -88
  33. package/lib/decorate.js +3 -7
  34. package/lib/error-serializer.js +2 -1
  35. package/lib/errors.js +31 -6
  36. package/lib/handleRequest.js +70 -39
  37. package/lib/httpMethods.js +34 -18
  38. package/lib/logger.js +24 -6
  39. package/lib/pluginUtils.js +5 -5
  40. package/lib/reply.js +7 -10
  41. package/lib/request.js +37 -19
  42. package/lib/route.js +6 -34
  43. package/lib/server.js +62 -123
  44. package/lib/warnings.js +24 -29
  45. package/lib/wrapThenable.js +46 -22
  46. package/package.json +38 -58
  47. package/test/404s.test.js +8 -12
  48. package/test/async-await.test.js +46 -2
  49. package/test/build/error-serializer.test.js +4 -2
  50. package/test/check.test.js +225 -0
  51. package/test/close-pipelining.test.js +2 -41
  52. package/test/close.test.js +1 -41
  53. package/test/content-parser.test.js +69 -117
  54. package/test/custom-parser.1.test.js +40 -1
  55. package/test/decorator-namespace.test._js_ +31 -0
  56. package/test/decorator.test.js +92 -43
  57. package/test/delete.test.js +21 -1
  58. package/test/diagnostics-channel/404.test.js +57 -0
  59. package/test/diagnostics-channel/async-delay-request.test.js +74 -0
  60. package/test/diagnostics-channel/async-request.test.js +72 -0
  61. package/test/diagnostics-channel/error-before-handler.test.js +36 -0
  62. package/test/diagnostics-channel/error-request.test.js +61 -0
  63. package/test/diagnostics-channel/error-status.test.js +39 -0
  64. package/test/{diagnostics-channel.test.js → diagnostics-channel/init.test.js} +6 -16
  65. package/test/diagnostics-channel/sync-delay-request.test.js +58 -0
  66. package/test/diagnostics-channel/sync-request-reply.test.js +58 -0
  67. package/test/diagnostics-channel/sync-request.test.js +61 -0
  68. package/test/encapsulated-error-handler.test.js +201 -14
  69. package/test/esm/index.test.js +2 -12
  70. package/test/findRoute.test.js +16 -0
  71. package/test/genReqId.test.js +9 -0
  72. package/test/get.test.js +28 -0
  73. package/test/has-route.test.js +1 -1
  74. package/test/helper.js +1 -5
  75. package/test/hooks.test.js +0 -4
  76. package/test/http2/constraint.test.js +22 -1
  77. package/test/http2/plain.test.js +21 -6
  78. package/test/http2/secure.test.js +12 -1
  79. package/test/https/https.test.js +57 -0
  80. package/test/inject.test.js +1 -2
  81. package/test/internals/decorator.test.js +0 -2
  82. package/test/internals/errors.test.js +57 -17
  83. package/test/internals/handleRequest.test.js +5 -1
  84. package/test/internals/initialConfig.test.js +5 -5
  85. package/test/internals/logger.test.js +31 -2
  86. package/test/internals/reply.test.js +6 -78
  87. package/test/internals/request.test.js +13 -11
  88. package/test/listen.1.test.js +5 -15
  89. package/test/listen.5.test.js +88 -0
  90. package/test/logger/instantiation.test.js +8 -8
  91. package/test/logger/logging.test.js +4 -4
  92. package/test/logger/options.test.js +102 -21
  93. package/test/logger/response.test.js +6 -6
  94. package/test/maxRequestsPerSocket.test.js +2 -5
  95. package/test/method-missing.test.js +24 -0
  96. package/test/plugin.1.test.js +2 -4
  97. package/test/plugin.2.test.js +0 -2
  98. package/test/plugin.3.test.js +0 -2
  99. package/test/plugin.4.test.js +92 -56
  100. package/test/register.test.js +2 -4
  101. package/test/reply-earlyHints.test.js +98 -0
  102. package/test/reply-error.test.js +0 -2
  103. package/test/route-hooks.test.js +0 -1
  104. package/test/route-shorthand.test.js +60 -0
  105. package/test/schema-special-usage.test.js +1 -1
  106. package/test/server.test.js +17 -2
  107. package/test/stream.2.test.js +1 -1
  108. package/test/stream.4.test.js +0 -42
  109. package/test/stream.5.test.js +2 -2
  110. package/test/trust-proxy.test.js +33 -27
  111. package/test/types/errors.test-d.ts +0 -2
  112. package/test/types/fastify.test-d.ts +14 -12
  113. package/test/types/hooks.test-d.ts +1 -0
  114. package/test/types/import.ts +1 -0
  115. package/test/types/instance.test-d.ts +10 -51
  116. package/test/types/logger.test-d.ts +43 -6
  117. package/test/types/plugin.test-d.ts +5 -2
  118. package/test/types/register.test-d.ts +2 -2
  119. package/test/types/reply.test-d.ts +13 -12
  120. package/test/types/request.test-d.ts +19 -8
  121. package/test/types/route.test-d.ts +30 -2
  122. package/test/types/schema.test-d.ts +2 -2
  123. package/test/types/serverFactory.test-d.ts +1 -1
  124. package/test/types/type-provider.test-d.ts +59 -12
  125. package/test/types/using.test-d.ts +4 -1
  126. package/test/url-rewriting.test.js +3 -2
  127. package/test/useSemicolonDelimiter.test.js +3 -6
  128. package/test/versioned-routes.test.js +1 -1
  129. package/test/web-api.test.js +0 -6
  130. package/types/content-type-parser.d.ts +3 -3
  131. package/types/context.d.ts +0 -1
  132. package/types/errors.d.ts +1 -0
  133. package/types/hooks.d.ts +6 -6
  134. package/types/instance.d.ts +28 -41
  135. package/types/logger.d.ts +3 -3
  136. package/types/plugin.d.ts +3 -3
  137. package/types/reply.d.ts +9 -12
  138. package/types/request.d.ts +5 -3
  139. package/types/route.d.ts +31 -31
  140. package/types/schema.d.ts +3 -3
  141. package/types/serverFactory.d.ts +2 -2
  142. package/types/type-provider.d.ts +22 -12
  143. package/types/utils.d.ts +18 -23
  144. package/.c8rc.json +0 -8
  145. package/.eslintrc +0 -4
  146. package/.tap/processinfo/029eb7a1-1942-40bc-98e2-cef3b7a14b5e.json +0 -268
  147. package/.tap/processinfo/03c196c6-01c3-4268-a9b5-298dff18a873.json +0 -269
  148. package/.tap/processinfo/04bbabba-8611-4908-9092-dfa9fcc13327.json +0 -268
  149. package/.tap/processinfo/05d8a743-3edf-4e2d-ae5a-dc99d0855ba5.json +0 -272
  150. package/.tap/processinfo/07718963-36a8-4d87-82ad-366c877a5247.json +0 -268
  151. package/.tap/processinfo/08fe3bde-5814-4308-9158-cdf1e47391b7.json +0 -268
  152. package/.tap/processinfo/0a3e3fb0-eabf-4532-ae80-20434da22678.json +0 -268
  153. package/.tap/processinfo/0caf2a75-4b3a-46c4-9b41-c7e450e5e15f.json +0 -268
  154. package/.tap/processinfo/0cf35d52-e5b2-4884-bcf0-b0ab3017b689.json +0 -268
  155. package/.tap/processinfo/0e666134-5013-4ecd-9ee6-59b22716c39c.json +0 -268
  156. package/.tap/processinfo/1087b811-4ec4-4f91-92b4-a78a51a437de.json +0 -268
  157. package/.tap/processinfo/13709ed3-b68c-42cf-8472-b0c4b8a89d2b.json +0 -268
  158. package/.tap/processinfo/13ac2f18-d0e0-439f-bc86-2ff0119af857.json +0 -268
  159. package/.tap/processinfo/13e47e0e-f6e8-4381-8a42-923b661f4a4f.json +0 -268
  160. package/.tap/processinfo/143f7d43-b8e8-4666-b482-f28fb37160ee.json +0 -268
  161. package/.tap/processinfo/14f3801d-03ab-4db3-9df5-c5d47e0a8cf0.json +0 -270
  162. package/.tap/processinfo/15a07dad-4bcd-442c-95e0-30c31f2b9818.json +0 -273
  163. package/.tap/processinfo/191ad3ad-04d8-4fb9-b119-ad2811f9b925.json +0 -243
  164. package/.tap/processinfo/1b25d54b-62d3-44cd-b581-31e705522fae.json +0 -268
  165. package/.tap/processinfo/1b7cb260-f04b-4135-a4fe-093081c4706f.json +0 -268
  166. package/.tap/processinfo/1e395d63-4815-4c77-aa47-df3709cc0ef9.json +0 -268
  167. package/.tap/processinfo/1e7f6a54-3abf-4771-863a-585cba110aec.json +0 -268
  168. package/.tap/processinfo/21a15e1d-0b41-47d8-b03d-0ba130969034.json +0 -244
  169. package/.tap/processinfo/21e02016-9ecd-4983-8417-9c74d224644f.json +0 -269
  170. package/.tap/processinfo/2327d941-d0d5-4762-b386-02a9a27ad28e.json +0 -268
  171. package/.tap/processinfo/23d39204-eac9-4f57-8db4-ffa996227fbd.json +0 -268
  172. package/.tap/processinfo/2493875a-0ac6-4d53-993c-f44471fd0678.json +0 -268
  173. package/.tap/processinfo/2698669f-f1e7-4a12-a687-8d58177be2b0.json +0 -269
  174. package/.tap/processinfo/2862b053-0a3d-46d7-9381-ffcb06287609.json +0 -268
  175. package/.tap/processinfo/2ac1b8d6-ac92-40e2-a59a-7681069f487c.json +0 -268
  176. package/.tap/processinfo/2c75e5f7-c4ef-47e4-a1c4-105eef6c0fab.json +0 -242
  177. package/.tap/processinfo/2e2c45cd-718b-4e5a-bf88-f801630f2803.json +0 -268
  178. package/.tap/processinfo/2f9ca478-3e03-4cce-a0bc-fcdc86d7c316.json +0 -268
  179. package/.tap/processinfo/30e3117f-fb74-456f-8f02-527e9eb9fcc3.json +0 -268
  180. package/.tap/processinfo/332be679-63c7-4b49-8b87-ef55995ada2d.json +0 -268
  181. package/.tap/processinfo/37c36f95-07f9-4ef0-8ab4-9e107d51b605.json +0 -269
  182. package/.tap/processinfo/3874eae2-f3db-44ef-9a9f-c8169d4b2b76.json +0 -268
  183. package/.tap/processinfo/38a7c3da-a411-41d0-8993-9deefd23500d.json +0 -268
  184. package/.tap/processinfo/3a7b6dbd-e153-4ce5-b557-21fb82009983.json +0 -269
  185. package/.tap/processinfo/3c6731ec-936d-470f-b7b0-0c87b54be051.json +0 -268
  186. package/.tap/processinfo/3c850ea9-4ef0-4044-a3fd-fbadfa9d543e.json +0 -268
  187. package/.tap/processinfo/3e4e15e0-a325-46f0-be57-5fd374560b7a.json +0 -269
  188. package/.tap/processinfo/3ed868e0-887c-402a-9f22-b1fdb74b4da0.json +0 -268
  189. package/.tap/processinfo/405498d7-5854-4ce1-a7dc-06920932f26d.json +0 -268
  190. package/.tap/processinfo/40b7eb19-ae35-4490-8a11-eb91a573c590.json +0 -268
  191. package/.tap/processinfo/40bb1260-d856-4248-8939-a0a05e322041.json +0 -268
  192. package/.tap/processinfo/41252e0b-7f69-44cc-b356-dd94bcbfdb29.json +0 -268
  193. package/.tap/processinfo/418fa710-e2fd-4508-b533-c179958da464.json +0 -269
  194. package/.tap/processinfo/433ef009-63aa-48fe-8e5d-c725228fa2fc.json +0 -268
  195. package/.tap/processinfo/44bf577c-9c01-4197-bd29-2e1ae888c4d4.json +0 -268
  196. package/.tap/processinfo/458fb7f2-20b9-48a2-8853-403c9851f605.json +0 -268
  197. package/.tap/processinfo/46b9892b-bb23-4b86-b0fa-9297f08c611a.json +0 -268
  198. package/.tap/processinfo/46bd9aaf-6cf3-4bd5-b90d-e136a7299a8e.json +0 -268
  199. package/.tap/processinfo/4779aa5f-e57a-4fcc-87e2-7d0bd4fca27f.json +0 -268
  200. package/.tap/processinfo/47b73f4b-ab31-49e1-97fd-8436dbe4bdf3.json +0 -269
  201. package/.tap/processinfo/49dba52e-e0c9-445d-8e9d-6d9ebe3ce6c4.json +0 -268
  202. package/.tap/processinfo/4b1dbc61-4e65-4c56-9784-2036f369038a.json +0 -268
  203. package/.tap/processinfo/4b6f0b40-43ef-4668-83a0-e07e28509df5.json +0 -268
  204. package/.tap/processinfo/4c236f70-f532-460b-8f7a-dd973301d493.json +0 -268
  205. package/.tap/processinfo/4d92b707-a268-48b8-885b-004d3a288c41.json +0 -269
  206. package/.tap/processinfo/4ff10bae-7c97-4c0a-b712-6c0d2f8c0e8e.json +0 -270
  207. package/.tap/processinfo/50f95bd5-ae12-4d83-99f4-ae9b0690c6a8.json +0 -268
  208. package/.tap/processinfo/557e4a49-d99c-4a63-b2f2-f33d897ab874.json +0 -268
  209. package/.tap/processinfo/589fd21a-8319-4abf-8cf7-82cb4a463a4b.json +0 -269
  210. package/.tap/processinfo/5a872f3a-949f-40be-8004-d739d034255c.json +0 -272
  211. package/.tap/processinfo/5abc301a-23da-424d-891e-3afbaff9156c.json +0 -269
  212. package/.tap/processinfo/5c31614c-a766-4837-ab59-dd6977166f72.json +0 -253
  213. package/.tap/processinfo/5d1e90c8-d819-4901-b022-f9ea4cd81978.json +0 -268
  214. package/.tap/processinfo/5d283e67-f31d-4fa8-a559-a1d8e82ee046.json +0 -269
  215. package/.tap/processinfo/5df505bc-6a4b-4c41-822f-51e2d7111de8.json +0 -268
  216. package/.tap/processinfo/5eaf64a2-fbfd-40e7-b391-c30f744b2bf1.json +0 -269
  217. package/.tap/processinfo/5ef5ede0-6436-4938-8401-d32ad4bffd5d.json +0 -268
  218. package/.tap/processinfo/606f05c0-8293-41db-bc92-eea82123697f.json +0 -269
  219. package/.tap/processinfo/6446806d-6cab-4c1d-a9ed-6bccaf3c4ea9.json +0 -268
  220. package/.tap/processinfo/64da7e08-925d-444d-98de-6568c6115d8d.json +0 -269
  221. package/.tap/processinfo/6917da6d-d2dc-466a-a893-7fb7412dde96.json +0 -268
  222. package/.tap/processinfo/69bbeee0-c398-4ccf-98b3-fb625a63bab4.json +0 -268
  223. package/.tap/processinfo/6da6ea8f-3370-4703-b230-90159531f766.json +0 -268
  224. package/.tap/processinfo/6ecffe1f-3016-4c11-9294-b488baced99f.json +0 -268
  225. package/.tap/processinfo/6f23f41f-ccbd-48cb-9ab6-311db0cfb65c.json +0 -270
  226. package/.tap/processinfo/713a674e-40e1-46b4-866e-949d57c1a9f9.json +0 -270
  227. package/.tap/processinfo/730254d4-eacb-4cdf-80f4-8da22341cde5.json +0 -268
  228. package/.tap/processinfo/7344e559-c546-416f-8f1b-0f9fe12c6f02.json +0 -268
  229. package/.tap/processinfo/7556217a-0155-448f-b4d4-bec1bb0f6040.json +0 -269
  230. package/.tap/processinfo/7572079c-166c-4c4c-85ff-89b9430b214f.json +0 -268
  231. package/.tap/processinfo/7808180f-1974-47cd-bba2-2d6b8b711d65.json +0 -273
  232. package/.tap/processinfo/796dde83-da66-4db2-8d27-d45a3627c9c7.json +0 -268
  233. package/.tap/processinfo/7979819f-3723-48be-9f55-be700e689441.json +0 -270
  234. package/.tap/processinfo/7a664d39-d7f5-42f9-89df-15563048fab6.json +0 -268
  235. package/.tap/processinfo/7b047b72-01d9-4217-857c-93341651b4b3.json +0 -269
  236. package/.tap/processinfo/7ce41af6-7961-45ae-8c6f-b6e1c5692a48.json +0 -268
  237. package/.tap/processinfo/7e1de1c6-127e-463d-9357-081ee33ef5ce.json +0 -269
  238. package/.tap/processinfo/81ac7a7f-b0c0-4ef6-82cb-c718ea84e152.json +0 -268
  239. package/.tap/processinfo/851a058f-a497-4b10-a0b7-c9182d9c4d5a.json +0 -268
  240. package/.tap/processinfo/86502974-c245-4194-ade4-d9c6fdbb757e.json +0 -268
  241. package/.tap/processinfo/8a3fe726-86ab-4300-8d73-7eacbbc02a05.json +0 -268
  242. package/.tap/processinfo/8adf928b-c963-4ba0-9c35-606fcbd8a2aa.json +0 -272
  243. package/.tap/processinfo/8b31a6d8-1a33-4a27-93ca-1c5b364be068.json +0 -240
  244. package/.tap/processinfo/8ec12773-6b18-49a2-8e52-874c797df965.json +0 -833
  245. package/.tap/processinfo/8edb9502-3420-42fb-a602-e5de93be2df1.json +0 -268
  246. package/.tap/processinfo/8fc572e6-9828-4f98-a49c-9e081b2193c4.json +0 -242
  247. package/.tap/processinfo/8fee2d30-c5dd-4fae-9cf2-2ef8dd0f90de.json +0 -834
  248. package/.tap/processinfo/92cc0496-5f26-4370-8212-18136b972f99.json +0 -268
  249. package/.tap/processinfo/93a3f064-3f6e-4f49-becb-f7925f2961a9.json +0 -268
  250. package/.tap/processinfo/967e3697-8310-4a19-8dd5-927ac8bd6c79.json +0 -269
  251. package/.tap/processinfo/97225e23-9d30-4287-b3f5-72bccebec50b.json +0 -268
  252. package/.tap/processinfo/9a363bc6-4e65-47e8-94ca-26a9db428fb4.json +0 -268
  253. package/.tap/processinfo/9d2fe462-57fa-43f1-b02c-d188f15de30b.json +0 -270
  254. package/.tap/processinfo/a00b6cda-feb7-4b8a-8179-4c43bc29d670.json +0 -269
  255. package/.tap/processinfo/a017cbd5-4ac7-49e1-8c77-1bf4f6e7f2a6.json +0 -271
  256. package/.tap/processinfo/a1277309-1984-48f8-b60b-f5e8639736be.json +0 -271
  257. package/.tap/processinfo/a16bf53e-4337-48ff-88fa-67f55738e0f5.json +0 -268
  258. package/.tap/processinfo/a3a9848f-440e-41bb-9b0b-568bcfee0ddc.json +0 -268
  259. package/.tap/processinfo/a468c11f-f2f1-4e92-9ba0-6d28b6569b72.json +0 -268
  260. package/.tap/processinfo/a5880465-68f1-46b3-84a5-0da389d0bc67.json +0 -268
  261. package/.tap/processinfo/a666f394-39b4-44ad-8e74-abebf74dde3b.json +0 -270
  262. package/.tap/processinfo/af09d8ca-7053-4410-b514-b22c47f5979f.json +0 -268
  263. package/.tap/processinfo/af203309-28aa-459d-a56e-d88833695521.json +0 -268
  264. package/.tap/processinfo/afa2f7b6-dcd2-4d90-bf3c-54ba8b6800eb.json +0 -268
  265. package/.tap/processinfo/b231291d-ef14-4ff0-85f9-38a73a5408f8.json +0 -268
  266. package/.tap/processinfo/b3d3f2a1-a9fc-4d88-b122-fae90248cd59.json +0 -268
  267. package/.tap/processinfo/b834bf83-26c4-403a-8e91-eb15fe4b0b5d.json +0 -268
  268. package/.tap/processinfo/b8786fd7-47df-4ac1-8d6f-2d4c7623c681.json +0 -268
  269. package/.tap/processinfo/b9758f53-7f5a-4b03-8684-8a42ad644e5a.json +0 -268
  270. package/.tap/processinfo/bd194ea2-a21a-4604-b225-ee48abf1e607.json +0 -242
  271. package/.tap/processinfo/bd7ced53-3872-43b7-ad73-3352e50b728b.json +0 -268
  272. package/.tap/processinfo/be50295b-7e50-46cd-8bf1-637bf222699c.json +0 -268
  273. package/.tap/processinfo/bec61dd9-aa52-4e6c-8e37-5c9c10e935fd.json +0 -268
  274. package/.tap/processinfo/c015adf9-1d60-447e-87b5-b2031fe55bba.json +0 -268
  275. package/.tap/processinfo/c0666afa-7f64-45bd-97fb-145df1380157.json +0 -268
  276. package/.tap/processinfo/c2c0c012-c1c0-4457-84d6-dadba8396c94.json +0 -268
  277. package/.tap/processinfo/c3dd3ecd-737b-47ce-a917-54341c7bbed3.json +0 -268
  278. package/.tap/processinfo/c41ac06d-64b8-4bb3-bf56-0551f5a48f4b.json +0 -268
  279. package/.tap/processinfo/c4235bfb-a2aa-4271-9c6b-3ceb370219b1.json +0 -268
  280. package/.tap/processinfo/c4e6f24f-288c-493c-b6f0-02924aeb6758.json +0 -270
  281. package/.tap/processinfo/c54227bb-4a7b-40bb-bfe6-b54fe55078f3.json +0 -268
  282. package/.tap/processinfo/c699de91-3b0b-4466-9418-6910a3eb640a.json +0 -269
  283. package/.tap/processinfo/c74e2f37-451a-4577-ac18-e597fbd9a1d4.json +0 -269
  284. package/.tap/processinfo/c90cccec-5b4b-445f-a935-ac22859675d0.json +0 -252
  285. package/.tap/processinfo/c9dd6c7d-0d16-45e5-87ae-117388bf2994.json +0 -268
  286. package/.tap/processinfo/ca2e48fb-58c5-47fc-ad2e-263838aea42c.json +0 -272
  287. package/.tap/processinfo/ca87351d-c710-45c1-838a-16bccac59874.json +0 -273
  288. package/.tap/processinfo/cdb4a671-5776-4944-91b9-c456c58841ef.json +0 -268
  289. package/.tap/processinfo/cf10fdc8-6a87-447a-9e12-45f447af61f3.json +0 -244
  290. package/.tap/processinfo/cf3f1f08-643e-4f24-82ca-40f7a349c3d1.json +0 -268
  291. package/.tap/processinfo/d091172a-06a5-469b-82a9-8fefe3dd99da.json +0 -240
  292. package/.tap/processinfo/d1675431-61d6-45f8-a010-6e654112a00a.json +0 -272
  293. package/.tap/processinfo/d2d54aa2-c221-4ad4-b6b7-0c58e3c3679c.json +0 -269
  294. package/.tap/processinfo/d4f3c95a-ddbe-419d-bce0-dd6acceee21f.json +0 -268
  295. package/.tap/processinfo/d54ed8f1-43c3-478a-90d3-2c8aced723f2.json +0 -269
  296. package/.tap/processinfo/d6e5a2a6-4647-4d98-916c-aec4ace54a65.json +0 -268
  297. package/.tap/processinfo/d7280c64-45e6-4b12-affc-3ac9a5d4014a.json +0 -268
  298. package/.tap/processinfo/d82c8367-d825-4405-88df-07298f6ef840.json +0 -269
  299. package/.tap/processinfo/d8f97e53-e921-4d33-9c8d-2f7e807a9425.json +0 -268
  300. package/.tap/processinfo/da546a73-9714-4f8c-bdbb-e42730edbcfa.json +0 -268
  301. package/.tap/processinfo/da7fb7fb-1da4-49f8-a3ee-d4ea623c01a5.json +0 -268
  302. package/.tap/processinfo/daa6a016-4f0c-4050-923c-2022e0bb21d8.json +0 -268
  303. package/.tap/processinfo/db9a251d-8540-4719-b464-e7d5febd97d1.json +0 -240
  304. package/.tap/processinfo/dc10c603-8e58-4611-baa3-44da2578d07a.json +0 -268
  305. package/.tap/processinfo/dde56c1a-858c-47cc-b0bb-61279620ac17.json +0 -268
  306. package/.tap/processinfo/e0d9c4ea-f7c7-4c64-8ced-66dc6f0ac5d2.json +0 -271
  307. package/.tap/processinfo/e121454f-5dfa-4209-ba15-4c39840871f2.json +0 -831
  308. package/.tap/processinfo/e1f43e40-c3fe-4eb8-a713-d5910cc6b25a.json +0 -268
  309. package/.tap/processinfo/e4575e7a-f00e-488b-94e1-8f877b54725e.json +0 -268
  310. package/.tap/processinfo/e9ad667e-8603-4488-af64-449cc9532803.json +0 -268
  311. package/.tap/processinfo/eb26a697-e5e2-4730-aeea-bcb9c49afd4d.json +0 -268
  312. package/.tap/processinfo/eb29d1c3-feaf-4744-9d84-cf257e8269b0.json +0 -268
  313. package/.tap/processinfo/ee720c0a-ed64-4e7e-8c0a-139c7b9725d2.json +0 -268
  314. package/.tap/processinfo/ef88c13a-87b2-49e4-a683-7b812505cd6f.json +0 -268
  315. package/.tap/processinfo/f4ed6948-dac0-4128-9f86-d083b6918ea7.json +0 -268
  316. package/.tap/processinfo/f7544c01-8ac7-4e42-8ad5-c4d62e094d1f.json +0 -270
  317. package/.tap/processinfo/f7cee4b3-7bcc-4591-a628-5629b0b41c9e.json +0 -268
  318. package/.tap/processinfo/f9c0a1f7-c1a4-44d3-ae3f-8c1eb42cd746.json +0 -269
  319. package/.tap/processinfo/fc46b4da-79db-4201-af7e-34bb17f92d69.json +0 -270
  320. package/.tap/processinfo/fccc0056-03c4-40cb-9d0b-2db4bbe573c1.json +0 -268
  321. package/.tap/processinfo/fd2df572-54d7-4ce7-b7aa-a2b4b00d4127.json +0 -254
  322. package/.tap/processinfo/fea9377f-b473-484d-bee6-ac7f49e50937.json +0 -269
  323. package/.tap/processinfo/feb516dc-abda-46e6-9b42-d37adfc63366.json +0 -268
  324. package/.tap/processinfo/ff0fda4c-aa2e-4236-906e-fdfb6bd6632e.json +0 -269
  325. package/test/default-route.test.js +0 -88
  326. package/test/listen.deprecated.test.js +0 -229
  327. package/test/unsupported-httpversion.test.js +0 -31
  328. package/types/.eslintrc.json +0 -48
@@ -2,7 +2,6 @@
2
2
 
3
3
  const { AsyncResource } = require('node:async_hooks')
4
4
  const { FifoMap: Fifo } = require('toad-cache')
5
- const { safeParse: safeParseContentType, defaultContentType } = require('fast-content-type-parse')
6
5
  const secureJson = require('secure-json-parse')
7
6
  const {
8
7
  kDefaultJsonParse,
@@ -27,6 +26,7 @@ const {
27
26
  FST_ERR_CTP_EMPTY_JSON_BODY,
28
27
  FST_ERR_CTP_INSTANCE_ALREADY_STARTED
29
28
  } = require('./errors')
29
+ const { FSTSEC001 } = require('./warnings')
30
30
 
31
31
  function ContentTypeParser (bodyLimit, onProtoPoisoning, onConstructorPoisoning) {
32
32
  this[kDefaultJsonParse] = getDefaultJsonParser(onProtoPoisoning, onConstructorPoisoning)
@@ -34,7 +34,7 @@ function ContentTypeParser (bodyLimit, onProtoPoisoning, onConstructorPoisoning)
34
34
  this.customParsers = new Map()
35
35
  this.customParsers.set('application/json', new Parser(true, false, bodyLimit, this[kDefaultJsonParse]))
36
36
  this.customParsers.set('text/plain', new Parser(true, false, bodyLimit, defaultPlainTextParser))
37
- this.parserList = [new ParserListItem('application/json'), new ParserListItem('text/plain')]
37
+ this.parserList = ['application/json', 'text/plain']
38
38
  this.parserRegExpList = []
39
39
  this.cache = new Fifo(100)
40
40
  }
@@ -42,9 +42,16 @@ function ContentTypeParser (bodyLimit, onProtoPoisoning, onConstructorPoisoning)
42
42
  ContentTypeParser.prototype.add = function (contentType, opts, parserFn) {
43
43
  const contentTypeIsString = typeof contentType === 'string'
44
44
 
45
- if (!contentTypeIsString && !(contentType instanceof RegExp)) throw new FST_ERR_CTP_INVALID_TYPE()
46
- if (contentTypeIsString && contentType.length === 0) throw new FST_ERR_CTP_EMPTY_TYPE()
47
- if (typeof parserFn !== 'function') throw new FST_ERR_CTP_INVALID_HANDLER()
45
+ if (contentTypeIsString) {
46
+ contentType = contentType.trim().toLowerCase()
47
+ if (contentType.length === 0) throw new FST_ERR_CTP_EMPTY_TYPE()
48
+ } else if (!(contentType instanceof RegExp)) {
49
+ throw new FST_ERR_CTP_INVALID_TYPE()
50
+ }
51
+
52
+ if (typeof parserFn !== 'function') {
53
+ throw new FST_ERR_CTP_INVALID_HANDLER()
54
+ }
48
55
 
49
56
  if (this.existingParser(contentType)) {
50
57
  throw new FST_ERR_CTP_ALREADY_PRESENT(contentType)
@@ -63,21 +70,29 @@ ContentTypeParser.prototype.add = function (contentType, opts, parserFn) {
63
70
  parserFn
64
71
  )
65
72
 
66
- if (contentTypeIsString && contentType === '*') {
73
+ if (contentType === '*') {
67
74
  this.customParsers.set('', parser)
68
75
  } else {
69
76
  if (contentTypeIsString) {
70
- this.parserList.unshift(new ParserListItem(contentType))
77
+ this.parserList.unshift(contentType)
78
+ this.customParsers.set(contentType, parser)
71
79
  } else {
72
- contentType.isEssence = contentType.source.indexOf(';') === -1
80
+ validateRegExp(contentType)
73
81
  this.parserRegExpList.unshift(contentType)
82
+ this.customParsers.set(contentType.toString(), parser)
74
83
  }
75
- this.customParsers.set(contentType.toString(), parser)
76
84
  }
77
85
  }
78
86
 
79
87
  ContentTypeParser.prototype.hasParser = function (contentType) {
80
- return this.customParsers.has(typeof contentType === 'string' ? contentType : contentType.toString())
88
+ if (typeof contentType === 'string') {
89
+ contentType = contentType.trim().toLowerCase()
90
+ } else {
91
+ if (!(contentType instanceof RegExp)) throw new FST_ERR_CTP_INVALID_TYPE()
92
+ contentType = contentType.toString()
93
+ }
94
+
95
+ return this.customParsers.has(contentType)
81
96
  }
82
97
 
83
98
  ContentTypeParser.prototype.existingParser = function (contentType) {
@@ -92,27 +107,20 @@ ContentTypeParser.prototype.existingParser = function (contentType) {
92
107
  }
93
108
 
94
109
  ContentTypeParser.prototype.getParser = function (contentType) {
95
- if (this.hasParser(contentType)) {
96
- return this.customParsers.get(contentType)
97
- }
98
-
99
- const parser = this.cache.get(contentType)
110
+ let parser = this.customParsers.get(contentType)
100
111
  if (parser !== undefined) return parser
101
112
 
102
- const parsed = safeParseContentType(contentType)
103
-
104
- // dummyContentType always the same object
105
- // we can use === for the comparison and return early
106
- if (parsed === defaultContentType) {
107
- return this.customParsers.get('')
108
- }
113
+ parser = this.cache.get(contentType)
114
+ if (parser !== undefined) return parser
109
115
 
110
116
  // eslint-disable-next-line no-var
111
117
  for (var i = 0; i !== this.parserList.length; ++i) {
112
118
  const parserListItem = this.parserList[i]
113
- if (compareContentType(parsed, parserListItem)) {
114
- const parser = this.customParsers.get(parserListItem.name)
115
- // we set request content-type in cache to reduce parsing of MIME type
119
+ if (
120
+ contentType.slice(0, parserListItem.length) === parserListItem &&
121
+ (contentType.length === parserListItem.length || contentType.charCodeAt(parserListItem.length) === 59 /* `;` */ || contentType.charCodeAt(parserListItem.length) === 32 /* ` ` */)
122
+ ) {
123
+ parser = this.customParsers.get(parserListItem)
116
124
  this.cache.set(contentType, parser)
117
125
  return parser
118
126
  }
@@ -121,9 +129,8 @@ ContentTypeParser.prototype.getParser = function (contentType) {
121
129
  // eslint-disable-next-line no-var
122
130
  for (var j = 0; j !== this.parserRegExpList.length; ++j) {
123
131
  const parserRegExp = this.parserRegExpList[j]
124
- if (compareRegExpContentType(contentType, parsed.type, parserRegExp)) {
125
- const parser = this.customParsers.get(parserRegExp.toString())
126
- // we set request content-type in cache to reduce parsing of MIME type
132
+ if (parserRegExp.test(contentType)) {
133
+ parser = this.customParsers.get(parserRegExp.toString())
127
134
  this.cache.set(contentType, parser)
128
135
  return parser
129
136
  }
@@ -140,13 +147,19 @@ ContentTypeParser.prototype.removeAll = function () {
140
147
  }
141
148
 
142
149
  ContentTypeParser.prototype.remove = function (contentType) {
143
- if (!(typeof contentType === 'string' || contentType instanceof RegExp)) throw new FST_ERR_CTP_INVALID_TYPE()
150
+ let parsers
144
151
 
145
- const removed = this.customParsers.delete(contentType.toString())
146
-
147
- const parsers = typeof contentType === 'string' ? this.parserList : this.parserRegExpList
152
+ if (typeof contentType === 'string') {
153
+ contentType = contentType.trim().toLowerCase()
154
+ parsers = this.parserList
155
+ } else {
156
+ if (!(contentType instanceof RegExp)) throw new FST_ERR_CTP_INVALID_TYPE()
157
+ contentType = contentType.toString()
158
+ parsers = this.parserRegExpList
159
+ }
148
160
 
149
- const idx = parsers.findIndex(ct => ct.toString() === contentType.toString())
161
+ const removed = this.customParsers.delete(contentType)
162
+ const idx = parsers.findIndex(ct => ct.toString() === contentType)
150
163
 
151
164
  if (idx > -1) {
152
165
  parsers.splice(idx, 1)
@@ -182,7 +195,7 @@ ContentTypeParser.prototype.run = function (contentType, handler, request, reply
182
195
  } else {
183
196
  const result = parser.fn(request, request[kRequestPayloadStream], done)
184
197
 
185
- if (result && typeof result.then === 'function') {
198
+ if (typeof result?.then === 'function') {
186
199
  result.then(body => done(null, body), done)
187
200
  }
188
201
  }
@@ -205,9 +218,7 @@ ContentTypeParser.prototype.run = function (contentType, handler, request, reply
205
218
  function rawBody (request, reply, options, parser, done) {
206
219
  const asString = parser.asString
207
220
  const limit = options.limit === null ? parser.bodyLimit : options.limit
208
- const contentLength = request.headers['content-length'] === undefined
209
- ? NaN
210
- : Number(request.headers['content-length'])
221
+ const contentLength = Number(request.headers['content-length'])
211
222
 
212
223
  if (contentLength > limit) {
213
224
  // We must close the connection as the client is going
@@ -373,60 +384,15 @@ function removeAllContentTypeParsers () {
373
384
  this[kContentTypeParser].removeAll()
374
385
  }
375
386
 
376
- function compareContentType (contentType, parserListItem) {
377
- if (parserListItem.isEssence) {
378
- // we do essence check
379
- return contentType.type.indexOf(parserListItem) !== -1
380
- } else {
381
- // when the content-type includes parameters
382
- // we do a full-text search
383
- // reject essence content-type before checking parameters
384
- if (contentType.type.indexOf(parserListItem.type) === -1) return false
385
- for (const key of parserListItem.parameterKeys) {
386
- // reject when missing parameters
387
- if (!(key in contentType.parameters)) return false
388
- // reject when parameters do not match
389
- if (contentType.parameters[key] !== parserListItem.parameters[key]) return false
390
- }
391
- return true
392
- }
393
- }
394
-
395
- function compareRegExpContentType (contentType, essenceMIMEType, regexp) {
396
- if (regexp.isEssence) {
397
- // we do essence check
398
- return regexp.test(essenceMIMEType)
399
- } else {
400
- // when the content-type includes parameters
401
- // we do a full-text match
402
- return regexp.test(contentType)
387
+ function validateRegExp (regexp) {
388
+ // RegExp should either start with ^ or include ;?
389
+ // It can ensure the user is properly detect the essence
390
+ // MIME types.
391
+ if (regexp.source[0] !== '^' && regexp.source.includes(';?') === false) {
392
+ FSTSEC001(regexp.source)
403
393
  }
404
394
  }
405
395
 
406
- function ParserListItem (contentType) {
407
- this.name = contentType
408
- // we pre-calculate all the needed information
409
- // before content-type comparison
410
- const parsed = safeParseContentType(contentType)
411
- this.isEssence = contentType.indexOf(';') === -1
412
- // we should not allow empty string for parser list item
413
- // because it would become a match-all handler
414
- if (this.isEssence === false && parsed.type === '') {
415
- // handle semicolon or empty string
416
- const tmp = contentType.split(';', 1)[0]
417
- this.type = tmp === '' ? contentType : tmp
418
- } else {
419
- this.type = parsed.type
420
- }
421
- this.parameters = parsed.parameters
422
- this.parameterKeys = Object.keys(parsed.parameters)
423
- }
424
-
425
- // used in ContentTypeParser.remove
426
- ParserListItem.prototype.toString = function () {
427
- return this.name
428
- }
429
-
430
396
  module.exports = ContentTypeParser
431
397
  module.exports.helpers = {
432
398
  buildContentTypeParser,
package/lib/decorate.js CHANGED
@@ -1,7 +1,5 @@
1
1
  'use strict'
2
2
 
3
- /* eslint no-prototype-builtins: 0 */
4
-
5
3
  const {
6
4
  kReply,
7
5
  kRequest,
@@ -13,11 +11,10 @@ const {
13
11
  FST_ERR_DEC_ALREADY_PRESENT,
14
12
  FST_ERR_DEC_MISSING_DEPENDENCY,
15
13
  FST_ERR_DEC_AFTER_START,
14
+ FST_ERR_DEC_REFERENCE_TYPE,
16
15
  FST_ERR_DEC_DEPENDENCY_INVALID_TYPE
17
16
  } = require('./errors')
18
17
 
19
- const { FSTDEP006 } = require('./warnings')
20
-
21
18
  function decorate (instance, name, fn, dependencies) {
22
19
  if (Object.prototype.hasOwnProperty.call(instance, name)) {
23
20
  throw new FST_ERR_DEC_ALREADY_PRESENT(name)
@@ -58,7 +55,7 @@ function decorateConstructor (konstructor, name, fn, dependencies) {
58
55
 
59
56
  function checkReferenceType (name, fn) {
60
57
  if (typeof fn === 'object' && fn && !(typeof fn.getter === 'function' || typeof fn.setter === 'function')) {
61
- FSTDEP006(name)
58
+ throw new FST_ERR_DEC_REFERENCE_TYPE(name, typeof fn)
62
59
  }
63
60
  }
64
61
 
@@ -102,8 +99,7 @@ function checkDependencies (instance, name, deps) {
102
99
  throw new FST_ERR_DEC_DEPENDENCY_INVALID_TYPE(name)
103
100
  }
104
101
 
105
- // eslint-disable-next-line no-var
106
- for (var i = 0; i !== deps.length; ++i) {
102
+ for (let i = 0; i !== deps.length; ++i) {
107
103
  if (!checkExistence(instance, deps[i])) {
108
104
  throw new FST_ERR_DEC_MISSING_DEPENDENCY(deps[i])
109
105
  }
@@ -1,5 +1,5 @@
1
1
  // This file is autogenerated by build/build-error-serializer.js, do not edit
2
- /* istanbul ignore file */
2
+ /* c8 ignore start */
3
3
 
4
4
  'use strict'
5
5
 
@@ -117,3 +117,4 @@ let addComma = false
117
117
  return main
118
118
 
119
119
  }(validator, serializer)
120
+ /* c8 ignore stop */
package/lib/errors.js CHANGED
@@ -151,6 +151,10 @@ const codes = {
151
151
  'FST_ERR_DEC_AFTER_START',
152
152
  "The decorator '%s' has been added after start!"
153
153
  ),
154
+ FST_ERR_DEC_REFERENCE_TYPE: createError(
155
+ 'FST_ERR_DEC_REFERENCE_TYPE',
156
+ "The decorator '%s' of type '%s' is a reference type. Use the { getter, setter } interface instead."
157
+ ),
154
158
 
155
159
  /**
156
160
  * hooks
@@ -209,6 +213,27 @@ const codes = {
209
213
  TypeError
210
214
  ),
211
215
 
216
+ FST_ERR_LOG_INVALID_LOGGER_INSTANCE: createError(
217
+ 'FST_ERR_LOG_INVALID_LOGGER_INSTANCE',
218
+ 'loggerInstance only accepts a logger instance.',
219
+ 500,
220
+ TypeError
221
+ ),
222
+
223
+ FST_ERR_LOG_INVALID_LOGGER_CONFIG: createError(
224
+ 'FST_ERR_LOG_INVALID_LOGGER_CONFIG',
225
+ 'logger options only accepts a configuration object.',
226
+ 500,
227
+ TypeError
228
+ ),
229
+
230
+ FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED: createError(
231
+ 'FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED',
232
+ 'You cannot provide both logger and loggerInstance. Please provide only one.',
233
+ 500,
234
+ TypeError
235
+ ),
236
+
212
237
  /**
213
238
  * reply
214
239
  */
@@ -339,12 +364,6 @@ const codes = {
339
364
  'Unexpected error from async constraint',
340
365
  500
341
366
  ),
342
- FST_ERR_DEFAULT_ROUTE_INVALID_TYPE: createError(
343
- 'FST_ERR_DEFAULT_ROUTE_INVALID_TYPE',
344
- 'The defaultRoute type should be a function',
345
- 500,
346
- TypeError
347
- ),
348
367
  FST_ERR_INVALID_URL: createError(
349
368
  'FST_ERR_INVALID_URL',
350
369
  "URL must be a string. Received '%s'",
@@ -429,6 +448,12 @@ const codes = {
429
448
  'FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE',
430
449
  "The decorator '%s'%s is not present in %s"
431
450
  ),
451
+ FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER: createError(
452
+ 'FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER',
453
+ 'The %s plugin being registered mixes async and callback styles. Async plugin should not mix async and callback style.',
454
+ 500,
455
+ TypeError
456
+ ),
432
457
 
433
458
  /**
434
459
  * Avvio Errors
@@ -1,13 +1,18 @@
1
1
  'use strict'
2
2
 
3
+ const { bodylessMethods, bodyMethods } = require('./httpMethods')
4
+ const diagnostics = require('dc-polyfill')
3
5
  const { validate: validateSchema } = require('./validation')
4
6
  const { preValidationHookRunner, preHandlerHookRunner } = require('./hooks')
5
7
  const wrapThenable = require('./wrapThenable')
6
8
  const {
7
9
  kReplyIsError,
8
- kRouteContext
10
+ kRouteContext,
11
+ kFourOhFourContext
9
12
  } = require('./symbols')
10
13
 
14
+ const channels = diagnostics.tracingChannel('fastify.request.handler')
15
+
11
16
  function handleRequest (err, request, reply) {
12
17
  if (reply.sent === true) return
13
18
  if (err != null) {
@@ -20,45 +25,37 @@ function handleRequest (err, request, reply) {
20
25
  const headers = request.headers
21
26
  const context = request[kRouteContext]
22
27
 
23
- if (method === 'GET' || method === 'HEAD') {
28
+ if (bodylessMethods.has(method)) {
24
29
  handler(request, reply)
25
30
  return
26
31
  }
27
32
 
28
- const contentType = headers['content-type']
33
+ if (bodyMethods.has(method)) {
34
+ const contentType = headers['content-type']
35
+ const contentLength = headers['content-length']
36
+ const transferEncoding = headers['transfer-encoding']
29
37
 
30
- if (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'TRACE' || method === 'SEARCH' ||
31
- method === 'PROPFIND' || method === 'PROPPATCH' || method === 'LOCK' || method === 'REPORT' || method === 'MKCALENDAR') {
32
38
  if (contentType === undefined) {
33
39
  if (
34
- headers['transfer-encoding'] === undefined &&
35
- (headers['content-length'] === '0' || headers['content-length'] === undefined)
36
- ) { // Request has no body to parse
40
+ (contentLength === undefined || contentLength === '0') &&
41
+ transferEncoding === undefined
42
+ ) {
43
+ // Request has no body to parse
37
44
  handler(request, reply)
38
45
  } else {
39
46
  context.contentTypeParser.run('', handler, request, reply)
40
47
  }
41
48
  } else {
49
+ if (contentLength === undefined && transferEncoding === undefined && method === 'OPTIONS') {
50
+ // OPTIONS can have a Content-Type header without a body
51
+ handler(request, reply)
52
+ return
53
+ }
42
54
  context.contentTypeParser.run(contentType, handler, request, reply)
43
55
  }
44
56
  return
45
57
  }
46
58
 
47
- if (method === 'OPTIONS' || method === 'DELETE') {
48
- if (
49
- contentType !== undefined &&
50
- (
51
- headers['transfer-encoding'] !== undefined ||
52
- headers['content-length'] !== undefined
53
- )
54
- ) {
55
- context.contentTypeParser.run(contentType, handler, request, reply)
56
- } else {
57
- handler(request, reply)
58
- }
59
- return
60
- }
61
-
62
59
  // Return 404 instead of 405 see https://github.com/fastify/fastify/pull/862 for discussion
63
60
  handler(request, reply)
64
61
  }
@@ -126,28 +123,62 @@ function validationCompleted (request, reply, validationErr) {
126
123
  function preHandlerCallback (err, request, reply) {
127
124
  if (reply.sent) return
128
125
 
129
- if (err != null) {
130
- reply[kReplyIsError] = true
131
- reply.send(err)
132
- return
126
+ const context = request[kRouteContext]
127
+
128
+ if (!channels.hasSubscribers || context[kFourOhFourContext] === null) {
129
+ preHandlerCallbackInner(err, request, reply)
130
+ } else {
131
+ const store = {
132
+ request,
133
+ reply,
134
+ async: false,
135
+ route: {
136
+ url: context.config.url,
137
+ method: context.config.method
138
+ }
139
+ }
140
+ channels.start.runStores(store, preHandlerCallbackInner, undefined, err, request, reply, store)
133
141
  }
142
+ }
134
143
 
135
- let result
144
+ function preHandlerCallbackInner (err, request, reply, store) {
145
+ const context = request[kRouteContext]
136
146
 
137
147
  try {
138
- result = request[kRouteContext].handler(request, reply)
139
- } catch (err) {
140
- reply[kReplyIsError] = true
141
- reply.send(err)
142
- return
143
- }
148
+ if (err != null) {
149
+ reply[kReplyIsError] = true
150
+ reply.send(err)
151
+ if (store) {
152
+ store.error = err
153
+ channels.error.publish(store)
154
+ }
155
+ return
156
+ }
144
157
 
145
- if (result !== undefined) {
146
- if (result !== null && typeof result.then === 'function') {
147
- wrapThenable(result, reply)
148
- } else {
149
- reply.send(result)
158
+ let result
159
+
160
+ try {
161
+ result = context.handler(request, reply)
162
+ } catch (err) {
163
+ if (store) {
164
+ store.error = err
165
+ channels.error.publish(store)
166
+ }
167
+
168
+ reply[kReplyIsError] = true
169
+ reply.send(err)
170
+ return
171
+ }
172
+
173
+ if (result !== undefined) {
174
+ if (result !== null && typeof result.then === 'function') {
175
+ wrapThenable(result, reply, store)
176
+ } else {
177
+ reply.send(result)
178
+ }
150
179
  }
180
+ } finally {
181
+ if (store) channels.end.publish(store)
151
182
  }
152
183
  }
153
184
 
@@ -1,24 +1,40 @@
1
1
  'use strict'
2
2
 
3
+ const bodylessMethods = new Set([
4
+ // Standard
5
+ 'GET',
6
+ 'HEAD',
7
+ 'TRACE',
8
+
9
+ // WebDAV
10
+ 'UNLOCK'
11
+ ])
12
+
13
+ const bodyMethods = new Set([
14
+ // Standard
15
+ 'DELETE',
16
+ 'OPTIONS',
17
+ 'PATCH',
18
+ 'PUT',
19
+ 'POST',
20
+
21
+ // WebDAV
22
+ 'COPY',
23
+ 'LOCK',
24
+ 'MOVE',
25
+ 'MKCOL',
26
+ 'PROPFIND',
27
+ 'PROPPATCH',
28
+ 'REPORT',
29
+ 'SEARCH',
30
+ 'MKCALENDAR'
31
+ ])
32
+
3
33
  module.exports = {
34
+ bodylessMethods,
35
+ bodyMethods,
4
36
  supportedMethods: [
5
- 'DELETE',
6
- 'GET',
7
- 'HEAD',
8
- 'PATCH',
9
- 'POST',
10
- 'PUT',
11
- 'OPTIONS',
12
- 'PROPFIND',
13
- 'PROPPATCH',
14
- 'MKCOL',
15
- 'COPY',
16
- 'MOVE',
17
- 'LOCK',
18
- 'UNLOCK',
19
- 'TRACE',
20
- 'SEARCH',
21
- 'REPORT',
22
- 'MKCALENDAR'
37
+ ...bodylessMethods,
38
+ ...bodyMethods
23
39
  ]
24
40
  }
package/lib/logger.js CHANGED
@@ -11,7 +11,10 @@ const pino = require('pino')
11
11
  const { serializersSym } = pino.symbols
12
12
  const {
13
13
  FST_ERR_LOG_INVALID_DESTINATION,
14
- FST_ERR_LOG_INVALID_LOGGER
14
+ FST_ERR_LOG_INVALID_LOGGER,
15
+ FST_ERR_LOG_INVALID_LOGGER_INSTANCE,
16
+ FST_ERR_LOG_INVALID_LOGGER_CONFIG,
17
+ FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED
15
18
  } = require('./errors')
16
19
 
17
20
  function createPinoLogger (opts) {
@@ -51,7 +54,7 @@ const serializers = {
51
54
  method: req.method,
52
55
  url: req.url,
53
56
  version: req.headers && req.headers['accept-version'],
54
- hostname: req.hostname,
57
+ host: req.host,
55
58
  remoteAddress: req.ip,
56
59
  remotePort: req.socket ? req.socket.remotePort : undefined
57
60
  }
@@ -70,20 +73,35 @@ function now () {
70
73
  }
71
74
 
72
75
  function createLogger (options) {
73
- if (!options.logger) {
76
+ // if no logger is provided, then create a default logger
77
+ if (!options.loggerInstance && !options.logger) {
74
78
  const logger = nullLogger
75
79
  logger.child = () => logger
76
80
  return { logger, hasLogger: false }
77
81
  }
78
82
 
79
- if (validateLogger(options.logger)) {
83
+ if (options.logger && options.loggerInstance) {
84
+ throw new FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED()
85
+ }
86
+
87
+ // check if the logger instance has all required properties
88
+ if (validateLogger(options.loggerInstance)) {
80
89
  const logger = createPinoLogger({
81
- logger: options.logger,
82
- serializers: Object.assign({}, serializers, options.logger.serializers)
90
+ logger: options.loggerInstance,
91
+ serializers: Object.assign({}, serializers, options.loggerInstance.serializers)
83
92
  })
84
93
  return { logger, hasLogger: true }
85
94
  }
86
95
 
96
+ // if a logger instance is passed to logger, throw an exception
97
+ if (validateLogger(options.logger)) {
98
+ throw FST_ERR_LOG_INVALID_LOGGER_CONFIG()
99
+ }
100
+
101
+ if (options.loggerInstance) {
102
+ throw FST_ERR_LOG_INVALID_LOGGER_INSTANCE()
103
+ }
104
+
87
105
  const localLoggerOptions = {}
88
106
  if (Object.prototype.toString.call(options.logger) === '[object Object]') {
89
107
  Reflect.ownKeys(options.logger).forEach(prop => {
@@ -9,9 +9,9 @@ const {
9
9
  const { exist, existReply, existRequest } = require('./decorate')
10
10
  const {
11
11
  FST_ERR_PLUGIN_VERSION_MISMATCH,
12
- FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE
12
+ FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE,
13
+ FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER
13
14
  } = require('./errors')
14
- const { FSTWRN002 } = require('./warnings.js')
15
15
 
16
16
  function getMeta (fn) {
17
17
  return fn[Symbol.for('plugin-meta')]
@@ -106,11 +106,11 @@ function _checkDecorators (that, instance, decorators, name) {
106
106
 
107
107
  function checkVersion (fn) {
108
108
  const meta = getMeta(fn)
109
- if (!meta) return
109
+ if (meta == null || meta?.fastify == null) return
110
110
 
111
111
  const requiredVersion = meta.fastify
112
112
 
113
- const fastifyRc = /-rc.+$/.test(this.version)
113
+ const fastifyRc = /-(rc|pre|alpha).+$/.test(this.version)
114
114
  if (fastifyRc === true && semver.gt(this.version, semver.coerce(requiredVersion)) === true) {
115
115
  // A Fastify release candidate phase is taking place. In order to reduce
116
116
  // the effort needed to test plugins with the RC, we allow plugins targeting
@@ -138,7 +138,7 @@ function registerPluginName (fn) {
138
138
 
139
139
  function checkPluginHealthiness (fn, pluginName) {
140
140
  if (fn.constructor.name === 'AsyncFunction' && fn.length === 3) {
141
- FSTWRN002(pluginName || 'anonymous')
141
+ throw new FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER(pluginName)
142
142
  }
143
143
  }
144
144