@lovrozagar/honey 0.7.3 → 1.0.0-rc.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/LICENSE +21 -0
- package/README.md +930 -1664
- package/bin/honey.js +87 -27
- package/dist/adapters/bun/serve.d.ts +18 -0
- package/dist/adapters/bun/serve.js +89 -0
- package/dist/adapters/fetch-request.d.ts +20 -0
- package/dist/adapters/fetch-request.js +29 -0
- package/dist/adapters/node/headers.d.ts +27 -0
- package/dist/adapters/node/headers.js +86 -0
- package/dist/adapters/node/request.d.ts +16 -0
- package/dist/adapters/node/request.js +214 -0
- package/dist/adapters/node/response.d.ts +11 -0
- package/dist/adapters/node/response.js +126 -0
- package/dist/adapters/node/serve.d.ts +39 -0
- package/dist/adapters/node/serve.js +205 -0
- package/dist/adapters/node/url.d.ts +13 -0
- package/dist/adapters/node/url.js +87 -0
- package/dist/adapters/serve.d.ts +36 -0
- package/dist/adapters/serve.js +52 -0
- package/dist/build/artifacts.d.ts +34 -0
- package/dist/build/artifacts.js +123 -0
- package/dist/build/cli-args.d.ts +30 -0
- package/dist/build/cli-args.js +97 -0
- package/dist/build/cli.d.ts +11 -0
- package/dist/build/cli.js +150 -0
- package/dist/build/config.d.ts +102 -0
- package/dist/build/config.js +89 -0
- package/dist/build/generate.d.ts +19 -0
- package/dist/build/generate.js +80 -0
- package/dist/build/glob.d.ts +8 -0
- package/dist/build/glob.js +97 -0
- package/dist/build/index.d.ts +3 -58
- package/dist/build/index.js +3 -173
- package/dist/build/init.d.ts +3 -0
- package/dist/build/init.js +131 -0
- package/dist/build/loaders.d.ts +33 -0
- package/dist/build/loaders.js +105 -0
- package/dist/build/plugin.d.ts +52 -0
- package/dist/build/plugin.js +146 -0
- package/dist/build/source.d.ts +21 -0
- package/dist/build/source.js +100 -0
- package/dist/build/targets.d.ts +59 -0
- package/dist/build/targets.js +107 -0
- package/dist/context/context.d.ts +111 -0
- package/dist/context/context.js +213 -0
- package/dist/context/cookie-sign.d.ts +38 -0
- package/dist/context/cookie-sign.js +113 -0
- package/dist/context/cookie.d.ts +28 -0
- package/dist/context/cookie.js +142 -0
- package/dist/context/peer.d.ts +34 -0
- package/dist/context/peer.js +190 -0
- package/dist/errors/error.d.ts +60 -0
- package/dist/errors/error.js +84 -0
- package/dist/errors/errors.d.ts +45 -0
- package/dist/errors/errors.js +31 -0
- package/dist/errors/on-error.d.ts +10 -0
- package/dist/errors/on-error.js +204 -0
- package/dist/errors/problem-json.d.ts +14 -0
- package/dist/errors/problem-json.js +58 -0
- package/dist/errors/projector.d.ts +50 -0
- package/dist/errors/projector.js +107 -0
- package/dist/i18n/error-i18n.d.ts +26 -0
- package/dist/i18n/error-i18n.js +77 -0
- package/dist/i18n/i18n.d.ts +21 -0
- package/dist/i18n/i18n.js +40 -0
- package/dist/i18n/icu.d.ts +29 -0
- package/dist/i18n/icu.js +170 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.js +3 -0
- package/dist/index.d.ts +30 -746
- package/dist/index.js +12 -2364
- package/dist/input/accepts.d.ts +5 -0
- package/dist/input/accepts.js +105 -0
- package/dist/input/binary.d.ts +20 -0
- package/dist/input/binary.js +40 -0
- package/dist/input/body-kind.d.ts +15 -0
- package/dist/input/body-kind.js +47 -0
- package/dist/input/body-limit.d.ts +21 -0
- package/dist/input/body-limit.js +99 -0
- package/dist/input/cookies.d.ts +7 -0
- package/dist/input/cookies.js +8 -0
- package/dist/input/form.d.ts +10 -0
- package/dist/input/form.js +24 -0
- package/dist/input/headers.d.ts +7 -0
- package/dist/input/headers.js +8 -0
- package/dist/input/input.d.ts +91 -0
- package/dist/input/input.js +88 -0
- package/dist/input/json.d.ts +10 -0
- package/dist/input/json.js +22 -0
- package/dist/input/params.d.ts +7 -0
- package/dist/input/params.js +8 -0
- package/dist/input/query.d.ts +10 -0
- package/dist/input/query.js +17 -0
- package/dist/mcp/mount.d.ts +116 -0
- package/dist/mcp/mount.js +45 -0
- package/dist/mcp/oauth.d.ts +14 -0
- package/dist/mcp/oauth.js +88 -0
- package/dist/mcp/uploads.d.ts +36 -0
- package/dist/mcp/uploads.js +171 -0
- package/dist/mcp/url-files.d.ts +32 -0
- package/dist/mcp/url-files.js +75 -0
- package/dist/meta/meta-spec-apply.d.ts +25 -0
- package/dist/meta/meta-spec-apply.js +83 -0
- package/dist/meta/meta-spec-merge.d.ts +103 -0
- package/dist/meta/meta-spec-merge.js +50 -0
- package/dist/meta/meta-spec-validate.d.ts +61 -0
- package/dist/meta/meta-spec-validate.js +166 -0
- package/dist/meta/meta-spec.d.ts +49 -0
- package/dist/meta/meta-spec.js +197 -0
- package/dist/middleware/compress.d.ts +15 -0
- package/dist/middleware/compress.js +93 -0
- package/dist/middleware/cors.d.ts +18 -0
- package/dist/middleware/cors.js +80 -0
- package/dist/middleware/csrf.d.ts +11 -0
- package/dist/middleware/csrf.js +65 -0
- package/dist/middleware/ip-restrict.d.ts +10 -0
- package/dist/middleware/ip-restrict.js +82 -0
- package/dist/middleware/middleware.d.ts +53 -0
- package/dist/middleware/middleware.js +112 -0
- package/dist/middleware/powered-by.d.ts +6 -0
- package/dist/middleware/powered-by.js +13 -0
- package/dist/middleware/rate-limit.d.ts +40 -0
- package/dist/middleware/rate-limit.js +90 -0
- package/dist/middleware/request-id.d.ts +25 -0
- package/dist/middleware/request-id.js +30 -0
- package/dist/middleware/secure-headers.d.ts +18 -0
- package/dist/middleware/secure-headers.js +36 -0
- package/dist/middleware/server-timing.d.ts +8 -0
- package/dist/middleware/server-timing.js +52 -0
- package/dist/middleware/timeout.d.ts +6 -0
- package/dist/middleware/timeout.js +29 -0
- package/dist/observability/curl-logger.d.ts +46 -0
- package/dist/observability/curl-logger.js +175 -0
- package/dist/observability/request-to-curl.d.ts +17 -0
- package/dist/observability/request-to-curl.js +47 -0
- package/dist/openapi/collect.d.ts +56 -18
- package/dist/openapi/collect.js +109 -23
- package/dist/openapi/components.d.ts +9 -0
- package/dist/openapi/components.js +90 -0
- package/dist/openapi/docs-page.d.ts +20 -18
- package/dist/openapi/docs-page.js +28 -46
- package/dist/openapi/document.d.ts +33 -26
- package/dist/openapi/document.js +21 -780
- package/dist/openapi/extract-schemas.d.ts +11 -0
- package/dist/openapi/extract-schemas.js +31 -0
- package/dist/openapi/generate.d.ts +47 -0
- package/dist/openapi/generate.js +180 -0
- package/dist/openapi/manifest.d.ts +41 -0
- package/dist/openapi/manifest.js +49 -0
- package/dist/openapi/output-keys.d.ts +6 -0
- package/dist/openapi/output-keys.js +24 -0
- package/dist/openapi/paths.d.ts +35 -0
- package/dist/openapi/paths.js +175 -0
- package/dist/openapi/register.d.ts +14 -3
- package/dist/openapi/register.js +13 -20
- package/dist/openapi/responses.d.ts +44 -0
- package/dist/openapi/responses.js +159 -0
- package/dist/openapi/scalar.d.ts +4 -14
- package/dist/openapi/scalar.js +5 -7
- package/dist/openapi/security.d.ts +4 -0
- package/dist/openapi/security.js +25 -0
- package/dist/openapi/serve.d.ts +25 -9
- package/dist/openapi/serve.js +108 -29
- package/dist/openapi/servers.d.ts +19 -0
- package/dist/openapi/servers.js +72 -0
- package/dist/openapi/swagger.d.ts +4 -14
- package/dist/openapi/swagger.js +5 -7
- package/dist/openapi/tags.d.ts +20 -0
- package/dist/openapi/tags.js +20 -0
- package/dist/openapi/webhooks.d.ts +19 -0
- package/dist/openapi/webhooks.js +70 -0
- package/dist/openapi/yaml.d.ts +8 -0
- package/dist/openapi/yaml.js +74 -0
- package/dist/proxy/headers.d.ts +30 -0
- package/dist/proxy/headers.js +86 -0
- package/dist/proxy/proxy.d.ts +39 -0
- package/dist/proxy/proxy.js +103 -0
- package/dist/proxy/upstream.d.ts +30 -0
- package/dist/proxy/upstream.js +116 -0
- package/dist/realtime/bus.d.ts +10 -13
- package/dist/realtime/bus.js +48 -93
- package/dist/realtime/invoke-user.d.ts +36 -0
- package/dist/realtime/invoke-user.js +103 -0
- package/dist/realtime/realtime.d.ts +7 -0
- package/dist/realtime/realtime.js +40 -0
- package/dist/realtime/route.d.ts +33 -27
- package/dist/realtime/route.js +27 -43
- package/dist/realtime/server.d.ts +24 -28
- package/dist/realtime/server.js +202 -225
- package/dist/response/binary.d.ts +18 -0
- package/dist/response/binary.js +10 -0
- package/dist/response/builder.d.ts +73 -0
- package/dist/response/builder.js +214 -0
- package/dist/response/cache-control.d.ts +30 -0
- package/dist/response/cache-control.js +74 -0
- package/dist/response/etag.d.ts +15 -0
- package/dist/response/etag.js +83 -0
- package/dist/response/media-type.d.ts +28 -0
- package/dist/response/media-type.js +97 -0
- package/dist/response/out-headers.d.ts +31 -0
- package/dist/response/out-headers.js +130 -0
- package/dist/response/pretty-json.d.ts +10 -0
- package/dist/response/pretty-json.js +44 -0
- package/dist/response/range.d.ts +19 -0
- package/dist/response/range.js +98 -0
- package/dist/response/response-headers.d.ts +11 -0
- package/dist/response/response-headers.js +21 -0
- package/dist/response/response.d.ts +69 -0
- package/dist/response/response.js +208 -0
- package/dist/response/sse.d.ts +41 -0
- package/dist/response/sse.js +73 -0
- package/dist/response/static.d.ts +20 -0
- package/dist/response/static.js +181 -0
- package/dist/response/status.d.ts +5 -0
- package/dist/response/status.js +68 -0
- package/dist/response/with-headers.d.ts +11 -0
- package/dist/response/with-headers.js +47 -0
- package/dist/routing/app-types.d.ts +175 -0
- package/dist/routing/app-types.js +1 -0
- package/dist/routing/app.d.ts +76 -0
- package/dist/routing/app.js +137 -0
- package/dist/routing/codegen-types.d.ts +17 -0
- package/dist/routing/codegen-types.js +1 -0
- package/dist/routing/delegate.d.ts +9 -0
- package/dist/routing/delegate.js +75 -0
- package/dist/routing/dispatch.d.ts +22 -0
- package/dist/routing/dispatch.js +255 -0
- package/dist/routing/finalize.d.ts +47 -0
- package/dist/routing/finalize.js +169 -0
- package/dist/routing/gateway-tree.d.ts +19 -0
- package/dist/routing/gateway-tree.js +74 -0
- package/dist/routing/invalidate-check.d.ts +58 -0
- package/dist/routing/invalidate-check.js +124 -0
- package/dist/routing/match.d.ts +22 -0
- package/dist/routing/match.js +108 -0
- package/dist/routing/meta-types.d.ts +34 -0
- package/dist/routing/meta-types.js +5 -0
- package/dist/routing/middleware-chain.d.ts +16 -0
- package/dist/routing/middleware-chain.js +41 -0
- package/dist/routing/output-types.d.ts +91 -0
- package/dist/routing/output-types.js +1 -0
- package/dist/routing/pattern.d.ts +55 -0
- package/dist/routing/pattern.js +219 -0
- package/dist/routing/record.d.ts +18 -0
- package/dist/routing/record.js +4 -0
- package/dist/routing/register.d.ts +135 -0
- package/dist/routing/register.js +155 -0
- package/dist/routing/request-path.d.ts +30 -0
- package/dist/routing/request-path.js +173 -0
- package/dist/routing/route-builder.d.ts +160 -0
- package/dist/routing/route-builder.js +86 -0
- package/dist/routing/route-tree.d.ts +18 -0
- package/dist/routing/route-tree.js +91 -0
- package/dist/routing/settings-chain.d.ts +75 -0
- package/dist/routing/settings-chain.js +137 -0
- package/dist/routing/settings.d.ts +90 -0
- package/dist/routing/settings.js +44 -0
- package/dist/routing/tap.d.ts +31 -0
- package/dist/routing/tap.js +77 -0
- package/dist/routing/tree-merge.d.ts +7 -0
- package/dist/routing/tree-merge.js +77 -0
- package/dist/routing/tree.d.ts +85 -0
- package/dist/routing/tree.js +196 -0
- package/dist/routing/types.d.ts +20 -0
- package/dist/routing/types.js +1 -0
- package/dist/routing/ws-builder.d.ts +62 -0
- package/dist/routing/ws-builder.js +109 -0
- package/dist/runtime/detect-runtime.d.ts +16 -0
- package/dist/runtime/detect-runtime.js +11 -0
- package/dist/runtime/optional-peer.d.ts +10 -0
- package/dist/runtime/optional-peer.js +19 -0
- package/dist/schema/arktype.d.ts +7 -0
- package/dist/schema/arktype.js +13 -0
- package/dist/schema/canonicalize.d.ts +8 -0
- package/dist/schema/canonicalize.js +19 -0
- package/dist/schema/effect.d.ts +7 -0
- package/dist/schema/effect.js +4 -0
- package/dist/schema/naming.d.ts +31 -0
- package/dist/schema/naming.js +116 -0
- package/dist/schema/sanitize-spec.d.ts +15 -0
- package/dist/schema/sanitize-spec.js +43 -0
- package/dist/schema/slots.d.ts +15 -0
- package/dist/schema/slots.js +179 -0
- package/dist/schema/to-json-schema.d.ts +34 -0
- package/dist/schema/to-json-schema.js +94 -0
- package/dist/schema/valibot.d.ts +4 -0
- package/dist/schema/valibot.js +153 -0
- package/dist/schema/yup.d.ts +3 -0
- package/dist/schema/yup.js +57 -0
- package/dist/schema/zod.d.ts +6 -0
- package/dist/schema/zod.js +192 -0
- package/dist/security/crypto.d.ts +7 -0
- package/dist/security/crypto.js +30 -0
- package/dist/streaming/producer-stream.d.ts +45 -0
- package/dist/streaming/producer-stream.js +251 -0
- package/dist/telemetry/fields.d.ts +43 -0
- package/dist/telemetry/fields.js +64 -0
- package/dist/telemetry/log-format.d.ts +7 -0
- package/dist/telemetry/log-format.js +43 -0
- package/dist/telemetry/logger.d.ts +44 -0
- package/dist/telemetry/logger.js +136 -0
- package/dist/telemetry/otel-subpath.d.ts +7 -0
- package/dist/telemetry/otel-subpath.js +5 -0
- package/dist/telemetry/otel.d.ts +50 -57
- package/dist/telemetry/otel.js +54 -130
- package/dist/telemetry/request-log.d.ts +22 -0
- package/dist/telemetry/request-log.js +83 -0
- package/dist/telemetry/request-trace.d.ts +123 -0
- package/dist/telemetry/request-trace.js +199 -0
- package/dist/telemetry/span-lifecycle.d.ts +11 -0
- package/dist/telemetry/span-lifecycle.js +114 -0
- package/dist/telemetry/traceparent.d.ts +40 -0
- package/dist/telemetry/traceparent.js +73 -0
- package/dist/testing/testing.d.ts +42 -0
- package/dist/testing/testing.js +101 -0
- package/dist/validation/content-type.d.ts +21 -0
- package/dist/validation/content-type.js +42 -0
- package/dist/validation/standard-schema.d.ts +41 -0
- package/dist/validation/standard-schema.js +5 -0
- package/dist/validation/validate-input.d.ts +45 -0
- package/dist/validation/validate-input.js +174 -0
- package/dist/validation/validate-output.d.ts +34 -0
- package/dist/validation/validate-output.js +107 -0
- package/dist/ws/bun.d.ts +30 -25
- package/dist/ws/bun.js +42 -46
- package/dist/ws/cloudflare.d.ts +6 -75
- package/dist/ws/cloudflare.js +37 -104
- package/dist/ws/contract.d.ts +74 -0
- package/dist/ws/contract.js +83 -0
- package/dist/ws/node.d.ts +12 -21
- package/dist/ws/node.js +103 -151
- package/dist/ws/origin.d.ts +23 -0
- package/dist/ws/origin.js +48 -0
- package/dist/ws/route.d.ts +14 -0
- package/dist/ws/route.js +5 -0
- package/dist/ws/session.d.ts +15 -6
- package/dist/ws/session.js +22 -23
- package/dist/ws/shared.d.ts +23 -33
- package/dist/ws/shared.js +53 -39
- package/package.json +169 -251
- package/dist/accepts.d.ts +0 -12
- package/dist/accepts.d.ts.map +0 -1
- package/dist/accepts.js +0 -126
- package/dist/accepts.js.map +0 -1
- package/dist/body-kind.d.ts +0 -26
- package/dist/body-kind.d.ts.map +0 -1
- package/dist/body-kind.js +0 -70
- package/dist/body-kind.js.map +0 -1
- package/dist/body-limit.d.ts +0 -26
- package/dist/body-limit.d.ts.map +0 -1
- package/dist/body-limit.js +0 -126
- package/dist/body-limit.js.map +0 -1
- package/dist/build/index.d.ts.map +0 -1
- package/dist/build/index.js.map +0 -1
- package/dist/cli-args.d.ts +0 -33
- package/dist/cli-args.d.ts.map +0 -1
- package/dist/cli-args.js +0 -102
- package/dist/cli-args.js.map +0 -1
- package/dist/cli-go/auth.go +0 -26
- package/dist/cli-go/config.go +0 -192
- package/dist/cli-go/errors.go +0 -75
- package/dist/cli-go/multipart.go +0 -79
- package/dist/cli-go/output.go +0 -163
- package/dist/cli-go/root.go +0 -30
- package/dist/cli-go/stream.go +0 -88
- package/dist/cli-go/version.go +0 -5
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -209
- package/dist/cli.js.map +0 -1
- package/dist/client/defaults.d.ts +0 -12
- package/dist/client/defaults.d.ts.map +0 -1
- package/dist/client/defaults.js +0 -48
- package/dist/client/defaults.js.map +0 -1
- package/dist/client/error.d.ts +0 -49
- package/dist/client/error.d.ts.map +0 -1
- package/dist/client/error.js +0 -71
- package/dist/client/error.js.map +0 -1
- package/dist/client/http.d.ts +0 -155
- package/dist/client/http.d.ts.map +0 -1
- package/dist/client/http.js +0 -571
- package/dist/client/http.js.map +0 -1
- package/dist/client/index.d.ts +0 -23
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -95
- package/dist/client/index.js.map +0 -1
- package/dist/client/path.d.ts +0 -26
- package/dist/client/path.d.ts.map +0 -1
- package/dist/client/path.js +0 -163
- package/dist/client/path.js.map +0 -1
- package/dist/client/redirect-policy.d.ts +0 -12
- package/dist/client/redirect-policy.d.ts.map +0 -1
- package/dist/client/redirect-policy.js +0 -20
- package/dist/client/redirect-policy.js.map +0 -1
- package/dist/client/sdk.d.ts +0 -70
- package/dist/client/sdk.d.ts.map +0 -1
- package/dist/client/sdk.js +0 -292
- package/dist/client/sdk.js.map +0 -1
- package/dist/client/sse.d.ts +0 -23
- package/dist/client/sse.d.ts.map +0 -1
- package/dist/client/sse.js +0 -129
- package/dist/client/sse.js.map +0 -1
- package/dist/client/types.d.ts +0 -124
- package/dist/client/types.d.ts.map +0 -1
- package/dist/client/types.js +0 -2
- package/dist/client/types.js.map +0 -1
- package/dist/client/ws.d.ts +0 -22
- package/dist/client/ws.d.ts.map +0 -1
- package/dist/client/ws.js +0 -112
- package/dist/client/ws.js.map +0 -1
- package/dist/client-go/errors.go +0 -236
- package/dist/client-go/export.go +0 -44
- package/dist/client-go/invalidation.go +0 -371
- package/dist/client-go/nullable.go +0 -62
- package/dist/client-go/realtime.go +0 -354
- package/dist/client-go/result.go +0 -20
- package/dist/client-go/runtime.go +0 -975
- package/dist/client-go/sse.go +0 -159
- package/dist/client-go/transport.go +0 -495
- package/dist/client-go/ws.go +0 -128
- package/dist/client-info.d.ts +0 -36
- package/dist/client-info.d.ts.map +0 -1
- package/dist/client-info.js +0 -53
- package/dist/client-info.js.map +0 -1
- package/dist/client-mcp/README.md +0 -10
- package/dist/client-mcp/server.ts +0 -221
- package/dist/client-mcp/types.ts +0 -19
- package/dist/client-python/_errors.py +0 -115
- package/dist/client-python/_invalidation.py +0 -494
- package/dist/client-python/_realtime.py +0 -179
- package/dist/client-python/_runtime.py +0 -860
- package/dist/client-python/_sse.py +0 -155
- package/dist/client-python/_transport.py +0 -366
- package/dist/client-python/_ws.py +0 -159
- package/dist/client-python/py.typed +0 -0
- package/dist/client-rust/errors.rs +0 -220
- package/dist/client-rust/invalidation.rs +0 -412
- package/dist/client-rust/invalidation_sync.rs +0 -93
- package/dist/client-rust/nullable.rs +0 -17
- package/dist/client-rust/realtime.rs +0 -702
- package/dist/client-rust/result.rs +0 -22
- package/dist/client-rust/runtime.rs +0 -980
- package/dist/client-rust/runtime_sync.rs +0 -484
- package/dist/client-rust/sse.rs +0 -188
- package/dist/client-rust/ws.rs +0 -167
- package/dist/codegen-go-cli.d.ts +0 -22
- package/dist/codegen-go-cli.d.ts.map +0 -1
- package/dist/codegen-go-cli.js +0 -964
- package/dist/codegen-go-cli.js.map +0 -1
- package/dist/codegen-go.d.ts +0 -41
- package/dist/codegen-go.d.ts.map +0 -1
- package/dist/codegen-go.js +0 -872
- package/dist/codegen-go.js.map +0 -1
- package/dist/codegen-hash.d.ts +0 -3
- package/dist/codegen-hash.d.ts.map +0 -1
- package/dist/codegen-hash.js +0 -9
- package/dist/codegen-hash.js.map +0 -1
- package/dist/codegen-ir.d.ts +0 -190
- package/dist/codegen-ir.d.ts.map +0 -1
- package/dist/codegen-ir.js +0 -661
- package/dist/codegen-ir.js.map +0 -1
- package/dist/codegen-lang.d.ts +0 -65
- package/dist/codegen-lang.d.ts.map +0 -1
- package/dist/codegen-lang.js +0 -526
- package/dist/codegen-lang.js.map +0 -1
- package/dist/codegen-load.d.ts +0 -31
- package/dist/codegen-load.d.ts.map +0 -1
- package/dist/codegen-load.js +0 -138
- package/dist/codegen-load.js.map +0 -1
- package/dist/codegen-loaders.d.ts +0 -12
- package/dist/codegen-loaders.d.ts.map +0 -1
- package/dist/codegen-loaders.js +0 -55
- package/dist/codegen-loaders.js.map +0 -1
- package/dist/codegen-mcp.d.ts +0 -13
- package/dist/codegen-mcp.d.ts.map +0 -1
- package/dist/codegen-mcp.js +0 -368
- package/dist/codegen-mcp.js.map +0 -1
- package/dist/codegen-python.d.ts +0 -33
- package/dist/codegen-python.d.ts.map +0 -1
- package/dist/codegen-python.js +0 -828
- package/dist/codegen-python.js.map +0 -1
- package/dist/codegen-route-tree-intern.d.ts +0 -40
- package/dist/codegen-route-tree-intern.d.ts.map +0 -1
- package/dist/codegen-route-tree-intern.js +0 -221
- package/dist/codegen-route-tree-intern.js.map +0 -1
- package/dist/codegen-rust.d.ts +0 -18
- package/dist/codegen-rust.d.ts.map +0 -1
- package/dist/codegen-rust.js +0 -1293
- package/dist/codegen-rust.js.map +0 -1
- package/dist/codegen-sanitize.d.ts +0 -3
- package/dist/codegen-sanitize.d.ts.map +0 -1
- package/dist/codegen-sanitize.js +0 -56
- package/dist/codegen-sanitize.js.map +0 -1
- package/dist/codegen-schema-naming.d.ts +0 -27
- package/dist/codegen-schema-naming.d.ts.map +0 -1
- package/dist/codegen-schema-naming.js +0 -150
- package/dist/codegen-schema-naming.js.map +0 -1
- package/dist/codegen-sdk-model.d.ts +0 -71
- package/dist/codegen-sdk-model.d.ts.map +0 -1
- package/dist/codegen-sdk-model.js +0 -179
- package/dist/codegen-sdk-model.js.map +0 -1
- package/dist/codegen.d.ts +0 -187
- package/dist/codegen.d.ts.map +0 -1
- package/dist/codegen.js +0 -4619
- package/dist/codegen.js.map +0 -1
- package/dist/context.d.ts +0 -86
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -242
- package/dist/context.js.map +0 -1
- package/dist/cookie-sign.d.ts +0 -17
- package/dist/cookie-sign.d.ts.map +0 -1
- package/dist/cookie-sign.js +0 -104
- package/dist/cookie-sign.js.map +0 -1
- package/dist/cookie.d.ts +0 -24
- package/dist/cookie.d.ts.map +0 -1
- package/dist/cookie.js +0 -138
- package/dist/cookie.js.map +0 -1
- package/dist/cors.d.ts +0 -14
- package/dist/cors.d.ts.map +0 -1
- package/dist/cors.js +0 -87
- package/dist/cors.js.map +0 -1
- package/dist/crypto.d.ts +0 -7
- package/dist/crypto.d.ts.map +0 -1
- package/dist/crypto.js +0 -38
- package/dist/crypto.js.map +0 -1
- package/dist/csrf.d.ts +0 -28
- package/dist/csrf.d.ts.map +0 -1
- package/dist/csrf.js +0 -79
- package/dist/csrf.js.map +0 -1
- package/dist/curl-logger.d.ts +0 -44
- package/dist/curl-logger.d.ts.map +0 -1
- package/dist/curl-logger.js +0 -199
- package/dist/curl-logger.js.map +0 -1
- package/dist/detect-runtime.d.ts +0 -16
- package/dist/detect-runtime.d.ts.map +0 -1
- package/dist/detect-runtime.js +0 -13
- package/dist/detect-runtime.js.map +0 -1
- package/dist/dict.d.ts +0 -11
- package/dist/dict.d.ts.map +0 -1
- package/dist/dict.js +0 -13
- package/dist/dict.js.map +0 -1
- package/dist/error.d.ts +0 -21
- package/dist/error.d.ts.map +0 -1
- package/dist/error.js +0 -44
- package/dist/error.js.map +0 -1
- package/dist/errors.d.ts +0 -40
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -39
- package/dist/errors.js.map +0 -1
- package/dist/etag.d.ts +0 -11
- package/dist/etag.d.ts.map +0 -1
- package/dist/etag.js +0 -82
- package/dist/etag.js.map +0 -1
- package/dist/feature-detect.d.ts +0 -25
- package/dist/feature-detect.d.ts.map +0 -1
- package/dist/feature-detect.js +0 -144
- package/dist/feature-detect.js.map +0 -1
- package/dist/feature-load.d.ts +0 -3
- package/dist/feature-load.d.ts.map +0 -1
- package/dist/feature-load.js +0 -36
- package/dist/feature-load.js.map +0 -1
- package/dist/feature-slots.d.ts +0 -44
- package/dist/feature-slots.d.ts.map +0 -1
- package/dist/feature-slots.js +0 -48
- package/dist/feature-slots.js.map +0 -1
- package/dist/fetch-request.d.ts +0 -10
- package/dist/fetch-request.d.ts.map +0 -1
- package/dist/fetch-request.js +0 -13
- package/dist/fetch-request.js.map +0 -1
- package/dist/gen-process.d.ts +0 -15
- package/dist/gen-process.d.ts.map +0 -1
- package/dist/gen-process.js +0 -43
- package/dist/gen-process.js.map +0 -1
- package/dist/gen-write.d.ts +0 -19
- package/dist/gen-write.d.ts.map +0 -1
- package/dist/gen-write.js +0 -120
- package/dist/gen-write.js.map +0 -1
- package/dist/glob.d.ts +0 -21
- package/dist/glob.d.ts.map +0 -1
- package/dist/glob.js +0 -115
- package/dist/glob.js.map +0 -1
- package/dist/go-type-emitter.d.ts +0 -47
- package/dist/go-type-emitter.d.ts.map +0 -1
- package/dist/go-type-emitter.js +0 -594
- package/dist/go-type-emitter.js.map +0 -1
- package/dist/honey-response.d.ts +0 -82
- package/dist/honey-response.d.ts.map +0 -1
- package/dist/honey-response.js +0 -338
- package/dist/honey-response.js.map +0 -1
- package/dist/i18n-slot.d.ts +0 -15
- package/dist/i18n-slot.d.ts.map +0 -1
- package/dist/i18n-slot.js +0 -14
- package/dist/i18n-slot.js.map +0 -1
- package/dist/i18n.d.ts +0 -29
- package/dist/i18n.d.ts.map +0 -1
- package/dist/i18n.js +0 -250
- package/dist/i18n.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/init.d.ts +0 -5
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -140
- package/dist/init.js.map +0 -1
- package/dist/input.d.ts +0 -6
- package/dist/input.d.ts.map +0 -1
- package/dist/input.js +0 -4
- package/dist/input.js.map +0 -1
- package/dist/invalidate-check.d.ts +0 -61
- package/dist/invalidate-check.d.ts.map +0 -1
- package/dist/invalidate-check.js +0 -163
- package/dist/invalidate-check.js.map +0 -1
- package/dist/invoke-user.d.ts +0 -35
- package/dist/invoke-user.d.ts.map +0 -1
- package/dist/invoke-user.js +0 -73
- package/dist/invoke-user.js.map +0 -1
- package/dist/ip-restrict.d.ts +0 -24
- package/dist/ip-restrict.d.ts.map +0 -1
- package/dist/ip-restrict.js +0 -60
- package/dist/ip-restrict.js.map +0 -1
- package/dist/ip.d.ts +0 -39
- package/dist/ip.d.ts.map +0 -1
- package/dist/ip.js +0 -209
- package/dist/ip.js.map +0 -1
- package/dist/logger.d.ts +0 -45
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -113
- package/dist/logger.js.map +0 -1
- package/dist/media-type.d.ts +0 -30
- package/dist/media-type.d.ts.map +0 -1
- package/dist/media-type.js +0 -97
- package/dist/media-type.js.map +0 -1
- package/dist/meta-spec-merge.d.ts +0 -32
- package/dist/meta-spec-merge.d.ts.map +0 -1
- package/dist/meta-spec-merge.js +0 -68
- package/dist/meta-spec-merge.js.map +0 -1
- package/dist/meta-spec.d.ts +0 -94
- package/dist/meta-spec.d.ts.map +0 -1
- package/dist/meta-spec.js +0 -535
- package/dist/meta-spec.js.map +0 -1
- package/dist/middleware.d.ts +0 -77
- package/dist/middleware.d.ts.map +0 -1
- package/dist/middleware.js +0 -253
- package/dist/middleware.js.map +0 -1
- package/dist/node-request.d.ts +0 -104
- package/dist/node-request.d.ts.map +0 -1
- package/dist/node-request.js +0 -407
- package/dist/node-request.js.map +0 -1
- package/dist/node.d.ts +0 -30
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js +0 -396
- package/dist/node.js.map +0 -1
- package/dist/openapi/collect.d.ts.map +0 -1
- package/dist/openapi/collect.js.map +0 -1
- package/dist/openapi/docs-page.d.ts.map +0 -1
- package/dist/openapi/docs-page.js.map +0 -1
- package/dist/openapi/document.d.ts.map +0 -1
- package/dist/openapi/document.js.map +0 -1
- package/dist/openapi/json-schema-slot.d.ts +0 -12
- package/dist/openapi/json-schema-slot.d.ts.map +0 -1
- package/dist/openapi/json-schema-slot.js +0 -38
- package/dist/openapi/json-schema-slot.js.map +0 -1
- package/dist/openapi/register.d.ts.map +0 -1
- package/dist/openapi/register.js.map +0 -1
- package/dist/openapi/scalar.d.ts.map +0 -1
- package/dist/openapi/scalar.js.map +0 -1
- package/dist/openapi/serve.d.ts.map +0 -1
- package/dist/openapi/serve.js.map +0 -1
- package/dist/openapi/spec-factory.d.ts +0 -65
- package/dist/openapi/spec-factory.d.ts.map +0 -1
- package/dist/openapi/spec-factory.js +0 -52
- package/dist/openapi/spec-factory.js.map +0 -1
- package/dist/openapi/spec.d.ts +0 -29
- package/dist/openapi/spec.d.ts.map +0 -1
- package/dist/openapi/spec.js +0 -50
- package/dist/openapi/spec.js.map +0 -1
- package/dist/openapi/swagger.d.ts.map +0 -1
- package/dist/openapi/swagger.js.map +0 -1
- package/dist/pattern.d.ts +0 -71
- package/dist/pattern.d.ts.map +0 -1
- package/dist/pattern.js +0 -239
- package/dist/pattern.js.map +0 -1
- package/dist/peer.d.ts +0 -17
- package/dist/peer.d.ts.map +0 -1
- package/dist/peer.js +0 -50
- package/dist/peer.js.map +0 -1
- package/dist/plugin.d.ts +0 -228
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -666
- package/dist/plugin.js.map +0 -1
- package/dist/powered-by.d.ts +0 -7
- package/dist/powered-by.d.ts.map +0 -1
- package/dist/powered-by.js +0 -11
- package/dist/powered-by.js.map +0 -1
- package/dist/pretty-json.d.ts +0 -10
- package/dist/pretty-json.d.ts.map +0 -1
- package/dist/pretty-json.js +0 -47
- package/dist/pretty-json.js.map +0 -1
- package/dist/producer-stream.d.ts +0 -47
- package/dist/producer-stream.d.ts.map +0 -1
- package/dist/producer-stream.js +0 -267
- package/dist/producer-stream.js.map +0 -1
- package/dist/proxy.d.ts +0 -90
- package/dist/proxy.d.ts.map +0 -1
- package/dist/proxy.js +0 -274
- package/dist/proxy.js.map +0 -1
- package/dist/python-type-emitter.d.ts +0 -24
- package/dist/python-type-emitter.d.ts.map +0 -1
- package/dist/python-type-emitter.js +0 -157
- package/dist/python-type-emitter.js.map +0 -1
- package/dist/realtime/bus.d.ts.map +0 -1
- package/dist/realtime/bus.js.map +0 -1
- package/dist/realtime/register.d.ts +0 -3
- package/dist/realtime/register.d.ts.map +0 -1
- package/dist/realtime/register.js +0 -10
- package/dist/realtime/register.js.map +0 -1
- package/dist/realtime/route.d.ts.map +0 -1
- package/dist/realtime/route.js.map +0 -1
- package/dist/realtime/server.d.ts.map +0 -1
- package/dist/realtime/server.js.map +0 -1
- package/dist/request-id.d.ts +0 -19
- package/dist/request-id.d.ts.map +0 -1
- package/dist/request-id.js +0 -16
- package/dist/request-id.js.map +0 -1
- package/dist/request-limits.d.ts +0 -3
- package/dist/request-limits.d.ts.map +0 -1
- package/dist/request-limits.js +0 -3
- package/dist/request-limits.js.map +0 -1
- package/dist/request-path.d.ts +0 -33
- package/dist/request-path.d.ts.map +0 -1
- package/dist/request-path.js +0 -178
- package/dist/request-path.js.map +0 -1
- package/dist/request-to-curl.d.ts +0 -15
- package/dist/request-to-curl.d.ts.map +0 -1
- package/dist/request-to-curl.js +0 -48
- package/dist/request-to-curl.js.map +0 -1
- package/dist/response.d.ts +0 -86
- package/dist/response.d.ts.map +0 -1
- package/dist/response.js +0 -313
- package/dist/response.js.map +0 -1
- package/dist/rust-type-emitter.d.ts +0 -44
- package/dist/rust-type-emitter.d.ts.map +0 -1
- package/dist/rust-type-emitter.js +0 -463
- package/dist/rust-type-emitter.js.map +0 -1
- package/dist/secure-headers.d.ts +0 -16
- package/dist/secure-headers.d.ts.map +0 -1
- package/dist/secure-headers.js +0 -53
- package/dist/secure-headers.js.map +0 -1
- package/dist/serve-register.d.ts +0 -6
- package/dist/serve-register.d.ts.map +0 -1
- package/dist/serve-register.js +0 -9
- package/dist/serve-register.js.map +0 -1
- package/dist/serve-slot.d.ts +0 -9
- package/dist/serve-slot.d.ts.map +0 -1
- package/dist/serve-slot.js +0 -52
- package/dist/serve-slot.js.map +0 -1
- package/dist/serve.d.ts +0 -38
- package/dist/serve.d.ts.map +0 -1
- package/dist/serve.js +0 -157
- package/dist/serve.js.map +0 -1
- package/dist/server-timing.d.ts +0 -9
- package/dist/server-timing.d.ts.map +0 -1
- package/dist/server-timing.js +0 -51
- package/dist/server-timing.js.map +0 -1
- package/dist/static.d.ts +0 -21
- package/dist/static.d.ts.map +0 -1
- package/dist/static.js +0 -102
- package/dist/static.js.map +0 -1
- package/dist/telemetry/otel.d.ts.map +0 -1
- package/dist/telemetry/otel.js.map +0 -1
- package/dist/testing.d.ts +0 -36
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -124
- package/dist/testing.js.map +0 -1
- package/dist/timeout.d.ts +0 -13
- package/dist/timeout.d.ts.map +0 -1
- package/dist/timeout.js +0 -36
- package/dist/timeout.js.map +0 -1
- package/dist/tree.d.ts +0 -197
- package/dist/tree.d.ts.map +0 -1
- package/dist/tree.js +0 -437
- package/dist/tree.js.map +0 -1
- package/dist/trust.d.ts +0 -21
- package/dist/trust.d.ts.map +0 -1
- package/dist/trust.js +0 -100
- package/dist/trust.js.map +0 -1
- package/dist/ts-type-emitter.d.ts +0 -8
- package/dist/ts-type-emitter.d.ts.map +0 -1
- package/dist/ts-type-emitter.js +0 -150
- package/dist/ts-type-emitter.js.map +0 -1
- package/dist/type-emitter.d.ts +0 -36
- package/dist/type-emitter.d.ts.map +0 -1
- package/dist/type-emitter.js +0 -729
- package/dist/type-emitter.js.map +0 -1
- package/dist/type-extractor.d.ts +0 -43
- package/dist/type-extractor.d.ts.map +0 -1
- package/dist/type-extractor.js +0 -819
- package/dist/type-extractor.js.map +0 -1
- package/dist/types.d.ts +0 -467
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -96
- package/dist/types.js.map +0 -1
- package/dist/validation.d.ts +0 -31
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js +0 -335
- package/dist/validation.js.map +0 -1
- package/dist/with-headers.d.ts +0 -15
- package/dist/with-headers.d.ts.map +0 -1
- package/dist/with-headers.js +0 -45
- package/dist/with-headers.js.map +0 -1
- package/dist/ws/bun.d.ts.map +0 -1
- package/dist/ws/bun.js.map +0 -1
- package/dist/ws/cloudflare.d.ts.map +0 -1
- package/dist/ws/cloudflare.js.map +0 -1
- package/dist/ws/deno.d.ts +0 -13
- package/dist/ws/deno.d.ts.map +0 -1
- package/dist/ws/deno.js +0 -133
- package/dist/ws/deno.js.map +0 -1
- package/dist/ws/node.d.ts.map +0 -1
- package/dist/ws/node.js.map +0 -1
- package/dist/ws/session.d.ts.map +0 -1
- package/dist/ws/session.js.map +0 -1
- package/dist/ws/shared.d.ts.map +0 -1
- package/dist/ws/shared.js.map +0 -1
- package/dist/ws-origin.d.ts +0 -20
- package/dist/ws-origin.d.ts.map +0 -1
- package/dist/ws-origin.js +0 -41
- package/dist/ws-origin.js.map +0 -1
- package/dist/yaml.d.ts +0 -18
- package/dist/yaml.d.ts.map +0 -1
- package/dist/yaml.js +0 -101
- package/dist/yaml.js.map +0 -1
- package/docs/api-ref/go.md +0 -399
- package/docs/api-ref/python.md +0 -399
- package/docs/api-ref/rust.md +0 -399
- package/docs/api-ref/typescript.md +0 -399
- package/docs/invalidate-spec.md +0 -333
- package/docs/meta-spec.md +0 -555
- package/docs/packaging.md +0 -104
- package/docs/regression-matrix/README.md +0 -32
- package/docs/regression-matrix/review.md +0 -44
- package/docs/regression-matrix/ws1-3.md +0 -97
- package/docs/regression-matrix/ws4-8.md +0 -107
- package/docs/regression-matrix/ws9-12.md +0 -266
- package/docs/sdk.md +0 -798
- package/src/accepts.ts +0 -136
- package/src/body-kind.ts +0 -67
- package/src/body-limit.ts +0 -152
- package/src/build/index.ts +0 -217
- package/src/cli-args.ts +0 -123
- package/src/cli-go/auth.go +0 -26
- package/src/cli-go/config.go +0 -192
- package/src/cli-go/errors.go +0 -75
- package/src/cli-go/multipart.go +0 -79
- package/src/cli-go/output.go +0 -163
- package/src/cli-go/root.go +0 -30
- package/src/cli-go/stream.go +0 -88
- package/src/cli-go/version.go +0 -5
- package/src/cli.ts +0 -209
- package/src/client/defaults.ts +0 -47
- package/src/client/error.ts +0 -82
- package/src/client/http.ts +0 -737
- package/src/client/index.ts +0 -157
- package/src/client/path.ts +0 -169
- package/src/client/redirect-policy.ts +0 -19
- package/src/client/sdk.ts +0 -351
- package/src/client/sse.ts +0 -128
- package/src/client/types.ts +0 -206
- package/src/client/ws.ts +0 -149
- package/src/client-go/errors.go +0 -236
- package/src/client-go/export.go +0 -44
- package/src/client-go/invalidation.go +0 -371
- package/src/client-go/nullable.go +0 -62
- package/src/client-go/realtime.go +0 -354
- package/src/client-go/result.go +0 -20
- package/src/client-go/runtime.go +0 -975
- package/src/client-go/sse.go +0 -159
- package/src/client-go/transport.go +0 -495
- package/src/client-go/ws.go +0 -128
- package/src/client-info.ts +0 -79
- package/src/client-mcp/README.md +0 -10
- package/src/client-mcp/server.ts +0 -221
- package/src/client-mcp/types.ts +0 -19
- package/src/client-python/_errors.py +0 -115
- package/src/client-python/_invalidation.py +0 -494
- package/src/client-python/_realtime.py +0 -179
- package/src/client-python/_runtime.py +0 -860
- package/src/client-python/_sse.py +0 -155
- package/src/client-python/_transport.py +0 -366
- package/src/client-python/_ws.py +0 -159
- package/src/client-python/py.typed +0 -0
- package/src/client-rust/errors.rs +0 -220
- package/src/client-rust/invalidation.rs +0 -412
- package/src/client-rust/invalidation_sync.rs +0 -93
- package/src/client-rust/nullable.rs +0 -17
- package/src/client-rust/realtime.rs +0 -702
- package/src/client-rust/result.rs +0 -22
- package/src/client-rust/runtime.rs +0 -980
- package/src/client-rust/runtime_sync.rs +0 -484
- package/src/client-rust/sse.rs +0 -188
- package/src/client-rust/ws.rs +0 -167
- package/src/codegen-go-cli.ts +0 -1066
- package/src/codegen-go.ts +0 -970
- package/src/codegen-hash.ts +0 -8
- package/src/codegen-ir.ts +0 -812
- package/src/codegen-lang.ts +0 -517
- package/src/codegen-load.ts +0 -150
- package/src/codegen-loaders.ts +0 -50
- package/src/codegen-mcp.ts +0 -445
- package/src/codegen-python.ts +0 -916
- package/src/codegen-route-tree-intern.ts +0 -198
- package/src/codegen-rust.ts +0 -1402
- package/src/codegen-sanitize.ts +0 -57
- package/src/codegen-schema-naming.ts +0 -165
- package/src/codegen-sdk-model.ts +0 -228
- package/src/codegen.ts +0 -5089
- package/src/context.ts +0 -325
- package/src/cookie-sign.ts +0 -119
- package/src/cookie.ts +0 -143
- package/src/cors.ts +0 -95
- package/src/crypto.ts +0 -38
- package/src/csrf.ts +0 -86
- package/src/curl-logger.ts +0 -258
- package/src/detect-runtime.ts +0 -17
- package/src/dict.ts +0 -12
- package/src/error.ts +0 -55
- package/src/errors.ts +0 -85
- package/src/etag.ts +0 -97
- package/src/feature-detect.ts +0 -147
- package/src/feature-load.ts +0 -23
- package/src/feature-slots.ts +0 -70
- package/src/fetch-request.ts +0 -13
- package/src/gen-process.ts +0 -42
- package/src/gen-write.ts +0 -127
- package/src/glob.ts +0 -109
- package/src/go-type-emitter.ts +0 -660
- package/src/honey-response.ts +0 -379
- package/src/i18n-slot.ts +0 -30
- package/src/i18n.ts +0 -300
- package/src/index.ts +0 -3829
- package/src/init.ts +0 -161
- package/src/input.ts +0 -8
- package/src/invalidate-check.ts +0 -205
- package/src/invoke-user.ts +0 -95
- package/src/ip-restrict.ts +0 -79
- package/src/ip.ts +0 -194
- package/src/logger.ts +0 -178
- package/src/media-type.ts +0 -104
- package/src/meta-spec-merge.ts +0 -80
- package/src/meta-spec.ts +0 -718
- package/src/middleware.ts +0 -331
- package/src/node-request.ts +0 -431
- package/src/node.ts +0 -454
- package/src/openapi/collect.ts +0 -50
- package/src/openapi/docs-page.ts +0 -89
- package/src/openapi/document.ts +0 -902
- package/src/openapi/json-schema-slot.ts +0 -53
- package/src/openapi/register.ts +0 -23
- package/src/openapi/scalar.ts +0 -34
- package/src/openapi/serve.ts +0 -39
- package/src/openapi/spec-factory.ts +0 -100
- package/src/openapi/spec.ts +0 -74
- package/src/openapi/swagger.ts +0 -35
- package/src/pattern.ts +0 -245
- package/src/peer.ts +0 -53
- package/src/plugin.ts +0 -864
- package/src/powered-by.ts +0 -18
- package/src/pretty-json.ts +0 -56
- package/src/producer-stream.ts +0 -296
- package/src/proxy.ts +0 -370
- package/src/python-type-emitter.ts +0 -181
- package/src/realtime/bus.ts +0 -140
- package/src/realtime/register.ts +0 -13
- package/src/realtime/route.ts +0 -153
- package/src/realtime/server.ts +0 -298
- package/src/request-id.ts +0 -32
- package/src/request-limits.ts +0 -2
- package/src/request-path.ts +0 -165
- package/src/request-to-curl.ts +0 -52
- package/src/response.ts +0 -411
- package/src/rust-type-emitter.ts +0 -548
- package/src/secure-headers.ts +0 -74
- package/src/serve-register.ts +0 -12
- package/src/serve-slot.ts +0 -58
- package/src/serve.ts +0 -220
- package/src/server-timing.ts +0 -71
- package/src/static.ts +0 -112
- package/src/telemetry/otel.ts +0 -156
- package/src/testing.ts +0 -167
- package/src/timeout.ts +0 -45
- package/src/tree.ts +0 -558
- package/src/trust.ts +0 -117
- package/src/ts-type-emitter.ts +0 -168
- package/src/type-emitter.ts +0 -760
- package/src/type-extractor.ts +0 -855
- package/src/types.ts +0 -756
- package/src/validation.ts +0 -413
- package/src/with-headers.ts +0 -45
- package/src/ws/bun.ts +0 -120
- package/src/ws/cloudflare.ts +0 -192
- package/src/ws/deno.ts +0 -188
- package/src/ws/node.ts +0 -240
- package/src/ws/session.ts +0 -73
- package/src/ws/shared.ts +0 -140
- package/src/ws-origin.ts +0 -53
- package/src/yaml.ts +0 -103
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { runSchema } from "../validation/validate-input.js";
|
|
2
|
+
/**
|
|
3
|
+
* `params` validated by `schema`: what the schema produced, a promise of it only for an async
|
|
4
|
+
* validator. Without a schema (a `readableStream()` entry) the params pass as they are.
|
|
5
|
+
*/
|
|
6
|
+
export function paramsInput(schema, params) {
|
|
7
|
+
return schema === null ? params : runSchema(schema, params, "params");
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The query as `.input({ search })` declares it. */
|
|
2
|
+
import type { StandardSchemaLike } from "../validation/standard-schema.ts";
|
|
3
|
+
import { type Shape } from "../validation/validate-input.ts";
|
|
4
|
+
/**
|
|
5
|
+
* The query (ctx.searchAll, parsed once per request) validated by `schema`. Repeated keys follow
|
|
6
|
+
* `shape` (the schema's, computed once per route), and `__proto__`, `constructor` and `prototype`
|
|
7
|
+
* never reach it (H18.13). Without a schema (a `readableStream()` entry) the query passes
|
|
8
|
+
* unvalidated.
|
|
9
|
+
*/
|
|
10
|
+
export declare function searchInput(schema: StandardSchemaLike | null, searchAll: Readonly<Record<string, readonly string[]>>, shape?: Shape | null): unknown;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { runSchema, shapedRecord, shapeOf } from "../validation/validate-input.js";
|
|
2
|
+
/** ctx.searchAll as key/value pairs, in request order per key. */
|
|
3
|
+
function* pairs(searchAll) {
|
|
4
|
+
for (const key in searchAll)
|
|
5
|
+
for (const value of searchAll[key])
|
|
6
|
+
yield [key, value];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The query (ctx.searchAll, parsed once per request) validated by `schema`. Repeated keys follow
|
|
10
|
+
* `shape` (the schema's, computed once per route), and `__proto__`, `constructor` and `prototype`
|
|
11
|
+
* never reach it (H18.13). Without a schema (a `readableStream()` entry) the query passes
|
|
12
|
+
* unvalidated.
|
|
13
|
+
*/
|
|
14
|
+
export function searchInput(schema, searchAll, shape = schema === null ? null : shapeOf(schema)) {
|
|
15
|
+
const record = shapedRecord(pairs(searchAll), shape);
|
|
16
|
+
return schema === null ? record : runSchema(schema, record, "search");
|
|
17
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mcp(app, path, handler, options?)` (bit 21 e, H24.3): the app's own tools over MCP's Streamable HTTP, served at
|
|
3
|
+
* `path` by the handler the plugin generates (`_gen/mcp.gen.ts`'s `mcpHandler`), typed against its shape alone, so
|
|
4
|
+
* core imports nothing of honey-clients. POST, GET and DELETE are plain routes on the handle (its basePath and every
|
|
5
|
+
* middleware apply; the handler answers GET and DELETE 405), internal and served, so they stay out of the documents
|
|
6
|
+
* and out of the tool set. Each call dispatches in-process through `app.fetch` with the request's env and execution
|
|
7
|
+
* context, every middleware and the operation's own auth running again; only the credential headers the tools'
|
|
8
|
+
* schemes name ride it. A plain function the app imports (`@lovrozagar/honey/mcp`), so an app serving no MCP
|
|
9
|
+
* bundles none of it.
|
|
10
|
+
*
|
|
11
|
+
* Auth, fail-closed: when any tool's operation requires a credential, the mount needs `authenticate`, run on every
|
|
12
|
+
* request before any dispatch; `false` is HTTP 401 with the scheme's challenge. Its answer reaches the tools only as
|
|
13
|
+
* the credential the request carries, which the inner routes check again. Mounting secured tools without it throws,
|
|
14
|
+
* with no exception.
|
|
15
|
+
*
|
|
16
|
+
* OAuth (bit 21 f, opt-in, H23): `oauth` takes what `oauth(options)` from `@lovrozagar/honey/mcp/oauth` returns,
|
|
17
|
+
* so an app that never imports it bundles none of the resource server. Here is only its hook: called once at mount
|
|
18
|
+
* (its refusals before any route registers), its challenge on every 401 and on the handler's challenged 403, its
|
|
19
|
+
* metadata route registered after the endpoint's. It needs `authenticate`, even when no tool declares security.
|
|
20
|
+
*
|
|
21
|
+
* Files (bit 21 g, opt-in, H23): `uploads` takes what `uploads(options)` from `@lovrozagar/honey/mcp/uploads`
|
|
22
|
+
* returns (called once at mount, its PUT route registered once the endpoint's path is checked free; each request's
|
|
23
|
+
* uploads handed to the handler), and `urlFiles` what `urlFiles(options)` from `@lovrozagar/honey/mcp/url-files` returns. Neither is
|
|
24
|
+
* imported here, so a mount without them bundles none of either.
|
|
25
|
+
*/
|
|
26
|
+
import type { HoneyContext } from "../context/context.ts";
|
|
27
|
+
/** What the mount hands the handler on each request. */
|
|
28
|
+
export type McpMount = {
|
|
29
|
+
/** the app, in process: each tool call's request through every middleware and its route */
|
|
30
|
+
readonly dispatch: (request: Request) => Promise<Response>;
|
|
31
|
+
/** the browser origins served beside the endpoint's own */
|
|
32
|
+
readonly origins: readonly string[];
|
|
33
|
+
/** the most bytes a request body may hold; the handler's own cap when unset */
|
|
34
|
+
readonly max: number | undefined;
|
|
35
|
+
/** this request's uploads, when the mount takes them */
|
|
36
|
+
readonly uploads: McpUploading | undefined;
|
|
37
|
+
/** the URL file fetch, when the mount has one */
|
|
38
|
+
readonly fetchFile: McpFileFetch | undefined;
|
|
39
|
+
};
|
|
40
|
+
/** A call an upload is bound to: the credential headers its request carried, the tool, every argument. */
|
|
41
|
+
export type McpUploadScope = {
|
|
42
|
+
readonly credential: string;
|
|
43
|
+
readonly tool: string;
|
|
44
|
+
readonly args: Record<string, unknown>;
|
|
45
|
+
};
|
|
46
|
+
/** A file an upload is for: its id in the call, its declared size, its SHA-256 (base64url). */
|
|
47
|
+
export type McpUploadFile = {
|
|
48
|
+
readonly id: string;
|
|
49
|
+
readonly size: number;
|
|
50
|
+
readonly digest: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* One request's uploads: the URL a token is PUT under (`base/<token>`), the most bytes a file may declare, a file's
|
|
54
|
+
* token, and its bytes on the call's retry, taken once; `take` rejects a token the call does not hold and resolves the
|
|
55
|
+
* rule a missing upload breaks.
|
|
56
|
+
*/
|
|
57
|
+
export type McpUploading = {
|
|
58
|
+
readonly base: string;
|
|
59
|
+
readonly max: number;
|
|
60
|
+
readonly issue: (scope: McpUploadScope, file: McpUploadFile) => Promise<string>;
|
|
61
|
+
readonly take: (scope: McpUploadScope, file: McpUploadFile, token: string) => Promise<Uint8Array | string>;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* The hook `uploads(options)` returns: called once at mount, once the endpoint's path is checked free, it registers the
|
|
65
|
+
* upload route and returns each request's uploads.
|
|
66
|
+
*/
|
|
67
|
+
export type McpUploads = (app: unknown, path: string) => (request: Request) => McpUploading;
|
|
68
|
+
/** What `urlFiles(options)` returns: a file's bytes, type and name fetched from its URL; rejects with the rule broken. */
|
|
69
|
+
export type McpFileFetch = (url: string, signal: AbortSignal) => Promise<{
|
|
70
|
+
readonly bytes: Uint8Array;
|
|
71
|
+
readonly type: string;
|
|
72
|
+
readonly name?: string;
|
|
73
|
+
}>;
|
|
74
|
+
/** The generated handler (`mcpHandler`): whether a tool requires a credential, the challenge it names, the endpoint. */
|
|
75
|
+
export type McpHandler = {
|
|
76
|
+
readonly secured: boolean;
|
|
77
|
+
readonly challenge: string;
|
|
78
|
+
readonly fetch: (request: Request, mount: McpMount) => Promise<Response>;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* The resource-server hook `oauth(options)` returns: called once at mount with the app and the mount path, it refuses
|
|
82
|
+
* an endpoint its options don't fit and answers the endpoint's Bearer challenges and its metadata route.
|
|
83
|
+
*/
|
|
84
|
+
export type McpProtectedResource = (app: unknown, path: string) => {
|
|
85
|
+
/** the challenge of a `status` refusal of `request`, the handler's own `inner` challenge carried over */
|
|
86
|
+
readonly challenge: (request: Request, status: number, inner?: string | null) => string;
|
|
87
|
+
/** registers the metadata route, once the endpoint's own are */
|
|
88
|
+
readonly register: () => void;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Whether `request` carries a credential the app accepts; `false` is refused before any dispatch. `ctx` is the
|
|
92
|
+
* mounting handle's own, as its routes see it: its env, and what its middleware adds.
|
|
93
|
+
*/
|
|
94
|
+
export type McpAuthenticate<TCtx = HoneyContext<unknown>> = (request: Request, ctx: TCtx) => boolean | Promise<boolean>;
|
|
95
|
+
/** The ctx a handle's routes are given (its `$ctx`); any app's, for anything else. */
|
|
96
|
+
type CtxOf<A> = A extends {
|
|
97
|
+
readonly $ctx: infer TCtx;
|
|
98
|
+
} ? TCtx : HoneyContext<unknown>;
|
|
99
|
+
/** What `mcp()` takes beside the handler; `TCtx` is the ctx `authenticate` is given, any app's by default. */
|
|
100
|
+
export type McpOptions<TCtx = HoneyContext<unknown>> = {
|
|
101
|
+
/** the check run on every request before any dispatch; required when a tool requires a credential */
|
|
102
|
+
readonly authenticate?: McpAuthenticate<TCtx>;
|
|
103
|
+
/** browser origins served beside the endpoint's own; any other Origin is 403 */
|
|
104
|
+
readonly origins?: readonly string[];
|
|
105
|
+
/** the most bytes a request body may hold (4 MiB by default); the app's bodyLimit applies before it */
|
|
106
|
+
readonly maxBodyBytes?: number;
|
|
107
|
+
/** the opt-in OAuth 2.1 resource-server role: RFC 9728 metadata and Bearer challenges pointing at it */
|
|
108
|
+
readonly oauth?: McpProtectedResource;
|
|
109
|
+
/** out-of-band file uploads, through the file-uploads extension: what `uploads(options)` returns */
|
|
110
|
+
readonly uploads?: McpUploads;
|
|
111
|
+
/** file arguments given as https URLs the app fetches: what `urlFiles(options)` returns */
|
|
112
|
+
readonly urlFiles?: McpFileFetch;
|
|
113
|
+
};
|
|
114
|
+
/** Serve `handler`'s tools at `path` on `app`; returns `app`. */
|
|
115
|
+
export declare function mcp<A>(app: A, path: string, handler: McpHandler, options?: McpOptions<CtxOf<A>>): A;
|
|
116
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { isStaticPattern, joinPatterns, parsePattern } from "../routing/pattern.js";
|
|
2
|
+
import { assertRouteFree, GRAPH, SERVED, VIEW } from "../routing/register.js";
|
|
3
|
+
const METHODS = ["post", "get", "delete"];
|
|
4
|
+
/** An answer of `status` with no body, its `challenge` the only header. */
|
|
5
|
+
const refusal = (status, challenge) => new Response(null, { headers: { "www-authenticate": challenge }, status });
|
|
6
|
+
/** Serve `handler`'s tools at `path` on `app`; returns `app`. */
|
|
7
|
+
export function mcp(app, path, handler, options = {}) {
|
|
8
|
+
const { authenticate, maxBodyBytes, oauth, origins = [], uploads, urlFiles } = options;
|
|
9
|
+
if (oauth !== undefined && typeof authenticate !== "function")
|
|
10
|
+
throw new Error(`mcp(${path}): oauth makes it a protected resource, so it needs authenticate: (request, ctx) => boolean`);
|
|
11
|
+
if (handler.secured && typeof authenticate !== "function")
|
|
12
|
+
throw new Error(`mcp(${path}): its tools require a credential, so it needs authenticate: (request, ctx) => boolean, run on ` +
|
|
13
|
+
"every request before any call");
|
|
14
|
+
const handle = app;
|
|
15
|
+
const segments = parsePattern(joinPatterns(handle[VIEW].basePath, path));
|
|
16
|
+
if (!isStaticPattern(segments))
|
|
17
|
+
throw new Error(`cannot serve MCP at ${path}: its path is fixed, with no parameter`);
|
|
18
|
+
const resource = oauth?.(app, path);
|
|
19
|
+
for (const method of METHODS)
|
|
20
|
+
assertRouteFree(handle[GRAPH], method.toUpperCase(), segments);
|
|
21
|
+
const files = uploads?.(app, path);
|
|
22
|
+
const serve = async (ctx) => {
|
|
23
|
+
if (typeof authenticate === "function" && !(await authenticate(ctx.req, ctx)))
|
|
24
|
+
return ctx.res.raw(refusal(401, resource ? resource.challenge(ctx.req, 401) : handler.challenge));
|
|
25
|
+
const dispatch = async (request) => handle.fetch(request, ctx.env, ctx.executionCtx);
|
|
26
|
+
const answer = await handler.fetch(ctx.req, {
|
|
27
|
+
dispatch,
|
|
28
|
+
fetchFile: urlFiles,
|
|
29
|
+
max: maxBodyBytes,
|
|
30
|
+
origins,
|
|
31
|
+
uploads: files?.(ctx.req),
|
|
32
|
+
});
|
|
33
|
+
const inner = answer.headers.get("www-authenticate");
|
|
34
|
+
/* under oauth the handler's 401, or its 403 with a challenge (insufficient_scope; an Origin 403 has none), is ours */
|
|
35
|
+
if (resource && (answer.status === 401 || (answer.status === 403 && inner !== null)))
|
|
36
|
+
return ctx.res.raw(refusal(answer.status, resource.challenge(ctx.req, answer.status, inner)));
|
|
37
|
+
return ctx.res.raw(answer);
|
|
38
|
+
};
|
|
39
|
+
for (const method of METHODS)
|
|
40
|
+
handle[method](path)
|
|
41
|
+
.meta({ internal: true, [SERVED]: true })
|
|
42
|
+
.handler(serve);
|
|
43
|
+
resource?.register();
|
|
44
|
+
return app;
|
|
45
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { McpProtectedResource } from "./mount.ts";
|
|
2
|
+
/** The options of `oauth()`: the resource server's metadata and where its tokens come from. */
|
|
3
|
+
export type McpOAuthOptions = {
|
|
4
|
+
/** issuer URLs of the authorization servers whose tokens the endpoint takes; at least one (RFC 9728 §2, MCP) */
|
|
5
|
+
readonly authorizationServers: readonly string[];
|
|
6
|
+
/** scopes a client may ask for, offered when a 401 names none; never `offline_access` (RFC 9728 §2) */
|
|
7
|
+
readonly scopesSupported?: readonly string[];
|
|
8
|
+
/** the endpoint's canonical URL, for an app whose requests do not carry its public origin (behind a proxy) */
|
|
9
|
+
readonly resource?: string;
|
|
10
|
+
/** the endpoint's name as a user sees it (RFC 9728 §2 `resource_name`) */
|
|
11
|
+
readonly resourceName?: string;
|
|
12
|
+
};
|
|
13
|
+
/** The resource-server hook for `mcp()`'s `oauth`: `options` refused now when the spec forbids them. */
|
|
14
|
+
export declare function oauth(options: McpOAuthOptions): McpProtectedResource;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { joinPatterns, parsePattern } from "../routing/pattern.js";
|
|
2
|
+
import { assertRouteFree, GRAPH, SERVED, VIEW } from "../routing/register.js";
|
|
3
|
+
import { startRoute } from "../routing/route-builder.js";
|
|
4
|
+
const WELL_KNOWN = "/.well-known/oauth-protected-resource";
|
|
5
|
+
/* an auth-param, its value a token or a whole quoted-string (RFC 9110 §11.2), so a quoted "scope=" is no param */
|
|
6
|
+
const PARAM = /([\w!#$%&'*+.^`|~-]+)\s*=\s*("(?:[^"\\]|\\.)*"|[^\s,]*)/g;
|
|
7
|
+
/* RFC 6749 §3.3's scope-token */
|
|
8
|
+
const SCOPE = /^[\x21\x23-\x5b\x5d-\x7e]+$/;
|
|
9
|
+
/* OAuth asks for TLS everywhere but a loopback host, where a local server has none (RFC 8252 §8.3) */
|
|
10
|
+
const LOOPBACK = ["localhost", "127.0.0.1", "[::1]"];
|
|
11
|
+
/** `value` as an OAuth party's URL: https (http on a loopback host) with no userinfo, query or fragment. */
|
|
12
|
+
function secure(value) {
|
|
13
|
+
const url = URL.canParse(value) && !/[?#]/.test(value) ? new URL(value) : undefined;
|
|
14
|
+
const scheme = url?.protocol === "https:" || (url?.protocol === "http:" && LOOPBACK.includes(url.hostname));
|
|
15
|
+
return scheme && url?.username === "" && url.password === "" ? url : undefined;
|
|
16
|
+
}
|
|
17
|
+
/** `value` as an auth-param's quoted-string (RFC 9110 §5.6.4). */
|
|
18
|
+
const quoted = (value) => `"${value.replace(/[\\"]/g, "\\$&")}"`;
|
|
19
|
+
/** The scopes a Bearer challenge names: its scope param read past every quoted string, valid tokens, once each. */
|
|
20
|
+
function scopesOf(challenge) {
|
|
21
|
+
if (!/^\s*Bearer\b/i.test(challenge ?? ""))
|
|
22
|
+
return [];
|
|
23
|
+
let scope = "";
|
|
24
|
+
const params = challenge.matchAll(PARAM);
|
|
25
|
+
for (const [, name, value] of params)
|
|
26
|
+
if (name.toLowerCase() === "scope")
|
|
27
|
+
scope = value.startsWith('"') ? value.slice(1, -1).replace(/\\(.)/g, "$1") : value;
|
|
28
|
+
return [...new Set(scope.split(" ").filter((each) => SCOPE.test(each) && each !== "offline_access"))];
|
|
29
|
+
}
|
|
30
|
+
/** A refusal of `oauth()`'s options, saying why. */
|
|
31
|
+
const refuse = (why) => new Error(`oauth(): ${why}`);
|
|
32
|
+
/** Refuse `options` the spec forbids, naming the option. */
|
|
33
|
+
function check({ authorizationServers, scopesSupported }) {
|
|
34
|
+
if (authorizationServers.length === 0)
|
|
35
|
+
throw refuse("authorizationServers lists no authorization server; RFC 9728 metadata needs at least one");
|
|
36
|
+
for (const issuer of authorizationServers)
|
|
37
|
+
if (secure(issuer) === undefined)
|
|
38
|
+
throw refuse(`authorizationServers names ${issuer}, which is no https URL without userinfo, a query or a fragment`);
|
|
39
|
+
for (const scope of scopesSupported ?? []) {
|
|
40
|
+
if (scope === "offline_access")
|
|
41
|
+
throw refuse("scopesSupported lists offline_access, a scope the authorization server grants and a resource never asks for");
|
|
42
|
+
if (!SCOPE.test(scope))
|
|
43
|
+
throw refuse(`scopesSupported lists ${JSON.stringify(scope)}, which is no scope token`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** The resource-server hook for `mcp()`'s `oauth`: `options` refused now when the spec forbids them. */
|
|
47
|
+
export function oauth(options) {
|
|
48
|
+
check(options);
|
|
49
|
+
const { authorizationServers, resource, resourceName, scopesSupported } = options;
|
|
50
|
+
return (app, at) => {
|
|
51
|
+
const handle = app;
|
|
52
|
+
const graph = handle[GRAPH];
|
|
53
|
+
/* the URL a client sees: the prefix the app strips, the basePath, the path; no trailing slash, so the endpoint
|
|
54
|
+
* at the root is its bare origin (MCP "Canonical Server URI") */
|
|
55
|
+
const endpoint = joinPatterns(graph.settings.stripPrefix ?? "/", joinPatterns(handle[VIEW].basePath, at));
|
|
56
|
+
const tail = endpoint.replace(/\/$/, "");
|
|
57
|
+
const fixed = resource === undefined ? undefined : secure(resource);
|
|
58
|
+
if (resource !== undefined && fixed?.pathname.replace(/\/$/, "") !== tail)
|
|
59
|
+
throw new Error(`mcp(${at}): oauth's resource ${resource} is not this endpoint's URL, whose path is ${endpoint}`);
|
|
60
|
+
const path = WELL_KNOWN + tail;
|
|
61
|
+
assertRouteFree(graph, "GET", parsePattern(path));
|
|
62
|
+
const origin = (url) => fixed?.origin ?? new URL(url).origin;
|
|
63
|
+
return {
|
|
64
|
+
challenge: (request, status, inner) => {
|
|
65
|
+
const error = status === 403 ? "insufficient_scope" : request.headers.has("authorization") && "invalid_token";
|
|
66
|
+
const scope = scopesOf(inner).join(" ");
|
|
67
|
+
const metadata = `resource_metadata=${quoted(origin(request.url) + path)}`;
|
|
68
|
+
const params = [error && `error=${quoted(error)}`, scope && `scope=${quoted(scope)}`];
|
|
69
|
+
return `Bearer ${[...params.filter(Boolean), metadata].join(", ")}`;
|
|
70
|
+
},
|
|
71
|
+
/* on the root, under the handle's middleware: the metadata sits beside the origin, not under the basePath */
|
|
72
|
+
register: () => void startRoute(graph, { ...handle[VIEW], basePath: "/" }, handle, {
|
|
73
|
+
extraMethods: [],
|
|
74
|
+
method: "GET",
|
|
75
|
+
path,
|
|
76
|
+
})
|
|
77
|
+
.meta({ internal: true, [SERVED]: true })
|
|
78
|
+
.handler((ctx) => ctx.res.raw(Response.json({
|
|
79
|
+
resource: origin(ctx.req.url) + tail,
|
|
80
|
+
authorization_servers: authorizationServers,
|
|
81
|
+
...(scopesSupported && { scopes_supported: scopesSupported }),
|
|
82
|
+
/* MCP sends the token in the Authorization header alone, never the query or body */
|
|
83
|
+
bearer_methods_supported: ["header"],
|
|
84
|
+
...(resourceName !== undefined && { resource_name: resourceName }),
|
|
85
|
+
}))),
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { McpUploads } from "./mount.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Where uploads wait for their call's retry. Each method may be async. On Workers, the atomic claim and take are a D1
|
|
4
|
+
* row or a Durable Object's (`INSERT … ON CONFLICT DO NOTHING`, `DELETE … RETURNING`) and the bytes R2's, since either
|
|
5
|
+
* row holds at most 2 MB; KV is eventually consistent, so two claims can both succeed there, and it cannot keep an
|
|
6
|
+
* upload one-shot.
|
|
7
|
+
*/
|
|
8
|
+
export type UploadStore = {
|
|
9
|
+
/** marks `id` used, atomically: true for its first claim alone; it need be kept only until `expires` (ms epoch) */
|
|
10
|
+
readonly claim: (id: string, expires: number) => boolean | Promise<boolean>;
|
|
11
|
+
/** keeps a claimed upload's checked bytes until they are taken or `expires` passes */
|
|
12
|
+
readonly put: (id: string, bytes: Uint8Array, expires: number) => void | Promise<void>;
|
|
13
|
+
/** the bytes kept under `id`, removed as they are returned, atomically, so one caller alone gets them */
|
|
14
|
+
readonly take: (id: string) => Uint8Array | undefined | Promise<Uint8Array | undefined>;
|
|
15
|
+
};
|
|
16
|
+
/** The options of `uploads()`. */
|
|
17
|
+
export type McpUploadsOptions = {
|
|
18
|
+
/** the HMAC key its tokens are signed with: at least 32 characters, the app's own secret */
|
|
19
|
+
readonly secret: string;
|
|
20
|
+
/** where uploads wait for their call's retry */
|
|
21
|
+
readonly store: UploadStore;
|
|
22
|
+
/** how long a token works, in ms: 10 minutes by default */
|
|
23
|
+
readonly ttlMs?: number;
|
|
24
|
+
/** the most bytes one file may declare: 50 MiB by default */
|
|
25
|
+
readonly maxBytes?: number;
|
|
26
|
+
/** the endpoint's public origin, for an app whose requests do not carry it (behind a proxy) */
|
|
27
|
+
readonly origin?: string;
|
|
28
|
+
};
|
|
29
|
+
/** The uploads hook for `mcp()`'s `uploads`: `options` refused now when they cannot work. */
|
|
30
|
+
export declare function uploads(options: McpUploadsOptions): McpUploads;
|
|
31
|
+
/**
|
|
32
|
+
* An in-memory UploadStore, for one process: development, tests, a single Node or Bun server. Its claim is atomic
|
|
33
|
+
* (no await between its check and its mark). Not for Workers or any app on more than one instance: each isolate has
|
|
34
|
+
* its own memory, so an upload PUT to one is missing on another.
|
|
35
|
+
*/
|
|
36
|
+
export declare function memoryUploadStore(): UploadStore;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { joinPatterns, parsePattern } from "../routing/pattern.js";
|
|
2
|
+
import { assertRouteFree, GRAPH, SERVED, VIEW } from "../routing/register.js";
|
|
3
|
+
// per-process-constant: text-codec
|
|
4
|
+
const TEXT = /* @__PURE__ */ new TextEncoder();
|
|
5
|
+
/** `bytes` as base64url, unpadded. */
|
|
6
|
+
const base64url = (bytes) => btoa(String.fromCharCode(...new Uint8Array(bytes)))
|
|
7
|
+
.replace(/=+$/, "")
|
|
8
|
+
.replaceAll("+", "-")
|
|
9
|
+
.replaceAll("/", "_");
|
|
10
|
+
/** `bytes`' SHA-256 as a FileInput's digest: base64url, unpadded. */
|
|
11
|
+
async function digestOf(bytes) {
|
|
12
|
+
const hash = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
|
|
13
|
+
return base64url(hash);
|
|
14
|
+
}
|
|
15
|
+
/** `value` as JSON with every object's keys sorted, so equal arguments are equal text whatever their order. */
|
|
16
|
+
function canonical(value) {
|
|
17
|
+
if (Array.isArray(value))
|
|
18
|
+
return `[${value.map(canonical).join(",")}]`;
|
|
19
|
+
/* arguments are JSON, so every other value has its JSON text */
|
|
20
|
+
if (value === null || typeof value !== "object")
|
|
21
|
+
return JSON.stringify(value);
|
|
22
|
+
const object = value;
|
|
23
|
+
return `{${Object.keys(object)
|
|
24
|
+
.sort()
|
|
25
|
+
.map((key) => `${JSON.stringify(key)}:${canonical(object[key])}`)
|
|
26
|
+
.join(",")}}`;
|
|
27
|
+
}
|
|
28
|
+
/** `request`'s body, at most `max` bytes counted as they stream; undefined past it. */
|
|
29
|
+
async function bodyOf(request, max) {
|
|
30
|
+
const chunks = [];
|
|
31
|
+
let size = 0;
|
|
32
|
+
const reader = request.body?.getReader();
|
|
33
|
+
for (let read = await reader?.read(); read && !read.done; read = await reader?.read()) {
|
|
34
|
+
if ((size += read.value.length) > max)
|
|
35
|
+
return void (await reader?.cancel());
|
|
36
|
+
chunks.push(read.value);
|
|
37
|
+
}
|
|
38
|
+
return new Uint8Array(await new Blob(chunks).arrayBuffer());
|
|
39
|
+
}
|
|
40
|
+
/** A refusal of the upload route, its rule as text. */
|
|
41
|
+
const refused = (status, rule) => new Response(rule, { status });
|
|
42
|
+
/** A refusal of `uploads()`'s options, saying why. */
|
|
43
|
+
const refuse = (why) => new Error(`uploads(): ${why}`);
|
|
44
|
+
/** Whether `value` is a whole number of at least `least`. */
|
|
45
|
+
const whole = (value, least) => Number.isSafeInteger(value) && value >= least;
|
|
46
|
+
/** The MACs under `secret`, each naming what it signs so no value of one kind passes for another. */
|
|
47
|
+
function signer(secret) {
|
|
48
|
+
const key = crypto.subtle.importKey("raw", TEXT.encode(secret), { hash: "SHA-256", name: "HMAC" }, false, ["sign"]);
|
|
49
|
+
const mac = async (kind, text) => base64url(await crypto.subtle.sign("HMAC", await key, TEXT.encode(`${kind}\n${text}`)));
|
|
50
|
+
return {
|
|
51
|
+
call: (tool, args, id) => mac("call", canonical([tool, args, id])),
|
|
52
|
+
principal: (credential) => mac("principal", credential),
|
|
53
|
+
/** `fields` as a token: each, then their MAC */
|
|
54
|
+
token: async (fields) => `${fields.join(".")}.${await mac("upload", fields.join("."))}`,
|
|
55
|
+
/** `token`'s fields when this app signed it; its expiry unchecked */
|
|
56
|
+
signed: async (token) => {
|
|
57
|
+
const parts = token.split(".");
|
|
58
|
+
const fields = parts.slice(0, 6);
|
|
59
|
+
return parts.length === 7 && (await mac("upload", fields.join("."))) === parts[6] ? fields : undefined;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** The upload route's answer to a PUT of `token`: the bytes kept under its claim, else the rule broken. */
|
|
64
|
+
async function stored(sign, store, token, request) {
|
|
65
|
+
const fields = await sign.signed(token);
|
|
66
|
+
if (fields === undefined)
|
|
67
|
+
return refused(403, "the upload token is not this app's");
|
|
68
|
+
const [id, expires, size, digest] = fields;
|
|
69
|
+
if (Date.now() > Number(expires))
|
|
70
|
+
return refused(403, "the upload token has expired");
|
|
71
|
+
const bytes = await bodyOf(request, Number(size));
|
|
72
|
+
if (bytes === undefined)
|
|
73
|
+
return refused(413, `the upload is past its ${size} bytes`);
|
|
74
|
+
if (bytes.length !== Number(size))
|
|
75
|
+
return refused(400, `the upload is not its ${size} bytes`);
|
|
76
|
+
if ((await digestOf(bytes)) !== digest)
|
|
77
|
+
return refused(400, "the upload does not match its digest");
|
|
78
|
+
if (!(await store.claim(id, Number(expires))))
|
|
79
|
+
return refused(409, "the upload token is used");
|
|
80
|
+
await store.put(id, bytes, Number(expires));
|
|
81
|
+
return new Response(null, { status: 204 });
|
|
82
|
+
}
|
|
83
|
+
/** One request's uploads under `base`: a file's token, and on the retry its bytes, taken once. */
|
|
84
|
+
function uploading(sign, store, limits, base) {
|
|
85
|
+
const upload = {
|
|
86
|
+
base,
|
|
87
|
+
issue: async ({ args, credential, tool }, file) => sign.token([
|
|
88
|
+
base64url(crypto.getRandomValues(new Uint8Array(16))),
|
|
89
|
+
String(Date.now() + limits.ttlMs),
|
|
90
|
+
String(file.size),
|
|
91
|
+
file.digest,
|
|
92
|
+
await sign.principal(credential),
|
|
93
|
+
await sign.call(tool, args, file.id),
|
|
94
|
+
]),
|
|
95
|
+
max: limits.maxBytes,
|
|
96
|
+
take: async ({ args, credential, tool }, file, token) => {
|
|
97
|
+
const fields = await sign.signed(token);
|
|
98
|
+
if (fields === undefined)
|
|
99
|
+
throw new Error("requestState holds no upload token of this app's");
|
|
100
|
+
const [id, expires, size, digest, principal, call] = fields;
|
|
101
|
+
if (Date.now() > Number(expires))
|
|
102
|
+
throw new Error("requestState's upload token has expired");
|
|
103
|
+
if (principal !== (await sign.principal(credential)))
|
|
104
|
+
throw new Error("requestState's upload was made under another credential");
|
|
105
|
+
if (call !== (await sign.call(tool, args, file.id)))
|
|
106
|
+
throw new Error("requestState's upload is another call's");
|
|
107
|
+
const bytes = await store.take(id);
|
|
108
|
+
if (bytes === undefined)
|
|
109
|
+
return "was not uploaded, or its upload was taken";
|
|
110
|
+
const intact = bytes.length === Number(size) && (await digestOf(bytes)) === digest;
|
|
111
|
+
return intact ? bytes : "does not match its upload's digest";
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
return upload;
|
|
115
|
+
}
|
|
116
|
+
/** The uploads hook for `mcp()`'s `uploads`: `options` refused now when they cannot work. */
|
|
117
|
+
export function uploads(options) {
|
|
118
|
+
const { maxBytes = 52_428_800, origin, secret, store, ttlMs = 600_000 } = options;
|
|
119
|
+
if (secret.length < 32)
|
|
120
|
+
throw refuse("secret needs at least 32 characters, the app's own");
|
|
121
|
+
if (!whole(ttlMs, 1))
|
|
122
|
+
throw refuse("ttlMs is no whole number of milliseconds");
|
|
123
|
+
if (!whole(maxBytes, 0))
|
|
124
|
+
throw refuse("maxBytes is no whole number of bytes");
|
|
125
|
+
if (origin !== undefined && (!URL.canParse(origin) || new URL(origin).origin !== origin))
|
|
126
|
+
throw refuse(`origin ${origin} is no origin: a scheme, a host and a port alone`);
|
|
127
|
+
const sign = signer(secret);
|
|
128
|
+
return (app, at) => {
|
|
129
|
+
const handle = app;
|
|
130
|
+
const graph = handle[GRAPH];
|
|
131
|
+
const route = joinPatterns(at, "uploads/:token");
|
|
132
|
+
assertRouteFree(graph, "PUT", parsePattern(joinPatterns(handle[VIEW].basePath, route)));
|
|
133
|
+
/* the URL a client PUTs to: the prefix the app strips, the basePath, the route */
|
|
134
|
+
const tail = joinPatterns(graph.settings.stripPrefix ?? "/", joinPatterns(handle[VIEW].basePath, at));
|
|
135
|
+
handle
|
|
136
|
+
.put(route)
|
|
137
|
+
.meta({ internal: true, [SERVED]: true })
|
|
138
|
+
.handler(async (ctx) => ctx.res.raw(await stored(sign, store, ctx.params.token, ctx.req)));
|
|
139
|
+
return (request) => uploading(sign, store, { maxBytes, ttlMs }, `${origin ?? new URL(request.url).origin}${tail.replace(/\/$/, "")}/uploads`);
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* An in-memory UploadStore, for one process: development, tests, a single Node or Bun server. Its claim is atomic
|
|
144
|
+
* (no await between its check and its mark). Not for Workers or any app on more than one instance: each isolate has
|
|
145
|
+
* its own memory, so an upload PUT to one is missing on another.
|
|
146
|
+
*/
|
|
147
|
+
export function memoryUploadStore() {
|
|
148
|
+
const claims = new Map();
|
|
149
|
+
const kept = new Map();
|
|
150
|
+
return {
|
|
151
|
+
claim: (id, expires) => {
|
|
152
|
+
const now = Date.now();
|
|
153
|
+
for (const [each, until] of claims)
|
|
154
|
+
if (until < now)
|
|
155
|
+
claims.delete(each);
|
|
156
|
+
for (const [each, upload] of kept)
|
|
157
|
+
if (upload.expires < now)
|
|
158
|
+
kept.delete(each);
|
|
159
|
+
if (claims.has(id))
|
|
160
|
+
return false;
|
|
161
|
+
claims.set(id, expires);
|
|
162
|
+
return true;
|
|
163
|
+
},
|
|
164
|
+
put: (id, bytes, expires) => void kept.set(id, { bytes, expires }),
|
|
165
|
+
take: (id) => {
|
|
166
|
+
const upload = kept.get(id);
|
|
167
|
+
kept.delete(id);
|
|
168
|
+
return upload && upload.expires >= Date.now() ? upload.bytes : undefined;
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `urlFiles(options)` (bit 21 g, H24.5), `@lovrozagar/honey/mcp/url-files`: a mounted tool's file argument given as
|
|
3
|
+
* `{url}`, fetched by the app, handed to `mcp(app, path, handler, { urlFiles: urlFiles(options) })`. Off unless
|
|
4
|
+
* imported and passed (H23); a mount without it shows no `{url}` value and refuses one. The guards, each its rule:
|
|
5
|
+
* - **the host** is one the list names exactly (its port too, when not 443); an entry `*.example.com` names every
|
|
6
|
+
* host under example.com, never example.com itself, and nothing else matches by suffix. The list holds names alone:
|
|
7
|
+
* an IP literal is refused when the list is made, in any form the URL parser reads as one (decimal, octal, hex,
|
|
8
|
+
* IPv4-mapped IPv6), so no private, loopback or link-local address is ever listed;
|
|
9
|
+
* - **https** alone, with no userinfo;
|
|
10
|
+
* - **no redirect**, to any host: a 3xx is the refusal (an allowed host that redirects is not followed to another);
|
|
11
|
+
* - **the size**, counted as the body streams, past `maxBytes` refused (Content-Length never trusted);
|
|
12
|
+
* - **the time**, headers and body together, past `timeoutMs` refused;
|
|
13
|
+
* - **no credential** of the request is sent: the fetch carries no header of its own.
|
|
14
|
+
* DNS is not resolved here. The hosts are the operator's own choice, so their names are trusted as far as their
|
|
15
|
+
* owners are: a listed host whose DNS points at a private address is the operator's to not list. Resolving first
|
|
16
|
+
* would not close it either, since fetch resolves again (rebinding), and fetch cannot be pinned to an address on
|
|
17
|
+
* Workers or Bun. Workers' fetch reaches no private range at all.
|
|
18
|
+
*/
|
|
19
|
+
import type { McpFileFetch } from "./mount.ts";
|
|
20
|
+
/** The options of `urlFiles()`. */
|
|
21
|
+
export type McpUrlFilesOptions = {
|
|
22
|
+
/** the hosts files are fetched from, each exact (`files.example.com`, `files.example.com:8443`) or `*.example.com` */
|
|
23
|
+
readonly hosts: readonly string[];
|
|
24
|
+
/** the most bytes a file may hold: 50 MiB by default */
|
|
25
|
+
readonly maxBytes?: number;
|
|
26
|
+
/** how long a fetch may take, headers and body, in ms: 30 s by default */
|
|
27
|
+
readonly timeoutMs?: number;
|
|
28
|
+
/** the fetch it runs: the platform's by default */
|
|
29
|
+
readonly fetch?: (request: Request) => Promise<Response>;
|
|
30
|
+
};
|
|
31
|
+
/** The URL file fetch for `mcp()`'s `urlFiles`: `options` refused now when they cannot work. */
|
|
32
|
+
export declare function urlFiles(options: McpUrlFilesOptions): McpFileFetch;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/* an IPv4 literal as the URL parser writes every form of one, or an IPv6 literal */
|
|
2
|
+
const LITERAL = /^(?:\d+\.\d+\.\d+\.\d+|\[.*\])$/;
|
|
3
|
+
/** A refusal of `urlFiles()`'s options, saying why. */
|
|
4
|
+
const refuse = (why) => new Error(`urlFiles(): ${why}`);
|
|
5
|
+
/** `entry`'s host as a URL's `host` reads it: lower case, its default port dropped; refused when it is no bare name. */
|
|
6
|
+
function hostOf(entry) {
|
|
7
|
+
const url = /^[^/@?#\\\s]+$/.test(entry) && URL.canParse(`https://${entry}`) ? new URL(`https://${entry}`) : undefined;
|
|
8
|
+
if (url === undefined)
|
|
9
|
+
throw refuse(`hosts names ${entry}, which is no host`);
|
|
10
|
+
if (LITERAL.test(url.hostname))
|
|
11
|
+
throw refuse(`hosts names ${entry}, an IP address; list hosts by name`);
|
|
12
|
+
return url.host;
|
|
13
|
+
}
|
|
14
|
+
/** `answer`'s body, at most `max` bytes counted as it streams; refused past it, or when the answer is no 200. */
|
|
15
|
+
async function bodyOf(answer, max) {
|
|
16
|
+
if (answer.status !== 200) {
|
|
17
|
+
await answer.body?.cancel();
|
|
18
|
+
const redirect = answer.status >= 300 && answer.status < 400 ? ", a redirect, which is never followed" : "";
|
|
19
|
+
throw new Error(`answered ${answer.status}${redirect}`);
|
|
20
|
+
}
|
|
21
|
+
const chunks = [];
|
|
22
|
+
let size = 0;
|
|
23
|
+
const reader = answer.body?.getReader();
|
|
24
|
+
for (let read = await reader?.read(); read && !read.done; read = await reader?.read()) {
|
|
25
|
+
if ((size += read.value.length) > max) {
|
|
26
|
+
await reader?.cancel();
|
|
27
|
+
throw new Error(`is past the ${max}-byte cap`);
|
|
28
|
+
}
|
|
29
|
+
chunks.push(read.value);
|
|
30
|
+
}
|
|
31
|
+
return new Uint8Array(await new Blob(chunks).arrayBuffer());
|
|
32
|
+
}
|
|
33
|
+
/** The URL file fetch for `mcp()`'s `urlFiles`: `options` refused now when they cannot work. */
|
|
34
|
+
export function urlFiles(options) {
|
|
35
|
+
const { maxBytes = 52_428_800, timeoutMs = 30_000 } = options;
|
|
36
|
+
if (options.hosts.length === 0)
|
|
37
|
+
throw refuse("hosts lists no host");
|
|
38
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes < 0)
|
|
39
|
+
throw refuse("maxBytes is no whole number of bytes");
|
|
40
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1)
|
|
41
|
+
throw refuse("timeoutMs is no whole number of milliseconds");
|
|
42
|
+
const exact = new Set();
|
|
43
|
+
const under = [];
|
|
44
|
+
for (const entry of options.hosts)
|
|
45
|
+
if (entry.startsWith("*."))
|
|
46
|
+
under.push(`.${hostOf(entry.slice(2))}`);
|
|
47
|
+
else
|
|
48
|
+
exact.add(hostOf(entry));
|
|
49
|
+
const fetcher = options.fetch ?? ((request) => fetch(request));
|
|
50
|
+
/** `value` as a URL this fetch may read: https, no userinfo, on a listed host */
|
|
51
|
+
const allowed = (value) => {
|
|
52
|
+
const url = URL.canParse(value) ? new URL(value) : undefined;
|
|
53
|
+
if (url?.protocol !== "https:" || url.username !== "" || url.password !== "")
|
|
54
|
+
throw new Error("is no https URL, or carries userinfo");
|
|
55
|
+
if (!exact.has(url.host) && !under.some((suffix) => url.host.endsWith(suffix)))
|
|
56
|
+
throw new Error(`is on ${url.host}, a host this server fetches no file from`);
|
|
57
|
+
return url;
|
|
58
|
+
};
|
|
59
|
+
return async (value, signal) => {
|
|
60
|
+
const url = allowed(value);
|
|
61
|
+
const timeout = AbortSignal.timeout(timeoutMs);
|
|
62
|
+
try {
|
|
63
|
+
const answer = await fetcher(new Request(url, { redirect: "manual", signal: AbortSignal.any([signal, timeout]) }));
|
|
64
|
+
const bytes = await bodyOf(answer, maxBytes);
|
|
65
|
+
const name = url.pathname.split("/").pop();
|
|
66
|
+
return { bytes, type: answer.headers.get("content-type") ?? "application/octet-stream", ...(name && { name }) };
|
|
67
|
+
/* a fetch the clock aborted says so; any other refusal is its own */
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (timeout.aborted)
|
|
71
|
+
throw new Error(`took longer than ${timeoutMs} ms`, { cause: error });
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applying a compiled metaSpec to one route: each entry's value, from route meta or the route's
|
|
3
|
+
* schema metadata, turned into operation fields; then `meta.extensions`; then the totality check.
|
|
4
|
+
*/
|
|
5
|
+
import type { CompiledMetaSpec } from "./meta-spec.ts";
|
|
6
|
+
import { type MetaSpecDiagnostics, type SchemaMetaLookup } from "./meta-spec-validate.ts";
|
|
7
|
+
export type ApplyMetaSpecArgs = {
|
|
8
|
+
readonly diagnostics: MetaSpecDiagnostics;
|
|
9
|
+
readonly filter: (key: string) => boolean;
|
|
10
|
+
readonly kind: "http" | "ws";
|
|
11
|
+
readonly meta: Readonly<Record<string, unknown>> | null;
|
|
12
|
+
readonly method: string;
|
|
13
|
+
/** written in place */
|
|
14
|
+
readonly operation: Record<string, unknown>;
|
|
15
|
+
readonly path: string;
|
|
16
|
+
readonly profile: string;
|
|
17
|
+
/** the route's schema metadata; schema entries are skipped without it */
|
|
18
|
+
readonly schemaMeta?: SchemaMetaLookup;
|
|
19
|
+
readonly spec: CompiledMetaSpec;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Write the operation fields `spec` derives for one route into `operation`. A key is written at
|
|
23
|
+
* its first, highest-ranked contribution: route meta over schema metadata, `meta.extensions` over both.
|
|
24
|
+
*/
|
|
25
|
+
export declare function applyMetaSpec(args: ApplyMetaSpecArgs): void;
|