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,421 @@
1
+ 'use strict'
2
+
3
+ const { test } = require('node:test')
4
+ const Fastify = require('../fastify')
5
+ const immediate = require('node:util').promisify(setImmediate)
6
+
7
+ test('onReady should be called in order', (t, done) => {
8
+ t.plan(7)
9
+ const fastify = Fastify()
10
+
11
+ let order = 0
12
+
13
+ fastify.addHook('onReady', function (done) {
14
+ t.assert.strictEqual(order++, 0, 'called in root')
15
+ t.assert.strictEqual(this.pluginName, fastify.pluginName, 'the this binding is the right instance')
16
+ done()
17
+ })
18
+
19
+ fastify.register(async (childOne, o) => {
20
+ childOne.addHook('onReady', function (done) {
21
+ t.assert.strictEqual(order++, 1, 'called in childOne')
22
+ t.assert.strictEqual(this.pluginName, childOne.pluginName, 'the this binding is the right instance')
23
+ done()
24
+ })
25
+
26
+ childOne.register(async (childTwo, o) => {
27
+ childTwo.addHook('onReady', async function () {
28
+ await immediate()
29
+ t.assert.strictEqual(order++, 2, 'called in childTwo')
30
+ t.assert.strictEqual(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')
31
+ })
32
+ })
33
+ })
34
+
35
+ fastify.ready(err => {
36
+ t.assert.ifError(err)
37
+ done()
38
+ })
39
+ })
40
+
41
+ test('onReady should be called once', async (t) => {
42
+ const app = Fastify()
43
+ let counter = 0
44
+
45
+ app.addHook('onReady', async function () {
46
+ counter++
47
+ })
48
+
49
+ const promises = [1, 2, 3, 4, 5].map((id) => app.ready().then(() => id))
50
+
51
+ const result = await Promise.race(promises)
52
+
53
+ t.assert.strictEqual(result, 1, 'Should resolve in order')
54
+ t.assert.strictEqual(counter, 1, 'Should call onReady only once')
55
+ })
56
+
57
+ test('async onReady should be called in order', async t => {
58
+ t.plan(7)
59
+ const fastify = Fastify()
60
+
61
+ let order = 0
62
+
63
+ fastify.addHook('onReady', async function () {
64
+ await immediate()
65
+ t.assert.strictEqual(order++, 0, 'called in root')
66
+ t.assert.strictEqual(this.pluginName, fastify.pluginName, 'the this binding is the right instance')
67
+ })
68
+
69
+ fastify.register(async (childOne, o) => {
70
+ childOne.addHook('onReady', async function () {
71
+ await immediate()
72
+ t.assert.strictEqual(order++, 1, 'called in childOne')
73
+ t.assert.strictEqual(this.pluginName, childOne.pluginName, 'the this binding is the right instance')
74
+ })
75
+
76
+ childOne.register(async (childTwo, o) => {
77
+ childTwo.addHook('onReady', async function () {
78
+ await immediate()
79
+ t.assert.strictEqual(order++, 2, 'called in childTwo')
80
+ t.assert.strictEqual(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')
81
+ })
82
+ })
83
+ })
84
+
85
+ await fastify.ready()
86
+ t.assert.ok('ready')
87
+ })
88
+
89
+ test('mix ready and onReady', async t => {
90
+ t.plan(2)
91
+ const fastify = Fastify()
92
+ let order = 0
93
+
94
+ fastify.addHook('onReady', async function () {
95
+ await immediate()
96
+ order++
97
+ })
98
+
99
+ await fastify.ready()
100
+ t.assert.strictEqual(order, 1)
101
+
102
+ await fastify.ready()
103
+ t.assert.strictEqual(order, 1, 'ready hooks execute once')
104
+ })
105
+
106
+ test('listen and onReady order', async t => {
107
+ t.plan(9)
108
+
109
+ const fastify = Fastify()
110
+ let order = 0
111
+
112
+ fastify.register((instance, opts, done) => {
113
+ instance.ready(checkOrder.bind(null, 0))
114
+ instance.addHook('onReady', checkOrder.bind(null, 4))
115
+
116
+ instance.register((subinstance, opts, done) => {
117
+ subinstance.ready(checkOrder.bind(null, 1))
118
+ subinstance.addHook('onReady', checkOrder.bind(null, 5))
119
+
120
+ subinstance.register((realSubInstance, opts, done) => {
121
+ realSubInstance.ready(checkOrder.bind(null, 2))
122
+ realSubInstance.addHook('onReady', checkOrder.bind(null, 6))
123
+ done()
124
+ })
125
+ done()
126
+ })
127
+ done()
128
+ })
129
+
130
+ fastify.addHook('onReady', checkOrder.bind(null, 3))
131
+
132
+ await fastify.ready()
133
+ t.assert.ok('trigger the onReady')
134
+ await fastify.listen({ port: 0 })
135
+ t.assert.ok('do not trigger the onReady')
136
+
137
+ await fastify.close()
138
+
139
+ function checkOrder (shouldbe) {
140
+ t.assert.strictEqual(order, shouldbe)
141
+ order++
142
+ }
143
+ })
144
+
145
+ test('multiple ready calls', async t => {
146
+ t.plan(11)
147
+
148
+ const fastify = Fastify()
149
+ let order = 0
150
+
151
+ fastify.register(async (instance, opts) => {
152
+ instance.ready(checkOrder.bind(null, 1))
153
+ instance.addHook('onReady', checkOrder.bind(null, 6))
154
+
155
+ await instance.register(async (subinstance, opts) => {
156
+ subinstance.ready(checkOrder.bind(null, 2))
157
+ subinstance.addHook('onReady', checkOrder.bind(null, 7))
158
+ })
159
+
160
+ t.assert.strictEqual(order, 0, 'ready and hooks not triggered yet')
161
+ order++
162
+ })
163
+
164
+ fastify.addHook('onReady', checkOrder.bind(null, 3))
165
+ fastify.addHook('onReady', checkOrder.bind(null, 4))
166
+ fastify.addHook('onReady', checkOrder.bind(null, 5))
167
+
168
+ await fastify.ready()
169
+ t.assert.ok('trigger the onReady')
170
+
171
+ await fastify.ready()
172
+ t.assert.ok('do not trigger the onReady')
173
+
174
+ await fastify.ready()
175
+ t.assert.ok('do not trigger the onReady')
176
+
177
+ function checkOrder (shouldbe) {
178
+ t.assert.strictEqual(order, shouldbe)
179
+ order++
180
+ }
181
+ })
182
+
183
+ test('onReady should manage error in sync', (t, done) => {
184
+ t.plan(4)
185
+ const fastify = Fastify()
186
+
187
+ fastify.addHook('onReady', function (done) {
188
+ t.assert.ok('called in root')
189
+ done()
190
+ })
191
+
192
+ fastify.register(async (childOne, o) => {
193
+ childOne.addHook('onReady', function (done) {
194
+ t.assert.ok('called in childOne')
195
+ done(new Error('FAIL ON READY'))
196
+ })
197
+
198
+ childOne.register(async (childTwo, o) => {
199
+ childTwo.addHook('onReady', async function () {
200
+ t.assert.fail('should not be called')
201
+ })
202
+ })
203
+ })
204
+
205
+ fastify.ready(err => {
206
+ t.assert.ok(err)
207
+ t.assert.strictEqual(err.message, 'FAIL ON READY')
208
+ done()
209
+ })
210
+ })
211
+
212
+ test('onReady should manage error in async', (t, done) => {
213
+ t.plan(4)
214
+ const fastify = Fastify()
215
+
216
+ fastify.addHook('onReady', function (done) {
217
+ t.assert.ok('called in root')
218
+ done()
219
+ })
220
+
221
+ fastify.register(async (childOne, o) => {
222
+ childOne.addHook('onReady', async function () {
223
+ t.assert.ok('called in childOne')
224
+ throw new Error('FAIL ON READY')
225
+ })
226
+
227
+ childOne.register(async (childTwo, o) => {
228
+ childTwo.addHook('onReady', async function () {
229
+ t.assert.fail('should not be called')
230
+ })
231
+ })
232
+ })
233
+
234
+ fastify.ready(err => {
235
+ t.assert.ok(err)
236
+ t.assert.strictEqual(err.message, 'FAIL ON READY')
237
+ done()
238
+ })
239
+ })
240
+
241
+ test('onReady should manage sync error', (t, done) => {
242
+ t.plan(4)
243
+ const fastify = Fastify()
244
+
245
+ fastify.addHook('onReady', function (done) {
246
+ t.assert.ok('called in root')
247
+ done()
248
+ })
249
+
250
+ fastify.register(async (childOne, o) => {
251
+ childOne.addHook('onReady', function (done) {
252
+ t.assert.ok('called in childOne')
253
+ throw new Error('FAIL UNWANTED SYNC EXCEPTION')
254
+ })
255
+
256
+ childOne.register(async (childTwo, o) => {
257
+ childTwo.addHook('onReady', async function () {
258
+ t.assert.fail('should not be called')
259
+ })
260
+ })
261
+ })
262
+
263
+ fastify.ready(err => {
264
+ t.assert.ok(err)
265
+ t.assert.strictEqual(err.message, 'FAIL UNWANTED SYNC EXCEPTION')
266
+ done()
267
+ })
268
+ })
269
+
270
+ test('onReady can not add decorators or application hooks', (t, done) => {
271
+ t.plan(3)
272
+ const fastify = Fastify()
273
+
274
+ fastify.addHook('onReady', function (done) {
275
+ t.assert.ok('called in root')
276
+ fastify.decorate('test', () => {})
277
+
278
+ fastify.addHook('onReady', async function () {
279
+ t.assert.fail('it will be not called')
280
+ })
281
+ done()
282
+ })
283
+
284
+ fastify.addHook('onReady', function (done) {
285
+ t.assert.ok(this.hasDecorator('test'))
286
+ done()
287
+ })
288
+
289
+ fastify.ready(err => {
290
+ t.assert.ifError(err)
291
+ done()
292
+ })
293
+ })
294
+
295
+ test('onReady cannot add lifecycle hooks', (t, done) => {
296
+ t.plan(5)
297
+ const fastify = Fastify()
298
+
299
+ fastify.addHook('onReady', function (done) {
300
+ t.assert.ok('called in root')
301
+ try {
302
+ fastify.addHook('onRequest', (request, reply, done) => {})
303
+ } catch (error) {
304
+ t.assert.ok(error)
305
+ t.assert.strictEqual(error.message, 'Root plugin has already booted')
306
+ // TODO: look where the error pops up
307
+ t.assert.strictEqual(error.code, 'AVV_ERR_ROOT_PLG_BOOTED')
308
+ done(error)
309
+ }
310
+ })
311
+
312
+ fastify.addHook('onRequest', (request, reply, done) => {})
313
+ fastify.get('/', async () => 'hello')
314
+
315
+ fastify.ready((err) => {
316
+ t.assert.ok(err)
317
+ done()
318
+ })
319
+ })
320
+
321
+ test('onReady throw loading error', t => {
322
+ t.plan(2)
323
+ const fastify = Fastify()
324
+
325
+ try {
326
+ fastify.addHook('onReady', async function (done) {})
327
+ } catch (e) {
328
+ t.assert.strictEqual(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')
329
+ t.assert.ok(e.message === 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')
330
+ }
331
+ })
332
+
333
+ test('onReady does not call done', (t, done) => {
334
+ t.plan(6)
335
+ const fastify = Fastify({ pluginTimeout: 500 })
336
+
337
+ fastify.addHook('onReady', function someHookName (done) {
338
+ t.assert.ok('called in root')
339
+ // done() // don't call done to test timeout
340
+ })
341
+
342
+ fastify.ready(err => {
343
+ t.assert.ok(err)
344
+ t.assert.strictEqual(err.message, 'A callback for \'onReady\' hook "someHookName" timed out. You may have forgotten to call \'done\' function or to resolve a Promise')
345
+ t.assert.strictEqual(err.code, 'FST_ERR_HOOK_TIMEOUT')
346
+ t.assert.ok(err.cause)
347
+ t.assert.strictEqual(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
348
+ done()
349
+ })
350
+ })
351
+
352
+ test('onReady execution order', (t, done) => {
353
+ t.plan(3)
354
+ const fastify = Fastify({ })
355
+
356
+ let i = 0
357
+ fastify.ready(() => { i++; t.assert.strictEqual(i, 1) })
358
+ fastify.ready(() => { i++; t.assert.strictEqual(i, 2) })
359
+ fastify.ready(() => {
360
+ i++
361
+ t.assert.strictEqual(i, 3)
362
+ done()
363
+ })
364
+ })
365
+
366
+ test('ready return the server with callback', (t, done) => {
367
+ t.plan(2)
368
+ const fastify = Fastify()
369
+
370
+ fastify.ready((err, instance) => {
371
+ t.assert.ifError(err)
372
+ t.assert.deepStrictEqual(instance, fastify)
373
+ done()
374
+ })
375
+ })
376
+
377
+ test('ready return the server with Promise', async t => {
378
+ t.plan(1)
379
+ const fastify = Fastify()
380
+
381
+ await fastify.ready()
382
+ .then(instance => { t.assert.deepStrictEqual(instance, fastify) })
383
+ .catch(err => { t.assert.fail(err) })
384
+ })
385
+
386
+ test('ready return registered', async t => {
387
+ t.plan(4)
388
+ const fastify = Fastify()
389
+
390
+ fastify.register((one, opts, done) => {
391
+ one.ready().then(itself => { t.assert.deepStrictEqual(itself, one) })
392
+ done()
393
+ })
394
+
395
+ fastify.register((two, opts, done) => {
396
+ two.ready().then(itself => { t.assert.deepStrictEqual(itself, two) })
397
+
398
+ two.register((twoDotOne, opts, done) => {
399
+ twoDotOne.ready().then(itself => { t.assert.deepStrictEqual(itself, twoDotOne) })
400
+ done()
401
+ })
402
+ done()
403
+ })
404
+
405
+ await fastify.ready()
406
+ .then(instance => { t.assert.deepStrictEqual(instance, fastify) })
407
+ .catch(err => { t.assert.fail(err) })
408
+ })
409
+
410
+ test('do not crash with error in follow up onReady hook', async t => {
411
+ const fastify = Fastify()
412
+
413
+ fastify.addHook('onReady', async function () {
414
+ })
415
+
416
+ fastify.addHook('onReady', function () {
417
+ throw new Error('kaboom')
418
+ })
419
+
420
+ await t.assert.rejects(fastify.ready())
421
+ })