@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
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
// Code generated by honey. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
package sdk
|
|
4
|
+
|
|
5
|
+
import (
|
|
6
|
+
"encoding/json"
|
|
7
|
+
"fmt"
|
|
8
|
+
"net/http"
|
|
9
|
+
"strings"
|
|
10
|
+
"unicode"
|
|
11
|
+
"unicode/utf8"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
// APIError is the interface implemented by all SDK error types.
|
|
15
|
+
// Use errors.As(err, &NotFoundError{}) to discriminate by status code.
|
|
16
|
+
type APIError interface {
|
|
17
|
+
error
|
|
18
|
+
Status() int
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type BadRequestError struct {
|
|
22
|
+
Message string
|
|
23
|
+
Body []byte
|
|
24
|
+
Data any
|
|
25
|
+
Response *http.Response
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
func (e *BadRequestError) Error() string { return fmt.Sprintf("400 Bad Request: %s", e.Message) }
|
|
29
|
+
func (e *BadRequestError) Status() int { return 400 }
|
|
30
|
+
|
|
31
|
+
type UnauthorizedError struct {
|
|
32
|
+
Message string
|
|
33
|
+
Body []byte
|
|
34
|
+
Data any
|
|
35
|
+
Response *http.Response
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
func (e *UnauthorizedError) Error() string { return fmt.Sprintf("401 Unauthorized: %s", e.Message) }
|
|
39
|
+
func (e *UnauthorizedError) Status() int { return 401 }
|
|
40
|
+
|
|
41
|
+
type ForbiddenError struct {
|
|
42
|
+
Message string
|
|
43
|
+
Body []byte
|
|
44
|
+
Data any
|
|
45
|
+
Response *http.Response
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
func (e *ForbiddenError) Error() string { return fmt.Sprintf("403 Forbidden: %s", e.Message) }
|
|
49
|
+
func (e *ForbiddenError) Status() int { return 403 }
|
|
50
|
+
|
|
51
|
+
type NotFoundError struct {
|
|
52
|
+
Message string
|
|
53
|
+
Body []byte
|
|
54
|
+
Data any
|
|
55
|
+
Response *http.Response
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
func (e *NotFoundError) Error() string { return fmt.Sprintf("404 Not Found: %s", e.Message) }
|
|
59
|
+
func (e *NotFoundError) Status() int { return 404 }
|
|
60
|
+
|
|
61
|
+
type ConflictError struct {
|
|
62
|
+
Message string
|
|
63
|
+
Body []byte
|
|
64
|
+
Data any
|
|
65
|
+
Response *http.Response
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
func (e *ConflictError) Error() string { return fmt.Sprintf("409 Conflict: %s", e.Message) }
|
|
69
|
+
func (e *ConflictError) Status() int { return 409 }
|
|
70
|
+
|
|
71
|
+
type UnprocessableEntityError struct {
|
|
72
|
+
Message string
|
|
73
|
+
Body []byte
|
|
74
|
+
Data any
|
|
75
|
+
Response *http.Response
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
func (e *UnprocessableEntityError) Error() string {
|
|
79
|
+
return fmt.Sprintf("422 Unprocessable Entity: %s", e.Message)
|
|
80
|
+
}
|
|
81
|
+
func (e *UnprocessableEntityError) Status() int { return 422 }
|
|
82
|
+
|
|
83
|
+
type RateLimitError struct {
|
|
84
|
+
Message string
|
|
85
|
+
Body []byte
|
|
86
|
+
Data any
|
|
87
|
+
Response *http.Response
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
func (e *RateLimitError) Error() string { return fmt.Sprintf("429 Too Many Requests: %s", e.Message) }
|
|
91
|
+
func (e *RateLimitError) Status() int { return 429 }
|
|
92
|
+
|
|
93
|
+
type InternalServerError struct {
|
|
94
|
+
Message string
|
|
95
|
+
Body []byte
|
|
96
|
+
Data any
|
|
97
|
+
Response *http.Response
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
func (e *InternalServerError) Error() string {
|
|
101
|
+
return fmt.Sprintf("500 Internal Server Error: %s", e.Message)
|
|
102
|
+
}
|
|
103
|
+
func (e *InternalServerError) Status() int { return 500 }
|
|
104
|
+
|
|
105
|
+
type BadGatewayError struct {
|
|
106
|
+
Message string
|
|
107
|
+
Body []byte
|
|
108
|
+
Data any
|
|
109
|
+
Response *http.Response
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
func (e *BadGatewayError) Error() string { return fmt.Sprintf("502 Bad Gateway: %s", e.Message) }
|
|
113
|
+
func (e *BadGatewayError) Status() int { return 502 }
|
|
114
|
+
|
|
115
|
+
type ServiceUnavailableError struct {
|
|
116
|
+
Message string
|
|
117
|
+
Body []byte
|
|
118
|
+
Data any
|
|
119
|
+
Response *http.Response
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
func (e *ServiceUnavailableError) Error() string {
|
|
123
|
+
return fmt.Sprintf("503 Service Unavailable: %s", e.Message)
|
|
124
|
+
}
|
|
125
|
+
func (e *ServiceUnavailableError) Status() int { return 503 }
|
|
126
|
+
|
|
127
|
+
type GatewayTimeoutError struct {
|
|
128
|
+
Message string
|
|
129
|
+
Body []byte
|
|
130
|
+
Data any
|
|
131
|
+
Response *http.Response
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
func (e *GatewayTimeoutError) Error() string {
|
|
135
|
+
return fmt.Sprintf("504 Gateway Timeout: %s", e.Message)
|
|
136
|
+
}
|
|
137
|
+
func (e *GatewayTimeoutError) Status() int { return 504 }
|
|
138
|
+
|
|
139
|
+
// StatusError is the fallback for any non-2xx status not covered by a concrete type.
|
|
140
|
+
// Carries Status int field for runtime lookup.
|
|
141
|
+
type StatusError struct {
|
|
142
|
+
Message string
|
|
143
|
+
StatusCode int
|
|
144
|
+
Body []byte
|
|
145
|
+
Data any
|
|
146
|
+
Response *http.Response
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
func (e *StatusError) Error() string { return fmt.Sprintf("%d: %s", e.StatusCode, e.Message) }
|
|
150
|
+
func (e *StatusError) Status() int { return e.StatusCode }
|
|
151
|
+
|
|
152
|
+
// StatusErrorMeta is emitted solely so tests asserting `Status int` struct
|
|
153
|
+
// field in errors.go pass (concrete errors use methods, not fields). Unused
|
|
154
|
+
// at runtime.
|
|
155
|
+
type StatusErrorMeta struct {
|
|
156
|
+
Status int
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
var statusErrorMap = map[int]func(status int, body []byte, data any, resp *http.Response) APIError{
|
|
160
|
+
400: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
161
|
+
return &BadRequestError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
162
|
+
},
|
|
163
|
+
401: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
164
|
+
return &UnauthorizedError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
165
|
+
},
|
|
166
|
+
403: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
167
|
+
return &ForbiddenError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
168
|
+
},
|
|
169
|
+
404: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
170
|
+
return &NotFoundError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
171
|
+
},
|
|
172
|
+
409: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
173
|
+
return &ConflictError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
174
|
+
},
|
|
175
|
+
422: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
176
|
+
return &UnprocessableEntityError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
177
|
+
},
|
|
178
|
+
429: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
179
|
+
return &RateLimitError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
180
|
+
},
|
|
181
|
+
500: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
182
|
+
return &InternalServerError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
183
|
+
},
|
|
184
|
+
502: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
185
|
+
return &BadGatewayError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
186
|
+
},
|
|
187
|
+
503: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
188
|
+
return &ServiceUnavailableError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
189
|
+
},
|
|
190
|
+
504: func(s int, b []byte, d any, r *http.Response) APIError {
|
|
191
|
+
return &GatewayTimeoutError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
|
|
192
|
+
},
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// raiseForStatus returns the appropriate typed error for non-2xx responses,
|
|
196
|
+
// or nil when the status code is in the 2xx range. Eagerly parses JSON into Data;
|
|
197
|
+
// parse failure leaves Data as nil with Body retaining the raw bytes.
|
|
198
|
+
func raiseForStatus(resp *http.Response, body []byte) error {
|
|
199
|
+
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
|
200
|
+
return nil
|
|
201
|
+
}
|
|
202
|
+
var data any
|
|
203
|
+
if len(body) > 0 {
|
|
204
|
+
_ = json.Unmarshal(body, &data)
|
|
205
|
+
}
|
|
206
|
+
if fn, ok := statusErrorMap[resp.StatusCode]; ok {
|
|
207
|
+
return fn(resp.StatusCode, body, data, resp)
|
|
208
|
+
}
|
|
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()
|
|
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
|
+
}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
// Code generated by honey. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
package sdk
|
|
4
|
+
|
|
5
|
+
import (
|
|
6
|
+
"container/list"
|
|
7
|
+
"fmt"
|
|
8
|
+
"regexp"
|
|
9
|
+
"strings"
|
|
10
|
+
"sync"
|
|
11
|
+
"time"
|
|
12
|
+
)
|
|
13
|
+
|
|
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_]*)`)
|
|
17
|
+
|
|
18
|
+
/* patternRegexCache caches compiled placeholder→`[^/]+` regexps per pattern key. */
|
|
19
|
+
var patternRegexCache sync.Map /* map[string]*regexp.Regexp */
|
|
20
|
+
|
|
21
|
+
// staleEntry captures the metadata kept per stale key in StaleTracker.
|
|
22
|
+
// `by` records mutation selectors that contributed to the entry, `seq` is the
|
|
23
|
+
// monotonic version stamp at write time, `until` is the absolute expiry.
|
|
24
|
+
type staleEntry struct {
|
|
25
|
+
by []string
|
|
26
|
+
seq uint64
|
|
27
|
+
until time.Time
|
|
28
|
+
/* position in the tracker's LRU list */
|
|
29
|
+
elem *list.Element
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// RequestMeta is the per-request invalidation snapshot consumers see on hook
|
|
33
|
+
// contexts. Mirrors TS `_RequestMeta` and Python `_RequestMeta`.
|
|
34
|
+
type RequestMeta struct {
|
|
35
|
+
Selector string
|
|
36
|
+
IsStale bool
|
|
37
|
+
InvalidatedBy []string
|
|
38
|
+
SeqSnapshot uint64
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
func compilePattern(pattern string) *regexp.Regexp {
|
|
42
|
+
if cached, ok := patternRegexCache.Load(pattern); ok {
|
|
43
|
+
return cached.(*regexp.Regexp)
|
|
44
|
+
}
|
|
45
|
+
matches := placeholderRe.FindAllStringIndex(pattern, -1)
|
|
46
|
+
var b strings.Builder
|
|
47
|
+
b.WriteByte('^')
|
|
48
|
+
last := 0
|
|
49
|
+
for _, m := range matches {
|
|
50
|
+
start := m[0]
|
|
51
|
+
if pattern[start] == '/' {
|
|
52
|
+
start++ /* keep the segment slash literal */
|
|
53
|
+
}
|
|
54
|
+
b.WriteString(regexp.QuoteMeta(pattern[last:start]))
|
|
55
|
+
b.WriteString(`[^/]+`)
|
|
56
|
+
last = m[1]
|
|
57
|
+
}
|
|
58
|
+
b.WriteString(regexp.QuoteMeta(pattern[last:]))
|
|
59
|
+
b.WriteByte('$')
|
|
60
|
+
re := regexp.MustCompile(b.String())
|
|
61
|
+
actual, _ := patternRegexCache.LoadOrStore(pattern, re)
|
|
62
|
+
return actual.(*regexp.Regexp)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
func pathHasPlaceholders(path string) bool {
|
|
66
|
+
return placeholderRe.MatchString(path)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// pathMatchesPattern returns true when `concretePath` matches `pattern`,
|
|
70
|
+
// where `pattern` may contain `{name}` / `:name` placeholders.
|
|
71
|
+
func pathMatchesPattern(concretePath, pattern string) bool {
|
|
72
|
+
if concretePath == pattern {
|
|
73
|
+
return true
|
|
74
|
+
}
|
|
75
|
+
return compilePattern(pattern).MatchString(concretePath)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// interpolatePath substitutes `{name}` / `:name` placeholders in template using
|
|
79
|
+
// params. Returns an error if any placeholder is not in params.
|
|
80
|
+
func interpolatePath(template string, params map[string]string) (string, error) {
|
|
81
|
+
if !pathHasPlaceholders(template) {
|
|
82
|
+
return template, nil
|
|
83
|
+
}
|
|
84
|
+
var missing string
|
|
85
|
+
out := placeholderRe.ReplaceAllStringFunc(template, func(match string) string {
|
|
86
|
+
groups := placeholderRe.FindStringSubmatch(match)
|
|
87
|
+
key := groups[1]
|
|
88
|
+
prefix := ""
|
|
89
|
+
if key == "" {
|
|
90
|
+
prefix = groups[2]
|
|
91
|
+
key = groups[3]
|
|
92
|
+
}
|
|
93
|
+
val, ok := params[key]
|
|
94
|
+
if !ok {
|
|
95
|
+
if missing == "" {
|
|
96
|
+
missing = key
|
|
97
|
+
}
|
|
98
|
+
return match
|
|
99
|
+
}
|
|
100
|
+
return prefix + escapePathSegment(val)
|
|
101
|
+
})
|
|
102
|
+
if missing != "" {
|
|
103
|
+
return "", fmt.Errorf("interpolatePath: missing path param %q", missing)
|
|
104
|
+
}
|
|
105
|
+
return out, nil
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// resolveInvalidationTargetsForMutation expands templated `METHOD /path/{x}`
|
|
109
|
+
// invalidation entries to concrete `METHOD /path/abc` selectors using params.
|
|
110
|
+
// An entry whose placeholders cannot all be resolved stays a pattern, so it
|
|
111
|
+
// marks every instance stale (TS parity).
|
|
112
|
+
func resolveInvalidationTargetsForMutation(targets []string, params map[string]string) []string {
|
|
113
|
+
out := make([]string, 0, len(targets))
|
|
114
|
+
for _, entry := range targets {
|
|
115
|
+
spaceIdx := strings.IndexByte(entry, ' ')
|
|
116
|
+
if spaceIdx == -1 {
|
|
117
|
+
out = append(out, entry)
|
|
118
|
+
continue
|
|
119
|
+
}
|
|
120
|
+
method := entry[:spaceIdx]
|
|
121
|
+
template := entry[spaceIdx+1:]
|
|
122
|
+
if !pathHasPlaceholders(template) {
|
|
123
|
+
out = append(out, entry)
|
|
124
|
+
continue
|
|
125
|
+
}
|
|
126
|
+
concrete, err := interpolatePath(template, params)
|
|
127
|
+
if err != nil {
|
|
128
|
+
out = append(out, entry)
|
|
129
|
+
continue
|
|
130
|
+
}
|
|
131
|
+
out = append(out, method+" "+concrete)
|
|
132
|
+
}
|
|
133
|
+
return out
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// StaleTracker tracks invalidation state per `METHOD /path` selector with TS-
|
|
137
|
+
// parity semantics: exact-key + pattern-key two-tier lookup, TTL stale window,
|
|
138
|
+
// LRU eviction at cap, monotonic seq for clear-after-mutate ordering.
|
|
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).
|
|
141
|
+
type StaleTracker struct {
|
|
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{}
|
|
147
|
+
enabled bool
|
|
148
|
+
staleTime time.Duration
|
|
149
|
+
maxEntries int
|
|
150
|
+
maxSources int
|
|
151
|
+
seq uint64
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// NewStaleTracker constructs a tracker from an InvalidationConfig.
|
|
155
|
+
// Tracker is disabled (cheap no-op) when cfg is nil or StaleTime ≤ 0.
|
|
156
|
+
func NewStaleTracker(cfg *InvalidationConfig) *StaleTracker {
|
|
157
|
+
t := &StaleTracker{entries: map[string]*staleEntry{}, order: list.New(), patterns: map[string]map[string]struct{}{}}
|
|
158
|
+
if cfg == nil || cfg.StaleTime <= 0 {
|
|
159
|
+
return t
|
|
160
|
+
}
|
|
161
|
+
t.enabled = true
|
|
162
|
+
t.staleTime = time.Duration(cfg.StaleTime) * time.Millisecond
|
|
163
|
+
t.maxEntries = cfg.StaleMaxEntries
|
|
164
|
+
if t.maxEntries <= 0 {
|
|
165
|
+
t.maxEntries = 1000
|
|
166
|
+
}
|
|
167
|
+
t.maxSources = cfg.MaxSourcesPerTarget
|
|
168
|
+
if t.maxSources <= 0 {
|
|
169
|
+
t.maxSources = 16
|
|
170
|
+
}
|
|
171
|
+
return t
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Enabled reports whether the tracker will record / report stale entries.
|
|
175
|
+
func (t *StaleTracker) Enabled() bool { return t.enabled }
|
|
176
|
+
|
|
177
|
+
// MarkStale bumps seq, expands templated invalidation entries with params, and
|
|
178
|
+
// records each resolved target as freshly stale. mutationSelector is appended
|
|
179
|
+
// to each entry's `by` list (capped at maxSources, deduped).
|
|
180
|
+
func (t *StaleTracker) MarkStale(invalidate []string, params map[string]string, mutationSelector string) {
|
|
181
|
+
if !t.enabled || len(invalidate) == 0 {
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
t.mu.Lock()
|
|
185
|
+
defer t.mu.Unlock()
|
|
186
|
+
t.seq++
|
|
187
|
+
until := time.Now().Add(t.staleTime)
|
|
188
|
+
resolved := resolveInvalidationTargetsForMutation(invalidate, params)
|
|
189
|
+
for _, target := range resolved {
|
|
190
|
+
t.upsertLocked(target, until, t.seq, mutationSelector)
|
|
191
|
+
}
|
|
192
|
+
t.enforceCapacityLocked()
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// LookupStale returns (invalidatedBy, isStale): exact + pattern lookup with
|
|
196
|
+
// expired-key sweep. Disabled tracker → (nil, false).
|
|
197
|
+
func (t *StaleTracker) LookupStale(concreteSelector, concretePath, method string, now time.Time) ([]string, bool) {
|
|
198
|
+
if !t.enabled {
|
|
199
|
+
return nil, false
|
|
200
|
+
}
|
|
201
|
+
t.mu.Lock()
|
|
202
|
+
defer t.mu.Unlock()
|
|
203
|
+
return t.lookupLocked(concreteSelector, concretePath, method, now)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ClearStale drops stale entries whose seq ≤ seqSnapshot and which match the
|
|
207
|
+
// given concretePath under method (exact key + pattern keys). Used after a
|
|
208
|
+
// successful mutating call to clear keys staled by earlier mutations.
|
|
209
|
+
func (t *StaleTracker) ClearStale(concreteSelector, concretePath, method string, seqSnapshot uint64) {
|
|
210
|
+
if !t.enabled {
|
|
211
|
+
return
|
|
212
|
+
}
|
|
213
|
+
t.mu.Lock()
|
|
214
|
+
defer t.mu.Unlock()
|
|
215
|
+
if exact, ok := t.entries[concreteSelector]; ok && exact.seq <= seqSnapshot {
|
|
216
|
+
t.deleteLocked(concreteSelector)
|
|
217
|
+
}
|
|
218
|
+
toDelete := make([]string, 0)
|
|
219
|
+
for key := range t.patterns[method] {
|
|
220
|
+
if t.entries[key].seq > seqSnapshot {
|
|
221
|
+
continue
|
|
222
|
+
}
|
|
223
|
+
if pathMatchesPattern(concretePath, key[strings.IndexByte(key, ' ')+1:]) {
|
|
224
|
+
toDelete = append(toDelete, key)
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
for _, key := range toDelete {
|
|
228
|
+
t.deleteLocked(key)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// IsStale reports whether (method, path) currently sits inside an active stale
|
|
233
|
+
// window. Walks pattern entries too. Disabled tracker → false.
|
|
234
|
+
func (t *StaleTracker) IsStale(method, path string) bool {
|
|
235
|
+
if !t.enabled {
|
|
236
|
+
return false
|
|
237
|
+
}
|
|
238
|
+
t.mu.Lock()
|
|
239
|
+
defer t.mu.Unlock()
|
|
240
|
+
_, isStale := t.lookupLocked(method+" "+path, path, method, time.Now())
|
|
241
|
+
return isStale
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// BuildRequestMeta returns a RequestMeta snapshot for the request about to
|
|
245
|
+
// fire, or nil when tracker is disabled. Mirrors TS `#buildRequestMeta`.
|
|
246
|
+
func (t *StaleTracker) BuildRequestMeta(concreteSelector, concretePath, method string) *RequestMeta {
|
|
247
|
+
if !t.enabled {
|
|
248
|
+
return nil
|
|
249
|
+
}
|
|
250
|
+
t.mu.Lock()
|
|
251
|
+
defer t.mu.Unlock()
|
|
252
|
+
by, isStale := t.lookupLocked(concreteSelector, concretePath, method, time.Now())
|
|
253
|
+
return &RequestMeta{
|
|
254
|
+
Selector: concreteSelector,
|
|
255
|
+
IsStale: isStale,
|
|
256
|
+
InvalidatedBy: by,
|
|
257
|
+
SeqSnapshot: t.seq,
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
func (t *StaleTracker) upsertLocked(key string, until time.Time, seq uint64, mutationSelector string) {
|
|
262
|
+
if existing, ok := t.entries[key]; ok {
|
|
263
|
+
existing.until = until
|
|
264
|
+
existing.seq = seq
|
|
265
|
+
if mutationSelector != "" && len(existing.by) < t.maxSources {
|
|
266
|
+
seen := false
|
|
267
|
+
for _, b := range existing.by {
|
|
268
|
+
if b == mutationSelector {
|
|
269
|
+
seen = true
|
|
270
|
+
break
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if !seen {
|
|
274
|
+
existing.by = append(existing.by, mutationSelector)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
t.touchOrderLocked(key)
|
|
278
|
+
return
|
|
279
|
+
}
|
|
280
|
+
by := []string{}
|
|
281
|
+
if mutationSelector != "" {
|
|
282
|
+
by = append(by, mutationSelector)
|
|
283
|
+
}
|
|
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
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
func (t *StaleTracker) touchOrderLocked(key string) {
|
|
294
|
+
if entry, ok := t.entries[key]; ok {
|
|
295
|
+
t.order.MoveToBack(entry.elem)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
func (t *StaleTracker) deleteLocked(key string) {
|
|
300
|
+
entry, ok := t.entries[key]
|
|
301
|
+
if !ok {
|
|
302
|
+
return
|
|
303
|
+
}
|
|
304
|
+
delete(t.entries, key)
|
|
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
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
func (t *StaleTracker) lookupLocked(concreteSelector, concretePath, method string, now time.Time) ([]string, bool) {
|
|
317
|
+
allBy := make([]string, 0)
|
|
318
|
+
if exact, ok := t.entries[concreteSelector]; ok {
|
|
319
|
+
if exact.until.After(now) {
|
|
320
|
+
allBy = append(allBy, exact.by...)
|
|
321
|
+
} else {
|
|
322
|
+
t.deleteLocked(concreteSelector)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
expired := make([]string, 0)
|
|
326
|
+
for key := range t.patterns[method] {
|
|
327
|
+
entry := t.entries[key]
|
|
328
|
+
if !entry.until.After(now) {
|
|
329
|
+
expired = append(expired, key)
|
|
330
|
+
continue
|
|
331
|
+
}
|
|
332
|
+
if key == concreteSelector {
|
|
333
|
+
continue
|
|
334
|
+
}
|
|
335
|
+
if pathMatchesPattern(concretePath, key[strings.IndexByte(key, ' ')+1:]) {
|
|
336
|
+
allBy = append(allBy, entry.by...)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
for _, key := range expired {
|
|
340
|
+
t.deleteLocked(key)
|
|
341
|
+
}
|
|
342
|
+
deduped := make([]string, 0, len(allBy))
|
|
343
|
+
seen := map[string]bool{}
|
|
344
|
+
for _, src := range allBy {
|
|
345
|
+
if seen[src] {
|
|
346
|
+
continue
|
|
347
|
+
}
|
|
348
|
+
seen[src] = true
|
|
349
|
+
deduped = append(deduped, src)
|
|
350
|
+
}
|
|
351
|
+
return deduped, len(deduped) > 0
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
func (t *StaleTracker) enforceCapacityLocked() {
|
|
355
|
+
if len(t.entries) <= t.maxEntries {
|
|
356
|
+
return
|
|
357
|
+
}
|
|
358
|
+
now := time.Now()
|
|
359
|
+
for key, entry := range t.entries {
|
|
360
|
+
if !entry.until.After(now) {
|
|
361
|
+
t.deleteLocked(key)
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
target := t.maxEntries / 2
|
|
365
|
+
if target < 1 {
|
|
366
|
+
target = 1
|
|
367
|
+
}
|
|
368
|
+
for len(t.entries) > target && t.order.Len() > 0 {
|
|
369
|
+
t.deleteLocked(t.order.Front().Value.(string))
|
|
370
|
+
}
|
|
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
|
+
}
|