@lovrozagar/honey 0.6.8 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +514 -192
- package/bin/honey.js +25 -0
- package/dist/accepts.d.ts +7 -1
- package/dist/accepts.d.ts.map +1 -1
- package/dist/accepts.js +126 -0
- package/dist/accepts.js.map +1 -0
- package/dist/body-kind.d.ts +26 -0
- package/dist/body-kind.d.ts.map +1 -0
- package/dist/body-kind.js +70 -0
- package/dist/body-kind.js.map +1 -0
- package/dist/body-limit.d.ts +5 -1
- package/dist/body-limit.d.ts.map +1 -1
- package/dist/body-limit.js +126 -0
- package/dist/body-limit.js.map +1 -0
- package/dist/build/index.d.ts +19 -3
- package/dist/build/index.d.ts.map +1 -1
- package/dist/build/index.js +173 -0
- package/dist/build/index.js.map +1 -0
- package/dist/cli-args.d.ts +33 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +102 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-go/auth.go +26 -0
- package/dist/cli-go/config.go +192 -0
- package/dist/cli-go/errors.go +75 -0
- package/dist/cli-go/multipart.go +79 -0
- package/dist/cli-go/output.go +163 -0
- package/dist/cli-go/root.go +30 -0
- package/dist/cli-go/stream.go +88 -0
- package/dist/cli-go/version.go +5 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +209 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/defaults.js +48 -0
- package/dist/client/defaults.js.map +1 -0
- package/dist/client/error.d.ts +35 -0
- package/dist/client/error.d.ts.map +1 -1
- package/dist/client/error.js +71 -0
- package/dist/client/error.js.map +1 -0
- package/dist/client/http.d.ts +67 -8
- package/dist/client/http.d.ts.map +1 -1
- package/dist/client/http.js +571 -0
- package/dist/client/http.js.map +1 -0
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +95 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/path.d.ts +26 -0
- package/dist/client/path.d.ts.map +1 -0
- package/dist/client/path.js +163 -0
- package/dist/client/path.js.map +1 -0
- package/dist/client/redirect-policy.d.ts +12 -0
- package/dist/client/redirect-policy.d.ts.map +1 -0
- package/dist/client/redirect-policy.js +20 -0
- package/dist/client/redirect-policy.js.map +1 -0
- package/dist/client/sdk.d.ts +36 -0
- package/dist/client/sdk.d.ts.map +1 -1
- package/dist/client/sdk.js +292 -0
- package/dist/client/sdk.js.map +1 -0
- package/dist/client/sse.d.ts +13 -0
- package/dist/client/sse.d.ts.map +1 -1
- package/dist/client/sse.js +129 -0
- package/dist/client/sse.js.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/ws.d.ts +9 -2
- package/dist/client/ws.d.ts.map +1 -1
- package/dist/client/ws.js +112 -0
- package/dist/client/ws.js.map +1 -0
- package/dist/client-go/errors.go +236 -0
- package/dist/client-go/export.go +44 -0
- package/dist/client-go/invalidation.go +371 -0
- package/dist/client-go/nullable.go +62 -0
- package/dist/client-go/realtime.go +354 -0
- package/dist/client-go/result.go +20 -0
- package/dist/client-go/runtime.go +975 -0
- package/dist/client-go/sse.go +159 -0
- package/dist/client-go/transport.go +495 -0
- package/dist/client-go/ws.go +128 -0
- package/dist/client-info.d.ts +36 -0
- package/dist/client-info.d.ts.map +1 -0
- package/dist/client-info.js +53 -0
- package/dist/client-info.js.map +1 -0
- package/dist/client-mcp/README.md +10 -0
- package/dist/client-mcp/server.ts +221 -0
- package/dist/client-mcp/types.ts +19 -0
- package/dist/client-python/_errors.py +115 -0
- package/dist/client-python/_invalidation.py +494 -0
- package/dist/client-python/_realtime.py +179 -0
- package/dist/client-python/_runtime.py +860 -0
- package/dist/client-python/_sse.py +155 -0
- package/dist/client-python/_transport.py +366 -0
- package/dist/client-python/_ws.py +159 -0
- package/dist/client-python/py.typed +0 -0
- package/dist/client-rust/errors.rs +220 -0
- package/dist/client-rust/invalidation.rs +412 -0
- package/dist/client-rust/invalidation_sync.rs +93 -0
- package/dist/client-rust/nullable.rs +17 -0
- package/dist/client-rust/realtime.rs +702 -0
- package/dist/client-rust/result.rs +22 -0
- package/dist/client-rust/runtime.rs +980 -0
- package/dist/client-rust/runtime_sync.rs +484 -0
- package/dist/client-rust/sse.rs +188 -0
- package/dist/client-rust/ws.rs +167 -0
- package/dist/codegen-go-cli.d.ts.map +1 -1
- package/dist/codegen-go-cli.js +964 -0
- package/dist/codegen-go-cli.js.map +1 -0
- package/dist/codegen-go.d.ts +15 -3
- package/dist/codegen-go.d.ts.map +1 -1
- package/dist/codegen-go.js +872 -0
- package/dist/codegen-go.js.map +1 -0
- package/dist/codegen-hash.js +9 -0
- package/dist/codegen-hash.js.map +1 -0
- package/dist/codegen-ir.d.ts +69 -2
- package/dist/codegen-ir.d.ts.map +1 -1
- package/dist/codegen-ir.js +661 -0
- package/dist/codegen-ir.js.map +1 -0
- package/dist/codegen-lang.d.ts +65 -0
- package/dist/codegen-lang.d.ts.map +1 -0
- package/dist/codegen-lang.js +526 -0
- package/dist/codegen-lang.js.map +1 -0
- package/dist/codegen-load.d.ts +31 -0
- package/dist/codegen-load.d.ts.map +1 -0
- package/dist/codegen-load.js +138 -0
- package/dist/codegen-load.js.map +1 -0
- package/dist/codegen-loaders.js +55 -0
- package/dist/codegen-loaders.js.map +1 -0
- package/dist/codegen-mcp.d.ts.map +1 -1
- package/dist/codegen-mcp.js +368 -0
- package/dist/codegen-mcp.js.map +1 -0
- package/dist/codegen-python.d.ts +13 -1
- package/dist/codegen-python.d.ts.map +1 -1
- package/dist/codegen-python.js +828 -0
- package/dist/codegen-python.js.map +1 -0
- package/dist/codegen-route-tree-intern.d.ts +15 -5
- package/dist/codegen-route-tree-intern.d.ts.map +1 -1
- package/dist/codegen-route-tree-intern.js +221 -0
- package/dist/codegen-route-tree-intern.js.map +1 -0
- package/dist/codegen-rust.d.ts.map +1 -1
- package/dist/codegen-rust.js +1293 -0
- package/dist/codegen-rust.js.map +1 -0
- package/dist/codegen-sanitize.d.ts.map +1 -1
- package/dist/codegen-sanitize.js +56 -0
- package/dist/codegen-sanitize.js.map +1 -0
- package/dist/codegen-schema-naming.d.ts +5 -0
- package/dist/codegen-schema-naming.d.ts.map +1 -1
- package/dist/codegen-schema-naming.js +150 -0
- package/dist/codegen-schema-naming.js.map +1 -0
- package/dist/codegen-sdk-model.d.ts +71 -0
- package/dist/codegen-sdk-model.d.ts.map +1 -0
- package/dist/codegen-sdk-model.js +179 -0
- package/dist/codegen-sdk-model.js.map +1 -0
- package/dist/codegen.d.ts +41 -23
- package/dist/codegen.d.ts.map +1 -1
- package/dist/codegen.js +4610 -0
- package/dist/codegen.js.map +1 -0
- package/dist/context.d.ts +36 -6
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +242 -0
- package/dist/context.js.map +1 -0
- package/dist/cookie-sign.d.ts +16 -2
- package/dist/cookie-sign.d.ts.map +1 -1
- package/dist/cookie-sign.js +104 -0
- package/dist/cookie-sign.js.map +1 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.d.ts.map +1 -1
- package/dist/cookie.js +138 -0
- package/dist/cookie.js.map +1 -0
- package/dist/cors.d.ts +1 -0
- package/dist/cors.d.ts.map +1 -1
- package/dist/cors.js +87 -0
- package/dist/cors.js.map +1 -0
- package/dist/crypto.d.ts +6 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +38 -0
- package/dist/crypto.js.map +1 -0
- package/dist/csrf.d.ts +19 -0
- package/dist/csrf.d.ts.map +1 -1
- package/dist/csrf.js +79 -0
- package/dist/csrf.js.map +1 -0
- package/dist/curl-logger.d.ts +14 -3
- package/dist/curl-logger.d.ts.map +1 -1
- package/dist/curl-logger.js +199 -0
- package/dist/curl-logger.js.map +1 -0
- package/dist/detect-runtime.js +13 -0
- package/dist/detect-runtime.js.map +1 -0
- package/dist/dict.d.ts +11 -0
- package/dist/dict.d.ts.map +1 -0
- package/dist/dict.js +13 -0
- package/dist/dict.js.map +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +44 -0
- package/dist/error.js.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/etag.d.ts +2 -0
- package/dist/etag.d.ts.map +1 -1
- package/dist/etag.js +82 -0
- package/dist/etag.js.map +1 -0
- package/dist/feature-detect.d.ts +25 -0
- package/dist/feature-detect.d.ts.map +1 -0
- package/dist/feature-detect.js +144 -0
- package/dist/feature-detect.js.map +1 -0
- package/dist/feature-load.js +36 -0
- package/dist/feature-load.js.map +1 -0
- package/dist/feature-slots.d.ts +44 -0
- package/dist/feature-slots.d.ts.map +1 -0
- package/dist/feature-slots.js +48 -0
- package/dist/feature-slots.js.map +1 -0
- package/dist/fetch-request.d.ts +10 -0
- package/dist/fetch-request.d.ts.map +1 -0
- package/dist/fetch-request.js +13 -0
- package/dist/fetch-request.js.map +1 -0
- package/dist/gen-process.d.ts +15 -0
- package/dist/gen-process.d.ts.map +1 -0
- package/dist/gen-process.js +43 -0
- package/dist/gen-process.js.map +1 -0
- package/dist/gen-write.d.ts +19 -0
- package/dist/gen-write.d.ts.map +1 -0
- package/dist/gen-write.js +120 -0
- package/dist/gen-write.js.map +1 -0
- package/dist/glob.d.ts +21 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +115 -0
- package/dist/glob.js.map +1 -0
- package/dist/go-type-emitter.d.ts +18 -4
- package/dist/go-type-emitter.d.ts.map +1 -1
- package/dist/go-type-emitter.js +594 -0
- package/dist/go-type-emitter.js.map +1 -0
- package/dist/honey-response.d.ts.map +1 -1
- package/dist/honey-response.js +338 -0
- package/dist/honey-response.js.map +1 -0
- package/dist/i18n-slot.d.ts +8 -0
- package/dist/i18n-slot.d.ts.map +1 -1
- package/dist/i18n-slot.js +14 -0
- package/dist/i18n-slot.js.map +1 -0
- package/dist/i18n.d.ts +3 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +250 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +408 -148
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2324 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +3 -5
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +140 -0
- package/dist/init.js.map +1 -0
- package/dist/input.js +4 -0
- package/dist/input.js.map +1 -0
- package/dist/invalidate-check.d.ts +11 -0
- package/dist/invalidate-check.d.ts.map +1 -1
- package/dist/invalidate-check.js +163 -0
- package/dist/invalidate-check.js.map +1 -0
- package/dist/invoke-user.d.ts +35 -0
- package/dist/invoke-user.d.ts.map +1 -0
- package/dist/invoke-user.js +73 -0
- package/dist/invoke-user.js.map +1 -0
- package/dist/ip-restrict.d.ts +13 -1
- package/dist/ip-restrict.d.ts.map +1 -1
- package/dist/ip-restrict.js +60 -0
- package/dist/ip-restrict.js.map +1 -0
- package/dist/ip.d.ts +39 -0
- package/dist/ip.d.ts.map +1 -0
- package/dist/ip.js +209 -0
- package/dist/ip.js.map +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +113 -0
- package/dist/logger.js.map +1 -0
- package/dist/media-type.d.ts +30 -0
- package/dist/media-type.d.ts.map +1 -0
- package/dist/media-type.js +97 -0
- package/dist/media-type.js.map +1 -0
- package/dist/meta-spec-merge.d.ts +32 -0
- package/dist/meta-spec-merge.d.ts.map +1 -0
- package/dist/meta-spec-merge.js +68 -0
- package/dist/meta-spec-merge.js.map +1 -0
- package/dist/meta-spec.d.ts +16 -3
- package/dist/meta-spec.d.ts.map +1 -1
- package/dist/meta-spec.js +535 -0
- package/dist/meta-spec.js.map +1 -0
- package/dist/middleware.d.ts +23 -6
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +253 -0
- package/dist/middleware.js.map +1 -0
- package/dist/node-request.d.ts +57 -12
- package/dist/node-request.d.ts.map +1 -1
- package/dist/node-request.js +407 -0
- package/dist/node-request.js.map +1 -0
- package/dist/node.d.ts +20 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +396 -0
- package/dist/node.js.map +1 -0
- package/dist/openapi/collect.d.ts +6 -3
- package/dist/openapi/collect.d.ts.map +1 -1
- package/dist/openapi/collect.js +30 -0
- package/dist/openapi/collect.js.map +1 -0
- package/dist/openapi/docs-page.d.ts +42 -0
- package/dist/openapi/docs-page.d.ts.map +1 -0
- package/dist/openapi/docs-page.js +80 -0
- package/dist/openapi/docs-page.js.map +1 -0
- package/dist/openapi/document.d.ts +4 -0
- package/dist/openapi/document.d.ts.map +1 -1
- package/dist/openapi/document.js +785 -0
- package/dist/openapi/document.js.map +1 -0
- package/dist/openapi/json-schema-slot.d.ts +7 -0
- package/dist/openapi/json-schema-slot.d.ts.map +1 -1
- package/dist/openapi/json-schema-slot.js +38 -0
- package/dist/openapi/json-schema-slot.js.map +1 -0
- package/dist/openapi/register.d.ts.map +1 -1
- package/dist/openapi/register.js +20 -0
- package/dist/openapi/register.js.map +1 -0
- package/dist/openapi/scalar.d.ts +3 -1
- package/dist/openapi/scalar.d.ts.map +1 -1
- package/dist/openapi/scalar.js +21 -0
- package/dist/openapi/scalar.js.map +1 -0
- package/dist/openapi/serve.d.ts +9 -0
- package/dist/openapi/serve.d.ts.map +1 -0
- package/dist/openapi/serve.js +36 -0
- package/dist/openapi/serve.js.map +1 -0
- package/dist/openapi/spec-factory.d.ts +30 -1
- package/dist/openapi/spec-factory.d.ts.map +1 -1
- package/dist/openapi/spec-factory.js +52 -0
- package/dist/openapi/spec-factory.js.map +1 -0
- package/dist/openapi/spec.d.ts +14 -5
- package/dist/openapi/spec.d.ts.map +1 -1
- package/dist/openapi/spec.js +50 -0
- package/dist/openapi/spec.js.map +1 -0
- package/dist/openapi/swagger.d.ts +3 -1
- package/dist/openapi/swagger.d.ts.map +1 -1
- package/dist/openapi/swagger.js +22 -0
- package/dist/openapi/swagger.js.map +1 -0
- package/dist/pattern.d.ts +71 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +239 -0
- package/dist/pattern.js.map +1 -0
- package/dist/peer.d.ts +17 -0
- package/dist/peer.d.ts.map +1 -0
- package/dist/peer.js +50 -0
- package/dist/peer.js.map +1 -0
- package/dist/plugin.d.ts +67 -16
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +649 -0
- package/dist/plugin.js.map +1 -0
- package/dist/powered-by.d.ts.map +1 -1
- package/dist/powered-by.js +11 -0
- package/dist/powered-by.js.map +1 -0
- package/dist/pretty-json.d.ts.map +1 -1
- package/dist/pretty-json.js +47 -0
- package/dist/pretty-json.js.map +1 -0
- package/dist/producer-stream.d.ts +47 -0
- package/dist/producer-stream.d.ts.map +1 -0
- package/dist/producer-stream.js +267 -0
- package/dist/producer-stream.js.map +1 -0
- package/dist/proxy.d.ts +47 -8
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +274 -0
- package/dist/proxy.js.map +1 -0
- package/dist/python-type-emitter.d.ts +14 -1
- package/dist/python-type-emitter.d.ts.map +1 -1
- package/dist/python-type-emitter.js +157 -0
- package/dist/python-type-emitter.js.map +1 -0
- package/dist/realtime/bus.d.ts +17 -1
- package/dist/realtime/bus.d.ts.map +1 -1
- package/dist/realtime/bus.js +112 -0
- package/dist/realtime/bus.js.map +1 -0
- package/dist/realtime/register.d.ts +3 -0
- package/dist/realtime/register.d.ts.map +1 -0
- package/dist/realtime/register.js +10 -0
- package/dist/realtime/register.js.map +1 -0
- package/dist/realtime/route.d.ts +65 -26
- package/dist/realtime/route.d.ts.map +1 -1
- package/dist/realtime/route.js +72 -0
- package/dist/realtime/route.js.map +1 -0
- package/dist/realtime/server.d.ts +43 -0
- package/dist/realtime/server.d.ts.map +1 -0
- package/dist/realtime/server.js +255 -0
- package/dist/realtime/server.js.map +1 -0
- package/dist/request-id.d.ts +7 -0
- package/dist/request-id.d.ts.map +1 -1
- package/dist/request-id.js +16 -0
- package/dist/request-id.js.map +1 -0
- package/dist/request-limits.d.ts +3 -0
- package/dist/request-limits.d.ts.map +1 -0
- package/dist/request-limits.js +3 -0
- package/dist/request-limits.js.map +1 -0
- package/dist/request-path.d.ts +33 -0
- package/dist/request-path.d.ts.map +1 -0
- package/dist/request-path.js +178 -0
- package/dist/request-path.js.map +1 -0
- package/dist/request-to-curl.d.ts +7 -1
- package/dist/request-to-curl.d.ts.map +1 -1
- package/dist/request-to-curl.js +48 -0
- package/dist/request-to-curl.js.map +1 -0
- package/dist/response.d.ts +25 -2
- package/dist/response.d.ts.map +1 -1
- package/dist/response.js +313 -0
- package/dist/response.js.map +1 -0
- package/dist/rust-type-emitter.d.ts +14 -2
- package/dist/rust-type-emitter.d.ts.map +1 -1
- package/dist/rust-type-emitter.js +463 -0
- package/dist/rust-type-emitter.js.map +1 -0
- package/dist/secure-headers.d.ts.map +1 -1
- package/dist/secure-headers.js +53 -0
- package/dist/secure-headers.js.map +1 -0
- package/dist/serve-register.d.ts +4 -0
- package/dist/serve-register.d.ts.map +1 -1
- package/dist/serve-register.js +9 -0
- package/dist/serve-register.js.map +1 -0
- package/dist/serve-slot.d.ts +3 -0
- package/dist/serve-slot.d.ts.map +1 -1
- package/dist/serve-slot.js +52 -0
- package/dist/serve-slot.js.map +1 -0
- package/dist/serve.d.ts +18 -1
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +157 -0
- package/dist/serve.js.map +1 -0
- package/dist/server-timing.d.ts.map +1 -1
- package/dist/server-timing.js +51 -0
- package/dist/server-timing.js.map +1 -0
- package/dist/static.d.ts +9 -0
- package/dist/static.d.ts.map +1 -1
- package/dist/static.js +102 -0
- package/dist/static.js.map +1 -0
- package/dist/telemetry/otel.d.ts +2 -0
- package/dist/telemetry/otel.d.ts.map +1 -1
- package/dist/telemetry/otel.js +135 -0
- package/dist/telemetry/otel.js.map +1 -0
- package/dist/testing.d.ts +12 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +124 -0
- package/dist/testing.js.map +1 -0
- package/dist/timeout.d.ts +6 -0
- package/dist/timeout.d.ts.map +1 -1
- package/dist/timeout.js +36 -0
- package/dist/timeout.js.map +1 -0
- package/dist/tree.d.ts +133 -36
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +437 -0
- package/dist/tree.js.map +1 -0
- package/dist/trust.d.ts +21 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +100 -0
- package/dist/trust.js.map +1 -0
- package/dist/ts-type-emitter.d.ts.map +1 -1
- package/dist/ts-type-emitter.js +150 -0
- package/dist/ts-type-emitter.js.map +1 -0
- package/dist/type-emitter.d.ts +16 -2
- package/dist/type-emitter.d.ts.map +1 -1
- package/dist/type-emitter.js +729 -0
- package/dist/type-emitter.js.map +1 -0
- package/dist/type-extractor.d.ts +8 -4
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +819 -0
- package/dist/type-extractor.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +96 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +14 -2
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +335 -0
- package/dist/validation.js.map +1 -0
- package/dist/with-headers.d.ts +15 -0
- package/dist/with-headers.d.ts.map +1 -0
- package/dist/with-headers.js +45 -0
- package/dist/with-headers.js.map +1 -0
- package/dist/ws/bun.d.ts +11 -5
- package/dist/ws/bun.d.ts.map +1 -1
- package/dist/ws/bun.js +82 -0
- package/dist/ws/bun.js.map +1 -0
- package/dist/ws/cloudflare.d.ts +25 -3
- package/dist/ws/cloudflare.d.ts.map +1 -1
- package/dist/ws/cloudflare.js +117 -0
- package/dist/ws/cloudflare.js.map +1 -0
- package/dist/ws/deno.d.ts +4 -4
- package/dist/ws/deno.d.ts.map +1 -1
- package/dist/ws/deno.js +133 -0
- package/dist/ws/deno.js.map +1 -0
- package/dist/ws/node.d.ts +20 -3
- package/dist/ws/node.d.ts.map +1 -1
- package/dist/ws/node.js +173 -0
- package/dist/ws/node.js.map +1 -0
- package/dist/ws/session.d.ts +11 -0
- package/dist/ws/session.d.ts.map +1 -0
- package/dist/ws/session.js +60 -0
- package/dist/ws/session.js.map +1 -0
- package/dist/ws/shared.d.ts +65 -0
- package/dist/ws/shared.d.ts.map +1 -0
- package/dist/ws/shared.js +103 -0
- package/dist/ws/shared.js.map +1 -0
- package/dist/ws-origin.d.ts +20 -0
- package/dist/ws-origin.d.ts.map +1 -0
- package/dist/ws-origin.js +41 -0
- package/dist/ws-origin.js.map +1 -0
- package/dist/yaml.d.ts +15 -1
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +101 -0
- package/dist/yaml.js.map +1 -0
- package/docs/invalidate-spec.md +13 -1
- package/docs/meta-spec.md +36 -12
- package/docs/packaging.md +43 -24
- package/docs/regression-matrix/README.md +32 -0
- package/docs/regression-matrix/review.md +44 -0
- package/docs/regression-matrix/ws1-3.md +97 -0
- package/docs/regression-matrix/ws4-8.md +107 -0
- package/docs/regression-matrix/ws9-12.md +266 -0
- package/docs/sdk.md +102 -52
- package/package.json +183 -52
- package/src/accepts.ts +91 -33
- package/src/body-kind.ts +67 -0
- package/src/body-limit.ts +102 -87
- package/src/build/index.ts +104 -54
- package/src/cli-args.ts +123 -0
- package/src/cli-go/auth.go +12 -1
- package/src/cli-go/config.go +29 -2
- package/src/cli-go/errors.go +28 -10
- package/src/cli-go/multipart.go +51 -27
- package/src/cli-go/output.go +58 -4
- package/src/cli-go/root.go +1 -1
- package/src/cli-go/version.go +2 -2
- package/src/cli.ts +154 -148
- package/src/client/error.ts +56 -1
- package/src/client/http.ts +479 -256
- package/src/client/index.ts +55 -17
- package/src/client/path.ts +169 -0
- package/src/client/redirect-policy.ts +19 -0
- package/src/client/sdk.ts +180 -101
- package/src/client/sse.ts +92 -66
- package/src/client/ws.ts +67 -31
- package/src/client-go/errors.go +41 -12
- package/src/client-go/export.go +44 -0
- package/src/client-go/invalidation.go +52 -54
- package/src/client-go/nullable.go +62 -0
- package/src/client-go/realtime.go +147 -110
- package/src/client-go/runtime.go +646 -88
- package/src/client-go/sse.go +104 -94
- package/src/client-go/transport.go +67 -27
- package/src/client-go/ws.go +49 -25
- package/src/client-info.ts +79 -0
- package/src/client-mcp/server.ts +133 -3
- package/src/client-python/_invalidation.py +207 -291
- package/src/client-python/_realtime.py +63 -40
- package/src/client-python/_runtime.py +501 -119
- package/src/client-python/_sse.py +130 -74
- package/src/client-python/_transport.py +37 -9
- package/src/client-python/_ws.py +50 -22
- package/src/client-rust/errors.rs +21 -1
- package/src/client-rust/invalidation.rs +202 -231
- package/src/client-rust/invalidation_sync.rs +16 -229
- package/src/client-rust/nullable.rs +17 -0
- package/src/client-rust/realtime.rs +217 -217
- package/src/client-rust/runtime.rs +602 -177
- package/src/client-rust/runtime_sync.rs +169 -145
- package/src/client-rust/sse.rs +142 -121
- package/src/client-rust/ws.rs +61 -37
- package/src/codegen-go-cli.ts +607 -728
- package/src/codegen-go.ts +710 -770
- package/src/codegen-ir.ts +381 -75
- package/src/codegen-lang.ts +517 -0
- package/src/codegen-load.ts +150 -0
- package/src/codegen-mcp.ts +207 -108
- package/src/codegen-python.ts +684 -816
- package/src/codegen-route-tree-intern.ts +51 -25
- package/src/codegen-rust.ts +946 -1240
- package/src/codegen-sanitize.ts +0 -4
- package/src/codegen-schema-naming.ts +19 -6
- package/src/codegen-sdk-model.ts +228 -0
- package/src/codegen.ts +1488 -1140
- package/src/context.ts +130 -11
- package/src/cookie-sign.ts +85 -16
- package/src/cookie.ts +66 -11
- package/src/cors.ts +55 -54
- package/src/crypto.ts +27 -5
- package/src/csrf.ts +57 -25
- package/src/curl-logger.ts +155 -114
- package/src/dict.ts +12 -0
- package/src/error.ts +4 -2
- package/src/etag.ts +58 -34
- package/src/feature-detect.ts +147 -0
- package/src/feature-slots.ts +70 -0
- package/src/fetch-request.ts +13 -0
- package/src/gen-process.ts +42 -0
- package/src/gen-write.ts +127 -0
- package/src/glob.ts +109 -0
- package/src/go-type-emitter.ts +406 -155
- package/src/honey-response.ts +36 -9
- package/src/i18n-slot.ts +10 -0
- package/src/i18n.ts +98 -23
- package/src/index.ts +1887 -1756
- package/src/init.ts +40 -28
- package/src/invalidate-check.ts +42 -4
- package/src/invoke-user.ts +95 -0
- package/src/ip-restrict.ts +47 -161
- package/src/ip.ts +194 -0
- package/src/logger.ts +65 -36
- package/src/media-type.ts +104 -0
- package/src/meta-spec-merge.ts +80 -0
- package/src/meta-spec.ts +0 -0
- package/src/middleware.ts +112 -12
- package/src/node-request.ts +242 -52
- package/src/node.ts +318 -75
- package/src/openapi/collect.ts +19 -44
- package/src/openapi/docs-page.ts +89 -0
- package/src/openapi/document.ts +503 -224
- package/src/openapi/json-schema-slot.ts +40 -0
- package/src/openapi/register.ts +7 -2
- package/src/openapi/scalar.ts +11 -10
- package/src/openapi/serve.ts +39 -0
- package/src/openapi/spec-factory.ts +50 -1
- package/src/openapi/spec.ts +53 -30
- package/src/openapi/swagger.ts +12 -11
- package/src/pattern.ts +245 -0
- package/src/peer.ts +53 -0
- package/src/plugin.ts +270 -185
- package/src/powered-by.ts +2 -2
- package/src/pretty-json.ts +25 -9
- package/src/producer-stream.ts +296 -0
- package/src/proxy.ts +253 -55
- package/src/python-type-emitter.ts +68 -56
- package/src/realtime/bus.ts +56 -9
- package/src/realtime/register.ts +13 -0
- package/src/realtime/route.ts +129 -80
- package/src/realtime/server.ts +298 -0
- package/src/request-id.ts +13 -3
- package/src/request-limits.ts +2 -0
- package/src/request-path.ts +165 -0
- package/src/request-to-curl.ts +28 -7
- package/src/response.ts +143 -103
- package/src/rust-type-emitter.ts +265 -170
- package/src/secure-headers.ts +8 -4
- package/src/serve-register.ts +4 -0
- package/src/serve-slot.ts +38 -0
- package/src/serve.ts +113 -25
- package/src/server-timing.ts +11 -7
- package/src/static.ts +85 -32
- package/src/telemetry/otel.ts +29 -7
- package/src/testing.ts +76 -14
- package/src/timeout.ts +15 -7
- package/src/tree.ts +405 -333
- package/src/trust.ts +117 -0
- package/src/ts-type-emitter.ts +18 -12
- package/src/type-emitter.ts +227 -89
- package/src/type-extractor.ts +603 -423
- package/src/types.ts +8 -0
- package/src/validation.ts +221 -96
- package/src/with-headers.ts +45 -0
- package/src/ws/bun.ts +53 -15
- package/src/ws/cloudflare.ts +81 -19
- package/src/ws/deno.ts +124 -36
- package/src/ws/node.ts +173 -79
- package/src/ws/session.ts +73 -0
- package/src/ws/shared.ts +140 -0
- package/src/ws-origin.ts +53 -0
- package/src/yaml.ts +45 -22
- package/dist/client-mcp/server.d.ts +0 -10
- package/dist/client-mcp/server.d.ts.map +0 -1
- package/dist/client-mcp/types.d.ts +0 -16
- package/dist/client-mcp/types.d.ts.map +0 -1
- package/dist/cloudflare/realtime.d.ts +0 -30
- package/dist/cloudflare/realtime.d.ts.map +0 -1
- package/dist/realtime/buffer.d.ts +0 -18
- package/dist/realtime/buffer.d.ts.map +0 -1
- package/dist/realtime/longpoll.d.ts +0 -23
- package/dist/realtime/longpoll.d.ts.map +0 -1
- package/dist/realtime/protocol.d.ts +0 -50
- package/dist/realtime/protocol.d.ts.map +0 -1
- package/dist/realtime/runtime.d.ts +0 -74
- package/dist/realtime/runtime.d.ts.map +0 -1
- package/src/cloudflare/realtime.ts +0 -234
- package/src/realtime/buffer.ts +0 -101
- package/src/realtime/longpoll.ts +0 -148
- package/src/realtime/protocol.ts +0 -128
- package/src/realtime/runtime.ts +0 -427
package/src/codegen-mcp.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
/* MCP server code generator.
|
|
2
|
-
*
|
|
3
|
-
*
|
|
1
|
+
/* MCP server code generator.
|
|
2
|
+
*
|
|
3
|
+
* Which operations become tools, their ids, their place in the TypeScript SDK and their parameter
|
|
4
|
+
* set come from the IR the TypeScript SDK is built from, so a tool always calls a method that
|
|
5
|
+
* exists. Only the JSON Schema of each parameter and JSON body is copied from the document,
|
|
6
|
+
* verbatim and with refs inlined: a tool's input contract is JSON Schema, and the IR keeps less
|
|
7
|
+
* than JSON Schema says (lengths, patterns, formats), which tool validation needs. */
|
|
4
8
|
|
|
5
9
|
import { readFileSync } from "node:fs"
|
|
6
10
|
import type { OpenApiSpecInput } from "./codegen.ts"
|
|
7
|
-
import {
|
|
11
|
+
import { sdkMemberPaths } from "./codegen.ts"
|
|
12
|
+
import { bodiesOf, toIR } from "./codegen-ir.ts"
|
|
13
|
+
import { isJsonMedia } from "./codegen-sdk-model.ts"
|
|
8
14
|
|
|
9
15
|
type MCPOptions = {
|
|
10
16
|
projectName: string
|
|
@@ -32,8 +38,6 @@ type MCPOp = {
|
|
|
32
38
|
|
|
33
39
|
type SpecRecord = Record<string, unknown>
|
|
34
40
|
|
|
35
|
-
const HTTP_METHODS = ["get", "post", "put", "patch", "delete", "head", "options"] as const
|
|
36
|
-
|
|
37
41
|
const TEMPLATE_FILE_NAMES = ["server.ts", "types.ts"] as const
|
|
38
42
|
const TEMPLATE_CACHE = new Map<string, string>()
|
|
39
43
|
|
|
@@ -51,16 +55,6 @@ function envVarNames(projectName: string): { apiKey: string; baseUrl: string } {
|
|
|
51
55
|
return { apiKey: `${upper}_API_KEY`, baseUrl: `${upper}_BASE_URL` }
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
function hasSSEResponse(op: SpecRecord): boolean {
|
|
55
|
-
const responses = op.responses as Record<string, SpecRecord> | undefined
|
|
56
|
-
if (!responses) return false
|
|
57
|
-
for (const resp of Object.values(responses)) {
|
|
58
|
-
const content = resp.content as SpecRecord | undefined
|
|
59
|
-
if (content && "text/event-stream" in content) return true
|
|
60
|
-
}
|
|
61
|
-
return false
|
|
62
|
-
}
|
|
63
|
-
|
|
64
58
|
function toSnakeCase(id: string): string {
|
|
65
59
|
/* camelCase + dots -> snake_case. "createUser" -> "create_user",
|
|
66
60
|
* "docs.extract" -> "docs_extract", "docs.listAll" -> "docs_list_all". */
|
|
@@ -71,88 +65,176 @@ function toSnakeCase(id: string): string {
|
|
|
71
65
|
.toLowerCase()
|
|
72
66
|
}
|
|
73
67
|
|
|
68
|
+
/** Follow a `$ref` chain to a concrete schema. A chain that loops back on itself is an error. */
|
|
69
|
+
/** MCP tool names: `^[a-zA-Z0-9_-]{1,64}$`. */
|
|
70
|
+
const MAX_TOOL_NAME = 64
|
|
71
|
+
|
|
72
|
+
function sanitizeToolName(name: string): string {
|
|
73
|
+
return (
|
|
74
|
+
name
|
|
75
|
+
.replace(/[^A-Za-z0-9_-]+/g, "_")
|
|
76
|
+
.replace(/_+/g, "_")
|
|
77
|
+
.replace(/^_|_$/g, "") || "tool"
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Deterministic, sanitized, unique tool names; a collision is an error naming both operations. */
|
|
82
|
+
function assignToolNames(ops: MCPOp[], projectName: string): void {
|
|
83
|
+
const byName = new Map<string, string>()
|
|
84
|
+
for (const op of ops) {
|
|
85
|
+
let name = sanitizeToolName(`${projectName}_${toSnakeCase(op.operationId)}`)
|
|
86
|
+
if (name.length > MAX_TOOL_NAME) {
|
|
87
|
+
let hash = 0
|
|
88
|
+
for (let i = 0; i < op.operationId.length; i++) hash = (Math.imul(hash, 31) + op.operationId.charCodeAt(i)) >>> 0
|
|
89
|
+
const suffix = `_${hash.toString(36)}`
|
|
90
|
+
name = `${name.slice(0, MAX_TOOL_NAME - suffix.length)}${suffix}`
|
|
91
|
+
}
|
|
92
|
+
const other = byName.get(name)
|
|
93
|
+
if (other !== undefined) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
`MCP codegen: operations ${JSON.stringify(other)} and ${JSON.stringify(op.operationId)} both map to tool ${JSON.stringify(name)}`,
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
byName.set(name, op.operationId)
|
|
99
|
+
op.toolName = name
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
74
103
|
function resolveSchema(spec: SpecRecord, schema: SpecRecord | undefined): SpecRecord | undefined {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
104
|
+
let cur: SpecRecord | undefined = schema
|
|
105
|
+
const chain = new Set<string>()
|
|
106
|
+
while (cur && typeof cur.$ref === "string") {
|
|
107
|
+
const ref = cur.$ref
|
|
108
|
+
if (chain.has(ref))
|
|
109
|
+
throw new Error(`MCP codegen: $ref cycle with no schema in between: ${[...chain, ref].join(" -> ")}`)
|
|
110
|
+
chain.add(ref)
|
|
111
|
+
if (!ref.startsWith("#/")) return undefined
|
|
112
|
+
let next: unknown = spec
|
|
113
|
+
for (const raw of ref.slice(2).split("/")) {
|
|
114
|
+
const part = raw.replace(/~1/g, "/").replace(/~0/g, "~")
|
|
115
|
+
if (next === null || typeof next !== "object" || !Object.hasOwn(next, part)) return undefined
|
|
116
|
+
next = (next as SpecRecord)[part]
|
|
117
|
+
}
|
|
118
|
+
cur = next as SpecRecord | undefined
|
|
119
|
+
}
|
|
120
|
+
return cur
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Inlining expands each $ref; a schema graph with many shared refs can grow exponentially,
|
|
124
|
+
so the output size is bounded and the generator fails loudly instead of hanging. */
|
|
125
|
+
const MAX_INLINED_NODES = 50_000
|
|
126
|
+
|
|
127
|
+
type InlineState = {
|
|
128
|
+
/** Fully expanded refs whose expansion did not cut a cycle, with their size in nodes. */
|
|
129
|
+
memo: Map<string, { nodes: number; schema: SpecRecord | undefined }>
|
|
130
|
+
nodes: number
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function charge(state: InlineState, nodes: number): void {
|
|
134
|
+
state.nodes += nodes
|
|
135
|
+
if (state.nodes > MAX_INLINED_NODES) {
|
|
136
|
+
throw new Error(`MCP codegen: inlined tool schema exceeds ${MAX_INLINED_NODES} nodes (deeply shared $refs)`)
|
|
83
137
|
}
|
|
84
|
-
if (cur === undefined) return undefined
|
|
85
|
-
/* recurse — resolved schema may itself be a ref */
|
|
86
|
-
return resolveSchema(spec, cur as SpecRecord)
|
|
87
138
|
}
|
|
88
139
|
|
|
89
140
|
function deepResolveSchema(
|
|
90
141
|
spec: SpecRecord,
|
|
91
142
|
schema: SpecRecord | undefined,
|
|
92
143
|
seen: Set<string> = new Set(),
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (schema
|
|
96
|
-
|
|
97
|
-
|
|
144
|
+
state: InlineState = { memo: new Map(), nodes: 0 },
|
|
145
|
+
): { cut: boolean; schema: SpecRecord | undefined } {
|
|
146
|
+
if (!schema) return { cut: false, schema: undefined }
|
|
147
|
+
if (typeof schema.$ref === "string") {
|
|
148
|
+
const ref = schema.$ref
|
|
149
|
+
/* a self-referential schema becomes an open object at the point it recurs */
|
|
150
|
+
if (seen.has(ref)) {
|
|
151
|
+
charge(state, 1)
|
|
152
|
+
return { cut: true, schema: { type: "object" } }
|
|
153
|
+
}
|
|
154
|
+
/* a memoized expansion is emitted again in full, so it costs its full size again */
|
|
155
|
+
const memo = state.memo.get(ref)
|
|
156
|
+
if (memo) {
|
|
157
|
+
charge(state, memo.nodes)
|
|
158
|
+
return { cut: false, schema: memo.schema }
|
|
159
|
+
}
|
|
98
160
|
const next = new Set(seen)
|
|
99
161
|
next.add(ref)
|
|
100
|
-
|
|
162
|
+
const before = state.nodes
|
|
163
|
+
const result = deepResolveSchema(spec, resolveSchema(spec, schema), next, state)
|
|
164
|
+
if (!result.cut) state.memo.set(ref, { nodes: state.nodes - before, schema: result.schema })
|
|
165
|
+
return result
|
|
101
166
|
}
|
|
167
|
+
charge(state, 1)
|
|
168
|
+
let cut = false
|
|
102
169
|
const out: SpecRecord = {}
|
|
103
170
|
for (const [k, v] of Object.entries(schema)) {
|
|
104
171
|
if (v === null || v === undefined) {
|
|
105
172
|
out[k] = v
|
|
106
173
|
} else if (Array.isArray(v)) {
|
|
107
|
-
out[k] = v.map((item) =>
|
|
108
|
-
item
|
|
109
|
-
|
|
174
|
+
out[k] = v.map((item) => {
|
|
175
|
+
if (item === null || typeof item !== "object") return item
|
|
176
|
+
const r = deepResolveSchema(spec, item as SpecRecord, seen, state)
|
|
177
|
+
cut ||= r.cut
|
|
178
|
+
return r.schema
|
|
179
|
+
})
|
|
110
180
|
} else if (typeof v === "object") {
|
|
111
|
-
|
|
181
|
+
const r = deepResolveSchema(spec, v as SpecRecord, seen, state)
|
|
182
|
+
cut ||= r.cut
|
|
183
|
+
out[k] = r.schema
|
|
112
184
|
} else {
|
|
113
185
|
out[k] = v
|
|
114
186
|
}
|
|
115
187
|
}
|
|
116
|
-
return out
|
|
188
|
+
return { cut, schema: out }
|
|
117
189
|
}
|
|
118
190
|
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
191
|
+
function inline(spec: SpecRecord, schema: SpecRecord | undefined): SpecRecord | undefined {
|
|
192
|
+
return deepResolveSchema(spec, schema).schema
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Declared parameters of an operation: its own, then the path item's it does not override. */
|
|
196
|
+
function declaredParameters(op: SpecRecord, pathItem: SpecRecord, spec: SpecRecord): SpecRecord[] {
|
|
197
|
+
const own = ((op.parameters as unknown[] | undefined) ?? []).map((p) => resolveSchema(spec, p as SpecRecord) ?? {})
|
|
198
|
+
const shared = ((pathItem.parameters as unknown[] | undefined) ?? []).map(
|
|
199
|
+
(p) => resolveSchema(spec, p as SpecRecord) ?? {},
|
|
200
|
+
)
|
|
201
|
+
const out = [...own]
|
|
202
|
+
for (const p of shared) if (!out.some((d) => d.name === p.name && d.in === p.in)) out.push(p)
|
|
203
|
+
return out
|
|
123
204
|
}
|
|
124
205
|
|
|
125
206
|
function collectMCPOps(spec: OpenApiSpecInput): MCPOp[] {
|
|
126
|
-
|
|
127
|
-
|
|
207
|
+
/* the ids, tree and member names the TypeScript SDK derives; its schemas are not needed here */
|
|
208
|
+
const ir = toIR(spec, { deriveOperationIds: true, duplicateOperationIds: "throw" })
|
|
209
|
+
const members = sdkMemberPaths(ir)
|
|
210
|
+
const specRec = spec as unknown as SpecRecord
|
|
128
211
|
const ops: MCPOp[] = []
|
|
129
212
|
|
|
130
|
-
for (const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
213
|
+
for (const irOp of ir.operations) {
|
|
214
|
+
const ext = irOp.extensions
|
|
215
|
+
if (ext.mcp !== true) continue
|
|
216
|
+
/* skip websocket / realtime / SSE operations — MCP is request/response only */
|
|
217
|
+
if (ext.websocket || ext.realtime || ext.sse) continue
|
|
218
|
+
|
|
219
|
+
const pathItem = (spec.paths?.[irOp.path] ?? {}) as SpecRecord
|
|
220
|
+
const op = (pathItem[irOp.method.toLowerCase()] ?? {}) as SpecRecord
|
|
221
|
+
const requestBody = resolveSchema(specRec, op.requestBody as SpecRecord | undefined)
|
|
222
|
+
const content = requestBody?.content as Record<string, SpecRecord> | undefined
|
|
223
|
+
/* the JSON body the SDK's `json` input sends: the first JSON media type, as the SDK picks it */
|
|
224
|
+
const jsonBody = bodiesOf(irOp).find((b) => b.kind === "raw" && isJsonMedia(b.contentType))
|
|
225
|
+
|
|
226
|
+
ops.push({
|
|
227
|
+
bodyRequired: jsonBody?.required === true,
|
|
228
|
+
bodySchema: jsonBody ? (content?.[jsonBody.contentType]?.schema as SpecRecord | undefined) : undefined,
|
|
229
|
+
description: irOp.description,
|
|
230
|
+
method: irOp.method,
|
|
231
|
+
operationId: irOp.id,
|
|
232
|
+
parameters: declaredParameters(op, pathItem, specRec),
|
|
233
|
+
path: irOp.path,
|
|
234
|
+
pathSegments: members.get(irOp.id) ?? irOp.id.split("."),
|
|
235
|
+
summary: irOp.summary,
|
|
236
|
+
toolName: "",
|
|
237
|
+
})
|
|
156
238
|
}
|
|
157
239
|
|
|
158
240
|
return ops
|
|
@@ -160,6 +242,8 @@ function collectMCPOps(spec: OpenApiSpecInput): MCPOp[] {
|
|
|
160
242
|
|
|
161
243
|
type ParamGroup = { props: SpecRecord; required: string[] }
|
|
162
244
|
|
|
245
|
+
const FORBIDDEN_HEADER_ARGS = new Set(["authorization", "cookie", "proxy-authorization"])
|
|
246
|
+
|
|
163
247
|
function emptyParamGroup(): ParamGroup {
|
|
164
248
|
return { props: {}, required: [] }
|
|
165
249
|
}
|
|
@@ -184,12 +268,15 @@ function buildToolInputSchema(op: MCPOp, spec: OpenApiSpecInput): SpecRecord {
|
|
|
184
268
|
const header = emptyParamGroup()
|
|
185
269
|
const groupByLoc: Record<string, ParamGroup> = { header, path, query }
|
|
186
270
|
|
|
187
|
-
for (const
|
|
271
|
+
for (const raw of op.parameters) {
|
|
272
|
+
const p = resolveSchema(specRec, raw) ?? {}
|
|
188
273
|
const name = p.name as string
|
|
189
274
|
const inLoc = p.in as string
|
|
190
|
-
const group = groupByLoc[inLoc]
|
|
191
|
-
if (!group) continue
|
|
192
|
-
|
|
275
|
+
const group = Object.hasOwn(groupByLoc, inLoc) ? groupByLoc[inLoc] : undefined
|
|
276
|
+
if (!group || typeof name !== "string") continue
|
|
277
|
+
/* credentials come from the server's config, never from tool arguments */
|
|
278
|
+
if (inLoc === "header" && FORBIDDEN_HEADER_ARGS.has(name.toLowerCase())) continue
|
|
279
|
+
group.props[name] = inline(specRec, (p.schema ?? {}) as SpecRecord) ?? {}
|
|
193
280
|
if (p.required === true) group.required.push(name)
|
|
194
281
|
}
|
|
195
282
|
|
|
@@ -198,7 +285,7 @@ function buildToolInputSchema(op: MCPOp, spec: OpenApiSpecInput): SpecRecord {
|
|
|
198
285
|
assignGroup(properties, required, "headers", header)
|
|
199
286
|
|
|
200
287
|
if (op.bodySchema) {
|
|
201
|
-
properties.json =
|
|
288
|
+
properties.json = inline(specRec, op.bodySchema) ?? { type: "object" }
|
|
202
289
|
if (op.bodyRequired) required.push("json")
|
|
203
290
|
}
|
|
204
291
|
|
|
@@ -207,51 +294,60 @@ function buildToolInputSchema(op: MCPOp, spec: OpenApiSpecInput): SpecRecord {
|
|
|
207
294
|
return schema
|
|
208
295
|
}
|
|
209
296
|
|
|
297
|
+
/** Keys a tool may forward to the SDK, per argument group; everything else is dropped. */
|
|
298
|
+
function allowedArgs(inputSchema: SpecRecord): Record<string, string[] | true> {
|
|
299
|
+
const out: Record<string, string[] | true> = {}
|
|
300
|
+
const props = inputSchema.properties as Record<string, SpecRecord>
|
|
301
|
+
for (const group of ["params", "search", "headers"]) {
|
|
302
|
+
const g = props[group]
|
|
303
|
+
if (g) out[group] = Object.keys((g.properties as SpecRecord | undefined) ?? {}).sort()
|
|
304
|
+
}
|
|
305
|
+
if (props.json) out.json = true
|
|
306
|
+
return out
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/** Text safe inside a block comment. */
|
|
310
|
+
function commentText(text: string): string {
|
|
311
|
+
return text.replace(/\*\//g, "*\\/").replace(/[\r\n]+/g, " ")
|
|
312
|
+
}
|
|
313
|
+
|
|
210
314
|
function buildToolsGen(ops: MCPOp[], spec: OpenApiSpecInput, projectName: string): string {
|
|
211
315
|
const l: string[] = []
|
|
212
316
|
l.push(`/* Generated by honey codegen-mcp.ts — do not edit by hand. */`)
|
|
213
317
|
l.push(``)
|
|
318
|
+
l.push(`import { callTool, type AllowedArgs } from "./_runtime"`)
|
|
214
319
|
l.push(`import type { Tool } from "./types"`)
|
|
215
320
|
l.push(``)
|
|
216
321
|
l.push(`export function buildTools(sdk: Record<string, unknown>): Tool[] {`)
|
|
322
|
+
/* callTool validates the arguments against inputSchema, forwards only declared keys, and
|
|
323
|
+
walks the SDK by operationId segments: ["checkout", "sessions", "create"]. */
|
|
324
|
+
l.push(
|
|
325
|
+
`\tconst tool = (name: string, description: string | undefined, inputSchema: Record<string, unknown>, segments: string[], allowed: AllowedArgs): Tool => ({`,
|
|
326
|
+
)
|
|
327
|
+
l.push(`\t\tdescription,`)
|
|
328
|
+
l.push(`\t\thandler: (args) => callTool(sdk, segments, args, inputSchema, allowed),`)
|
|
329
|
+
l.push(`\t\tinputSchema,`)
|
|
330
|
+
l.push(`\t\tname,`)
|
|
331
|
+
l.push(`\t})`)
|
|
217
332
|
l.push(`\treturn [`)
|
|
218
333
|
|
|
219
334
|
for (const op of ops) {
|
|
220
335
|
const desc = op.description ?? op.summary ?? ""
|
|
221
336
|
const inputSchema = buildToolInputSchema(op, spec)
|
|
222
|
-
l.push(`\t\
|
|
223
|
-
l.push(`\t\t\
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
l.push(`\t\t\
|
|
228
|
-
|
|
229
|
-
* arguments shape already matches TS SDK method signature: { params?, search?, headers?, json? }. */
|
|
230
|
-
const callExpr = op.pathSegments.reduce(
|
|
231
|
-
(acc, seg, i) =>
|
|
232
|
-
i === 0
|
|
233
|
-
? `(sdk as Record<string, unknown>)[${JSON.stringify(seg)}]`
|
|
234
|
-
: `(${acc} as Record<string, unknown>)[${JSON.stringify(seg)}]`,
|
|
235
|
-
"",
|
|
236
|
-
)
|
|
237
|
-
l.push(`\t\t\thandler: async (args) => {`)
|
|
238
|
-
l.push(`\t\t\t\tconst method = ${callExpr}`)
|
|
239
|
-
l.push(`\t\t\t\tif (typeof method !== "function") {`)
|
|
240
|
-
l.push(
|
|
241
|
-
`\t\t\t\t\treturn { content: [{ type: "text", text: JSON.stringify({ message: "SDK missing method ${op.operationId}" }) }], isError: true }`,
|
|
242
|
-
)
|
|
243
|
-
l.push(`\t\t\t\t}`)
|
|
244
|
-
l.push(`\t\t\t\tconst result = await method.call(sdk, args)`)
|
|
245
|
-
l.push(`\t\t\t\treturn { content: [{ type: "text", text: JSON.stringify(result) }] }`)
|
|
246
|
-
l.push(`\t\t\t},`)
|
|
247
|
-
l.push(`\t\t},`)
|
|
337
|
+
l.push(`\t\ttool(`)
|
|
338
|
+
l.push(`\t\t\t${JSON.stringify(op.toolName)},`)
|
|
339
|
+
l.push(`\t\t\t${desc.length > 0 ? JSON.stringify(desc) : "undefined"},`)
|
|
340
|
+
l.push(`\t\t\t${JSON.stringify(inputSchema)},`)
|
|
341
|
+
l.push(`\t\t\t${JSON.stringify(op.pathSegments)},`)
|
|
342
|
+
l.push(`\t\t\t${JSON.stringify(allowedArgs(inputSchema))},`)
|
|
343
|
+
l.push(`\t\t),`)
|
|
248
344
|
}
|
|
249
345
|
|
|
250
346
|
l.push(`\t]`)
|
|
251
347
|
l.push(`}`)
|
|
252
348
|
l.push(``)
|
|
253
349
|
/* project name embedded for tool-naming contract visibility — consumed by tests */
|
|
254
|
-
l.push(`/* project: ${projectName} */`)
|
|
350
|
+
l.push(`/* project: ${commentText(projectName)} */`)
|
|
255
351
|
l.push(``)
|
|
256
352
|
return l.join("\n")
|
|
257
353
|
}
|
|
@@ -264,7 +360,6 @@ function buildServerEntry(
|
|
|
264
360
|
version: string,
|
|
265
361
|
): string {
|
|
266
362
|
const { apiKey: envVar, baseUrl: baseUrlEnvVar } = envVarNames(projectName)
|
|
267
|
-
const defaultBaseUrl = `https://api.${projectName}.com`
|
|
268
363
|
const l: string[] = []
|
|
269
364
|
l.push(`/* Generated by honey codegen-mcp.ts — do not edit by hand. */`)
|
|
270
365
|
l.push(``)
|
|
@@ -273,7 +368,14 @@ function buildServerEntry(
|
|
|
273
368
|
l.push(`import { buildTools } from "./tools.gen"`)
|
|
274
369
|
l.push(``)
|
|
275
370
|
l.push(`const apiKey = process.env[${JSON.stringify(envVar)}] ?? ""`)
|
|
276
|
-
|
|
371
|
+
/* No guessed default: the API key must never be sent to a host nobody configured. */
|
|
372
|
+
l.push(`const baseURL = process.env[${JSON.stringify(baseUrlEnvVar)}] ?? ""`)
|
|
373
|
+
l.push(`if (baseURL.length === 0) {`)
|
|
374
|
+
l.push(
|
|
375
|
+
`\tprocess.stderr.write(${JSON.stringify(`${baseUrlEnvVar} is required (the API base URL, e.g. https://api.example.com)\n`)})`,
|
|
376
|
+
)
|
|
377
|
+
l.push(`\tprocess.exit(1)`)
|
|
378
|
+
l.push(`}`)
|
|
277
379
|
l.push(``)
|
|
278
380
|
l.push(`const sdk = new ${sdkClassName}({`)
|
|
279
381
|
l.push(`\tbaseURL,`)
|
|
@@ -317,7 +419,6 @@ function buildTsconfig(): string {
|
|
|
317
419
|
}
|
|
318
420
|
|
|
319
421
|
export function generateMCPServer(spec: OpenApiSpecInput, options: MCPOptions): MCPResult {
|
|
320
|
-
toIR(spec)
|
|
321
422
|
const { projectName, sdkClassName, sdkPackageName } = options
|
|
322
423
|
const version = options.version ?? "0.1.0"
|
|
323
424
|
|
|
@@ -325,9 +426,7 @@ export function generateMCPServer(spec: OpenApiSpecInput, options: MCPOptions):
|
|
|
325
426
|
if (ops.length === 0) {
|
|
326
427
|
throw new Error("No operations marked x-mcp: true; nothing to emit")
|
|
327
428
|
}
|
|
328
|
-
|
|
329
|
-
op.toolName = `${projectName}_${toSnakeCase(op.operationId)}`
|
|
330
|
-
}
|
|
429
|
+
assignToolNames(ops, projectName)
|
|
331
430
|
|
|
332
431
|
const info = (spec as { info?: { title?: string } }).info ?? {}
|
|
333
432
|
const serverName = info.title ?? `@${projectName}/mcp-server`
|