@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,484 @@
|
|
|
1
|
+
/* Code generated by honey. DO NOT EDIT. */
|
|
2
|
+
|
|
3
|
+
#![allow(dead_code)]
|
|
4
|
+
|
|
5
|
+
/* WARNING: reqwest::blocking::Client WILL deadlock if called from inside a tokio async task.
|
|
6
|
+
Only use SyncClient and do_request_blocking from non-async contexts (e.g. plain threads,
|
|
7
|
+
test harnesses, CLI tools). Never call blocking methods from within an async runtime. */
|
|
8
|
+
|
|
9
|
+
use crate::errors::{raise_for_status, Error};
|
|
10
|
+
use crate::runtime::{build_url, encode_query, merged_headers, set_header, LogEntry, OnLogHook};
|
|
11
|
+
use std::collections::HashMap;
|
|
12
|
+
use std::sync::atomic::{AtomicBool, Ordering};
|
|
13
|
+
use std::sync::{Arc, Mutex};
|
|
14
|
+
use std::time::Duration;
|
|
15
|
+
|
|
16
|
+
/// SyncOnRequestHook is a synchronous (non-async) request hook.
|
|
17
|
+
/// Returns Result<(), Error> directly — no Future, no Pin<Box<...>>.
|
|
18
|
+
pub type SyncOnRequestHook =
|
|
19
|
+
Arc<dyn Fn(&mut SyncRequestContext) -> Result<(), Error> + Send + Sync>;
|
|
20
|
+
|
|
21
|
+
/// SyncOnResponseHook is a synchronous (non-async) response hook.
|
|
22
|
+
pub type SyncOnResponseHook =
|
|
23
|
+
Arc<dyn Fn(&mut SyncResponseContext) -> Result<(), Error> + Send + Sync>;
|
|
24
|
+
|
|
25
|
+
/// SyncRequestContext carries mutable request metadata through SyncOnRequestHook invocations.
|
|
26
|
+
/// `selector` / `is_stale` / `invalidated_by` mirror the async RequestContext fields.
|
|
27
|
+
pub struct SyncRequestContext {
|
|
28
|
+
pub method: reqwest::Method,
|
|
29
|
+
pub url: String,
|
|
30
|
+
pub path: String,
|
|
31
|
+
pub headers: HashMap<String, String>,
|
|
32
|
+
/// `SyncClientConfig::state`, shared by every hook of every call; a fresh map per call when unset.
|
|
33
|
+
pub state: Arc<std::sync::Mutex<HashMap<String, serde_json::Value>>>,
|
|
34
|
+
pub is_retry: bool,
|
|
35
|
+
pub selector: String,
|
|
36
|
+
pub is_stale: bool,
|
|
37
|
+
pub invalidated_by: Vec<String>,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// SyncResponseContext carries response metadata through SyncOnResponseHook invocations.
|
|
41
|
+
pub struct SyncResponseContext {
|
|
42
|
+
pub status: u16,
|
|
43
|
+
pub response: Vec<u8>,
|
|
44
|
+
pub headers: reqwest::header::HeaderMap,
|
|
45
|
+
/// The same map the request hooks saw.
|
|
46
|
+
pub state: Arc<std::sync::Mutex<HashMap<String, serde_json::Value>>>,
|
|
47
|
+
pub is_retry: bool,
|
|
48
|
+
pub selector: String,
|
|
49
|
+
pub is_stale: bool,
|
|
50
|
+
pub invalidated_by: Vec<String>,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/// SyncRequestBody represents the different body types a blocking request can carry.
|
|
54
|
+
/// `Multipart` and `Stream` own single-shot bodies and are not retried on 401.
|
|
55
|
+
pub enum SyncRequestBody<'a> {
|
|
56
|
+
None,
|
|
57
|
+
Json(&'a serde_json::Value),
|
|
58
|
+
FormUrl(Vec<(String, String)>),
|
|
59
|
+
Raw(&'static str, bytes::Bytes),
|
|
60
|
+
Multipart(reqwest::blocking::multipart::Form),
|
|
61
|
+
Stream(reqwest::blocking::Body),
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/// SyncClientConfig holds all configuration for the blocking SDK client.
|
|
65
|
+
/// Same semantics as [`crate::runtime::ClientConfig`].
|
|
66
|
+
#[derive(Clone)]
|
|
67
|
+
pub struct SyncClientConfig {
|
|
68
|
+
pub base_url: String,
|
|
69
|
+
pub bearer_token: Option<String>,
|
|
70
|
+
pub headers: HashMap<String, String>,
|
|
71
|
+
pub timeout: Duration,
|
|
72
|
+
/// Ignored at runtime: whether methods return `SdkResult` is fixed when the SDK is generated.
|
|
73
|
+
#[deprecated(note = "has no effect; generate with `throwOnError: false` for SdkResult methods")]
|
|
74
|
+
pub throw_on_error: bool,
|
|
75
|
+
/// Fallback for `InvalidationConfig::stale_max_entries` when that is 0.
|
|
76
|
+
pub stale_max_entries: usize,
|
|
77
|
+
pub invalidation: Option<crate::runtime::InvalidationConfig>,
|
|
78
|
+
/// Returns the new token; an empty string means "give up".
|
|
79
|
+
pub on_auth_expired:
|
|
80
|
+
Option<Arc<dyn Fn() -> Result<String, Error> + Send + Sync>>,
|
|
81
|
+
pub http_client: Option<reqwest::blocking::Client>,
|
|
82
|
+
pub auth_header_name: Option<String>,
|
|
83
|
+
pub auth_header_prefix: Option<String>,
|
|
84
|
+
pub on_request: Vec<SyncOnRequestHook>,
|
|
85
|
+
pub on_response: Vec<SyncOnResponseHook>,
|
|
86
|
+
pub on_log: Option<OnLogHook>,
|
|
87
|
+
/// Shared state handed to every `on_request` / `on_response` hook (`ctx.state`).
|
|
88
|
+
pub state: Option<Arc<std::sync::Mutex<HashMap<String, serde_json::Value>>>>,
|
|
89
|
+
pub max_response_bytes: usize,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
#[allow(deprecated)]
|
|
93
|
+
impl Default for SyncClientConfig {
|
|
94
|
+
fn default() -> Self {
|
|
95
|
+
SyncClientConfig {
|
|
96
|
+
base_url: String::new(),
|
|
97
|
+
bearer_token: None,
|
|
98
|
+
headers: HashMap::new(),
|
|
99
|
+
timeout: Duration::from_secs(30),
|
|
100
|
+
throw_on_error: true,
|
|
101
|
+
stale_max_entries: 500,
|
|
102
|
+
invalidation: None,
|
|
103
|
+
on_auth_expired: None,
|
|
104
|
+
http_client: None,
|
|
105
|
+
auth_header_name: None,
|
|
106
|
+
auth_header_prefix: None,
|
|
107
|
+
on_request: Vec::new(),
|
|
108
|
+
on_response: Vec::new(),
|
|
109
|
+
on_log: None,
|
|
110
|
+
state: None,
|
|
111
|
+
max_response_bytes: crate::runtime::DEFAULT_MAX_RESPONSE_BYTES,
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/// SyncAuthState is the blocking twin of [`crate::runtime::AuthState`].
|
|
117
|
+
pub struct SyncAuthState {
|
|
118
|
+
token: Mutex<Option<String>>,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
impl SyncAuthState {
|
|
122
|
+
pub fn new(token: Option<String>) -> Self {
|
|
123
|
+
SyncAuthState { token: Mutex::new(token) }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
pub fn current(&self) -> Option<String> {
|
|
127
|
+
self.token.lock().unwrap_or_else(|p| p.into_inner()).clone()
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
fn refresh(
|
|
131
|
+
&self,
|
|
132
|
+
hook: &Arc<dyn Fn() -> Result<String, Error> + Send + Sync>,
|
|
133
|
+
rejected: Option<&str>,
|
|
134
|
+
) -> Result<Option<String>, Error> {
|
|
135
|
+
let mut guard = self.token.lock().unwrap_or_else(|p| p.into_inner());
|
|
136
|
+
if guard.as_deref() != rejected {
|
|
137
|
+
return Ok(guard.clone());
|
|
138
|
+
}
|
|
139
|
+
let token = hook().map_err(|e| Error::AuthExpired(e.to_string()))?;
|
|
140
|
+
if token.is_empty() {
|
|
141
|
+
return Ok(None);
|
|
142
|
+
}
|
|
143
|
+
*guard = Some(token.clone());
|
|
144
|
+
Ok(Some(token))
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/// default_http_client_blocking follows redirects on the same origin only.
|
|
149
|
+
pub fn default_http_client_blocking() -> reqwest::blocking::Client {
|
|
150
|
+
reqwest::blocking::Client::builder()
|
|
151
|
+
.redirect(crate::runtime::same_host_redirects())
|
|
152
|
+
.build()
|
|
153
|
+
.unwrap_or_default()
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* emit_log invokes the on_log callback if configured, swallowing any panic so a
|
|
157
|
+
faulty logger cannot break the request path. Mirrors runtime.rs sibling. */
|
|
158
|
+
fn emit_log(cfg: &SyncClientConfig, entry: LogEntry) {
|
|
159
|
+
if let Some(ref hook) = cfg.on_log {
|
|
160
|
+
let h = Arc::clone(hook);
|
|
161
|
+
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(move || h(entry)));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* err_status extracts an HTTP status from a typed Error::Api. */
|
|
166
|
+
fn err_status(err: &Error) -> Option<i32> {
|
|
167
|
+
if let Error::Api(api) = err {
|
|
168
|
+
Some(api.status() as i32)
|
|
169
|
+
} else {
|
|
170
|
+
None
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
fn map_err(e: reqwest::Error) -> Error {
|
|
175
|
+
if e.is_timeout() {
|
|
176
|
+
Error::Timeout
|
|
177
|
+
} else {
|
|
178
|
+
Error::Transport(e)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/// SyncRequestResult carries the raw bytes, status, headers, and final URL from a blocking request.
|
|
183
|
+
#[allow(dead_code)]
|
|
184
|
+
pub(crate) struct SyncRequestResult {
|
|
185
|
+
pub body: Vec<u8>,
|
|
186
|
+
pub status: u16,
|
|
187
|
+
pub headers: reqwest::header::HeaderMap,
|
|
188
|
+
pub url: String,
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/// do_request_blocking executes a blocking HTTP request, injects auth, merges headers,
|
|
192
|
+
/// handles on_auth_expired retry on 401, fires on_request/on_response hooks, and wraps
|
|
193
|
+
/// errors into typed Error variants. Emits on_log lifecycle entries (request_start once,
|
|
194
|
+
/// response_received once for the final response, error on terminal failure).
|
|
195
|
+
#[allow(clippy::too_many_arguments)]
|
|
196
|
+
pub(crate) fn do_request_blocking(
|
|
197
|
+
client: &reqwest::blocking::Client,
|
|
198
|
+
cfg: &SyncClientConfig,
|
|
199
|
+
auth: &SyncAuthState,
|
|
200
|
+
method: reqwest::Method,
|
|
201
|
+
raw_url: &str,
|
|
202
|
+
query: &[(String, String)],
|
|
203
|
+
body: SyncRequestBody<'_>,
|
|
204
|
+
call_headers: Option<&HashMap<String, String>>,
|
|
205
|
+
timeout: Option<Duration>,
|
|
206
|
+
cancel_token: Option<Arc<AtomicBool>>,
|
|
207
|
+
operation: &str,
|
|
208
|
+
request_meta: Option<&crate::invalidation::RequestMeta>,
|
|
209
|
+
) -> Result<SyncRequestResult, Error> {
|
|
210
|
+
let start = std::time::Instant::now();
|
|
211
|
+
let log_error = |e: &Error| {
|
|
212
|
+
emit_log(
|
|
213
|
+
cfg,
|
|
214
|
+
LogEntry {
|
|
215
|
+
level: "error".to_string(),
|
|
216
|
+
event: "error".to_string(),
|
|
217
|
+
operation: operation.to_string(),
|
|
218
|
+
duration_ms: start.elapsed().as_millis() as i64,
|
|
219
|
+
status: err_status(e),
|
|
220
|
+
error: Some(format!("{:?}", e)),
|
|
221
|
+
},
|
|
222
|
+
)
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
/* Pre-flight cancellation check — short-circuit before any work. Blocking
|
|
226
|
+
sends cannot be interrupted once started. */
|
|
227
|
+
if let Some(ref tok) = cancel_token {
|
|
228
|
+
if tok.load(Ordering::Acquire) {
|
|
229
|
+
log_error(&Error::Canceled);
|
|
230
|
+
return Err(Error::Canceled);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
emit_log(
|
|
235
|
+
cfg,
|
|
236
|
+
LogEntry {
|
|
237
|
+
level: "debug".to_string(),
|
|
238
|
+
event: "request_start".to_string(),
|
|
239
|
+
operation: operation.to_string(),
|
|
240
|
+
duration_ms: 0,
|
|
241
|
+
status: None,
|
|
242
|
+
error: None,
|
|
243
|
+
},
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
let retry_body: Option<SyncRequestBody<'_>> = match &body {
|
|
247
|
+
SyncRequestBody::None => Some(SyncRequestBody::None),
|
|
248
|
+
SyncRequestBody::Json(v) => Some(SyncRequestBody::Json(v)),
|
|
249
|
+
SyncRequestBody::FormUrl(m) => Some(SyncRequestBody::FormUrl(m.clone())),
|
|
250
|
+
SyncRequestBody::Raw(ct, b) => Some(SyncRequestBody::Raw(ct, b.clone())),
|
|
251
|
+
SyncRequestBody::Multipart(_) => None,
|
|
252
|
+
SyncRequestBody::Stream(_) => None,
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
let token = auth.current();
|
|
256
|
+
let mut result = match execute_request_blocking(
|
|
257
|
+
client,
|
|
258
|
+
cfg,
|
|
259
|
+
method.clone(),
|
|
260
|
+
raw_url,
|
|
261
|
+
query,
|
|
262
|
+
body,
|
|
263
|
+
call_headers,
|
|
264
|
+
token.as_deref(),
|
|
265
|
+
false,
|
|
266
|
+
timeout,
|
|
267
|
+
cancel_token.clone(),
|
|
268
|
+
request_meta,
|
|
269
|
+
) {
|
|
270
|
+
Ok(r) => r,
|
|
271
|
+
Err(e) => {
|
|
272
|
+
log_error(&e);
|
|
273
|
+
return Err(e);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
if result.status == 401 {
|
|
278
|
+
if let (Some(hook), Some(retry)) = (cfg.on_auth_expired.as_ref(), retry_body) {
|
|
279
|
+
let new_token = match auth.refresh(hook, token.as_deref()) {
|
|
280
|
+
Ok(t) => t,
|
|
281
|
+
Err(e) => {
|
|
282
|
+
log_error(&e);
|
|
283
|
+
return Err(e);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
if let Some(new_token) = new_token {
|
|
287
|
+
result = match execute_request_blocking(
|
|
288
|
+
client,
|
|
289
|
+
cfg,
|
|
290
|
+
method,
|
|
291
|
+
raw_url,
|
|
292
|
+
query,
|
|
293
|
+
retry,
|
|
294
|
+
call_headers,
|
|
295
|
+
Some(&new_token),
|
|
296
|
+
true,
|
|
297
|
+
timeout,
|
|
298
|
+
cancel_token,
|
|
299
|
+
request_meta,
|
|
300
|
+
) {
|
|
301
|
+
Ok(r) => r,
|
|
302
|
+
Err(e) => {
|
|
303
|
+
log_error(&e);
|
|
304
|
+
return Err(e);
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
let status_i32 = result.status as i32;
|
|
312
|
+
let level = if result.status >= 400 { "warn" } else { "info" };
|
|
313
|
+
emit_log(
|
|
314
|
+
cfg,
|
|
315
|
+
LogEntry {
|
|
316
|
+
level: level.to_string(),
|
|
317
|
+
event: "response_received".to_string(),
|
|
318
|
+
operation: operation.to_string(),
|
|
319
|
+
duration_ms: start.elapsed().as_millis() as i64,
|
|
320
|
+
status: Some(status_i32),
|
|
321
|
+
error: None,
|
|
322
|
+
},
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
if !(200..300).contains(&result.status) {
|
|
326
|
+
if let Some(err) = raise_for_status(result.status, std::mem::take(&mut result.body)) {
|
|
327
|
+
log_error(&err);
|
|
328
|
+
return Err(err);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
Ok(result)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
#[allow(clippy::too_many_arguments)]
|
|
336
|
+
fn execute_request_blocking(
|
|
337
|
+
client: &reqwest::blocking::Client,
|
|
338
|
+
cfg: &SyncClientConfig,
|
|
339
|
+
method: reqwest::Method,
|
|
340
|
+
raw_url: &str,
|
|
341
|
+
query: &[(String, String)],
|
|
342
|
+
body: SyncRequestBody<'_>,
|
|
343
|
+
call_headers: Option<&HashMap<String, String>>,
|
|
344
|
+
bearer_token: Option<&str>,
|
|
345
|
+
is_retry: bool,
|
|
346
|
+
per_call_timeout: Option<Duration>,
|
|
347
|
+
cancel_token: Option<Arc<AtomicBool>>,
|
|
348
|
+
request_meta: Option<&crate::invalidation::RequestMeta>,
|
|
349
|
+
) -> Result<SyncRequestResult, Error> {
|
|
350
|
+
let url = build_url(&cfg.base_url, raw_url, query)?;
|
|
351
|
+
|
|
352
|
+
let mut hook_headers = merged_headers(
|
|
353
|
+
&cfg.headers,
|
|
354
|
+
call_headers,
|
|
355
|
+
cfg.auth_header_name.as_deref(),
|
|
356
|
+
cfg.auth_header_prefix.as_deref(),
|
|
357
|
+
bearer_token,
|
|
358
|
+
);
|
|
359
|
+
match &body {
|
|
360
|
+
SyncRequestBody::Json(_) => set_header(&mut hook_headers, "Content-Type", "application/json".into()),
|
|
361
|
+
SyncRequestBody::FormUrl(_) => set_header(
|
|
362
|
+
&mut hook_headers,
|
|
363
|
+
"Content-Type",
|
|
364
|
+
"application/x-www-form-urlencoded".into(),
|
|
365
|
+
),
|
|
366
|
+
SyncRequestBody::Raw(ct, _) => set_header(&mut hook_headers, "Content-Type", ct.to_string()),
|
|
367
|
+
SyncRequestBody::Stream(_) => {
|
|
368
|
+
if !hook_headers.keys().any(|k| k.eq_ignore_ascii_case("content-type")) {
|
|
369
|
+
set_header(&mut hook_headers, "Content-Type", "application/octet-stream".into());
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
SyncRequestBody::Multipart(_) | SyncRequestBody::None => {}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
let state = cfg
|
|
376
|
+
.state
|
|
377
|
+
.clone()
|
|
378
|
+
.unwrap_or_else(|| Arc::new(std::sync::Mutex::new(HashMap::new())));
|
|
379
|
+
|
|
380
|
+
let (meta_selector, meta_is_stale, meta_by) = match request_meta {
|
|
381
|
+
Some(m) => (m.selector.clone(), m.is_stale, m.invalidated_by.clone()),
|
|
382
|
+
None => (String::new(), false, Vec::new()),
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
let mut req_ctx = SyncRequestContext {
|
|
386
|
+
method: method.clone(),
|
|
387
|
+
url: url.to_string(),
|
|
388
|
+
path: raw_url.to_string(),
|
|
389
|
+
headers: hook_headers,
|
|
390
|
+
state: Arc::clone(&state),
|
|
391
|
+
is_retry,
|
|
392
|
+
selector: meta_selector.clone(),
|
|
393
|
+
is_stale: meta_is_stale,
|
|
394
|
+
invalidated_by: meta_by.clone(),
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
for hook in cfg.on_request.iter() {
|
|
398
|
+
hook(&mut req_ctx)?;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
let mut req = client.request(req_ctx.method.clone(), &req_ctx.url);
|
|
402
|
+
for (k, v) in &req_ctx.headers {
|
|
403
|
+
req = req.header(k.as_str(), v.as_str());
|
|
404
|
+
}
|
|
405
|
+
req = match body {
|
|
406
|
+
SyncRequestBody::Json(v) => req.body(serde_json::to_vec(v)?),
|
|
407
|
+
SyncRequestBody::FormUrl(pairs) => req.body(encode_query(&pairs)),
|
|
408
|
+
SyncRequestBody::Raw(_, b) => req.body(b.to_vec()),
|
|
409
|
+
SyncRequestBody::Multipart(f) => req.multipart(f),
|
|
410
|
+
SyncRequestBody::Stream(b) => req.body(b),
|
|
411
|
+
SyncRequestBody::None => req,
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
/* per-call timeout overrides cfg.timeout; ZERO means no timeout */
|
|
415
|
+
let effective_timeout = per_call_timeout.unwrap_or(cfg.timeout);
|
|
416
|
+
if !effective_timeout.is_zero() {
|
|
417
|
+
req = req.timeout(effective_timeout);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if let Some(ref tok) = cancel_token {
|
|
421
|
+
if tok.load(Ordering::Acquire) {
|
|
422
|
+
return Err(Error::Canceled);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
let mut resp = req.send().map_err(map_err)?;
|
|
427
|
+
|
|
428
|
+
let status = resp.status().as_u16();
|
|
429
|
+
let resp_headers = resp.headers().clone();
|
|
430
|
+
let resp_url = resp.url().to_string();
|
|
431
|
+
let mut body_bytes = Vec::new();
|
|
432
|
+
let limit = cfg.max_response_bytes;
|
|
433
|
+
{
|
|
434
|
+
use std::io::Read;
|
|
435
|
+
let mut buf = [0u8; 16 * 1024];
|
|
436
|
+
loop {
|
|
437
|
+
let n = resp.read(&mut buf).map_err(|e| {
|
|
438
|
+
if e.kind() == std::io::ErrorKind::TimedOut {
|
|
439
|
+
Error::Timeout
|
|
440
|
+
} else {
|
|
441
|
+
Error::Other(e.to_string())
|
|
442
|
+
}
|
|
443
|
+
})?;
|
|
444
|
+
if n == 0 {
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
if limit > 0 && body_bytes.len() + n > limit {
|
|
448
|
+
return Err(Error::Other(format!("response body exceeds {} bytes", limit)));
|
|
449
|
+
}
|
|
450
|
+
body_bytes.extend_from_slice(&buf[..n]);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
let mut resp_ctx = SyncResponseContext {
|
|
455
|
+
status,
|
|
456
|
+
response: body_bytes,
|
|
457
|
+
headers: resp_headers,
|
|
458
|
+
state,
|
|
459
|
+
is_retry,
|
|
460
|
+
selector: meta_selector,
|
|
461
|
+
is_stale: meta_is_stale,
|
|
462
|
+
invalidated_by: meta_by,
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
for hook in cfg.on_response.iter() {
|
|
466
|
+
hook(&mut resp_ctx)?;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
Ok(SyncRequestResult {
|
|
470
|
+
body: resp_ctx.response,
|
|
471
|
+
status,
|
|
472
|
+
headers: resp_ctx.headers,
|
|
473
|
+
url: resp_url,
|
|
474
|
+
})
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/// build_url_sync constructs the full URL from base + path + query params.
|
|
478
|
+
pub(crate) fn build_url_sync(
|
|
479
|
+
base_url: &str,
|
|
480
|
+
path: &str,
|
|
481
|
+
query: &[(String, String)],
|
|
482
|
+
) -> Result<url::Url, Error> {
|
|
483
|
+
build_url(base_url, path, query)
|
|
484
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/* Code generated by honey. DO NOT EDIT. */
|
|
2
|
+
|
|
3
|
+
use crate::errors::{raise_for_status, Error};
|
|
4
|
+
use futures_util::StreamExt;
|
|
5
|
+
|
|
6
|
+
/// SseEvent represents a single server-sent event. `id` is the last event id
|
|
7
|
+
/// seen on the stream so far (the spec's sticky "last event ID buffer").
|
|
8
|
+
#[derive(Debug, Clone, Default, PartialEq)]
|
|
9
|
+
pub struct SseEvent {
|
|
10
|
+
pub data: String,
|
|
11
|
+
pub event: String,
|
|
12
|
+
pub id: String,
|
|
13
|
+
pub retry: i32,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/// Largest single line, and largest data of one event.
|
|
17
|
+
pub const SSE_MAX_LINE: usize = 1024 * 1024;
|
|
18
|
+
pub const SSE_MAX_EVENT: usize = 8 * 1024 * 1024;
|
|
19
|
+
|
|
20
|
+
/// SseParser is an incremental WHATWG event-stream parser. Lines end in CRLF,
|
|
21
|
+
/// LF or CR; a blank line dispatches; a final event without its blank line is
|
|
22
|
+
/// never dispatched; `id` is sticky; `retry` needs ASCII digits; field values
|
|
23
|
+
/// are not trimmed. Each input byte is scanned once.
|
|
24
|
+
#[derive(Debug, Default)]
|
|
25
|
+
pub struct SseParser {
|
|
26
|
+
line: Vec<u8>,
|
|
27
|
+
pending_cr: bool,
|
|
28
|
+
started: bool,
|
|
29
|
+
data: String,
|
|
30
|
+
has_data: bool,
|
|
31
|
+
event: String,
|
|
32
|
+
last_id: String,
|
|
33
|
+
retry: i32,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
impl SseParser {
|
|
37
|
+
pub fn new() -> Self {
|
|
38
|
+
Self::default()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// feed consumes a chunk and returns every event it completes.
|
|
42
|
+
pub fn feed(&mut self, chunk: &[u8]) -> Result<Vec<SseEvent>, Error> {
|
|
43
|
+
let mut out = Vec::new();
|
|
44
|
+
for &b in chunk {
|
|
45
|
+
if self.pending_cr {
|
|
46
|
+
self.pending_cr = false;
|
|
47
|
+
if b == b'\n' {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
match b {
|
|
52
|
+
b'\n' | b'\r' => {
|
|
53
|
+
if b == b'\r' {
|
|
54
|
+
self.pending_cr = true;
|
|
55
|
+
}
|
|
56
|
+
let line = std::mem::take(&mut self.line);
|
|
57
|
+
if let Some(ev) = self.process(&line)? {
|
|
58
|
+
out.push(ev);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
_ => {
|
|
62
|
+
if self.line.len() >= SSE_MAX_LINE {
|
|
63
|
+
return Err(Error::Other("sse line exceeds 1 MiB".into()));
|
|
64
|
+
}
|
|
65
|
+
self.line.push(b);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
Ok(out)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fn process(&mut self, raw: &[u8]) -> Result<Option<SseEvent>, Error> {
|
|
73
|
+
let mut line = String::from_utf8_lossy(raw).into_owned();
|
|
74
|
+
if !self.started {
|
|
75
|
+
self.started = true;
|
|
76
|
+
if let Some(rest) = line.strip_prefix('\u{feff}') {
|
|
77
|
+
line = rest.to_string();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if line.is_empty() {
|
|
81
|
+
return Ok(self.dispatch());
|
|
82
|
+
}
|
|
83
|
+
if line.starts_with(':') {
|
|
84
|
+
return Ok(None);
|
|
85
|
+
}
|
|
86
|
+
let (field, value) = match line.find(':') {
|
|
87
|
+
Some(i) => {
|
|
88
|
+
let v = &line[i + 1..];
|
|
89
|
+
(&line[..i], v.strip_prefix(' ').unwrap_or(v))
|
|
90
|
+
}
|
|
91
|
+
None => (line.as_str(), ""),
|
|
92
|
+
};
|
|
93
|
+
match field {
|
|
94
|
+
"data" => {
|
|
95
|
+
if self.has_data {
|
|
96
|
+
self.data.push('\n');
|
|
97
|
+
}
|
|
98
|
+
if self.data.len() + value.len() > SSE_MAX_EVENT {
|
|
99
|
+
return Err(Error::Other("sse event exceeds 8 MiB".into()));
|
|
100
|
+
}
|
|
101
|
+
self.data.push_str(value);
|
|
102
|
+
self.has_data = true;
|
|
103
|
+
}
|
|
104
|
+
"event" => self.event = value.to_string(),
|
|
105
|
+
"id" => {
|
|
106
|
+
if !value.contains('\0') {
|
|
107
|
+
self.last_id = value.to_string();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
"retry" => {
|
|
111
|
+
if !value.is_empty() && value.bytes().all(|c| c.is_ascii_digit()) {
|
|
112
|
+
if let Ok(n) = value.parse::<i32>() {
|
|
113
|
+
self.retry = n;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
_ => {}
|
|
118
|
+
}
|
|
119
|
+
Ok(None)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
fn dispatch(&mut self) -> Option<SseEvent> {
|
|
123
|
+
let ev = if self.has_data {
|
|
124
|
+
Some(SseEvent {
|
|
125
|
+
data: std::mem::take(&mut self.data),
|
|
126
|
+
event: std::mem::take(&mut self.event),
|
|
127
|
+
id: self.last_id.clone(),
|
|
128
|
+
retry: self.retry,
|
|
129
|
+
})
|
|
130
|
+
} else {
|
|
131
|
+
None
|
|
132
|
+
};
|
|
133
|
+
self.data.clear();
|
|
134
|
+
self.has_data = false;
|
|
135
|
+
self.event.clear();
|
|
136
|
+
self.retry = 0;
|
|
137
|
+
ev
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/// parse_sse_text parses complete text; used by the conformance vectors.
|
|
142
|
+
pub fn parse_sse_text(chunks: &[&str]) -> Result<Vec<SseEvent>, Error> {
|
|
143
|
+
let mut p = SseParser::new();
|
|
144
|
+
let mut out = Vec::new();
|
|
145
|
+
for c in chunks {
|
|
146
|
+
out.extend(p.feed(c.as_bytes())?);
|
|
147
|
+
}
|
|
148
|
+
Ok(out)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/// parse_sse_stream returns a Stream of SseEvent values read from a reqwest Response.
|
|
152
|
+
/// On non-2xx response it yields a typed error immediately then terminates.
|
|
153
|
+
pub fn parse_sse_stream(
|
|
154
|
+
resp: reqwest::Response,
|
|
155
|
+
) -> impl futures_util::Stream<Item = Result<SseEvent, Error>> {
|
|
156
|
+
async_stream::stream! {
|
|
157
|
+
let status = resp.status().as_u16();
|
|
158
|
+
if !(200..300).contains(&status) {
|
|
159
|
+
let body = resp.bytes().await.unwrap_or_default().to_vec();
|
|
160
|
+
if let Some(err) = raise_for_status(status, body) {
|
|
161
|
+
yield Err(err);
|
|
162
|
+
}
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let mut byte_stream = resp.bytes_stream();
|
|
167
|
+
let mut parser = SseParser::new();
|
|
168
|
+
while let Some(chunk) = byte_stream.next().await {
|
|
169
|
+
match chunk {
|
|
170
|
+
Err(e) => {
|
|
171
|
+
yield Err(Error::Transport(e));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
Ok(bytes) => match parser.feed(&bytes) {
|
|
175
|
+
Ok(events) => {
|
|
176
|
+
for ev in events {
|
|
177
|
+
yield Ok(ev);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
Err(e) => {
|
|
181
|
+
yield Err(e);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|