@lovrozagar/honey 0.6.8 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +514 -192
- package/bin/honey.js +25 -0
- package/dist/accepts.d.ts +7 -1
- package/dist/accepts.d.ts.map +1 -1
- package/dist/accepts.js +126 -0
- package/dist/accepts.js.map +1 -0
- package/dist/body-kind.d.ts +26 -0
- package/dist/body-kind.d.ts.map +1 -0
- package/dist/body-kind.js +70 -0
- package/dist/body-kind.js.map +1 -0
- package/dist/body-limit.d.ts +5 -1
- package/dist/body-limit.d.ts.map +1 -1
- package/dist/body-limit.js +126 -0
- package/dist/body-limit.js.map +1 -0
- package/dist/build/index.d.ts +19 -3
- package/dist/build/index.d.ts.map +1 -1
- package/dist/build/index.js +173 -0
- package/dist/build/index.js.map +1 -0
- package/dist/cli-args.d.ts +33 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +102 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-go/auth.go +26 -0
- package/dist/cli-go/config.go +192 -0
- package/dist/cli-go/errors.go +75 -0
- package/dist/cli-go/multipart.go +79 -0
- package/dist/cli-go/output.go +163 -0
- package/dist/cli-go/root.go +30 -0
- package/dist/cli-go/stream.go +88 -0
- package/dist/cli-go/version.go +5 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +209 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/defaults.js +48 -0
- package/dist/client/defaults.js.map +1 -0
- package/dist/client/error.d.ts +35 -0
- package/dist/client/error.d.ts.map +1 -1
- package/dist/client/error.js +71 -0
- package/dist/client/error.js.map +1 -0
- package/dist/client/http.d.ts +67 -8
- package/dist/client/http.d.ts.map +1 -1
- package/dist/client/http.js +571 -0
- package/dist/client/http.js.map +1 -0
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +95 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/path.d.ts +26 -0
- package/dist/client/path.d.ts.map +1 -0
- package/dist/client/path.js +163 -0
- package/dist/client/path.js.map +1 -0
- package/dist/client/redirect-policy.d.ts +12 -0
- package/dist/client/redirect-policy.d.ts.map +1 -0
- package/dist/client/redirect-policy.js +20 -0
- package/dist/client/redirect-policy.js.map +1 -0
- package/dist/client/sdk.d.ts +36 -0
- package/dist/client/sdk.d.ts.map +1 -1
- package/dist/client/sdk.js +292 -0
- package/dist/client/sdk.js.map +1 -0
- package/dist/client/sse.d.ts +13 -0
- package/dist/client/sse.d.ts.map +1 -1
- package/dist/client/sse.js +129 -0
- package/dist/client/sse.js.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/ws.d.ts +9 -2
- package/dist/client/ws.d.ts.map +1 -1
- package/dist/client/ws.js +112 -0
- package/dist/client/ws.js.map +1 -0
- package/dist/client-go/errors.go +236 -0
- package/dist/client-go/export.go +44 -0
- package/dist/client-go/invalidation.go +371 -0
- package/dist/client-go/nullable.go +62 -0
- package/dist/client-go/realtime.go +354 -0
- package/dist/client-go/result.go +20 -0
- package/dist/client-go/runtime.go +975 -0
- package/dist/client-go/sse.go +159 -0
- package/dist/client-go/transport.go +495 -0
- package/dist/client-go/ws.go +128 -0
- package/dist/client-info.d.ts +36 -0
- package/dist/client-info.d.ts.map +1 -0
- package/dist/client-info.js +53 -0
- package/dist/client-info.js.map +1 -0
- package/dist/client-mcp/README.md +10 -0
- package/dist/client-mcp/server.ts +221 -0
- package/dist/client-mcp/types.ts +19 -0
- package/dist/client-python/_errors.py +115 -0
- package/dist/client-python/_invalidation.py +494 -0
- package/dist/client-python/_realtime.py +179 -0
- package/dist/client-python/_runtime.py +860 -0
- package/dist/client-python/_sse.py +155 -0
- package/dist/client-python/_transport.py +366 -0
- package/dist/client-python/_ws.py +159 -0
- package/dist/client-python/py.typed +0 -0
- package/dist/client-rust/errors.rs +220 -0
- package/dist/client-rust/invalidation.rs +412 -0
- package/dist/client-rust/invalidation_sync.rs +93 -0
- package/dist/client-rust/nullable.rs +17 -0
- package/dist/client-rust/realtime.rs +702 -0
- package/dist/client-rust/result.rs +22 -0
- package/dist/client-rust/runtime.rs +980 -0
- package/dist/client-rust/runtime_sync.rs +484 -0
- package/dist/client-rust/sse.rs +188 -0
- package/dist/client-rust/ws.rs +167 -0
- package/dist/codegen-go-cli.d.ts.map +1 -1
- package/dist/codegen-go-cli.js +964 -0
- package/dist/codegen-go-cli.js.map +1 -0
- package/dist/codegen-go.d.ts +15 -3
- package/dist/codegen-go.d.ts.map +1 -1
- package/dist/codegen-go.js +872 -0
- package/dist/codegen-go.js.map +1 -0
- package/dist/codegen-hash.js +9 -0
- package/dist/codegen-hash.js.map +1 -0
- package/dist/codegen-ir.d.ts +69 -2
- package/dist/codegen-ir.d.ts.map +1 -1
- package/dist/codegen-ir.js +661 -0
- package/dist/codegen-ir.js.map +1 -0
- package/dist/codegen-lang.d.ts +65 -0
- package/dist/codegen-lang.d.ts.map +1 -0
- package/dist/codegen-lang.js +526 -0
- package/dist/codegen-lang.js.map +1 -0
- package/dist/codegen-load.d.ts +31 -0
- package/dist/codegen-load.d.ts.map +1 -0
- package/dist/codegen-load.js +138 -0
- package/dist/codegen-load.js.map +1 -0
- package/dist/codegen-loaders.js +55 -0
- package/dist/codegen-loaders.js.map +1 -0
- package/dist/codegen-mcp.d.ts.map +1 -1
- package/dist/codegen-mcp.js +368 -0
- package/dist/codegen-mcp.js.map +1 -0
- package/dist/codegen-python.d.ts +13 -1
- package/dist/codegen-python.d.ts.map +1 -1
- package/dist/codegen-python.js +828 -0
- package/dist/codegen-python.js.map +1 -0
- package/dist/codegen-route-tree-intern.d.ts +15 -5
- package/dist/codegen-route-tree-intern.d.ts.map +1 -1
- package/dist/codegen-route-tree-intern.js +221 -0
- package/dist/codegen-route-tree-intern.js.map +1 -0
- package/dist/codegen-rust.d.ts.map +1 -1
- package/dist/codegen-rust.js +1293 -0
- package/dist/codegen-rust.js.map +1 -0
- package/dist/codegen-sanitize.d.ts.map +1 -1
- package/dist/codegen-sanitize.js +56 -0
- package/dist/codegen-sanitize.js.map +1 -0
- package/dist/codegen-schema-naming.d.ts +5 -0
- package/dist/codegen-schema-naming.d.ts.map +1 -1
- package/dist/codegen-schema-naming.js +150 -0
- package/dist/codegen-schema-naming.js.map +1 -0
- package/dist/codegen-sdk-model.d.ts +71 -0
- package/dist/codegen-sdk-model.d.ts.map +1 -0
- package/dist/codegen-sdk-model.js +179 -0
- package/dist/codegen-sdk-model.js.map +1 -0
- package/dist/codegen.d.ts +41 -23
- package/dist/codegen.d.ts.map +1 -1
- package/dist/codegen.js +4610 -0
- package/dist/codegen.js.map +1 -0
- package/dist/context.d.ts +36 -6
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +242 -0
- package/dist/context.js.map +1 -0
- package/dist/cookie-sign.d.ts +16 -2
- package/dist/cookie-sign.d.ts.map +1 -1
- package/dist/cookie-sign.js +104 -0
- package/dist/cookie-sign.js.map +1 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.d.ts.map +1 -1
- package/dist/cookie.js +138 -0
- package/dist/cookie.js.map +1 -0
- package/dist/cors.d.ts +1 -0
- package/dist/cors.d.ts.map +1 -1
- package/dist/cors.js +87 -0
- package/dist/cors.js.map +1 -0
- package/dist/crypto.d.ts +6 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +38 -0
- package/dist/crypto.js.map +1 -0
- package/dist/csrf.d.ts +19 -0
- package/dist/csrf.d.ts.map +1 -1
- package/dist/csrf.js +79 -0
- package/dist/csrf.js.map +1 -0
- package/dist/curl-logger.d.ts +14 -3
- package/dist/curl-logger.d.ts.map +1 -1
- package/dist/curl-logger.js +199 -0
- package/dist/curl-logger.js.map +1 -0
- package/dist/detect-runtime.js +13 -0
- package/dist/detect-runtime.js.map +1 -0
- package/dist/dict.d.ts +11 -0
- package/dist/dict.d.ts.map +1 -0
- package/dist/dict.js +13 -0
- package/dist/dict.js.map +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +44 -0
- package/dist/error.js.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/etag.d.ts +2 -0
- package/dist/etag.d.ts.map +1 -1
- package/dist/etag.js +82 -0
- package/dist/etag.js.map +1 -0
- package/dist/feature-detect.d.ts +25 -0
- package/dist/feature-detect.d.ts.map +1 -0
- package/dist/feature-detect.js +144 -0
- package/dist/feature-detect.js.map +1 -0
- package/dist/feature-load.js +36 -0
- package/dist/feature-load.js.map +1 -0
- package/dist/feature-slots.d.ts +44 -0
- package/dist/feature-slots.d.ts.map +1 -0
- package/dist/feature-slots.js +48 -0
- package/dist/feature-slots.js.map +1 -0
- package/dist/fetch-request.d.ts +10 -0
- package/dist/fetch-request.d.ts.map +1 -0
- package/dist/fetch-request.js +13 -0
- package/dist/fetch-request.js.map +1 -0
- package/dist/gen-process.d.ts +15 -0
- package/dist/gen-process.d.ts.map +1 -0
- package/dist/gen-process.js +43 -0
- package/dist/gen-process.js.map +1 -0
- package/dist/gen-write.d.ts +19 -0
- package/dist/gen-write.d.ts.map +1 -0
- package/dist/gen-write.js +120 -0
- package/dist/gen-write.js.map +1 -0
- package/dist/glob.d.ts +21 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +115 -0
- package/dist/glob.js.map +1 -0
- package/dist/go-type-emitter.d.ts +18 -4
- package/dist/go-type-emitter.d.ts.map +1 -1
- package/dist/go-type-emitter.js +594 -0
- package/dist/go-type-emitter.js.map +1 -0
- package/dist/honey-response.d.ts.map +1 -1
- package/dist/honey-response.js +338 -0
- package/dist/honey-response.js.map +1 -0
- package/dist/i18n-slot.d.ts +8 -0
- package/dist/i18n-slot.d.ts.map +1 -1
- package/dist/i18n-slot.js +14 -0
- package/dist/i18n-slot.js.map +1 -0
- package/dist/i18n.d.ts +3 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +250 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +408 -148
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2324 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +3 -5
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +140 -0
- package/dist/init.js.map +1 -0
- package/dist/input.js +4 -0
- package/dist/input.js.map +1 -0
- package/dist/invalidate-check.d.ts +11 -0
- package/dist/invalidate-check.d.ts.map +1 -1
- package/dist/invalidate-check.js +163 -0
- package/dist/invalidate-check.js.map +1 -0
- package/dist/invoke-user.d.ts +35 -0
- package/dist/invoke-user.d.ts.map +1 -0
- package/dist/invoke-user.js +73 -0
- package/dist/invoke-user.js.map +1 -0
- package/dist/ip-restrict.d.ts +13 -1
- package/dist/ip-restrict.d.ts.map +1 -1
- package/dist/ip-restrict.js +60 -0
- package/dist/ip-restrict.js.map +1 -0
- package/dist/ip.d.ts +39 -0
- package/dist/ip.d.ts.map +1 -0
- package/dist/ip.js +209 -0
- package/dist/ip.js.map +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +113 -0
- package/dist/logger.js.map +1 -0
- package/dist/media-type.d.ts +30 -0
- package/dist/media-type.d.ts.map +1 -0
- package/dist/media-type.js +97 -0
- package/dist/media-type.js.map +1 -0
- package/dist/meta-spec-merge.d.ts +32 -0
- package/dist/meta-spec-merge.d.ts.map +1 -0
- package/dist/meta-spec-merge.js +68 -0
- package/dist/meta-spec-merge.js.map +1 -0
- package/dist/meta-spec.d.ts +16 -3
- package/dist/meta-spec.d.ts.map +1 -1
- package/dist/meta-spec.js +535 -0
- package/dist/meta-spec.js.map +1 -0
- package/dist/middleware.d.ts +23 -6
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +253 -0
- package/dist/middleware.js.map +1 -0
- package/dist/node-request.d.ts +57 -12
- package/dist/node-request.d.ts.map +1 -1
- package/dist/node-request.js +407 -0
- package/dist/node-request.js.map +1 -0
- package/dist/node.d.ts +20 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +396 -0
- package/dist/node.js.map +1 -0
- package/dist/openapi/collect.d.ts +6 -3
- package/dist/openapi/collect.d.ts.map +1 -1
- package/dist/openapi/collect.js +30 -0
- package/dist/openapi/collect.js.map +1 -0
- package/dist/openapi/docs-page.d.ts +42 -0
- package/dist/openapi/docs-page.d.ts.map +1 -0
- package/dist/openapi/docs-page.js +80 -0
- package/dist/openapi/docs-page.js.map +1 -0
- package/dist/openapi/document.d.ts +4 -0
- package/dist/openapi/document.d.ts.map +1 -1
- package/dist/openapi/document.js +785 -0
- package/dist/openapi/document.js.map +1 -0
- package/dist/openapi/json-schema-slot.d.ts +7 -0
- package/dist/openapi/json-schema-slot.d.ts.map +1 -1
- package/dist/openapi/json-schema-slot.js +38 -0
- package/dist/openapi/json-schema-slot.js.map +1 -0
- package/dist/openapi/register.d.ts.map +1 -1
- package/dist/openapi/register.js +20 -0
- package/dist/openapi/register.js.map +1 -0
- package/dist/openapi/scalar.d.ts +3 -1
- package/dist/openapi/scalar.d.ts.map +1 -1
- package/dist/openapi/scalar.js +21 -0
- package/dist/openapi/scalar.js.map +1 -0
- package/dist/openapi/serve.d.ts +9 -0
- package/dist/openapi/serve.d.ts.map +1 -0
- package/dist/openapi/serve.js +36 -0
- package/dist/openapi/serve.js.map +1 -0
- package/dist/openapi/spec-factory.d.ts +30 -1
- package/dist/openapi/spec-factory.d.ts.map +1 -1
- package/dist/openapi/spec-factory.js +52 -0
- package/dist/openapi/spec-factory.js.map +1 -0
- package/dist/openapi/spec.d.ts +14 -5
- package/dist/openapi/spec.d.ts.map +1 -1
- package/dist/openapi/spec.js +50 -0
- package/dist/openapi/spec.js.map +1 -0
- package/dist/openapi/swagger.d.ts +3 -1
- package/dist/openapi/swagger.d.ts.map +1 -1
- package/dist/openapi/swagger.js +22 -0
- package/dist/openapi/swagger.js.map +1 -0
- package/dist/pattern.d.ts +71 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +239 -0
- package/dist/pattern.js.map +1 -0
- package/dist/peer.d.ts +17 -0
- package/dist/peer.d.ts.map +1 -0
- package/dist/peer.js +50 -0
- package/dist/peer.js.map +1 -0
- package/dist/plugin.d.ts +67 -16
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +649 -0
- package/dist/plugin.js.map +1 -0
- package/dist/powered-by.d.ts.map +1 -1
- package/dist/powered-by.js +11 -0
- package/dist/powered-by.js.map +1 -0
- package/dist/pretty-json.d.ts.map +1 -1
- package/dist/pretty-json.js +47 -0
- package/dist/pretty-json.js.map +1 -0
- package/dist/producer-stream.d.ts +47 -0
- package/dist/producer-stream.d.ts.map +1 -0
- package/dist/producer-stream.js +267 -0
- package/dist/producer-stream.js.map +1 -0
- package/dist/proxy.d.ts +47 -8
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +274 -0
- package/dist/proxy.js.map +1 -0
- package/dist/python-type-emitter.d.ts +14 -1
- package/dist/python-type-emitter.d.ts.map +1 -1
- package/dist/python-type-emitter.js +157 -0
- package/dist/python-type-emitter.js.map +1 -0
- package/dist/realtime/bus.d.ts +17 -1
- package/dist/realtime/bus.d.ts.map +1 -1
- package/dist/realtime/bus.js +112 -0
- package/dist/realtime/bus.js.map +1 -0
- package/dist/realtime/register.d.ts +3 -0
- package/dist/realtime/register.d.ts.map +1 -0
- package/dist/realtime/register.js +10 -0
- package/dist/realtime/register.js.map +1 -0
- package/dist/realtime/route.d.ts +65 -26
- package/dist/realtime/route.d.ts.map +1 -1
- package/dist/realtime/route.js +72 -0
- package/dist/realtime/route.js.map +1 -0
- package/dist/realtime/server.d.ts +43 -0
- package/dist/realtime/server.d.ts.map +1 -0
- package/dist/realtime/server.js +255 -0
- package/dist/realtime/server.js.map +1 -0
- package/dist/request-id.d.ts +7 -0
- package/dist/request-id.d.ts.map +1 -1
- package/dist/request-id.js +16 -0
- package/dist/request-id.js.map +1 -0
- package/dist/request-limits.d.ts +3 -0
- package/dist/request-limits.d.ts.map +1 -0
- package/dist/request-limits.js +3 -0
- package/dist/request-limits.js.map +1 -0
- package/dist/request-path.d.ts +33 -0
- package/dist/request-path.d.ts.map +1 -0
- package/dist/request-path.js +178 -0
- package/dist/request-path.js.map +1 -0
- package/dist/request-to-curl.d.ts +7 -1
- package/dist/request-to-curl.d.ts.map +1 -1
- package/dist/request-to-curl.js +48 -0
- package/dist/request-to-curl.js.map +1 -0
- package/dist/response.d.ts +25 -2
- package/dist/response.d.ts.map +1 -1
- package/dist/response.js +313 -0
- package/dist/response.js.map +1 -0
- package/dist/rust-type-emitter.d.ts +14 -2
- package/dist/rust-type-emitter.d.ts.map +1 -1
- package/dist/rust-type-emitter.js +463 -0
- package/dist/rust-type-emitter.js.map +1 -0
- package/dist/secure-headers.d.ts.map +1 -1
- package/dist/secure-headers.js +53 -0
- package/dist/secure-headers.js.map +1 -0
- package/dist/serve-register.d.ts +4 -0
- package/dist/serve-register.d.ts.map +1 -1
- package/dist/serve-register.js +9 -0
- package/dist/serve-register.js.map +1 -0
- package/dist/serve-slot.d.ts +3 -0
- package/dist/serve-slot.d.ts.map +1 -1
- package/dist/serve-slot.js +52 -0
- package/dist/serve-slot.js.map +1 -0
- package/dist/serve.d.ts +18 -1
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +157 -0
- package/dist/serve.js.map +1 -0
- package/dist/server-timing.d.ts.map +1 -1
- package/dist/server-timing.js +51 -0
- package/dist/server-timing.js.map +1 -0
- package/dist/static.d.ts +9 -0
- package/dist/static.d.ts.map +1 -1
- package/dist/static.js +102 -0
- package/dist/static.js.map +1 -0
- package/dist/telemetry/otel.d.ts +2 -0
- package/dist/telemetry/otel.d.ts.map +1 -1
- package/dist/telemetry/otel.js +135 -0
- package/dist/telemetry/otel.js.map +1 -0
- package/dist/testing.d.ts +12 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +124 -0
- package/dist/testing.js.map +1 -0
- package/dist/timeout.d.ts +6 -0
- package/dist/timeout.d.ts.map +1 -1
- package/dist/timeout.js +36 -0
- package/dist/timeout.js.map +1 -0
- package/dist/tree.d.ts +133 -36
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +437 -0
- package/dist/tree.js.map +1 -0
- package/dist/trust.d.ts +21 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +100 -0
- package/dist/trust.js.map +1 -0
- package/dist/ts-type-emitter.d.ts.map +1 -1
- package/dist/ts-type-emitter.js +150 -0
- package/dist/ts-type-emitter.js.map +1 -0
- package/dist/type-emitter.d.ts +16 -2
- package/dist/type-emitter.d.ts.map +1 -1
- package/dist/type-emitter.js +729 -0
- package/dist/type-emitter.js.map +1 -0
- package/dist/type-extractor.d.ts +8 -4
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +776 -0
- package/dist/type-extractor.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +96 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +14 -2
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +335 -0
- package/dist/validation.js.map +1 -0
- package/dist/with-headers.d.ts +15 -0
- package/dist/with-headers.d.ts.map +1 -0
- package/dist/with-headers.js +45 -0
- package/dist/with-headers.js.map +1 -0
- package/dist/ws/bun.d.ts +11 -5
- package/dist/ws/bun.d.ts.map +1 -1
- package/dist/ws/bun.js +82 -0
- package/dist/ws/bun.js.map +1 -0
- package/dist/ws/cloudflare.d.ts +25 -3
- package/dist/ws/cloudflare.d.ts.map +1 -1
- package/dist/ws/cloudflare.js +117 -0
- package/dist/ws/cloudflare.js.map +1 -0
- package/dist/ws/deno.d.ts +4 -4
- package/dist/ws/deno.d.ts.map +1 -1
- package/dist/ws/deno.js +133 -0
- package/dist/ws/deno.js.map +1 -0
- package/dist/ws/node.d.ts +20 -3
- package/dist/ws/node.d.ts.map +1 -1
- package/dist/ws/node.js +173 -0
- package/dist/ws/node.js.map +1 -0
- package/dist/ws/session.d.ts +11 -0
- package/dist/ws/session.d.ts.map +1 -0
- package/dist/ws/session.js +60 -0
- package/dist/ws/session.js.map +1 -0
- package/dist/ws/shared.d.ts +65 -0
- package/dist/ws/shared.d.ts.map +1 -0
- package/dist/ws/shared.js +103 -0
- package/dist/ws/shared.js.map +1 -0
- package/dist/ws-origin.d.ts +20 -0
- package/dist/ws-origin.d.ts.map +1 -0
- package/dist/ws-origin.js +41 -0
- package/dist/ws-origin.js.map +1 -0
- package/dist/yaml.d.ts +15 -1
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +101 -0
- package/dist/yaml.js.map +1 -0
- package/docs/invalidate-spec.md +13 -1
- package/docs/meta-spec.md +36 -12
- package/docs/packaging.md +43 -24
- package/docs/regression-matrix/README.md +32 -0
- package/docs/regression-matrix/review.md +44 -0
- package/docs/regression-matrix/ws1-3.md +97 -0
- package/docs/regression-matrix/ws4-8.md +107 -0
- package/docs/regression-matrix/ws9-12.md +266 -0
- package/docs/sdk.md +102 -52
- package/package.json +183 -52
- package/src/accepts.ts +91 -33
- package/src/body-kind.ts +67 -0
- package/src/body-limit.ts +102 -87
- package/src/build/index.ts +104 -54
- package/src/cli-args.ts +123 -0
- package/src/cli-go/auth.go +12 -1
- package/src/cli-go/config.go +29 -2
- package/src/cli-go/errors.go +28 -10
- package/src/cli-go/multipart.go +51 -27
- package/src/cli-go/output.go +58 -4
- package/src/cli-go/root.go +1 -1
- package/src/cli-go/version.go +2 -2
- package/src/cli.ts +154 -148
- package/src/client/error.ts +56 -1
- package/src/client/http.ts +479 -256
- package/src/client/index.ts +55 -17
- package/src/client/path.ts +169 -0
- package/src/client/redirect-policy.ts +19 -0
- package/src/client/sdk.ts +180 -101
- package/src/client/sse.ts +92 -66
- package/src/client/ws.ts +67 -31
- package/src/client-go/errors.go +41 -12
- package/src/client-go/export.go +44 -0
- package/src/client-go/invalidation.go +52 -54
- package/src/client-go/nullable.go +62 -0
- package/src/client-go/realtime.go +147 -110
- package/src/client-go/runtime.go +646 -88
- package/src/client-go/sse.go +104 -94
- package/src/client-go/transport.go +67 -27
- package/src/client-go/ws.go +49 -25
- package/src/client-info.ts +79 -0
- package/src/client-mcp/server.ts +133 -3
- package/src/client-python/_invalidation.py +207 -291
- package/src/client-python/_realtime.py +63 -40
- package/src/client-python/_runtime.py +501 -119
- package/src/client-python/_sse.py +130 -74
- package/src/client-python/_transport.py +37 -9
- package/src/client-python/_ws.py +50 -22
- package/src/client-rust/errors.rs +21 -1
- package/src/client-rust/invalidation.rs +202 -231
- package/src/client-rust/invalidation_sync.rs +16 -229
- package/src/client-rust/nullable.rs +17 -0
- package/src/client-rust/realtime.rs +217 -217
- package/src/client-rust/runtime.rs +602 -177
- package/src/client-rust/runtime_sync.rs +169 -145
- package/src/client-rust/sse.rs +142 -121
- package/src/client-rust/ws.rs +61 -37
- package/src/codegen-go-cli.ts +607 -728
- package/src/codegen-go.ts +710 -770
- package/src/codegen-ir.ts +381 -75
- package/src/codegen-lang.ts +517 -0
- package/src/codegen-load.ts +150 -0
- package/src/codegen-mcp.ts +207 -108
- package/src/codegen-python.ts +684 -816
- package/src/codegen-route-tree-intern.ts +51 -25
- package/src/codegen-rust.ts +946 -1240
- package/src/codegen-sanitize.ts +0 -4
- package/src/codegen-schema-naming.ts +19 -6
- package/src/codegen-sdk-model.ts +228 -0
- package/src/codegen.ts +1488 -1140
- package/src/context.ts +130 -11
- package/src/cookie-sign.ts +85 -16
- package/src/cookie.ts +66 -11
- package/src/cors.ts +55 -54
- package/src/crypto.ts +27 -5
- package/src/csrf.ts +57 -25
- package/src/curl-logger.ts +155 -114
- package/src/dict.ts +12 -0
- package/src/error.ts +4 -2
- package/src/etag.ts +58 -34
- package/src/feature-detect.ts +147 -0
- package/src/feature-slots.ts +70 -0
- package/src/fetch-request.ts +13 -0
- package/src/gen-process.ts +42 -0
- package/src/gen-write.ts +127 -0
- package/src/glob.ts +109 -0
- package/src/go-type-emitter.ts +406 -155
- package/src/honey-response.ts +36 -9
- package/src/i18n-slot.ts +10 -0
- package/src/i18n.ts +98 -23
- package/src/index.ts +1887 -1756
- package/src/init.ts +40 -28
- package/src/invalidate-check.ts +42 -4
- package/src/invoke-user.ts +95 -0
- package/src/ip-restrict.ts +47 -161
- package/src/ip.ts +194 -0
- package/src/logger.ts +65 -36
- package/src/media-type.ts +104 -0
- package/src/meta-spec-merge.ts +80 -0
- package/src/meta-spec.ts +0 -0
- package/src/middleware.ts +112 -12
- package/src/node-request.ts +242 -52
- package/src/node.ts +318 -75
- package/src/openapi/collect.ts +19 -44
- package/src/openapi/docs-page.ts +89 -0
- package/src/openapi/document.ts +503 -224
- package/src/openapi/json-schema-slot.ts +40 -0
- package/src/openapi/register.ts +7 -2
- package/src/openapi/scalar.ts +11 -10
- package/src/openapi/serve.ts +39 -0
- package/src/openapi/spec-factory.ts +50 -1
- package/src/openapi/spec.ts +53 -30
- package/src/openapi/swagger.ts +12 -11
- package/src/pattern.ts +245 -0
- package/src/peer.ts +53 -0
- package/src/plugin.ts +270 -185
- package/src/powered-by.ts +2 -2
- package/src/pretty-json.ts +25 -9
- package/src/producer-stream.ts +296 -0
- package/src/proxy.ts +253 -55
- package/src/python-type-emitter.ts +68 -56
- package/src/realtime/bus.ts +56 -9
- package/src/realtime/register.ts +13 -0
- package/src/realtime/route.ts +129 -80
- package/src/realtime/server.ts +298 -0
- package/src/request-id.ts +13 -3
- package/src/request-limits.ts +2 -0
- package/src/request-path.ts +165 -0
- package/src/request-to-curl.ts +28 -7
- package/src/response.ts +143 -103
- package/src/rust-type-emitter.ts +265 -170
- package/src/secure-headers.ts +8 -4
- package/src/serve-register.ts +4 -0
- package/src/serve-slot.ts +38 -0
- package/src/serve.ts +113 -25
- package/src/server-timing.ts +11 -7
- package/src/static.ts +85 -32
- package/src/telemetry/otel.ts +29 -7
- package/src/testing.ts +76 -14
- package/src/timeout.ts +15 -7
- package/src/tree.ts +405 -333
- package/src/trust.ts +117 -0
- package/src/ts-type-emitter.ts +18 -12
- package/src/type-emitter.ts +227 -89
- package/src/type-extractor.ts +562 -424
- package/src/types.ts +8 -0
- package/src/validation.ts +221 -96
- package/src/with-headers.ts +45 -0
- package/src/ws/bun.ts +53 -15
- package/src/ws/cloudflare.ts +81 -19
- package/src/ws/deno.ts +124 -36
- package/src/ws/node.ts +173 -79
- package/src/ws/session.ts +73 -0
- package/src/ws/shared.ts +140 -0
- package/src/ws-origin.ts +53 -0
- package/src/yaml.ts +45 -22
- package/dist/client-mcp/server.d.ts +0 -10
- package/dist/client-mcp/server.d.ts.map +0 -1
- package/dist/client-mcp/types.d.ts +0 -16
- package/dist/client-mcp/types.d.ts.map +0 -1
- package/dist/cloudflare/realtime.d.ts +0 -30
- package/dist/cloudflare/realtime.d.ts.map +0 -1
- package/dist/realtime/buffer.d.ts +0 -18
- package/dist/realtime/buffer.d.ts.map +0 -1
- package/dist/realtime/longpoll.d.ts +0 -23
- package/dist/realtime/longpoll.d.ts.map +0 -1
- package/dist/realtime/protocol.d.ts +0 -50
- package/dist/realtime/protocol.d.ts.map +0 -1
- package/dist/realtime/runtime.d.ts +0 -74
- package/dist/realtime/runtime.d.ts.map +0 -1
- package/src/cloudflare/realtime.ts +0 -234
- package/src/realtime/buffer.ts +0 -101
- package/src/realtime/longpoll.ts +0 -148
- package/src/realtime/protocol.ts +0 -128
- package/src/realtime/runtime.ts +0 -427
package/src/body-limit.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { namedMiddleware } from "./middleware.ts"
|
|
2
2
|
import { HoneyError } from "./error.ts"
|
|
3
|
+
import { parseMediaType } from "./media-type.ts"
|
|
3
4
|
import type { MiddlewareFn } from "./middleware.ts"
|
|
4
5
|
import { EK, SK } from "./types.ts"
|
|
5
6
|
|
|
6
7
|
type BodyLimitOptions = {
|
|
7
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Per media-type size limits. A key matches when the request's media type
|
|
10
|
+
* (lowercased, parameters dropped) starts with it, so `"multipart/"` covers
|
|
11
|
+
* every multipart type. The longest matching key wins.
|
|
12
|
+
*/
|
|
8
13
|
limits?: Record<string, number>
|
|
9
14
|
/** Default max body size in bytes — used when no content-type match or no limits map */
|
|
10
15
|
maxSize: number
|
|
@@ -22,112 +27,122 @@ type BodyLimitOptions = {
|
|
|
22
27
|
|
|
23
28
|
export type { BodyLimitOptions }
|
|
24
29
|
|
|
30
|
+
/* After an overflow the rest of the upload is read and discarded so the client
|
|
31
|
+
* sees the 413 instead of a reset, but only this much: past it the stream is
|
|
32
|
+
* cancelled, so a client cannot hold the connection open with an endless body. */
|
|
33
|
+
const DRAIN_LIMIT = 1_048_576
|
|
34
|
+
|
|
35
|
+
/* the shared parser lowercases and drops parameters; a malformed type matches no key */
|
|
36
|
+
function mediaType(contentType: string | null): string | null {
|
|
37
|
+
return parseMediaType(contentType)?.essence ?? null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function tooLarge(): HoneyError {
|
|
41
|
+
return new HoneyError({ errorKey: EK.content_too_large, status: SK.content_too_large })
|
|
42
|
+
}
|
|
43
|
+
|
|
25
44
|
export function bodyLimit(opts: BodyLimitOptions): MiddlewareFn<{ req: Request }, {}> {
|
|
26
45
|
const { limits, maxSize, trustContentLength } = opts
|
|
27
|
-
const limitEntries =
|
|
46
|
+
const limitEntries =
|
|
47
|
+
limits !== undefined
|
|
48
|
+
? Object.entries(limits)
|
|
49
|
+
.map(([key, limit]) => [key.trim().toLowerCase(), limit] as const)
|
|
50
|
+
.sort((a, b) => b[0].length - a[0].length)
|
|
51
|
+
: null
|
|
28
52
|
|
|
53
|
+
const resolveMax = (req: Request): number => {
|
|
54
|
+
if (limitEntries === null) return maxSize
|
|
55
|
+
const type = mediaType(req.headers.get("content-type"))
|
|
56
|
+
if (type === null) return maxSize
|
|
57
|
+
for (const [key, limit] of limitEntries) {
|
|
58
|
+
if (type.startsWith(key)) return limit
|
|
59
|
+
}
|
|
60
|
+
return maxSize
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* every method: a DELETE or PROPFIND with a body is as large as a POST */
|
|
29
64
|
const mw: MiddlewareFn<{ req: Request }, {}> = (ctx, next) => {
|
|
30
65
|
const req = ctx.req
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
66
|
+
const contentLength = req.headers.get("content-length")
|
|
67
|
+
const body = req.body
|
|
68
|
+
if (body === null && contentLength === null) return next()
|
|
35
69
|
|
|
36
|
-
|
|
37
|
-
let resolvedMax = maxSize
|
|
38
|
-
if (limitEntries !== null) {
|
|
39
|
-
const ct = req.headers.get("content-type")
|
|
40
|
-
if (ct !== null) {
|
|
41
|
-
for (const [key, limit] of limitEntries) {
|
|
42
|
-
if (ct.startsWith(key)) {
|
|
43
|
-
resolvedMax = limit
|
|
44
|
-
break
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
70
|
+
const limit = resolveMax(req)
|
|
49
71
|
|
|
50
72
|
/* fast path: Content-Length header present */
|
|
51
|
-
const contentLength = req.headers.get("content-length")
|
|
52
73
|
if (contentLength !== null) {
|
|
53
74
|
const len = Number.parseInt(contentLength, 10)
|
|
54
|
-
if (!Number.isNaN(len) && len >
|
|
55
|
-
throw new HoneyError({
|
|
56
|
-
errorKey: EK.content_too_large,
|
|
57
|
-
status: SK.content_too_large,
|
|
58
|
-
})
|
|
59
|
-
}
|
|
75
|
+
if (!Number.isNaN(len) && len > limit) throw tooLarge()
|
|
60
76
|
if (trustContentLength === true) return next()
|
|
61
77
|
}
|
|
62
78
|
|
|
63
79
|
/* slow path: stream-count when no Content-Length (chunked) or trustContentLength disabled.
|
|
64
80
|
* On overflow, error the downstream consumer then drain (do not cancel) the upstream —
|
|
65
81
|
* cancelling an undici FormData body mid-encode enqueues into a closed stream on Node 24. */
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
if (body === null) return next()
|
|
83
|
+
|
|
84
|
+
let totalBytes = 0
|
|
85
|
+
let overflowed = false
|
|
86
|
+
const reader = body.getReader()
|
|
87
|
+
|
|
88
|
+
const drainUpstream = (): void => {
|
|
89
|
+
void (async () => {
|
|
90
|
+
let drained = 0
|
|
91
|
+
try {
|
|
92
|
+
while (true) {
|
|
93
|
+
const r = await reader.read()
|
|
94
|
+
if (r.done) break
|
|
95
|
+
drained += r.value.byteLength
|
|
96
|
+
if (drained > DRAIN_LIMIT) {
|
|
97
|
+
await reader.cancel()
|
|
98
|
+
break
|
|
78
99
|
}
|
|
79
|
-
} catch {
|
|
80
|
-
/* producer may already be done */
|
|
81
100
|
}
|
|
82
|
-
}
|
|
83
|
-
|
|
101
|
+
} catch {
|
|
102
|
+
/* producer may already be done */
|
|
103
|
+
}
|
|
104
|
+
})()
|
|
105
|
+
}
|
|
84
106
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
107
|
+
const limited = new ReadableStream<Uint8Array>({
|
|
108
|
+
cancel() {
|
|
109
|
+
/* consumer aborted — still drain so undici FormData encoders can finish */
|
|
110
|
+
drainUpstream()
|
|
111
|
+
},
|
|
112
|
+
async pull(controller) {
|
|
113
|
+
if (overflowed) return
|
|
114
|
+
let result: ReadableStreamReadResult<Uint8Array>
|
|
115
|
+
try {
|
|
116
|
+
result = await reader.read()
|
|
117
|
+
} catch (err) {
|
|
118
|
+
controller.error(err)
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
if (result.done) {
|
|
122
|
+
controller.close()
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
totalBytes += result.value.byteLength
|
|
126
|
+
if (totalBytes > limit) {
|
|
127
|
+
overflowed = true
|
|
128
|
+
controller.error(tooLarge())
|
|
88
129
|
drainUpstream()
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (totalBytes > limit) {
|
|
106
|
-
overflowed = true
|
|
107
|
-
controller.error(
|
|
108
|
-
new HoneyError({
|
|
109
|
-
errorKey: EK.content_too_large,
|
|
110
|
-
status: SK.content_too_large,
|
|
111
|
-
}),
|
|
112
|
-
)
|
|
113
|
-
drainUpstream()
|
|
114
|
-
return
|
|
115
|
-
}
|
|
116
|
-
controller.enqueue(result.value)
|
|
117
|
-
},
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
const replaceBody = (req as unknown as Record<symbol, unknown>)[Symbol.for("honey.replaceBody")]
|
|
121
|
-
if (typeof replaceBody === "function") {
|
|
122
|
-
;(replaceBody as (stream: ReadableStream<Uint8Array>) => void).call(req, limited)
|
|
123
|
-
} else {
|
|
124
|
-
/* duplex: "half" required by Node/undici when body is a ReadableStream */
|
|
125
|
-
const newReq = new Request(req, {
|
|
126
|
-
body: limited,
|
|
127
|
-
duplex: "half",
|
|
128
|
-
} as RequestInit)
|
|
129
|
-
Object.defineProperty(ctx, "req", { configurable: true, value: newReq })
|
|
130
|
-
}
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
controller.enqueue(result.value)
|
|
133
|
+
},
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
const replaceBody = (req as unknown as Record<symbol, unknown>)[Symbol.for("honey.replaceBody")]
|
|
137
|
+
if (typeof replaceBody === "function") {
|
|
138
|
+
;(replaceBody as (stream: ReadableStream<Uint8Array>) => void).call(req, limited)
|
|
139
|
+
} else {
|
|
140
|
+
/* duplex: "half" required by Node/undici when body is a ReadableStream */
|
|
141
|
+
const newReq = new Request(req, {
|
|
142
|
+
body: limited,
|
|
143
|
+
duplex: "half",
|
|
144
|
+
} as RequestInit)
|
|
145
|
+
Object.defineProperty(ctx, "req", { configurable: true, value: newReq })
|
|
131
146
|
}
|
|
132
147
|
|
|
133
148
|
return next()
|
package/src/build/index.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs"
|
|
2
2
|
import { builtinModules } from "node:module"
|
|
3
|
-
import { resolve } from "node:path"
|
|
3
|
+
import { extname, resolve } from "node:path"
|
|
4
|
+
import { detectFeaturesInSource, FEATURES, featurePrelude, type HoneyFeature, scanProgram } from "../feature-detect.ts"
|
|
4
5
|
|
|
5
6
|
/* ---- Public types ---- */
|
|
6
7
|
|
|
7
8
|
export type HoneyBuildConfig = {
|
|
8
9
|
external?: string[]
|
|
10
|
+
/**
|
|
11
|
+
* Force optional features on or off. Unset features are detected by scanning the app's
|
|
12
|
+
* import graph for `.openapi()` / `.manifest()`, `.errorI18n()` and `.serve()` calls.
|
|
13
|
+
*/
|
|
14
|
+
features?: Partial<Record<HoneyFeature, boolean>>
|
|
9
15
|
minify?: boolean
|
|
10
16
|
outDir?: string
|
|
11
17
|
port?: number
|
|
@@ -22,46 +28,38 @@ type ResolvedBuildConfig = {
|
|
|
22
28
|
|
|
23
29
|
type BuildAdapterDef = {
|
|
24
30
|
entry(config: ResolvedBuildConfig): string
|
|
31
|
+
/** Bundle every dependency. Workers have no node_modules at run time. */
|
|
32
|
+
noExternal: boolean
|
|
33
|
+
/** Features the target can never use. */
|
|
34
|
+
skipFeatures: HoneyFeature[]
|
|
25
35
|
ssrTarget: "node" | "webworker"
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
/* ---- Entry helpers ---- */
|
|
29
39
|
|
|
30
|
-
function featurePrelude(appSource: string): string {
|
|
31
|
-
const lines: string[] = []
|
|
32
|
-
if (/\.openapi\s*\(|\.manifest\s*\(/.test(appSource)) {
|
|
33
|
-
lines.push('import { enableOpenApi } from "@lovrozagar/honey/openapi"', "enableOpenApi()")
|
|
34
|
-
}
|
|
35
|
-
if (/\.errorI18n\s*\(/.test(appSource)) {
|
|
36
|
-
lines.push('import { enableI18n } from "@lovrozagar/honey/i18n"', "enableI18n()")
|
|
37
|
-
}
|
|
38
|
-
if (/(?<!Bun)(?<!Deno)\.serve\s*\(/.test(appSource)) {
|
|
39
|
-
lines.push('import { enableServe } from "@lovrozagar/honey/serve"', "enableServe()")
|
|
40
|
-
}
|
|
41
|
-
return lines.length > 0 ? `${lines.join("\n")}\n` : ""
|
|
42
|
-
}
|
|
43
|
-
|
|
44
40
|
function importApp(entry: string, exportName: string): string {
|
|
45
41
|
if (exportName === "default") return `import app from "./${entry}"`
|
|
46
42
|
return `import { ${exportName} as app } from "./${entry}"`
|
|
47
43
|
}
|
|
48
44
|
|
|
45
|
+
/* server targets start through the same code path as `app.serve()`: WS adapter, env, hostname */
|
|
46
|
+
function serverEntry(config: ResolvedBuildConfig, runtime: "bun" | "deno" | "node", env: string, port: string): string {
|
|
47
|
+
return [
|
|
48
|
+
'import { startHoneyServer } from "@lovrozagar/honey/serve"',
|
|
49
|
+
importApp(config.entry, config.export),
|
|
50
|
+
"",
|
|
51
|
+
`const port = Number(${port})`,
|
|
52
|
+
`await startHoneyServer(app, { env: ${env}, hostname: "0.0.0.0", port, runtime: "${runtime}" })`,
|
|
53
|
+
].join("\n")
|
|
54
|
+
}
|
|
55
|
+
|
|
49
56
|
/* ---- Adapter definitions ---- */
|
|
50
57
|
|
|
51
58
|
const adapters: Record<HoneyBuildConfig["target"], BuildAdapterDef> = {
|
|
52
59
|
bun: {
|
|
53
|
-
entry(config) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"",
|
|
57
|
-
`const port = Number(process.env.PORT ?? ${config.port})`,
|
|
58
|
-
"Bun.serve({",
|
|
59
|
-
" fetch: (req, server) => app.fetch(req, { server }),",
|
|
60
|
-
' hostname: "0.0.0.0",',
|
|
61
|
-
" port,",
|
|
62
|
-
"})",
|
|
63
|
-
].join("\n")
|
|
64
|
-
},
|
|
60
|
+
entry: (config) => serverEntry(config, "bun", "process.env", `process.env.PORT ?? ${config.port}`),
|
|
61
|
+
noExternal: false,
|
|
62
|
+
skipFeatures: [],
|
|
65
63
|
ssrTarget: "node",
|
|
66
64
|
},
|
|
67
65
|
cloudflare: {
|
|
@@ -74,33 +72,81 @@ const adapters: Record<HoneyBuildConfig["target"], BuildAdapterDef> = {
|
|
|
74
72
|
"}",
|
|
75
73
|
].join("\n")
|
|
76
74
|
},
|
|
75
|
+
noExternal: true,
|
|
76
|
+
/* a Worker cannot listen; serve would pull node:http into the bundle */
|
|
77
|
+
skipFeatures: ["serve"],
|
|
77
78
|
ssrTarget: "webworker",
|
|
78
79
|
},
|
|
79
80
|
deno: {
|
|
80
|
-
entry(config) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"",
|
|
84
|
-
`const port = Number(Deno.env.get("PORT") ?? "${config.port}")`,
|
|
85
|
-
'Deno.serve({ hostname: "0.0.0.0", port }, (req) => app.fetch(req, {}))',
|
|
86
|
-
].join("\n")
|
|
87
|
-
},
|
|
81
|
+
entry: (config) => serverEntry(config, "deno", "Deno.env.toObject()", `Deno.env.get("PORT") ?? "${config.port}"`),
|
|
82
|
+
noExternal: true,
|
|
83
|
+
skipFeatures: [],
|
|
88
84
|
ssrTarget: "webworker",
|
|
89
85
|
},
|
|
90
86
|
node: {
|
|
91
|
-
entry(config) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
importApp(config.entry, config.export),
|
|
95
|
-
"",
|
|
96
|
-
`const port = Number(process.env.PORT ?? ${config.port})`,
|
|
97
|
-
'serve(app, { env: process.env, hostname: "0.0.0.0", port })',
|
|
98
|
-
].join("\n")
|
|
99
|
-
},
|
|
87
|
+
entry: (config) => serverEntry(config, "node", "process.env", `process.env.PORT ?? ${config.port}`),
|
|
88
|
+
noExternal: false,
|
|
89
|
+
skipFeatures: [],
|
|
100
90
|
ssrTarget: "node",
|
|
101
91
|
},
|
|
102
92
|
}
|
|
103
93
|
|
|
94
|
+
/* ---- Feature detection over the import graph ---- */
|
|
95
|
+
|
|
96
|
+
const SCANNED_EXT = /\.(?:[cm]?[jt]sx?)$/
|
|
97
|
+
|
|
98
|
+
type ParseContext = {
|
|
99
|
+
parse?: (code: string, options?: { lang?: "js" | "jsx" | "ts" | "tsx" }) => unknown
|
|
100
|
+
resolve?: (source: string, importer?: string) => Promise<{ external?: unknown; id: string } | null>
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function langOf(file: string): "js" | "jsx" | "ts" | "tsx" {
|
|
104
|
+
const ext = extname(file)
|
|
105
|
+
if (ext === ".tsx") return "tsx"
|
|
106
|
+
if (ext === ".jsx") return "jsx"
|
|
107
|
+
return /^\.[cm]?ts$/.test(ext) ? "ts" : "js"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Walks the app's own modules (never node_modules) from `entry`, following static and dynamic
|
|
112
|
+
* imports, and collects feature calls. Comments and strings do not count.
|
|
113
|
+
*/
|
|
114
|
+
async function detectGraphFeatures(ctx: ParseContext, entry: string): Promise<Set<HoneyFeature>> {
|
|
115
|
+
const features = new Set<HoneyFeature>()
|
|
116
|
+
const seen = new Set<string>()
|
|
117
|
+
const queue = [entry]
|
|
118
|
+
while (queue.length > 0) {
|
|
119
|
+
const file = queue.pop() as string
|
|
120
|
+
if (seen.has(file)) continue
|
|
121
|
+
seen.add(file)
|
|
122
|
+
if (!SCANNED_EXT.test(file) || file.includes("node_modules") || !existsSync(file)) continue
|
|
123
|
+
const code = readFileSync(file, "utf-8")
|
|
124
|
+
|
|
125
|
+
let imports: string[] = []
|
|
126
|
+
let program: unknown
|
|
127
|
+
try {
|
|
128
|
+
program = ctx.parse?.(code, { lang: langOf(file) })
|
|
129
|
+
} catch {
|
|
130
|
+
program = undefined
|
|
131
|
+
}
|
|
132
|
+
if (program) {
|
|
133
|
+
const scanned = scanProgram(program)
|
|
134
|
+
for (const f of scanned.features) features.add(f)
|
|
135
|
+
imports = scanned.imports
|
|
136
|
+
} else {
|
|
137
|
+
for (const f of detectFeaturesInSource(code)) features.add(f)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (!ctx.resolve) continue
|
|
141
|
+
for (const source of imports) {
|
|
142
|
+
const resolved = await ctx.resolve(source, file).catch(() => null)
|
|
143
|
+
if (!resolved || resolved.external || resolved.id.startsWith("\0")) continue
|
|
144
|
+
queue.push(resolved.id.split("?")[0] as string)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return features
|
|
148
|
+
}
|
|
149
|
+
|
|
104
150
|
/* ---- Virtual module constants ---- */
|
|
105
151
|
|
|
106
152
|
const VIRTUAL_BUILD_ENTRY = "virtual:honey-build-entry"
|
|
@@ -135,7 +181,8 @@ export function createBuildPlugin(buildConfig: HoneyBuildConfig, shared: { entry
|
|
|
135
181
|
ssr: true,
|
|
136
182
|
},
|
|
137
183
|
ssr: {
|
|
138
|
-
|
|
184
|
+
/* node and bun install dependencies next to the bundle; inlining them would also inline native addons */
|
|
185
|
+
...(adapter.noExternal ? { noExternal: true } : {}),
|
|
139
186
|
target: adapter.ssrTarget,
|
|
140
187
|
},
|
|
141
188
|
}
|
|
@@ -145,16 +192,19 @@ export function createBuildPlugin(buildConfig: HoneyBuildConfig, shared: { entry
|
|
|
145
192
|
root = cfg.root
|
|
146
193
|
},
|
|
147
194
|
|
|
148
|
-
load(id: string): { code: string; moduleType: string } | undefined {
|
|
149
|
-
if (id
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
195
|
+
async load(this: ParseContext | undefined, id: string): Promise<{ code: string; moduleType: string } | undefined> {
|
|
196
|
+
if (id !== RESOLVED_BUILD_ENTRY) return undefined
|
|
197
|
+
const appPath = resolve(root || ".", shared.entry)
|
|
198
|
+
const detected = await detectGraphFeatures(this ?? {}, appPath)
|
|
199
|
+
const features = FEATURES.filter((feature) => {
|
|
200
|
+
if (adapter.skipFeatures.includes(feature)) return false
|
|
201
|
+
return buildConfig.features?.[feature] ?? detected.has(feature)
|
|
202
|
+
})
|
|
203
|
+
const prelude = featurePrelude(features)
|
|
204
|
+
return {
|
|
205
|
+
code: `${prelude ? `${prelude}\n` : ""}${adapter.entry(resolvedConfig)}`,
|
|
206
|
+
moduleType: "js",
|
|
156
207
|
}
|
|
157
|
-
return undefined
|
|
158
208
|
},
|
|
159
209
|
|
|
160
210
|
name: "honey:build",
|
package/src/cli-args.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/** Argument parsing for the `honey` CLI. Not a package export. */
|
|
2
|
+
|
|
3
|
+
export const USAGE = `Usage: honey generate [options]
|
|
4
|
+
honey init [--cf] [--force]
|
|
5
|
+
|
|
6
|
+
generate options:
|
|
7
|
+
--config <path> Vite config holding honey() (default: vite.config.{ts,mts,js,mjs,…})
|
|
8
|
+
--plugin <n> Which honey() plugin in the config, 0-based (when there are several)
|
|
9
|
+
--app <path> App entry; overrides the config's app, or replaces the config
|
|
10
|
+
--watch Regenerate when files next to the app change
|
|
11
|
+
--tree --types --manifest --sdk
|
|
12
|
+
Turn on an output
|
|
13
|
+
--merge-tree <path> Route tree source for a gateway
|
|
14
|
+
--cli --cli-out <dir> --cli-binary-name <name> [--cli-config-name <name>]
|
|
15
|
+
[--cli-default-base-url <url>] [--cli-env-prefix <prefix>] [--cli-module-path <path>]
|
|
16
|
+
[--cli-sdk-module-path <path>]
|
|
17
|
+
Generate the Go CLI
|
|
18
|
+
-h, --help Show this help`
|
|
19
|
+
|
|
20
|
+
export class UsageError extends Error {}
|
|
21
|
+
|
|
22
|
+
export type CliFlags = {
|
|
23
|
+
app?: string
|
|
24
|
+
cli?: boolean
|
|
25
|
+
cliBinaryName?: string
|
|
26
|
+
cliConfigName?: string
|
|
27
|
+
cliDefaultBaseUrl?: string
|
|
28
|
+
cliEnvPrefix?: string
|
|
29
|
+
cliModulePath?: string
|
|
30
|
+
cliOut?: string
|
|
31
|
+
cliSdkModulePath?: string
|
|
32
|
+
config?: string
|
|
33
|
+
help?: boolean
|
|
34
|
+
manifest?: boolean
|
|
35
|
+
mergeTree?: string
|
|
36
|
+
plugin?: number
|
|
37
|
+
sdk?: boolean
|
|
38
|
+
tree?: boolean
|
|
39
|
+
types?: boolean
|
|
40
|
+
watch?: boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const BOOLEAN_FLAGS: Record<string, keyof CliFlags> = {
|
|
44
|
+
cli: "cli",
|
|
45
|
+
help: "help",
|
|
46
|
+
manifest: "manifest",
|
|
47
|
+
sdk: "sdk",
|
|
48
|
+
tree: "tree",
|
|
49
|
+
types: "types",
|
|
50
|
+
watch: "watch",
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const VALUE_FLAGS: Record<string, keyof CliFlags> = {
|
|
54
|
+
app: "app",
|
|
55
|
+
"cli-binary-name": "cliBinaryName",
|
|
56
|
+
"cli-config-name": "cliConfigName",
|
|
57
|
+
"cli-default-base-url": "cliDefaultBaseUrl",
|
|
58
|
+
"cli-env-prefix": "cliEnvPrefix",
|
|
59
|
+
"cli-module-path": "cliModulePath",
|
|
60
|
+
"cli-out": "cliOut",
|
|
61
|
+
"cli-sdk-module-path": "cliSdkModulePath",
|
|
62
|
+
config: "config",
|
|
63
|
+
"merge-tree": "mergeTree",
|
|
64
|
+
plugin: "plugin",
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Strict: unknown flags, stray positionals and missing values are errors. Accepts `--k v` and `--k=v`. */
|
|
68
|
+
export function parseGenerateArgs(args: string[]): CliFlags {
|
|
69
|
+
const flags: Record<string, unknown> = {}
|
|
70
|
+
for (let i = 0; i < args.length; i++) {
|
|
71
|
+
const arg = args[i] as string
|
|
72
|
+
if (arg === "-h") {
|
|
73
|
+
flags.help = true
|
|
74
|
+
continue
|
|
75
|
+
}
|
|
76
|
+
if (!arg.startsWith("--") || arg === "--") throw new UsageError(`unexpected argument: ${arg}`)
|
|
77
|
+
const eq = arg.indexOf("=")
|
|
78
|
+
const name = eq === -1 ? arg.slice(2) : arg.slice(2, eq)
|
|
79
|
+
const inline = eq === -1 ? undefined : arg.slice(eq + 1)
|
|
80
|
+
|
|
81
|
+
const bool = BOOLEAN_FLAGS[name]
|
|
82
|
+
if (bool) {
|
|
83
|
+
if (inline === undefined || inline === "true") flags[bool] = true
|
|
84
|
+
else if (inline === "false") flags[bool] = false
|
|
85
|
+
else throw new UsageError(`--${name} takes no value (got "${inline}")`)
|
|
86
|
+
continue
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const key = VALUE_FLAGS[name]
|
|
90
|
+
if (!key) throw new UsageError(`unknown option: --${name}`)
|
|
91
|
+
let value = inline
|
|
92
|
+
if (value === undefined) {
|
|
93
|
+
const next = args[i + 1]
|
|
94
|
+
if (next === undefined || next.startsWith("--")) throw new UsageError(`--${name} requires a value`)
|
|
95
|
+
value = next
|
|
96
|
+
i++
|
|
97
|
+
}
|
|
98
|
+
if (value === "") throw new UsageError(`--${name} requires a value`)
|
|
99
|
+
if (key === "plugin") {
|
|
100
|
+
if (!/^\d+$/.test(value)) throw new UsageError(`--plugin takes a non-negative integer (got "${value}")`)
|
|
101
|
+
flags.plugin = Number(value)
|
|
102
|
+
} else {
|
|
103
|
+
flags[key] = value
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return flags as CliFlags
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** `honey init` flags. `--cloudflare` is an alias of `--cf`. */
|
|
110
|
+
export type InitFlags = {
|
|
111
|
+
cf: boolean
|
|
112
|
+
force: boolean
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function parseInitFlags(args: string[]): InitFlags {
|
|
116
|
+
const flags: InitFlags = { cf: false, force: false }
|
|
117
|
+
for (const arg of args) {
|
|
118
|
+
if (arg === "--cf" || arg === "--cloudflare") flags.cf = true
|
|
119
|
+
else if (arg === "--force") flags.force = true
|
|
120
|
+
else throw new UsageError(arg.startsWith("-") ? `unknown option: ${arg}` : `unexpected argument: ${arg}`)
|
|
121
|
+
}
|
|
122
|
+
return flags
|
|
123
|
+
}
|
package/src/cli-go/auth.go
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// Code generated by honey. DO NOT EDIT.
|
|
2
2
|
package cli
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import (
|
|
5
|
+
"errors"
|
|
6
|
+
"net/http"
|
|
7
|
+
)
|
|
5
8
|
|
|
6
9
|
// ErrMissingAPIKey is returned when no API key can be found via flags, env, or config file.
|
|
7
10
|
var ErrMissingAPIKey = errors.New("api key required: set --api-key, env var, or config file")
|
|
@@ -13,3 +16,11 @@ func ResolveAPIKey(cfg Config) (string, error) {
|
|
|
13
16
|
}
|
|
14
17
|
return "", ErrMissingAPIKey
|
|
15
18
|
}
|
|
19
|
+
|
|
20
|
+
// ApplyAuth sets the auth header for apiKey: prefix + key under headerName.
|
|
21
|
+
func ApplyAuth(h http.Header, headerName, prefix, apiKey string) {
|
|
22
|
+
if apiKey == "" {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
h.Set(headerName, prefix+apiKey)
|
|
26
|
+
}
|
package/src/cli-go/config.go
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
package cli
|
|
3
3
|
|
|
4
4
|
import (
|
|
5
|
+
"errors"
|
|
5
6
|
"fmt"
|
|
6
7
|
"io"
|
|
8
|
+
"io/fs"
|
|
7
9
|
"os"
|
|
8
10
|
"path/filepath"
|
|
11
|
+
"runtime"
|
|
9
12
|
|
|
10
13
|
"github.com/pelletier/go-toml/v2"
|
|
11
14
|
"github.com/spf13/pflag"
|
|
@@ -44,21 +47,30 @@ func LoadConfig(flags *pflag.FlagSet, envPrefix, configName string) (Config, err
|
|
|
44
47
|
var cfg Config
|
|
45
48
|
|
|
46
49
|
cfgPath := ""
|
|
50
|
+
explicit := false
|
|
47
51
|
if flags.Changed("config") {
|
|
48
52
|
v, _ := flags.GetString("config")
|
|
49
53
|
cfgPath = v
|
|
54
|
+
explicit = true
|
|
50
55
|
} else if v := os.Getenv(envPrefix + "_CONFIG"); v != "" {
|
|
51
56
|
cfgPath = v
|
|
57
|
+
explicit = true
|
|
52
58
|
} else {
|
|
53
59
|
cfgPath = defaultConfigPath(configName)
|
|
54
60
|
}
|
|
55
61
|
|
|
56
62
|
var fromFile tomlConfig
|
|
57
63
|
if cfgPath != "" {
|
|
58
|
-
|
|
64
|
+
data, err := os.ReadFile(cfgPath)
|
|
65
|
+
switch {
|
|
66
|
+
case err == nil:
|
|
59
67
|
if err := toml.Unmarshal(data, &fromFile); err != nil {
|
|
60
|
-
return cfg, fmt.Errorf("parse config %s: %w", cfgPath, err)
|
|
68
|
+
return cfg, Usage(fmt.Errorf("parse config %s: %w", cfgPath, err))
|
|
61
69
|
}
|
|
70
|
+
warnIfReadableByOthers(cfgPath, fromFile.APIKey != "")
|
|
71
|
+
case explicit || !errors.Is(err, fs.ErrNotExist):
|
|
72
|
+
/* a config the user named must exist; only the default path may be absent */
|
|
73
|
+
return cfg, Usage(fmt.Errorf("read config %s: %w", cfgPath, err))
|
|
62
74
|
}
|
|
63
75
|
}
|
|
64
76
|
cfg.ConfigPath = cfgPath
|
|
@@ -113,6 +125,21 @@ func LoadConfig(flags *pflag.FlagSet, envPrefix, configName string) (Config, err
|
|
|
113
125
|
return cfg, nil
|
|
114
126
|
}
|
|
115
127
|
|
|
128
|
+
// warnIfReadableByOthers warns when a config file holding an API key can be
|
|
129
|
+
// read by group or other users.
|
|
130
|
+
func warnIfReadableByOthers(path string, hasKey bool) {
|
|
131
|
+
if !hasKey || runtime.GOOS == "windows" {
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
info, err := os.Stat(path)
|
|
135
|
+
if err != nil {
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
if info.Mode().Perm()&0o077 != 0 {
|
|
139
|
+
fmt.Fprintf(os.Stderr, "warning: %s holds an API key and is readable by other users; run: chmod 600 %s\n", path, path)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
116
143
|
func defaultConfigPath(configName string) string {
|
|
117
144
|
if configName == "" {
|
|
118
145
|
return ""
|