@lovrozagar/honey 0.6.8 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +514 -192
- package/bin/honey.js +25 -0
- package/dist/accepts.d.ts +7 -1
- package/dist/accepts.d.ts.map +1 -1
- package/dist/accepts.js +126 -0
- package/dist/accepts.js.map +1 -0
- package/dist/body-kind.d.ts +26 -0
- package/dist/body-kind.d.ts.map +1 -0
- package/dist/body-kind.js +70 -0
- package/dist/body-kind.js.map +1 -0
- package/dist/body-limit.d.ts +5 -1
- package/dist/body-limit.d.ts.map +1 -1
- package/dist/body-limit.js +126 -0
- package/dist/body-limit.js.map +1 -0
- package/dist/build/index.d.ts +19 -3
- package/dist/build/index.d.ts.map +1 -1
- package/dist/build/index.js +173 -0
- package/dist/build/index.js.map +1 -0
- package/dist/cli-args.d.ts +33 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +102 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-go/auth.go +26 -0
- package/dist/cli-go/config.go +192 -0
- package/dist/cli-go/errors.go +75 -0
- package/dist/cli-go/multipart.go +79 -0
- package/dist/cli-go/output.go +163 -0
- package/dist/cli-go/root.go +30 -0
- package/dist/cli-go/stream.go +88 -0
- package/dist/cli-go/version.go +5 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +209 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/defaults.js +48 -0
- package/dist/client/defaults.js.map +1 -0
- package/dist/client/error.d.ts +35 -0
- package/dist/client/error.d.ts.map +1 -1
- package/dist/client/error.js +71 -0
- package/dist/client/error.js.map +1 -0
- package/dist/client/http.d.ts +67 -8
- package/dist/client/http.d.ts.map +1 -1
- package/dist/client/http.js +571 -0
- package/dist/client/http.js.map +1 -0
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +95 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/path.d.ts +26 -0
- package/dist/client/path.d.ts.map +1 -0
- package/dist/client/path.js +163 -0
- package/dist/client/path.js.map +1 -0
- package/dist/client/redirect-policy.d.ts +12 -0
- package/dist/client/redirect-policy.d.ts.map +1 -0
- package/dist/client/redirect-policy.js +20 -0
- package/dist/client/redirect-policy.js.map +1 -0
- package/dist/client/sdk.d.ts +36 -0
- package/dist/client/sdk.d.ts.map +1 -1
- package/dist/client/sdk.js +292 -0
- package/dist/client/sdk.js.map +1 -0
- package/dist/client/sse.d.ts +13 -0
- package/dist/client/sse.d.ts.map +1 -1
- package/dist/client/sse.js +129 -0
- package/dist/client/sse.js.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/ws.d.ts +9 -2
- package/dist/client/ws.d.ts.map +1 -1
- package/dist/client/ws.js +112 -0
- package/dist/client/ws.js.map +1 -0
- package/dist/client-go/errors.go +236 -0
- package/dist/client-go/export.go +44 -0
- package/dist/client-go/invalidation.go +371 -0
- package/dist/client-go/nullable.go +62 -0
- package/dist/client-go/realtime.go +354 -0
- package/dist/client-go/result.go +20 -0
- package/dist/client-go/runtime.go +975 -0
- package/dist/client-go/sse.go +159 -0
- package/dist/client-go/transport.go +495 -0
- package/dist/client-go/ws.go +128 -0
- package/dist/client-info.d.ts +36 -0
- package/dist/client-info.d.ts.map +1 -0
- package/dist/client-info.js +53 -0
- package/dist/client-info.js.map +1 -0
- package/dist/client-mcp/README.md +10 -0
- package/dist/client-mcp/server.ts +221 -0
- package/dist/client-mcp/types.ts +19 -0
- package/dist/client-python/_errors.py +115 -0
- package/dist/client-python/_invalidation.py +494 -0
- package/dist/client-python/_realtime.py +179 -0
- package/dist/client-python/_runtime.py +860 -0
- package/dist/client-python/_sse.py +155 -0
- package/dist/client-python/_transport.py +366 -0
- package/dist/client-python/_ws.py +159 -0
- package/dist/client-python/py.typed +0 -0
- package/dist/client-rust/errors.rs +220 -0
- package/dist/client-rust/invalidation.rs +412 -0
- package/dist/client-rust/invalidation_sync.rs +93 -0
- package/dist/client-rust/nullable.rs +17 -0
- package/dist/client-rust/realtime.rs +702 -0
- package/dist/client-rust/result.rs +22 -0
- package/dist/client-rust/runtime.rs +980 -0
- package/dist/client-rust/runtime_sync.rs +484 -0
- package/dist/client-rust/sse.rs +188 -0
- package/dist/client-rust/ws.rs +167 -0
- package/dist/codegen-go-cli.d.ts.map +1 -1
- package/dist/codegen-go-cli.js +964 -0
- package/dist/codegen-go-cli.js.map +1 -0
- package/dist/codegen-go.d.ts +15 -3
- package/dist/codegen-go.d.ts.map +1 -1
- package/dist/codegen-go.js +872 -0
- package/dist/codegen-go.js.map +1 -0
- package/dist/codegen-hash.js +9 -0
- package/dist/codegen-hash.js.map +1 -0
- package/dist/codegen-ir.d.ts +69 -2
- package/dist/codegen-ir.d.ts.map +1 -1
- package/dist/codegen-ir.js +661 -0
- package/dist/codegen-ir.js.map +1 -0
- package/dist/codegen-lang.d.ts +65 -0
- package/dist/codegen-lang.d.ts.map +1 -0
- package/dist/codegen-lang.js +526 -0
- package/dist/codegen-lang.js.map +1 -0
- package/dist/codegen-load.d.ts +31 -0
- package/dist/codegen-load.d.ts.map +1 -0
- package/dist/codegen-load.js +138 -0
- package/dist/codegen-load.js.map +1 -0
- package/dist/codegen-loaders.js +55 -0
- package/dist/codegen-loaders.js.map +1 -0
- package/dist/codegen-mcp.d.ts.map +1 -1
- package/dist/codegen-mcp.js +368 -0
- package/dist/codegen-mcp.js.map +1 -0
- package/dist/codegen-python.d.ts +13 -1
- package/dist/codegen-python.d.ts.map +1 -1
- package/dist/codegen-python.js +828 -0
- package/dist/codegen-python.js.map +1 -0
- package/dist/codegen-route-tree-intern.d.ts +15 -5
- package/dist/codegen-route-tree-intern.d.ts.map +1 -1
- package/dist/codegen-route-tree-intern.js +221 -0
- package/dist/codegen-route-tree-intern.js.map +1 -0
- package/dist/codegen-rust.d.ts.map +1 -1
- package/dist/codegen-rust.js +1293 -0
- package/dist/codegen-rust.js.map +1 -0
- package/dist/codegen-sanitize.d.ts.map +1 -1
- package/dist/codegen-sanitize.js +56 -0
- package/dist/codegen-sanitize.js.map +1 -0
- package/dist/codegen-schema-naming.d.ts +5 -0
- package/dist/codegen-schema-naming.d.ts.map +1 -1
- package/dist/codegen-schema-naming.js +150 -0
- package/dist/codegen-schema-naming.js.map +1 -0
- package/dist/codegen-sdk-model.d.ts +71 -0
- package/dist/codegen-sdk-model.d.ts.map +1 -0
- package/dist/codegen-sdk-model.js +179 -0
- package/dist/codegen-sdk-model.js.map +1 -0
- package/dist/codegen.d.ts +41 -23
- package/dist/codegen.d.ts.map +1 -1
- package/dist/codegen.js +4610 -0
- package/dist/codegen.js.map +1 -0
- package/dist/context.d.ts +36 -6
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +242 -0
- package/dist/context.js.map +1 -0
- package/dist/cookie-sign.d.ts +16 -2
- package/dist/cookie-sign.d.ts.map +1 -1
- package/dist/cookie-sign.js +104 -0
- package/dist/cookie-sign.js.map +1 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.d.ts.map +1 -1
- package/dist/cookie.js +138 -0
- package/dist/cookie.js.map +1 -0
- package/dist/cors.d.ts +1 -0
- package/dist/cors.d.ts.map +1 -1
- package/dist/cors.js +87 -0
- package/dist/cors.js.map +1 -0
- package/dist/crypto.d.ts +6 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +38 -0
- package/dist/crypto.js.map +1 -0
- package/dist/csrf.d.ts +19 -0
- package/dist/csrf.d.ts.map +1 -1
- package/dist/csrf.js +79 -0
- package/dist/csrf.js.map +1 -0
- package/dist/curl-logger.d.ts +14 -3
- package/dist/curl-logger.d.ts.map +1 -1
- package/dist/curl-logger.js +199 -0
- package/dist/curl-logger.js.map +1 -0
- package/dist/detect-runtime.js +13 -0
- package/dist/detect-runtime.js.map +1 -0
- package/dist/dict.d.ts +11 -0
- package/dist/dict.d.ts.map +1 -0
- package/dist/dict.js +13 -0
- package/dist/dict.js.map +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +44 -0
- package/dist/error.js.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/etag.d.ts +2 -0
- package/dist/etag.d.ts.map +1 -1
- package/dist/etag.js +82 -0
- package/dist/etag.js.map +1 -0
- package/dist/feature-detect.d.ts +25 -0
- package/dist/feature-detect.d.ts.map +1 -0
- package/dist/feature-detect.js +144 -0
- package/dist/feature-detect.js.map +1 -0
- package/dist/feature-load.js +36 -0
- package/dist/feature-load.js.map +1 -0
- package/dist/feature-slots.d.ts +44 -0
- package/dist/feature-slots.d.ts.map +1 -0
- package/dist/feature-slots.js +48 -0
- package/dist/feature-slots.js.map +1 -0
- package/dist/fetch-request.d.ts +10 -0
- package/dist/fetch-request.d.ts.map +1 -0
- package/dist/fetch-request.js +13 -0
- package/dist/fetch-request.js.map +1 -0
- package/dist/gen-process.d.ts +15 -0
- package/dist/gen-process.d.ts.map +1 -0
- package/dist/gen-process.js +43 -0
- package/dist/gen-process.js.map +1 -0
- package/dist/gen-write.d.ts +19 -0
- package/dist/gen-write.d.ts.map +1 -0
- package/dist/gen-write.js +120 -0
- package/dist/gen-write.js.map +1 -0
- package/dist/glob.d.ts +21 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +115 -0
- package/dist/glob.js.map +1 -0
- package/dist/go-type-emitter.d.ts +18 -4
- package/dist/go-type-emitter.d.ts.map +1 -1
- package/dist/go-type-emitter.js +594 -0
- package/dist/go-type-emitter.js.map +1 -0
- package/dist/honey-response.d.ts.map +1 -1
- package/dist/honey-response.js +338 -0
- package/dist/honey-response.js.map +1 -0
- package/dist/i18n-slot.d.ts +8 -0
- package/dist/i18n-slot.d.ts.map +1 -1
- package/dist/i18n-slot.js +14 -0
- package/dist/i18n-slot.js.map +1 -0
- package/dist/i18n.d.ts +3 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +250 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +408 -148
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2324 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +3 -5
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +140 -0
- package/dist/init.js.map +1 -0
- package/dist/input.js +4 -0
- package/dist/input.js.map +1 -0
- package/dist/invalidate-check.d.ts +11 -0
- package/dist/invalidate-check.d.ts.map +1 -1
- package/dist/invalidate-check.js +163 -0
- package/dist/invalidate-check.js.map +1 -0
- package/dist/invoke-user.d.ts +35 -0
- package/dist/invoke-user.d.ts.map +1 -0
- package/dist/invoke-user.js +73 -0
- package/dist/invoke-user.js.map +1 -0
- package/dist/ip-restrict.d.ts +13 -1
- package/dist/ip-restrict.d.ts.map +1 -1
- package/dist/ip-restrict.js +60 -0
- package/dist/ip-restrict.js.map +1 -0
- package/dist/ip.d.ts +39 -0
- package/dist/ip.d.ts.map +1 -0
- package/dist/ip.js +209 -0
- package/dist/ip.js.map +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +113 -0
- package/dist/logger.js.map +1 -0
- package/dist/media-type.d.ts +30 -0
- package/dist/media-type.d.ts.map +1 -0
- package/dist/media-type.js +97 -0
- package/dist/media-type.js.map +1 -0
- package/dist/meta-spec-merge.d.ts +32 -0
- package/dist/meta-spec-merge.d.ts.map +1 -0
- package/dist/meta-spec-merge.js +68 -0
- package/dist/meta-spec-merge.js.map +1 -0
- package/dist/meta-spec.d.ts +16 -3
- package/dist/meta-spec.d.ts.map +1 -1
- package/dist/meta-spec.js +535 -0
- package/dist/meta-spec.js.map +1 -0
- package/dist/middleware.d.ts +23 -6
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +253 -0
- package/dist/middleware.js.map +1 -0
- package/dist/node-request.d.ts +57 -12
- package/dist/node-request.d.ts.map +1 -1
- package/dist/node-request.js +407 -0
- package/dist/node-request.js.map +1 -0
- package/dist/node.d.ts +20 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +396 -0
- package/dist/node.js.map +1 -0
- package/dist/openapi/collect.d.ts +6 -3
- package/dist/openapi/collect.d.ts.map +1 -1
- package/dist/openapi/collect.js +30 -0
- package/dist/openapi/collect.js.map +1 -0
- package/dist/openapi/docs-page.d.ts +42 -0
- package/dist/openapi/docs-page.d.ts.map +1 -0
- package/dist/openapi/docs-page.js +80 -0
- package/dist/openapi/docs-page.js.map +1 -0
- package/dist/openapi/document.d.ts +4 -0
- package/dist/openapi/document.d.ts.map +1 -1
- package/dist/openapi/document.js +785 -0
- package/dist/openapi/document.js.map +1 -0
- package/dist/openapi/json-schema-slot.d.ts +7 -0
- package/dist/openapi/json-schema-slot.d.ts.map +1 -1
- package/dist/openapi/json-schema-slot.js +38 -0
- package/dist/openapi/json-schema-slot.js.map +1 -0
- package/dist/openapi/register.d.ts.map +1 -1
- package/dist/openapi/register.js +20 -0
- package/dist/openapi/register.js.map +1 -0
- package/dist/openapi/scalar.d.ts +3 -1
- package/dist/openapi/scalar.d.ts.map +1 -1
- package/dist/openapi/scalar.js +21 -0
- package/dist/openapi/scalar.js.map +1 -0
- package/dist/openapi/serve.d.ts +9 -0
- package/dist/openapi/serve.d.ts.map +1 -0
- package/dist/openapi/serve.js +36 -0
- package/dist/openapi/serve.js.map +1 -0
- package/dist/openapi/spec-factory.d.ts +30 -1
- package/dist/openapi/spec-factory.d.ts.map +1 -1
- package/dist/openapi/spec-factory.js +52 -0
- package/dist/openapi/spec-factory.js.map +1 -0
- package/dist/openapi/spec.d.ts +14 -5
- package/dist/openapi/spec.d.ts.map +1 -1
- package/dist/openapi/spec.js +50 -0
- package/dist/openapi/spec.js.map +1 -0
- package/dist/openapi/swagger.d.ts +3 -1
- package/dist/openapi/swagger.d.ts.map +1 -1
- package/dist/openapi/swagger.js +22 -0
- package/dist/openapi/swagger.js.map +1 -0
- package/dist/pattern.d.ts +71 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +239 -0
- package/dist/pattern.js.map +1 -0
- package/dist/peer.d.ts +17 -0
- package/dist/peer.d.ts.map +1 -0
- package/dist/peer.js +50 -0
- package/dist/peer.js.map +1 -0
- package/dist/plugin.d.ts +67 -16
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +649 -0
- package/dist/plugin.js.map +1 -0
- package/dist/powered-by.d.ts.map +1 -1
- package/dist/powered-by.js +11 -0
- package/dist/powered-by.js.map +1 -0
- package/dist/pretty-json.d.ts.map +1 -1
- package/dist/pretty-json.js +47 -0
- package/dist/pretty-json.js.map +1 -0
- package/dist/producer-stream.d.ts +47 -0
- package/dist/producer-stream.d.ts.map +1 -0
- package/dist/producer-stream.js +267 -0
- package/dist/producer-stream.js.map +1 -0
- package/dist/proxy.d.ts +47 -8
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +274 -0
- package/dist/proxy.js.map +1 -0
- package/dist/python-type-emitter.d.ts +14 -1
- package/dist/python-type-emitter.d.ts.map +1 -1
- package/dist/python-type-emitter.js +157 -0
- package/dist/python-type-emitter.js.map +1 -0
- package/dist/realtime/bus.d.ts +17 -1
- package/dist/realtime/bus.d.ts.map +1 -1
- package/dist/realtime/bus.js +112 -0
- package/dist/realtime/bus.js.map +1 -0
- package/dist/realtime/register.d.ts +3 -0
- package/dist/realtime/register.d.ts.map +1 -0
- package/dist/realtime/register.js +10 -0
- package/dist/realtime/register.js.map +1 -0
- package/dist/realtime/route.d.ts +65 -26
- package/dist/realtime/route.d.ts.map +1 -1
- package/dist/realtime/route.js +72 -0
- package/dist/realtime/route.js.map +1 -0
- package/dist/realtime/server.d.ts +43 -0
- package/dist/realtime/server.d.ts.map +1 -0
- package/dist/realtime/server.js +255 -0
- package/dist/realtime/server.js.map +1 -0
- package/dist/request-id.d.ts +7 -0
- package/dist/request-id.d.ts.map +1 -1
- package/dist/request-id.js +16 -0
- package/dist/request-id.js.map +1 -0
- package/dist/request-limits.d.ts +3 -0
- package/dist/request-limits.d.ts.map +1 -0
- package/dist/request-limits.js +3 -0
- package/dist/request-limits.js.map +1 -0
- package/dist/request-path.d.ts +33 -0
- package/dist/request-path.d.ts.map +1 -0
- package/dist/request-path.js +178 -0
- package/dist/request-path.js.map +1 -0
- package/dist/request-to-curl.d.ts +7 -1
- package/dist/request-to-curl.d.ts.map +1 -1
- package/dist/request-to-curl.js +48 -0
- package/dist/request-to-curl.js.map +1 -0
- package/dist/response.d.ts +25 -2
- package/dist/response.d.ts.map +1 -1
- package/dist/response.js +313 -0
- package/dist/response.js.map +1 -0
- package/dist/rust-type-emitter.d.ts +14 -2
- package/dist/rust-type-emitter.d.ts.map +1 -1
- package/dist/rust-type-emitter.js +463 -0
- package/dist/rust-type-emitter.js.map +1 -0
- package/dist/secure-headers.d.ts.map +1 -1
- package/dist/secure-headers.js +53 -0
- package/dist/secure-headers.js.map +1 -0
- package/dist/serve-register.d.ts +4 -0
- package/dist/serve-register.d.ts.map +1 -1
- package/dist/serve-register.js +9 -0
- package/dist/serve-register.js.map +1 -0
- package/dist/serve-slot.d.ts +3 -0
- package/dist/serve-slot.d.ts.map +1 -1
- package/dist/serve-slot.js +52 -0
- package/dist/serve-slot.js.map +1 -0
- package/dist/serve.d.ts +18 -1
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +157 -0
- package/dist/serve.js.map +1 -0
- package/dist/server-timing.d.ts.map +1 -1
- package/dist/server-timing.js +51 -0
- package/dist/server-timing.js.map +1 -0
- package/dist/static.d.ts +9 -0
- package/dist/static.d.ts.map +1 -1
- package/dist/static.js +102 -0
- package/dist/static.js.map +1 -0
- package/dist/telemetry/otel.d.ts +2 -0
- package/dist/telemetry/otel.d.ts.map +1 -1
- package/dist/telemetry/otel.js +135 -0
- package/dist/telemetry/otel.js.map +1 -0
- package/dist/testing.d.ts +12 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +124 -0
- package/dist/testing.js.map +1 -0
- package/dist/timeout.d.ts +6 -0
- package/dist/timeout.d.ts.map +1 -1
- package/dist/timeout.js +36 -0
- package/dist/timeout.js.map +1 -0
- package/dist/tree.d.ts +133 -36
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +437 -0
- package/dist/tree.js.map +1 -0
- package/dist/trust.d.ts +21 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +100 -0
- package/dist/trust.js.map +1 -0
- package/dist/ts-type-emitter.d.ts.map +1 -1
- package/dist/ts-type-emitter.js +150 -0
- package/dist/ts-type-emitter.js.map +1 -0
- package/dist/type-emitter.d.ts +16 -2
- package/dist/type-emitter.d.ts.map +1 -1
- package/dist/type-emitter.js +729 -0
- package/dist/type-emitter.js.map +1 -0
- package/dist/type-extractor.d.ts +8 -4
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +819 -0
- package/dist/type-extractor.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +96 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +14 -2
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +335 -0
- package/dist/validation.js.map +1 -0
- package/dist/with-headers.d.ts +15 -0
- package/dist/with-headers.d.ts.map +1 -0
- package/dist/with-headers.js +45 -0
- package/dist/with-headers.js.map +1 -0
- package/dist/ws/bun.d.ts +11 -5
- package/dist/ws/bun.d.ts.map +1 -1
- package/dist/ws/bun.js +82 -0
- package/dist/ws/bun.js.map +1 -0
- package/dist/ws/cloudflare.d.ts +25 -3
- package/dist/ws/cloudflare.d.ts.map +1 -1
- package/dist/ws/cloudflare.js +117 -0
- package/dist/ws/cloudflare.js.map +1 -0
- package/dist/ws/deno.d.ts +4 -4
- package/dist/ws/deno.d.ts.map +1 -1
- package/dist/ws/deno.js +133 -0
- package/dist/ws/deno.js.map +1 -0
- package/dist/ws/node.d.ts +20 -3
- package/dist/ws/node.d.ts.map +1 -1
- package/dist/ws/node.js +173 -0
- package/dist/ws/node.js.map +1 -0
- package/dist/ws/session.d.ts +11 -0
- package/dist/ws/session.d.ts.map +1 -0
- package/dist/ws/session.js +60 -0
- package/dist/ws/session.js.map +1 -0
- package/dist/ws/shared.d.ts +65 -0
- package/dist/ws/shared.d.ts.map +1 -0
- package/dist/ws/shared.js +103 -0
- package/dist/ws/shared.js.map +1 -0
- package/dist/ws-origin.d.ts +20 -0
- package/dist/ws-origin.d.ts.map +1 -0
- package/dist/ws-origin.js +41 -0
- package/dist/ws-origin.js.map +1 -0
- package/dist/yaml.d.ts +15 -1
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +101 -0
- package/dist/yaml.js.map +1 -0
- package/docs/invalidate-spec.md +13 -1
- package/docs/meta-spec.md +36 -12
- package/docs/packaging.md +43 -24
- package/docs/regression-matrix/README.md +32 -0
- package/docs/regression-matrix/review.md +44 -0
- package/docs/regression-matrix/ws1-3.md +97 -0
- package/docs/regression-matrix/ws4-8.md +107 -0
- package/docs/regression-matrix/ws9-12.md +266 -0
- package/docs/sdk.md +102 -52
- package/package.json +183 -52
- package/src/accepts.ts +91 -33
- package/src/body-kind.ts +67 -0
- package/src/body-limit.ts +102 -87
- package/src/build/index.ts +104 -54
- package/src/cli-args.ts +123 -0
- package/src/cli-go/auth.go +12 -1
- package/src/cli-go/config.go +29 -2
- package/src/cli-go/errors.go +28 -10
- package/src/cli-go/multipart.go +51 -27
- package/src/cli-go/output.go +58 -4
- package/src/cli-go/root.go +1 -1
- package/src/cli-go/version.go +2 -2
- package/src/cli.ts +154 -148
- package/src/client/error.ts +56 -1
- package/src/client/http.ts +479 -256
- package/src/client/index.ts +55 -17
- package/src/client/path.ts +169 -0
- package/src/client/redirect-policy.ts +19 -0
- package/src/client/sdk.ts +180 -101
- package/src/client/sse.ts +92 -66
- package/src/client/ws.ts +67 -31
- package/src/client-go/errors.go +41 -12
- package/src/client-go/export.go +44 -0
- package/src/client-go/invalidation.go +52 -54
- package/src/client-go/nullable.go +62 -0
- package/src/client-go/realtime.go +147 -110
- package/src/client-go/runtime.go +646 -88
- package/src/client-go/sse.go +104 -94
- package/src/client-go/transport.go +67 -27
- package/src/client-go/ws.go +49 -25
- package/src/client-info.ts +79 -0
- package/src/client-mcp/server.ts +133 -3
- package/src/client-python/_invalidation.py +207 -291
- package/src/client-python/_realtime.py +63 -40
- package/src/client-python/_runtime.py +501 -119
- package/src/client-python/_sse.py +130 -74
- package/src/client-python/_transport.py +37 -9
- package/src/client-python/_ws.py +50 -22
- package/src/client-rust/errors.rs +21 -1
- package/src/client-rust/invalidation.rs +202 -231
- package/src/client-rust/invalidation_sync.rs +16 -229
- package/src/client-rust/nullable.rs +17 -0
- package/src/client-rust/realtime.rs +217 -217
- package/src/client-rust/runtime.rs +602 -177
- package/src/client-rust/runtime_sync.rs +169 -145
- package/src/client-rust/sse.rs +142 -121
- package/src/client-rust/ws.rs +61 -37
- package/src/codegen-go-cli.ts +607 -728
- package/src/codegen-go.ts +710 -770
- package/src/codegen-ir.ts +381 -75
- package/src/codegen-lang.ts +517 -0
- package/src/codegen-load.ts +150 -0
- package/src/codegen-mcp.ts +207 -108
- package/src/codegen-python.ts +684 -816
- package/src/codegen-route-tree-intern.ts +51 -25
- package/src/codegen-rust.ts +946 -1240
- package/src/codegen-sanitize.ts +0 -4
- package/src/codegen-schema-naming.ts +19 -6
- package/src/codegen-sdk-model.ts +228 -0
- package/src/codegen.ts +1488 -1140
- package/src/context.ts +130 -11
- package/src/cookie-sign.ts +85 -16
- package/src/cookie.ts +66 -11
- package/src/cors.ts +55 -54
- package/src/crypto.ts +27 -5
- package/src/csrf.ts +57 -25
- package/src/curl-logger.ts +155 -114
- package/src/dict.ts +12 -0
- package/src/error.ts +4 -2
- package/src/etag.ts +58 -34
- package/src/feature-detect.ts +147 -0
- package/src/feature-slots.ts +70 -0
- package/src/fetch-request.ts +13 -0
- package/src/gen-process.ts +42 -0
- package/src/gen-write.ts +127 -0
- package/src/glob.ts +109 -0
- package/src/go-type-emitter.ts +406 -155
- package/src/honey-response.ts +36 -9
- package/src/i18n-slot.ts +10 -0
- package/src/i18n.ts +98 -23
- package/src/index.ts +1887 -1756
- package/src/init.ts +40 -28
- package/src/invalidate-check.ts +42 -4
- package/src/invoke-user.ts +95 -0
- package/src/ip-restrict.ts +47 -161
- package/src/ip.ts +194 -0
- package/src/logger.ts +65 -36
- package/src/media-type.ts +104 -0
- package/src/meta-spec-merge.ts +80 -0
- package/src/meta-spec.ts +0 -0
- package/src/middleware.ts +112 -12
- package/src/node-request.ts +242 -52
- package/src/node.ts +318 -75
- package/src/openapi/collect.ts +19 -44
- package/src/openapi/docs-page.ts +89 -0
- package/src/openapi/document.ts +503 -224
- package/src/openapi/json-schema-slot.ts +40 -0
- package/src/openapi/register.ts +7 -2
- package/src/openapi/scalar.ts +11 -10
- package/src/openapi/serve.ts +39 -0
- package/src/openapi/spec-factory.ts +50 -1
- package/src/openapi/spec.ts +53 -30
- package/src/openapi/swagger.ts +12 -11
- package/src/pattern.ts +245 -0
- package/src/peer.ts +53 -0
- package/src/plugin.ts +270 -185
- package/src/powered-by.ts +2 -2
- package/src/pretty-json.ts +25 -9
- package/src/producer-stream.ts +296 -0
- package/src/proxy.ts +253 -55
- package/src/python-type-emitter.ts +68 -56
- package/src/realtime/bus.ts +56 -9
- package/src/realtime/register.ts +13 -0
- package/src/realtime/route.ts +129 -80
- package/src/realtime/server.ts +298 -0
- package/src/request-id.ts +13 -3
- package/src/request-limits.ts +2 -0
- package/src/request-path.ts +165 -0
- package/src/request-to-curl.ts +28 -7
- package/src/response.ts +143 -103
- package/src/rust-type-emitter.ts +265 -170
- package/src/secure-headers.ts +8 -4
- package/src/serve-register.ts +4 -0
- package/src/serve-slot.ts +38 -0
- package/src/serve.ts +113 -25
- package/src/server-timing.ts +11 -7
- package/src/static.ts +85 -32
- package/src/telemetry/otel.ts +29 -7
- package/src/testing.ts +76 -14
- package/src/timeout.ts +15 -7
- package/src/tree.ts +405 -333
- package/src/trust.ts +117 -0
- package/src/ts-type-emitter.ts +18 -12
- package/src/type-emitter.ts +227 -89
- package/src/type-extractor.ts +603 -423
- package/src/types.ts +8 -0
- package/src/validation.ts +221 -96
- package/src/with-headers.ts +45 -0
- package/src/ws/bun.ts +53 -15
- package/src/ws/cloudflare.ts +81 -19
- package/src/ws/deno.ts +124 -36
- package/src/ws/node.ts +173 -79
- package/src/ws/session.ts +73 -0
- package/src/ws/shared.ts +140 -0
- package/src/ws-origin.ts +53 -0
- package/src/yaml.ts +45 -22
- package/dist/client-mcp/server.d.ts +0 -10
- package/dist/client-mcp/server.d.ts.map +0 -1
- package/dist/client-mcp/types.d.ts +0 -16
- package/dist/client-mcp/types.d.ts.map +0 -1
- package/dist/cloudflare/realtime.d.ts +0 -30
- package/dist/cloudflare/realtime.d.ts.map +0 -1
- package/dist/realtime/buffer.d.ts +0 -18
- package/dist/realtime/buffer.d.ts.map +0 -1
- package/dist/realtime/longpoll.d.ts +0 -23
- package/dist/realtime/longpoll.d.ts.map +0 -1
- package/dist/realtime/protocol.d.ts +0 -50
- package/dist/realtime/protocol.d.ts.map +0 -1
- package/dist/realtime/runtime.d.ts +0 -74
- package/dist/realtime/runtime.d.ts.map +0 -1
- package/src/cloudflare/realtime.ts +0 -234
- package/src/realtime/buffer.ts +0 -101
- package/src/realtime/longpoll.ts +0 -148
- package/src/realtime/protocol.ts +0 -128
- package/src/realtime/runtime.ts +0 -427
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// Code generated by honey. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
package sdk
|
|
4
|
+
|
|
5
|
+
import (
|
|
6
|
+
"bufio"
|
|
7
|
+
"context"
|
|
8
|
+
"errors"
|
|
9
|
+
"io"
|
|
10
|
+
"iter"
|
|
11
|
+
"net/http"
|
|
12
|
+
"strconv"
|
|
13
|
+
"strings"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
// SSEEvent represents a single server-sent event. ID is the last event ID seen
|
|
17
|
+
// on the stream so far (the spec's sticky "last event ID buffer").
|
|
18
|
+
type SSEEvent struct {
|
|
19
|
+
Data string
|
|
20
|
+
Event string
|
|
21
|
+
ID string
|
|
22
|
+
Retry int
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// sseMaxLine caps one line, and sseMaxEvent the data of one event.
|
|
26
|
+
const (
|
|
27
|
+
sseMaxLine = 1024 * 1024
|
|
28
|
+
sseMaxEvent = 8 * 1024 * 1024
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
// ErrSSELineTooLong is returned when a single SSE line exceeds the cap.
|
|
32
|
+
var ErrSSELineTooLong = errors.New("honey: sse line exceeds 1 MiB")
|
|
33
|
+
|
|
34
|
+
// parseSSEStream returns an iter.Seq2 that yields SSEEvent values read from resp.Body.
|
|
35
|
+
// On non-2xx response it yields a typed error immediately then terminates.
|
|
36
|
+
// The response body is closed when the iterator returns.
|
|
37
|
+
func parseSSEStream(ctx context.Context, resp *http.Response) iter.Seq2[SSEEvent, error] {
|
|
38
|
+
return func(yield func(SSEEvent, error) bool) {
|
|
39
|
+
defer resp.Body.Close()
|
|
40
|
+
|
|
41
|
+
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
|
42
|
+
body, _ := readBody(resp.Body, 64<<10)
|
|
43
|
+
yield(SSEEvent{}, raiseForStatus(resp, body))
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
for ev, err := range parseSSE(resp.Body) {
|
|
48
|
+
if ctx.Err() != nil {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
if !yield(ev, err) || err != nil {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// parseSSE implements the WHATWG event-stream parser: lines end in CRLF, LF or
|
|
59
|
+
// CR; a blank line dispatches; a final event without its blank line is
|
|
60
|
+
// discarded; the id is sticky across events; retry needs only ASCII digits.
|
|
61
|
+
func parseSSE(r io.Reader) iter.Seq2[SSEEvent, error] {
|
|
62
|
+
return func(yield func(SSEEvent, error) bool) {
|
|
63
|
+
br := bufio.NewReaderSize(r, 64*1024)
|
|
64
|
+
var (
|
|
65
|
+
data strings.Builder
|
|
66
|
+
hasData bool
|
|
67
|
+
event string
|
|
68
|
+
lastID string
|
|
69
|
+
retry int
|
|
70
|
+
firstLine = true
|
|
71
|
+
)
|
|
72
|
+
for {
|
|
73
|
+
line, err := readSSELine(br)
|
|
74
|
+
if err != nil {
|
|
75
|
+
if !errors.Is(err, io.EOF) {
|
|
76
|
+
yield(SSEEvent{}, err)
|
|
77
|
+
}
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
if firstLine {
|
|
81
|
+
line = strings.TrimPrefix(line, string(rune(0xFEFF)))
|
|
82
|
+
firstLine = false
|
|
83
|
+
}
|
|
84
|
+
if line == "" {
|
|
85
|
+
if hasData {
|
|
86
|
+
ev := SSEEvent{Data: data.String(), Event: event, ID: lastID, Retry: retry}
|
|
87
|
+
if !yield(ev, nil) {
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
data.Reset()
|
|
92
|
+
hasData = false
|
|
93
|
+
event = ""
|
|
94
|
+
retry = 0
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
97
|
+
if strings.HasPrefix(line, ":") {
|
|
98
|
+
continue
|
|
99
|
+
}
|
|
100
|
+
field, value := line, ""
|
|
101
|
+
if i := strings.IndexByte(line, ':'); i >= 0 {
|
|
102
|
+
field, value = line[:i], strings.TrimPrefix(line[i+1:], " ")
|
|
103
|
+
}
|
|
104
|
+
switch field {
|
|
105
|
+
case "data":
|
|
106
|
+
if hasData {
|
|
107
|
+
data.WriteByte('\n')
|
|
108
|
+
}
|
|
109
|
+
if data.Len()+len(value) > sseMaxEvent {
|
|
110
|
+
yield(SSEEvent{}, errors.New("honey: sse event exceeds 8 MiB"))
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
data.WriteString(value)
|
|
114
|
+
hasData = true
|
|
115
|
+
case "event":
|
|
116
|
+
event = value
|
|
117
|
+
case "id":
|
|
118
|
+
if !strings.ContainsRune(value, 0) {
|
|
119
|
+
lastID = value
|
|
120
|
+
}
|
|
121
|
+
case "retry":
|
|
122
|
+
if value != "" && strings.Trim(value, "0123456789") == "" {
|
|
123
|
+
if n, convErr := strconv.Atoi(value); convErr == nil {
|
|
124
|
+
retry = n
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// readSSELine reads one line without its terminator. A CR may be followed by
|
|
133
|
+
// an LF that belongs to the same terminator. io.EOF is returned only when no
|
|
134
|
+
// complete line remains, so a truncated final line is never parsed.
|
|
135
|
+
func readSSELine(br *bufio.Reader) (string, error) {
|
|
136
|
+
var b strings.Builder
|
|
137
|
+
for {
|
|
138
|
+
c, err := br.ReadByte()
|
|
139
|
+
if err != nil {
|
|
140
|
+
if errors.Is(err, io.EOF) {
|
|
141
|
+
return "", io.EOF
|
|
142
|
+
}
|
|
143
|
+
return "", err
|
|
144
|
+
}
|
|
145
|
+
switch c {
|
|
146
|
+
case '\n':
|
|
147
|
+
return b.String(), nil
|
|
148
|
+
case '\r':
|
|
149
|
+
if next, peekErr := br.Peek(1); peekErr == nil && next[0] == '\n' {
|
|
150
|
+
_, _ = br.ReadByte()
|
|
151
|
+
}
|
|
152
|
+
return b.String(), nil
|
|
153
|
+
}
|
|
154
|
+
if b.Len() >= sseMaxLine {
|
|
155
|
+
return "", ErrSSELineTooLong
|
|
156
|
+
}
|
|
157
|
+
b.WriteByte(c)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
// Code generated by honey. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
package sdk
|
|
4
|
+
|
|
5
|
+
import (
|
|
6
|
+
"context"
|
|
7
|
+
"encoding/json"
|
|
8
|
+
"errors"
|
|
9
|
+
"fmt"
|
|
10
|
+
"io"
|
|
11
|
+
"net/http"
|
|
12
|
+
"net/url"
|
|
13
|
+
"strings"
|
|
14
|
+
"sync"
|
|
15
|
+
"time"
|
|
16
|
+
|
|
17
|
+
"nhooyr.io/websocket"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
// TransportKind tags which transport a connection was opened with.
|
|
21
|
+
// Mirrors Rust TransportKind / Python TransportKind.
|
|
22
|
+
type TransportKind string
|
|
23
|
+
|
|
24
|
+
const (
|
|
25
|
+
TransportWs TransportKind = "ws"
|
|
26
|
+
TransportSse TransportKind = "sse"
|
|
27
|
+
TransportLongpoll TransportKind = "longpoll"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
// TransportOpts is handed to each Transport.Connect call. Mirrors the TS
|
|
31
|
+
// TransportOpts plus per-language extras (HTTPClient for SSE/longpoll dial).
|
|
32
|
+
//
|
|
33
|
+
// MaxMessageBytes caps one inbound WebSocket message (zero means 16 MiB).
|
|
34
|
+
// PollTimeout bounds one long-poll request (zero means 60s).
|
|
35
|
+
type TransportOpts struct {
|
|
36
|
+
ReconnectToken string
|
|
37
|
+
LastEventID string
|
|
38
|
+
Headers http.Header
|
|
39
|
+
MaxReconnectAttempts int
|
|
40
|
+
ReconnectDelayMs int
|
|
41
|
+
Protocols []string
|
|
42
|
+
HTTPClient *http.Client
|
|
43
|
+
MaxMessageBytes int64
|
|
44
|
+
PollTimeout time.Duration
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const (
|
|
48
|
+
defaultMaxMessageBytes = 16 << 20
|
|
49
|
+
defaultPollTimeout = 60 * time.Second
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
func (o *TransportOpts) maxMessageBytes() int64 {
|
|
53
|
+
if o == nil || o.MaxMessageBytes <= 0 {
|
|
54
|
+
return defaultMaxMessageBytes
|
|
55
|
+
}
|
|
56
|
+
return o.MaxMessageBytes
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// TransportConn is the live per-transport connection object. Each built-in
|
|
60
|
+
// adapter returns its own impl (wsConn, sseConn, longpollConn). Recv returns
|
|
61
|
+
// decoded JSON (map[string]any, []any, string, number, bool) or raw string
|
|
62
|
+
// fallback when the payload is not JSON.
|
|
63
|
+
type TransportConn interface {
|
|
64
|
+
Recv(ctx context.Context) (any, error)
|
|
65
|
+
Send(ctx context.Context, data any) error
|
|
66
|
+
Close() error
|
|
67
|
+
Kind() TransportKind
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Transport is the pluggable adapter interface. Consumers swap in their own
|
|
71
|
+
// WS/SSE/longpoll impls by implementing this. Mirrors Rust trait Transport
|
|
72
|
+
// and Python TransportAdapter Protocol.
|
|
73
|
+
type Transport interface {
|
|
74
|
+
Name() string
|
|
75
|
+
Kind() TransportKind
|
|
76
|
+
Connect(ctx context.Context, url string, opts *TransportOpts) (TransportConn, error)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* errTransportNotImplemented remains as a transitional sentinel from the 8.b.3
|
|
80
|
+
* stub phase. Real Connect bodies below no longer return it; kept to avoid
|
|
81
|
+
* breaking any consumer that wrote defensive errors.Is checks. Removal deferred
|
|
82
|
+
* to 8.d cleanup. */
|
|
83
|
+
var errTransportNotImplemented = errors.New("honey: transport adapter Connect not implemented")
|
|
84
|
+
|
|
85
|
+
/* ───────────────────────── WebSocket adapter ───────────────────────── */
|
|
86
|
+
|
|
87
|
+
// WsTransport is the default WebSocket adapter. Wraps nhooyr.io/websocket.
|
|
88
|
+
type WsTransport struct {
|
|
89
|
+
Subprotocols []string
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Name returns "ws".
|
|
93
|
+
func (t *WsTransport) Name() string { return "ws" }
|
|
94
|
+
|
|
95
|
+
// Kind returns TransportWs.
|
|
96
|
+
func (t *WsTransport) Kind() TransportKind { return TransportWs }
|
|
97
|
+
|
|
98
|
+
// Connect dials the WebSocket endpoint. Auth + resume tokens ride as query
|
|
99
|
+
// params on the URL; protocols + headers come from opts. Returned conn is a
|
|
100
|
+
// *wsConn satisfying TransportConn.
|
|
101
|
+
func (t *WsTransport) Connect(ctx context.Context, rawURL string, opts *TransportOpts) (TransportConn, error) {
|
|
102
|
+
wsURL := toWsURL(rawURL)
|
|
103
|
+
if opts != nil {
|
|
104
|
+
q := url.Values{}
|
|
105
|
+
if opts.ReconnectToken != "" {
|
|
106
|
+
q.Set("reconnect_token", opts.ReconnectToken)
|
|
107
|
+
}
|
|
108
|
+
if opts.LastEventID != "" {
|
|
109
|
+
q.Set("last_event_id", opts.LastEventID)
|
|
110
|
+
}
|
|
111
|
+
if len(q) > 0 {
|
|
112
|
+
sep := "?"
|
|
113
|
+
if strings.Contains(wsURL, "?") {
|
|
114
|
+
sep = "&"
|
|
115
|
+
}
|
|
116
|
+
wsURL = wsURL + sep + q.Encode()
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
dialOpts := &websocket.DialOptions{}
|
|
120
|
+
if opts != nil {
|
|
121
|
+
if len(opts.Protocols) > 0 {
|
|
122
|
+
dialOpts.Subprotocols = opts.Protocols
|
|
123
|
+
}
|
|
124
|
+
if len(opts.Headers) > 0 {
|
|
125
|
+
dialOpts.HTTPHeader = opts.Headers.Clone()
|
|
126
|
+
}
|
|
127
|
+
dialOpts.HTTPClient = opts.HTTPClient
|
|
128
|
+
}
|
|
129
|
+
if dialOpts.Subprotocols == nil && len(t.Subprotocols) > 0 {
|
|
130
|
+
dialOpts.Subprotocols = t.Subprotocols
|
|
131
|
+
}
|
|
132
|
+
conn, _, err := websocket.Dial(ctx, wsURL, dialOpts)
|
|
133
|
+
if err != nil {
|
|
134
|
+
return nil, err
|
|
135
|
+
}
|
|
136
|
+
conn.SetReadLimit(opts.maxMessageBytes())
|
|
137
|
+
return &wsConn{conn: conn}, nil
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
type wsConn struct {
|
|
141
|
+
conn *websocket.Conn
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
func (c *wsConn) Kind() TransportKind { return TransportWs }
|
|
145
|
+
|
|
146
|
+
func (c *wsConn) Recv(ctx context.Context) (any, error) {
|
|
147
|
+
_, data, err := c.conn.Read(ctx)
|
|
148
|
+
if err != nil {
|
|
149
|
+
return nil, err
|
|
150
|
+
}
|
|
151
|
+
var v any
|
|
152
|
+
if jsonErr := json.Unmarshal(data, &v); jsonErr != nil {
|
|
153
|
+
/* non-JSON payload — fall through to raw string (matches Python decode). */
|
|
154
|
+
return string(data), nil
|
|
155
|
+
}
|
|
156
|
+
return v, nil
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
func (c *wsConn) Send(ctx context.Context, data any) error {
|
|
160
|
+
switch v := data.(type) {
|
|
161
|
+
case []byte:
|
|
162
|
+
return c.conn.Write(ctx, websocket.MessageBinary, v)
|
|
163
|
+
case string:
|
|
164
|
+
return c.conn.Write(ctx, websocket.MessageText, []byte(v))
|
|
165
|
+
default:
|
|
166
|
+
encoded, err := json.Marshal(v)
|
|
167
|
+
if err != nil {
|
|
168
|
+
return err
|
|
169
|
+
}
|
|
170
|
+
return c.conn.Write(ctx, websocket.MessageText, encoded)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
func (c *wsConn) Close() error {
|
|
175
|
+
return c.conn.Close(websocket.StatusNormalClosure, "client close")
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// toWsURL swaps the scheme only; a URL inside the query string is untouched.
|
|
179
|
+
func toWsURL(u string) string {
|
|
180
|
+
if strings.HasPrefix(u, "https://") {
|
|
181
|
+
return "wss://" + u[len("https://"):]
|
|
182
|
+
}
|
|
183
|
+
if strings.HasPrefix(u, "http://") {
|
|
184
|
+
return "ws://" + u[len("http://"):]
|
|
185
|
+
}
|
|
186
|
+
return u
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* ────────────────────────────── SSE adapter ────────────────────────────── */
|
|
190
|
+
|
|
191
|
+
// SseTransport is the default SSE adapter. Uses net/http streaming GET via
|
|
192
|
+
// parseSSEStream. A background goroutine bridges the iterator to a Recv channel
|
|
193
|
+
// so ResumableConnection.Recv has uniform blocking semantics across transports.
|
|
194
|
+
type SseTransport struct {
|
|
195
|
+
HTTPClient *http.Client
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Name returns "sse".
|
|
199
|
+
func (t *SseTransport) Name() string { return "sse" }
|
|
200
|
+
|
|
201
|
+
// Kind returns TransportSse.
|
|
202
|
+
func (t *SseTransport) Kind() TransportKind { return TransportSse }
|
|
203
|
+
|
|
204
|
+
// Connect opens the SSE byte stream. Reconnect token rides as a query param;
|
|
205
|
+
// Last-Event-ID rides as a request header (HTML spec).
|
|
206
|
+
func (t *SseTransport) Connect(ctx context.Context, rawURL string, opts *TransportOpts) (TransportConn, error) {
|
|
207
|
+
client := t.HTTPClient
|
|
208
|
+
if opts != nil && opts.HTTPClient != nil {
|
|
209
|
+
client = opts.HTTPClient
|
|
210
|
+
}
|
|
211
|
+
if client == nil {
|
|
212
|
+
client = http.DefaultClient
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
u := rawURL
|
|
216
|
+
if opts != nil && opts.ReconnectToken != "" {
|
|
217
|
+
sep := "?"
|
|
218
|
+
if strings.Contains(u, "?") {
|
|
219
|
+
sep = "&"
|
|
220
|
+
}
|
|
221
|
+
u = u + sep + "reconnect_token=" + url.QueryEscape(opts.ReconnectToken)
|
|
222
|
+
}
|
|
223
|
+
/* ctx bounds the open only; the stream lives until Close cancels streamCtx */
|
|
224
|
+
streamCtx, cancel := context.WithCancel(context.Background())
|
|
225
|
+
stop := context.AfterFunc(ctx, cancel)
|
|
226
|
+
req, err := http.NewRequestWithContext(streamCtx, "GET", u, nil)
|
|
227
|
+
if err != nil {
|
|
228
|
+
stop()
|
|
229
|
+
cancel()
|
|
230
|
+
return nil, err
|
|
231
|
+
}
|
|
232
|
+
req.Header.Set("Accept", "text/event-stream")
|
|
233
|
+
if opts != nil {
|
|
234
|
+
for k, vv := range opts.Headers {
|
|
235
|
+
for _, v := range vv {
|
|
236
|
+
req.Header.Add(k, v)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if opts.LastEventID != "" {
|
|
240
|
+
req.Header.Set("Last-Event-ID", opts.LastEventID)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if req.Header.Get("X-Request-Id") == "" {
|
|
244
|
+
req.Header.Set("X-Request-Id", newUUIDv4())
|
|
245
|
+
}
|
|
246
|
+
resp, err := client.Do(req)
|
|
247
|
+
opened := stop()
|
|
248
|
+
if err != nil {
|
|
249
|
+
cancel()
|
|
250
|
+
return nil, err
|
|
251
|
+
}
|
|
252
|
+
if !opened {
|
|
253
|
+
/* ctx ended while the headers arrived */
|
|
254
|
+
_ = resp.Body.Close()
|
|
255
|
+
cancel()
|
|
256
|
+
return nil, ctx.Err()
|
|
257
|
+
}
|
|
258
|
+
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
|
259
|
+
_ = resp.Body.Close()
|
|
260
|
+
cancel()
|
|
261
|
+
return nil, fmt.Errorf("honey: sse transport: status %d", resp.StatusCode)
|
|
262
|
+
}
|
|
263
|
+
if ct := resp.Header.Get("Content-Type"); !strings.HasPrefix(strings.ToLower(ct), "text/event-stream") {
|
|
264
|
+
_ = resp.Body.Close()
|
|
265
|
+
cancel()
|
|
266
|
+
return nil, fmt.Errorf("honey: sse transport: unexpected content type %q", ct)
|
|
267
|
+
}
|
|
268
|
+
sc := &sseConn{
|
|
269
|
+
resp: resp,
|
|
270
|
+
next: make(chan sseResult, 1),
|
|
271
|
+
done: make(chan struct{}),
|
|
272
|
+
cancel: cancel,
|
|
273
|
+
}
|
|
274
|
+
go sc.run(streamCtx)
|
|
275
|
+
return sc, nil
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
type sseResult struct {
|
|
279
|
+
value any
|
|
280
|
+
err error
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
type sseConn struct {
|
|
284
|
+
resp *http.Response
|
|
285
|
+
next chan sseResult
|
|
286
|
+
done chan struct{}
|
|
287
|
+
cancel context.CancelFunc
|
|
288
|
+
mu sync.Mutex
|
|
289
|
+
closed bool
|
|
290
|
+
once sync.Once
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
func (c *sseConn) Kind() TransportKind { return TransportSse }
|
|
294
|
+
|
|
295
|
+
func (c *sseConn) run(ctx context.Context) {
|
|
296
|
+
defer c.finish()
|
|
297
|
+
for ev, err := range parseSSEStream(ctx, c.resp) {
|
|
298
|
+
select {
|
|
299
|
+
case <-c.done:
|
|
300
|
+
return
|
|
301
|
+
default:
|
|
302
|
+
}
|
|
303
|
+
if err != nil {
|
|
304
|
+
select {
|
|
305
|
+
case c.next <- sseResult{err: err}:
|
|
306
|
+
case <-c.done:
|
|
307
|
+
}
|
|
308
|
+
return
|
|
309
|
+
}
|
|
310
|
+
var v any
|
|
311
|
+
if jsonErr := json.Unmarshal([]byte(ev.Data), &v); jsonErr != nil {
|
|
312
|
+
v = ev.Data
|
|
313
|
+
}
|
|
314
|
+
select {
|
|
315
|
+
case c.next <- sseResult{value: v}:
|
|
316
|
+
case <-c.done:
|
|
317
|
+
return
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
func (c *sseConn) finish() {
|
|
323
|
+
c.mu.Lock()
|
|
324
|
+
defer c.mu.Unlock()
|
|
325
|
+
if c.closed {
|
|
326
|
+
return
|
|
327
|
+
}
|
|
328
|
+
c.closed = true
|
|
329
|
+
close(c.next)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
func (c *sseConn) Recv(ctx context.Context) (any, error) {
|
|
333
|
+
select {
|
|
334
|
+
case r, ok := <-c.next:
|
|
335
|
+
if !ok {
|
|
336
|
+
return nil, io.EOF
|
|
337
|
+
}
|
|
338
|
+
return r.value, r.err
|
|
339
|
+
case <-ctx.Done():
|
|
340
|
+
return nil, ctx.Err()
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
func (c *sseConn) Send(ctx context.Context, data any) error {
|
|
345
|
+
return errors.New("honey: sse transport is receive-only")
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
func (c *sseConn) Close() error {
|
|
349
|
+
c.once.Do(func() {
|
|
350
|
+
close(c.done)
|
|
351
|
+
c.cancel()
|
|
352
|
+
})
|
|
353
|
+
return c.resp.Body.Close()
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/* ──────────────────────────── Longpoll adapter ─────────────────────────── */
|
|
357
|
+
|
|
358
|
+
// LongpollTransport is the default long-poll adapter. Each Recv fires a GET
|
|
359
|
+
// against the configured URL with cursor query params and blocks until the
|
|
360
|
+
// server replies. Payloads that look like JSON objects have their
|
|
361
|
+
// reconnect_token / id / last_event_id fields harvested to advance the cursor.
|
|
362
|
+
type LongpollTransport struct {
|
|
363
|
+
HTTPClient *http.Client
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Name returns "longpoll".
|
|
367
|
+
func (t *LongpollTransport) Name() string { return "longpoll" }
|
|
368
|
+
|
|
369
|
+
// Kind returns TransportLongpoll.
|
|
370
|
+
func (t *LongpollTransport) Kind() TransportKind { return TransportLongpoll }
|
|
371
|
+
|
|
372
|
+
// Connect constructs the longpoll conn; no wire traffic until first Recv.
|
|
373
|
+
func (t *LongpollTransport) Connect(ctx context.Context, rawURL string, opts *TransportOpts) (TransportConn, error) {
|
|
374
|
+
client := t.HTTPClient
|
|
375
|
+
if opts != nil && opts.HTTPClient != nil {
|
|
376
|
+
client = opts.HTTPClient
|
|
377
|
+
}
|
|
378
|
+
if client == nil {
|
|
379
|
+
client = http.DefaultClient
|
|
380
|
+
}
|
|
381
|
+
lp := &longpollConn{
|
|
382
|
+
client: client,
|
|
383
|
+
url: rawURL,
|
|
384
|
+
headers: http.Header{},
|
|
385
|
+
pollTimeout: defaultPollTimeout,
|
|
386
|
+
}
|
|
387
|
+
if opts != nil && opts.PollTimeout > 0 {
|
|
388
|
+
lp.pollTimeout = opts.PollTimeout
|
|
389
|
+
}
|
|
390
|
+
if opts != nil {
|
|
391
|
+
lp.reconnectToken = opts.ReconnectToken
|
|
392
|
+
lp.lastEventID = opts.LastEventID
|
|
393
|
+
if opts.Headers != nil {
|
|
394
|
+
lp.headers = opts.Headers.Clone()
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return lp, nil
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
type longpollConn struct {
|
|
401
|
+
pollTimeout time.Duration
|
|
402
|
+
client *http.Client
|
|
403
|
+
url string
|
|
404
|
+
headers http.Header
|
|
405
|
+
reconnectToken string
|
|
406
|
+
lastEventID string
|
|
407
|
+
mu sync.Mutex
|
|
408
|
+
closed bool
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
func (c *longpollConn) Kind() TransportKind { return TransportLongpoll }
|
|
412
|
+
|
|
413
|
+
func (c *longpollConn) Recv(ctx context.Context) (any, error) {
|
|
414
|
+
c.mu.Lock()
|
|
415
|
+
if c.closed {
|
|
416
|
+
c.mu.Unlock()
|
|
417
|
+
return nil, io.EOF
|
|
418
|
+
}
|
|
419
|
+
token := c.reconnectToken
|
|
420
|
+
lastID := c.lastEventID
|
|
421
|
+
headers := c.headers
|
|
422
|
+
c.mu.Unlock()
|
|
423
|
+
|
|
424
|
+
q := url.Values{}
|
|
425
|
+
if token != "" {
|
|
426
|
+
q.Set("reconnect_token", token)
|
|
427
|
+
}
|
|
428
|
+
if lastID != "" {
|
|
429
|
+
q.Set("last_event_id", lastID)
|
|
430
|
+
}
|
|
431
|
+
u := c.url
|
|
432
|
+
if len(q) > 0 {
|
|
433
|
+
sep := "?"
|
|
434
|
+
if strings.Contains(u, "?") {
|
|
435
|
+
sep = "&"
|
|
436
|
+
}
|
|
437
|
+
u = u + sep + q.Encode()
|
|
438
|
+
}
|
|
439
|
+
pollCtx, cancel := context.WithTimeout(ctx, c.pollTimeout)
|
|
440
|
+
defer cancel()
|
|
441
|
+
req, err := http.NewRequestWithContext(pollCtx, "GET", u, nil)
|
|
442
|
+
if err != nil {
|
|
443
|
+
return nil, err
|
|
444
|
+
}
|
|
445
|
+
for k, vv := range headers {
|
|
446
|
+
for _, v := range vv {
|
|
447
|
+
req.Header.Add(k, v)
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
resp, err := c.client.Do(req)
|
|
451
|
+
if err != nil {
|
|
452
|
+
return nil, err
|
|
453
|
+
}
|
|
454
|
+
defer resp.Body.Close()
|
|
455
|
+
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
|
456
|
+
return nil, fmt.Errorf("honey: longpoll transport: status %d", resp.StatusCode)
|
|
457
|
+
}
|
|
458
|
+
body, err := readBody(resp.Body, defaultMaxMessageBytes)
|
|
459
|
+
if err != nil {
|
|
460
|
+
return nil, err
|
|
461
|
+
}
|
|
462
|
+
var v any
|
|
463
|
+
if jsonErr := json.Unmarshal(body, &v); jsonErr != nil {
|
|
464
|
+
v = string(body)
|
|
465
|
+
}
|
|
466
|
+
if m, ok := v.(map[string]any); ok {
|
|
467
|
+
c.mu.Lock()
|
|
468
|
+
if tok, ok := m["reconnect_token"].(string); ok {
|
|
469
|
+
c.reconnectToken = tok
|
|
470
|
+
}
|
|
471
|
+
if id, ok := m["id"].(string); ok {
|
|
472
|
+
c.lastEventID = id
|
|
473
|
+
}
|
|
474
|
+
if id, ok := m["last_event_id"].(string); ok {
|
|
475
|
+
c.lastEventID = id
|
|
476
|
+
}
|
|
477
|
+
c.mu.Unlock()
|
|
478
|
+
}
|
|
479
|
+
return v, nil
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
func (c *longpollConn) Send(ctx context.Context, data any) error {
|
|
483
|
+
return errors.New("honey: longpoll transport is receive-only")
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
func (c *longpollConn) Close() error {
|
|
487
|
+
c.mu.Lock()
|
|
488
|
+
c.closed = true
|
|
489
|
+
c.mu.Unlock()
|
|
490
|
+
return nil
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/* internal sentinel used by tests; exported-like lowercase to keep public
|
|
494
|
+
* surface unchanged from 8.b.3. */
|
|
495
|
+
var _ = errTransportNotImplemented
|