@lovrozagar/honey-clients 0.0.0 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +75 -0
- package/bin/honey-clients.js +94 -0
- package/dist/cli.d.ts +34 -0
- package/dist/cli.js +204 -0
- package/dist/emit/cli/commands.d.ts +27 -0
- package/dist/emit/cli/commands.js +187 -0
- package/dist/emit/cli/discovery.d.ts +35 -0
- package/dist/emit/cli/discovery.js +202 -0
- package/dist/emit/cli/flags.d.ts +59 -0
- package/dist/emit/cli/flags.js +186 -0
- package/dist/emit/cli/index.d.ts +1 -0
- package/dist/emit/cli/index.js +1 -0
- package/dist/emit/cli/install-ps1.d.ts +8 -0
- package/dist/emit/cli/install-ps1.js +111 -0
- package/dist/emit/cli/install.d.ts +32 -0
- package/dist/emit/cli/install.js +216 -0
- package/dist/emit/cli/layout.d.ts +21 -0
- package/dist/emit/cli/layout.js +118 -0
- package/dist/emit/cli/module.d.ts +19 -0
- package/dist/emit/cli/module.js +167 -0
- package/dist/emit/cli/release.d.ts +25 -0
- package/dist/emit/cli/release.js +114 -0
- package/dist/emit/cli/skills.d.ts +11 -0
- package/dist/emit/cli/skills.js +56 -0
- package/dist/emit/csharp/errors.d.ts +7 -0
- package/dist/emit/csharp/errors.js +69 -0
- package/dist/emit/csharp/index.d.ts +1 -0
- package/dist/emit/csharp/index.js +1 -0
- package/dist/emit/csharp/json.d.ts +13 -0
- package/dist/emit/csharp/json.js +113 -0
- package/dist/emit/csharp/realtime.d.ts +10 -0
- package/dist/emit/csharp/realtime.js +33 -0
- package/dist/emit/csharp/sdk-answer.d.ts +48 -0
- package/dist/emit/csharp/sdk-answer.js +85 -0
- package/dist/emit/csharp/sdk-body.d.ts +10 -0
- package/dist/emit/csharp/sdk-body.js +87 -0
- package/dist/emit/csharp/sdk-client.d.ts +32 -0
- package/dist/emit/csharp/sdk-client.js +177 -0
- package/dist/emit/csharp/sdk-csproj.d.ts +20 -0
- package/dist/emit/csharp/sdk-csproj.js +67 -0
- package/dist/emit/csharp/sdk-doc.d.ts +12 -0
- package/dist/emit/csharp/sdk-doc.js +35 -0
- package/dist/emit/csharp/sdk-method.d.ts +26 -0
- package/dist/emit/csharp/sdk-method.js +187 -0
- package/dist/emit/csharp/sdk-plan.d.ts +38 -0
- package/dist/emit/csharp/sdk-plan.js +1 -0
- package/dist/emit/csharp/sdk.d.ts +23 -0
- package/dist/emit/csharp/sdk.js +97 -0
- package/dist/emit/csharp/sse.d.ts +18 -0
- package/dist/emit/csharp/sse.js +29 -0
- package/dist/emit/csharp/transport.d.ts +11 -0
- package/dist/emit/csharp/transport.js +67 -0
- package/dist/emit/csharp/types-enum.d.ts +19 -0
- package/dist/emit/csharp/types-enum.js +63 -0
- package/dist/emit/csharp/types-names.d.ts +33 -0
- package/dist/emit/csharp/types-names.js +182 -0
- package/dist/emit/csharp/types-record.d.ts +25 -0
- package/dist/emit/csharp/types-record.js +65 -0
- package/dist/emit/csharp/types-union.d.ts +27 -0
- package/dist/emit/csharp/types-union.js +113 -0
- package/dist/emit/csharp/types.d.ts +36 -0
- package/dist/emit/csharp/types.js +126 -0
- package/dist/emit/csharp/ws.d.ts +20 -0
- package/dist/emit/csharp/ws.js +14 -0
- package/dist/emit/go/errors.d.ts +7 -0
- package/dist/emit/go/errors.js +44 -0
- package/dist/emit/go/http.d.ts +11 -0
- package/dist/emit/go/http.js +50 -0
- package/dist/emit/go/index.d.ts +1 -0
- package/dist/emit/go/index.js +1 -0
- package/dist/emit/go/sdk-answer.d.ts +28 -0
- package/dist/emit/go/sdk-answer.js +41 -0
- package/dist/emit/go/sdk-body.d.ts +24 -0
- package/dist/emit/go/sdk-body.js +76 -0
- package/dist/emit/go/sdk-client.d.ts +29 -0
- package/dist/emit/go/sdk-client.js +141 -0
- package/dist/emit/go/sdk-method.d.ts +68 -0
- package/dist/emit/go/sdk-method.js +172 -0
- package/dist/emit/go/sdk-mirror.d.ts +23 -0
- package/dist/emit/go/sdk-mirror.js +97 -0
- package/dist/emit/go/sdk-opts.d.ts +55 -0
- package/dist/emit/go/sdk-opts.js +100 -0
- package/dist/emit/go/sdk.d.ts +21 -0
- package/dist/emit/go/sdk.js +107 -0
- package/dist/emit/go/sse.d.ts +16 -0
- package/dist/emit/go/sse.js +26 -0
- package/dist/emit/go/types-codec.d.ts +15 -0
- package/dist/emit/go/types-codec.js +171 -0
- package/dist/emit/go/types-names.d.ts +14 -0
- package/dist/emit/go/types-names.js +64 -0
- package/dist/emit/go/types-struct.d.ts +29 -0
- package/dist/emit/go/types-struct.js +65 -0
- package/dist/emit/go/types-union.d.ts +17 -0
- package/dist/emit/go/types-union.js +84 -0
- package/dist/emit/go/types.d.ts +32 -0
- package/dist/emit/go/types.js +177 -0
- package/dist/emit/go/ws.d.ts +12 -0
- package/dist/emit/go/ws.js +70 -0
- package/dist/emit/java/gradle.d.ts +35 -0
- package/dist/emit/java/gradle.js +154 -0
- package/dist/emit/java/index.d.ts +2 -0
- package/dist/emit/java/index.js +2 -0
- package/dist/emit/java/json.d.ts +13 -0
- package/dist/emit/java/json.js +84 -0
- package/dist/emit/java/layout-ast.d.ts +146 -0
- package/dist/emit/java/layout-ast.js +102 -0
- package/dist/emit/java/layout-decl.d.ts +20 -0
- package/dist/emit/java/layout-decl.js +155 -0
- package/dist/emit/java/layout-doc.d.ts +55 -0
- package/dist/emit/java/layout-doc.js +166 -0
- package/dist/emit/java/layout-dot.d.ts +18 -0
- package/dist/emit/java/layout-dot.js +127 -0
- package/dist/emit/java/layout-strings.d.ts +8 -0
- package/dist/emit/java/layout-strings.js +76 -0
- package/dist/emit/java/layout-types.d.ts +11 -0
- package/dist/emit/java/layout-types.js +95 -0
- package/dist/emit/java/layout-visitor.d.ts +38 -0
- package/dist/emit/java/layout-visitor.js +232 -0
- package/dist/emit/java/layout.d.ts +61 -0
- package/dist/emit/java/layout.js +121 -0
- package/dist/emit/java/models-enum.d.ts +17 -0
- package/dist/emit/java/models-enum.js +51 -0
- package/dist/emit/java/models-names.d.ts +29 -0
- package/dist/emit/java/models-names.js +97 -0
- package/dist/emit/java/models-record.d.ts +24 -0
- package/dist/emit/java/models-record.js +79 -0
- package/dist/emit/java/models-union.d.ts +27 -0
- package/dist/emit/java/models-union.js +86 -0
- package/dist/emit/java/models.d.ts +28 -0
- package/dist/emit/java/models.js +118 -0
- package/dist/emit/java/realtime.d.ts +50 -0
- package/dist/emit/java/realtime.js +69 -0
- package/dist/emit/java/sdk-client.d.ts +66 -0
- package/dist/emit/java/sdk-client.js +207 -0
- package/dist/emit/java/sdk-decl.d.ts +11 -0
- package/dist/emit/java/sdk-decl.js +63 -0
- package/dist/emit/java/sdk-errors.d.ts +13 -0
- package/dist/emit/java/sdk-errors.js +141 -0
- package/dist/emit/java/sdk-headers.d.ts +12 -0
- package/dist/emit/java/sdk-headers.js +74 -0
- package/dist/emit/java/sdk-mirror.d.ts +14 -0
- package/dist/emit/java/sdk-mirror.js +107 -0
- package/dist/emit/java/sdk-models.d.ts +16 -0
- package/dist/emit/java/sdk-models.js +68 -0
- package/dist/emit/java/sdk-op.d.ts +57 -0
- package/dist/emit/java/sdk-op.js +216 -0
- package/dist/emit/java/sdk-params.d.ts +38 -0
- package/dist/emit/java/sdk-params.js +133 -0
- package/dist/emit/java/sdk-plan.d.ts +52 -0
- package/dist/emit/java/sdk-plan.js +1 -0
- package/dist/emit/java/sdk-record.d.ts +16 -0
- package/dist/emit/java/sdk-record.js +99 -0
- package/dist/emit/java/sdk.d.ts +44 -0
- package/dist/emit/java/sdk.js +213 -0
- package/dist/emit/java/sse.d.ts +35 -0
- package/dist/emit/java/sse.js +57 -0
- package/dist/emit/java/ws.d.ts +27 -0
- package/dist/emit/java/ws.js +31 -0
- package/dist/emit/mcp/annotations.d.ts +15 -0
- package/dist/emit/mcp/annotations.js +15 -0
- package/dist/emit/mcp/files.d.ts +18 -0
- package/dist/emit/mcp/files.js +42 -0
- package/dist/emit/mcp/index.d.ts +3 -0
- package/dist/emit/mcp/index.js +3 -0
- package/dist/emit/mcp/literal.d.ts +2 -0
- package/dist/emit/mcp/literal.js +33 -0
- package/dist/emit/mcp/mounted.d.ts +16 -0
- package/dist/emit/mcp/mounted.js +89 -0
- package/dist/emit/mcp/output-schema.d.ts +18 -0
- package/dist/emit/mcp/output-schema.js +38 -0
- package/dist/emit/mcp/runtime.d.ts +10 -0
- package/dist/emit/mcp/runtime.js +47 -0
- package/dist/emit/mcp/schema.d.ts +19 -0
- package/dist/emit/mcp/schema.js +88 -0
- package/dist/emit/mcp/server.d.ts +20 -0
- package/dist/emit/mcp/server.js +219 -0
- package/dist/emit/mcp/tools.d.ts +51 -0
- package/dist/emit/mcp/tools.js +153 -0
- package/dist/emit/python/errors.d.ts +8 -0
- package/dist/emit/python/errors.js +68 -0
- package/dist/emit/python/index.d.ts +1 -0
- package/dist/emit/python/index.js +1 -0
- package/dist/emit/python/realtime.d.ts +10 -0
- package/dist/emit/python/realtime.js +33 -0
- package/dist/emit/python/sdk-answer.d.ts +49 -0
- package/dist/emit/python/sdk-answer.js +89 -0
- package/dist/emit/python/sdk-body.d.ts +11 -0
- package/dist/emit/python/sdk-body.js +40 -0
- package/dist/emit/python/sdk-client.d.ts +36 -0
- package/dist/emit/python/sdk-client.js +163 -0
- package/dist/emit/python/sdk-doc.d.ts +9 -0
- package/dist/emit/python/sdk-doc.js +32 -0
- package/dist/emit/python/sdk-imports.d.ts +14 -0
- package/dist/emit/python/sdk-imports.js +38 -0
- package/dist/emit/python/sdk-method.d.ts +29 -0
- package/dist/emit/python/sdk-method.js +183 -0
- package/dist/emit/python/sdk-plan.d.ts +33 -0
- package/dist/emit/python/sdk-plan.js +1 -0
- package/dist/emit/python/sdk-pyproject.d.ts +20 -0
- package/dist/emit/python/sdk-pyproject.js +47 -0
- package/dist/emit/python/sdk.d.ts +19 -0
- package/dist/emit/python/sdk.js +153 -0
- package/dist/emit/python/sse.d.ts +12 -0
- package/dist/emit/python/sse.js +23 -0
- package/dist/emit/python/transport.d.ts +15 -0
- package/dist/emit/python/transport.js +60 -0
- package/dist/emit/python/types-dict.d.ts +31 -0
- package/dist/emit/python/types-dict.js +45 -0
- package/dist/emit/python/types-names.d.ts +16 -0
- package/dist/emit/python/types-names.js +52 -0
- package/dist/emit/python/types-union.d.ts +32 -0
- package/dist/emit/python/types-union.js +46 -0
- package/dist/emit/python/types.d.ts +36 -0
- package/dist/emit/python/types.js +128 -0
- package/dist/emit/python/ws.d.ts +14 -0
- package/dist/emit/python/ws.js +16 -0
- package/dist/emit/rust/errors.d.ts +7 -0
- package/dist/emit/rust/errors.js +107 -0
- package/dist/emit/rust/http.d.ts +13 -0
- package/dist/emit/rust/http.js +67 -0
- package/dist/emit/rust/index.d.ts +1 -0
- package/dist/emit/rust/index.js +1 -0
- package/dist/emit/rust/realtime.d.ts +11 -0
- package/dist/emit/rust/realtime.js +29 -0
- package/dist/emit/rust/sdk-body.d.ts +19 -0
- package/dist/emit/rust/sdk-body.js +53 -0
- package/dist/emit/rust/sdk-cargo.d.ts +21 -0
- package/dist/emit/rust/sdk-cargo.js +121 -0
- package/dist/emit/rust/sdk-client.d.ts +25 -0
- package/dist/emit/rust/sdk-client.js +108 -0
- package/dist/emit/rust/sdk-method.d.ts +15 -0
- package/dist/emit/rust/sdk-method.js +119 -0
- package/dist/emit/rust/sdk-opts.d.ts +58 -0
- package/dist/emit/rust/sdk-opts.js +117 -0
- package/dist/emit/rust/sdk-plan.d.ts +33 -0
- package/dist/emit/rust/sdk-plan.js +1 -0
- package/dist/emit/rust/sdk.d.ts +19 -0
- package/dist/emit/rust/sdk.js +113 -0
- package/dist/emit/rust/sse.d.ts +19 -0
- package/dist/emit/rust/sse.js +20 -0
- package/dist/emit/rust/types-enum.d.ts +13 -0
- package/dist/emit/rust/types-enum.js +62 -0
- package/dist/emit/rust/types-names.d.ts +19 -0
- package/dist/emit/rust/types-names.js +66 -0
- package/dist/emit/rust/types-struct.d.ts +21 -0
- package/dist/emit/rust/types-struct.js +59 -0
- package/dist/emit/rust/types-union.d.ts +24 -0
- package/dist/emit/rust/types-union.js +97 -0
- package/dist/emit/rust/types.d.ts +34 -0
- package/dist/emit/rust/types.js +105 -0
- package/dist/emit/rust/ws.d.ts +21 -0
- package/dist/emit/rust/ws.js +20 -0
- package/dist/emit/shared/escape.d.ts +55 -0
- package/dist/emit/shared/escape.js +144 -0
- package/dist/emit/shared/format.d.ts +24 -0
- package/dist/emit/shared/format.js +23 -0
- package/dist/emit/shared/gofmt.d.ts +3 -0
- package/dist/emit/shared/gofmt.js +26 -0
- package/dist/emit/shared/lang.d.ts +60 -0
- package/dist/emit/shared/lang.js +233 -0
- package/dist/emit/shared/literals.d.ts +4 -0
- package/dist/emit/shared/literals.js +31 -0
- package/dist/emit/shared/mirror.d.ts +22 -0
- package/dist/emit/shared/mirror.js +26 -0
- package/dist/emit/shared/ruff.d.ts +3 -0
- package/dist/emit/shared/ruff.js +31 -0
- package/dist/emit/shared/rustfmt.d.ts +3 -0
- package/dist/emit/shared/rustfmt.js +32 -0
- package/dist/emit/shared/status-keys.d.ts +7 -0
- package/dist/emit/shared/status-keys.js +67 -0
- package/dist/emit/shared/type-emitter.d.ts +19 -0
- package/dist/emit/shared/type-emitter.js +100 -0
- package/dist/emit/shared/webhooks.d.ts +20 -0
- package/dist/emit/shared/webhooks.js +171 -0
- package/dist/emit/ts/app-client.d.ts +4 -0
- package/dist/emit/ts/app-client.js +68 -0
- package/dist/emit/ts/http.d.ts +4 -0
- package/dist/emit/ts/http.js +40 -0
- package/dist/emit/ts/route-tree.d.ts +33 -0
- package/dist/emit/ts/route-tree.js +228 -0
- package/dist/emit/ts/sdk-types.d.ts +13 -0
- package/dist/emit/ts/sdk-types.js +282 -0
- package/dist/emit/ts/sdk.d.ts +15 -0
- package/dist/emit/ts/sdk.js +129 -0
- package/dist/emit/ts/service-map.d.ts +40 -0
- package/dist/emit/ts/service-map.js +141 -0
- package/dist/emit/ts/type-gen.d.ts +22 -0
- package/dist/emit/ts/type-gen.js +205 -0
- package/dist/extract/chain.d.ts +30 -0
- package/dist/extract/chain.js +84 -0
- package/dist/extract/extract.d.ts +27 -0
- package/dist/extract/extract.js +178 -0
- package/dist/extract/serialize.d.ts +32 -0
- package/dist/extract/serialize.js +280 -0
- package/dist/extract/walk.d.ts +35 -0
- package/dist/extract/walk.js +92 -0
- package/dist/gen/args.d.ts +40 -0
- package/dist/gen/args.js +129 -0
- package/dist/gen/process.d.ts +13 -0
- package/dist/gen/process.js +35 -0
- package/dist/gen/write.d.ts +17 -0
- package/dist/gen/write.js +101 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/ir/build.d.ts +37 -0
- package/dist/ir/build.js +152 -0
- package/dist/ir/load.d.ts +11 -0
- package/dist/ir/load.js +102 -0
- package/dist/ir/model.d.ts +208 -0
- package/dist/ir/model.js +5 -0
- package/dist/ir/resolve-refs.d.ts +11 -0
- package/dist/ir/resolve-refs.js +66 -0
- package/dist/ir/resource-tree.d.ts +9 -0
- package/dist/ir/resource-tree.js +53 -0
- package/dist/ir/route-tree-intern.d.ts +18 -0
- package/dist/ir/route-tree-intern.js +174 -0
- package/dist/ir/schema.d.ts +11 -0
- package/dist/ir/schema.js +180 -0
- package/dist/ir/sdk-model.d.ts +86 -0
- package/dist/ir/sdk-model.js +204 -0
- package/dist/ir/slots.d.ts +42 -0
- package/dist/ir/slots.js +245 -0
- package/dist/runtime/cli/body.go +176 -0
- package/dist/runtime/cli/config.go +243 -0
- package/dist/runtime/cli/discovery.go +147 -0
- package/dist/runtime/cli/format.go +174 -0
- package/dist/runtime/cli/log.go +117 -0
- package/dist/runtime/cli/output.go +247 -0
- package/dist/runtime/cli/params.go +197 -0
- package/dist/runtime/cli/run.go +226 -0
- package/dist/runtime/cli/socket.go +60 -0
- package/dist/runtime/cli/stream.go +217 -0
- package/dist/runtime/cli/target.go +117 -0
- package/dist/runtime/csharp/Adapters.cs +183 -0
- package/dist/runtime/csharp/Auth.cs +56 -0
- package/dist/runtime/csharp/Body.cs +135 -0
- package/dist/runtime/csharp/Config.cs +161 -0
- package/dist/runtime/csharp/Envelope.cs +149 -0
- package/dist/runtime/csharp/Errors.cs +194 -0
- package/dist/runtime/csharp/Events.cs +155 -0
- package/dist/runtime/csharp/Exchange.cs +247 -0
- package/dist/runtime/csharp/Handler.cs +103 -0
- package/dist/runtime/csharp/Hooks.cs +128 -0
- package/dist/runtime/csharp/Invalidation.cs +102 -0
- package/dist/runtime/csharp/Json.cs +144 -0
- package/dist/runtime/csharp/Log.cs +48 -0
- package/dist/runtime/csharp/Operation.cs +33 -0
- package/dist/runtime/csharp/Path.cs +65 -0
- package/dist/runtime/csharp/Query.cs +72 -0
- package/dist/runtime/csharp/Realtime.cs +118 -0
- package/dist/runtime/csharp/RealtimeLoop.cs +236 -0
- package/dist/runtime/csharp/Redirect.cs +53 -0
- package/dist/runtime/csharp/Result.cs +57 -0
- package/dist/runtime/csharp/Sse.cs +122 -0
- package/dist/runtime/csharp/Stale.cs +151 -0
- package/dist/runtime/csharp/Transport.cs +143 -0
- package/dist/runtime/csharp/TransportLongPoll.cs +63 -0
- package/dist/runtime/csharp/TransportSse.cs +54 -0
- package/dist/runtime/csharp/TransportWs.cs +40 -0
- package/dist/runtime/csharp/Wire.cs +109 -0
- package/dist/runtime/csharp/Ws.cs +300 -0
- package/dist/runtime/csharp/WsDial.cs +127 -0
- package/dist/runtime/go/auth.go +127 -0
- package/dist/runtime/go/body.go +129 -0
- package/dist/runtime/go/config.go +75 -0
- package/dist/runtime/go/errors.go +185 -0
- package/dist/runtime/go/export.go +37 -0
- package/dist/runtime/go/hooks.go +53 -0
- package/dist/runtime/go/invalidation.go +112 -0
- package/dist/runtime/go/log.go +92 -0
- package/dist/runtime/go/nullable.go +64 -0
- package/dist/runtime/go/options.go +118 -0
- package/dist/runtime/go/path.go +156 -0
- package/dist/runtime/go/query.go +147 -0
- package/dist/runtime/go/realtime.go +239 -0
- package/dist/runtime/go/realtime_loop.go +208 -0
- package/dist/runtime/go/redirect.go +124 -0
- package/dist/runtime/go/request.go +222 -0
- package/dist/runtime/go/result.go +86 -0
- package/dist/runtime/go/sse.go +186 -0
- package/dist/runtime/go/stale.go +229 -0
- package/dist/runtime/go/stream.go +105 -0
- package/dist/runtime/go/transport.go +242 -0
- package/dist/runtime/go/transport_longpoll.go +121 -0
- package/dist/runtime/go/transport_sse.go +175 -0
- package/dist/runtime/go/ws.go +205 -0
- package/dist/runtime/java/Answer.java +107 -0
- package/dist/runtime/java/ApiException.java +110 -0
- package/dist/runtime/java/BinaryBody.java +36 -0
- package/dist/runtime/java/Body.java +105 -0
- package/dist/runtime/java/Call.java +23 -0
- package/dist/runtime/java/CallLog.java +51 -0
- package/dist/runtime/java/ClientConfig.java +233 -0
- package/dist/runtime/java/ConnectionState.java +12 -0
- package/dist/runtime/java/Credential.java +58 -0
- package/dist/runtime/java/Deadline.java +38 -0
- package/dist/runtime/java/Decode.java +181 -0
- package/dist/runtime/java/Envelope.java +141 -0
- package/dist/runtime/java/ErrorEnvelope.java +23 -0
- package/dist/runtime/java/EventStream.java +129 -0
- package/dist/runtime/java/Exchange.java +62 -0
- package/dist/runtime/java/FilePart.java +5 -0
- package/dist/runtime/java/Flight.java +306 -0
- package/dist/runtime/java/HoneyException.java +14 -0
- package/dist/runtime/java/Hooks.java +47 -0
- package/dist/runtime/java/Hops.java +133 -0
- package/dist/runtime/java/InvalidationConfig.java +73 -0
- package/dist/runtime/java/Json.java +23 -0
- package/dist/runtime/java/Keepalive.java +60 -0
- package/dist/runtime/java/LogEntry.java +14 -0
- package/dist/runtime/java/LongPollAdapter.java +68 -0
- package/dist/runtime/java/Operation.java +21 -0
- package/dist/runtime/java/Opt.java +121 -0
- package/dist/runtime/java/Pump.java +160 -0
- package/dist/runtime/java/RawResponse.java +48 -0
- package/dist/runtime/java/Realtime.java +152 -0
- package/dist/runtime/java/RealtimeLoop.java +371 -0
- package/dist/runtime/java/RedirectPolicy.java +13 -0
- package/dist/runtime/java/Redirects.java +126 -0
- package/dist/runtime/java/RequestContext.java +78 -0
- package/dist/runtime/java/RequestHook.java +9 -0
- package/dist/runtime/java/RequestOptions.java +91 -0
- package/dist/runtime/java/ResponseContext.java +70 -0
- package/dist/runtime/java/ResponseHook.java +12 -0
- package/dist/runtime/java/Result.java +32 -0
- package/dist/runtime/java/ResumableConnection.java +165 -0
- package/dist/runtime/java/SdkException.java +11 -0
- package/dist/runtime/java/Socket.java +301 -0
- package/dist/runtime/java/Sse.java +171 -0
- package/dist/runtime/java/SseAdapter.java +61 -0
- package/dist/runtime/java/SseEvent.java +10 -0
- package/dist/runtime/java/StaleMeta.java +16 -0
- package/dist/runtime/java/StaleTracker.java +287 -0
- package/dist/runtime/java/Transport.java +16 -0
- package/dist/runtime/java/TransportAdapter.java +14 -0
- package/dist/runtime/java/TransportConnection.java +15 -0
- package/dist/runtime/java/TransportKind.java +12 -0
- package/dist/runtime/java/TransportMessage.java +9 -0
- package/dist/runtime/java/TransportOptions.java +138 -0
- package/dist/runtime/java/TypedWebSocket.java +83 -0
- package/dist/runtime/java/UrlPath.java +49 -0
- package/dist/runtime/java/UrlQuery.java +99 -0
- package/dist/runtime/java/WsAdapter.java +52 -0
- package/dist/runtime/java/WsClose.java +47 -0
- package/dist/runtime/java/WsDial.java +148 -0
- package/dist/runtime/java/WsMessage.java +18 -0
- package/dist/runtime/mcp/call.ts +167 -0
- package/dist/runtime/mcp/files.ts +183 -0
- package/dist/runtime/mcp/guard.ts +176 -0
- package/dist/runtime/mcp/http.ts +159 -0
- package/dist/runtime/mcp/jsonrpc.ts +50 -0
- package/dist/runtime/mcp/listen.ts +76 -0
- package/dist/runtime/mcp/mount.ts +123 -0
- package/dist/runtime/mcp/protocol.ts +219 -0
- package/dist/runtime/mcp/reader.ts +57 -0
- package/dist/runtime/mcp/result.ts +85 -0
- package/dist/runtime/mcp/stdio.ts +79 -0
- package/dist/runtime/mcp/stream.ts +62 -0
- package/dist/runtime/python/__init__.py +2 -0
- package/dist/runtime/python/auth.py +67 -0
- package/dist/runtime/python/body.py +83 -0
- package/dist/runtime/python/config.py +139 -0
- package/dist/runtime/python/errors.py +213 -0
- package/dist/runtime/python/events.py +152 -0
- package/dist/runtime/python/exchange.py +298 -0
- package/dist/runtime/python/hooks.py +86 -0
- package/dist/runtime/python/invalidation.py +57 -0
- package/dist/runtime/python/log.py +60 -0
- package/dist/runtime/python/operation.py +25 -0
- package/dist/runtime/python/path.py +41 -0
- package/dist/runtime/python/query.py +48 -0
- package/dist/runtime/python/realtime.py +244 -0
- package/dist/runtime/python/redirect.py +93 -0
- package/dist/runtime/python/result.py +58 -0
- package/dist/runtime/python/send_async.py +189 -0
- package/dist/runtime/python/send_sync.py +105 -0
- package/dist/runtime/python/sse.py +81 -0
- package/dist/runtime/python/stale.py +94 -0
- package/dist/runtime/python/transport.py +157 -0
- package/dist/runtime/python/transport_longpoll.py +60 -0
- package/dist/runtime/python/transport_sse.py +60 -0
- package/dist/runtime/python/transport_ws.py +57 -0
- package/dist/runtime/python/ws.py +276 -0
- package/dist/runtime/rust/Cargo.lock +1763 -0
- package/dist/runtime/rust/answer.rs +120 -0
- package/dist/runtime/rust/auth.rs +80 -0
- package/dist/runtime/rust/body.rs +150 -0
- package/dist/runtime/rust/call.rs +200 -0
- package/dist/runtime/rust/config.rs +254 -0
- package/dist/runtime/rust/envelope.rs +84 -0
- package/dist/runtime/rust/errors.rs +235 -0
- package/dist/runtime/rust/events.rs +177 -0
- package/dist/runtime/rust/exchange.rs +287 -0
- package/dist/runtime/rust/hooks.rs +63 -0
- package/dist/runtime/rust/invalidation.rs +84 -0
- package/dist/runtime/rust/log.rs +88 -0
- package/dist/runtime/rust/nullable.rs +13 -0
- package/dist/runtime/rust/path.rs +83 -0
- package/dist/runtime/rust/query.rs +84 -0
- package/dist/runtime/rust/realtime.rs +182 -0
- package/dist/runtime/rust/realtime_loop.rs +177 -0
- package/dist/runtime/rust/redirect.rs +121 -0
- package/dist/runtime/rust/request.rs +178 -0
- package/dist/runtime/rust/result.rs +101 -0
- package/dist/runtime/rust/sse.rs +104 -0
- package/dist/runtime/rust/stale.rs +209 -0
- package/dist/runtime/rust/transport.rs +221 -0
- package/dist/runtime/rust/transport_longpoll.rs +108 -0
- package/dist/runtime/rust/transport_sse.rs +91 -0
- package/dist/runtime/rust/transport_ws.rs +75 -0
- package/dist/runtime/rust/ws.rs +322 -0
- package/dist/runtime/ts/app-types.ts +200 -0
- package/dist/runtime/ts/app.ts +103 -0
- package/dist/runtime/ts/config.ts +119 -0
- package/dist/runtime/ts/defaults.ts +48 -0
- package/dist/runtime/ts/error.ts +113 -0
- package/dist/runtime/ts/hooks.ts +82 -0
- package/dist/runtime/ts/http.ts +283 -0
- package/dist/runtime/ts/media-type.ts +36 -0
- package/dist/runtime/ts/path.ts +152 -0
- package/dist/runtime/ts/realtime-connection.ts +296 -0
- package/dist/runtime/ts/realtime-transports.ts +149 -0
- package/dist/runtime/ts/realtime.ts +293 -0
- package/dist/runtime/ts/redirect-policy.ts +17 -0
- package/dist/runtime/ts/redirects.ts +74 -0
- package/dist/runtime/ts/request.ts +237 -0
- package/dist/runtime/ts/response.ts +223 -0
- package/dist/runtime/ts/sdk.ts +299 -0
- package/dist/runtime/ts/sse.ts +156 -0
- package/dist/runtime/ts/stale.ts +137 -0
- package/dist/runtime/ts/ws.ts +144 -0
- package/package.json +70 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lovro Žagar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# @lovrozagar/honey-clients
|
|
2
|
+
|
|
3
|
+
Generates SDKs (TypeScript, Go, Rust, Python, C#, Java), a Go command-line client and an MCP server from an OpenAPI
|
|
4
|
+
3.x document, or straight from a [`@lovrozagar/honey`](https://www.npmjs.com/package/@lovrozagar/honey) app.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
npm install --save-dev @lovrozagar/honey-clients
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Node 22.12 or later, or Bun 1.3 or later.
|
|
13
|
+
|
|
14
|
+
## Start
|
|
15
|
+
|
|
16
|
+
From a document:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npx honey-clients generate --spec openapi.json --target ts --target python --out generated
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
From a honey app module, with no document written first:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
npx honey-clients generate --app src/app.ts --target ts --target go --go-module-path github.com/acme/shop/sdk \
|
|
26
|
+
--out generated
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The targets are `ts`, `go`, `rust`, `python`, `csharp`, `java`, `cli` and `mcp`.
|
|
30
|
+
|
|
31
|
+
## honey-clients generate
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
honey-clients generate --spec openapi.json --target ts --target cli --out generated \
|
|
35
|
+
--cli-binary-name shop --cli-module-path github.com/acme/shop --cli-repo acme/shop
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- `--spec <file>`: the OpenAPI document, as JSON.
|
|
39
|
+
- `--app <module>[#export]`: a honey app module instead of `--spec` (give one, never both). Its named export, else
|
|
40
|
+
`app`, else `default`, is the app; its document is made by the app's own `@lovrozagar/honey/openapi`, resolved from
|
|
41
|
+
the app as at run time, and the module's `openApi` export, if any, is that document's options (`info`,
|
|
42
|
+
`securitySchemes`, `invalidate`, …, as `generateOpenApi` takes them). Started by `bun run`, the bin hands the load to
|
|
43
|
+
that Bun, so a module needing Bun's loaders works; a run ends once it has written, whatever the module left open.
|
|
44
|
+
The module exports the app and serves nothing: one that calls `serve()` as it loads is outside `--app`'s contract,
|
|
45
|
+
since honey never serves implicitly and has no switch to stop it.
|
|
46
|
+
- `--target <name>`: `ts`, `go`, `rust`, `python`, `csharp`, `java`, `cli` or `mcp`; repeat it for more than one. Each
|
|
47
|
+
target's files go under `<out>/<target>`.
|
|
48
|
+
- `--<target>-<option>`: a target's options are its generator's, passed through as given (`--go-module-path`,
|
|
49
|
+
`--rust-crate-name`, `--cli-binary-name`). Each takes a value. `honey-clients --help` lists them all.
|
|
50
|
+
- `--watch`: generate again on each change of the spec (or the `--app` module), each run in a fresh process.
|
|
51
|
+
|
|
52
|
+
The `go` and `cli` targets format every Go file they write with gofmt, so they need Go installed. gofmt is found by
|
|
53
|
+
`$GOFMT`, then `$GOROOT/bin/gofmt`, then `gofmt` on `PATH`, then beside the `go` on `PATH`. Without one they refuse.
|
|
54
|
+
|
|
55
|
+
The `ts` target formats every file it writes with oxfmt, an optional peer: install `oxfmt` beside honey-clients. Without
|
|
56
|
+
it the files go out as emitted, valid TypeScript that is not formatted.
|
|
57
|
+
|
|
58
|
+
**Stale files are deleted, edited ones kept.** Each `<out>/<target>` keeps `.honey-generated.json`: every file the run
|
|
59
|
+
wrote, with its sha256. A file is rewritten only when its bytes change, through a temp file renamed over it. A
|
|
60
|
+
regeneration deletes a file the last run wrote and this one does not (a `cli` target's old `<name>_cmds.go`, say), unless
|
|
61
|
+
it was edited since: that one is kept and named on stderr. A file the manifest never listed is never deleted, nothing
|
|
62
|
+
outside `<out>/<target>` is touched, and no symlink is followed. Without a manifest, nothing is deleted.
|
|
63
|
+
|
|
64
|
+
## Documentation
|
|
65
|
+
|
|
66
|
+
- [Code generation](https://github.com/lovrozagar/honey/blob/main/docs/codegen.md): every target and its options.
|
|
67
|
+
- [Generated clients](https://github.com/lovrozagar/honey/blob/main/docs/client.md) and their
|
|
68
|
+
[per-language recipes](https://github.com/lovrozagar/honey/blob/main/docs/sdk-recipes.md).
|
|
69
|
+
- [The generated CLI](https://github.com/lovrozagar/honey/blob/main/docs/cli.md),
|
|
70
|
+
[releasing it](https://github.com/lovrozagar/honey/blob/main/docs/cli-release.md), and
|
|
71
|
+
[the MCP server](https://github.com/lovrozagar/honey/blob/main/docs/mcp.md).
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The honey-clients bin (bit 17 phase h). A repository checkout (marked by tsconfig.json, which is not published)
|
|
3
|
+
// runs the TypeScript source, natively on Bun (under the honey-source condition) and through jiti on Node, so a stale
|
|
4
|
+
// dist/ never runs; an installed package runs the compiled JavaScript on any runtime (the tarball ships dist/, not src/).
|
|
5
|
+
import { spawn } from "node:child_process"
|
|
6
|
+
import { existsSync } from "node:fs"
|
|
7
|
+
import { basename } from "node:path"
|
|
8
|
+
import { fileURLToPath } from "node:url"
|
|
9
|
+
|
|
10
|
+
const isBun = typeof globalThis.Bun !== "undefined"
|
|
11
|
+
const checkout = existsSync(new URL("../tsconfig.json", import.meta.url))
|
|
12
|
+
|
|
13
|
+
// `bun run` and `bunx` start this file through its node shebang, while what they run is meant for Bun: hand over to
|
|
14
|
+
// the Bun that started us, which they name in npm_execpath. Once, never again in the child.
|
|
15
|
+
function invokingBun() {
|
|
16
|
+
if (isBun || process.env.HONEY_NO_BUN_HANDOFF === "1") return null
|
|
17
|
+
if (!process.env.npm_config_user_agent?.startsWith("bun/")) return null
|
|
18
|
+
const bun = process.env.npm_execpath
|
|
19
|
+
if (!bun || !/^bunx?(\.exe)?$/.test(basename(bun)) || !existsSync(bun)) return null
|
|
20
|
+
return bun
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// The handoff: Bun runs this file with our arguments and `env` over ours; a signal we get is passed on to it, and we
|
|
24
|
+
// end as it ended, its exit code or the same signal.
|
|
25
|
+
function handOff(bun, env) {
|
|
26
|
+
// Forwarders first: a signal landing as spawn returns would otherwise end this process by its default action,
|
|
27
|
+
// orphaning the child. A handler runs from the event loop, after this block, so `child` is set by then.
|
|
28
|
+
let child
|
|
29
|
+
const forward = (signal) => child.kill(signal)
|
|
30
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) process.on(signal, forward)
|
|
31
|
+
child = spawn(bun, [fileURLToPath(import.meta.url), ...process.argv.slice(2)], {
|
|
32
|
+
env: { ...process.env, ...env, HONEY_NO_BUN_HANDOFF: "1" },
|
|
33
|
+
stdio: "inherit",
|
|
34
|
+
})
|
|
35
|
+
child.on("error", (error) => {
|
|
36
|
+
console.error(`honey-clients: could not start ${bun}: ${error.message}`)
|
|
37
|
+
process.exit(1)
|
|
38
|
+
})
|
|
39
|
+
child.on("exit", (code, signal) => {
|
|
40
|
+
if (signal) {
|
|
41
|
+
for (const each of ["SIGINT", "SIGTERM", "SIGHUP"]) process.off(each, forward)
|
|
42
|
+
process.kill(process.pid, signal)
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
process.exit(code ?? 1)
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// A checkout on Bun runs under the honey-source condition: an --app module's checkout core then resolves to its
|
|
50
|
+
// source, never to an unbuilt or stale dist/ (bit 20). Set through BUN_OPTIONS when the caller did not, in the one
|
|
51
|
+
// handoff, so a watch's generation children inherit it; Bun reports BUN_OPTIONS' flags in execArgv, so a Bun started
|
|
52
|
+
// with it never hands off again.
|
|
53
|
+
const SOURCE_CONDITION = "--conditions=honey-source"
|
|
54
|
+
const unconditioned = isBun && checkout && !process.execArgv.includes(SOURCE_CONDITION)
|
|
55
|
+
// The hand-off's backstop: its child carries HONEY_BUN_HANDOFF, the depth of hand-offs before it. A child that would
|
|
56
|
+
// hand off again (the condition set but not in its execArgv) refuses instead of re-running itself without end.
|
|
57
|
+
const handOffDepth = Number(process.env.HONEY_BUN_HANDOFF ?? 0)
|
|
58
|
+
const sourceEnv = checkout
|
|
59
|
+
? {
|
|
60
|
+
BUN_OPTIONS: `${process.env.BUN_OPTIONS ?? ""} ${SOURCE_CONDITION}`.trim(),
|
|
61
|
+
HONEY_BUN_HANDOFF: String(handOffDepth + 1),
|
|
62
|
+
}
|
|
63
|
+
: {}
|
|
64
|
+
|
|
65
|
+
async function entry() {
|
|
66
|
+
if (checkout) {
|
|
67
|
+
if (isBun) return import("../src/cli.ts")
|
|
68
|
+
const { createJiti } = await import("jiti")
|
|
69
|
+
return createJiti(import.meta.url).import("../src/cli.ts")
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
return await import("../dist/cli.js")
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (error?.code === "ERR_MODULE_NOT_FOUND" && String(error.url).endsWith("/dist/cli.js")) {
|
|
75
|
+
console.error("honey-clients: dist/ is missing from this install. Reinstall it, or run it with Bun.")
|
|
76
|
+
process.exit(1)
|
|
77
|
+
}
|
|
78
|
+
throw error
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const bun = invokingBun()
|
|
83
|
+
if (bun) handOff(bun, sourceEnv)
|
|
84
|
+
else if (unconditioned && handOffDepth >= 1) {
|
|
85
|
+
console.error("honey-clients: Bun hand-off loop: --conditions=honey-source not visible after re-exec")
|
|
86
|
+
process.exit(1)
|
|
87
|
+
} else if (unconditioned) handOff(process.execPath, sourceEnv)
|
|
88
|
+
else {
|
|
89
|
+
const { main } = await entry()
|
|
90
|
+
const code = await main(process.argv.slice(2))
|
|
91
|
+
/* an --app module may leave a timer or a socket open: the run is over once main returns, its output flushed */
|
|
92
|
+
for (const stream of [process.stdout, process.stderr]) await new Promise((done) => stream.write("", done))
|
|
93
|
+
process.exit(code)
|
|
94
|
+
}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type Formatter } from "./emit/shared/format.ts";
|
|
2
|
+
import { type Generate } from "./gen/args.ts";
|
|
3
|
+
/**
|
|
4
|
+
* The gofmt the go and cli targets are formatted with: `$GOFMT`, else `$GOROOT/bin/gofmt`, else gofmt on PATH, else
|
|
5
|
+
* the gofmt beside the real `go` on PATH (where every Go install keeps it); none when no Go is installed. Found by
|
|
6
|
+
* looking, never by running Go.
|
|
7
|
+
*/
|
|
8
|
+
export declare function findGofmt(env?: NodeJS.ProcessEnv): string | undefined;
|
|
9
|
+
/** oxfmt's `format`, the optional peer, when installed; else undefined (TS then goes out as emitted). */
|
|
10
|
+
export declare function loadOxfmt(specifier?: string): Promise<Formatter | undefined>;
|
|
11
|
+
/** What a generation reads beside its run: the environment, where skips are reported, the oxfmt module to load. */
|
|
12
|
+
export type GenerateContext = {
|
|
13
|
+
readonly env: NodeJS.ProcessEnv;
|
|
14
|
+
readonly report: (line: string) => void;
|
|
15
|
+
/** oxfmt's specifier, "oxfmt" by default: a leg names a missing one to run without it */
|
|
16
|
+
readonly oxfmt?: string;
|
|
17
|
+
};
|
|
18
|
+
/** Every file a run writes, by target and its path under the target's directory, Go's through gofmt, TS's through oxfmt. */
|
|
19
|
+
export declare function generated(run: Pick<Generate, "options" | "targets">, document: Record<string, unknown>, { env, oxfmt, report }: GenerateContext): Promise<Partial<Record<"cli" | "csharp" | "go" | "java" | "mcp" | "python" | "rust" | "ts", Readonly<Record<string, string>>>>>;
|
|
20
|
+
/** Where the CLI writes: standard output and standard error, by default the process's. */
|
|
21
|
+
export type Io = {
|
|
22
|
+
readonly out: (text: string) => void;
|
|
23
|
+
readonly err: (text: string) => void;
|
|
24
|
+
};
|
|
25
|
+
/** `document`'s targets generated and written under `<out>/<target>`, stale files deleted. */
|
|
26
|
+
export declare function writeGenerated(run: Pick<Generate, "options" | "out" | "targets">, document: Record<string, unknown>, io: Io, env: NodeJS.ProcessEnv): Promise<number>;
|
|
27
|
+
/** What a run takes beside its arguments: the environment, the directory paths resolve from, a watch's stop signal. */
|
|
28
|
+
export type RunOptions = {
|
|
29
|
+
readonly cwd?: string;
|
|
30
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
31
|
+
readonly signal?: AbortSignal;
|
|
32
|
+
};
|
|
33
|
+
/** Runs `honey-clients <argv>`: the exit code it ends with (a watch ends only by `options.signal`). */
|
|
34
|
+
export declare function main(argv: readonly string[], io?: Io, options?: RunOptions): Promise<number>;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The honey-clients generate CLI (bit 17 phase h): `honey-clients generate --spec <openapi.json> --target <name>...
|
|
11
|
+
* --out <dir>` writes each target's generated files under `<out>/<target>`. A target's options are its generate
|
|
12
|
+
* function's, spelled `--<target>-<option>` and passed through untouched: each generator validates its own. The go and
|
|
13
|
+
* cli targets' whole trees go through gofmt (the post-pass), so a missing gofmt is a refusal, never unformatted Go; the
|
|
14
|
+
* ts target's files go through oxfmt, the optional peer, imported lazily, and go out as emitted without it (00-rules).
|
|
15
|
+
* `--watch` regenerates in a fresh child on each change of the spec. Parsing is strict: an unknown flag, a missing
|
|
16
|
+
* value, a stray argument or an option for a target not asked for is a usage error. Each target is written through
|
|
17
|
+
* write.ts: only changed files, a hashed manifest, a removed operation's unedited files deleted (bit 19 h1). `--app`
|
|
18
|
+
* generates from a honey app module instead of a spec, its document made by the app's own core (ir/load.ts, bit 19 h2).
|
|
19
|
+
*/
|
|
20
|
+
import { existsSync, readFileSync, realpathSync, statSync, watch } from "node:fs";
|
|
21
|
+
import { basename, delimiter, dirname, join, resolve } from "node:path";
|
|
22
|
+
import { generateGoCli } from "./emit/cli/module.js";
|
|
23
|
+
import { generateCSharpSdk } from "./emit/csharp/sdk.js";
|
|
24
|
+
import { generateGoSdk } from "./emit/go/sdk.js";
|
|
25
|
+
import { generateJavaSdk } from "./emit/java/sdk.js";
|
|
26
|
+
import { generateMcpServer } from "./emit/mcp/server.js";
|
|
27
|
+
import { generatePythonSdk } from "./emit/python/sdk.js";
|
|
28
|
+
import { generateRustSdk } from "./emit/rust/sdk.js";
|
|
29
|
+
import { formatFiles } from "./emit/shared/format.js";
|
|
30
|
+
import { gofmtFormatter } from "./emit/shared/gofmt.js";
|
|
31
|
+
import { generateSdk } from "./emit/ts/sdk.js";
|
|
32
|
+
import { parseGenerate, usage, UsageError } from "./gen/args.js";
|
|
33
|
+
import { runCli } from "./gen/process.js";
|
|
34
|
+
import { appRef, loadAppDocument } from "./ir/load.js";
|
|
35
|
+
import { writeTarget } from "./gen/write.js";
|
|
36
|
+
/** An executable named `name` on PATH, or none. */
|
|
37
|
+
function onPath(name, env) {
|
|
38
|
+
return (env.PATH ?? "")
|
|
39
|
+
.split(delimiter)
|
|
40
|
+
.filter(Boolean)
|
|
41
|
+
.map((dir) => join(dir, name))
|
|
42
|
+
.find((path) => existsSync(path) && statSync(path).isFile());
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The gofmt the go and cli targets are formatted with: `$GOFMT`, else `$GOROOT/bin/gofmt`, else gofmt on PATH, else
|
|
46
|
+
* the gofmt beside the real `go` on PATH (where every Go install keeps it); none when no Go is installed. Found by
|
|
47
|
+
* looking, never by running Go.
|
|
48
|
+
*/
|
|
49
|
+
export function findGofmt(env = process.env) {
|
|
50
|
+
if (env.GOFMT)
|
|
51
|
+
return env.GOFMT;
|
|
52
|
+
const fromRoot = env.GOROOT ? join(env.GOROOT, "bin", "gofmt") : undefined;
|
|
53
|
+
if (fromRoot !== undefined && existsSync(fromRoot))
|
|
54
|
+
return fromRoot;
|
|
55
|
+
const go = onPath("go", env);
|
|
56
|
+
const beside = go === undefined ? undefined : join(dirname(realpathSync(go)), "gofmt");
|
|
57
|
+
return onPath("gofmt", env) ?? (beside !== undefined && existsSync(beside) ? beside : undefined);
|
|
58
|
+
}
|
|
59
|
+
/** One SDK target's generation: its files and what it reports (a name it renamed). */
|
|
60
|
+
function sdkOf(target, document, options) {
|
|
61
|
+
switch (target) {
|
|
62
|
+
case "ts":
|
|
63
|
+
return generateSdk(document, { name: "SDK", ...options });
|
|
64
|
+
case "go":
|
|
65
|
+
return generateGoSdk(document, options);
|
|
66
|
+
case "rust":
|
|
67
|
+
return generateRustSdk(document, options);
|
|
68
|
+
case "python":
|
|
69
|
+
return generatePythonSdk(document, options);
|
|
70
|
+
case "csharp":
|
|
71
|
+
return generateCSharpSdk(document, options);
|
|
72
|
+
case "java":
|
|
73
|
+
return generateJavaSdk(document, options);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** One target's files for `document`, by their path under the target's directory; what it leaves out to `report`. */
|
|
77
|
+
function filesOf(target, document, options, report) {
|
|
78
|
+
if (target === "cli")
|
|
79
|
+
return generateGoCli(document, options).files;
|
|
80
|
+
if (target === "mcp") {
|
|
81
|
+
const server = generateMcpServer(document, options);
|
|
82
|
+
for (const op of server.skipped)
|
|
83
|
+
report(`honey-clients: mcp: no tool serves ${op} yet: skipped\n`);
|
|
84
|
+
return server.files;
|
|
85
|
+
}
|
|
86
|
+
const sdk = sdkOf(target, document, options);
|
|
87
|
+
for (const notice of sdk.notices)
|
|
88
|
+
report(`honey-clients: ${notice}\n`);
|
|
89
|
+
return sdk.files;
|
|
90
|
+
}
|
|
91
|
+
/** oxfmt's `format`, the optional peer, when installed; else undefined (TS then goes out as emitted). */
|
|
92
|
+
export async function loadOxfmt(specifier = "oxfmt") {
|
|
93
|
+
try {
|
|
94
|
+
return (await import(__rewriteRelativeImportExtension(specifier))).format;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error.code === "ERR_MODULE_NOT_FOUND")
|
|
98
|
+
return undefined;
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Every file a run writes, by target and its path under the target's directory, Go's through gofmt, TS's through oxfmt. */
|
|
103
|
+
export async function generated(run, document, { env, oxfmt, report }) {
|
|
104
|
+
const out = {};
|
|
105
|
+
for (const target of run.targets) {
|
|
106
|
+
let files = filesOf(target, document, run.options[target], report);
|
|
107
|
+
if (target === "go" || target === "cli") {
|
|
108
|
+
const gofmt = findGofmt(env);
|
|
109
|
+
if (gofmt === undefined)
|
|
110
|
+
throw new Error("gofmt is required for the go and cli targets (install Go, or set GOFMT)");
|
|
111
|
+
files = await formatFiles(files, { go: gofmtFormatter(gofmt) });
|
|
112
|
+
}
|
|
113
|
+
if (target === "ts") {
|
|
114
|
+
const format = await loadOxfmt(oxfmt);
|
|
115
|
+
if (format !== undefined)
|
|
116
|
+
files = await formatFiles(files, { ts: format });
|
|
117
|
+
}
|
|
118
|
+
out[target] = files;
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
/** The spec at `path`, parsed. */
|
|
123
|
+
function readSpec(path) {
|
|
124
|
+
const text = readFileSync(path, "utf8");
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse(text);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
throw new Error(`${path}: not a JSON document (${error.message})`, { cause: error });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const PROCESS_IO = {
|
|
133
|
+
err: (text) => void process.stderr.write(text),
|
|
134
|
+
out: (text) => void process.stdout.write(text),
|
|
135
|
+
};
|
|
136
|
+
/** `document`'s targets generated and written under `<out>/<target>`, stale files deleted. */
|
|
137
|
+
export async function writeGenerated(run, document, io, env) {
|
|
138
|
+
let count = 0;
|
|
139
|
+
for (const [target, files] of Object.entries(await generated(run, document, { env, report: io.err }))) {
|
|
140
|
+
for (const rel of writeTarget(join(run.out, target), files).kept)
|
|
141
|
+
io.err(`honey-clients: ${join(target, rel)} is stale but edited since it was generated, or not its to delete: kept\n`);
|
|
142
|
+
count += Object.keys(files).length;
|
|
143
|
+
}
|
|
144
|
+
io.out(`honey-clients: generated ${count} files into ${run.out}\n`);
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
/** One generation: the spec read, or the app's document made (the module resolved from `cwd`), then written. */
|
|
148
|
+
async function generateOnce(run, io, env, cwd) {
|
|
149
|
+
const document = run.app === "" ? readSpec(resolve(cwd, run.spec)) : await loadAppDocument(run.app, cwd);
|
|
150
|
+
return writeGenerated({ ...run, out: resolve(cwd, run.out) }, document, io, env);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Generates now and on each change of the spec, each run a fresh child after the one before it (a change during a run
|
|
154
|
+
* is one more run, never two at once); `signal` stops the watch, which then ends 0 once the last run is done. A
|
|
155
|
+
* generation child (HONEY_CODEGEN_CHILD) never watches: were `--watch` ever passed down, each child would start another.
|
|
156
|
+
*/
|
|
157
|
+
function watchSpec(run, argv, io, options) {
|
|
158
|
+
if (options.env.HONEY_CODEGEN_CHILD === "1")
|
|
159
|
+
throw new Error("--watch is not allowed in a generation child");
|
|
160
|
+
const args = ["generate", ...argv.filter((arg) => arg !== "--watch" && !arg.startsWith("--watch="))];
|
|
161
|
+
const spec = resolve(options.cwd, run.app === "" ? run.spec : appRef(run.app).module);
|
|
162
|
+
let queue = Promise.resolve();
|
|
163
|
+
const generate = () => {
|
|
164
|
+
queue = queue.then(() => runCli(args, { cwd: options.cwd, env: options.env }).catch((error) => io.err(`honey-clients: ${error.message}\n`)));
|
|
165
|
+
};
|
|
166
|
+
let timer;
|
|
167
|
+
const watcher = watch(dirname(spec), (_event, name) => {
|
|
168
|
+
if (name !== basename(spec))
|
|
169
|
+
return;
|
|
170
|
+
clearTimeout(timer);
|
|
171
|
+
timer = setTimeout(generate, 100);
|
|
172
|
+
});
|
|
173
|
+
io.out(`honey-clients: watching ${spec}\n`);
|
|
174
|
+
generate();
|
|
175
|
+
return new Promise((settle) => options.signal?.addEventListener("abort", () => {
|
|
176
|
+
watcher.close();
|
|
177
|
+
clearTimeout(timer);
|
|
178
|
+
void queue.then(() => settle(0));
|
|
179
|
+
}, { once: true }));
|
|
180
|
+
}
|
|
181
|
+
/** Runs `honey-clients <argv>`: the exit code it ends with (a watch ends only by `options.signal`). */
|
|
182
|
+
export async function main(argv, io = PROCESS_IO, options = {}) {
|
|
183
|
+
try {
|
|
184
|
+
if (argv.length === 0 || argv[0] === "-h" || argv[0] === "--help" || argv.includes("--help")) {
|
|
185
|
+
io.out(`${usage()}\n`);
|
|
186
|
+
return argv.length === 0 ? 1 : 0;
|
|
187
|
+
}
|
|
188
|
+
if (argv[0] !== "generate")
|
|
189
|
+
throw new UsageError(`unknown command ${JSON.stringify(argv[0])}`);
|
|
190
|
+
const run = parseGenerate(argv.slice(1));
|
|
191
|
+
const [env, cwd] = [options.env ?? process.env, options.cwd ?? process.cwd()];
|
|
192
|
+
return run.watch
|
|
193
|
+
? await watchSpec(run, argv.slice(1), io, { cwd, env, signal: options.signal })
|
|
194
|
+
: await generateOnce(run, io, env, cwd);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
if (error instanceof UsageError) {
|
|
198
|
+
io.err(`honey-clients: ${error.message}\n\n${usage()}\n`);
|
|
199
|
+
return 1;
|
|
200
|
+
}
|
|
201
|
+
io.err(`honey-clients: ${error.message}\n`);
|
|
202
|
+
return 1;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One command per operation (bit 17), by its dotted id: `items.get` is `items get`, `a.b.c` is `a b c`, a flat id
|
|
3
|
+
* (`getRoot`) a top-level `get-root`. The verb is the id's last segment as authored, never renamed. In a group a
|
|
4
|
+
* subgroup claims its name before a command, and at the root every built-in (completion, commands, config, help,
|
|
5
|
+
* schema, skill, version) is taken first, so a clash is suffixed as the IR suffixes ids (`version2`). Each command calls
|
|
6
|
+
* the embedded SDK's own method by the emitter's call plan, its body read from its flags (a multipart one part by
|
|
7
|
+
* part), and prints the answer with the response it came on, or a stream's events one line each (phase d).
|
|
8
|
+
*/
|
|
9
|
+
import type { IR } from "../../ir/model.ts";
|
|
10
|
+
import type { SdkOp } from "../../ir/sdk-model.ts";
|
|
11
|
+
import type { GoCallPlan } from "../go/sdk-client.ts";
|
|
12
|
+
/** The root's own commands, each taken before an operation's. */
|
|
13
|
+
export declare const BUILT_INS: string[];
|
|
14
|
+
/** A command node: a group of others, or one operation's command. */
|
|
15
|
+
export type CommandNode = {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly fn: string;
|
|
18
|
+
readonly children: readonly CommandNode[];
|
|
19
|
+
readonly op?: {
|
|
20
|
+
readonly op: SdkOp;
|
|
21
|
+
readonly plan: GoCallPlan;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
/** The command tree under the root, by the ids of every operation `ops` holds a command for. */
|
|
25
|
+
export declare function commandTree(ops: readonly SdkOp[], plans: Readonly<Record<string, GoCallPlan>>): CommandNode[];
|
|
26
|
+
/** A group's command function, then each of its children's. */
|
|
27
|
+
export declare function groupFuncs(node: CommandNode, path: readonly string[], ir: IR): string[][];
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { goString, lineComment } from "../shared/escape.js";
|
|
2
|
+
import { compareCodeUnits, NameScope, pascalWords } from "../shared/lang.js";
|
|
3
|
+
import { commandFlags, helpText, kebab } from "./flags.js";
|
|
4
|
+
/** The root's own commands, each taken before an operation's. */
|
|
5
|
+
export const BUILT_INS = ["commands", "completion", "config", "help", "schema", "skill", "version"];
|
|
6
|
+
function rawTree(ops, plans) {
|
|
7
|
+
const root = { groups: new Map(), leaves: new Map() };
|
|
8
|
+
for (const op of [...ops].sort((a, b) => compareCodeUnits(a.id, b.id))) {
|
|
9
|
+
let at = root;
|
|
10
|
+
for (const segment of op.segments.slice(0, -1)) {
|
|
11
|
+
if (!at.groups.has(segment))
|
|
12
|
+
at.groups.set(segment, { groups: new Map(), leaves: new Map() });
|
|
13
|
+
at = at.groups.get(segment);
|
|
14
|
+
}
|
|
15
|
+
at.leaves.set(op.segments.at(-1), { op, plan: plans[op.id] });
|
|
16
|
+
}
|
|
17
|
+
return root;
|
|
18
|
+
}
|
|
19
|
+
/** `raw` named: its groups first, then its commands, each claimed in its parent's scope; funcs claimed in `funcs`. */
|
|
20
|
+
function named(raw, path, scope, funcs) {
|
|
21
|
+
const groups = [...raw.groups].sort(([a], [b]) => compareCodeUnits(a, b));
|
|
22
|
+
const leaves = [...raw.leaves].sort(([a], [b]) => compareCodeUnits(a, b));
|
|
23
|
+
return [
|
|
24
|
+
...groups.map(([segment, child]) => {
|
|
25
|
+
const name = scope.claim(kebab(segment));
|
|
26
|
+
const at = [...path, name];
|
|
27
|
+
return {
|
|
28
|
+
children: named(child, at, new NameScope(), funcs),
|
|
29
|
+
fn: funcs.claim(`new${pascalWords(at.join(" "))}Cmd`),
|
|
30
|
+
name,
|
|
31
|
+
};
|
|
32
|
+
}),
|
|
33
|
+
...leaves.map(([segment, leaf]) => {
|
|
34
|
+
const name = scope.claim(kebab(segment));
|
|
35
|
+
return { children: [], fn: funcs.claim(`new${pascalWords([...path, name].join(" "))}Cmd`), name, op: leaf };
|
|
36
|
+
}),
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
/** The command tree under the root, by the ids of every operation `ops` holds a command for. */
|
|
40
|
+
export function commandTree(ops, plans) {
|
|
41
|
+
return named(rawTree(ops, plans), [], new NameScope(BUILT_INS), new NameScope(["Root", "newClient", "failed"]));
|
|
42
|
+
}
|
|
43
|
+
/** A named type of the SDK's, as package cmd spells it: `sdk.` before each exported name. */
|
|
44
|
+
const qualified = (type) => type.replace(/(?<![\w.])([A-Z]\w*)/g, "sdk.$1");
|
|
45
|
+
/** A multipart body's statements: each file part from its opened files, each text part from its flag. */
|
|
46
|
+
function multipartLines(type, parts) {
|
|
47
|
+
const lines = [`\tvar body ${type}`];
|
|
48
|
+
for (const [i, part] of parts.entries()) {
|
|
49
|
+
if (!part.file) {
|
|
50
|
+
lines.push(`\tif err := cli.Set(&body.${part.field}, p.Values(${goString(part.flag)})); err != nil {`, "\t\treturn err", "\t}");
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const file = "sdk.FilePart{Filename: upload.Filename, Data: upload.Data}";
|
|
54
|
+
const set = part.list ? `body.${part.field} = append(body.${part.field}, ${file})` : `body.${part.field} = ${file}`;
|
|
55
|
+
lines.push(`\tuploads${i}, err := p.Files(${goString(part.flag)})`, "\tif err != nil {", "\t\treturn err", "\t}", `\tfor _, upload := range uploads${i} {`, `\t\t${set}`, "\t}");
|
|
56
|
+
}
|
|
57
|
+
return lines;
|
|
58
|
+
}
|
|
59
|
+
/** The statements reading the body, and the argument passing it. */
|
|
60
|
+
function bodyLines(op, plan, flags) {
|
|
61
|
+
const { fields } = flags;
|
|
62
|
+
const body = op.body;
|
|
63
|
+
if (body === undefined)
|
|
64
|
+
return [[], ""];
|
|
65
|
+
const required = String(body.required);
|
|
66
|
+
const map = `map[string]string{${fields.map(([flag, key]) => `${goString(flag)}: ${goString(key)}`).join(", ")}}`;
|
|
67
|
+
const fail = ["\tif err != nil {", "\t\treturn err", "\t}"];
|
|
68
|
+
switch (body.kind) {
|
|
69
|
+
case "json": {
|
|
70
|
+
/* a pointer type decodes as well: json.Unmarshal allocates it, and an absent optional body stays nil */
|
|
71
|
+
const read = `\tif err := p.JSON(&body, ${required}, ${map}); err != nil {`;
|
|
72
|
+
return [[`\tvar body ${qualified(plan.bodyType)}`, read, "\t\treturn err", "\t}"], ", body"];
|
|
73
|
+
}
|
|
74
|
+
case "form":
|
|
75
|
+
return [[`\tbody, err := p.Form(${required}, ${map})`, ...fail], ", body"];
|
|
76
|
+
case "text":
|
|
77
|
+
return [[`\tbody, err := p.Text(${required})`, ...fail], ", body"];
|
|
78
|
+
case "multipart":
|
|
79
|
+
return [multipartLines(qualified(plan.bodyType), flags.parts), ", body"];
|
|
80
|
+
default:
|
|
81
|
+
return [[`\tbody, err := p.Reader(${required})`, ...fail], ", body"];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** A stream's call: its stream opened first (its output flags checked), then each event printed as it comes. */
|
|
85
|
+
function streamLines(call, stream) {
|
|
86
|
+
const open = ["\tout, err := cli.OpenStream(c)", "\tif err != nil {", "\t\treturn err", "\t}", "\tdefer out.Close()"];
|
|
87
|
+
if (stream === "sse")
|
|
88
|
+
return [
|
|
89
|
+
...open,
|
|
90
|
+
`\tfor event, err := range ${call} {`,
|
|
91
|
+
"\t\tif err != nil {",
|
|
92
|
+
"\t\t\treturn failed(err)",
|
|
93
|
+
"\t\t}",
|
|
94
|
+
"\t\tif !out.Event(event.Event, event.ID, event.Data) {",
|
|
95
|
+
"\t\t\tbreak",
|
|
96
|
+
"\t\t}",
|
|
97
|
+
"\t}",
|
|
98
|
+
"\treturn out.Err()",
|
|
99
|
+
];
|
|
100
|
+
return [
|
|
101
|
+
...open,
|
|
102
|
+
`\tconn, err := ${call}`,
|
|
103
|
+
"\tif err != nil {",
|
|
104
|
+
"\t\treturn failed(err)",
|
|
105
|
+
"\t}",
|
|
106
|
+
stream === "realtime" ? "\treturn failed(out.Resume(conn))" : "\treturn out.Converse(conn)",
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
/** The call and what follows it, by what the method returns: the answer printed with the response it came on. */
|
|
110
|
+
function callLines(call, plan) {
|
|
111
|
+
const declared = Object.keys(plan.responseHeaders?.fields ?? {})
|
|
112
|
+
.map(goString)
|
|
113
|
+
.join(", ");
|
|
114
|
+
const answer = (data) => `\treturn cli.Print(c, cli.Answer{${data}Response: resp, Declared: []string{${declared}}})`;
|
|
115
|
+
if (plan.returns === "error")
|
|
116
|
+
return [
|
|
117
|
+
"\tvar resp *http.Response",
|
|
118
|
+
`\tif err := ${call}; err != nil {`,
|
|
119
|
+
"\t\treturn failed(err)",
|
|
120
|
+
"\t}",
|
|
121
|
+
answer(""),
|
|
122
|
+
];
|
|
123
|
+
return [
|
|
124
|
+
"\tvar resp *http.Response",
|
|
125
|
+
`\tanswer, err := ${call}`,
|
|
126
|
+
"\tif err != nil {",
|
|
127
|
+
"\t\treturn failed(err)",
|
|
128
|
+
"\t}",
|
|
129
|
+
answer("Data: answer, "),
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
/** An operation's command function: its flags, then the RunE that checks them, calls the SDK and prints. */
|
|
133
|
+
function opFunc(node, path, ir) {
|
|
134
|
+
const { op, plan } = node.op;
|
|
135
|
+
const flags = commandFlags(op, plan, ir.schemas);
|
|
136
|
+
const use = [node.name, ...plan.pathParams.map((name) => `<${kebab(name)}>`)].join(" ");
|
|
137
|
+
const [read, bodyArg] = bodyLines(op, plan, flags);
|
|
138
|
+
const args = plan.pathParams.map((_, i) => `, path[${i}]`).join("");
|
|
139
|
+
const method = ["client", ...plan.members, plan.method].join(".");
|
|
140
|
+
const cobra = [`Use: ${goString(use)}`, `Short: ${goString(helpText(op.summary))}`];
|
|
141
|
+
if (op.description !== "")
|
|
142
|
+
cobra.push(`Long: ${goString(helpText(op.description))}`);
|
|
143
|
+
const run = [
|
|
144
|
+
"\tif err := p.Check(); err != nil {",
|
|
145
|
+
"\t\treturn err",
|
|
146
|
+
"\t}",
|
|
147
|
+
...(plan.pathParams.length > 0 ? ["\tpath := p.PathValues(args)"] : []),
|
|
148
|
+
`\topts := &sdk.${plan.opts}{}`,
|
|
149
|
+
...flags.opts,
|
|
150
|
+
...read,
|
|
151
|
+
"\tclient, err := newClient(c)",
|
|
152
|
+
"\tif err != nil {",
|
|
153
|
+
"\t\treturn err",
|
|
154
|
+
"\t}",
|
|
155
|
+
...(plan.stream === null
|
|
156
|
+
? callLines(`${method}(c.Context()${args}${bodyArg}, opts, sdk.WithResponseInto(&resp))`, plan)
|
|
157
|
+
: streamLines(`${method}(c.Context()${args}${bodyArg}, opts)`, plan.stream)),
|
|
158
|
+
];
|
|
159
|
+
return [
|
|
160
|
+
...lineComment(`${node.fn} is \`${[...path, node.name].join(" ")}\`: ${op.method} ${op.path}.`, "//"),
|
|
161
|
+
`func ${node.fn}() *cobra.Command {`,
|
|
162
|
+
`\tcmd := &cobra.Command{${cobra.join(", ")}}`,
|
|
163
|
+
"\tp := cli.NewParams(cmd)",
|
|
164
|
+
...flags.declare,
|
|
165
|
+
`\tcmd.RunE = func(c *cobra.Command, ${plan.pathParams.length > 0 ? "args" : "_"} []string) error {`,
|
|
166
|
+
...run.map((line) => `\t${line}`),
|
|
167
|
+
"\t}",
|
|
168
|
+
"\treturn cmd",
|
|
169
|
+
"}",
|
|
170
|
+
];
|
|
171
|
+
}
|
|
172
|
+
/** A group's command function, then each of its children's. */
|
|
173
|
+
export function groupFuncs(node, path, ir) {
|
|
174
|
+
if (node.op !== undefined)
|
|
175
|
+
return [opFunc(node, path, ir)];
|
|
176
|
+
const at = [...path, node.name];
|
|
177
|
+
const children = node.children.map((child) => `${child.fn}()`).join(", ");
|
|
178
|
+
const own = [
|
|
179
|
+
...lineComment(`${node.fn} is \`${at.join(" ")}\`, a group of commands.`, "//"),
|
|
180
|
+
`func ${node.fn}() *cobra.Command {`,
|
|
181
|
+
`\tcmd := cli.Group(&cobra.Command{Use: ${goString(node.name)}})`,
|
|
182
|
+
`\tcmd.AddCommand(${children})`,
|
|
183
|
+
"\treturn cmd",
|
|
184
|
+
"}",
|
|
185
|
+
];
|
|
186
|
+
return [own, ...node.children.flatMap((child) => groupFuncs(child, at, ir))];
|
|
187
|
+
}
|