jishushell 0.6.18 → 0.7.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.
- package/apps/anythingllm-container.yaml +1 -0
- package/apps/browserless-chromium-container.yaml +1 -0
- package/apps/filebrowser-container.yaml +1 -0
- package/apps/hermes-container.yaml +1 -7
- package/apps/immich-container-lite.yaml +337 -0
- package/apps/immich-container.yaml +371 -0
- package/apps/jishu-kb-container.yaml +26 -21
- package/apps/ollama-binary.yaml +1 -0
- package/apps/ollama-cpu-container.yaml +1 -0
- package/apps/ollama-with-hollama-binary.yaml +2 -0
- package/apps/openclaw-binary.yaml +4 -8
- package/apps/openclaw-container.yaml +1 -7
- package/apps/openclaw-with-ollama-container.yaml +1 -0
- package/apps/openclaw-with-searxng-container.yaml +20 -0
- package/apps/searxng-container.yaml +20 -0
- package/apps/weknora-container.yaml +5 -0
- package/dependencies/jishushell-panel-0.7.3.tgz +0 -0
- package/dist/cli/core.js +1 -1
- package/dist/cli/core.js.map +1 -1
- package/dist/cli/doctor.js +96 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/config.d.ts +9 -1
- package/dist/config.js +72 -2
- package/dist/config.js.map +1 -1
- package/dist/install.js +60 -19
- package/dist/install.js.map +1 -1
- package/dist/routes/admin.d.ts +2 -0
- package/dist/routes/admin.js +72 -0
- package/dist/routes/admin.js.map +1 -0
- package/dist/routes/docker.d.ts +2 -0
- package/dist/routes/docker.js +58 -0
- package/dist/routes/docker.js.map +1 -0
- package/dist/routes/file-mounts.js +5 -8
- package/dist/routes/file-mounts.js.map +1 -1
- package/dist/routes/instances.d.ts +0 -14
- package/dist/routes/instances.js +44 -1184
- package/dist/routes/instances.js.map +1 -1
- package/dist/server.d.ts +6 -0
- package/dist/server.js +53 -20
- package/dist/server.js.map +1 -1
- package/dist/services/app-common/catalog-service.js +15 -5
- package/dist/services/app-common/catalog-service.js.map +1 -1
- package/dist/services/app-common/delete-service.js +5 -0
- package/dist/services/app-common/delete-service.js.map +1 -1
- package/dist/services/app-common/instance-store.js +3 -0
- package/dist/services/app-common/instance-store.js.map +1 -1
- package/dist/services/app-common/lifecycle-service.js +12 -4
- package/dist/services/app-common/lifecycle-service.js.map +1 -1
- package/dist/services/app-common/ownership.d.ts +3 -0
- package/dist/services/app-common/ownership.js +11 -0
- package/dist/services/app-common/ownership.js.map +1 -0
- package/dist/services/app-common/runtime-facts.js +2 -0
- package/dist/services/app-common/runtime-facts.js.map +1 -1
- package/dist/services/app-common/spec-materializer.d.ts +0 -1
- package/dist/services/app-common/spec-materializer.js +21 -87
- package/dist/services/app-common/spec-materializer.js.map +1 -1
- package/dist/services/app-common/status-refresh.js +25 -13
- package/dist/services/app-common/status-refresh.js.map +1 -1
- package/dist/services/app-modules/browserless/routes.js +5 -3
- package/dist/services/app-modules/browserless/routes.js.map +1 -1
- package/dist/services/capabilities/contract.d.ts +1 -2
- package/dist/services/capabilities/contract.js +0 -10
- package/dist/services/capabilities/contract.js.map +1 -1
- package/dist/services/capabilities/endpoint-validator.js +0 -1
- package/dist/services/capabilities/endpoint-validator.js.map +1 -1
- package/dist/services/capabilities/health.js +1 -1
- package/dist/services/capabilities/health.js.map +1 -1
- package/dist/services/capability-proxy/http.d.ts +7 -0
- package/dist/services/capability-proxy/http.js +555 -0
- package/dist/services/capability-proxy/http.js.map +1 -0
- package/dist/services/capability-proxy/terminal.d.ts +4 -0
- package/dist/services/capability-proxy/terminal.js +179 -0
- package/dist/services/capability-proxy/terminal.js.map +1 -0
- package/dist/services/connections/admin.js +19 -9
- package/dist/services/connections/admin.js.map +1 -1
- package/dist/services/connections/apply.d.ts +3 -9
- package/dist/services/connections/apply.js +0 -29
- package/dist/services/connections/apply.js.map +1 -1
- package/dist/services/connections/transactor.js +2 -2
- package/dist/services/connections/transactor.js.map +1 -1
- package/dist/services/files/bootstrap.d.ts +7 -0
- package/dist/services/files/bootstrap.js +16 -0
- package/dist/services/files/bootstrap.js.map +1 -0
- package/dist/services/files/photos/upload-page.d.ts +2 -0
- package/dist/services/files/photos/upload-page.js +248 -0
- package/dist/services/files/photos/upload-page.js.map +1 -0
- package/dist/services/files/photos/upload-store.d.ts +74 -0
- package/dist/services/files/photos/upload-store.js +432 -0
- package/dist/services/files/photos/upload-store.js.map +1 -0
- package/dist/services/http/proxy-utils.d.ts +7 -0
- package/dist/services/http/proxy-utils.js +29 -0
- package/dist/services/http/proxy-utils.js.map +1 -0
- package/dist/services/http/request-utils.d.ts +3 -0
- package/dist/services/http/request-utils.js +23 -0
- package/dist/services/http/request-utils.js.map +1 -0
- package/dist/services/instances/manager.d.ts +6 -5
- package/dist/services/instances/manager.js +45 -51
- package/dist/services/instances/manager.js.map +1 -1
- package/dist/services/instances/pairing.d.ts +17 -0
- package/dist/services/instances/pairing.js +53 -0
- package/dist/services/instances/pairing.js.map +1 -0
- package/dist/services/instances/status.d.ts +2 -0
- package/dist/services/instances/status.js +11 -0
- package/dist/services/instances/status.js.map +1 -0
- package/dist/services/integrations/hermes/integration.d.ts +1 -1
- package/dist/services/integrations/hermes/integration.js +7 -8
- package/dist/services/integrations/hermes/integration.js.map +1 -1
- package/dist/services/integrations/immich/client.d.ts +93 -0
- package/dist/services/integrations/immich/client.js +458 -0
- package/dist/services/integrations/immich/client.js.map +1 -0
- package/dist/services/integrations/immich/config.d.ts +15 -0
- package/dist/services/integrations/immich/config.js +178 -0
- package/dist/services/integrations/immich/config.js.map +1 -0
- package/dist/services/integrations/immich/discovery.d.ts +9 -0
- package/dist/services/integrations/immich/discovery.js +101 -0
- package/dist/services/integrations/immich/discovery.js.map +1 -0
- package/dist/services/integrations/immich/gallery-renderer.d.ts +5 -0
- package/dist/services/integrations/immich/gallery-renderer.js +150 -0
- package/dist/services/integrations/immich/gallery-renderer.js.map +1 -0
- package/dist/services/integrations/immich/immich-shim.d.ts +11 -0
- package/dist/services/integrations/immich/immich-shim.js +439 -0
- package/dist/services/integrations/immich/immich-shim.js.map +1 -0
- package/dist/services/integrations/immich/integration.d.ts +18 -0
- package/dist/services/integrations/immich/integration.js +64 -0
- package/dist/services/integrations/immich/integration.js.map +1 -0
- package/dist/services/integrations/immich/photo-library.d.ts +4 -0
- package/dist/services/integrations/immich/photo-library.js +63 -0
- package/dist/services/integrations/immich/photo-library.js.map +1 -0
- package/dist/services/integrations/immich/review-executor.d.ts +3 -0
- package/dist/services/integrations/immich/review-executor.js +41 -0
- package/dist/services/integrations/immich/review-executor.js.map +1 -0
- package/dist/services/integrations/immich/review-session-service.d.ts +27 -0
- package/dist/services/integrations/immich/review-session-service.js +206 -0
- package/dist/services/integrations/immich/review-session-service.js.map +1 -0
- package/dist/services/integrations/immich/review-store.d.ts +47 -0
- package/dist/services/integrations/immich/review-store.js +347 -0
- package/dist/services/integrations/immich/review-store.js.map +1 -0
- package/dist/services/integrations/immich/routes.d.ts +7 -0
- package/dist/services/integrations/immich/routes.js +363 -0
- package/dist/services/integrations/immich/routes.js.map +1 -0
- package/dist/services/integrations/immich/types.d.ts +186 -0
- package/dist/services/integrations/immich/types.js +2 -0
- package/dist/services/integrations/immich/types.js.map +1 -0
- package/dist/services/integrations/index.d.ts +1 -0
- package/dist/services/integrations/index.js +1 -0
- package/dist/services/integrations/index.js.map +1 -1
- package/dist/services/integrations/installable/installers/integration.js +113 -7
- package/dist/services/integrations/installable/installers/integration.js.map +1 -1
- package/dist/services/integrations/jishukb/integration.d.ts +3 -1
- package/dist/services/integrations/jishukb/integration.js +121 -10
- package/dist/services/integrations/jishukb/integration.js.map +1 -1
- package/dist/services/integrations/openclaw/integration.d.ts +21 -7
- package/dist/services/integrations/openclaw/integration.js +385 -158
- package/dist/services/integrations/openclaw/integration.js.map +1 -1
- package/dist/services/integrations/openclaw/jishukb-native-mcp.d.ts +58 -0
- package/dist/services/integrations/openclaw/jishukb-native-mcp.js +373 -0
- package/dist/services/integrations/openclaw/jishukb-native-mcp.js.map +1 -0
- package/dist/services/integrations/openclaw/jishukb-shim.d.ts +8 -4
- package/dist/services/integrations/openclaw/jishukb-shim.js +624 -17
- package/dist/services/integrations/openclaw/jishukb-shim.js.map +1 -1
- package/dist/services/integrations/openclaw/mcporter.d.ts +13 -0
- package/dist/services/integrations/openclaw/mcporter.js +31 -0
- package/dist/services/integrations/openclaw/mcporter.js.map +1 -1
- package/dist/services/integrations/openclaw/native-mcp.d.ts +48 -0
- package/dist/services/integrations/openclaw/native-mcp.js +125 -0
- package/dist/services/integrations/openclaw/native-mcp.js.map +1 -0
- package/dist/services/integrations/openclaw/routes.js +4 -1
- package/dist/services/integrations/openclaw/routes.js.map +1 -1
- package/dist/services/integrations/types.d.ts +5 -17
- package/dist/services/repair/runtime-repair.js +68 -1
- package/dist/services/repair/runtime-repair.js.map +1 -1
- package/dist/services/runtime/docker-network.d.ts +8 -0
- package/dist/services/runtime/docker-network.js +123 -0
- package/dist/services/runtime/docker-network.js.map +1 -0
- package/dist/services/runtime/driver-registry.d.ts +4 -0
- package/dist/services/runtime/driver-registry.js.map +1 -1
- package/dist/services/runtime/drivers/nomad.d.ts +1 -0
- package/dist/services/runtime/drivers/nomad.js +35 -5
- package/dist/services/runtime/drivers/nomad.js.map +1 -1
- package/dist/services/runtime/service-manager.d.ts +2 -0
- package/dist/services/runtime/service-manager.js +18 -0
- package/dist/services/runtime/service-manager.js.map +1 -0
- package/dist/services/runtime/types.d.ts +1 -0
- package/dist/services/runtime/workload-compiler.js +29 -4
- package/dist/services/runtime/workload-compiler.js.map +1 -1
- package/dist/services/setup/setup-manager.js +29 -73
- package/dist/services/setup/setup-manager.js.map +1 -1
- package/dist/services/system/runtime-ownership.d.ts +36 -0
- package/dist/services/system/runtime-ownership.js +250 -0
- package/dist/services/system/runtime-ownership.js.map +1 -0
- package/dist/services/system/system-reconciler.js +53 -0
- package/dist/services/system/system-reconciler.js.map +1 -1
- package/dist/types.d.ts +19 -3
- package/dist/utils/path-safety.js +1 -1
- package/dist/utils/service-user.d.ts +13 -0
- package/dist/utils/service-user.js +129 -0
- package/dist/utils/service-user.js.map +1 -0
- package/install/jishu-install.sh +0 -1
- package/node_modules/brace-expansion/dist/commonjs/index.js +24 -14
- package/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -1
- package/node_modules/brace-expansion/dist/esm/index.js +24 -14
- package/node_modules/brace-expansion/dist/esm/index.js.map +1 -1
- package/node_modules/brace-expansion/package.json +2 -2
- package/node_modules/fast-uri/index.js +1 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/security.test.js +28 -0
- package/node_modules/fastify/SECURITY.md +1 -1
- package/node_modules/fastify/SPONSORS.md +6 -4
- package/node_modules/fastify/docs/Guides/Database.md +0 -28
- package/node_modules/fastify/docs/Guides/Ecosystem.md +13 -2
- package/node_modules/fastify/docs/Guides/Serverless.md +2 -2
- package/node_modules/fastify/docs/Guides/Write-Plugin.md +1 -1
- package/node_modules/fastify/docs/Reference/Encapsulation.md +27 -26
- package/node_modules/fastify/docs/Reference/Errors.md +10 -4
- package/node_modules/fastify/docs/Reference/HTTP2.md +10 -10
- package/node_modules/fastify/docs/Reference/Hooks.md +4 -4
- package/node_modules/fastify/docs/Reference/Index.md +14 -16
- package/node_modules/fastify/docs/Reference/LTS.md +12 -13
- package/node_modules/fastify/docs/Reference/Lifecycle.md +9 -8
- package/node_modules/fastify/docs/Reference/Logging.md +44 -39
- package/node_modules/fastify/docs/Reference/Middleware.md +21 -25
- package/node_modules/fastify/docs/Reference/Principles.md +2 -2
- package/node_modules/fastify/docs/Reference/Reply.md +6 -1
- package/node_modules/fastify/docs/Reference/Request.md +27 -16
- package/node_modules/fastify/docs/Reference/Routes.md +5 -2
- package/node_modules/fastify/docs/Reference/Server.md +31 -3
- package/node_modules/fastify/docs/Reference/Type-Providers.md +29 -5
- package/node_modules/fastify/docs/Reference/Validation-and-Serialization.md +15 -2
- package/node_modules/fastify/docs/Reference/Warnings.md +7 -6
- package/node_modules/fastify/eslint.config.js +7 -2
- package/node_modules/fastify/fastify.d.ts +8 -3
- package/node_modules/fastify/fastify.js +43 -14
- package/node_modules/fastify/lib/content-type-parser.js +13 -1
- package/node_modules/fastify/lib/decorate.js +11 -3
- package/node_modules/fastify/lib/error-handler.js +4 -3
- package/node_modules/fastify/lib/error-serializer.js +59 -59
- package/node_modules/fastify/lib/errors.js +16 -1
- package/node_modules/fastify/lib/four-oh-four.js +14 -9
- package/node_modules/fastify/lib/handle-request.js +11 -5
- package/node_modules/fastify/lib/plugin-override.js +2 -1
- package/node_modules/fastify/lib/plugin-utils.js +5 -5
- package/node_modules/fastify/lib/reply.js +63 -8
- package/node_modules/fastify/lib/request.js +14 -4
- package/node_modules/fastify/lib/route.js +20 -6
- package/node_modules/fastify/lib/schema-controller.js +1 -1
- package/node_modules/fastify/lib/schemas.js +37 -30
- package/node_modules/fastify/lib/symbols.js +3 -1
- package/node_modules/fastify/lib/validation.js +1 -13
- package/node_modules/fastify/lib/warnings.js +3 -3
- package/node_modules/fastify/package.json +13 -15
- package/node_modules/fastify/scripts/validate-ecosystem-links.js +1 -0
- package/node_modules/fastify/test/bundler/esbuild/package.json +1 -1
- package/node_modules/fastify/test/close-pipelining.test.js +1 -2
- package/node_modules/fastify/test/custom-http-server.test.js +38 -0
- package/node_modules/fastify/test/decorator-instance-properties.test.js +63 -0
- package/node_modules/fastify/test/diagnostics-channel/async-error-handler.test.js +74 -0
- package/node_modules/fastify/test/hooks.test.js +23 -0
- package/node_modules/fastify/test/http-methods/get.test.js +1 -1
- package/node_modules/fastify/test/http2/plain.test.js +135 -0
- package/node_modules/fastify/test/http2/secure-with-fallback.test.js +1 -1
- package/node_modules/fastify/test/https/https.test.js +1 -2
- package/node_modules/fastify/test/internals/errors.test.js +31 -1
- package/node_modules/fastify/test/internals/plugin.test.js +3 -1
- package/node_modules/fastify/test/internals/request.test.js +27 -3
- package/node_modules/fastify/test/internals/schema-controller-perf.test.js +33 -0
- package/node_modules/fastify/test/logger/logging.test.js +18 -1
- package/node_modules/fastify/test/logger/options.test.js +38 -1
- package/node_modules/fastify/test/reply-error.test.js +1 -1
- package/node_modules/fastify/test/reply-trailers.test.js +70 -0
- package/node_modules/fastify/test/request-media-type.test.js +105 -0
- package/node_modules/fastify/test/route-prefix.test.js +34 -0
- package/node_modules/fastify/test/router-options.test.js +222 -11
- package/node_modules/fastify/test/schema-serialization.test.js +108 -0
- package/node_modules/fastify/test/schema-validation.test.js +24 -0
- package/node_modules/fastify/test/scripts/validate-ecosystem-links.test.js +40 -57
- package/node_modules/fastify/test/throw.test.js +14 -0
- package/node_modules/fastify/test/trust-proxy.test.js +21 -0
- package/node_modules/fastify/test/types/content-type-parser.tst.ts +70 -0
- package/node_modules/fastify/test/types/{decorate-request-reply.test-d.ts → decorate-request-reply.tst.ts} +4 -4
- package/node_modules/fastify/test/types/{dummy-plugin.ts → dummy-plugin.mts} +1 -1
- package/node_modules/fastify/test/types/errors.tst.ts +91 -0
- package/node_modules/fastify/test/types/fastify.tst.ts +351 -0
- package/node_modules/fastify/test/types/hooks.tst.ts +578 -0
- package/node_modules/fastify/test/types/instance.tst.ts +597 -0
- package/node_modules/fastify/test/types/{logger.test-d.ts → logger.tst.ts} +61 -62
- package/node_modules/fastify/test/types/plugin.tst.ts +96 -0
- package/node_modules/fastify/test/types/register.tst.ts +245 -0
- package/node_modules/fastify/test/types/reply.tst.ts +297 -0
- package/node_modules/fastify/test/types/request.tst.ts +199 -0
- package/node_modules/fastify/test/types/route.tst.ts +576 -0
- package/node_modules/fastify/test/types/{schema.test-d.ts → schema.tst.ts} +22 -22
- package/node_modules/fastify/test/types/{serverFactory.test-d.ts → serverFactory.tst.ts} +4 -4
- package/node_modules/fastify/test/types/tsconfig.json +9 -0
- package/node_modules/fastify/test/types/{type-provider.test-d.ts → type-provider.tst.ts} +256 -250
- package/node_modules/fastify/test/types/using.tst.ts +14 -0
- package/node_modules/fastify/types/errors.d.ts +3 -0
- package/node_modules/fastify/types/request.d.ts +23 -2
- package/node_modules/jishushell-panel/output/public/assets/{ApiKeyField-NKcbHjNz.js → ApiKeyField-Ce5d1xna.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{Dashboard-Da1fL38t.js → Dashboard-BXame3yg.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{HermesChatPanel-DZvmYsoh.js → HermesChatPanel-BHZtPCJd.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{HermesConfigForm-BLUWlKwm.js → HermesConfigForm-CB3GbNX9.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{InitPassword-BAKsshzk.js → InitPassword-Boab9F6g.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/InstanceDetail-DrIWCqo-.js +14 -0
- package/node_modules/jishushell-panel/output/public/assets/{Login-DHeOmwI8.js → Login-CzpOkNau.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/NewInstance-CANXyCcL.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/{ProviderRecommendations-H0ByEYF0.js → ProviderRecommendations-BABo9VOC.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/Settings-CKp5XxFh.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/Setup-C7xVDPow.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/{WeixinLoginPanel-D-T6BxkQ.js → WeixinLoginPanel-B765Xz4C.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/{index-ERt6_ngA.js → index-Bs6DSbiR.js} +6 -6
- package/node_modules/jishushell-panel/output/public/assets/{registry-DF93EzIb.js → registry-sWIZsIEF.js} +2 -2
- package/node_modules/jishushell-panel/output/public/assets/{usePolling-DeoThIQn.js → usePolling-D4IDOQd_.js} +1 -1
- package/node_modules/jishushell-panel/output/public/assets/vendor-i18n-Df8aUdv8.js +1 -0
- package/node_modules/jishushell-panel/output/public/assets/{vendor-react-Cc84NArf.js → vendor-react-0L0rjmYG.js} +3 -3
- package/node_modules/jishushell-panel/output/public/index.html +3 -3
- package/node_modules/jishushell-panel/package.json +1 -1
- package/node_modules/semver/classes/range.js +6 -2
- package/node_modules/semver/package.json +1 -1
- package/package.json +4 -4
- package/scripts/check-app-spec.mjs +4 -12
- package/scripts/check-architecture-boundaries.mjs +178 -0
- package/scripts/pack-gui-and-send-pi.sh +5 -3
- package/dependencies/jishushell-panel-0.6.18.tgz +0 -0
- package/dist/services/connections/suggestions.d.ts +0 -27
- package/dist/services/connections/suggestions.js +0 -124
- package/dist/services/connections/suggestions.js.map +0 -1
- package/node_modules/fastify/test/types/content-type-parser.test-d.ts +0 -72
- package/node_modules/fastify/test/types/errors.test-d.ts +0 -90
- package/node_modules/fastify/test/types/fastify.test-d.ts +0 -352
- package/node_modules/fastify/test/types/hooks.test-d.ts +0 -550
- package/node_modules/fastify/test/types/import.ts +0 -2
- package/node_modules/fastify/test/types/instance.test-d.ts +0 -588
- package/node_modules/fastify/test/types/plugin.test-d.ts +0 -97
- package/node_modules/fastify/test/types/register.test-d.ts +0 -237
- package/node_modules/fastify/test/types/reply.test-d.ts +0 -254
- package/node_modules/fastify/test/types/request.test-d.ts +0 -188
- package/node_modules/fastify/test/types/route.test-d.ts +0 -553
- package/node_modules/fastify/test/types/using.test-d.ts +0 -17
- package/node_modules/jishushell-panel/output/public/assets/InstanceDetail-Dgyc_TX5.js +0 -14
- package/node_modules/jishushell-panel/output/public/assets/NewInstance-CIy0cYtp.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/Settings-DAT-UMfP.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/Setup-g3uckFYR.js +0 -1
- package/node_modules/jishushell-panel/output/public/assets/vendor-i18n-CS8DFbkQ.js +0 -1
|
@@ -10,6 +10,7 @@ const {
|
|
|
10
10
|
FST_ERR_SCH_DUPLICATE,
|
|
11
11
|
FST_ERR_SCH_CONTENT_MISSING_SCHEMA
|
|
12
12
|
} = require('./errors')
|
|
13
|
+
const ContentType = require('./content-type')
|
|
13
14
|
|
|
14
15
|
const SCHEMAS_SOURCE = ['params', 'body', 'querystring', 'query', 'headers']
|
|
15
16
|
|
|
@@ -147,52 +148,58 @@ function getSchemaSerializer (context, statusCode, contentType) {
|
|
|
147
148
|
return false
|
|
148
149
|
}
|
|
149
150
|
if (responseSchemaDef[statusCode]) {
|
|
150
|
-
if (responseSchemaDef[statusCode].constructor === Object
|
|
151
|
-
const
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
if (responseSchemaDef[statusCode].constructor === Object) {
|
|
152
|
+
const ct = new ContentType(contentType)
|
|
153
|
+
if (ct.isValid) {
|
|
154
|
+
if (responseSchemaDef[statusCode][ct.mediaType]) {
|
|
155
|
+
return responseSchemaDef[statusCode][ct.mediaType]
|
|
156
|
+
}
|
|
155
157
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
// fallback to match all media-type
|
|
159
|
+
if (responseSchemaDef[statusCode]['*/*']) {
|
|
160
|
+
return responseSchemaDef[statusCode]['*/*']
|
|
161
|
+
}
|
|
160
162
|
|
|
161
|
-
|
|
163
|
+
return false
|
|
164
|
+
}
|
|
162
165
|
}
|
|
163
166
|
return responseSchemaDef[statusCode]
|
|
164
167
|
}
|
|
165
168
|
const fallbackStatusCode = (statusCode + '')[0] + 'xx'
|
|
166
169
|
if (responseSchemaDef[fallbackStatusCode]) {
|
|
167
|
-
if (responseSchemaDef[fallbackStatusCode].constructor === Object
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
if (responseSchemaDef[fallbackStatusCode].constructor === Object) {
|
|
171
|
+
const ct = new ContentType(contentType)
|
|
172
|
+
if (ct.isValid) {
|
|
173
|
+
if (responseSchemaDef[fallbackStatusCode][ct.mediaType]) {
|
|
174
|
+
return responseSchemaDef[fallbackStatusCode][ct.mediaType]
|
|
175
|
+
}
|
|
172
176
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
+
// fallback to match all media-type
|
|
178
|
+
if (responseSchemaDef[fallbackStatusCode]['*/*']) {
|
|
179
|
+
return responseSchemaDef[fallbackStatusCode]['*/*']
|
|
180
|
+
}
|
|
177
181
|
|
|
178
|
-
|
|
182
|
+
return false
|
|
183
|
+
}
|
|
179
184
|
}
|
|
180
185
|
|
|
181
186
|
return responseSchemaDef[fallbackStatusCode]
|
|
182
187
|
}
|
|
183
188
|
if (responseSchemaDef.default) {
|
|
184
|
-
if (responseSchemaDef.default.constructor === Object
|
|
185
|
-
const
|
|
186
|
-
if (
|
|
187
|
-
|
|
188
|
-
|
|
189
|
+
if (responseSchemaDef.default.constructor === Object) {
|
|
190
|
+
const ct = new ContentType(contentType)
|
|
191
|
+
if (ct.isValid) {
|
|
192
|
+
if (responseSchemaDef.default[ct.mediaType]) {
|
|
193
|
+
return responseSchemaDef.default[ct.mediaType]
|
|
194
|
+
}
|
|
189
195
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
196
|
+
// fallback to match all media-type
|
|
197
|
+
if (responseSchemaDef.default['*/*']) {
|
|
198
|
+
return responseSchemaDef.default['*/*']
|
|
199
|
+
}
|
|
194
200
|
|
|
195
|
-
|
|
201
|
+
return false
|
|
202
|
+
}
|
|
196
203
|
}
|
|
197
204
|
|
|
198
205
|
return responseSchemaDef.default
|
|
@@ -32,6 +32,7 @@ const keys = {
|
|
|
32
32
|
kRequestPayloadStream: Symbol('fastify.RequestPayloadStream'),
|
|
33
33
|
kRequestAcceptVersion: Symbol('fastify.RequestAcceptVersion'),
|
|
34
34
|
kRequestCacheValidateFns: Symbol('fastify.request.cache.validateFns'),
|
|
35
|
+
kRequestContentType: Symbol('fastify.request.contentType'),
|
|
35
36
|
kRequestOriginalUrl: Symbol('fastify.request.originalUrl'),
|
|
36
37
|
kRequestSignal: Symbol('fastify.request.signal'),
|
|
37
38
|
kHandlerTimeout: Symbol('fastify.handlerTimeout'),
|
|
@@ -65,7 +66,8 @@ const keys = {
|
|
|
65
66
|
kChildLoggerFactory: Symbol('fastify.childLoggerFactory'),
|
|
66
67
|
kHasBeenDecorated: Symbol('fastify.hasBeenDecorated'),
|
|
67
68
|
kKeepAliveConnections: Symbol('fastify.keepAliveConnections'),
|
|
68
|
-
kRouteByFastify: Symbol('fastify.routeByFastify')
|
|
69
|
+
kRouteByFastify: Symbol('fastify.routeByFastify'),
|
|
70
|
+
kDiagnosticsStore: Symbol('fastify.diagnosticsStore')
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
module.exports = keys
|
|
@@ -162,9 +162,7 @@ function validate (context, request, execution) {
|
|
|
162
162
|
if (typeof context[bodySchema] === 'function') {
|
|
163
163
|
validatorFunction = context[bodySchema]
|
|
164
164
|
} else if (context[bodySchema]) {
|
|
165
|
-
|
|
166
|
-
const contentType = getEssenceMediaType(request.headers['content-type'])
|
|
167
|
-
const contentSchema = context[bodySchema][contentType]
|
|
165
|
+
const contentSchema = context[bodySchema][request.mediaType]
|
|
168
166
|
if (contentSchema) {
|
|
169
167
|
validatorFunction = contentSchema
|
|
170
168
|
}
|
|
@@ -262,16 +260,6 @@ function wrapValidationError (result, dataVar, schemaErrorFormatter) {
|
|
|
262
260
|
return error
|
|
263
261
|
}
|
|
264
262
|
|
|
265
|
-
/**
|
|
266
|
-
* simple function to retrieve the essence media type
|
|
267
|
-
* @param {string} header
|
|
268
|
-
* @returns {string} Mimetype string.
|
|
269
|
-
*/
|
|
270
|
-
function getEssenceMediaType (header) {
|
|
271
|
-
if (!header) return ''
|
|
272
|
-
return header.trimStart().split(/[ ;]/, 1)[0].trim().toLowerCase()
|
|
273
|
-
}
|
|
274
|
-
|
|
275
263
|
module.exports = {
|
|
276
264
|
symbols: { bodySchema, querystringSchema, responseSchema, paramsSchema, headersSchema },
|
|
277
265
|
compileSchemasForValidation,
|
|
@@ -8,9 +8,9 @@ const { createWarning } = require('process-warning')
|
|
|
8
8
|
* - FSTSEC001
|
|
9
9
|
* - FSTDEP022
|
|
10
10
|
*
|
|
11
|
-
* Deprecation Codes FSTDEP001 - FSTDEP021 were used by v4 and MUST NOT
|
|
11
|
+
* Deprecation Codes FSTDEP001 - FSTDEP021 were used by v4 and MUST NOT be reused.
|
|
12
12
|
* - FSTDEP022 is used by v5 and MUST NOT be reused.
|
|
13
|
-
* Warning Codes FSTWRN001 - FSTWRN002 were used by v4 and MUST NOT
|
|
13
|
+
* Warning Codes FSTWRN001 - FSTWRN002 were used by v4 and MUST NOT be reused.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const FSTWRN001 = createWarning({
|
|
@@ -30,7 +30,7 @@ const FSTWRN003 = createWarning({
|
|
|
30
30
|
const FSTWRN004 = createWarning({
|
|
31
31
|
name: 'FastifyWarning',
|
|
32
32
|
code: 'FSTWRN004',
|
|
33
|
-
message: 'It seems that you are overriding an errorHandler in the same scope, which can lead to subtle bugs.',
|
|
33
|
+
message: 'It seems that you are overriding an errorHandler in the same scope, which can lead to subtle bugs. To disable this behavior, set \'allowErrorHandlerOverride\' to false. For more information, visit: https://fastify.dev/docs/latest/Reference/Server/#allowerrorhandleroverride',
|
|
34
34
|
unlimited: true
|
|
35
35
|
})
|
|
36
36
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.9.0",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"lint:markdown": "markdownlint-cli2",
|
|
20
20
|
"lint:eslint": "eslint",
|
|
21
21
|
"prepublishOnly": "cross-env PREPUBLISH=true borp --reporter=@jsumners/line-reporter && npm run test:validator:integrity && npm run build:sync-version",
|
|
22
|
-
"test": "npm run lint && npm run unit && npm run test:
|
|
23
|
-
"test:ci": "npm run unit && npm run test:
|
|
24
|
-
"test:report": "npm run lint && npm run unit:report && npm run test:
|
|
22
|
+
"test": "npm run lint && npm run unit && npm run test:types",
|
|
23
|
+
"test:ci": "npm run unit && npm run test:types",
|
|
24
|
+
"test:report": "npm run lint && npm run unit:report && npm run test:types",
|
|
25
25
|
"test:validator:integrity": "npm run build:validation && git diff --quiet --ignore-all-space --ignore-blank-lines --ignore-cr-at-eol lib/error-serializer.js && git diff --quiet --ignore-all-space --ignore-blank-lines --ignore-cr-at-eol lib/config-validator.js",
|
|
26
|
-
"test:
|
|
26
|
+
"test:types": "tstyche",
|
|
27
27
|
"test:watch": "npm run unit -- --watch --coverage-report=none --reporter=terse",
|
|
28
28
|
"unit": "borp",
|
|
29
29
|
"unit:report": "c8 --reporter html borp --reporter=@jsumners/line-reporter",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"contributors": [
|
|
46
46
|
{
|
|
47
47
|
"name": "Tomas Della Vedova",
|
|
48
|
-
"url": "
|
|
48
|
+
"url": "https://delvedor.dev",
|
|
49
49
|
"author": true
|
|
50
50
|
},
|
|
51
51
|
{
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
"name": "Dustin Deus",
|
|
62
|
-
"url": "
|
|
62
|
+
"url": "https://starptech.com",
|
|
63
63
|
"email": "deusdustin@gmail.com"
|
|
64
64
|
},
|
|
65
65
|
{
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
"name": "Trivikram Kamat",
|
|
77
|
-
"url": "
|
|
77
|
+
"url": "https://trivikr.github.io",
|
|
78
78
|
"email": "trivikr.dev@gmail.com"
|
|
79
79
|
},
|
|
80
80
|
{
|
|
@@ -179,11 +179,12 @@
|
|
|
179
179
|
"autocannon": "^8.0.0",
|
|
180
180
|
"borp": "^1.0.0",
|
|
181
181
|
"branch-comparer": "^1.1.0",
|
|
182
|
-
"concurrently": "^
|
|
182
|
+
"concurrently": "^10.0.0",
|
|
183
183
|
"cross-env": "^10.0.0",
|
|
184
184
|
"eslint": "^9.0.0",
|
|
185
185
|
"fast-json-body": "^1.1.0",
|
|
186
|
-
"fastify-plugin": "^
|
|
186
|
+
"fastify-plugin": "^6.0.0",
|
|
187
|
+
"fastify-tsconfig": "^3.0.0",
|
|
187
188
|
"fluent-json-schema": "^6.0.0",
|
|
188
189
|
"h2url": "^0.2.0",
|
|
189
190
|
"http-errors": "^2.0.0",
|
|
@@ -195,7 +196,7 @@
|
|
|
195
196
|
"node-forge": "^1.3.1",
|
|
196
197
|
"proxyquire": "^2.1.3",
|
|
197
198
|
"split2": "^4.2.0",
|
|
198
|
-
"
|
|
199
|
+
"tstyche": "^7.0.0",
|
|
199
200
|
"typebox": "^1.0.81",
|
|
200
201
|
"typescript": "~6.0.2",
|
|
201
202
|
"undici": "^7.11.0",
|
|
@@ -210,7 +211,7 @@
|
|
|
210
211
|
"abstract-logging": "^2.0.1",
|
|
211
212
|
"avvio": "^9.0.0",
|
|
212
213
|
"fast-json-stringify": "^6.0.0",
|
|
213
|
-
"find-my-way": "^9.
|
|
214
|
+
"find-my-way": "^9.6.0",
|
|
214
215
|
"light-my-request": "^6.0.0",
|
|
215
216
|
"pino": "^9.14.0 || ^10.1.0",
|
|
216
217
|
"process-warning": "^5.0.0",
|
|
@@ -218,8 +219,5 @@
|
|
|
218
219
|
"secure-json-parse": "^4.0.0",
|
|
219
220
|
"semver": "^7.6.0",
|
|
220
221
|
"toad-cache": "^3.7.0"
|
|
221
|
-
},
|
|
222
|
-
"tsd": {
|
|
223
|
-
"directory": "test/types"
|
|
224
222
|
}
|
|
225
223
|
}
|
|
@@ -41,8 +41,7 @@ test('Should return 503 while closing - pipelining', async t => {
|
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
test('Should close the socket abruptly - pipelining - return503OnClosing: false', async t => {
|
|
44
|
-
//
|
|
45
|
-
// therefore our socket will be closed
|
|
44
|
+
// Node.js will always invoke server.closeIdleConnections() therefore our socket will be closed
|
|
46
45
|
const fastify = Fastify({
|
|
47
46
|
return503OnClosing: false,
|
|
48
47
|
forceCloseConnections: false
|
|
@@ -63,6 +63,44 @@ async function setup () {
|
|
|
63
63
|
)
|
|
64
64
|
})
|
|
65
65
|
|
|
66
|
+
test('Should not make an extra closeIdleConnections call for native servers', async t => {
|
|
67
|
+
const fastify = Fastify({
|
|
68
|
+
forceCloseConnections: 'idle'
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
await fastify.listen({ port: 0 })
|
|
72
|
+
|
|
73
|
+
let called = 0
|
|
74
|
+
fastify.server.closeIdleConnections = function () {
|
|
75
|
+
called++
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
await fastify.close()
|
|
79
|
+
|
|
80
|
+
t.assert.strictEqual(called, 1)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
test('Should preserve the extra closeIdleConnections call for custom servers', async t => {
|
|
84
|
+
let called = 0
|
|
85
|
+
const fastify = Fastify({
|
|
86
|
+
forceCloseConnections: 'idle',
|
|
87
|
+
serverFactory (handler) {
|
|
88
|
+
const server = http.createServer(handler)
|
|
89
|
+
const originalCloseIdleConnections = server.closeIdleConnections.bind(server)
|
|
90
|
+
server.closeIdleConnections = function () {
|
|
91
|
+
called++
|
|
92
|
+
return originalCloseIdleConnections()
|
|
93
|
+
}
|
|
94
|
+
return server
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
await fastify.listen({ port: 0 })
|
|
99
|
+
await fastify.close()
|
|
100
|
+
|
|
101
|
+
t.assert.strictEqual(called, 2)
|
|
102
|
+
})
|
|
103
|
+
|
|
66
104
|
test('Should accept user defined serverFactory and ignore secondary server creation', async t => {
|
|
67
105
|
const server = http.createServer(() => { })
|
|
68
106
|
t.after(() => new Promise(resolve => server.close(resolve)))
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('node:test')
|
|
4
|
+
const Fastify = require('..')
|
|
5
|
+
|
|
6
|
+
test('hasRequestDecorator returns true for built-in constructor-assigned request properties', t => {
|
|
7
|
+
t.plan(6)
|
|
8
|
+
const fastify = Fastify()
|
|
9
|
+
t.assert.equal(fastify.hasRequestDecorator('id'), true)
|
|
10
|
+
t.assert.equal(fastify.hasRequestDecorator('params'), true)
|
|
11
|
+
t.assert.equal(fastify.hasRequestDecorator('raw'), true)
|
|
12
|
+
t.assert.equal(fastify.hasRequestDecorator('query'), true)
|
|
13
|
+
t.assert.equal(fastify.hasRequestDecorator('log'), true)
|
|
14
|
+
t.assert.equal(fastify.hasRequestDecorator('body'), true)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('hasReplyDecorator returns true for built-in constructor-assigned reply properties', t => {
|
|
18
|
+
t.plan(3)
|
|
19
|
+
const fastify = Fastify()
|
|
20
|
+
t.assert.equal(fastify.hasReplyDecorator('raw'), true)
|
|
21
|
+
t.assert.equal(fastify.hasReplyDecorator('request'), true)
|
|
22
|
+
t.assert.equal(fastify.hasReplyDecorator('log'), true)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('decorateRequest throws FST_ERR_DEC_ALREADY_PRESENT for built-in request properties', t => {
|
|
26
|
+
t.plan(4)
|
|
27
|
+
const fastify = Fastify()
|
|
28
|
+
for (const name of ['id', 'params', 'raw', 'body']) {
|
|
29
|
+
t.assert.throws(
|
|
30
|
+
() => fastify.decorateRequest(name, null),
|
|
31
|
+
(err) => err.code === 'FST_ERR_DEC_ALREADY_PRESENT'
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('decorateReply throws FST_ERR_DEC_ALREADY_PRESENT for built-in reply properties', t => {
|
|
37
|
+
t.plan(2)
|
|
38
|
+
const fastify = Fastify()
|
|
39
|
+
for (const name of ['raw', 'request']) {
|
|
40
|
+
t.assert.throws(
|
|
41
|
+
() => fastify.decorateReply(name, null),
|
|
42
|
+
(err) => err.code === 'FST_ERR_DEC_ALREADY_PRESENT'
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
test('hasRequestDecorator returns false for unknown properties', t => {
|
|
48
|
+
t.plan(1)
|
|
49
|
+
const fastify = Fastify()
|
|
50
|
+
t.assert.equal(fastify.hasRequestDecorator('nonExistent'), false)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('decorateRequest still works for non-built-in names', (t, done) => {
|
|
54
|
+
t.plan(2)
|
|
55
|
+
const fastify = Fastify()
|
|
56
|
+
fastify.decorateRequest('myExtra', null)
|
|
57
|
+
t.assert.equal(fastify.hasRequestDecorator('myExtra'), true)
|
|
58
|
+
fastify.get('/', async (req) => req.myExtra)
|
|
59
|
+
fastify.ready((err) => {
|
|
60
|
+
t.assert.ifError(err)
|
|
61
|
+
done()
|
|
62
|
+
})
|
|
63
|
+
})
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('node:test')
|
|
4
|
+
const diagnostics = require('node:diagnostics_channel')
|
|
5
|
+
const Fastify = require('../..')
|
|
6
|
+
const Request = require('../../lib/request')
|
|
7
|
+
const Reply = require('../../lib/reply')
|
|
8
|
+
|
|
9
|
+
test('diagnostics channel tracks async operations in async error handlers', async t => {
|
|
10
|
+
t.plan(17)
|
|
11
|
+
let callOrder = 0
|
|
12
|
+
let firstEncounteredMessage
|
|
13
|
+
let asyncStartFired = false
|
|
14
|
+
let asyncEndFired = false
|
|
15
|
+
|
|
16
|
+
const fastify = Fastify()
|
|
17
|
+
|
|
18
|
+
function subscribe (name, handler) {
|
|
19
|
+
const wrapped = (msg) => {
|
|
20
|
+
if (msg.request.server === fastify) handler(msg)
|
|
21
|
+
}
|
|
22
|
+
diagnostics.subscribe(name, wrapped)
|
|
23
|
+
t.after(() => diagnostics.unsubscribe(name, wrapped))
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
subscribe('tracing:fastify.request.handler:start', (msg) => {
|
|
27
|
+
t.assert.strictEqual(callOrder++, 0)
|
|
28
|
+
firstEncounteredMessage = msg
|
|
29
|
+
t.assert.ok(msg.request instanceof Request)
|
|
30
|
+
t.assert.ok(msg.reply instanceof Reply)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
subscribe('tracing:fastify.request.handler:error', (msg) => {
|
|
34
|
+
t.assert.strictEqual(callOrder++, 1)
|
|
35
|
+
t.assert.ok(msg.error instanceof Error)
|
|
36
|
+
t.assert.strictEqual(msg.error.message, 'handler error')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
subscribe('tracing:fastify.request.handler:end', (msg) => {
|
|
40
|
+
t.assert.strictEqual(callOrder++, 2)
|
|
41
|
+
t.assert.strictEqual(msg, firstEncounteredMessage)
|
|
42
|
+
t.assert.strictEqual(msg.async, true)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
subscribe('tracing:fastify.request.handler:asyncStart', (msg) => {
|
|
46
|
+
t.assert.strictEqual(callOrder++, 3)
|
|
47
|
+
t.assert.strictEqual(msg, firstEncounteredMessage)
|
|
48
|
+
asyncStartFired = true
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
subscribe('tracing:fastify.request.handler:asyncEnd', (msg) => {
|
|
52
|
+
t.assert.strictEqual(callOrder++, 4)
|
|
53
|
+
t.assert.strictEqual(msg, firstEncounteredMessage)
|
|
54
|
+
asyncEndFired = true
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
fastify.setErrorHandler(async (error, request, reply) => {
|
|
58
|
+
await new Promise(resolve => setImmediate(resolve))
|
|
59
|
+
reply.status(503).send({ error: error.message })
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
fastify.get('/', () => {
|
|
63
|
+
throw new Error('handler error')
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
67
|
+
t.after(() => fastify.close())
|
|
68
|
+
|
|
69
|
+
const response = await fetch(fastifyServer)
|
|
70
|
+
t.assert.ok(!response.ok)
|
|
71
|
+
t.assert.strictEqual(response.status, 503)
|
|
72
|
+
t.assert.ok(asyncStartFired, 'asyncStart should fire for async error handler')
|
|
73
|
+
t.assert.ok(asyncEndFired, 'asyncEnd should fire for async error handler')
|
|
74
|
+
})
|
|
@@ -12,6 +12,7 @@ const proxyquire = require('proxyquire')
|
|
|
12
12
|
const { connect } = require('node:net')
|
|
13
13
|
const { sleep } = require('./helper')
|
|
14
14
|
const { waitForCb } = require('./toolkit.js')
|
|
15
|
+
const { fetch } = require('undici')
|
|
15
16
|
|
|
16
17
|
process.removeAllListeners('warning')
|
|
17
18
|
|
|
@@ -3277,6 +3278,28 @@ test('onTimeout should be triggered and socket _meta is set', async t => {
|
|
|
3277
3278
|
}
|
|
3278
3279
|
})
|
|
3279
3280
|
|
|
3281
|
+
test('socket._meta is cleared after response to prevent keep-alive leaks', async t => {
|
|
3282
|
+
t.plan(3)
|
|
3283
|
+
const fastify = Fastify({ connectionTimeout: 500 })
|
|
3284
|
+
t.after(() => { fastify.close() })
|
|
3285
|
+
|
|
3286
|
+
fastify.addHook('onTimeout', function (req, res, done) { done() })
|
|
3287
|
+
|
|
3288
|
+
fastify.addHook('onResponse', function (req, reply, done) {
|
|
3289
|
+
t.assert.strictEqual(req.raw.socket._meta, null, 'socket._meta must be null after response')
|
|
3290
|
+
done()
|
|
3291
|
+
})
|
|
3292
|
+
|
|
3293
|
+
fastify.get('/', async (req, reply) => {
|
|
3294
|
+
return { hello: 'world' }
|
|
3295
|
+
})
|
|
3296
|
+
|
|
3297
|
+
const address = await fastify.listen({ port: 0 })
|
|
3298
|
+
const result = await fetch(address)
|
|
3299
|
+
t.assert.ok(result.ok)
|
|
3300
|
+
t.assert.strictEqual(result.status, 200)
|
|
3301
|
+
})
|
|
3302
|
+
|
|
3280
3303
|
test('registering invalid hooks should throw an error', async t => {
|
|
3281
3304
|
t.plan(3)
|
|
3282
3305
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
|
+
const http2 = require('node:http2')
|
|
4
5
|
const Fastify = require('../..')
|
|
5
6
|
const h2url = require('h2url')
|
|
6
7
|
const msg = { hello: 'world' }
|
|
@@ -66,3 +67,137 @@ test('http2 plain test', async t => {
|
|
|
66
67
|
t.assert.strictEqual(JSON.parse(res.body).port, parseInt(host.split(':')[1]))
|
|
67
68
|
})
|
|
68
69
|
})
|
|
70
|
+
|
|
71
|
+
test('http2 large non-stream replies are sent completely', async t => {
|
|
72
|
+
const modes = ['buffer', 'string']
|
|
73
|
+
|
|
74
|
+
for (const mode of modes) {
|
|
75
|
+
await t.test(mode, async t => {
|
|
76
|
+
const fastify = Fastify({ http2: true })
|
|
77
|
+
const payload = mode === 'buffer'
|
|
78
|
+
? Buffer.alloc((64 * 1024) + 1, 'a')
|
|
79
|
+
: 'a'.repeat((64 * 1024) + 1)
|
|
80
|
+
const contentLength = Buffer.byteLength(payload)
|
|
81
|
+
|
|
82
|
+
fastify.get('/large', async (req, reply) => {
|
|
83
|
+
reply.header('content-type', 'application/octet-stream')
|
|
84
|
+
reply.header('content-length', contentLength)
|
|
85
|
+
|
|
86
|
+
return payload
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
await fastify.listen({ port: 0, host: '127.0.0.1' })
|
|
90
|
+
|
|
91
|
+
const client = http2.connect(`http://127.0.0.1:${fastify.server.address().port}`)
|
|
92
|
+
t.after(() => {
|
|
93
|
+
client.close()
|
|
94
|
+
return fastify.close()
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
await new Promise((resolve, reject) => {
|
|
98
|
+
const large = client.request({
|
|
99
|
+
[http2.constants.HTTP2_HEADER_METHOD]: http2.constants.HTTP2_METHOD_GET,
|
|
100
|
+
[http2.constants.HTTP2_HEADER_PATH]: '/large'
|
|
101
|
+
})
|
|
102
|
+
const chunks = []
|
|
103
|
+
|
|
104
|
+
large.on('error', reject)
|
|
105
|
+
large.on('data', chunk => {
|
|
106
|
+
chunks.push(chunk)
|
|
107
|
+
})
|
|
108
|
+
large.on('end', () => {
|
|
109
|
+
t.assert.strictEqual(Buffer.concat(chunks).length, contentLength)
|
|
110
|
+
resolve()
|
|
111
|
+
})
|
|
112
|
+
large.end()
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
test('http2 large buffer replies can be cancelled without rejecting the next stream', async t => {
|
|
119
|
+
const fastify = Fastify({ http2: true })
|
|
120
|
+
const payload = Buffer.alloc(32 * 1024 * 1024, 'a')
|
|
121
|
+
let smallHit = false
|
|
122
|
+
|
|
123
|
+
fastify.get('/large', async (req, reply) => {
|
|
124
|
+
reply.header('content-type', 'application/octet-stream')
|
|
125
|
+
reply.header('content-length', payload.length)
|
|
126
|
+
|
|
127
|
+
return payload
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
fastify.get('/small', async () => {
|
|
131
|
+
smallHit = true
|
|
132
|
+
return 'ok'
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
await fastify.listen({ port: 0, host: '127.0.0.1' })
|
|
136
|
+
|
|
137
|
+
const client = http2.connect(`http://127.0.0.1:${fastify.server.address().port}`)
|
|
138
|
+
t.after(() => {
|
|
139
|
+
client.close()
|
|
140
|
+
return fastify.close()
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
await new Promise((resolve, reject) => {
|
|
144
|
+
let cancelTimer
|
|
145
|
+
let requestTimer
|
|
146
|
+
let timeout
|
|
147
|
+
|
|
148
|
+
function cleanup () {
|
|
149
|
+
clearTimeout(cancelTimer)
|
|
150
|
+
clearTimeout(requestTimer)
|
|
151
|
+
clearTimeout(timeout)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const large = client.request({
|
|
155
|
+
[http2.constants.HTTP2_HEADER_METHOD]: http2.constants.HTTP2_METHOD_GET,
|
|
156
|
+
[http2.constants.HTTP2_HEADER_PATH]: '/large'
|
|
157
|
+
})
|
|
158
|
+
let largeResponded = false
|
|
159
|
+
|
|
160
|
+
large.on('error', err => {
|
|
161
|
+
if (!largeResponded) {
|
|
162
|
+
cleanup()
|
|
163
|
+
reject(err)
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
large.on('response', () => {
|
|
167
|
+
largeResponded = true
|
|
168
|
+
large.pause()
|
|
169
|
+
cancelTimer = setTimeout(() => {
|
|
170
|
+
large.close(http2.constants.NGHTTP2_CANCEL)
|
|
171
|
+
}, 100)
|
|
172
|
+
requestTimer = setTimeout(() => {
|
|
173
|
+
const small = client.request({
|
|
174
|
+
[http2.constants.HTTP2_HEADER_METHOD]: http2.constants.HTTP2_METHOD_GET,
|
|
175
|
+
[http2.constants.HTTP2_HEADER_PATH]: '/small'
|
|
176
|
+
})
|
|
177
|
+
let body = ''
|
|
178
|
+
|
|
179
|
+
timeout = setTimeout(() => {
|
|
180
|
+
cleanup()
|
|
181
|
+
reject(new Error('timed out waiting for /small response'))
|
|
182
|
+
}, 3000)
|
|
183
|
+
|
|
184
|
+
small.setEncoding('utf8')
|
|
185
|
+
small.on('error', err => {
|
|
186
|
+
cleanup()
|
|
187
|
+
reject(err)
|
|
188
|
+
})
|
|
189
|
+
small.on('data', chunk => {
|
|
190
|
+
body += chunk
|
|
191
|
+
})
|
|
192
|
+
small.on('end', () => {
|
|
193
|
+
cleanup()
|
|
194
|
+
t.assert.strictEqual(body, 'ok')
|
|
195
|
+
t.assert.strictEqual(smallHit, true)
|
|
196
|
+
resolve()
|
|
197
|
+
})
|
|
198
|
+
small.end()
|
|
199
|
+
}, 200)
|
|
200
|
+
})
|
|
201
|
+
large.end()
|
|
202
|
+
})
|
|
203
|
+
})
|
|
@@ -6,7 +6,7 @@ const h2url = require('h2url')
|
|
|
6
6
|
const msg = { hello: 'world' }
|
|
7
7
|
|
|
8
8
|
const { buildCertificate } = require('../build-certificate')
|
|
9
|
-
const { Agent } = require('undici')
|
|
9
|
+
const { Agent, fetch } = require('undici')
|
|
10
10
|
test.before(buildCertificate)
|
|
11
11
|
|
|
12
12
|
test('secure with fallback', async (t) => {
|