@lovrozagar/honey 0.7.3 → 1.0.0-rc.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/LICENSE +21 -0
- package/README.md +36 -1969
- package/bin/honey.js +87 -27
- package/dist/adapters/bun/serve.d.ts +18 -0
- package/dist/adapters/bun/serve.js +89 -0
- package/dist/adapters/fetch-request.d.ts +20 -0
- package/dist/adapters/fetch-request.js +29 -0
- package/dist/adapters/node/headers.d.ts +27 -0
- package/dist/adapters/node/headers.js +86 -0
- package/dist/adapters/node/request.d.ts +16 -0
- package/dist/adapters/node/request.js +214 -0
- package/dist/adapters/node/response.d.ts +11 -0
- package/dist/adapters/node/response.js +126 -0
- package/dist/adapters/node/serve.d.ts +39 -0
- package/dist/adapters/node/serve.js +205 -0
- package/dist/adapters/node/url.d.ts +13 -0
- package/dist/adapters/node/url.js +87 -0
- package/dist/adapters/serve.d.ts +36 -0
- package/dist/adapters/serve.js +52 -0
- package/dist/build/artifacts.d.ts +34 -0
- package/dist/build/artifacts.js +123 -0
- package/dist/build/cli-args.d.ts +30 -0
- package/dist/build/cli-args.js +97 -0
- package/dist/build/cli.d.ts +11 -0
- package/dist/build/cli.js +150 -0
- package/dist/build/config.d.ts +102 -0
- package/dist/build/config.js +89 -0
- package/dist/build/generate.d.ts +19 -0
- package/dist/build/generate.js +80 -0
- package/dist/build/glob.d.ts +8 -0
- package/dist/build/glob.js +97 -0
- package/dist/build/index.d.ts +3 -58
- package/dist/build/index.js +3 -173
- package/dist/build/init.d.ts +3 -0
- package/dist/build/init.js +131 -0
- package/dist/build/loaders.d.ts +33 -0
- package/dist/build/loaders.js +105 -0
- package/dist/build/plugin.d.ts +52 -0
- package/dist/build/plugin.js +146 -0
- package/dist/build/source.d.ts +21 -0
- package/dist/build/source.js +100 -0
- package/dist/build/targets.d.ts +59 -0
- package/dist/build/targets.js +107 -0
- package/dist/context/context.d.ts +111 -0
- package/dist/context/context.js +213 -0
- package/dist/context/cookie-sign.d.ts +38 -0
- package/dist/context/cookie-sign.js +113 -0
- package/dist/context/cookie.d.ts +28 -0
- package/dist/context/cookie.js +142 -0
- package/dist/context/peer.d.ts +34 -0
- package/dist/context/peer.js +190 -0
- package/dist/errors/error.d.ts +60 -0
- package/dist/errors/error.js +84 -0
- package/dist/errors/errors.d.ts +45 -0
- package/dist/errors/errors.js +31 -0
- package/dist/errors/on-error.d.ts +10 -0
- package/dist/errors/on-error.js +204 -0
- package/dist/errors/problem-json.d.ts +14 -0
- package/dist/errors/problem-json.js +58 -0
- package/dist/errors/projector.d.ts +50 -0
- package/dist/errors/projector.js +107 -0
- package/dist/i18n/error-i18n.d.ts +26 -0
- package/dist/i18n/error-i18n.js +77 -0
- package/dist/i18n/i18n.d.ts +21 -0
- package/dist/i18n/i18n.js +40 -0
- package/dist/i18n/icu.d.ts +29 -0
- package/dist/i18n/icu.js +170 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.js +3 -0
- package/dist/index.d.ts +30 -746
- package/dist/index.js +12 -2364
- package/dist/input/accepts.d.ts +5 -0
- package/dist/input/accepts.js +105 -0
- package/dist/input/binary.d.ts +20 -0
- package/dist/input/binary.js +40 -0
- package/dist/input/body-kind.d.ts +15 -0
- package/dist/input/body-kind.js +47 -0
- package/dist/input/body-limit.d.ts +21 -0
- package/dist/input/body-limit.js +99 -0
- package/dist/input/cookies.d.ts +7 -0
- package/dist/input/cookies.js +8 -0
- package/dist/input/form.d.ts +10 -0
- package/dist/input/form.js +24 -0
- package/dist/input/headers.d.ts +7 -0
- package/dist/input/headers.js +8 -0
- package/dist/input/input.d.ts +91 -0
- package/dist/input/input.js +88 -0
- package/dist/input/json.d.ts +10 -0
- package/dist/input/json.js +22 -0
- package/dist/input/params.d.ts +7 -0
- package/dist/input/params.js +8 -0
- package/dist/input/query.d.ts +10 -0
- package/dist/input/query.js +17 -0
- package/dist/mcp/mount.d.ts +116 -0
- package/dist/mcp/mount.js +45 -0
- package/dist/mcp/oauth.d.ts +14 -0
- package/dist/mcp/oauth.js +88 -0
- package/dist/mcp/uploads.d.ts +36 -0
- package/dist/mcp/uploads.js +171 -0
- package/dist/mcp/url-files.d.ts +32 -0
- package/dist/mcp/url-files.js +75 -0
- package/dist/meta/meta-spec-apply.d.ts +25 -0
- package/dist/meta/meta-spec-apply.js +83 -0
- package/dist/meta/meta-spec-merge.d.ts +103 -0
- package/dist/meta/meta-spec-merge.js +50 -0
- package/dist/meta/meta-spec-validate.d.ts +61 -0
- package/dist/meta/meta-spec-validate.js +166 -0
- package/dist/meta/meta-spec.d.ts +49 -0
- package/dist/meta/meta-spec.js +197 -0
- package/dist/middleware/compress.d.ts +15 -0
- package/dist/middleware/compress.js +93 -0
- package/dist/middleware/cors.d.ts +18 -0
- package/dist/middleware/cors.js +80 -0
- package/dist/middleware/csrf.d.ts +11 -0
- package/dist/middleware/csrf.js +65 -0
- package/dist/middleware/ip-restrict.d.ts +10 -0
- package/dist/middleware/ip-restrict.js +82 -0
- package/dist/middleware/middleware.d.ts +53 -0
- package/dist/middleware/middleware.js +112 -0
- package/dist/middleware/powered-by.d.ts +6 -0
- package/dist/middleware/powered-by.js +13 -0
- package/dist/middleware/rate-limit.d.ts +40 -0
- package/dist/middleware/rate-limit.js +90 -0
- package/dist/middleware/request-id.d.ts +25 -0
- package/dist/middleware/request-id.js +30 -0
- package/dist/middleware/secure-headers.d.ts +18 -0
- package/dist/middleware/secure-headers.js +36 -0
- package/dist/middleware/server-timing.d.ts +8 -0
- package/dist/middleware/server-timing.js +52 -0
- package/dist/middleware/timeout.d.ts +6 -0
- package/dist/middleware/timeout.js +29 -0
- package/dist/observability/curl-logger.d.ts +46 -0
- package/dist/observability/curl-logger.js +175 -0
- package/dist/observability/request-to-curl.d.ts +17 -0
- package/dist/observability/request-to-curl.js +47 -0
- package/dist/openapi/collect.d.ts +56 -18
- package/dist/openapi/collect.js +109 -23
- package/dist/openapi/components.d.ts +9 -0
- package/dist/openapi/components.js +90 -0
- package/dist/openapi/docs-page.d.ts +20 -18
- package/dist/openapi/docs-page.js +28 -46
- package/dist/openapi/document.d.ts +33 -26
- package/dist/openapi/document.js +21 -780
- package/dist/openapi/extract-schemas.d.ts +11 -0
- package/dist/openapi/extract-schemas.js +31 -0
- package/dist/openapi/generate.d.ts +47 -0
- package/dist/openapi/generate.js +180 -0
- package/dist/openapi/manifest.d.ts +41 -0
- package/dist/openapi/manifest.js +49 -0
- package/dist/openapi/output-keys.d.ts +6 -0
- package/dist/openapi/output-keys.js +24 -0
- package/dist/openapi/paths.d.ts +35 -0
- package/dist/openapi/paths.js +175 -0
- package/dist/openapi/register.d.ts +14 -3
- package/dist/openapi/register.js +13 -20
- package/dist/openapi/responses.d.ts +44 -0
- package/dist/openapi/responses.js +159 -0
- package/dist/openapi/scalar.d.ts +4 -14
- package/dist/openapi/scalar.js +5 -7
- package/dist/openapi/security.d.ts +4 -0
- package/dist/openapi/security.js +25 -0
- package/dist/openapi/serve.d.ts +25 -9
- package/dist/openapi/serve.js +108 -29
- package/dist/openapi/servers.d.ts +19 -0
- package/dist/openapi/servers.js +72 -0
- package/dist/openapi/swagger.d.ts +4 -14
- package/dist/openapi/swagger.js +5 -7
- package/dist/openapi/tags.d.ts +20 -0
- package/dist/openapi/tags.js +20 -0
- package/dist/openapi/webhooks.d.ts +19 -0
- package/dist/openapi/webhooks.js +70 -0
- package/dist/openapi/yaml.d.ts +8 -0
- package/dist/openapi/yaml.js +74 -0
- package/dist/proxy/headers.d.ts +30 -0
- package/dist/proxy/headers.js +86 -0
- package/dist/proxy/proxy.d.ts +39 -0
- package/dist/proxy/proxy.js +103 -0
- package/dist/proxy/upstream.d.ts +30 -0
- package/dist/proxy/upstream.js +116 -0
- package/dist/realtime/bus.d.ts +10 -13
- package/dist/realtime/bus.js +48 -93
- package/dist/realtime/invoke-user.d.ts +36 -0
- package/dist/realtime/invoke-user.js +103 -0
- package/dist/realtime/realtime.d.ts +7 -0
- package/dist/realtime/realtime.js +40 -0
- package/dist/realtime/route.d.ts +33 -27
- package/dist/realtime/route.js +27 -43
- package/dist/realtime/server.d.ts +24 -28
- package/dist/realtime/server.js +202 -225
- package/dist/response/binary.d.ts +18 -0
- package/dist/response/binary.js +10 -0
- package/dist/response/builder.d.ts +73 -0
- package/dist/response/builder.js +214 -0
- package/dist/response/cache-control.d.ts +30 -0
- package/dist/response/cache-control.js +74 -0
- package/dist/response/etag.d.ts +15 -0
- package/dist/response/etag.js +83 -0
- package/dist/response/media-type.d.ts +28 -0
- package/dist/response/media-type.js +97 -0
- package/dist/response/out-headers.d.ts +31 -0
- package/dist/response/out-headers.js +130 -0
- package/dist/response/pretty-json.d.ts +10 -0
- package/dist/response/pretty-json.js +44 -0
- package/dist/response/range.d.ts +19 -0
- package/dist/response/range.js +98 -0
- package/dist/response/response-headers.d.ts +11 -0
- package/dist/response/response-headers.js +21 -0
- package/dist/response/response.d.ts +69 -0
- package/dist/response/response.js +208 -0
- package/dist/response/sse.d.ts +41 -0
- package/dist/response/sse.js +73 -0
- package/dist/response/static.d.ts +20 -0
- package/dist/response/static.js +181 -0
- package/dist/response/status.d.ts +5 -0
- package/dist/response/status.js +68 -0
- package/dist/response/with-headers.d.ts +11 -0
- package/dist/response/with-headers.js +47 -0
- package/dist/routing/app-types.d.ts +181 -0
- package/dist/routing/app-types.js +1 -0
- package/dist/routing/app.d.ts +76 -0
- package/dist/routing/app.js +137 -0
- package/dist/routing/codegen-types.d.ts +17 -0
- package/dist/routing/codegen-types.js +1 -0
- package/dist/routing/delegate.d.ts +9 -0
- package/dist/routing/delegate.js +75 -0
- package/dist/routing/dispatch.d.ts +22 -0
- package/dist/routing/dispatch.js +255 -0
- package/dist/routing/finalize.d.ts +47 -0
- package/dist/routing/finalize.js +169 -0
- package/dist/routing/gateway-tree.d.ts +19 -0
- package/dist/routing/gateway-tree.js +74 -0
- package/dist/routing/invalidate-check.d.ts +58 -0
- package/dist/routing/invalidate-check.js +124 -0
- package/dist/routing/match.d.ts +22 -0
- package/dist/routing/match.js +108 -0
- package/dist/routing/middleware-chain.d.ts +16 -0
- package/dist/routing/middleware-chain.js +41 -0
- package/dist/routing/output-types.d.ts +91 -0
- package/dist/routing/output-types.js +1 -0
- package/dist/routing/pattern.d.ts +55 -0
- package/dist/routing/pattern.js +219 -0
- package/dist/routing/record.d.ts +18 -0
- package/dist/routing/record.js +4 -0
- package/dist/routing/register.d.ts +135 -0
- package/dist/routing/register.js +155 -0
- package/dist/routing/request-path.d.ts +30 -0
- package/dist/routing/request-path.js +173 -0
- package/dist/routing/route-builder.d.ts +160 -0
- package/dist/routing/route-builder.js +86 -0
- package/dist/routing/route-tree.d.ts +18 -0
- package/dist/routing/route-tree.js +91 -0
- package/dist/routing/settings-chain.d.ts +75 -0
- package/dist/routing/settings-chain.js +137 -0
- package/dist/routing/settings.d.ts +90 -0
- package/dist/routing/settings.js +44 -0
- package/dist/routing/tap.d.ts +31 -0
- package/dist/routing/tap.js +77 -0
- package/dist/routing/tree-merge.d.ts +7 -0
- package/dist/routing/tree-merge.js +77 -0
- package/dist/routing/tree.d.ts +85 -0
- package/dist/routing/tree.js +196 -0
- package/dist/routing/types.d.ts +20 -0
- package/dist/routing/types.js +1 -0
- package/dist/routing/ws-builder.d.ts +62 -0
- package/dist/routing/ws-builder.js +109 -0
- package/dist/runtime/detect-runtime.d.ts +16 -0
- package/dist/runtime/detect-runtime.js +11 -0
- package/dist/runtime/optional-peer.d.ts +10 -0
- package/dist/runtime/optional-peer.js +19 -0
- package/dist/schema/arktype.d.ts +7 -0
- package/dist/schema/arktype.js +13 -0
- package/dist/schema/canonicalize.d.ts +8 -0
- package/dist/schema/canonicalize.js +19 -0
- package/dist/schema/effect.d.ts +7 -0
- package/dist/schema/effect.js +4 -0
- package/dist/schema/naming.d.ts +31 -0
- package/dist/schema/naming.js +116 -0
- package/dist/schema/sanitize-spec.d.ts +15 -0
- package/dist/schema/sanitize-spec.js +43 -0
- package/dist/schema/slots.d.ts +15 -0
- package/dist/schema/slots.js +179 -0
- package/dist/schema/to-json-schema.d.ts +34 -0
- package/dist/schema/to-json-schema.js +94 -0
- package/dist/schema/valibot.d.ts +4 -0
- package/dist/schema/valibot.js +153 -0
- package/dist/schema/yup.d.ts +3 -0
- package/dist/schema/yup.js +57 -0
- package/dist/schema/zod.d.ts +6 -0
- package/dist/schema/zod.js +192 -0
- package/dist/security/crypto.d.ts +7 -0
- package/dist/security/crypto.js +30 -0
- package/dist/streaming/producer-stream.d.ts +45 -0
- package/dist/streaming/producer-stream.js +251 -0
- package/dist/telemetry/fields.d.ts +43 -0
- package/dist/telemetry/fields.js +64 -0
- package/dist/telemetry/log-format.d.ts +7 -0
- package/dist/telemetry/log-format.js +43 -0
- package/dist/telemetry/logger.d.ts +44 -0
- package/dist/telemetry/logger.js +122 -0
- package/dist/telemetry/otel-subpath.d.ts +7 -0
- package/dist/telemetry/otel-subpath.js +5 -0
- package/dist/telemetry/otel.d.ts +50 -57
- package/dist/telemetry/otel.js +54 -130
- package/dist/telemetry/request-log.d.ts +22 -0
- package/dist/telemetry/request-log.js +83 -0
- package/dist/telemetry/request-trace.d.ts +123 -0
- package/dist/telemetry/request-trace.js +199 -0
- package/dist/telemetry/span-lifecycle.d.ts +11 -0
- package/dist/telemetry/span-lifecycle.js +114 -0
- package/dist/telemetry/traceparent.d.ts +40 -0
- package/dist/telemetry/traceparent.js +73 -0
- package/dist/testing/testing.d.ts +42 -0
- package/dist/testing/testing.js +101 -0
- package/dist/validation/content-type.d.ts +21 -0
- package/dist/validation/content-type.js +42 -0
- package/dist/validation/standard-schema.d.ts +41 -0
- package/dist/validation/standard-schema.js +5 -0
- package/dist/validation/validate-input.d.ts +45 -0
- package/dist/validation/validate-input.js +174 -0
- package/dist/validation/validate-output.d.ts +34 -0
- package/dist/validation/validate-output.js +107 -0
- package/dist/ws/bun.d.ts +30 -25
- package/dist/ws/bun.js +42 -46
- package/dist/ws/cloudflare.d.ts +6 -75
- package/dist/ws/cloudflare.js +37 -104
- package/dist/ws/contract.d.ts +74 -0
- package/dist/ws/contract.js +83 -0
- package/dist/ws/node.d.ts +12 -21
- package/dist/ws/node.js +103 -151
- package/dist/ws/origin.d.ts +23 -0
- package/dist/ws/origin.js +48 -0
- package/dist/ws/route.d.ts +14 -0
- package/dist/ws/route.js +5 -0
- package/dist/ws/session.d.ts +15 -6
- package/dist/ws/session.js +22 -23
- package/dist/ws/shared.d.ts +23 -33
- package/dist/ws/shared.js +53 -39
- package/package.json +169 -251
- package/dist/accepts.d.ts +0 -12
- package/dist/accepts.d.ts.map +0 -1
- package/dist/accepts.js +0 -126
- package/dist/accepts.js.map +0 -1
- package/dist/body-kind.d.ts +0 -26
- package/dist/body-kind.d.ts.map +0 -1
- package/dist/body-kind.js +0 -70
- package/dist/body-kind.js.map +0 -1
- package/dist/body-limit.d.ts +0 -26
- package/dist/body-limit.d.ts.map +0 -1
- package/dist/body-limit.js +0 -126
- package/dist/body-limit.js.map +0 -1
- package/dist/build/index.d.ts.map +0 -1
- package/dist/build/index.js.map +0 -1
- package/dist/cli-args.d.ts +0 -33
- package/dist/cli-args.d.ts.map +0 -1
- package/dist/cli-args.js +0 -102
- package/dist/cli-args.js.map +0 -1
- package/dist/cli-go/auth.go +0 -26
- package/dist/cli-go/config.go +0 -192
- package/dist/cli-go/errors.go +0 -75
- package/dist/cli-go/multipart.go +0 -79
- package/dist/cli-go/output.go +0 -163
- package/dist/cli-go/root.go +0 -30
- package/dist/cli-go/stream.go +0 -88
- package/dist/cli-go/version.go +0 -5
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -209
- package/dist/cli.js.map +0 -1
- package/dist/client/defaults.d.ts +0 -12
- package/dist/client/defaults.d.ts.map +0 -1
- package/dist/client/defaults.js +0 -48
- package/dist/client/defaults.js.map +0 -1
- package/dist/client/error.d.ts +0 -49
- package/dist/client/error.d.ts.map +0 -1
- package/dist/client/error.js +0 -71
- package/dist/client/error.js.map +0 -1
- package/dist/client/http.d.ts +0 -155
- package/dist/client/http.d.ts.map +0 -1
- package/dist/client/http.js +0 -571
- package/dist/client/http.js.map +0 -1
- package/dist/client/index.d.ts +0 -23
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -95
- package/dist/client/index.js.map +0 -1
- package/dist/client/path.d.ts +0 -26
- package/dist/client/path.d.ts.map +0 -1
- package/dist/client/path.js +0 -163
- package/dist/client/path.js.map +0 -1
- package/dist/client/redirect-policy.d.ts +0 -12
- package/dist/client/redirect-policy.d.ts.map +0 -1
- package/dist/client/redirect-policy.js +0 -20
- package/dist/client/redirect-policy.js.map +0 -1
- package/dist/client/sdk.d.ts +0 -70
- package/dist/client/sdk.d.ts.map +0 -1
- package/dist/client/sdk.js +0 -292
- package/dist/client/sdk.js.map +0 -1
- package/dist/client/sse.d.ts +0 -23
- package/dist/client/sse.d.ts.map +0 -1
- package/dist/client/sse.js +0 -129
- package/dist/client/sse.js.map +0 -1
- package/dist/client/types.d.ts +0 -124
- package/dist/client/types.d.ts.map +0 -1
- package/dist/client/types.js +0 -2
- package/dist/client/types.js.map +0 -1
- package/dist/client/ws.d.ts +0 -22
- package/dist/client/ws.d.ts.map +0 -1
- package/dist/client/ws.js +0 -112
- package/dist/client/ws.js.map +0 -1
- package/dist/client-go/errors.go +0 -236
- package/dist/client-go/export.go +0 -44
- package/dist/client-go/invalidation.go +0 -371
- package/dist/client-go/nullable.go +0 -62
- package/dist/client-go/realtime.go +0 -354
- package/dist/client-go/result.go +0 -20
- package/dist/client-go/runtime.go +0 -975
- package/dist/client-go/sse.go +0 -159
- package/dist/client-go/transport.go +0 -495
- package/dist/client-go/ws.go +0 -128
- package/dist/client-info.d.ts +0 -36
- package/dist/client-info.d.ts.map +0 -1
- package/dist/client-info.js +0 -53
- package/dist/client-info.js.map +0 -1
- package/dist/client-mcp/README.md +0 -10
- package/dist/client-mcp/server.ts +0 -221
- package/dist/client-mcp/types.ts +0 -19
- package/dist/client-python/_errors.py +0 -115
- package/dist/client-python/_invalidation.py +0 -494
- package/dist/client-python/_realtime.py +0 -179
- package/dist/client-python/_runtime.py +0 -860
- package/dist/client-python/_sse.py +0 -155
- package/dist/client-python/_transport.py +0 -366
- package/dist/client-python/_ws.py +0 -159
- package/dist/client-python/py.typed +0 -0
- package/dist/client-rust/errors.rs +0 -220
- package/dist/client-rust/invalidation.rs +0 -412
- package/dist/client-rust/invalidation_sync.rs +0 -93
- package/dist/client-rust/nullable.rs +0 -17
- package/dist/client-rust/realtime.rs +0 -702
- package/dist/client-rust/result.rs +0 -22
- package/dist/client-rust/runtime.rs +0 -980
- package/dist/client-rust/runtime_sync.rs +0 -484
- package/dist/client-rust/sse.rs +0 -188
- package/dist/client-rust/ws.rs +0 -167
- package/dist/codegen-go-cli.d.ts +0 -22
- package/dist/codegen-go-cli.d.ts.map +0 -1
- package/dist/codegen-go-cli.js +0 -964
- package/dist/codegen-go-cli.js.map +0 -1
- package/dist/codegen-go.d.ts +0 -41
- package/dist/codegen-go.d.ts.map +0 -1
- package/dist/codegen-go.js +0 -872
- package/dist/codegen-go.js.map +0 -1
- package/dist/codegen-hash.d.ts +0 -3
- package/dist/codegen-hash.d.ts.map +0 -1
- package/dist/codegen-hash.js +0 -9
- package/dist/codegen-hash.js.map +0 -1
- package/dist/codegen-ir.d.ts +0 -190
- package/dist/codegen-ir.d.ts.map +0 -1
- package/dist/codegen-ir.js +0 -661
- package/dist/codegen-ir.js.map +0 -1
- package/dist/codegen-lang.d.ts +0 -65
- package/dist/codegen-lang.d.ts.map +0 -1
- package/dist/codegen-lang.js +0 -526
- package/dist/codegen-lang.js.map +0 -1
- package/dist/codegen-load.d.ts +0 -31
- package/dist/codegen-load.d.ts.map +0 -1
- package/dist/codegen-load.js +0 -138
- package/dist/codegen-load.js.map +0 -1
- package/dist/codegen-loaders.d.ts +0 -12
- package/dist/codegen-loaders.d.ts.map +0 -1
- package/dist/codegen-loaders.js +0 -55
- package/dist/codegen-loaders.js.map +0 -1
- package/dist/codegen-mcp.d.ts +0 -13
- package/dist/codegen-mcp.d.ts.map +0 -1
- package/dist/codegen-mcp.js +0 -368
- package/dist/codegen-mcp.js.map +0 -1
- package/dist/codegen-python.d.ts +0 -33
- package/dist/codegen-python.d.ts.map +0 -1
- package/dist/codegen-python.js +0 -828
- package/dist/codegen-python.js.map +0 -1
- package/dist/codegen-route-tree-intern.d.ts +0 -40
- package/dist/codegen-route-tree-intern.d.ts.map +0 -1
- package/dist/codegen-route-tree-intern.js +0 -221
- package/dist/codegen-route-tree-intern.js.map +0 -1
- package/dist/codegen-rust.d.ts +0 -18
- package/dist/codegen-rust.d.ts.map +0 -1
- package/dist/codegen-rust.js +0 -1293
- package/dist/codegen-rust.js.map +0 -1
- package/dist/codegen-sanitize.d.ts +0 -3
- package/dist/codegen-sanitize.d.ts.map +0 -1
- package/dist/codegen-sanitize.js +0 -56
- package/dist/codegen-sanitize.js.map +0 -1
- package/dist/codegen-schema-naming.d.ts +0 -27
- package/dist/codegen-schema-naming.d.ts.map +0 -1
- package/dist/codegen-schema-naming.js +0 -150
- package/dist/codegen-schema-naming.js.map +0 -1
- package/dist/codegen-sdk-model.d.ts +0 -71
- package/dist/codegen-sdk-model.d.ts.map +0 -1
- package/dist/codegen-sdk-model.js +0 -179
- package/dist/codegen-sdk-model.js.map +0 -1
- package/dist/codegen.d.ts +0 -187
- package/dist/codegen.d.ts.map +0 -1
- package/dist/codegen.js +0 -4619
- package/dist/codegen.js.map +0 -1
- package/dist/context.d.ts +0 -86
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -242
- package/dist/context.js.map +0 -1
- package/dist/cookie-sign.d.ts +0 -17
- package/dist/cookie-sign.d.ts.map +0 -1
- package/dist/cookie-sign.js +0 -104
- package/dist/cookie-sign.js.map +0 -1
- package/dist/cookie.d.ts +0 -24
- package/dist/cookie.d.ts.map +0 -1
- package/dist/cookie.js +0 -138
- package/dist/cookie.js.map +0 -1
- package/dist/cors.d.ts +0 -14
- package/dist/cors.d.ts.map +0 -1
- package/dist/cors.js +0 -87
- package/dist/cors.js.map +0 -1
- package/dist/crypto.d.ts +0 -7
- package/dist/crypto.d.ts.map +0 -1
- package/dist/crypto.js +0 -38
- package/dist/crypto.js.map +0 -1
- package/dist/csrf.d.ts +0 -28
- package/dist/csrf.d.ts.map +0 -1
- package/dist/csrf.js +0 -79
- package/dist/csrf.js.map +0 -1
- package/dist/curl-logger.d.ts +0 -44
- package/dist/curl-logger.d.ts.map +0 -1
- package/dist/curl-logger.js +0 -199
- package/dist/curl-logger.js.map +0 -1
- package/dist/detect-runtime.d.ts +0 -16
- package/dist/detect-runtime.d.ts.map +0 -1
- package/dist/detect-runtime.js +0 -13
- package/dist/detect-runtime.js.map +0 -1
- package/dist/dict.d.ts +0 -11
- package/dist/dict.d.ts.map +0 -1
- package/dist/dict.js +0 -13
- package/dist/dict.js.map +0 -1
- package/dist/error.d.ts +0 -21
- package/dist/error.d.ts.map +0 -1
- package/dist/error.js +0 -44
- package/dist/error.js.map +0 -1
- package/dist/errors.d.ts +0 -40
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -39
- package/dist/errors.js.map +0 -1
- package/dist/etag.d.ts +0 -11
- package/dist/etag.d.ts.map +0 -1
- package/dist/etag.js +0 -82
- package/dist/etag.js.map +0 -1
- package/dist/feature-detect.d.ts +0 -25
- package/dist/feature-detect.d.ts.map +0 -1
- package/dist/feature-detect.js +0 -144
- package/dist/feature-detect.js.map +0 -1
- package/dist/feature-load.d.ts +0 -3
- package/dist/feature-load.d.ts.map +0 -1
- package/dist/feature-load.js +0 -36
- package/dist/feature-load.js.map +0 -1
- package/dist/feature-slots.d.ts +0 -44
- package/dist/feature-slots.d.ts.map +0 -1
- package/dist/feature-slots.js +0 -48
- package/dist/feature-slots.js.map +0 -1
- package/dist/fetch-request.d.ts +0 -10
- package/dist/fetch-request.d.ts.map +0 -1
- package/dist/fetch-request.js +0 -13
- package/dist/fetch-request.js.map +0 -1
- package/dist/gen-process.d.ts +0 -15
- package/dist/gen-process.d.ts.map +0 -1
- package/dist/gen-process.js +0 -43
- package/dist/gen-process.js.map +0 -1
- package/dist/gen-write.d.ts +0 -19
- package/dist/gen-write.d.ts.map +0 -1
- package/dist/gen-write.js +0 -120
- package/dist/gen-write.js.map +0 -1
- package/dist/glob.d.ts +0 -21
- package/dist/glob.d.ts.map +0 -1
- package/dist/glob.js +0 -115
- package/dist/glob.js.map +0 -1
- package/dist/go-type-emitter.d.ts +0 -47
- package/dist/go-type-emitter.d.ts.map +0 -1
- package/dist/go-type-emitter.js +0 -594
- package/dist/go-type-emitter.js.map +0 -1
- package/dist/honey-response.d.ts +0 -82
- package/dist/honey-response.d.ts.map +0 -1
- package/dist/honey-response.js +0 -338
- package/dist/honey-response.js.map +0 -1
- package/dist/i18n-slot.d.ts +0 -15
- package/dist/i18n-slot.d.ts.map +0 -1
- package/dist/i18n-slot.js +0 -14
- package/dist/i18n-slot.js.map +0 -1
- package/dist/i18n.d.ts +0 -29
- package/dist/i18n.d.ts.map +0 -1
- package/dist/i18n.js +0 -250
- package/dist/i18n.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/init.d.ts +0 -5
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -140
- package/dist/init.js.map +0 -1
- package/dist/input.d.ts +0 -6
- package/dist/input.d.ts.map +0 -1
- package/dist/input.js +0 -4
- package/dist/input.js.map +0 -1
- package/dist/invalidate-check.d.ts +0 -61
- package/dist/invalidate-check.d.ts.map +0 -1
- package/dist/invalidate-check.js +0 -163
- package/dist/invalidate-check.js.map +0 -1
- package/dist/invoke-user.d.ts +0 -35
- package/dist/invoke-user.d.ts.map +0 -1
- package/dist/invoke-user.js +0 -73
- package/dist/invoke-user.js.map +0 -1
- package/dist/ip-restrict.d.ts +0 -24
- package/dist/ip-restrict.d.ts.map +0 -1
- package/dist/ip-restrict.js +0 -60
- package/dist/ip-restrict.js.map +0 -1
- package/dist/ip.d.ts +0 -39
- package/dist/ip.d.ts.map +0 -1
- package/dist/ip.js +0 -209
- package/dist/ip.js.map +0 -1
- package/dist/logger.d.ts +0 -45
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -113
- package/dist/logger.js.map +0 -1
- package/dist/media-type.d.ts +0 -30
- package/dist/media-type.d.ts.map +0 -1
- package/dist/media-type.js +0 -97
- package/dist/media-type.js.map +0 -1
- package/dist/meta-spec-merge.d.ts +0 -32
- package/dist/meta-spec-merge.d.ts.map +0 -1
- package/dist/meta-spec-merge.js +0 -68
- package/dist/meta-spec-merge.js.map +0 -1
- package/dist/meta-spec.d.ts +0 -94
- package/dist/meta-spec.d.ts.map +0 -1
- package/dist/meta-spec.js +0 -535
- package/dist/meta-spec.js.map +0 -1
- package/dist/middleware.d.ts +0 -77
- package/dist/middleware.d.ts.map +0 -1
- package/dist/middleware.js +0 -253
- package/dist/middleware.js.map +0 -1
- package/dist/node-request.d.ts +0 -104
- package/dist/node-request.d.ts.map +0 -1
- package/dist/node-request.js +0 -407
- package/dist/node-request.js.map +0 -1
- package/dist/node.d.ts +0 -30
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js +0 -396
- package/dist/node.js.map +0 -1
- package/dist/openapi/collect.d.ts.map +0 -1
- package/dist/openapi/collect.js.map +0 -1
- package/dist/openapi/docs-page.d.ts.map +0 -1
- package/dist/openapi/docs-page.js.map +0 -1
- package/dist/openapi/document.d.ts.map +0 -1
- package/dist/openapi/document.js.map +0 -1
- package/dist/openapi/json-schema-slot.d.ts +0 -12
- package/dist/openapi/json-schema-slot.d.ts.map +0 -1
- package/dist/openapi/json-schema-slot.js +0 -38
- package/dist/openapi/json-schema-slot.js.map +0 -1
- package/dist/openapi/register.d.ts.map +0 -1
- package/dist/openapi/register.js.map +0 -1
- package/dist/openapi/scalar.d.ts.map +0 -1
- package/dist/openapi/scalar.js.map +0 -1
- package/dist/openapi/serve.d.ts.map +0 -1
- package/dist/openapi/serve.js.map +0 -1
- package/dist/openapi/spec-factory.d.ts +0 -65
- package/dist/openapi/spec-factory.d.ts.map +0 -1
- package/dist/openapi/spec-factory.js +0 -52
- package/dist/openapi/spec-factory.js.map +0 -1
- package/dist/openapi/spec.d.ts +0 -29
- package/dist/openapi/spec.d.ts.map +0 -1
- package/dist/openapi/spec.js +0 -50
- package/dist/openapi/spec.js.map +0 -1
- package/dist/openapi/swagger.d.ts.map +0 -1
- package/dist/openapi/swagger.js.map +0 -1
- package/dist/pattern.d.ts +0 -71
- package/dist/pattern.d.ts.map +0 -1
- package/dist/pattern.js +0 -239
- package/dist/pattern.js.map +0 -1
- package/dist/peer.d.ts +0 -17
- package/dist/peer.d.ts.map +0 -1
- package/dist/peer.js +0 -50
- package/dist/peer.js.map +0 -1
- package/dist/plugin.d.ts +0 -228
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -666
- package/dist/plugin.js.map +0 -1
- package/dist/powered-by.d.ts +0 -7
- package/dist/powered-by.d.ts.map +0 -1
- package/dist/powered-by.js +0 -11
- package/dist/powered-by.js.map +0 -1
- package/dist/pretty-json.d.ts +0 -10
- package/dist/pretty-json.d.ts.map +0 -1
- package/dist/pretty-json.js +0 -47
- package/dist/pretty-json.js.map +0 -1
- package/dist/producer-stream.d.ts +0 -47
- package/dist/producer-stream.d.ts.map +0 -1
- package/dist/producer-stream.js +0 -267
- package/dist/producer-stream.js.map +0 -1
- package/dist/proxy.d.ts +0 -90
- package/dist/proxy.d.ts.map +0 -1
- package/dist/proxy.js +0 -274
- package/dist/proxy.js.map +0 -1
- package/dist/python-type-emitter.d.ts +0 -24
- package/dist/python-type-emitter.d.ts.map +0 -1
- package/dist/python-type-emitter.js +0 -157
- package/dist/python-type-emitter.js.map +0 -1
- package/dist/realtime/bus.d.ts.map +0 -1
- package/dist/realtime/bus.js.map +0 -1
- package/dist/realtime/register.d.ts +0 -3
- package/dist/realtime/register.d.ts.map +0 -1
- package/dist/realtime/register.js +0 -10
- package/dist/realtime/register.js.map +0 -1
- package/dist/realtime/route.d.ts.map +0 -1
- package/dist/realtime/route.js.map +0 -1
- package/dist/realtime/server.d.ts.map +0 -1
- package/dist/realtime/server.js.map +0 -1
- package/dist/request-id.d.ts +0 -19
- package/dist/request-id.d.ts.map +0 -1
- package/dist/request-id.js +0 -16
- package/dist/request-id.js.map +0 -1
- package/dist/request-limits.d.ts +0 -3
- package/dist/request-limits.d.ts.map +0 -1
- package/dist/request-limits.js +0 -3
- package/dist/request-limits.js.map +0 -1
- package/dist/request-path.d.ts +0 -33
- package/dist/request-path.d.ts.map +0 -1
- package/dist/request-path.js +0 -178
- package/dist/request-path.js.map +0 -1
- package/dist/request-to-curl.d.ts +0 -15
- package/dist/request-to-curl.d.ts.map +0 -1
- package/dist/request-to-curl.js +0 -48
- package/dist/request-to-curl.js.map +0 -1
- package/dist/response.d.ts +0 -86
- package/dist/response.d.ts.map +0 -1
- package/dist/response.js +0 -313
- package/dist/response.js.map +0 -1
- package/dist/rust-type-emitter.d.ts +0 -44
- package/dist/rust-type-emitter.d.ts.map +0 -1
- package/dist/rust-type-emitter.js +0 -463
- package/dist/rust-type-emitter.js.map +0 -1
- package/dist/secure-headers.d.ts +0 -16
- package/dist/secure-headers.d.ts.map +0 -1
- package/dist/secure-headers.js +0 -53
- package/dist/secure-headers.js.map +0 -1
- package/dist/serve-register.d.ts +0 -6
- package/dist/serve-register.d.ts.map +0 -1
- package/dist/serve-register.js +0 -9
- package/dist/serve-register.js.map +0 -1
- package/dist/serve-slot.d.ts +0 -9
- package/dist/serve-slot.d.ts.map +0 -1
- package/dist/serve-slot.js +0 -52
- package/dist/serve-slot.js.map +0 -1
- package/dist/serve.d.ts +0 -38
- package/dist/serve.d.ts.map +0 -1
- package/dist/serve.js +0 -157
- package/dist/serve.js.map +0 -1
- package/dist/server-timing.d.ts +0 -9
- package/dist/server-timing.d.ts.map +0 -1
- package/dist/server-timing.js +0 -51
- package/dist/server-timing.js.map +0 -1
- package/dist/static.d.ts +0 -21
- package/dist/static.d.ts.map +0 -1
- package/dist/static.js +0 -102
- package/dist/static.js.map +0 -1
- package/dist/telemetry/otel.d.ts.map +0 -1
- package/dist/telemetry/otel.js.map +0 -1
- package/dist/testing.d.ts +0 -36
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -124
- package/dist/testing.js.map +0 -1
- package/dist/timeout.d.ts +0 -13
- package/dist/timeout.d.ts.map +0 -1
- package/dist/timeout.js +0 -36
- package/dist/timeout.js.map +0 -1
- package/dist/tree.d.ts +0 -197
- package/dist/tree.d.ts.map +0 -1
- package/dist/tree.js +0 -437
- package/dist/tree.js.map +0 -1
- package/dist/trust.d.ts +0 -21
- package/dist/trust.d.ts.map +0 -1
- package/dist/trust.js +0 -100
- package/dist/trust.js.map +0 -1
- package/dist/ts-type-emitter.d.ts +0 -8
- package/dist/ts-type-emitter.d.ts.map +0 -1
- package/dist/ts-type-emitter.js +0 -150
- package/dist/ts-type-emitter.js.map +0 -1
- package/dist/type-emitter.d.ts +0 -36
- package/dist/type-emitter.d.ts.map +0 -1
- package/dist/type-emitter.js +0 -729
- package/dist/type-emitter.js.map +0 -1
- package/dist/type-extractor.d.ts +0 -43
- package/dist/type-extractor.d.ts.map +0 -1
- package/dist/type-extractor.js +0 -819
- package/dist/type-extractor.js.map +0 -1
- package/dist/types.d.ts +0 -467
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -96
- package/dist/types.js.map +0 -1
- package/dist/validation.d.ts +0 -31
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js +0 -335
- package/dist/validation.js.map +0 -1
- package/dist/with-headers.d.ts +0 -15
- package/dist/with-headers.d.ts.map +0 -1
- package/dist/with-headers.js +0 -45
- package/dist/with-headers.js.map +0 -1
- package/dist/ws/bun.d.ts.map +0 -1
- package/dist/ws/bun.js.map +0 -1
- package/dist/ws/cloudflare.d.ts.map +0 -1
- package/dist/ws/cloudflare.js.map +0 -1
- package/dist/ws/deno.d.ts +0 -13
- package/dist/ws/deno.d.ts.map +0 -1
- package/dist/ws/deno.js +0 -133
- package/dist/ws/deno.js.map +0 -1
- package/dist/ws/node.d.ts.map +0 -1
- package/dist/ws/node.js.map +0 -1
- package/dist/ws/session.d.ts.map +0 -1
- package/dist/ws/session.js.map +0 -1
- package/dist/ws/shared.d.ts.map +0 -1
- package/dist/ws/shared.js.map +0 -1
- package/dist/ws-origin.d.ts +0 -20
- package/dist/ws-origin.d.ts.map +0 -1
- package/dist/ws-origin.js +0 -41
- package/dist/ws-origin.js.map +0 -1
- package/dist/yaml.d.ts +0 -18
- package/dist/yaml.d.ts.map +0 -1
- package/dist/yaml.js +0 -101
- package/dist/yaml.js.map +0 -1
- package/docs/api-ref/go.md +0 -399
- package/docs/api-ref/python.md +0 -399
- package/docs/api-ref/rust.md +0 -399
- package/docs/api-ref/typescript.md +0 -399
- package/docs/invalidate-spec.md +0 -333
- package/docs/meta-spec.md +0 -555
- package/docs/packaging.md +0 -104
- package/docs/regression-matrix/README.md +0 -32
- package/docs/regression-matrix/review.md +0 -44
- package/docs/regression-matrix/ws1-3.md +0 -97
- package/docs/regression-matrix/ws4-8.md +0 -107
- package/docs/regression-matrix/ws9-12.md +0 -266
- package/docs/sdk.md +0 -798
- package/src/accepts.ts +0 -136
- package/src/body-kind.ts +0 -67
- package/src/body-limit.ts +0 -152
- package/src/build/index.ts +0 -217
- package/src/cli-args.ts +0 -123
- package/src/cli-go/auth.go +0 -26
- package/src/cli-go/config.go +0 -192
- package/src/cli-go/errors.go +0 -75
- package/src/cli-go/multipart.go +0 -79
- package/src/cli-go/output.go +0 -163
- package/src/cli-go/root.go +0 -30
- package/src/cli-go/stream.go +0 -88
- package/src/cli-go/version.go +0 -5
- package/src/cli.ts +0 -209
- package/src/client/defaults.ts +0 -47
- package/src/client/error.ts +0 -82
- package/src/client/http.ts +0 -737
- package/src/client/index.ts +0 -157
- package/src/client/path.ts +0 -169
- package/src/client/redirect-policy.ts +0 -19
- package/src/client/sdk.ts +0 -351
- package/src/client/sse.ts +0 -128
- package/src/client/types.ts +0 -206
- package/src/client/ws.ts +0 -149
- package/src/client-go/errors.go +0 -236
- package/src/client-go/export.go +0 -44
- package/src/client-go/invalidation.go +0 -371
- package/src/client-go/nullable.go +0 -62
- package/src/client-go/realtime.go +0 -354
- package/src/client-go/result.go +0 -20
- package/src/client-go/runtime.go +0 -975
- package/src/client-go/sse.go +0 -159
- package/src/client-go/transport.go +0 -495
- package/src/client-go/ws.go +0 -128
- package/src/client-info.ts +0 -79
- package/src/client-mcp/README.md +0 -10
- package/src/client-mcp/server.ts +0 -221
- package/src/client-mcp/types.ts +0 -19
- package/src/client-python/_errors.py +0 -115
- package/src/client-python/_invalidation.py +0 -494
- package/src/client-python/_realtime.py +0 -179
- package/src/client-python/_runtime.py +0 -860
- package/src/client-python/_sse.py +0 -155
- package/src/client-python/_transport.py +0 -366
- package/src/client-python/_ws.py +0 -159
- package/src/client-python/py.typed +0 -0
- package/src/client-rust/errors.rs +0 -220
- package/src/client-rust/invalidation.rs +0 -412
- package/src/client-rust/invalidation_sync.rs +0 -93
- package/src/client-rust/nullable.rs +0 -17
- package/src/client-rust/realtime.rs +0 -702
- package/src/client-rust/result.rs +0 -22
- package/src/client-rust/runtime.rs +0 -980
- package/src/client-rust/runtime_sync.rs +0 -484
- package/src/client-rust/sse.rs +0 -188
- package/src/client-rust/ws.rs +0 -167
- package/src/codegen-go-cli.ts +0 -1066
- package/src/codegen-go.ts +0 -970
- package/src/codegen-hash.ts +0 -8
- package/src/codegen-ir.ts +0 -812
- package/src/codegen-lang.ts +0 -517
- package/src/codegen-load.ts +0 -150
- package/src/codegen-loaders.ts +0 -50
- package/src/codegen-mcp.ts +0 -445
- package/src/codegen-python.ts +0 -916
- package/src/codegen-route-tree-intern.ts +0 -198
- package/src/codegen-rust.ts +0 -1402
- package/src/codegen-sanitize.ts +0 -57
- package/src/codegen-schema-naming.ts +0 -165
- package/src/codegen-sdk-model.ts +0 -228
- package/src/codegen.ts +0 -5089
- package/src/context.ts +0 -325
- package/src/cookie-sign.ts +0 -119
- package/src/cookie.ts +0 -143
- package/src/cors.ts +0 -95
- package/src/crypto.ts +0 -38
- package/src/csrf.ts +0 -86
- package/src/curl-logger.ts +0 -258
- package/src/detect-runtime.ts +0 -17
- package/src/dict.ts +0 -12
- package/src/error.ts +0 -55
- package/src/errors.ts +0 -85
- package/src/etag.ts +0 -97
- package/src/feature-detect.ts +0 -147
- package/src/feature-load.ts +0 -23
- package/src/feature-slots.ts +0 -70
- package/src/fetch-request.ts +0 -13
- package/src/gen-process.ts +0 -42
- package/src/gen-write.ts +0 -127
- package/src/glob.ts +0 -109
- package/src/go-type-emitter.ts +0 -660
- package/src/honey-response.ts +0 -379
- package/src/i18n-slot.ts +0 -30
- package/src/i18n.ts +0 -300
- package/src/index.ts +0 -3829
- package/src/init.ts +0 -161
- package/src/input.ts +0 -8
- package/src/invalidate-check.ts +0 -205
- package/src/invoke-user.ts +0 -95
- package/src/ip-restrict.ts +0 -79
- package/src/ip.ts +0 -194
- package/src/logger.ts +0 -178
- package/src/media-type.ts +0 -104
- package/src/meta-spec-merge.ts +0 -80
- package/src/meta-spec.ts +0 -718
- package/src/middleware.ts +0 -331
- package/src/node-request.ts +0 -431
- package/src/node.ts +0 -454
- package/src/openapi/collect.ts +0 -50
- package/src/openapi/docs-page.ts +0 -89
- package/src/openapi/document.ts +0 -902
- package/src/openapi/json-schema-slot.ts +0 -53
- package/src/openapi/register.ts +0 -23
- package/src/openapi/scalar.ts +0 -34
- package/src/openapi/serve.ts +0 -39
- package/src/openapi/spec-factory.ts +0 -100
- package/src/openapi/spec.ts +0 -74
- package/src/openapi/swagger.ts +0 -35
- package/src/pattern.ts +0 -245
- package/src/peer.ts +0 -53
- package/src/plugin.ts +0 -864
- package/src/powered-by.ts +0 -18
- package/src/pretty-json.ts +0 -56
- package/src/producer-stream.ts +0 -296
- package/src/proxy.ts +0 -370
- package/src/python-type-emitter.ts +0 -181
- package/src/realtime/bus.ts +0 -140
- package/src/realtime/register.ts +0 -13
- package/src/realtime/route.ts +0 -153
- package/src/realtime/server.ts +0 -298
- package/src/request-id.ts +0 -32
- package/src/request-limits.ts +0 -2
- package/src/request-path.ts +0 -165
- package/src/request-to-curl.ts +0 -52
- package/src/response.ts +0 -411
- package/src/rust-type-emitter.ts +0 -548
- package/src/secure-headers.ts +0 -74
- package/src/serve-register.ts +0 -12
- package/src/serve-slot.ts +0 -58
- package/src/serve.ts +0 -220
- package/src/server-timing.ts +0 -71
- package/src/static.ts +0 -112
- package/src/telemetry/otel.ts +0 -156
- package/src/testing.ts +0 -167
- package/src/timeout.ts +0 -45
- package/src/tree.ts +0 -558
- package/src/trust.ts +0 -117
- package/src/ts-type-emitter.ts +0 -168
- package/src/type-emitter.ts +0 -760
- package/src/type-extractor.ts +0 -855
- package/src/types.ts +0 -756
- package/src/validation.ts +0 -413
- package/src/with-headers.ts +0 -45
- package/src/ws/bun.ts +0 -120
- package/src/ws/cloudflare.ts +0 -192
- package/src/ws/deno.ts +0 -188
- package/src/ws/node.ts +0 -240
- package/src/ws/session.ts +0 -73
- package/src/ws/shared.ts +0 -140
- package/src/ws-origin.ts +0 -53
- package/src/yaml.ts +0 -103
|
@@ -1,975 +0,0 @@
|
|
|
1
|
-
// Code generated by honey. DO NOT EDIT.
|
|
2
|
-
|
|
3
|
-
package sdk
|
|
4
|
-
|
|
5
|
-
import (
|
|
6
|
-
"bytes"
|
|
7
|
-
"context"
|
|
8
|
-
"crypto/rand"
|
|
9
|
-
"encoding/json"
|
|
10
|
-
"errors"
|
|
11
|
-
"fmt"
|
|
12
|
-
"io"
|
|
13
|
-
"math"
|
|
14
|
-
"mime/multipart"
|
|
15
|
-
"net/http"
|
|
16
|
-
"net/textproto"
|
|
17
|
-
"net/url"
|
|
18
|
-
"reflect"
|
|
19
|
-
"sort"
|
|
20
|
-
"strconv"
|
|
21
|
-
"strings"
|
|
22
|
-
"sync"
|
|
23
|
-
"time"
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
// RequestContext carries mutable request metadata through OnRequest hook
|
|
27
|
-
// invocations. Hooks may mutate Method, URL, Headers, or Body; mutations are
|
|
28
|
-
// applied to the outgoing request after the full hook chain completes.
|
|
29
|
-
// Selector / IsStale / InvalidatedBy mirror the TS hook ctx and are populated
|
|
30
|
-
// only when the SDK has an active StaleTracker.
|
|
31
|
-
type RequestContext struct {
|
|
32
|
-
Method string
|
|
33
|
-
URL string
|
|
34
|
-
Path string
|
|
35
|
-
Headers http.Header
|
|
36
|
-
Body []byte
|
|
37
|
-
IsRetry bool
|
|
38
|
-
Selector string
|
|
39
|
-
IsStale bool
|
|
40
|
-
InvalidatedBy []string
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ResponseContext carries response metadata through OnResponse hook invocations.
|
|
44
|
-
// Hooks may inspect or mutate Body bytes prior to JSON unmarshal in the caller.
|
|
45
|
-
// Status is observational and is not mutated by hooks.
|
|
46
|
-
// Selector / IsStale / InvalidatedBy mirror the TS hook ctx and are populated
|
|
47
|
-
// only when the SDK has an active StaleTracker.
|
|
48
|
-
type ResponseContext struct {
|
|
49
|
-
Status int
|
|
50
|
-
Headers http.Header
|
|
51
|
-
Body []byte
|
|
52
|
-
IsRetry bool
|
|
53
|
-
Selector string
|
|
54
|
-
IsStale bool
|
|
55
|
-
InvalidatedBy []string
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Config holds all configuration for the SDK client.
|
|
59
|
-
//
|
|
60
|
-
// Timeout bounds a whole regular request, including reading the response body.
|
|
61
|
-
// Streams (SSE, WebSocket, realtime) are not bounded by it. Zero means 30s; a
|
|
62
|
-
// negative value disables the timeout.
|
|
63
|
-
//
|
|
64
|
-
// HTTPClient defaults to a client that does not follow redirects to another
|
|
65
|
-
// host (the 3xx response is returned as an error instead), so custom auth
|
|
66
|
-
// headers never reach a different origin.
|
|
67
|
-
//
|
|
68
|
-
// MaxResponseBytes caps a buffered response body. Zero means 100 MiB; a
|
|
69
|
-
// negative value disables the cap.
|
|
70
|
-
type Config struct {
|
|
71
|
-
BaseURL string
|
|
72
|
-
BearerToken string
|
|
73
|
-
Headers map[string]string
|
|
74
|
-
Timeout time.Duration
|
|
75
|
-
ThrowOnError bool
|
|
76
|
-
StaleMaxEntries int
|
|
77
|
-
Invalidation *InvalidationConfig
|
|
78
|
-
OnAuthExpired func(context.Context) (string, error)
|
|
79
|
-
HTTPClient *http.Client
|
|
80
|
-
AuthHeaderName string
|
|
81
|
-
AuthHeaderPrefix string
|
|
82
|
-
OnRequest []func(*RequestContext) error
|
|
83
|
-
OnResponse []func(*ResponseContext) error
|
|
84
|
-
OnLog func(LogEntry)
|
|
85
|
-
MaxResponseBytes int64
|
|
86
|
-
|
|
87
|
-
auth *authState
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const (
|
|
91
|
-
defaultTimeout = 30 * time.Second
|
|
92
|
-
defaultMaxResponseBytes = 100 << 20
|
|
93
|
-
maxErrorMessageRunes = 512
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
// authState holds the current bearer token so a refreshed token is reused by
|
|
97
|
-
// later calls, and serializes refreshes so N concurrent 401s refresh once.
|
|
98
|
-
type authState struct {
|
|
99
|
-
mu sync.Mutex
|
|
100
|
-
token string
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
func (a *authState) current(cfg Config) string {
|
|
104
|
-
if a == nil {
|
|
105
|
-
return cfg.BearerToken
|
|
106
|
-
}
|
|
107
|
-
a.mu.Lock()
|
|
108
|
-
defer a.mu.Unlock()
|
|
109
|
-
return a.token
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// refresh calls OnAuthExpired unless another call already replaced rejected.
|
|
113
|
-
func (a *authState) refresh(ctx context.Context, cfg Config, rejected string) (string, error) {
|
|
114
|
-
if a == nil {
|
|
115
|
-
return cfg.OnAuthExpired(ctx)
|
|
116
|
-
}
|
|
117
|
-
a.mu.Lock()
|
|
118
|
-
defer a.mu.Unlock()
|
|
119
|
-
if a.token != rejected {
|
|
120
|
-
return a.token, nil
|
|
121
|
-
}
|
|
122
|
-
token, err := cfg.OnAuthExpired(ctx)
|
|
123
|
-
if err != nil {
|
|
124
|
-
return "", err
|
|
125
|
-
}
|
|
126
|
-
a.token = token
|
|
127
|
-
return token, nil
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// prepareConfig fills defaults. NewClient calls it once.
|
|
131
|
-
func prepareConfig(cfg Config) Config {
|
|
132
|
-
if cfg.HTTPClient == nil {
|
|
133
|
-
cfg.HTTPClient = &http.Client{CheckRedirect: sameHostRedirects}
|
|
134
|
-
}
|
|
135
|
-
if cfg.Timeout == 0 {
|
|
136
|
-
cfg.Timeout = defaultTimeout
|
|
137
|
-
}
|
|
138
|
-
if cfg.MaxResponseBytes == 0 {
|
|
139
|
-
cfg.MaxResponseBytes = defaultMaxResponseBytes
|
|
140
|
-
}
|
|
141
|
-
cfg.auth = &authState{token: cfg.BearerToken}
|
|
142
|
-
return cfg
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// sameHostRedirects follows redirects on the same scheme and host only.
|
|
146
|
-
func sameHostRedirects(req *http.Request, via []*http.Request) error {
|
|
147
|
-
if len(via) >= 10 {
|
|
148
|
-
return errors.New("honey: stopped after 10 redirects")
|
|
149
|
-
}
|
|
150
|
-
first := via[0].URL
|
|
151
|
-
if req.URL.Scheme != first.Scheme || req.URL.Host != first.Host {
|
|
152
|
-
return http.ErrUseLastResponse
|
|
153
|
-
}
|
|
154
|
-
return nil
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// LogEntry is the payload passed to Config.OnLog. Consumers plug in their own
|
|
158
|
-
// logger; the SDK never formats, levels, or persists. Status is a pointer so
|
|
159
|
-
// nil encodes "omitted" (request_start) without colliding with a real 0 status.
|
|
160
|
-
// Err is the underlying error on the "error" event; nil otherwise. JSON tags
|
|
161
|
-
// match the TS/Python LogEntry shape for cross-language consumer parity.
|
|
162
|
-
type LogEntry struct {
|
|
163
|
-
Level string `json:"level"`
|
|
164
|
-
Event string `json:"event"`
|
|
165
|
-
Operation string `json:"operation"`
|
|
166
|
-
DurationMs int64 `json:"duration_ms"`
|
|
167
|
-
Status *int `json:"status,omitempty"`
|
|
168
|
-
Err error `json:"-"`
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// emitLog invokes the OnLog callback if configured, swallowing any panic so a
|
|
172
|
-
// faulty logger cannot break the request path. Mirrors Python _emit_log /
|
|
173
|
-
// TS optional-chained call.
|
|
174
|
-
func emitLog(cfg Config, entry LogEntry) {
|
|
175
|
-
if cfg.OnLog == nil {
|
|
176
|
-
return
|
|
177
|
-
}
|
|
178
|
-
defer func() {
|
|
179
|
-
_ = recover()
|
|
180
|
-
}()
|
|
181
|
-
cfg.OnLog(entry)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
func errStatus(err error) *int {
|
|
185
|
-
var apiErr APIError
|
|
186
|
-
if errors.As(err, &apiErr) {
|
|
187
|
-
s := apiErr.Status()
|
|
188
|
-
return &s
|
|
189
|
-
}
|
|
190
|
-
return nil
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// InvalidationConfig controls cache invalidation behaviour. StaleTime is in
|
|
194
|
-
// milliseconds; ≤0 disables the tracker. StaleMaxEntries caps the LRU map.
|
|
195
|
-
// MaxSourcesPerTarget caps the `by` list per stale entry.
|
|
196
|
-
type InvalidationConfig struct {
|
|
197
|
-
StaleTime int64
|
|
198
|
-
StaleMaxEntries int
|
|
199
|
-
MaxSourcesPerTarget int
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
type requestResult struct {
|
|
203
|
-
body []byte
|
|
204
|
-
status int
|
|
205
|
-
resp *http.Response
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// requestBody is one request payload. JSON values and byte payloads can be
|
|
209
|
-
// sent again on an auth retry; a Reader cannot.
|
|
210
|
-
type requestBody struct {
|
|
211
|
-
json any
|
|
212
|
-
hasJSON bool
|
|
213
|
-
raw []byte
|
|
214
|
-
hasRaw bool
|
|
215
|
-
reader io.Reader
|
|
216
|
-
contentType string
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
func noBody() requestBody { return requestBody{} }
|
|
220
|
-
|
|
221
|
-
func jsonBody(v any) requestBody { return requestBody{json: v, hasJSON: true} }
|
|
222
|
-
|
|
223
|
-
func readerBody(r io.Reader, contentType string) requestBody {
|
|
224
|
-
return requestBody{reader: r, contentType: contentType}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
func formBody(values url.Values) requestBody {
|
|
228
|
-
return requestBody{raw: []byte(values.Encode()), hasRaw: true, contentType: "application/x-www-form-urlencoded"}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
func rawBody(raw []byte, contentType string) requestBody {
|
|
232
|
-
return requestBody{raw: raw, hasRaw: true, contentType: contentType}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// setHeaderValue sets a header parameter: nil and nil pointers are skipped,
|
|
236
|
-
// slices are joined with commas.
|
|
237
|
-
func setHeaderValue(h map[string]string, name string, v any) {
|
|
238
|
-
var q queryList
|
|
239
|
-
q.set(name, v)
|
|
240
|
-
if len(q) == 0 {
|
|
241
|
-
return
|
|
242
|
-
}
|
|
243
|
-
values := make([]string, 0, len(q))
|
|
244
|
-
for _, p := range q {
|
|
245
|
-
values = append(values, p.value)
|
|
246
|
-
}
|
|
247
|
-
h[name] = strings.Join(values, ",")
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// hasHeader reports whether h has name in any casing.
|
|
251
|
-
func hasHeader(h map[string]string, name string) bool {
|
|
252
|
-
for k := range h {
|
|
253
|
-
if strings.EqualFold(k, name) {
|
|
254
|
-
return true
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return false
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
func (b requestBody) present() bool { return b.hasJSON || b.hasRaw || b.reader != nil }
|
|
261
|
-
|
|
262
|
-
func (b requestBody) replayable() bool { return b.reader == nil }
|
|
263
|
-
|
|
264
|
-
// bytes returns the encoded payload for JSON and raw bodies.
|
|
265
|
-
func (b requestBody) bytes() ([]byte, error) {
|
|
266
|
-
if b.hasRaw {
|
|
267
|
-
return b.raw, nil
|
|
268
|
-
}
|
|
269
|
-
if b.hasJSON {
|
|
270
|
-
encoded, err := json.Marshal(b.json)
|
|
271
|
-
if err != nil {
|
|
272
|
-
return nil, fmt.Errorf("honey: marshal body: %w", err)
|
|
273
|
-
}
|
|
274
|
-
return encoded, nil
|
|
275
|
-
}
|
|
276
|
-
return nil, nil
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// FilePart is one file in a multipart/form-data upload. The SDK reads Data
|
|
280
|
-
// fully before sending, so the request can be retried after an auth refresh.
|
|
281
|
-
type FilePart struct {
|
|
282
|
-
Filename string
|
|
283
|
-
ContentType string
|
|
284
|
-
Data io.Reader
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
type multipartField struct {
|
|
288
|
-
name string
|
|
289
|
-
value string
|
|
290
|
-
file *FilePart
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
func textField(name string, value any) multipartField {
|
|
294
|
-
return multipartField{name: name, value: formatQueryValue(value)}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
func fileField(name string, file FilePart) multipartField {
|
|
298
|
-
return multipartField{name: name, file: &file}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
func multipartBody(fields []multipartField) (requestBody, error) {
|
|
302
|
-
var buf bytes.Buffer
|
|
303
|
-
w := multipart.NewWriter(&buf)
|
|
304
|
-
for _, f := range fields {
|
|
305
|
-
if f.file == nil {
|
|
306
|
-
if err := w.WriteField(f.name, f.value); err != nil {
|
|
307
|
-
return requestBody{}, err
|
|
308
|
-
}
|
|
309
|
-
continue
|
|
310
|
-
}
|
|
311
|
-
h := make(textproto.MIMEHeader)
|
|
312
|
-
filename := f.file.Filename
|
|
313
|
-
if filename == "" {
|
|
314
|
-
filename = f.name
|
|
315
|
-
}
|
|
316
|
-
h.Set("Content-Disposition", fmt.Sprintf(`form-data; name=%s; filename=%s`, strconv.Quote(f.name), strconv.Quote(filename)))
|
|
317
|
-
ct := f.file.ContentType
|
|
318
|
-
if ct == "" {
|
|
319
|
-
ct = "application/octet-stream"
|
|
320
|
-
}
|
|
321
|
-
h.Set("Content-Type", ct)
|
|
322
|
-
part, err := w.CreatePart(h)
|
|
323
|
-
if err != nil {
|
|
324
|
-
return requestBody{}, err
|
|
325
|
-
}
|
|
326
|
-
if f.file.Data != nil {
|
|
327
|
-
if _, err := io.Copy(part, f.file.Data); err != nil {
|
|
328
|
-
return requestBody{}, err
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
if err := w.Close(); err != nil {
|
|
333
|
-
return requestBody{}, err
|
|
334
|
-
}
|
|
335
|
-
return requestBody{raw: buf.Bytes(), hasRaw: true, contentType: w.FormDataContentType()}, nil
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// PathParamError reports a path parameter that is missing, or that would
|
|
339
|
-
// change the request path once a URL parser normalizes it ("", "." and "..").
|
|
340
|
-
type PathParamError struct {
|
|
341
|
-
Name string
|
|
342
|
-
Value string
|
|
343
|
-
Missing bool
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
func (e *PathParamError) Error() string {
|
|
347
|
-
if e.Missing {
|
|
348
|
-
return "Missing path param: " + e.Name
|
|
349
|
-
}
|
|
350
|
-
return fmt.Sprintf("Invalid path param %q: %q is not a path segment", e.Name, e.Value)
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
func percentEncode(s string, keep func(c byte) bool, spaceAsPlus bool) string {
|
|
354
|
-
const hex = "0123456789ABCDEF"
|
|
355
|
-
var b strings.Builder
|
|
356
|
-
for i := 0; i < len(s); i++ {
|
|
357
|
-
c := s[i]
|
|
358
|
-
switch {
|
|
359
|
-
case (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || keep(c):
|
|
360
|
-
b.WriteByte(c)
|
|
361
|
-
case c == ' ' && spaceAsPlus:
|
|
362
|
-
b.WriteByte('+')
|
|
363
|
-
default:
|
|
364
|
-
b.WriteByte('%')
|
|
365
|
-
b.WriteByte(hex[c>>4])
|
|
366
|
-
b.WriteByte(hex[c&0x0f])
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
return b.String()
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// escapePathSegment encodes like JavaScript's encodeURIComponent, so every
|
|
373
|
-
// SDK language (and the TypeScript client) sends the same path bytes.
|
|
374
|
-
func escapePathSegment(s string) string {
|
|
375
|
-
return percentEncode(s, func(c byte) bool { return strings.IndexByte("-_.!~*'()", c) >= 0 }, false)
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// escapeQueryComponent encodes like URLSearchParams (space becomes '+').
|
|
379
|
-
func escapeQueryComponent(s string) string {
|
|
380
|
-
return percentEncode(s, func(c byte) bool { return strings.IndexByte("*-._", c) >= 0 }, true)
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
func encodeSegmentValue(name, value string) (string, error) {
|
|
384
|
-
if value == "" || value == "." || value == ".." {
|
|
385
|
-
return "", &PathParamError{Name: name, Value: value}
|
|
386
|
-
}
|
|
387
|
-
return escapePathSegment(value), nil
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// expandPath fills a path template, segment by segment, with the same grammar
|
|
391
|
-
// as the TypeScript client: `:name` (or `:name?`) takes a whole segment,
|
|
392
|
-
// `*name` (or `*`) as the last segment takes the rest of the path, `{name}`
|
|
393
|
-
// may appear anywhere inside a segment. Values are encoded; values that a URL
|
|
394
|
-
// parser would collapse ("", ".", "..") are rejected.
|
|
395
|
-
func expandPath(template string, params map[string]string) (string, error) {
|
|
396
|
-
segments := strings.Split(template, "/")
|
|
397
|
-
out := make([]string, 0, len(segments))
|
|
398
|
-
for i, seg := range segments {
|
|
399
|
-
switch {
|
|
400
|
-
case len(seg) > 1 && seg[0] == ':':
|
|
401
|
-
optional := strings.HasSuffix(seg, "?")
|
|
402
|
-
name := strings.TrimSuffix(seg[1:], "?")
|
|
403
|
-
if !optional {
|
|
404
|
-
name = seg[1:]
|
|
405
|
-
}
|
|
406
|
-
value, ok := params[name]
|
|
407
|
-
if !ok {
|
|
408
|
-
if optional {
|
|
409
|
-
continue
|
|
410
|
-
}
|
|
411
|
-
return "", &PathParamError{Name: name, Missing: true}
|
|
412
|
-
}
|
|
413
|
-
enc, err := encodeSegmentValue(name, value)
|
|
414
|
-
if err != nil {
|
|
415
|
-
return "", err
|
|
416
|
-
}
|
|
417
|
-
out = append(out, enc)
|
|
418
|
-
case len(seg) > 0 && seg[0] == '*' && i == len(segments)-1:
|
|
419
|
-
name := "*"
|
|
420
|
-
if len(seg) > 1 {
|
|
421
|
-
name = seg[1:]
|
|
422
|
-
}
|
|
423
|
-
value, ok := params[name]
|
|
424
|
-
if !ok {
|
|
425
|
-
if len(seg) == 1 {
|
|
426
|
-
out = append(out, "")
|
|
427
|
-
continue
|
|
428
|
-
}
|
|
429
|
-
return "", &PathParamError{Name: name, Missing: true}
|
|
430
|
-
}
|
|
431
|
-
if value == "" {
|
|
432
|
-
out = append(out, "")
|
|
433
|
-
continue
|
|
434
|
-
}
|
|
435
|
-
parts := strings.Split(value, "/")
|
|
436
|
-
for j, part := range parts {
|
|
437
|
-
enc, err := encodeSegmentValue(name, part)
|
|
438
|
-
if err != nil {
|
|
439
|
-
return "", err
|
|
440
|
-
}
|
|
441
|
-
parts[j] = enc
|
|
442
|
-
}
|
|
443
|
-
out = append(out, strings.Join(parts, "/"))
|
|
444
|
-
default:
|
|
445
|
-
var b strings.Builder
|
|
446
|
-
rest := seg
|
|
447
|
-
for {
|
|
448
|
-
open := strings.IndexByte(rest, '{')
|
|
449
|
-
end := -1
|
|
450
|
-
if open >= 0 {
|
|
451
|
-
end = strings.IndexByte(rest[open:], '}')
|
|
452
|
-
}
|
|
453
|
-
if open < 0 || end < 0 || strings.ContainsRune(rest[open+1:open+end], '{') {
|
|
454
|
-
b.WriteString(rest)
|
|
455
|
-
break
|
|
456
|
-
}
|
|
457
|
-
name := rest[open+1 : open+end]
|
|
458
|
-
value, ok := params[name]
|
|
459
|
-
if !ok {
|
|
460
|
-
return "", &PathParamError{Name: name, Missing: true}
|
|
461
|
-
}
|
|
462
|
-
enc, err := encodeSegmentValue(name, value)
|
|
463
|
-
if err != nil {
|
|
464
|
-
return "", err
|
|
465
|
-
}
|
|
466
|
-
b.WriteString(rest[:open])
|
|
467
|
-
b.WriteString(enc)
|
|
468
|
-
rest = rest[open+end+1:]
|
|
469
|
-
}
|
|
470
|
-
out = append(out, b.String())
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
return strings.Join(out, "/"), nil
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// queryPair is one key=value in send order.
|
|
477
|
-
type queryPair struct {
|
|
478
|
-
key string
|
|
479
|
-
value string
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
type queryList []queryPair
|
|
483
|
-
|
|
484
|
-
// set appends v under key: nil and nil pointers are skipped, slices repeat the key.
|
|
485
|
-
func (q *queryList) set(key string, v any) {
|
|
486
|
-
rv := reflect.ValueOf(v)
|
|
487
|
-
for rv.IsValid() && (rv.Kind() == reflect.Pointer || rv.Kind() == reflect.Interface) {
|
|
488
|
-
if rv.IsNil() {
|
|
489
|
-
return
|
|
490
|
-
}
|
|
491
|
-
rv = rv.Elem()
|
|
492
|
-
}
|
|
493
|
-
if !rv.IsValid() {
|
|
494
|
-
return
|
|
495
|
-
}
|
|
496
|
-
if (rv.Kind() == reflect.Slice || rv.Kind() == reflect.Array) && rv.Type().Elem().Kind() != reflect.Uint8 {
|
|
497
|
-
for i := 0; i < rv.Len(); i++ {
|
|
498
|
-
q.set(key, rv.Index(i).Interface())
|
|
499
|
-
}
|
|
500
|
-
return
|
|
501
|
-
}
|
|
502
|
-
*q = append(*q, queryPair{key: key, value: formatQueryValue(rv.Interface())})
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
func (q queryList) encode() string {
|
|
506
|
-
parts := make([]string, 0, len(q))
|
|
507
|
-
for _, p := range q {
|
|
508
|
-
parts = append(parts, escapeQueryComponent(p.key)+"="+escapeQueryComponent(p.value))
|
|
509
|
-
}
|
|
510
|
-
return strings.Join(parts, "&")
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// formatQueryValue renders a scalar the way every SDK language does: strings
|
|
514
|
-
// as-is, booleans as true/false, numbers in shortest decimal form, anything
|
|
515
|
-
// else as JSON.
|
|
516
|
-
func formatQueryValue(v any) string {
|
|
517
|
-
rv := reflect.ValueOf(v)
|
|
518
|
-
switch rv.Kind() {
|
|
519
|
-
case reflect.String:
|
|
520
|
-
return rv.String()
|
|
521
|
-
case reflect.Bool:
|
|
522
|
-
return strconv.FormatBool(rv.Bool())
|
|
523
|
-
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
524
|
-
return strconv.FormatInt(rv.Int(), 10)
|
|
525
|
-
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
526
|
-
return strconv.FormatUint(rv.Uint(), 10)
|
|
527
|
-
case reflect.Float32, reflect.Float64:
|
|
528
|
-
return formatFloatJS(rv.Float())
|
|
529
|
-
}
|
|
530
|
-
encoded, err := json.Marshal(v)
|
|
531
|
-
if err != nil {
|
|
532
|
-
return fmt.Sprint(v)
|
|
533
|
-
}
|
|
534
|
-
return string(encoded)
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
// formatFloatJS renders a float like JavaScript's Number#toString.
|
|
538
|
-
func formatFloatJS(f float64) string {
|
|
539
|
-
switch {
|
|
540
|
-
case math.IsNaN(f):
|
|
541
|
-
return "NaN"
|
|
542
|
-
case math.IsInf(f, 1):
|
|
543
|
-
return "Infinity"
|
|
544
|
-
case math.IsInf(f, -1):
|
|
545
|
-
return "-Infinity"
|
|
546
|
-
case f == 0:
|
|
547
|
-
return "0"
|
|
548
|
-
}
|
|
549
|
-
abs := math.Abs(f)
|
|
550
|
-
if abs >= 1e-6 && abs < 1e21 {
|
|
551
|
-
return strconv.FormatFloat(f, 'f', -1, 64)
|
|
552
|
-
}
|
|
553
|
-
s := strconv.FormatFloat(f, 'e', -1, 64)
|
|
554
|
-
mantissa, exp, _ := strings.Cut(s, "e")
|
|
555
|
-
n, _ := strconv.Atoi(exp)
|
|
556
|
-
sign := "+"
|
|
557
|
-
if n < 0 {
|
|
558
|
-
sign = "-"
|
|
559
|
-
n = -n
|
|
560
|
-
}
|
|
561
|
-
return mantissa + "e" + sign + strconv.Itoa(n)
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
// buildURL joins base and an already-escaped path, keeping the base path and
|
|
565
|
-
// base query, then appends query pairs.
|
|
566
|
-
func buildURL(baseURL, path string, query queryList) (string, error) {
|
|
567
|
-
base, err := url.Parse(baseURL)
|
|
568
|
-
if err != nil {
|
|
569
|
-
return "", err
|
|
570
|
-
}
|
|
571
|
-
if base.Scheme == "" || base.Host == "" {
|
|
572
|
-
return "", fmt.Errorf("honey: base URL %q needs a scheme and host", baseURL)
|
|
573
|
-
}
|
|
574
|
-
if !strings.HasPrefix(path, "/") {
|
|
575
|
-
path = "/" + path
|
|
576
|
-
}
|
|
577
|
-
out := *base
|
|
578
|
-
out.Fragment = ""
|
|
579
|
-
out.RawFragment = ""
|
|
580
|
-
joined := strings.TrimRight(base.EscapedPath(), "/") + path
|
|
581
|
-
unescaped, err := url.PathUnescape(joined)
|
|
582
|
-
if err != nil {
|
|
583
|
-
return "", err
|
|
584
|
-
}
|
|
585
|
-
out.Path = unescaped
|
|
586
|
-
out.RawPath = joined
|
|
587
|
-
extra := query.encode()
|
|
588
|
-
switch {
|
|
589
|
-
case out.RawQuery == "":
|
|
590
|
-
out.RawQuery = extra
|
|
591
|
-
case extra != "":
|
|
592
|
-
out.RawQuery = out.RawQuery + "&" + extra
|
|
593
|
-
}
|
|
594
|
-
return out.String(), nil
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
// doRequest executes an HTTP request, injects auth, merges headers, fires
|
|
598
|
-
// OnRequest/OnResponse hooks in declaration order, handles OnAuthExpired retry
|
|
599
|
-
// on 401, and wraps context cancellation errors. Emits OnLog lifecycle entries
|
|
600
|
-
// (request_start once at entry, response_received once for the final response,
|
|
601
|
-
// error on terminal failure) — matching TS/Python behavior where retry rounds
|
|
602
|
-
// do not double-emit.
|
|
603
|
-
func doRequest(
|
|
604
|
-
ctx context.Context,
|
|
605
|
-
cfg Config,
|
|
606
|
-
method string,
|
|
607
|
-
path string,
|
|
608
|
-
query queryList,
|
|
609
|
-
body requestBody,
|
|
610
|
-
callHeaders map[string]string,
|
|
611
|
-
operation string,
|
|
612
|
-
requestMeta *RequestMeta,
|
|
613
|
-
) (result *requestResult, err error) {
|
|
614
|
-
start := time.Now()
|
|
615
|
-
defer func() {
|
|
616
|
-
if err != nil {
|
|
617
|
-
emitLog(cfg, LogEntry{
|
|
618
|
-
Level: "error",
|
|
619
|
-
Event: "error",
|
|
620
|
-
Operation: operation,
|
|
621
|
-
DurationMs: time.Since(start).Milliseconds(),
|
|
622
|
-
Status: errStatus(err),
|
|
623
|
-
Err: err,
|
|
624
|
-
})
|
|
625
|
-
}
|
|
626
|
-
}()
|
|
627
|
-
|
|
628
|
-
if ctx.Err() != nil {
|
|
629
|
-
return nil, fmt.Errorf("honey: request canceled: %w", ctx.Err())
|
|
630
|
-
}
|
|
631
|
-
if cfg.Timeout > 0 {
|
|
632
|
-
var cancel context.CancelFunc
|
|
633
|
-
ctx, cancel = context.WithTimeout(ctx, cfg.Timeout)
|
|
634
|
-
defer cancel()
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
emitLog(cfg, LogEntry{
|
|
638
|
-
Level: "debug",
|
|
639
|
-
Event: "request_start",
|
|
640
|
-
Operation: operation,
|
|
641
|
-
})
|
|
642
|
-
|
|
643
|
-
token := cfg.auth.current(cfg)
|
|
644
|
-
result, err = executeRequest(ctx, cfg, method, path, query, body, callHeaders, token, false, requestMeta)
|
|
645
|
-
if err != nil {
|
|
646
|
-
return nil, err
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
if result.status == 401 && cfg.OnAuthExpired != nil && body.replayable() {
|
|
650
|
-
newToken, authErr := cfg.auth.refresh(ctx, cfg, token)
|
|
651
|
-
if authErr != nil {
|
|
652
|
-
err = fmt.Errorf("honey: OnAuthExpired failed: %w", authErr)
|
|
653
|
-
return nil, err
|
|
654
|
-
}
|
|
655
|
-
if newToken != "" {
|
|
656
|
-
result, err = executeRequest(ctx, cfg, method, path, query, body, callHeaders, newToken, true, requestMeta)
|
|
657
|
-
if err != nil {
|
|
658
|
-
return nil, err
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
status := result.status
|
|
664
|
-
level := "info"
|
|
665
|
-
if status >= 400 {
|
|
666
|
-
level = "warn"
|
|
667
|
-
}
|
|
668
|
-
emitLog(cfg, LogEntry{
|
|
669
|
-
Level: level,
|
|
670
|
-
Event: "response_received",
|
|
671
|
-
Operation: operation,
|
|
672
|
-
DurationMs: time.Since(start).Milliseconds(),
|
|
673
|
-
Status: &status,
|
|
674
|
-
})
|
|
675
|
-
|
|
676
|
-
if err2 := raiseForStatus(result.resp, result.body); err2 != nil {
|
|
677
|
-
err = err2
|
|
678
|
-
return nil, err
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
return result, nil
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
func wrapTransportError(ctx context.Context, err error) error {
|
|
685
|
-
if ctx.Err() != nil {
|
|
686
|
-
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
|
687
|
-
return fmt.Errorf("honey: request timed out: %w", ctx.Err())
|
|
688
|
-
}
|
|
689
|
-
if errors.Is(ctx.Err(), context.Canceled) {
|
|
690
|
-
return fmt.Errorf("honey: request canceled: %w", ctx.Err())
|
|
691
|
-
}
|
|
692
|
-
return fmt.Errorf("honey: context error: %w", ctx.Err())
|
|
693
|
-
}
|
|
694
|
-
return fmt.Errorf("honey: http do: %w", err)
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
// newRequest builds the outgoing request after running the OnRequest hooks.
|
|
698
|
-
func newRequest(
|
|
699
|
-
ctx context.Context,
|
|
700
|
-
cfg Config,
|
|
701
|
-
method string,
|
|
702
|
-
path string,
|
|
703
|
-
query queryList,
|
|
704
|
-
body requestBody,
|
|
705
|
-
callHeaders map[string]string,
|
|
706
|
-
bearerToken string,
|
|
707
|
-
isRetry bool,
|
|
708
|
-
requestMeta *RequestMeta,
|
|
709
|
-
) (*http.Request, error) {
|
|
710
|
-
fullURL, err := buildURL(cfg.BaseURL, path, query)
|
|
711
|
-
if err != nil {
|
|
712
|
-
return nil, fmt.Errorf("honey: build URL: %w", err)
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
/* Reader bodies stream as-is; RequestContext.Body stays nil for them so hook
|
|
716
|
-
* consumers don't try to read or re-hash a single-shot reader. */
|
|
717
|
-
bodyBytes, err := body.bytes()
|
|
718
|
-
if err != nil {
|
|
719
|
-
return nil, err
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
headers := mergeHeaders(cfg, callHeaders, bearerToken, body.present(), body.contentType)
|
|
723
|
-
|
|
724
|
-
reqCtx := &RequestContext{
|
|
725
|
-
Method: method,
|
|
726
|
-
URL: fullURL,
|
|
727
|
-
Path: path,
|
|
728
|
-
Headers: headers,
|
|
729
|
-
Body: bodyBytes,
|
|
730
|
-
IsRetry: isRetry,
|
|
731
|
-
}
|
|
732
|
-
if requestMeta != nil {
|
|
733
|
-
reqCtx.Selector = requestMeta.Selector
|
|
734
|
-
reqCtx.IsStale = requestMeta.IsStale
|
|
735
|
-
reqCtx.InvalidatedBy = requestMeta.InvalidatedBy
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
for _, hook := range cfg.OnRequest {
|
|
739
|
-
if hookErr := hook(reqCtx); hookErr != nil {
|
|
740
|
-
return nil, fmt.Errorf("honey: OnRequest hook: %w", hookErr)
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
var reader io.Reader
|
|
745
|
-
if body.reader != nil {
|
|
746
|
-
reader = body.reader
|
|
747
|
-
} else if reqCtx.Body != nil {
|
|
748
|
-
reader = bytes.NewReader(reqCtx.Body)
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
req, err := http.NewRequestWithContext(ctx, reqCtx.Method, reqCtx.URL, reader)
|
|
752
|
-
if err != nil {
|
|
753
|
-
return nil, fmt.Errorf("honey: build request: %w", err)
|
|
754
|
-
}
|
|
755
|
-
req.Header = reqCtx.Headers
|
|
756
|
-
return req, nil
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
func executeRequest(
|
|
760
|
-
ctx context.Context,
|
|
761
|
-
cfg Config,
|
|
762
|
-
method string,
|
|
763
|
-
path string,
|
|
764
|
-
query queryList,
|
|
765
|
-
body requestBody,
|
|
766
|
-
callHeaders map[string]string,
|
|
767
|
-
bearerToken string,
|
|
768
|
-
isRetry bool,
|
|
769
|
-
requestMeta *RequestMeta,
|
|
770
|
-
) (*requestResult, error) {
|
|
771
|
-
req, err := newRequest(ctx, cfg, method, path, query, body, callHeaders, bearerToken, isRetry, requestMeta)
|
|
772
|
-
if err != nil {
|
|
773
|
-
return nil, err
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
resp, err := cfg.HTTPClient.Do(req)
|
|
777
|
-
if err != nil {
|
|
778
|
-
return nil, wrapTransportError(ctx, err)
|
|
779
|
-
}
|
|
780
|
-
defer resp.Body.Close()
|
|
781
|
-
|
|
782
|
-
respBody, readErr := readBody(resp.Body, cfg.MaxResponseBytes)
|
|
783
|
-
if readErr != nil {
|
|
784
|
-
return nil, wrapTransportError(ctx, readErr)
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
respCtx := &ResponseContext{
|
|
788
|
-
Status: resp.StatusCode,
|
|
789
|
-
Headers: resp.Header,
|
|
790
|
-
Body: respBody,
|
|
791
|
-
IsRetry: isRetry,
|
|
792
|
-
}
|
|
793
|
-
if requestMeta != nil {
|
|
794
|
-
respCtx.Selector = requestMeta.Selector
|
|
795
|
-
respCtx.IsStale = requestMeta.IsStale
|
|
796
|
-
respCtx.InvalidatedBy = requestMeta.InvalidatedBy
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
for _, hook := range cfg.OnResponse {
|
|
800
|
-
if hookErr := hook(respCtx); hookErr != nil {
|
|
801
|
-
return nil, fmt.Errorf("honey: OnResponse hook: %w", hookErr)
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
return &requestResult{body: respCtx.Body, status: resp.StatusCode, resp: resp}, nil
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
// ErrResponseTooLarge is returned when a buffered body exceeds Config.MaxResponseBytes.
|
|
809
|
-
var ErrResponseTooLarge = errors.New("honey: response body exceeds MaxResponseBytes")
|
|
810
|
-
|
|
811
|
-
func readBody(r io.Reader, limit int64) ([]byte, error) {
|
|
812
|
-
if limit < 0 {
|
|
813
|
-
return io.ReadAll(r)
|
|
814
|
-
}
|
|
815
|
-
body, err := io.ReadAll(io.LimitReader(r, limit+1))
|
|
816
|
-
if err != nil {
|
|
817
|
-
return nil, err
|
|
818
|
-
}
|
|
819
|
-
if int64(len(body)) > limit {
|
|
820
|
-
return nil, ErrResponseTooLarge
|
|
821
|
-
}
|
|
822
|
-
return body, nil
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
// streamClient is the configured client without its overall timeout: an
|
|
826
|
-
// http.Client Timeout also bounds body reads, which would cut every stream.
|
|
827
|
-
func streamClient(cfg Config) *http.Client {
|
|
828
|
-
c := *cfg.HTTPClient
|
|
829
|
-
c.Timeout = 0
|
|
830
|
-
return &c
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
// openStream sends a streaming request (SSE) through the same URL, header,
|
|
834
|
-
// auth and hook pipeline as a regular request. Non-2xx statuses become typed
|
|
835
|
-
// errors; the caller owns the returned body.
|
|
836
|
-
func openStream(
|
|
837
|
-
ctx context.Context,
|
|
838
|
-
cfg Config,
|
|
839
|
-
method string,
|
|
840
|
-
path string,
|
|
841
|
-
query queryList,
|
|
842
|
-
body requestBody,
|
|
843
|
-
callHeaders map[string]string,
|
|
844
|
-
) (*http.Response, error) {
|
|
845
|
-
token := cfg.auth.current(cfg)
|
|
846
|
-
for attempt := 0; ; attempt++ {
|
|
847
|
-
req, err := newRequest(ctx, cfg, method, path, query, body, callHeaders, token, attempt > 0, nil)
|
|
848
|
-
if err != nil {
|
|
849
|
-
return nil, err
|
|
850
|
-
}
|
|
851
|
-
resp, err := streamClient(cfg).Do(req)
|
|
852
|
-
if err != nil {
|
|
853
|
-
return nil, wrapTransportError(ctx, err)
|
|
854
|
-
}
|
|
855
|
-
if resp.StatusCode == 401 && attempt == 0 && cfg.OnAuthExpired != nil && body.replayable() {
|
|
856
|
-
errBody, _ := readBody(resp.Body, 64<<10)
|
|
857
|
-
resp.Body.Close()
|
|
858
|
-
newToken, authErr := cfg.auth.refresh(ctx, cfg, token)
|
|
859
|
-
if authErr != nil {
|
|
860
|
-
return nil, fmt.Errorf("honey: OnAuthExpired failed: %w", authErr)
|
|
861
|
-
}
|
|
862
|
-
if newToken == "" {
|
|
863
|
-
return nil, raiseForStatus(resp, errBody)
|
|
864
|
-
}
|
|
865
|
-
token = newToken
|
|
866
|
-
continue
|
|
867
|
-
}
|
|
868
|
-
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
|
869
|
-
defer resp.Body.Close()
|
|
870
|
-
errBody, _ := readBody(resp.Body, 64<<10)
|
|
871
|
-
return nil, raiseForStatus(resp, errBody)
|
|
872
|
-
}
|
|
873
|
-
return resp, nil
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
// authHeaders returns cfg.Headers plus the auth header, for transports that
|
|
878
|
-
// cannot run the full request pipeline (WebSocket dials).
|
|
879
|
-
func authHeaders(cfg Config, extra map[string]string) http.Header {
|
|
880
|
-
return mergeHeaders(cfg, extra, cfg.auth.current(cfg), false, "")
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
// mergeHeaders builds the final http.Header for a request by merging in order:
|
|
884
|
-
// config Headers → call Headers (per-call wins per key, case-insensitively) →
|
|
885
|
-
// Content-Type when hasBody → Authorization when bearerToken non-empty →
|
|
886
|
-
// X-Request-Id when absent (OnRequest hooks may still overwrite). Returned
|
|
887
|
-
// header is owned by the caller and may be mutated freely (e.g. by OnRequest
|
|
888
|
-
// hooks). contentType is the explicit Content-Type for the request body; when
|
|
889
|
-
// empty and hasBody is true, defaults to application/json.
|
|
890
|
-
func mergeHeaders(
|
|
891
|
-
cfg Config,
|
|
892
|
-
callHeaders map[string]string,
|
|
893
|
-
bearerToken string,
|
|
894
|
-
hasBody bool,
|
|
895
|
-
contentType string,
|
|
896
|
-
) http.Header {
|
|
897
|
-
h := http.Header{}
|
|
898
|
-
if hasBody {
|
|
899
|
-
ct := contentType
|
|
900
|
-
if ct == "" {
|
|
901
|
-
ct = "application/json"
|
|
902
|
-
}
|
|
903
|
-
h.Set("Content-Type", ct)
|
|
904
|
-
}
|
|
905
|
-
for _, k := range sortedKeys(cfg.Headers) {
|
|
906
|
-
h.Set(k, cfg.Headers[k])
|
|
907
|
-
}
|
|
908
|
-
for _, k := range sortedKeys(callHeaders) {
|
|
909
|
-
h.Set(k, callHeaders[k])
|
|
910
|
-
}
|
|
911
|
-
if bearerToken != "" {
|
|
912
|
-
name := cfg.AuthHeaderName
|
|
913
|
-
if name == "" {
|
|
914
|
-
name = "Authorization"
|
|
915
|
-
}
|
|
916
|
-
prefix := cfg.AuthHeaderPrefix
|
|
917
|
-
if prefix == "" {
|
|
918
|
-
prefix = "Bearer "
|
|
919
|
-
}
|
|
920
|
-
h.Set(name, prefix+bearerToken)
|
|
921
|
-
}
|
|
922
|
-
if h.Get("X-Request-Id") == "" {
|
|
923
|
-
h.Set("X-Request-Id", newUUIDv4())
|
|
924
|
-
}
|
|
925
|
-
return h
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
func sortedKeys(m map[string]string) []string {
|
|
929
|
-
keys := make([]string, 0, len(m))
|
|
930
|
-
for k := range m {
|
|
931
|
-
keys = append(keys, k)
|
|
932
|
-
}
|
|
933
|
-
sort.Strings(keys)
|
|
934
|
-
return keys
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
func unmarshalBody[T any](body []byte) (*T, error) {
|
|
938
|
-
if len(body) == 0 {
|
|
939
|
-
return nil, nil
|
|
940
|
-
}
|
|
941
|
-
var out T
|
|
942
|
-
if err := json.Unmarshal(body, &out); err != nil {
|
|
943
|
-
return nil, fmt.Errorf("honey: unmarshal response: %w", err)
|
|
944
|
-
}
|
|
945
|
-
return &out, nil
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
// newUUIDv4 returns a freshly generated RFC 4122 §4.4 random UUID string.
|
|
949
|
-
// Uses crypto/rand for entropy; sets version (4) and variant (10xx) bits per
|
|
950
|
-
// the spec, then formats canonical 8-4-4-4-12 lower-case hex. Zero external
|
|
951
|
-
// deps so generated SDKs add no third-party rows to consumer go.sum files.
|
|
952
|
-
func newUUIDv4() string {
|
|
953
|
-
var b [16]byte
|
|
954
|
-
if _, err := rand.Read(b[:]); err != nil {
|
|
955
|
-
/* crypto/rand.Read is documented to never return non-nil err on supported
|
|
956
|
-
* platforms; if it does the OS entropy source is broken — silent fallback
|
|
957
|
-
* would corrupt dedupe semantics, so panic mirrors google/uuid. */
|
|
958
|
-
panic("honey: crypto/rand failed: " + err.Error())
|
|
959
|
-
}
|
|
960
|
-
b[6] = (b[6] & 0x0f) | 0x40 /* version 4 */
|
|
961
|
-
b[8] = (b[8] & 0x3f) | 0x80 /* variant 10xx */
|
|
962
|
-
const hex = "0123456789abcdef"
|
|
963
|
-
out := make([]byte, 36)
|
|
964
|
-
j := 0
|
|
965
|
-
for i, by := range b {
|
|
966
|
-
if i == 4 || i == 6 || i == 8 || i == 10 {
|
|
967
|
-
out[j] = '-'
|
|
968
|
-
j++
|
|
969
|
-
}
|
|
970
|
-
out[j] = hex[by>>4]
|
|
971
|
-
out[j+1] = hex[by&0x0f]
|
|
972
|
-
j += 2
|
|
973
|
-
}
|
|
974
|
-
return string(out)
|
|
975
|
-
}
|