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,152 @@
1
+ 'use strict'
2
+
3
+ const {
4
+ kReply,
5
+ kRequest,
6
+ kState,
7
+ kHasBeenDecorated
8
+ } = require('./symbols.js')
9
+
10
+ const {
11
+ FST_ERR_DEC_ALREADY_PRESENT,
12
+ FST_ERR_DEC_MISSING_DEPENDENCY,
13
+ FST_ERR_DEC_AFTER_START,
14
+ FST_ERR_DEC_REFERENCE_TYPE,
15
+ FST_ERR_DEC_DEPENDENCY_INVALID_TYPE,
16
+ FST_ERR_DEC_UNDECLARED
17
+ } = require('./errors')
18
+
19
+ function decorate (instance, name, fn, dependencies) {
20
+ if (Object.hasOwn(instance, name)) {
21
+ throw new FST_ERR_DEC_ALREADY_PRESENT(name)
22
+ }
23
+
24
+ checkDependencies(instance, name, dependencies)
25
+
26
+ if (fn && (typeof fn.getter === 'function' || typeof fn.setter === 'function')) {
27
+ Object.defineProperty(instance, name, {
28
+ get: fn.getter,
29
+ set: fn.setter
30
+ })
31
+ } else {
32
+ instance[name] = fn
33
+ }
34
+ }
35
+
36
+ function getInstanceDecorator (name) {
37
+ if (!checkExistence(this, name)) {
38
+ throw new FST_ERR_DEC_UNDECLARED(name, 'instance')
39
+ }
40
+
41
+ if (typeof this[name] === 'function') {
42
+ return this[name].bind(this)
43
+ }
44
+
45
+ return this[name]
46
+ }
47
+
48
+ function decorateConstructor (konstructor, name, fn, dependencies) {
49
+ const instance = konstructor.prototype
50
+ if (Object.hasOwn(instance, name) || hasKey(konstructor, name)) {
51
+ throw new FST_ERR_DEC_ALREADY_PRESENT(name)
52
+ }
53
+
54
+ konstructor[kHasBeenDecorated] = true
55
+ checkDependencies(konstructor, name, dependencies)
56
+
57
+ if (fn && (typeof fn.getter === 'function' || typeof fn.setter === 'function')) {
58
+ Object.defineProperty(instance, name, {
59
+ get: fn.getter,
60
+ set: fn.setter
61
+ })
62
+ } else if (typeof fn === 'function') {
63
+ instance[name] = fn
64
+ } else {
65
+ konstructor.props.push({ key: name, value: fn })
66
+ }
67
+ }
68
+
69
+ function checkReferenceType (name, fn) {
70
+ if (typeof fn === 'object' && fn && !(typeof fn.getter === 'function' || typeof fn.setter === 'function')) {
71
+ throw new FST_ERR_DEC_REFERENCE_TYPE(name, typeof fn)
72
+ }
73
+ }
74
+
75
+ function decorateFastify (name, fn, dependencies) {
76
+ assertNotStarted(this, name)
77
+ decorate(this, name, fn, dependencies)
78
+ return this
79
+ }
80
+
81
+ function checkExistence (instance, name) {
82
+ if (name) {
83
+ return name in instance || (instance.prototype && name in instance.prototype) || hasKey(instance, name)
84
+ }
85
+
86
+ return instance in this
87
+ }
88
+
89
+ function hasKey (fn, name) {
90
+ if (fn.props) {
91
+ return fn.props.find(({ key }) => key === name)
92
+ }
93
+ return false
94
+ }
95
+
96
+ function checkRequestExistence (name) {
97
+ if (name && hasKey(this[kRequest], name)) return true
98
+ return checkExistence(this[kRequest].prototype, name)
99
+ }
100
+
101
+ function checkReplyExistence (name) {
102
+ if (name && hasKey(this[kReply], name)) return true
103
+ return checkExistence(this[kReply].prototype, name)
104
+ }
105
+
106
+ function checkDependencies (instance, name, deps) {
107
+ if (deps === undefined || deps === null) {
108
+ return
109
+ }
110
+
111
+ if (!Array.isArray(deps)) {
112
+ throw new FST_ERR_DEC_DEPENDENCY_INVALID_TYPE(name)
113
+ }
114
+
115
+ for (let i = 0; i !== deps.length; ++i) {
116
+ if (!checkExistence(instance, deps[i])) {
117
+ throw new FST_ERR_DEC_MISSING_DEPENDENCY(deps[i])
118
+ }
119
+ }
120
+ }
121
+
122
+ function decorateReply (name, fn, dependencies) {
123
+ assertNotStarted(this, name)
124
+ checkReferenceType(name, fn)
125
+ decorateConstructor(this[kReply], name, fn, dependencies)
126
+ return this
127
+ }
128
+
129
+ function decorateRequest (name, fn, dependencies) {
130
+ assertNotStarted(this, name)
131
+ checkReferenceType(name, fn)
132
+ decorateConstructor(this[kRequest], name, fn, dependencies)
133
+ return this
134
+ }
135
+
136
+ function assertNotStarted (instance, name) {
137
+ if (instance[kState].started) {
138
+ throw new FST_ERR_DEC_AFTER_START(name)
139
+ }
140
+ }
141
+
142
+ module.exports = {
143
+ add: decorateFastify,
144
+ exist: checkExistence,
145
+ existRequest: checkRequestExistence,
146
+ existReply: checkReplyExistence,
147
+ dependencies: checkDependencies,
148
+ decorateReply,
149
+ decorateRequest,
150
+ getInstanceDecorator,
151
+ hasKey
152
+ }
@@ -0,0 +1,173 @@
1
+ 'use strict'
2
+
3
+ const statusCodes = require('node:http').STATUS_CODES
4
+ const wrapThenable = require('./wrap-thenable.js')
5
+ const { setErrorStatusCode } = require('./error-status.js')
6
+ const {
7
+ kReplyHeaders,
8
+ kReplyNextErrorHandler,
9
+ kReplyIsRunningOnErrorHook,
10
+ kRouteContext,
11
+ kDisableRequestLogging
12
+ } = require('./symbols.js')
13
+
14
+ const {
15
+ FST_ERR_REP_INVALID_PAYLOAD_TYPE,
16
+ FST_ERR_FAILED_ERROR_SERIALIZATION
17
+ } = require('./errors')
18
+
19
+ const { getSchemaSerializer } = require('./schemas')
20
+
21
+ const serializeError = require('./error-serializer')
22
+
23
+ const rootErrorHandler = {
24
+ func: defaultErrorHandler,
25
+ toJSON () {
26
+ return this.func.name.toString() + '()'
27
+ }
28
+ }
29
+
30
+ function handleError (reply, error, cb) {
31
+ reply[kReplyIsRunningOnErrorHook] = false
32
+
33
+ const context = reply[kRouteContext]
34
+ if (reply[kReplyNextErrorHandler] === false) {
35
+ fallbackErrorHandler(error, reply, function (reply, payload) {
36
+ try {
37
+ reply.raw.writeHead(reply.raw.statusCode, reply[kReplyHeaders])
38
+ } catch (error) {
39
+ if (!reply.log[kDisableRequestLogging]) {
40
+ reply.log.warn(
41
+ { req: reply.request, res: reply, err: error },
42
+ error?.message
43
+ )
44
+ }
45
+ reply.raw.writeHead(reply.raw.statusCode)
46
+ }
47
+ reply.raw.end(payload)
48
+ })
49
+ return
50
+ }
51
+ const errorHandler = reply[kReplyNextErrorHandler] || context.errorHandler
52
+
53
+ // In case the error handler throws, we set the next errorHandler so we can error again
54
+ reply[kReplyNextErrorHandler] = Object.getPrototypeOf(errorHandler)
55
+
56
+ // we need to remove content-type to allow content-type guessing for serialization
57
+ delete reply[kReplyHeaders]['content-type']
58
+ delete reply[kReplyHeaders]['content-length']
59
+
60
+ const func = errorHandler.func
61
+
62
+ if (!func) {
63
+ reply[kReplyNextErrorHandler] = false
64
+ fallbackErrorHandler(error, reply, cb)
65
+ return
66
+ }
67
+
68
+ try {
69
+ const result = func(error, reply.request, reply)
70
+ if (result !== undefined) {
71
+ if (result !== null && typeof result.then === 'function') {
72
+ wrapThenable(result, reply)
73
+ } else {
74
+ reply.send(result)
75
+ }
76
+ }
77
+ } catch (err) {
78
+ reply.send(err)
79
+ }
80
+ }
81
+
82
+ function defaultErrorHandler (error, request, reply) {
83
+ setErrorHeaders(error, reply)
84
+ setErrorStatusCode(reply, error)
85
+ if (reply.statusCode < 500) {
86
+ if (!reply.log[kDisableRequestLogging]) {
87
+ reply.log.info(
88
+ { res: reply, err: error },
89
+ error?.message
90
+ )
91
+ }
92
+ } else {
93
+ if (!reply.log[kDisableRequestLogging]) {
94
+ reply.log.error(
95
+ { req: request, res: reply, err: error },
96
+ error?.message
97
+ )
98
+ }
99
+ }
100
+ reply.send(error)
101
+ }
102
+
103
+ function fallbackErrorHandler (error, reply, cb) {
104
+ const res = reply.raw
105
+ const statusCode = reply.statusCode
106
+ reply[kReplyHeaders]['content-type'] = reply[kReplyHeaders]['content-type'] ?? 'application/json; charset=utf-8'
107
+ let payload
108
+ try {
109
+ const serializerFn = getSchemaSerializer(reply[kRouteContext], statusCode, reply[kReplyHeaders]['content-type'])
110
+ if (serializerFn === false) {
111
+ payload = serializeError({
112
+ error: statusCodes[statusCode + ''],
113
+ code: error.code,
114
+ message: error.message,
115
+ statusCode
116
+ })
117
+ } else {
118
+ payload = serializerFn(Object.create(error, {
119
+ error: { value: statusCodes[statusCode + ''] },
120
+ message: { value: error.message },
121
+ statusCode: { value: statusCode }
122
+ }))
123
+ }
124
+ } catch (err) {
125
+ if (!reply.log[kDisableRequestLogging]) {
126
+ // error is always FST_ERR_SCH_SERIALIZATION_BUILD because this is called from route/compileSchemasForSerialization
127
+ reply.log.error({ err, statusCode: res.statusCode }, 'The serializer for the given status code failed')
128
+ }
129
+ reply.code(500)
130
+ payload = serializeError(new FST_ERR_FAILED_ERROR_SERIALIZATION(err.message, error.message))
131
+ }
132
+
133
+ if (typeof payload !== 'string' && !Buffer.isBuffer(payload)) {
134
+ payload = serializeError(new FST_ERR_REP_INVALID_PAYLOAD_TYPE(typeof payload))
135
+ }
136
+
137
+ reply[kReplyHeaders]['content-length'] = '' + Buffer.byteLength(payload)
138
+
139
+ cb(reply, payload)
140
+ }
141
+
142
+ function buildErrorHandler (parent = rootErrorHandler, func) {
143
+ if (!func) {
144
+ return parent
145
+ }
146
+
147
+ const errorHandler = Object.create(parent)
148
+ errorHandler.func = func
149
+ return errorHandler
150
+ }
151
+
152
+ function setErrorHeaders (error, reply) {
153
+ const res = reply.raw
154
+ let statusCode = res.statusCode
155
+ statusCode = (statusCode >= 400) ? statusCode : 500
156
+ // treat undefined and null as same
157
+ if (error != null) {
158
+ if (error.headers !== undefined) {
159
+ reply.headers(error.headers)
160
+ }
161
+ if (error.status >= 400) {
162
+ statusCode = error.status
163
+ } else if (error.statusCode >= 400) {
164
+ statusCode = error.statusCode
165
+ }
166
+ }
167
+ res.statusCode = statusCode
168
+ }
169
+
170
+ module.exports = {
171
+ buildErrorHandler,
172
+ handleError
173
+ }
@@ -0,0 +1,134 @@
1
+ // This file is autogenerated by build/build-error-serializer.js, do not edit
2
+ /* c8 ignore start */
3
+
4
+ 'use strict'
5
+
6
+ const Serializer = require('fast-json-stringify/lib/serializer')
7
+ const serializerState = {"mode":"standalone"}
8
+ const serializer = Serializer.restoreFromState(serializerState)
9
+
10
+ const validator = null
11
+
12
+
13
+ module.exports = function anonymous(validator,serializer
14
+ ) {
15
+
16
+
17
+ const {
18
+ asString,
19
+ asNumber,
20
+ asBoolean,
21
+ asDateTime,
22
+ asDate,
23
+ asTime,
24
+ asUnsafeString
25
+ } = serializer
26
+
27
+ const asInteger = serializer.asInteger.bind(serializer)
28
+
29
+
30
+ const JSON_STR_BEGIN_OBJECT = '{'
31
+ const JSON_STR_END_OBJECT = '}'
32
+ const JSON_STR_BEGIN_ARRAY = '['
33
+ const JSON_STR_END_ARRAY = ']'
34
+ const JSON_STR_COMMA = ','
35
+ const JSON_STR_COLONS = ':'
36
+ const JSON_STR_QUOTE = '"'
37
+ const JSON_STR_EMPTY_OBJECT = JSON_STR_BEGIN_OBJECT + JSON_STR_END_OBJECT
38
+ const JSON_STR_EMPTY_ARRAY = JSON_STR_BEGIN_ARRAY + JSON_STR_END_ARRAY
39
+ const JSON_STR_EMPTY_STRING = JSON_STR_QUOTE + JSON_STR_QUOTE
40
+ const JSON_STR_NULL = 'null'
41
+
42
+
43
+
44
+ // #
45
+ function anonymous0 (input) {
46
+ const obj = (input && typeof input.toJSON === 'function')
47
+ ? input.toJSON()
48
+ : input
49
+
50
+ if (obj === null) return JSON_STR_EMPTY_OBJECT
51
+
52
+ let value
53
+ let json = JSON_STR_BEGIN_OBJECT
54
+ let addComma = false
55
+
56
+ value = obj["statusCode"]
57
+ if (value !== undefined) {
58
+ !addComma && (addComma = true) || (json += JSON_STR_COMMA)
59
+ json += "\"statusCode\":"
60
+ json += asNumber(value)
61
+ }
62
+
63
+ value = obj["code"]
64
+ if (value !== undefined) {
65
+ !addComma && (addComma = true) || (json += JSON_STR_COMMA)
66
+ json += "\"code\":"
67
+
68
+ if (typeof value !== 'string') {
69
+ if (value === null) {
70
+ json += JSON_STR_EMPTY_STRING
71
+ } else if (value instanceof Date) {
72
+ json += JSON_STR_QUOTE + value.toISOString() + JSON_STR_QUOTE
73
+ } else if (value instanceof RegExp) {
74
+ json += asString(value.source)
75
+ } else {
76
+ json += asString(value.toString())
77
+ }
78
+ } else {
79
+ json += asString(value)
80
+ }
81
+
82
+ }
83
+
84
+ value = obj["error"]
85
+ if (value !== undefined) {
86
+ !addComma && (addComma = true) || (json += JSON_STR_COMMA)
87
+ json += "\"error\":"
88
+
89
+ if (typeof value !== 'string') {
90
+ if (value === null) {
91
+ json += JSON_STR_EMPTY_STRING
92
+ } else if (value instanceof Date) {
93
+ json += JSON_STR_QUOTE + value.toISOString() + JSON_STR_QUOTE
94
+ } else if (value instanceof RegExp) {
95
+ json += asString(value.source)
96
+ } else {
97
+ json += asString(value.toString())
98
+ }
99
+ } else {
100
+ json += asString(value)
101
+ }
102
+
103
+ }
104
+
105
+ value = obj["message"]
106
+ if (value !== undefined) {
107
+ !addComma && (addComma = true) || (json += JSON_STR_COMMA)
108
+ json += "\"message\":"
109
+
110
+ if (typeof value !== 'string') {
111
+ if (value === null) {
112
+ json += JSON_STR_EMPTY_STRING
113
+ } else if (value instanceof Date) {
114
+ json += JSON_STR_QUOTE + value.toISOString() + JSON_STR_QUOTE
115
+ } else if (value instanceof RegExp) {
116
+ json += asString(value.source)
117
+ } else {
118
+ json += asString(value.toString())
119
+ }
120
+ } else {
121
+ json += asString(value)
122
+ }
123
+
124
+ }
125
+
126
+ return json + JSON_STR_END_OBJECT
127
+
128
+ }
129
+
130
+ const main = anonymous0
131
+ return main
132
+
133
+ }(validator, serializer)
134
+ /* c8 ignore stop */
@@ -0,0 +1,14 @@
1
+ 'use strict'
2
+
3
+ const {
4
+ kReplyHasStatusCode
5
+ } = require('./symbols')
6
+
7
+ function setErrorStatusCode (reply, err) {
8
+ if (!reply[kReplyHasStatusCode] || reply.statusCode === 200) {
9
+ const statusCode = err && (err.statusCode || err.status)
10
+ reply.code(statusCode >= 400 ? statusCode : 500)
11
+ }
12
+ }
13
+
14
+ module.exports = { setErrorStatusCode }