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,58 @@
1
+
2
+ <h1 align="center">Fastify</h1>
3
+
4
+ **Table of contents**
5
+ - [Warnings](#warnings)
6
+ - [Warnings In Fastify](#warnings-in-fastify)
7
+ - [Fastify Warning Codes](#fastify-warning-codes)
8
+ - [FSTWRN001](#FSTWRN001)
9
+ - [FSTWRN002](#FSTWRN002)
10
+ - [Fastify Deprecation Codes](#fastify-deprecation-codes)
11
+ - [FSTDEP022](#FSTDEP022)
12
+
13
+ ## Warnings
14
+
15
+ ### Warnings In Fastify
16
+
17
+ Fastify uses Node.js's [warning event](https://nodejs.org/api/process.html#event-warning)
18
+ API to notify users of deprecated features and coding mistakes. Fastify's
19
+ warnings are recognizable by the `FSTWRN` and `FSTDEP` prefixes. When
20
+ encountering such a warning, it is highly recommended to determine the cause
21
+ using the [`--trace-warnings`](https://nodejs.org/api/cli.html#--trace-warnings)
22
+ and [`--trace-deprecation`](https://nodejs.org/api/cli.html#--trace-deprecation)
23
+ flags. These produce stack traces pointing to where the issue occurs in the
24
+ application's code. Issues opened about warnings without this information will
25
+ be closed due to lack of details.
26
+
27
+ Warnings can also be disabled, though it is not recommended. If necessary, use
28
+ one of the following methods:
29
+
30
+ - Set the `NODE_NO_WARNINGS` environment variable to `1`
31
+ - Pass the `--no-warnings` flag to the node process
32
+ - Set `no-warnings` in the `NODE_OPTIONS` environment variable
33
+
34
+ For more information on disabling warnings, see [Node's documentation](https://nodejs.org/api/cli.html).
35
+
36
+ Disabling warnings may cause issues when upgrading Fastify versions. Only
37
+ experienced users should consider disabling warnings.
38
+
39
+ ### Fastify Warning Codes
40
+
41
+ | Code | Description | How to solve | Discussion |
42
+ | ---- | ----------- | ------------ | ---------- |
43
+ | <a id="FSTWRN001">FSTWRN001</a> | The specified schema for a route is missing. This may indicate the schema is not well specified. | Check the schema for the route. | [#4647](https://github.com/fastify/fastify/pull/4647) |
44
+ | <a id="FSTWRN002">FSTWRN002</a> | The %s plugin being registered mixes async and callback styles, which will result in an error in `fastify@5`. | Do not mix async and callback style. | [#5139](https://github.com/fastify/fastify/pull/5139) |
45
+
46
+
47
+ ### Fastify Deprecation Codes
48
+
49
+ Deprecation codes are supported by the Node.js CLI options:
50
+
51
+ - [--no-deprecation](https://nodejs.org/api/cli.html#--no-deprecation)
52
+ - [--throw-deprecation](https://nodejs.org/api/cli.html#--throw-deprecation)
53
+ - [--trace-deprecation](https://nodejs.org/api/cli.html#--trace-deprecation)
54
+
55
+
56
+ | Code | Description | How to solve | Discussion |
57
+ | ---- | ----------- | ------------ | ---------- |
58
+ | <a id="FSTDEP022">FSTDEP022</a> | You are trying to access the deprecated router options on top option properties. | Use `options.routerOptions`. | [#5985](https://github.com/fastify/fastify/pull/5985)
package/docs/index.md ADDED
@@ -0,0 +1,24 @@
1
+ <h1 align="center">Fastify</h1>
2
+
3
+ The documentation for Fastify is split into two categories:
4
+
5
+ - [Reference documentation](./Reference/Index.md)
6
+ - [Guides](./Guides/Index.md)
7
+
8
+ The reference documentation utilizes a very formal style in an effort to document
9
+ Fastify's API and implementation details thoroughly for the developer who needs
10
+ such. The guides category utilizes an informal educational style as a means to
11
+ introduce newcomers to core and advanced Fastify concepts.
12
+
13
+ ## Where To Start
14
+
15
+ Complete newcomers to Fastify should first read our [Getting
16
+ Started](./Guides/Getting-Started.md) guide.
17
+
18
+ Developers experienced with Fastify should consult the [reference
19
+ documentation](./Reference/Index.md) directly to find the topic they are seeking
20
+ more information about.
21
+
22
+ ## Additional Documentation
23
+
24
+ - Fastify's [Long Term Support (LTS)](./Reference/LTS.md) policy
@@ -0,0 +1 @@
1
+ <mxfile host="app.diagrams.net" modified="2020-12-06T18:51:58.018Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" etag="vyaguDTT1c9e-NqGeV_7" version="13.10.9" type="device"><diagram id="hZ89Y7exsLGRT07QCK17" name="Page-1">7ZpPk5owGMY/jcd2SCKIx0q3todOO+thjzsRAmQ2Eopx1f30DRKUNLCrncXN6uKMA0/+EN5feJNndICCxWZa4Dz9ySPCBtCJNgP0dQDhaDiS36WwrQQfOJWQFDSqJHAQZvSJKLGutqIRWWoVBedM0FwXQ55lJBSahouCr/VqMWf6XXOcEEOYhZiZ6h2NRKqewnUO+ndCk7S+M3BUyQLXlZWwTHHE1w0J3QxQUHAuqrPFJiCsjF0dl6rdt47S/cAKkoljGjyhO8+Z3U9YQP3bP1PHvc9+fFK9PGK2Ug98Ww4IOgHPBNkINXSxreOxTqkgsxyH5fVaIh+gSSoWTF4BeYqXeUUhphsibzyJKWMBZ7zYNUexW36k/kgKQWWYvzCaZLJM8LKngq+yqGy362wpCv5AGq293VH2KkfX0KtD6mZM6geUtyObhqRiNCV8QUSxlVVU6VDh2uqX6wN8d6y0tAF+L2I14ZJ9zwcm8kRhOQER6kL0m60SmhmE5DzLy9O84CFZytFMXmA2x+FDsov8r5VgNCNK12H8CzKOYRi2QYq8ued6rwMDOq5Gwzdp+C0wUF8shtfMYmwXC/eKWSDfLhbATFJG/MtQ5sc/+35Jx/O6B+fZmABPz9wAmUFBXktU+guLZ0QlSKncgHQvr/rcemGCdk299rX1lAn5POSXp+nbhXzUGfI3TQsRJn7cmha80CfzuBcKdan+XrS8FmfNFf4HIZOQXYjGBiJp7rIo7DF57cN/ZPLqHwrUmdQrbjO1wRYoALp9LbKOnW8OAZFLRm2Qxt4I4X5WmNqtjT7rOyEA3norZFrqq6cEkH2Y4AcmI+MhaB0m03EbYM5tLFCL2zrzLheY5vddO4thByubnAXodnOXsnE9HoOd1gJcvvv7D0SWMTL93/s3FydTsc9cmJ7PilfnFfdDJ0Oyz1zAy7eApyc4+8wFvHwPeHrGO6e5kJeHH9Z3ZY1/J6Cbvw==</diagram></mxfile>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="591px" height="591px" viewBox="-0.5 -0.5 591 591" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2020-12-06T18:52:11.078Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36&quot; etag=&quot;_w1zgMmeoq0M6WH2W2QF&quot; version=&quot;13.10.9&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;hZ89Y7exsLGRT07QCK17&quot; name=&quot;Page-1&quot;&gt;7ZpPk5owGMY/jcd2SCKIx0q3todOO+thjzsRAmQ2Eopx1f30DRKUNLCrncXN6uKMA0/+EN5feJNndICCxWZa4Dz9ySPCBtCJNgP0dQDhaDiS36WwrQQfOJWQFDSqJHAQZvSJKLGutqIRWWoVBedM0FwXQ55lJBSahouCr/VqMWf6XXOcEEOYhZiZ6h2NRKqewnUO+ndCk7S+M3BUyQLXlZWwTHHE1w0J3QxQUHAuqrPFJiCsjF0dl6rdt47S/cAKkoljGjyhO8+Z3U9YQP3bP1PHvc9+fFK9PGK2Ug98Ww4IOgHPBNkINXSxreOxTqkgsxyH5fVaIh+gSSoWTF4BeYqXeUUhphsibzyJKWMBZ7zYNUexW36k/kgKQWWYvzCaZLJM8LKngq+yqGy362wpCv5AGq293VH2KkfX0KtD6mZM6geUtyObhqRiNCV8QUSxlVVU6VDh2uqX6wN8d6y0tAF+L2I14ZJ9zwcm8kRhOQER6kL0m60SmhmE5DzLy9O84CFZytFMXmA2x+FDsov8r5VgNCNK12H8CzKOYRi2QYq8ued6rwMDOq5Gwzdp+C0wUF8shtfMYmwXC/eKWSDfLhbATFJG/MtQ5sc/+35Jx/O6B+fZmABPz9wAmUFBXktU+guLZ0QlSKncgHQvr/rcemGCdk299rX1lAn5POSXp+nbhXzUGfI3TQsRJn7cmha80CfzuBcKdan+XrS8FmfNFf4HIZOQXYjGBiJp7rIo7DF57cN/ZPLqHwrUmdQrbjO1wRYoALp9LbKOnW8OAZFLRm2Qxt4I4X5WmNqtjT7rOyEA3norZFrqq6cEkH2Y4AcmI+MhaB0m03EbYM5tLFCL2zrzLheY5vddO4thByubnAXodnOXsnE9HoOd1gJcvvv7D0SWMTL93/s3FydTsc9cmJ7PilfnFfdDJ0Oyz1zAy7eApyc4+8wFvHwPeHrGO6e5kJeHH9Z3ZY1/J6Cbvw==&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><rect x="0" y="0" width="590" height="590" rx="88.5" ry="88.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 588px; height: 1px; padding-top: 7px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Root Context</div></div></div></foreignObject><text x="295" y="19" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">Root Context</text></switch></g><rect x="165" y="40" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><path d="M 173 40 L 173 70 M 237 40 L 237 70" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 55px; margin-left: 174px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Root Plugin</div></div></div></foreignObject><text x="205" y="59" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Root Plugin</text></switch></g><rect x="255" y="40" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><path d="M 263 40 L 263 70 M 327 40 L 327 70" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 55px; margin-left: 264px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Root Plugin</div></div></div></foreignObject><text x="295" y="59" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Root Plugin</text></switch></g><rect x="345" y="40" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><path d="M 353 40 L 353 70 M 417 40 L 417 70" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 55px; margin-left: 354px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Root Plugin</div></div></div></foreignObject><text x="385" y="59" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Root Plugin</text></switch></g><rect x="120" y="90" width="360" height="230" rx="34.5" ry="34.5" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 358px; height: 1px; padding-top: 97px; margin-left: 121px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Context</div></div></div></foreignObject><text x="300" y="109" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Context</text></switch></g><rect x="130" y="120" width="80" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><path d="M 138 120 L 138 150 M 202 120 L 202 150" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 135px; margin-left: 139px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="170" y="139" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g><rect x="220" y="120" width="80" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><path d="M 228 120 L 228 150 M 292 120 L 292 150" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 135px; margin-left: 229px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="260" y="139" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g><rect x="140" y="175" width="320" height="125" rx="18.75" ry="18.75" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 318px; height: 1px; padding-top: 182px; margin-left: 141px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Grandchild Context</div></div></div></foreignObject><text x="300" y="194" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Grandchild Context</text></switch></g><rect x="167.5" y="200" width="80" height="30" rx="4.5" ry="4.5" fill="#e1d5e7" stroke="#9673a6" pointer-events="all"/><path d="M 175.5 200 L 175.5 230 M 239.5 200 L 239.5 230" fill="none" stroke="#9673a6" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 215px; margin-left: 177px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="208" y="219" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g><rect x="257.5" y="200" width="80" height="30" rx="4.5" ry="4.5" fill="#e1d5e7" stroke="#9673a6" pointer-events="all"/><path d="M 265.5 200 L 265.5 230 M 329.5 200 L 329.5 230" fill="none" stroke="#9673a6" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 215px; margin-left: 267px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="298" y="219" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g><rect x="352.5" y="200" width="80" height="30" rx="4.5" ry="4.5" fill="#e1d5e7" stroke="#9673a6" pointer-events="all"/><path d="M 360.5 200 L 360.5 230 M 424.5 200 L 424.5 230" fill="none" stroke="#9673a6" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 215px; margin-left: 362px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="393" y="219" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g><rect x="120" y="340" width="360" height="230" rx="34.5" ry="34.5" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 358px; height: 1px; padding-top: 347px; margin-left: 121px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Context</div></div></div></foreignObject><text x="300" y="359" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Context</text></switch></g><rect x="130" y="370" width="80" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><path d="M 138 370 L 138 400 M 202 370 L 202 400" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 385px; margin-left: 139px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="170" y="389" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g><rect x="220" y="370" width="80" height="30" rx="4.5" ry="4.5" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><path d="M 228 370 L 228 400 M 292 370 L 292 400" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 385px; margin-left: 229px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="260" y="389" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g><rect x="140" y="425" width="320" height="125" rx="18.75" ry="18.75" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 318px; height: 1px; padding-top: 432px; margin-left: 141px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Grandchild Context</div></div></div></foreignObject><text x="300" y="444" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Grandchild Context</text></switch></g><rect x="167.5" y="450" width="80" height="30" rx="4.5" ry="4.5" fill="#e1d5e7" stroke="#9673a6" pointer-events="all"/><path d="M 175.5 450 L 175.5 480 M 239.5 450 L 239.5 480" fill="none" stroke="#9673a6" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 465px; margin-left: 177px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="208" y="469" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g><rect x="257.5" y="450" width="80" height="30" rx="4.5" ry="4.5" fill="#e1d5e7" stroke="#9673a6" pointer-events="all"/><path d="M 265.5 450 L 265.5 480 M 329.5 450 L 329.5 480" fill="none" stroke="#9673a6" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 465px; margin-left: 267px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="298" y="469" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g><rect x="352.5" y="450" width="80" height="30" rx="4.5" ry="4.5" fill="#e1d5e7" stroke="#9673a6" pointer-events="all"/><path d="M 360.5 450 L 360.5 480 M 424.5 450 L 424.5 480" fill="none" stroke="#9673a6" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 465px; margin-left: 362px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Child Plugin</div></div></div></foreignObject><text x="393" y="469" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Child Plug...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://desk.draw.io/support/solutions/articles/16000042487" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
@@ -0,0 +1,35 @@
1
+ 'use strict'
2
+ const neostandard = require('neostandard')
3
+
4
+ module.exports = [
5
+ ...neostandard({
6
+ ignores: [
7
+ 'lib/config-validator.js',
8
+ 'lib/error-serializer.js',
9
+ 'test/same-shape.test.js',
10
+ 'test/types/import.js'
11
+ ],
12
+ ts: true
13
+ }),
14
+ {
15
+ rules: {
16
+ 'comma-dangle': ['error', 'never'],
17
+ 'max-len': ['error', {
18
+ code: 120,
19
+ tabWidth: 2,
20
+ ignoreUrls: true,
21
+ ignoreStrings: true,
22
+ ignoreTemplateLiterals: true,
23
+ ignoreRegExpLiterals: true,
24
+ ignoreComments: true,
25
+ ignoreTrailingComments: true
26
+ }]
27
+ }
28
+ },
29
+ {
30
+ files: ['**/*.d.ts'],
31
+ rules: {
32
+ 'max-len': 'off'
33
+ }
34
+ }
35
+ ]
@@ -0,0 +1,38 @@
1
+ 'use strict'
2
+
3
+ const fastify = require('../fastify')({ logger: true })
4
+
5
+ const schema = {
6
+ schema: {
7
+ response: {
8
+ 200: {
9
+ type: 'object',
10
+ properties: {
11
+ hello: {
12
+ type: 'string'
13
+ }
14
+ }
15
+ }
16
+ }
17
+ }
18
+ }
19
+
20
+ function result () {
21
+ return Promise.resolve({ hello: 'world' })
22
+ }
23
+
24
+ fastify
25
+ .get('/await', schema, async function (req, reply) {
26
+ reply.header('Content-Type', 'application/json').code(200)
27
+ return result()
28
+ })
29
+ .get('/', schema, async function (req, reply) {
30
+ reply.header('Content-Type', 'application/json').code(200)
31
+ return { hello: 'world' }
32
+ })
33
+
34
+ fastify.listen({ port: 3000 }, err => {
35
+ if (err) {
36
+ throw err
37
+ }
38
+ })
@@ -0,0 +1,3 @@
1
+ {
2
+ "hello": "world"
3
+ }
@@ -0,0 +1,44 @@
1
+ 'use strict'
2
+
3
+ const fastify = require('../../fastify')({ logger: false })
4
+
5
+ const opts = {
6
+ schema: {
7
+ response: {
8
+ 200: {
9
+ type: 'object',
10
+ properties: {
11
+ hello: {
12
+ type: 'string'
13
+ }
14
+ }
15
+ }
16
+ }
17
+ }
18
+ }
19
+
20
+ function promiseFunction (resolve) {
21
+ setImmediate(resolve)
22
+ }
23
+
24
+ async function asyncHook () {
25
+ await new Promise(promiseFunction)
26
+ }
27
+
28
+ fastify
29
+ .addHook('onRequest', asyncHook)
30
+ .addHook('onRequest', asyncHook)
31
+ .addHook('preHandler', asyncHook)
32
+ .addHook('preHandler', asyncHook)
33
+ .addHook('preHandler', asyncHook)
34
+ .addHook('onSend', asyncHook)
35
+
36
+ fastify.get('/', opts, function (request, reply) {
37
+ reply.send({ hello: 'world' })
38
+ })
39
+
40
+ fastify.listen({ port: 3000 }, function (err) {
41
+ if (err) {
42
+ throw err
43
+ }
44
+ })
@@ -0,0 +1,52 @@
1
+ 'use strict'
2
+
3
+ const fastify = require('../../fastify')({ logger: false })
4
+
5
+ const opts = {
6
+ schema: {
7
+ response: {
8
+ 200: {
9
+ type: 'object',
10
+ properties: {
11
+ hello: {
12
+ type: 'string'
13
+ }
14
+ }
15
+ }
16
+ }
17
+ }
18
+ }
19
+
20
+ fastify
21
+ .addHook('onRequest', function (request, reply, done) {
22
+ done()
23
+ })
24
+ .addHook('onRequest', function (request, reply, done) {
25
+ done()
26
+ })
27
+
28
+ fastify
29
+ .addHook('preHandler', function (request, reply, done) {
30
+ done()
31
+ })
32
+ .addHook('preHandler', function (request, reply, done) {
33
+ setImmediate(done)
34
+ })
35
+ .addHook('preHandler', function (request, reply, done) {
36
+ done()
37
+ })
38
+
39
+ fastify
40
+ .addHook('onSend', function (request, reply, payload, done) {
41
+ done()
42
+ })
43
+
44
+ fastify.get('/', opts, function (request, reply) {
45
+ reply.send({ hello: 'world' })
46
+ })
47
+
48
+ fastify.listen({ port: 3000 }, function (err) {
49
+ if (err) {
50
+ throw err
51
+ }
52
+ })
@@ -0,0 +1,47 @@
1
+ 'use strict'
2
+
3
+ const fastify = require('../../fastify')({
4
+ logger: false
5
+ })
6
+
7
+ const jsonParser = require('fast-json-body')
8
+ const querystring = require('node:querystring')
9
+
10
+ // Handled by fastify
11
+ // curl -X POST -d '{"hello":"world"}' -H'Content-type: application/json' http://localhost:3000/
12
+
13
+ // curl -X POST -d '{"hello":"world"}' -H'Content-type: application/jsoff' http://localhost:3000/
14
+ fastify.addContentTypeParser('application/jsoff', function (request, payload, done) {
15
+ jsonParser(payload, function (err, body) {
16
+ done(err, body)
17
+ })
18
+ })
19
+
20
+ // curl -X POST -d 'hello=world' -H'Content-type: application/x-www-form-urlencoded' http://localhost:3000/
21
+ fastify.addContentTypeParser('application/x-www-form-urlencoded', function (request, payload, done) {
22
+ let body = ''
23
+ payload.on('data', function (data) {
24
+ body += data
25
+ })
26
+ payload.on('end', function () {
27
+ try {
28
+ const parsed = querystring.parse(body)
29
+ done(null, parsed)
30
+ } catch (e) {
31
+ done(e)
32
+ }
33
+ })
34
+ payload.on('error', done)
35
+ })
36
+
37
+ // curl -X POST -d '{"hello":"world"}' -H'Content-type: application/vnd.custom+json' http://localhost:3000/
38
+ fastify.addContentTypeParser(/^application\/.+\+json$/, { parseAs: 'string' }, fastify.getDefaultJsonParser('error', 'ignore'))
39
+
40
+ fastify
41
+ .post('/', function (req, reply) {
42
+ reply.send(req.body)
43
+ })
44
+
45
+ fastify.listen({ port: 3000 }, (err, address) => {
46
+ if (err) throw err
47
+ })
@@ -0,0 +1,30 @@
1
+ 'use strict'
2
+
3
+ const fastify = require('../../fastify')({
4
+ logger: false
5
+ })
6
+
7
+ const schema = {
8
+ schema: {
9
+ response: {
10
+ 200: {
11
+ type: 'object',
12
+ properties: {
13
+ hello: {
14
+ type: 'string'
15
+ }
16
+ }
17
+ }
18
+ }
19
+ }
20
+ }
21
+
22
+ fastify
23
+ .get('/', schema, function (req, reply) {
24
+ reply
25
+ .send({ hello: 'world' })
26
+ })
27
+
28
+ fastify.listen({ port: 3000 }, (err, address) => {
29
+ if (err) throw err
30
+ })
@@ -0,0 +1,27 @@
1
+ 'use strict'
2
+
3
+ const fastify = require('../../fastify')({
4
+ logger: false
5
+ })
6
+
7
+ const payload = JSON.stringify({ hello: 'world' })
8
+
9
+ fastify.get('/', function (req, reply) {
10
+ const stream = new ReadableStream({
11
+ start (controller) {
12
+ controller.enqueue(payload)
13
+ controller.close()
14
+ }
15
+ })
16
+ return new Response(stream, {
17
+ status: 200,
18
+ headers: {
19
+ 'content-type': 'application/json; charset=utf-8'
20
+ }
21
+ })
22
+ })
23
+
24
+ fastify.listen({ port: 3000 }, (err, address) => {
25
+ if (err) throw err
26
+ console.log(`Server listening on ${address}`)
27
+ })
@@ -0,0 +1,91 @@
1
+ 'use strict'
2
+
3
+ const fastify = require('../fastify')({ logger: true })
4
+
5
+ const opts = {
6
+ schema: {
7
+ response: {
8
+ '2xx': {
9
+ type: 'object',
10
+ properties: {
11
+ hello: {
12
+ type: 'string'
13
+ }
14
+ }
15
+ }
16
+ }
17
+ }
18
+ }
19
+
20
+ const optsPost = {
21
+ schema: {
22
+ body: {
23
+ type: 'object',
24
+ required: ['hello'],
25
+ properties: {
26
+ hello: {
27
+ type: 'string'
28
+ }
29
+ }
30
+ },
31
+ response: opts.response
32
+ }
33
+ }
34
+
35
+ fastify
36
+ .addHook('onRequest', function (request, reply, done) {
37
+ console.log('onRequest')
38
+ done()
39
+ })
40
+ .addHook('preParsing', function (request, reply, payload, done) {
41
+ console.log('preParsing')
42
+ done()
43
+ })
44
+ .addHook('preValidation', function (request, reply, done) {
45
+ console.log('preValidation')
46
+ done()
47
+ })
48
+ .addHook('preHandler', function (request, reply, done) {
49
+ console.log('preHandler')
50
+ done()
51
+ })
52
+ .addHook('preSerialization', function (request, reply, payload, done) {
53
+ console.log('preSerialization', payload)
54
+ done()
55
+ })
56
+ .addHook('onError', function (request, reply, error, done) {
57
+ console.log('onError', error.message)
58
+ done()
59
+ })
60
+ .addHook('onSend', function (request, reply, payload, done) {
61
+ console.log('onSend', payload)
62
+ done()
63
+ })
64
+ .addHook('onResponse', function (request, reply, done) {
65
+ console.log('onResponse')
66
+ done()
67
+ })
68
+ .addHook('onRoute', function (routeOptions) {
69
+ console.log('onRoute')
70
+ })
71
+ .addHook('onListen', async function () {
72
+ console.log('onListen')
73
+ })
74
+ .addHook('onClose', function (instance, done) {
75
+ console.log('onClose')
76
+ done()
77
+ })
78
+
79
+ fastify.get('/', opts, function (req, reply) {
80
+ reply.send({ hello: 'world' })
81
+ })
82
+
83
+ fastify.post('/', optsPost, function (req, reply) {
84
+ reply.send({ hello: 'world' })
85
+ })
86
+
87
+ fastify.listen({ port: 3000 }, function (err) {
88
+ if (err) {
89
+ throw err
90
+ }
91
+ })
@@ -0,0 +1,39 @@
1
+ 'use strict'
2
+
3
+ const fs = require('node:fs')
4
+ const path = require('node:path')
5
+ const fastify = require('../fastify')({
6
+ http2: true,
7
+ https: {
8
+ key: fs.readFileSync(path.join(__dirname, '../test/https/fastify.key')),
9
+ cert: fs.readFileSync(path.join(__dirname, '../test/https/fastify.cert'))
10
+ },
11
+ logger: true
12
+ })
13
+
14
+ const opts = {
15
+ schema: {
16
+ response: {
17
+ '2xx': {
18
+ type: 'object',
19
+ properties: {
20
+ hello: {
21
+ type: 'string'
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }
28
+
29
+ fastify
30
+ .get('/', opts, function (req, reply) {
31
+ reply.header('Content-Type', 'application/json').code(200)
32
+ reply.send({ hello: 'world' })
33
+ })
34
+
35
+ fastify.listen({ port: 3000 }, err => {
36
+ if (err) {
37
+ throw err
38
+ }
39
+ })
@@ -0,0 +1,38 @@
1
+ 'use strict'
2
+
3
+ const fs = require('node:fs')
4
+ const path = require('node:path')
5
+ const fastify = require('../fastify')({
6
+ https: {
7
+ key: fs.readFileSync(path.join(__dirname, '../test/https/fastify.key')),
8
+ cert: fs.readFileSync(path.join(__dirname, '../test/https/fastify.cert'))
9
+ },
10
+ logger: true
11
+ })
12
+
13
+ const opts = {
14
+ schema: {
15
+ response: {
16
+ '2xx': {
17
+ type: 'object',
18
+ properties: {
19
+ hello: {
20
+ type: 'string'
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+
28
+ fastify
29
+ .get('/', opts, function (req, reply) {
30
+ reply.header('Content-Type', 'application/json').code(200)
31
+ reply.send({ hello: 'world' })
32
+ })
33
+
34
+ fastify.listen({ port: 3000 }, err => {
35
+ if (err) {
36
+ throw err
37
+ }
38
+ })
@@ -0,0 +1,53 @@
1
+ 'use strict'
2
+
3
+ const fastify = require('../fastify')({ logger: true })
4
+ const jsonParser = require('fast-json-body')
5
+ const querystring = require('node:querystring')
6
+
7
+ // Handled by fastify
8
+ // curl -X POST -d '{"hello":"world"}' -H'Content-type: application/json' http://localhost:3000/
9
+
10
+ // curl -X POST -d '{"hello":"world"}' -H'Content-type: application/jsoff' http://localhost:3000/
11
+ fastify.addContentTypeParser('application/jsoff', function (request, payload, done) {
12
+ jsonParser(payload, function (err, body) {
13
+ done(err, body)
14
+ })
15
+ })
16
+
17
+ // curl -X POST -d 'hello=world' -H'Content-type: application/x-www-form-urlencoded' http://localhost:3000/
18
+ fastify.addContentTypeParser('application/x-www-form-urlencoded', function (request, payload, done) {
19
+ let body = ''
20
+ payload.on('data', function (data) {
21
+ body += data
22
+ })
23
+ payload.on('end', function () {
24
+ try {
25
+ const parsed = querystring.parse(body)
26
+ done(null, parsed)
27
+ } catch (e) {
28
+ done(e)
29
+ }
30
+ })
31
+ payload.on('error', done)
32
+ })
33
+
34
+ // curl -X POST -d '{"hello":"world"}' -H'Content-type: application/vnd.custom+json' http://localhost:3000/
35
+ fastify.addContentTypeParser(/^application\/.+\+json$/, { parseAs: 'string' }, fastify.getDefaultJsonParser('error', 'ignore'))
36
+
37
+ // remove default json parser
38
+ // curl -X POST -d '{"hello":"world"}' -H'Content-type: application/json' http://localhost:3000/ is now no longer handled by fastify
39
+ fastify.removeContentTypeParser('application/json')
40
+
41
+ // This call would remove any content type parser
42
+ // fastify.removeAllContentTypeParsers()
43
+
44
+ fastify
45
+ .post('/', function (req, reply) {
46
+ reply.send(req.body)
47
+ })
48
+
49
+ fastify.listen({ port: 3000 }, err => {
50
+ if (err) {
51
+ throw err
52
+ }
53
+ })