@lovrozagar/honey 0.6.8 → 0.7.1
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/README.md +514 -192
- package/bin/honey.js +25 -0
- package/dist/accepts.d.ts +7 -1
- package/dist/accepts.d.ts.map +1 -1
- package/dist/accepts.js +126 -0
- package/dist/accepts.js.map +1 -0
- package/dist/body-kind.d.ts +26 -0
- package/dist/body-kind.d.ts.map +1 -0
- package/dist/body-kind.js +70 -0
- package/dist/body-kind.js.map +1 -0
- package/dist/body-limit.d.ts +5 -1
- package/dist/body-limit.d.ts.map +1 -1
- package/dist/body-limit.js +126 -0
- package/dist/body-limit.js.map +1 -0
- package/dist/build/index.d.ts +19 -3
- package/dist/build/index.d.ts.map +1 -1
- package/dist/build/index.js +173 -0
- package/dist/build/index.js.map +1 -0
- package/dist/cli-args.d.ts +33 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +102 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-go/auth.go +26 -0
- package/dist/cli-go/config.go +192 -0
- package/dist/cli-go/errors.go +75 -0
- package/dist/cli-go/multipart.go +79 -0
- package/dist/cli-go/output.go +163 -0
- package/dist/cli-go/root.go +30 -0
- package/dist/cli-go/stream.go +88 -0
- package/dist/cli-go/version.go +5 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +209 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/defaults.js +48 -0
- package/dist/client/defaults.js.map +1 -0
- package/dist/client/error.d.ts +35 -0
- package/dist/client/error.d.ts.map +1 -1
- package/dist/client/error.js +71 -0
- package/dist/client/error.js.map +1 -0
- package/dist/client/http.d.ts +67 -8
- package/dist/client/http.d.ts.map +1 -1
- package/dist/client/http.js +571 -0
- package/dist/client/http.js.map +1 -0
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +95 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/path.d.ts +26 -0
- package/dist/client/path.d.ts.map +1 -0
- package/dist/client/path.js +163 -0
- package/dist/client/path.js.map +1 -0
- package/dist/client/redirect-policy.d.ts +12 -0
- package/dist/client/redirect-policy.d.ts.map +1 -0
- package/dist/client/redirect-policy.js +20 -0
- package/dist/client/redirect-policy.js.map +1 -0
- package/dist/client/sdk.d.ts +36 -0
- package/dist/client/sdk.d.ts.map +1 -1
- package/dist/client/sdk.js +292 -0
- package/dist/client/sdk.js.map +1 -0
- package/dist/client/sse.d.ts +13 -0
- package/dist/client/sse.d.ts.map +1 -1
- package/dist/client/sse.js +129 -0
- package/dist/client/sse.js.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/ws.d.ts +9 -2
- package/dist/client/ws.d.ts.map +1 -1
- package/dist/client/ws.js +112 -0
- package/dist/client/ws.js.map +1 -0
- package/dist/client-go/errors.go +236 -0
- package/dist/client-go/export.go +44 -0
- package/dist/client-go/invalidation.go +371 -0
- package/dist/client-go/nullable.go +62 -0
- package/dist/client-go/realtime.go +354 -0
- package/dist/client-go/result.go +20 -0
- package/dist/client-go/runtime.go +975 -0
- package/dist/client-go/sse.go +159 -0
- package/dist/client-go/transport.go +495 -0
- package/dist/client-go/ws.go +128 -0
- package/dist/client-info.d.ts +36 -0
- package/dist/client-info.d.ts.map +1 -0
- package/dist/client-info.js +53 -0
- package/dist/client-info.js.map +1 -0
- package/dist/client-mcp/README.md +10 -0
- package/dist/client-mcp/server.ts +221 -0
- package/dist/client-mcp/types.ts +19 -0
- package/dist/client-python/_errors.py +115 -0
- package/dist/client-python/_invalidation.py +494 -0
- package/dist/client-python/_realtime.py +179 -0
- package/dist/client-python/_runtime.py +860 -0
- package/dist/client-python/_sse.py +155 -0
- package/dist/client-python/_transport.py +366 -0
- package/dist/client-python/_ws.py +159 -0
- package/dist/client-python/py.typed +0 -0
- package/dist/client-rust/errors.rs +220 -0
- package/dist/client-rust/invalidation.rs +412 -0
- package/dist/client-rust/invalidation_sync.rs +93 -0
- package/dist/client-rust/nullable.rs +17 -0
- package/dist/client-rust/realtime.rs +702 -0
- package/dist/client-rust/result.rs +22 -0
- package/dist/client-rust/runtime.rs +980 -0
- package/dist/client-rust/runtime_sync.rs +484 -0
- package/dist/client-rust/sse.rs +188 -0
- package/dist/client-rust/ws.rs +167 -0
- package/dist/codegen-go-cli.d.ts.map +1 -1
- package/dist/codegen-go-cli.js +964 -0
- package/dist/codegen-go-cli.js.map +1 -0
- package/dist/codegen-go.d.ts +15 -3
- package/dist/codegen-go.d.ts.map +1 -1
- package/dist/codegen-go.js +872 -0
- package/dist/codegen-go.js.map +1 -0
- package/dist/codegen-hash.js +9 -0
- package/dist/codegen-hash.js.map +1 -0
- package/dist/codegen-ir.d.ts +69 -2
- package/dist/codegen-ir.d.ts.map +1 -1
- package/dist/codegen-ir.js +661 -0
- package/dist/codegen-ir.js.map +1 -0
- package/dist/codegen-lang.d.ts +65 -0
- package/dist/codegen-lang.d.ts.map +1 -0
- package/dist/codegen-lang.js +526 -0
- package/dist/codegen-lang.js.map +1 -0
- package/dist/codegen-load.d.ts +31 -0
- package/dist/codegen-load.d.ts.map +1 -0
- package/dist/codegen-load.js +138 -0
- package/dist/codegen-load.js.map +1 -0
- package/dist/codegen-loaders.js +55 -0
- package/dist/codegen-loaders.js.map +1 -0
- package/dist/codegen-mcp.d.ts.map +1 -1
- package/dist/codegen-mcp.js +368 -0
- package/dist/codegen-mcp.js.map +1 -0
- package/dist/codegen-python.d.ts +13 -1
- package/dist/codegen-python.d.ts.map +1 -1
- package/dist/codegen-python.js +828 -0
- package/dist/codegen-python.js.map +1 -0
- package/dist/codegen-route-tree-intern.d.ts +15 -5
- package/dist/codegen-route-tree-intern.d.ts.map +1 -1
- package/dist/codegen-route-tree-intern.js +221 -0
- package/dist/codegen-route-tree-intern.js.map +1 -0
- package/dist/codegen-rust.d.ts.map +1 -1
- package/dist/codegen-rust.js +1293 -0
- package/dist/codegen-rust.js.map +1 -0
- package/dist/codegen-sanitize.d.ts.map +1 -1
- package/dist/codegen-sanitize.js +56 -0
- package/dist/codegen-sanitize.js.map +1 -0
- package/dist/codegen-schema-naming.d.ts +5 -0
- package/dist/codegen-schema-naming.d.ts.map +1 -1
- package/dist/codegen-schema-naming.js +150 -0
- package/dist/codegen-schema-naming.js.map +1 -0
- package/dist/codegen-sdk-model.d.ts +71 -0
- package/dist/codegen-sdk-model.d.ts.map +1 -0
- package/dist/codegen-sdk-model.js +179 -0
- package/dist/codegen-sdk-model.js.map +1 -0
- package/dist/codegen.d.ts +41 -23
- package/dist/codegen.d.ts.map +1 -1
- package/dist/codegen.js +4610 -0
- package/dist/codegen.js.map +1 -0
- package/dist/context.d.ts +36 -6
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +242 -0
- package/dist/context.js.map +1 -0
- package/dist/cookie-sign.d.ts +16 -2
- package/dist/cookie-sign.d.ts.map +1 -1
- package/dist/cookie-sign.js +104 -0
- package/dist/cookie-sign.js.map +1 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.d.ts.map +1 -1
- package/dist/cookie.js +138 -0
- package/dist/cookie.js.map +1 -0
- package/dist/cors.d.ts +1 -0
- package/dist/cors.d.ts.map +1 -1
- package/dist/cors.js +87 -0
- package/dist/cors.js.map +1 -0
- package/dist/crypto.d.ts +6 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +38 -0
- package/dist/crypto.js.map +1 -0
- package/dist/csrf.d.ts +19 -0
- package/dist/csrf.d.ts.map +1 -1
- package/dist/csrf.js +79 -0
- package/dist/csrf.js.map +1 -0
- package/dist/curl-logger.d.ts +14 -3
- package/dist/curl-logger.d.ts.map +1 -1
- package/dist/curl-logger.js +199 -0
- package/dist/curl-logger.js.map +1 -0
- package/dist/detect-runtime.js +13 -0
- package/dist/detect-runtime.js.map +1 -0
- package/dist/dict.d.ts +11 -0
- package/dist/dict.d.ts.map +1 -0
- package/dist/dict.js +13 -0
- package/dist/dict.js.map +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +44 -0
- package/dist/error.js.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/etag.d.ts +2 -0
- package/dist/etag.d.ts.map +1 -1
- package/dist/etag.js +82 -0
- package/dist/etag.js.map +1 -0
- package/dist/feature-detect.d.ts +25 -0
- package/dist/feature-detect.d.ts.map +1 -0
- package/dist/feature-detect.js +144 -0
- package/dist/feature-detect.js.map +1 -0
- package/dist/feature-load.js +36 -0
- package/dist/feature-load.js.map +1 -0
- package/dist/feature-slots.d.ts +44 -0
- package/dist/feature-slots.d.ts.map +1 -0
- package/dist/feature-slots.js +48 -0
- package/dist/feature-slots.js.map +1 -0
- package/dist/fetch-request.d.ts +10 -0
- package/dist/fetch-request.d.ts.map +1 -0
- package/dist/fetch-request.js +13 -0
- package/dist/fetch-request.js.map +1 -0
- package/dist/gen-process.d.ts +15 -0
- package/dist/gen-process.d.ts.map +1 -0
- package/dist/gen-process.js +43 -0
- package/dist/gen-process.js.map +1 -0
- package/dist/gen-write.d.ts +19 -0
- package/dist/gen-write.d.ts.map +1 -0
- package/dist/gen-write.js +120 -0
- package/dist/gen-write.js.map +1 -0
- package/dist/glob.d.ts +21 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +115 -0
- package/dist/glob.js.map +1 -0
- package/dist/go-type-emitter.d.ts +18 -4
- package/dist/go-type-emitter.d.ts.map +1 -1
- package/dist/go-type-emitter.js +594 -0
- package/dist/go-type-emitter.js.map +1 -0
- package/dist/honey-response.d.ts.map +1 -1
- package/dist/honey-response.js +338 -0
- package/dist/honey-response.js.map +1 -0
- package/dist/i18n-slot.d.ts +8 -0
- package/dist/i18n-slot.d.ts.map +1 -1
- package/dist/i18n-slot.js +14 -0
- package/dist/i18n-slot.js.map +1 -0
- package/dist/i18n.d.ts +3 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +250 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +408 -148
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2324 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +3 -5
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +140 -0
- package/dist/init.js.map +1 -0
- package/dist/input.js +4 -0
- package/dist/input.js.map +1 -0
- package/dist/invalidate-check.d.ts +11 -0
- package/dist/invalidate-check.d.ts.map +1 -1
- package/dist/invalidate-check.js +163 -0
- package/dist/invalidate-check.js.map +1 -0
- package/dist/invoke-user.d.ts +35 -0
- package/dist/invoke-user.d.ts.map +1 -0
- package/dist/invoke-user.js +73 -0
- package/dist/invoke-user.js.map +1 -0
- package/dist/ip-restrict.d.ts +13 -1
- package/dist/ip-restrict.d.ts.map +1 -1
- package/dist/ip-restrict.js +60 -0
- package/dist/ip-restrict.js.map +1 -0
- package/dist/ip.d.ts +39 -0
- package/dist/ip.d.ts.map +1 -0
- package/dist/ip.js +209 -0
- package/dist/ip.js.map +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +113 -0
- package/dist/logger.js.map +1 -0
- package/dist/media-type.d.ts +30 -0
- package/dist/media-type.d.ts.map +1 -0
- package/dist/media-type.js +97 -0
- package/dist/media-type.js.map +1 -0
- package/dist/meta-spec-merge.d.ts +32 -0
- package/dist/meta-spec-merge.d.ts.map +1 -0
- package/dist/meta-spec-merge.js +68 -0
- package/dist/meta-spec-merge.js.map +1 -0
- package/dist/meta-spec.d.ts +16 -3
- package/dist/meta-spec.d.ts.map +1 -1
- package/dist/meta-spec.js +535 -0
- package/dist/meta-spec.js.map +1 -0
- package/dist/middleware.d.ts +23 -6
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +253 -0
- package/dist/middleware.js.map +1 -0
- package/dist/node-request.d.ts +57 -12
- package/dist/node-request.d.ts.map +1 -1
- package/dist/node-request.js +407 -0
- package/dist/node-request.js.map +1 -0
- package/dist/node.d.ts +20 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +396 -0
- package/dist/node.js.map +1 -0
- package/dist/openapi/collect.d.ts +6 -3
- package/dist/openapi/collect.d.ts.map +1 -1
- package/dist/openapi/collect.js +30 -0
- package/dist/openapi/collect.js.map +1 -0
- package/dist/openapi/docs-page.d.ts +42 -0
- package/dist/openapi/docs-page.d.ts.map +1 -0
- package/dist/openapi/docs-page.js +80 -0
- package/dist/openapi/docs-page.js.map +1 -0
- package/dist/openapi/document.d.ts +4 -0
- package/dist/openapi/document.d.ts.map +1 -1
- package/dist/openapi/document.js +785 -0
- package/dist/openapi/document.js.map +1 -0
- package/dist/openapi/json-schema-slot.d.ts +7 -0
- package/dist/openapi/json-schema-slot.d.ts.map +1 -1
- package/dist/openapi/json-schema-slot.js +38 -0
- package/dist/openapi/json-schema-slot.js.map +1 -0
- package/dist/openapi/register.d.ts.map +1 -1
- package/dist/openapi/register.js +20 -0
- package/dist/openapi/register.js.map +1 -0
- package/dist/openapi/scalar.d.ts +3 -1
- package/dist/openapi/scalar.d.ts.map +1 -1
- package/dist/openapi/scalar.js +21 -0
- package/dist/openapi/scalar.js.map +1 -0
- package/dist/openapi/serve.d.ts +9 -0
- package/dist/openapi/serve.d.ts.map +1 -0
- package/dist/openapi/serve.js +36 -0
- package/dist/openapi/serve.js.map +1 -0
- package/dist/openapi/spec-factory.d.ts +30 -1
- package/dist/openapi/spec-factory.d.ts.map +1 -1
- package/dist/openapi/spec-factory.js +52 -0
- package/dist/openapi/spec-factory.js.map +1 -0
- package/dist/openapi/spec.d.ts +14 -5
- package/dist/openapi/spec.d.ts.map +1 -1
- package/dist/openapi/spec.js +50 -0
- package/dist/openapi/spec.js.map +1 -0
- package/dist/openapi/swagger.d.ts +3 -1
- package/dist/openapi/swagger.d.ts.map +1 -1
- package/dist/openapi/swagger.js +22 -0
- package/dist/openapi/swagger.js.map +1 -0
- package/dist/pattern.d.ts +71 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +239 -0
- package/dist/pattern.js.map +1 -0
- package/dist/peer.d.ts +17 -0
- package/dist/peer.d.ts.map +1 -0
- package/dist/peer.js +50 -0
- package/dist/peer.js.map +1 -0
- package/dist/plugin.d.ts +67 -16
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +649 -0
- package/dist/plugin.js.map +1 -0
- package/dist/powered-by.d.ts.map +1 -1
- package/dist/powered-by.js +11 -0
- package/dist/powered-by.js.map +1 -0
- package/dist/pretty-json.d.ts.map +1 -1
- package/dist/pretty-json.js +47 -0
- package/dist/pretty-json.js.map +1 -0
- package/dist/producer-stream.d.ts +47 -0
- package/dist/producer-stream.d.ts.map +1 -0
- package/dist/producer-stream.js +267 -0
- package/dist/producer-stream.js.map +1 -0
- package/dist/proxy.d.ts +47 -8
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +274 -0
- package/dist/proxy.js.map +1 -0
- package/dist/python-type-emitter.d.ts +14 -1
- package/dist/python-type-emitter.d.ts.map +1 -1
- package/dist/python-type-emitter.js +157 -0
- package/dist/python-type-emitter.js.map +1 -0
- package/dist/realtime/bus.d.ts +17 -1
- package/dist/realtime/bus.d.ts.map +1 -1
- package/dist/realtime/bus.js +112 -0
- package/dist/realtime/bus.js.map +1 -0
- package/dist/realtime/register.d.ts +3 -0
- package/dist/realtime/register.d.ts.map +1 -0
- package/dist/realtime/register.js +10 -0
- package/dist/realtime/register.js.map +1 -0
- package/dist/realtime/route.d.ts +65 -26
- package/dist/realtime/route.d.ts.map +1 -1
- package/dist/realtime/route.js +72 -0
- package/dist/realtime/route.js.map +1 -0
- package/dist/realtime/server.d.ts +43 -0
- package/dist/realtime/server.d.ts.map +1 -0
- package/dist/realtime/server.js +255 -0
- package/dist/realtime/server.js.map +1 -0
- package/dist/request-id.d.ts +7 -0
- package/dist/request-id.d.ts.map +1 -1
- package/dist/request-id.js +16 -0
- package/dist/request-id.js.map +1 -0
- package/dist/request-limits.d.ts +3 -0
- package/dist/request-limits.d.ts.map +1 -0
- package/dist/request-limits.js +3 -0
- package/dist/request-limits.js.map +1 -0
- package/dist/request-path.d.ts +33 -0
- package/dist/request-path.d.ts.map +1 -0
- package/dist/request-path.js +178 -0
- package/dist/request-path.js.map +1 -0
- package/dist/request-to-curl.d.ts +7 -1
- package/dist/request-to-curl.d.ts.map +1 -1
- package/dist/request-to-curl.js +48 -0
- package/dist/request-to-curl.js.map +1 -0
- package/dist/response.d.ts +25 -2
- package/dist/response.d.ts.map +1 -1
- package/dist/response.js +313 -0
- package/dist/response.js.map +1 -0
- package/dist/rust-type-emitter.d.ts +14 -2
- package/dist/rust-type-emitter.d.ts.map +1 -1
- package/dist/rust-type-emitter.js +463 -0
- package/dist/rust-type-emitter.js.map +1 -0
- package/dist/secure-headers.d.ts.map +1 -1
- package/dist/secure-headers.js +53 -0
- package/dist/secure-headers.js.map +1 -0
- package/dist/serve-register.d.ts +4 -0
- package/dist/serve-register.d.ts.map +1 -1
- package/dist/serve-register.js +9 -0
- package/dist/serve-register.js.map +1 -0
- package/dist/serve-slot.d.ts +3 -0
- package/dist/serve-slot.d.ts.map +1 -1
- package/dist/serve-slot.js +52 -0
- package/dist/serve-slot.js.map +1 -0
- package/dist/serve.d.ts +18 -1
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +157 -0
- package/dist/serve.js.map +1 -0
- package/dist/server-timing.d.ts.map +1 -1
- package/dist/server-timing.js +51 -0
- package/dist/server-timing.js.map +1 -0
- package/dist/static.d.ts +9 -0
- package/dist/static.d.ts.map +1 -1
- package/dist/static.js +102 -0
- package/dist/static.js.map +1 -0
- package/dist/telemetry/otel.d.ts +2 -0
- package/dist/telemetry/otel.d.ts.map +1 -1
- package/dist/telemetry/otel.js +135 -0
- package/dist/telemetry/otel.js.map +1 -0
- package/dist/testing.d.ts +12 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +124 -0
- package/dist/testing.js.map +1 -0
- package/dist/timeout.d.ts +6 -0
- package/dist/timeout.d.ts.map +1 -1
- package/dist/timeout.js +36 -0
- package/dist/timeout.js.map +1 -0
- package/dist/tree.d.ts +133 -36
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +437 -0
- package/dist/tree.js.map +1 -0
- package/dist/trust.d.ts +21 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +100 -0
- package/dist/trust.js.map +1 -0
- package/dist/ts-type-emitter.d.ts.map +1 -1
- package/dist/ts-type-emitter.js +150 -0
- package/dist/ts-type-emitter.js.map +1 -0
- package/dist/type-emitter.d.ts +16 -2
- package/dist/type-emitter.d.ts.map +1 -1
- package/dist/type-emitter.js +729 -0
- package/dist/type-emitter.js.map +1 -0
- package/dist/type-extractor.d.ts +8 -4
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +819 -0
- package/dist/type-extractor.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +96 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +14 -2
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +335 -0
- package/dist/validation.js.map +1 -0
- package/dist/with-headers.d.ts +15 -0
- package/dist/with-headers.d.ts.map +1 -0
- package/dist/with-headers.js +45 -0
- package/dist/with-headers.js.map +1 -0
- package/dist/ws/bun.d.ts +11 -5
- package/dist/ws/bun.d.ts.map +1 -1
- package/dist/ws/bun.js +82 -0
- package/dist/ws/bun.js.map +1 -0
- package/dist/ws/cloudflare.d.ts +25 -3
- package/dist/ws/cloudflare.d.ts.map +1 -1
- package/dist/ws/cloudflare.js +117 -0
- package/dist/ws/cloudflare.js.map +1 -0
- package/dist/ws/deno.d.ts +4 -4
- package/dist/ws/deno.d.ts.map +1 -1
- package/dist/ws/deno.js +133 -0
- package/dist/ws/deno.js.map +1 -0
- package/dist/ws/node.d.ts +20 -3
- package/dist/ws/node.d.ts.map +1 -1
- package/dist/ws/node.js +173 -0
- package/dist/ws/node.js.map +1 -0
- package/dist/ws/session.d.ts +11 -0
- package/dist/ws/session.d.ts.map +1 -0
- package/dist/ws/session.js +60 -0
- package/dist/ws/session.js.map +1 -0
- package/dist/ws/shared.d.ts +65 -0
- package/dist/ws/shared.d.ts.map +1 -0
- package/dist/ws/shared.js +103 -0
- package/dist/ws/shared.js.map +1 -0
- package/dist/ws-origin.d.ts +20 -0
- package/dist/ws-origin.d.ts.map +1 -0
- package/dist/ws-origin.js +41 -0
- package/dist/ws-origin.js.map +1 -0
- package/dist/yaml.d.ts +15 -1
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +101 -0
- package/dist/yaml.js.map +1 -0
- package/docs/invalidate-spec.md +13 -1
- package/docs/meta-spec.md +36 -12
- package/docs/packaging.md +43 -24
- package/docs/regression-matrix/README.md +32 -0
- package/docs/regression-matrix/review.md +44 -0
- package/docs/regression-matrix/ws1-3.md +97 -0
- package/docs/regression-matrix/ws4-8.md +107 -0
- package/docs/regression-matrix/ws9-12.md +266 -0
- package/docs/sdk.md +102 -52
- package/package.json +183 -52
- package/src/accepts.ts +91 -33
- package/src/body-kind.ts +67 -0
- package/src/body-limit.ts +102 -87
- package/src/build/index.ts +104 -54
- package/src/cli-args.ts +123 -0
- package/src/cli-go/auth.go +12 -1
- package/src/cli-go/config.go +29 -2
- package/src/cli-go/errors.go +28 -10
- package/src/cli-go/multipart.go +51 -27
- package/src/cli-go/output.go +58 -4
- package/src/cli-go/root.go +1 -1
- package/src/cli-go/version.go +2 -2
- package/src/cli.ts +154 -148
- package/src/client/error.ts +56 -1
- package/src/client/http.ts +479 -256
- package/src/client/index.ts +55 -17
- package/src/client/path.ts +169 -0
- package/src/client/redirect-policy.ts +19 -0
- package/src/client/sdk.ts +180 -101
- package/src/client/sse.ts +92 -66
- package/src/client/ws.ts +67 -31
- package/src/client-go/errors.go +41 -12
- package/src/client-go/export.go +44 -0
- package/src/client-go/invalidation.go +52 -54
- package/src/client-go/nullable.go +62 -0
- package/src/client-go/realtime.go +147 -110
- package/src/client-go/runtime.go +646 -88
- package/src/client-go/sse.go +104 -94
- package/src/client-go/transport.go +67 -27
- package/src/client-go/ws.go +49 -25
- package/src/client-info.ts +79 -0
- package/src/client-mcp/server.ts +133 -3
- package/src/client-python/_invalidation.py +207 -291
- package/src/client-python/_realtime.py +63 -40
- package/src/client-python/_runtime.py +501 -119
- package/src/client-python/_sse.py +130 -74
- package/src/client-python/_transport.py +37 -9
- package/src/client-python/_ws.py +50 -22
- package/src/client-rust/errors.rs +21 -1
- package/src/client-rust/invalidation.rs +202 -231
- package/src/client-rust/invalidation_sync.rs +16 -229
- package/src/client-rust/nullable.rs +17 -0
- package/src/client-rust/realtime.rs +217 -217
- package/src/client-rust/runtime.rs +602 -177
- package/src/client-rust/runtime_sync.rs +169 -145
- package/src/client-rust/sse.rs +142 -121
- package/src/client-rust/ws.rs +61 -37
- package/src/codegen-go-cli.ts +607 -728
- package/src/codegen-go.ts +710 -770
- package/src/codegen-ir.ts +381 -75
- package/src/codegen-lang.ts +517 -0
- package/src/codegen-load.ts +150 -0
- package/src/codegen-mcp.ts +207 -108
- package/src/codegen-python.ts +684 -816
- package/src/codegen-route-tree-intern.ts +51 -25
- package/src/codegen-rust.ts +946 -1240
- package/src/codegen-sanitize.ts +0 -4
- package/src/codegen-schema-naming.ts +19 -6
- package/src/codegen-sdk-model.ts +228 -0
- package/src/codegen.ts +1488 -1140
- package/src/context.ts +130 -11
- package/src/cookie-sign.ts +85 -16
- package/src/cookie.ts +66 -11
- package/src/cors.ts +55 -54
- package/src/crypto.ts +27 -5
- package/src/csrf.ts +57 -25
- package/src/curl-logger.ts +155 -114
- package/src/dict.ts +12 -0
- package/src/error.ts +4 -2
- package/src/etag.ts +58 -34
- package/src/feature-detect.ts +147 -0
- package/src/feature-slots.ts +70 -0
- package/src/fetch-request.ts +13 -0
- package/src/gen-process.ts +42 -0
- package/src/gen-write.ts +127 -0
- package/src/glob.ts +109 -0
- package/src/go-type-emitter.ts +406 -155
- package/src/honey-response.ts +36 -9
- package/src/i18n-slot.ts +10 -0
- package/src/i18n.ts +98 -23
- package/src/index.ts +1887 -1756
- package/src/init.ts +40 -28
- package/src/invalidate-check.ts +42 -4
- package/src/invoke-user.ts +95 -0
- package/src/ip-restrict.ts +47 -161
- package/src/ip.ts +194 -0
- package/src/logger.ts +65 -36
- package/src/media-type.ts +104 -0
- package/src/meta-spec-merge.ts +80 -0
- package/src/meta-spec.ts +0 -0
- package/src/middleware.ts +112 -12
- package/src/node-request.ts +242 -52
- package/src/node.ts +318 -75
- package/src/openapi/collect.ts +19 -44
- package/src/openapi/docs-page.ts +89 -0
- package/src/openapi/document.ts +503 -224
- package/src/openapi/json-schema-slot.ts +40 -0
- package/src/openapi/register.ts +7 -2
- package/src/openapi/scalar.ts +11 -10
- package/src/openapi/serve.ts +39 -0
- package/src/openapi/spec-factory.ts +50 -1
- package/src/openapi/spec.ts +53 -30
- package/src/openapi/swagger.ts +12 -11
- package/src/pattern.ts +245 -0
- package/src/peer.ts +53 -0
- package/src/plugin.ts +270 -185
- package/src/powered-by.ts +2 -2
- package/src/pretty-json.ts +25 -9
- package/src/producer-stream.ts +296 -0
- package/src/proxy.ts +253 -55
- package/src/python-type-emitter.ts +68 -56
- package/src/realtime/bus.ts +56 -9
- package/src/realtime/register.ts +13 -0
- package/src/realtime/route.ts +129 -80
- package/src/realtime/server.ts +298 -0
- package/src/request-id.ts +13 -3
- package/src/request-limits.ts +2 -0
- package/src/request-path.ts +165 -0
- package/src/request-to-curl.ts +28 -7
- package/src/response.ts +143 -103
- package/src/rust-type-emitter.ts +265 -170
- package/src/secure-headers.ts +8 -4
- package/src/serve-register.ts +4 -0
- package/src/serve-slot.ts +38 -0
- package/src/serve.ts +113 -25
- package/src/server-timing.ts +11 -7
- package/src/static.ts +85 -32
- package/src/telemetry/otel.ts +29 -7
- package/src/testing.ts +76 -14
- package/src/timeout.ts +15 -7
- package/src/tree.ts +405 -333
- package/src/trust.ts +117 -0
- package/src/ts-type-emitter.ts +18 -12
- package/src/type-emitter.ts +227 -89
- package/src/type-extractor.ts +603 -423
- package/src/types.ts +8 -0
- package/src/validation.ts +221 -96
- package/src/with-headers.ts +45 -0
- package/src/ws/bun.ts +53 -15
- package/src/ws/cloudflare.ts +81 -19
- package/src/ws/deno.ts +124 -36
- package/src/ws/node.ts +173 -79
- package/src/ws/session.ts +73 -0
- package/src/ws/shared.ts +140 -0
- package/src/ws-origin.ts +53 -0
- package/src/yaml.ts +45 -22
- package/dist/client-mcp/server.d.ts +0 -10
- package/dist/client-mcp/server.d.ts.map +0 -1
- package/dist/client-mcp/types.d.ts +0 -16
- package/dist/client-mcp/types.d.ts.map +0 -1
- package/dist/cloudflare/realtime.d.ts +0 -30
- package/dist/cloudflare/realtime.d.ts.map +0 -1
- package/dist/realtime/buffer.d.ts +0 -18
- package/dist/realtime/buffer.d.ts.map +0 -1
- package/dist/realtime/longpoll.d.ts +0 -23
- package/dist/realtime/longpoll.d.ts.map +0 -1
- package/dist/realtime/protocol.d.ts +0 -50
- package/dist/realtime/protocol.d.ts.map +0 -1
- package/dist/realtime/runtime.d.ts +0 -74
- package/dist/realtime/runtime.d.ts.map +0 -1
- package/src/cloudflare/realtime.ts +0 -234
- package/src/realtime/buffer.ts +0 -101
- package/src/realtime/longpoll.ts +0 -148
- package/src/realtime/protocol.ts +0 -128
- package/src/realtime/runtime.ts +0 -427
package/src/logger.ts
CHANGED
|
@@ -39,38 +39,61 @@ type CreateLoggerOptions = {
|
|
|
39
39
|
write?: (line: string) => void
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
/* Methods live on the prototype: `logger()` makes a child per request, and a
|
|
43
|
+
* closure-per-level instance cost seven allocations each time. */
|
|
44
|
+
class Logger implements LoggerInstance {
|
|
45
|
+
level: LogLevel
|
|
46
|
+
#threshold: number
|
|
47
|
+
#write: (line: string) => void
|
|
48
|
+
#base: Record<string, unknown>
|
|
49
|
+
|
|
50
|
+
constructor(level: LogLevel, write: (line: string) => void, base: Record<string, unknown>) {
|
|
51
|
+
this.level = level
|
|
52
|
+
this.#threshold = LEVELS[level]
|
|
53
|
+
this.#write = write
|
|
54
|
+
this.#base = base
|
|
55
|
+
}
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
child(bindings: Record<string, unknown>): LoggerInstance {
|
|
58
|
+
return new Logger(this.level, this.#write, { ...this.#base, ...bindings })
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
trace(first: Record<string, unknown> | string, second?: string): void {
|
|
62
|
+
this.#emit(LEVELS.trace, first, second)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
debug(first: Record<string, unknown> | string, second?: string): void {
|
|
66
|
+
this.#emit(LEVELS.debug, first, second)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
info(first: Record<string, unknown> | string, second?: string): void {
|
|
70
|
+
this.#emit(LEVELS.info, first, second)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
warn(first: Record<string, unknown> | string, second?: string): void {
|
|
74
|
+
this.#emit(LEVELS.warn, first, second)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
error(first: Record<string, unknown> | string, second?: string): void {
|
|
78
|
+
this.#emit(LEVELS.error, first, second)
|
|
54
79
|
}
|
|
55
80
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
info: (first: Record<string, unknown> | string, second?: string) => emit(LEVELS.info, first, second),
|
|
68
|
-
level: opts?.level ?? "info",
|
|
69
|
-
trace: (first: Record<string, unknown> | string, second?: string) => emit(LEVELS.trace, first, second),
|
|
70
|
-
warn: (first: Record<string, unknown> | string, second?: string) => emit(LEVELS.warn, first, second),
|
|
81
|
+
fatal(first: Record<string, unknown> | string, second?: string): void {
|
|
82
|
+
this.#emit(LEVELS.fatal, first, second)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
#emit(level: number, first: Record<string, unknown> | string, second?: string): void {
|
|
86
|
+
if (level < this.#threshold) return
|
|
87
|
+
const obj =
|
|
88
|
+
typeof first === "string"
|
|
89
|
+
? { ...this.#base, level, msg: first, time: Date.now() }
|
|
90
|
+
: { ...this.#base, ...first, level, msg: second ?? "", time: Date.now() }
|
|
91
|
+
this.#write(JSON.stringify(obj))
|
|
71
92
|
}
|
|
93
|
+
}
|
|
72
94
|
|
|
73
|
-
|
|
95
|
+
function createLogger(opts?: CreateLoggerOptions): LoggerInstance {
|
|
96
|
+
return new Logger(opts?.level ?? "info", opts?.write ?? ((line: string) => console.log(line)), opts?.base ?? {})
|
|
74
97
|
}
|
|
75
98
|
|
|
76
99
|
/* ── request lifecycle middleware ── */
|
|
@@ -116,8 +139,13 @@ function logger(options?: LoggerOptions): MiddlewareFn<{ path: string; req: Requ
|
|
|
116
139
|
})
|
|
117
140
|
: noopLogger
|
|
118
141
|
|
|
142
|
+
/* a failing sink never fails the request, on the way in or out */
|
|
119
143
|
if (instance) {
|
|
120
|
-
|
|
144
|
+
try {
|
|
145
|
+
child.info(`--> ${method} ${path}`)
|
|
146
|
+
} catch (err) {
|
|
147
|
+
console.error("logger: failed to log request", err)
|
|
148
|
+
}
|
|
121
149
|
}
|
|
122
150
|
|
|
123
151
|
const response = await next({ log: child })
|
|
@@ -131,14 +159,15 @@ function logger(options?: LoggerOptions): MiddlewareFn<{ path: string; req: Requ
|
|
|
131
159
|
status: response.status,
|
|
132
160
|
}
|
|
133
161
|
|
|
134
|
-
|
|
135
|
-
return response
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
162
|
+
try {
|
|
163
|
+
if (skip?.(data)) return response
|
|
164
|
+
if (instance) {
|
|
165
|
+
child.info({ duration, status: response.status }, `<-- ${method} ${path}`)
|
|
166
|
+
} else {
|
|
167
|
+
log(data)
|
|
168
|
+
}
|
|
169
|
+
} catch (err) {
|
|
170
|
+
console.error("logger: failed to log request", err)
|
|
142
171
|
}
|
|
143
172
|
|
|
144
173
|
return response
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One media-type parser (RFC 9110 §8.3.1) for every place that reads a `Content-Type`:
|
|
3
|
+
* input validation, `bodyLimit`, and the client. Type, subtype and parameter names are
|
|
4
|
+
* case-insensitive, so they are lowercased; parameter values keep their case.
|
|
5
|
+
*
|
|
6
|
+
* Pure and dependency-free: the client entry imports it too.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export type MediaType = {
|
|
10
|
+
/** `type/subtype`, lowercased, without parameters */
|
|
11
|
+
essence: string
|
|
12
|
+
/** parameters by lowercased name; a repeated name keeps the first value */
|
|
13
|
+
params: Record<string, string>
|
|
14
|
+
subtype: string
|
|
15
|
+
/** the structured-syntax suffix (`json` for `application/vnd.api+json`), or `null` */
|
|
16
|
+
suffix: string | null
|
|
17
|
+
type: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* RFC 9110 token characters */
|
|
21
|
+
const TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
|
|
22
|
+
|
|
23
|
+
function isToken(s: string): boolean {
|
|
24
|
+
return s.length > 0 && TOKEN.test(s)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Parses a `Content-Type` (or any media type) value. Returns `null` for an absent or
|
|
29
|
+
* malformed value, so a caller never mistakes `application/jsonx` or `json` for JSON.
|
|
30
|
+
*/
|
|
31
|
+
export function parseMediaType(value: string | null | undefined): MediaType | null {
|
|
32
|
+
if (value === null || value === undefined) return null
|
|
33
|
+
const semi = value.indexOf(";")
|
|
34
|
+
const head = (semi === -1 ? value : value.slice(0, semi)).trim()
|
|
35
|
+
const slash = head.indexOf("/")
|
|
36
|
+
if (slash === -1) return null
|
|
37
|
+
const type = head.slice(0, slash).toLowerCase()
|
|
38
|
+
const subtype = head.slice(slash + 1).toLowerCase()
|
|
39
|
+
if (!isToken(type) || !isToken(subtype)) return null
|
|
40
|
+
const plus = subtype.lastIndexOf("+")
|
|
41
|
+
const suffix = plus > 0 && plus < subtype.length - 1 ? subtype.slice(plus + 1) : null
|
|
42
|
+
const params = Object.create(null) as Record<string, string>
|
|
43
|
+
if (semi !== -1) parseParams(value, semi + 1, params)
|
|
44
|
+
return { essence: `${type}/${subtype}`, params, subtype, suffix, type }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* `; name=value` pairs; value is a token or a quoted-string. Malformed pairs are skipped,
|
|
48
|
+
* as browsers and undici do, rather than rejecting the whole header. */
|
|
49
|
+
function parseParams(value: string, start: number, out: Record<string, string>): void {
|
|
50
|
+
let i = start
|
|
51
|
+
const n = value.length
|
|
52
|
+
while (i < n) {
|
|
53
|
+
while (i < n && (value[i] === " " || value[i] === "\t" || value[i] === ";")) i++
|
|
54
|
+
const eq = value.indexOf("=", i)
|
|
55
|
+
const nextSemi = value.indexOf(";", i)
|
|
56
|
+
if (eq === -1 || (nextSemi !== -1 && nextSemi < eq)) {
|
|
57
|
+
i = nextSemi === -1 ? n : nextSemi + 1
|
|
58
|
+
continue
|
|
59
|
+
}
|
|
60
|
+
const name = value.slice(i, eq).trim().toLowerCase()
|
|
61
|
+
i = eq + 1
|
|
62
|
+
let v: string
|
|
63
|
+
if (value[i] === '"') {
|
|
64
|
+
i++
|
|
65
|
+
let buf = ""
|
|
66
|
+
while (i < n && value[i] !== '"') {
|
|
67
|
+
if (value[i] === "\\" && i + 1 < n) i++
|
|
68
|
+
buf += value[i]
|
|
69
|
+
i++
|
|
70
|
+
}
|
|
71
|
+
v = buf
|
|
72
|
+
i++ /* closing quote */
|
|
73
|
+
const after = value.indexOf(";", i)
|
|
74
|
+
i = after === -1 ? n : after + 1
|
|
75
|
+
} else {
|
|
76
|
+
const end = value.indexOf(";", i)
|
|
77
|
+
v = (end === -1 ? value.slice(i) : value.slice(i, end)).trim()
|
|
78
|
+
i = end === -1 ? n : end + 1
|
|
79
|
+
}
|
|
80
|
+
if (isToken(name) && !(name in out)) out[name] = v
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** `application/json`, or any `+json` structured-syntax type (`application/problem+json`). */
|
|
85
|
+
export function isJsonMediaType(mt: MediaType | null): boolean {
|
|
86
|
+
return mt !== null && (mt.essence === "application/json" || mt.suffix === "json")
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Text-like bodies: `text/*`, `application/xml`, and any `+xml` type. */
|
|
90
|
+
export function isTextMediaType(mt: MediaType | null): boolean {
|
|
91
|
+
return mt !== null && (mt.type === "text" || mt.essence === "application/xml" || mt.suffix === "xml")
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type BodyParser = "json" | "multipart" | "urlencoded"
|
|
95
|
+
|
|
96
|
+
/** Which body parser a request `Content-Type` selects, or `null` when none applies. */
|
|
97
|
+
export function bodyParserFor(contentType: string | null | undefined): BodyParser | null {
|
|
98
|
+
const mt = parseMediaType(contentType)
|
|
99
|
+
if (mt === null) return null
|
|
100
|
+
if (isJsonMediaType(mt)) return "json"
|
|
101
|
+
if (mt.essence === "multipart/form-data") return "multipart"
|
|
102
|
+
if (mt.essence === "application/x-www-form-urlencoded") return "urlencoded"
|
|
103
|
+
return null
|
|
104
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composition of metaSpec policies across mounted sub-apps. Kept apart from the policy engine
|
|
3
|
+
* so the app core can merge policies without loading the engine.
|
|
4
|
+
*/
|
|
5
|
+
import type { MetaSpecConfig, MetaSpecEntry, MetaSpecMergeConflict, MetaSpecStrictness } from "./types.ts"
|
|
6
|
+
|
|
7
|
+
/** The strictness a declared policy actually runs with: `"error"` unless it says otherwise. */
|
|
8
|
+
export function resolvedStrictness(config: MetaSpecConfig | null): MetaSpecStrictness {
|
|
9
|
+
return config?.strict ?? (config ? "error" : "off")
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Merge a mounted sub-app's policy into a parent's.
|
|
14
|
+
*
|
|
15
|
+
* The parent wins on conflict, so one gateway keeps one answer for its aggregate document —
|
|
16
|
+
* with a single exception. A sub entry of `false` wins over anything the parent says, because
|
|
17
|
+
* hiding is a safety claim and the strictest claim has to survive composition: a worker that
|
|
18
|
+
* declares a field unpublishable must not have the gateway publish it. Wrongly hidden is a
|
|
19
|
+
* visible gap; wrongly published is a leak.
|
|
20
|
+
*
|
|
21
|
+
* Strictness is the parent's *resolved* setting: a parent that never wrote `strict` runs with
|
|
22
|
+
* `"error"`, and a sub-app's `"off"` must not downgrade it. Every other disagreement is
|
|
23
|
+
* recorded in `conflicts` and reported at codegen.
|
|
24
|
+
*
|
|
25
|
+
* Order-independent with respect to when the parent declares its own policy: callers may keep
|
|
26
|
+
* the absorbed sub policies and merge them in at codegen time.
|
|
27
|
+
*/
|
|
28
|
+
export function mergeMetaSpec(own: MetaSpecConfig | null, sub: MetaSpecConfig | null): MetaSpecConfig | null {
|
|
29
|
+
if (!sub) return own
|
|
30
|
+
if (!own) return sub
|
|
31
|
+
const conflicts: MetaSpecMergeConflict[] = [...(own.conflicts ?? []), ...(sub.conflicts ?? [])]
|
|
32
|
+
|
|
33
|
+
const meta: Record<string, MetaSpecEntry> = { ...sub.meta, ...own.meta }
|
|
34
|
+
for (const [key, subEntry] of Object.entries(sub.meta ?? {})) {
|
|
35
|
+
const ownEntry = own.meta?.[key]
|
|
36
|
+
if (ownEntry === undefined || ownEntry === subEntry) continue
|
|
37
|
+
if (subEntry === false && ownEntry !== false) {
|
|
38
|
+
meta[key] = false
|
|
39
|
+
conflicts.push({ key, resolution: "hidden", section: "meta" })
|
|
40
|
+
continue
|
|
41
|
+
}
|
|
42
|
+
conflicts.push({ key, resolution: "parent", section: "meta" })
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const recordOverlap = (section: "profiles" | "schema", subSide: object, ownSide: object): void => {
|
|
46
|
+
for (const [key, subEntry] of Object.entries(subSide)) {
|
|
47
|
+
const ownEntry = (ownSide as Record<string, unknown>)[key]
|
|
48
|
+
if (ownEntry === undefined || ownEntry === subEntry) continue
|
|
49
|
+
conflicts.push({ key, resolution: "parent", section })
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
recordOverlap("schema", sub.schema ?? {}, own.schema ?? {})
|
|
53
|
+
recordOverlap("profiles", sub.profiles ?? {}, own.profiles ?? {})
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
conflicts,
|
|
57
|
+
meta,
|
|
58
|
+
profiles: { ...sub.profiles, ...own.profiles },
|
|
59
|
+
schema: { ...sub.schema, ...own.schema },
|
|
60
|
+
strict: resolvedStrictness(own),
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** A policy as an app holds it: its own declaration and each mounted sub-app's source, unmerged. */
|
|
65
|
+
export type MetaSpecSource = {
|
|
66
|
+
readonly declared: MetaSpecConfig | null
|
|
67
|
+
readonly absorbed: readonly MetaSpecSource[]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function resolveSource(source: MetaSpecSource): MetaSpecConfig | null {
|
|
71
|
+
let merged = source.declared
|
|
72
|
+
for (const sub of source.absorbed) merged = mergeMetaSpec(merged, resolveSource(sub))
|
|
73
|
+
return merged
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The policy codegen applies to `app`: its own, with every mounted sub-app's merged in mount order. */
|
|
77
|
+
export function metaSpecOf(app: unknown): MetaSpecConfig | null {
|
|
78
|
+
const source = (app as { _metaSpecSource?: MetaSpecSource })._metaSpecSource
|
|
79
|
+
return source === undefined ? null : resolveSource(source)
|
|
80
|
+
}
|
package/src/meta-spec.ts
CHANGED
|
Binary file
|
package/src/middleware.ts
CHANGED
|
@@ -94,9 +94,8 @@ export function createMiddleware<TReqs = {}, TRet extends Promise<Response> = Pr
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
|
-
* Merge meta contributed by a middleware chain, in
|
|
98
|
-
*
|
|
99
|
-
* and a lazily-derived value would diverge from it.
|
|
97
|
+
* Merge meta contributed by a middleware chain, in run order (later wins). Resolved once when
|
|
98
|
+
* the app finalizes, from the chain the route runs — never per request.
|
|
100
99
|
*/
|
|
101
100
|
export function collectMiddlewareMeta(
|
|
102
101
|
groups: ReadonlyArray<ReadonlyArray<RuntimeMiddleware>>,
|
|
@@ -114,20 +113,71 @@ export function collectMiddlewareMeta(
|
|
|
114
113
|
}
|
|
115
114
|
|
|
116
115
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
116
|
+
* Every name the framework owns on a request context — fields, lazy getters, methods and
|
|
117
|
+
* internal backing state. `next({ ... })` additions and `.context()` values may not use them:
|
|
118
|
+
* an addition would silently replace framework state, and a value assigned over a getter-only
|
|
119
|
+
* field throws on every request. TypeScript prevents most of this at compile time; this set
|
|
120
|
+
* is the runtime guard.
|
|
120
121
|
*/
|
|
121
|
-
const RESERVED_CTX_KEYS = new Set([
|
|
122
|
+
export const RESERVED_CTX_KEYS: ReadonlySet<string> = new Set([
|
|
123
|
+
"background",
|
|
124
|
+
"cookies",
|
|
125
|
+
"env",
|
|
126
|
+
"error",
|
|
127
|
+
"errors",
|
|
128
|
+
"executionCtx",
|
|
129
|
+
"headers",
|
|
130
|
+
"input",
|
|
131
|
+
"ip",
|
|
132
|
+
"meta",
|
|
133
|
+
"params",
|
|
134
|
+
"path",
|
|
135
|
+
"realtime",
|
|
136
|
+
"req",
|
|
137
|
+
"res",
|
|
138
|
+
"routePattern",
|
|
139
|
+
"search",
|
|
140
|
+
"searchAll",
|
|
141
|
+
"signal",
|
|
142
|
+
"tap",
|
|
143
|
+
"_ac",
|
|
144
|
+
"_errorToResponse",
|
|
145
|
+
"_isErrorResponse",
|
|
146
|
+
"_lzClient",
|
|
147
|
+
"_lzCookies",
|
|
148
|
+
"_lzHeaders",
|
|
149
|
+
"_lzSearch",
|
|
150
|
+
"_lzSearchAll",
|
|
151
|
+
"_lzUrlFn",
|
|
152
|
+
"_pendingTaps",
|
|
153
|
+
"_rq",
|
|
154
|
+
"_setErrors",
|
|
155
|
+
])
|
|
122
156
|
|
|
123
157
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
158
|
+
* Turns a value thrown inside a chain into the Response that stands in for it. Supplied by
|
|
159
|
+
* the app; must not throw.
|
|
160
|
+
*/
|
|
161
|
+
export type ChainErrorConverter = (thrown: unknown, ctx: object) => Response | Promise<Response>
|
|
162
|
+
|
|
163
|
+
const NO_RESPONSE_HANDLER = "handler must return a Response — did you forget 'return ctx.res...()'?"
|
|
164
|
+
const NO_RESPONSE_MIDDLEWARE = "middleware must return a Response — did you forget 'return next(...)'?"
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Compile a middleware chain + handler into a single function, once.
|
|
168
|
+
*
|
|
169
|
+
* With `convert`, every `next()` boundary is an error boundary: whatever the handler or a
|
|
170
|
+
* middleware throws (or rejects with) becomes a Response at that layer, so the middleware
|
|
171
|
+
* around it always gets a Response back from `next()` and its post-`next()` code — headers,
|
|
172
|
+
* logging, timing — runs on error responses too. The compiled function never rejects as long
|
|
173
|
+
* as `convert` does not. Without `convert`, throws propagate (the bare executor).
|
|
126
174
|
*/
|
|
127
175
|
export function compileChain(
|
|
128
176
|
middlewares: RuntimeMiddleware[],
|
|
129
177
|
handler: (ctx: object) => Response | Promise<Response>,
|
|
178
|
+
convert?: ChainErrorConverter,
|
|
130
179
|
): (ctx: object) => Response | Promise<Response> {
|
|
180
|
+
if (convert !== undefined) return compileConverting(middlewares, handler, convert)
|
|
131
181
|
if (middlewares.length === 0) {
|
|
132
182
|
/* sync fast path — avoids microtask overhead for sync handlers */
|
|
133
183
|
return (ctx) => {
|
|
@@ -136,7 +186,7 @@ export function compileChain(
|
|
|
136
186
|
return result.then(validateResponse)
|
|
137
187
|
}
|
|
138
188
|
if (result === undefined || result === null) {
|
|
139
|
-
throw new Error(
|
|
189
|
+
throw new Error(NO_RESPONSE_HANDLER)
|
|
140
190
|
}
|
|
141
191
|
return result
|
|
142
192
|
}
|
|
@@ -165,6 +215,56 @@ export function compileChain(
|
|
|
165
215
|
return (ctx) => executeChain(middlewares, ctx, handler)
|
|
166
216
|
}
|
|
167
217
|
|
|
218
|
+
function compileConverting(
|
|
219
|
+
middlewares: readonly RuntimeMiddleware[],
|
|
220
|
+
handler: (ctx: object) => Response | Promise<Response>,
|
|
221
|
+
convert: ChainErrorConverter,
|
|
222
|
+
): (ctx: object) => Response | Promise<Response> {
|
|
223
|
+
const n = middlewares.length
|
|
224
|
+
|
|
225
|
+
const runHandler = (ctx: object): Response | Promise<Response> => {
|
|
226
|
+
let result: Response | Promise<Response>
|
|
227
|
+
try {
|
|
228
|
+
result = handler(ctx)
|
|
229
|
+
} catch (thrown) {
|
|
230
|
+
return convert(thrown, ctx)
|
|
231
|
+
}
|
|
232
|
+
if (result instanceof Promise) {
|
|
233
|
+
return result.then(
|
|
234
|
+
(value) => (value === undefined || value === null ? convert(new Error(NO_RESPONSE_HANDLER), ctx) : value),
|
|
235
|
+
(thrown: unknown) => convert(thrown, ctx),
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
if (result === undefined || result === null) return convert(new Error(NO_RESPONSE_HANDLER), ctx)
|
|
239
|
+
return result
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const step = (i: number, ctx: object): Response | Promise<Response> => {
|
|
243
|
+
if (i === n) return runHandler(ctx)
|
|
244
|
+
const mw = middlewares[i] as RuntimeMiddleware
|
|
245
|
+
let called = false
|
|
246
|
+
const next = (additions?: Record<string, unknown>): Promise<Response> => {
|
|
247
|
+
if (called) throw new Error("next() called multiple times")
|
|
248
|
+
called = true
|
|
249
|
+
if (additions) mergeAdditions(ctx, additions)
|
|
250
|
+
const downstream = step(i + 1, ctx)
|
|
251
|
+
return downstream instanceof Promise ? downstream : Promise.resolve(downstream)
|
|
252
|
+
}
|
|
253
|
+
let out: Promise<Response>
|
|
254
|
+
try {
|
|
255
|
+
out = mw(ctx as Record<string, unknown>, next)
|
|
256
|
+
} catch (thrown) {
|
|
257
|
+
return convert(thrown, ctx)
|
|
258
|
+
}
|
|
259
|
+
return Promise.resolve(out).then(
|
|
260
|
+
(value) => (value === undefined || value === null ? convert(new Error(NO_RESPONSE_MIDDLEWARE), ctx) : value),
|
|
261
|
+
(thrown: unknown) => convert(thrown, ctx),
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return (ctx) => step(0, ctx)
|
|
266
|
+
}
|
|
267
|
+
|
|
168
268
|
function mergeAdditions(ctx: object, additions: Record<string, unknown>): void {
|
|
169
269
|
for (const key in additions) {
|
|
170
270
|
if (!RESERVED_CTX_KEYS.has(key)) {
|
|
@@ -175,14 +275,14 @@ function mergeAdditions(ctx: object, additions: Record<string, unknown>): void {
|
|
|
175
275
|
|
|
176
276
|
function validateResponse(result: Response): Response {
|
|
177
277
|
if (result === undefined || result === null) {
|
|
178
|
-
throw new Error(
|
|
278
|
+
throw new Error(NO_RESPONSE_HANDLER)
|
|
179
279
|
}
|
|
180
280
|
return result
|
|
181
281
|
}
|
|
182
282
|
|
|
183
283
|
function validateMiddlewareResponse(result: Response): Response {
|
|
184
284
|
if (result === undefined || result === null) {
|
|
185
|
-
throw new Error(
|
|
285
|
+
throw new Error(NO_RESPONSE_MIDDLEWARE)
|
|
186
286
|
}
|
|
187
287
|
return result
|
|
188
288
|
}
|