@lovrozagar/honey 0.6.8 → 0.7.0
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 +776 -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 +562 -424
- 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/client/ws.ts
CHANGED
|
@@ -1,54 +1,81 @@
|
|
|
1
1
|
export type TypedWebSocket = {
|
|
2
2
|
close(code?: number, reason?: string): void
|
|
3
|
-
off(event: "close" | "error" | "message" | "open", handler: (...args: never[]) => void): void
|
|
3
|
+
off(event: "binary" | "close" | "error" | "message" | "open", handler: (...args: never[]) => void): void
|
|
4
|
+
/** Binary frames, as `ArrayBuffer`. Text frames go to `"message"`. */
|
|
5
|
+
on(event: "binary", handler: (data: ArrayBuffer) => void): void
|
|
4
6
|
on(event: "close", handler: (code: number, reason: string) => void): void
|
|
5
7
|
on(event: "error", handler: (error: unknown) => void): void
|
|
8
|
+
/** Text frames. */
|
|
6
9
|
on(event: "message", handler: (data: string) => void): void
|
|
7
10
|
on(event: "open", handler: () => void): void
|
|
8
11
|
readonly readyState: number
|
|
9
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Strings, `ArrayBuffer`, typed arrays and `Blob` are sent as-is; any other value is
|
|
14
|
+
* JSON-encoded. Sends before the socket opens are queued; after it closes they are dropped.
|
|
15
|
+
*/
|
|
16
|
+
send(data: ArrayBuffer | ArrayBufferView | Blob | object | string): void
|
|
10
17
|
}
|
|
11
18
|
|
|
12
19
|
export type WSOptions = {
|
|
13
20
|
protocols?: string | string[]
|
|
14
21
|
}
|
|
15
22
|
|
|
23
|
+
type Payload = Blob | string | Uint8Array<ArrayBuffer>
|
|
24
|
+
|
|
25
|
+
const EVENTS = new Set(["binary", "close", "error", "message", "open"])
|
|
26
|
+
|
|
16
27
|
export function createTypedWebSocket(
|
|
17
28
|
url: string,
|
|
18
29
|
opts?: WSOptions,
|
|
19
30
|
WebSocketImpl: typeof WebSocket = WebSocket,
|
|
20
31
|
): TypedWebSocket {
|
|
21
32
|
const ws = opts?.protocols ? new WebSocketImpl(url, opts.protocols) : new WebSocketImpl(url)
|
|
33
|
+
ws.binaryType = "arraybuffer"
|
|
22
34
|
|
|
23
|
-
/*
|
|
24
|
-
const
|
|
25
|
-
/*
|
|
26
|
-
const sendBuffer:
|
|
27
|
-
let
|
|
35
|
+
/* user handler → wrapped listener, per event, so one handler can be registered for several events */
|
|
36
|
+
const listeners = new Map<string, WeakMap<(...args: never[]) => void, EventListener>>()
|
|
37
|
+
/* queue sends until OPEN; stop queueing for good once the socket closes or fails */
|
|
38
|
+
const sendBuffer: Payload[] = []
|
|
39
|
+
let state: "closed" | "connecting" | "open" = "connecting"
|
|
28
40
|
|
|
29
41
|
ws.addEventListener("open", () => {
|
|
30
|
-
|
|
42
|
+
state = "open"
|
|
31
43
|
for (const msg of sendBuffer) {
|
|
32
44
|
ws.send(msg)
|
|
33
45
|
}
|
|
34
46
|
sendBuffer.length = 0
|
|
35
47
|
})
|
|
48
|
+
ws.addEventListener("close", () => {
|
|
49
|
+
state = "closed"
|
|
50
|
+
sendBuffer.length = 0
|
|
51
|
+
})
|
|
36
52
|
|
|
37
53
|
function close(code?: number, reason?: string) {
|
|
38
|
-
|
|
54
|
+
state = "closed"
|
|
39
55
|
sendBuffer.length = 0
|
|
40
56
|
ws.close(code, reason)
|
|
41
57
|
}
|
|
42
58
|
|
|
59
|
+
function on(event: "binary", handler: (data: ArrayBuffer) => void): void
|
|
43
60
|
function on(event: "close", handler: (code: number, reason: string) => void): void
|
|
44
61
|
function on(event: "error", handler: (error: unknown) => void): void
|
|
45
62
|
function on(event: "message", handler: (data: string) => void): void
|
|
46
63
|
function on(event: "open", handler: () => void): void
|
|
47
64
|
function on(event: string, handler: (...args: never[]) => void): void {
|
|
65
|
+
if (!EVENTS.has(event)) return
|
|
48
66
|
let wrapped: EventListener
|
|
49
67
|
switch (event) {
|
|
50
68
|
case "message":
|
|
51
|
-
wrapped = (e: Event) =>
|
|
69
|
+
wrapped = (e: Event) => {
|
|
70
|
+
const data = (e as MessageEvent).data
|
|
71
|
+
if (typeof data === "string") (handler as (data: string) => void)(data)
|
|
72
|
+
}
|
|
73
|
+
break
|
|
74
|
+
case "binary":
|
|
75
|
+
wrapped = (e: Event) => {
|
|
76
|
+
const data = (e as MessageEvent).data
|
|
77
|
+
if (data instanceof ArrayBuffer) (handler as (data: ArrayBuffer) => void)(data)
|
|
78
|
+
}
|
|
52
79
|
break
|
|
53
80
|
case "open":
|
|
54
81
|
wrapped = () => (handler as () => void)()
|
|
@@ -57,40 +84,49 @@ export function createTypedWebSocket(
|
|
|
57
84
|
wrapped = (e: Event) =>
|
|
58
85
|
(handler as (code: number, reason: string) => void)((e as CloseEvent).code, (e as CloseEvent).reason)
|
|
59
86
|
break
|
|
60
|
-
|
|
87
|
+
default:
|
|
61
88
|
wrapped = (e: Event) => (handler as (error: unknown) => void)(e)
|
|
62
89
|
break
|
|
63
|
-
default:
|
|
64
|
-
return
|
|
65
90
|
}
|
|
66
|
-
|
|
67
|
-
|
|
91
|
+
let byHandler = listeners.get(event)
|
|
92
|
+
if (byHandler === undefined) {
|
|
93
|
+
byHandler = new WeakMap()
|
|
94
|
+
listeners.set(event, byHandler)
|
|
95
|
+
}
|
|
96
|
+
const previous = byHandler.get(handler)
|
|
97
|
+
if (previous) ws.removeEventListener(event === "binary" ? "message" : event, previous)
|
|
98
|
+
byHandler.set(handler, wrapped)
|
|
99
|
+
ws.addEventListener(event === "binary" ? "message" : event, wrapped)
|
|
68
100
|
}
|
|
69
101
|
|
|
70
102
|
function off(event: string, handler: (...args: never[]) => void): void {
|
|
71
|
-
const
|
|
103
|
+
const byHandler = listeners.get(event)
|
|
104
|
+
const wrapped = byHandler?.get(handler)
|
|
72
105
|
if (wrapped) {
|
|
73
|
-
ws.removeEventListener(event, wrapped)
|
|
74
|
-
|
|
106
|
+
ws.removeEventListener(event === "binary" ? "message" : event, wrapped)
|
|
107
|
+
byHandler?.delete(handler)
|
|
75
108
|
}
|
|
76
109
|
}
|
|
77
110
|
|
|
78
|
-
function
|
|
111
|
+
function toPayload(data: ArrayBuffer | ArrayBufferView | Blob | object | string): Payload {
|
|
79
112
|
if (typeof data === "string") return data
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
113
|
+
if (typeof Blob !== "undefined" && data instanceof Blob) return data
|
|
114
|
+
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
|
115
|
+
const view =
|
|
116
|
+
data instanceof ArrayBuffer
|
|
117
|
+
? new Uint8Array(data)
|
|
118
|
+
: new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
|
|
119
|
+
const copy = new Uint8Array(view.byteLength)
|
|
120
|
+
copy.set(view)
|
|
121
|
+
return copy
|
|
122
|
+
}
|
|
123
|
+
return JSON.stringify(data)
|
|
85
124
|
}
|
|
86
125
|
|
|
87
|
-
function send(data: ArrayBuffer | ArrayBufferView | object | string) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
: JSON.stringify(data)
|
|
92
|
-
|
|
93
|
-
if (buffering) {
|
|
126
|
+
function send(data: ArrayBuffer | ArrayBufferView | Blob | object | string) {
|
|
127
|
+
if (state === "closed") return
|
|
128
|
+
const payload = toPayload(data)
|
|
129
|
+
if (state === "connecting") {
|
|
94
130
|
sendBuffer.push(payload)
|
|
95
131
|
} else {
|
|
96
132
|
ws.send(payload)
|
package/src/client-go/errors.go
CHANGED
|
@@ -6,6 +6,9 @@ import (
|
|
|
6
6
|
"encoding/json"
|
|
7
7
|
"fmt"
|
|
8
8
|
"net/http"
|
|
9
|
+
"strings"
|
|
10
|
+
"unicode"
|
|
11
|
+
"unicode/utf8"
|
|
9
12
|
)
|
|
10
13
|
|
|
11
14
|
// APIError is the interface implemented by all SDK error types.
|
|
@@ -155,37 +158,37 @@ type StatusErrorMeta struct {
|
|
|
155
158
|
|
|
156
159
|
var statusErrorMap = map[int]func(status int, body []byte, data any, resp *http.Response) APIError{
|
|
157
160
|
400: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
158
|
-
return &BadRequestError{Body: b, Data: d, Response: r, Message:
|
|
161
|
+
return &BadRequestError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
159
162
|
},
|
|
160
163
|
401: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
161
|
-
return &UnauthorizedError{Body: b, Data: d, Response: r, Message:
|
|
164
|
+
return &UnauthorizedError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
162
165
|
},
|
|
163
166
|
403: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
164
|
-
return &ForbiddenError{Body: b, Data: d, Response: r, Message:
|
|
167
|
+
return &ForbiddenError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
165
168
|
},
|
|
166
169
|
404: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
167
|
-
return &NotFoundError{Body: b, Data: d, Response: r, Message:
|
|
170
|
+
return &NotFoundError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
168
171
|
},
|
|
169
172
|
409: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
170
|
-
return &ConflictError{Body: b, Data: d, Response: r, Message:
|
|
173
|
+
return &ConflictError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
171
174
|
},
|
|
172
175
|
422: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
173
|
-
return &UnprocessableEntityError{Body: b, Data: d, Response: r, Message:
|
|
176
|
+
return &UnprocessableEntityError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
174
177
|
},
|
|
175
178
|
429: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
176
|
-
return &RateLimitError{Body: b, Data: d, Response: r, Message:
|
|
179
|
+
return &RateLimitError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
177
180
|
},
|
|
178
181
|
500: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
179
|
-
return &InternalServerError{Body: b, Data: d, Response: r, Message:
|
|
182
|
+
return &InternalServerError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
180
183
|
},
|
|
181
184
|
502: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
182
|
-
return &BadGatewayError{Body: b, Data: d, Response: r, Message:
|
|
185
|
+
return &BadGatewayError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
183
186
|
},
|
|
184
187
|
503: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
185
|
-
return &ServiceUnavailableError{Body: b, Data: d, Response: r, Message:
|
|
188
|
+
return &ServiceUnavailableError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
186
189
|
},
|
|
187
190
|
504: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
188
|
-
return &GatewayTimeoutError{Body: b, Data: d, Response: r, Message:
|
|
191
|
+
return &GatewayTimeoutError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
189
192
|
},
|
|
190
193
|
}
|
|
191
194
|
|
|
@@ -203,5 +206,31 @@ func raiseForStatus(resp *http.Response, body []byte) error {
|
|
|
203
206
|
if fn, ok := statusErrorMap[resp.StatusCode]; ok {
|
|
204
207
|
return fn(resp.StatusCode, body, data, resp)
|
|
205
208
|
}
|
|
206
|
-
return &StatusError{StatusCode: resp.StatusCode, Body: body, Data: data, Response: resp, Message:
|
|
209
|
+
return &StatusError{StatusCode: resp.StatusCode, Body: body, Data: data, Response: resp, Message: errorMessage(body, data)}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// errorMessage is the server's `message` field when the body is a JSON object
|
|
213
|
+
// carrying one, else the body text. Control characters are dropped and the
|
|
214
|
+
// result is capped, so a hostile server cannot fill logs or drive a terminal.
|
|
215
|
+
func errorMessage(body []byte, data any) string {
|
|
216
|
+
text := string(body)
|
|
217
|
+
if m, ok := data.(map[string]any); ok {
|
|
218
|
+
if msg, ok := m["message"].(string); ok {
|
|
219
|
+
text = msg
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
var b strings.Builder
|
|
223
|
+
n := 0
|
|
224
|
+
for _, r := range text {
|
|
225
|
+
if n >= maxErrorMessageRunes {
|
|
226
|
+
b.WriteString("…")
|
|
227
|
+
break
|
|
228
|
+
}
|
|
229
|
+
if r == utf8.RuneError || unicode.IsControl(r) {
|
|
230
|
+
continue
|
|
231
|
+
}
|
|
232
|
+
b.WriteRune(r)
|
|
233
|
+
n++
|
|
234
|
+
}
|
|
235
|
+
return b.String()
|
|
207
236
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Code generated by honey. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
package sdk
|
|
4
|
+
|
|
5
|
+
import (
|
|
6
|
+
"context"
|
|
7
|
+
"iter"
|
|
8
|
+
"net/http"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// The Honey* functions expose the SDK's URL, SSE and error handling to the
|
|
12
|
+
// generated CLI, so both send byte-identical requests.
|
|
13
|
+
|
|
14
|
+
// HoneyExpandPath fills `{name}` placeholders with escaped values and rejects
|
|
15
|
+
// "", "." and "..".
|
|
16
|
+
func HoneyExpandPath(template string, params map[string]string) (string, error) {
|
|
17
|
+
return expandPath(template, params)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// HoneyBuildURL joins base and an escaped path (keeping the base path) and
|
|
21
|
+
// appends the query pairs in order.
|
|
22
|
+
func HoneyBuildURL(baseURL, path string, query [][2]string) (string, error) {
|
|
23
|
+
q := make(queryList, 0, len(query))
|
|
24
|
+
for _, p := range query {
|
|
25
|
+
q = append(q, queryPair{key: p[0], value: p[1]})
|
|
26
|
+
}
|
|
27
|
+
return buildURL(baseURL, path, q)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// HoneyParseSSEStream yields the events of an SSE response and closes its body.
|
|
31
|
+
func HoneyParseSSEStream(ctx context.Context, resp *http.Response) iter.Seq2[SSEEvent, error] {
|
|
32
|
+
return parseSSEStream(ctx, resp)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// HoneyRaiseForStatus returns the typed error for a non-2xx response, or nil.
|
|
36
|
+
func HoneyRaiseForStatus(resp *http.Response, body []byte) error {
|
|
37
|
+
return raiseForStatus(resp, body)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// HoneyFormatQueryValue renders a query or header value the way every SDK
|
|
41
|
+
// language does.
|
|
42
|
+
func HoneyFormatQueryValue(v any) string {
|
|
43
|
+
return formatQueryValue(v)
|
|
44
|
+
}
|
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
package sdk
|
|
4
4
|
|
|
5
5
|
import (
|
|
6
|
+
"container/list"
|
|
6
7
|
"fmt"
|
|
7
|
-
"net/url"
|
|
8
8
|
"regexp"
|
|
9
9
|
"strings"
|
|
10
10
|
"sync"
|
|
11
11
|
"time"
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
-
/* placeholderRe matches `{name}`
|
|
15
|
-
|
|
14
|
+
/* placeholderRe matches `{name}` (any name without braces or slashes) and a
|
|
15
|
+
* `:name` segment. A colon inside a segment (`/ops/1:cancel`) is literal. */
|
|
16
|
+
var placeholderRe = regexp.MustCompile(`\{([^{}/]+)\}|(^|/):([a-zA-Z_][a-zA-Z0-9_]*)`)
|
|
16
17
|
|
|
17
18
|
/* patternRegexCache caches compiled placeholder→`[^/]+` regexps per pattern key. */
|
|
18
19
|
var patternRegexCache sync.Map /* map[string]*regexp.Regexp */
|
|
@@ -24,6 +25,8 @@ type staleEntry struct {
|
|
|
24
25
|
by []string
|
|
25
26
|
seq uint64
|
|
26
27
|
until time.Time
|
|
28
|
+
/* position in the tracker's LRU list */
|
|
29
|
+
elem *list.Element
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
// RequestMeta is the per-request invalidation snapshot consumers see on hook
|
|
@@ -44,7 +47,11 @@ func compilePattern(pattern string) *regexp.Regexp {
|
|
|
44
47
|
b.WriteByte('^')
|
|
45
48
|
last := 0
|
|
46
49
|
for _, m := range matches {
|
|
47
|
-
|
|
50
|
+
start := m[0]
|
|
51
|
+
if pattern[start] == '/' {
|
|
52
|
+
start++ /* keep the segment slash literal */
|
|
53
|
+
}
|
|
54
|
+
b.WriteString(regexp.QuoteMeta(pattern[last:start]))
|
|
48
55
|
b.WriteString(`[^/]+`)
|
|
49
56
|
last = m[1]
|
|
50
57
|
}
|
|
@@ -78,8 +85,10 @@ func interpolatePath(template string, params map[string]string) (string, error)
|
|
|
78
85
|
out := placeholderRe.ReplaceAllStringFunc(template, func(match string) string {
|
|
79
86
|
groups := placeholderRe.FindStringSubmatch(match)
|
|
80
87
|
key := groups[1]
|
|
88
|
+
prefix := ""
|
|
81
89
|
if key == "" {
|
|
82
|
-
|
|
90
|
+
prefix = groups[2]
|
|
91
|
+
key = groups[3]
|
|
83
92
|
}
|
|
84
93
|
val, ok := params[key]
|
|
85
94
|
if !ok {
|
|
@@ -88,7 +97,7 @@ func interpolatePath(template string, params map[string]string) (string, error)
|
|
|
88
97
|
}
|
|
89
98
|
return match
|
|
90
99
|
}
|
|
91
|
-
return
|
|
100
|
+
return prefix + escapePathSegment(val)
|
|
92
101
|
})
|
|
93
102
|
if missing != "" {
|
|
94
103
|
return "", fmt.Errorf("interpolatePath: missing path param %q", missing)
|
|
@@ -98,8 +107,8 @@ func interpolatePath(template string, params map[string]string) (string, error)
|
|
|
98
107
|
|
|
99
108
|
// resolveInvalidationTargetsForMutation expands templated `METHOD /path/{x}`
|
|
100
109
|
// invalidation entries to concrete `METHOD /path/abc` selectors using params.
|
|
101
|
-
//
|
|
102
|
-
//
|
|
110
|
+
// An entry whose placeholders cannot all be resolved stays a pattern, so it
|
|
111
|
+
// marks every instance stale (TS parity).
|
|
103
112
|
func resolveInvalidationTargetsForMutation(targets []string, params map[string]string) []string {
|
|
104
113
|
out := make([]string, 0, len(targets))
|
|
105
114
|
for _, entry := range targets {
|
|
@@ -116,6 +125,7 @@ func resolveInvalidationTargetsForMutation(targets []string, params map[string]s
|
|
|
116
125
|
}
|
|
117
126
|
concrete, err := interpolatePath(template, params)
|
|
118
127
|
if err != nil {
|
|
128
|
+
out = append(out, entry)
|
|
119
129
|
continue
|
|
120
130
|
}
|
|
121
131
|
out = append(out, method+" "+concrete)
|
|
@@ -126,11 +136,14 @@ func resolveInvalidationTargetsForMutation(targets []string, params map[string]s
|
|
|
126
136
|
// StaleTracker tracks invalidation state per `METHOD /path` selector with TS-
|
|
127
137
|
// parity semantics: exact-key + pattern-key two-tier lookup, TTL stale window,
|
|
128
138
|
// LRU eviction at cap, monotonic seq for clear-after-mutate ordering.
|
|
129
|
-
// All public methods are safe for concurrent use.
|
|
139
|
+
// All public methods are safe for concurrent use. A lookup costs one map read plus a scan of
|
|
140
|
+
// the pattern keys of its method; touch and eviction are O(1).
|
|
130
141
|
type StaleTracker struct {
|
|
131
|
-
mu
|
|
132
|
-
entries
|
|
133
|
-
order
|
|
142
|
+
mu sync.Mutex
|
|
143
|
+
entries map[string]*staleEntry
|
|
144
|
+
order *list.List /* of string keys; oldest at the front */
|
|
145
|
+
/* method → keys whose path still holds placeholders */
|
|
146
|
+
patterns map[string]map[string]struct{}
|
|
134
147
|
enabled bool
|
|
135
148
|
staleTime time.Duration
|
|
136
149
|
maxEntries int
|
|
@@ -141,7 +154,7 @@ type StaleTracker struct {
|
|
|
141
154
|
// NewStaleTracker constructs a tracker from an InvalidationConfig.
|
|
142
155
|
// Tracker is disabled (cheap no-op) when cfg is nil or StaleTime ≤ 0.
|
|
143
156
|
func NewStaleTracker(cfg *InvalidationConfig) *StaleTracker {
|
|
144
|
-
t := &StaleTracker{entries: map[string]*staleEntry{}}
|
|
157
|
+
t := &StaleTracker{entries: map[string]*staleEntry{}, order: list.New(), patterns: map[string]map[string]struct{}{}}
|
|
145
158
|
if cfg == nil || cfg.StaleTime <= 0 {
|
|
146
159
|
return t
|
|
147
160
|
}
|
|
@@ -203,21 +216,11 @@ func (t *StaleTracker) ClearStale(concreteSelector, concretePath, method string,
|
|
|
203
216
|
t.deleteLocked(concreteSelector)
|
|
204
217
|
}
|
|
205
218
|
toDelete := make([]string, 0)
|
|
206
|
-
for key
|
|
207
|
-
if
|
|
219
|
+
for key := range t.patterns[method] {
|
|
220
|
+
if t.entries[key].seq > seqSnapshot {
|
|
208
221
|
continue
|
|
209
222
|
}
|
|
210
|
-
if
|
|
211
|
-
continue
|
|
212
|
-
}
|
|
213
|
-
spaceIdx := strings.IndexByte(key, ' ')
|
|
214
|
-
if spaceIdx == -1 {
|
|
215
|
-
continue
|
|
216
|
-
}
|
|
217
|
-
if key[:spaceIdx] != method {
|
|
218
|
-
continue
|
|
219
|
-
}
|
|
220
|
-
if pathMatchesPattern(concretePath, key[spaceIdx+1:]) {
|
|
223
|
+
if pathMatchesPattern(concretePath, key[strings.IndexByte(key, ' ')+1:]) {
|
|
221
224
|
toDelete = append(toDelete, key)
|
|
222
225
|
}
|
|
223
226
|
}
|
|
@@ -278,29 +281,34 @@ func (t *StaleTracker) upsertLocked(key string, until time.Time, seq uint64, mut
|
|
|
278
281
|
if mutationSelector != "" {
|
|
279
282
|
by = append(by, mutationSelector)
|
|
280
283
|
}
|
|
281
|
-
t.entries[key] = &staleEntry{by: by, seq: seq, until: until}
|
|
282
|
-
|
|
284
|
+
t.entries[key] = &staleEntry{by: by, elem: t.order.PushBack(key), seq: seq, until: until}
|
|
285
|
+
if method, path, ok := strings.Cut(key, " "); ok && pathHasPlaceholders(path) {
|
|
286
|
+
if t.patterns[method] == nil {
|
|
287
|
+
t.patterns[method] = map[string]struct{}{}
|
|
288
|
+
}
|
|
289
|
+
t.patterns[method][key] = struct{}{}
|
|
290
|
+
}
|
|
283
291
|
}
|
|
284
292
|
|
|
285
293
|
func (t *StaleTracker) touchOrderLocked(key string) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
t.order = append(t.order[:i], t.order[i+1:]...)
|
|
289
|
-
break
|
|
290
|
-
}
|
|
294
|
+
if entry, ok := t.entries[key]; ok {
|
|
295
|
+
t.order.MoveToBack(entry.elem)
|
|
291
296
|
}
|
|
292
|
-
t.order = append(t.order, key)
|
|
293
297
|
}
|
|
294
298
|
|
|
295
299
|
func (t *StaleTracker) deleteLocked(key string) {
|
|
296
|
-
|
|
300
|
+
entry, ok := t.entries[key]
|
|
301
|
+
if !ok {
|
|
297
302
|
return
|
|
298
303
|
}
|
|
299
304
|
delete(t.entries, key)
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
305
|
+
t.order.Remove(entry.elem)
|
|
306
|
+
if method, _, ok := strings.Cut(key, " "); ok {
|
|
307
|
+
if bucket := t.patterns[method]; bucket != nil {
|
|
308
|
+
delete(bucket, key)
|
|
309
|
+
if len(bucket) == 0 {
|
|
310
|
+
delete(t.patterns, method)
|
|
311
|
+
}
|
|
304
312
|
}
|
|
305
313
|
}
|
|
306
314
|
}
|
|
@@ -315,7 +323,8 @@ func (t *StaleTracker) lookupLocked(concreteSelector, concretePath, method strin
|
|
|
315
323
|
}
|
|
316
324
|
}
|
|
317
325
|
expired := make([]string, 0)
|
|
318
|
-
for key
|
|
326
|
+
for key := range t.patterns[method] {
|
|
327
|
+
entry := t.entries[key]
|
|
319
328
|
if !entry.until.After(now) {
|
|
320
329
|
expired = append(expired, key)
|
|
321
330
|
continue
|
|
@@ -323,17 +332,7 @@ func (t *StaleTracker) lookupLocked(concreteSelector, concretePath, method strin
|
|
|
323
332
|
if key == concreteSelector {
|
|
324
333
|
continue
|
|
325
334
|
}
|
|
326
|
-
if
|
|
327
|
-
continue
|
|
328
|
-
}
|
|
329
|
-
spaceIdx := strings.IndexByte(key, ' ')
|
|
330
|
-
if spaceIdx == -1 {
|
|
331
|
-
continue
|
|
332
|
-
}
|
|
333
|
-
if key[:spaceIdx] != method {
|
|
334
|
-
continue
|
|
335
|
-
}
|
|
336
|
-
if pathMatchesPattern(concretePath, key[spaceIdx+1:]) {
|
|
335
|
+
if pathMatchesPattern(concretePath, key[strings.IndexByte(key, ' ')+1:]) {
|
|
337
336
|
allBy = append(allBy, entry.by...)
|
|
338
337
|
}
|
|
339
338
|
}
|
|
@@ -366,8 +365,7 @@ func (t *StaleTracker) enforceCapacityLocked() {
|
|
|
366
365
|
if target < 1 {
|
|
367
366
|
target = 1
|
|
368
367
|
}
|
|
369
|
-
for len(t.entries) > target &&
|
|
370
|
-
|
|
371
|
-
t.deleteLocked(oldest)
|
|
368
|
+
for len(t.entries) > target && t.order.Len() > 0 {
|
|
369
|
+
t.deleteLocked(t.order.Front().Value.(string))
|
|
372
370
|
}
|
|
373
371
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Code generated by honey. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
package sdk
|
|
4
|
+
|
|
5
|
+
import (
|
|
6
|
+
"bytes"
|
|
7
|
+
"encoding/json"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// Nullable is an optional field that may also be null. Its zero value is "absent": the key is
|
|
11
|
+
// left out of the request (the field carries `omitzero`). NullOf sends an explicit null, Some a
|
|
12
|
+
// value. Decoding sets it from the response: absent stays absent, null becomes null.
|
|
13
|
+
type Nullable[T any] struct {
|
|
14
|
+
value T
|
|
15
|
+
set bool
|
|
16
|
+
null bool
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Some is a present, non-null value.
|
|
20
|
+
func Some[T any](v T) Nullable[T] {
|
|
21
|
+
return Nullable[T]{value: v, set: true}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// NullOf is an explicit null.
|
|
25
|
+
func NullOf[T any]() Nullable[T] {
|
|
26
|
+
return Nullable[T]{set: true, null: true}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// IsZero reports an absent field; encoding/json leaves it out under `omitzero`.
|
|
30
|
+
func (n Nullable[T]) IsZero() bool {
|
|
31
|
+
return !n.set
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// IsNull reports an explicit null.
|
|
35
|
+
func (n Nullable[T]) IsNull() bool {
|
|
36
|
+
return n.set && n.null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Get returns the value and whether there is one (false for absent and for null).
|
|
40
|
+
func (n Nullable[T]) Get() (T, bool) {
|
|
41
|
+
return n.value, n.set && !n.null
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
func (n Nullable[T]) MarshalJSON() ([]byte, error) {
|
|
45
|
+
if !n.set || n.null {
|
|
46
|
+
return []byte("null"), nil
|
|
47
|
+
}
|
|
48
|
+
return json.Marshal(n.value)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
func (n *Nullable[T]) UnmarshalJSON(data []byte) error {
|
|
52
|
+
if bytes.Equal(bytes.TrimSpace(data), []byte("null")) {
|
|
53
|
+
*n = NullOf[T]()
|
|
54
|
+
return nil
|
|
55
|
+
}
|
|
56
|
+
var v T
|
|
57
|
+
if err := json.Unmarshal(data, &v); err != nil {
|
|
58
|
+
return err
|
|
59
|
+
}
|
|
60
|
+
*n = Some(v)
|
|
61
|
+
return nil
|
|
62
|
+
}
|