ts-procedures 7.3.0 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -3
- package/agent_config/claude-code/agents/ts-procedures-architect.md +6 -8
- package/agent_config/claude-code/skills/ts-procedures/SKILL.md +30 -33
- package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +104 -53
- package/agent_config/claude-code/skills/ts-procedures/api-reference.md +205 -232
- package/agent_config/claude-code/skills/ts-procedures/patterns.md +80 -153
- package/agent_config/claude-code/skills/ts-procedures-review/SKILL.md +1 -1
- package/agent_config/claude-code/skills/ts-procedures-review/checklist.md +4 -5
- package/agent_config/claude-code/skills/ts-procedures-scaffold/SKILL.md +4 -7
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono.md +223 -0
- package/agent_config/copilot/copilot-instructions.md +34 -48
- package/agent_config/cursor/cursorrules +34 -48
- package/build/client/call.js +4 -1
- package/build/client/call.js.map +1 -1
- package/build/client/call.test.js +23 -0
- package/build/client/call.test.js.map +1 -1
- package/build/client/fetch-adapter.js +3 -1
- package/build/client/fetch-adapter.js.map +1 -1
- package/build/client/fetch-adapter.test.js +11 -1
- package/build/client/fetch-adapter.test.js.map +1 -1
- package/build/client/index.test.js +7 -7
- package/build/client/index.test.js.map +1 -1
- package/build/client/request-builder.d.ts +1 -1
- package/build/client/request-builder.js +2 -2
- package/build/client/request-builder.js.map +1 -1
- package/build/client/stream.js +13 -2
- package/build/client/stream.js.map +1 -1
- package/build/client/stream.test.js +32 -7
- package/build/client/stream.test.js.map +1 -1
- package/build/client/typed-error-dispatch.test.js +8 -92
- package/build/client/typed-error-dispatch.test.js.map +1 -1
- package/build/client/types.d.ts +21 -3
- package/build/codegen/bin/cli.js +0 -0
- package/build/codegen/e2e.test.js +418 -23
- package/build/codegen/e2e.test.js.map +1 -1
- package/build/codegen/emit-errors.integration.test.js +1 -1
- package/build/codegen/emit-errors.integration.test.js.map +1 -1
- package/build/codegen/emit-scope.js +351 -55
- package/build/codegen/emit-scope.js.map +1 -1
- package/build/codegen/emit-scope.test.js +540 -110
- package/build/codegen/emit-scope.test.js.map +1 -1
- package/build/codegen/emit-types.d.ts +6 -2
- package/build/codegen/emit-types.js +81 -20
- package/build/codegen/emit-types.js.map +1 -1
- package/build/codegen/emit-types.test.js +70 -1
- package/build/codegen/emit-types.test.js.map +1 -1
- package/build/codegen/pipeline.test.js +7 -7
- package/build/codegen/pipeline.test.js.map +1 -1
- package/build/codegen/resolve-envelope.js +1 -1
- package/build/codegen/resolve-envelope.js.map +1 -1
- package/build/codegen/resolve-envelope.test.js +5 -5
- package/build/codegen/resolve-envelope.test.js.map +1 -1
- package/build/codegen/targets/_shared/route-slots.d.ts +8 -3
- package/build/codegen/targets/_shared/route-slots.js +49 -8
- package/build/codegen/targets/_shared/route-slots.js.map +1 -1
- package/build/codegen/targets/_shared/route-slots.test.js +99 -26
- package/build/codegen/targets/_shared/route-slots.test.js.map +1 -1
- package/build/codegen/targets/kotlin/emit-route-kotlin.test.js +88 -17
- package/build/codegen/targets/kotlin/emit-route-kotlin.test.js.map +1 -1
- package/build/codegen/targets/kotlin/emit-scope-kotlin.test.js +9 -6
- package/build/codegen/targets/kotlin/emit-scope-kotlin.test.js.map +1 -1
- package/build/codegen/targets/kotlin/integration.test.js +6 -0
- package/build/codegen/targets/kotlin/integration.test.js.map +1 -1
- package/build/codegen/targets/swift/access-level.test.js +8 -11
- package/build/codegen/targets/swift/access-level.test.js.map +1 -1
- package/build/codegen/targets/swift/emit-route-swift.test.js +91 -20
- package/build/codegen/targets/swift/emit-route-swift.test.js.map +1 -1
- package/build/codegen/targets/swift/emit-scope-swift.test.js +12 -9
- package/build/codegen/targets/swift/emit-scope-swift.test.js.map +1 -1
- package/build/codegen/targets/swift/integration.test.js +6 -0
- package/build/codegen/targets/swift/integration.test.js.map +1 -1
- package/build/create-http-stream.d.ts +58 -0
- package/build/create-http-stream.js +122 -0
- package/build/create-http-stream.js.map +1 -0
- package/build/create-http-stream.test.js +88 -0
- package/build/create-http-stream.test.js.map +1 -0
- package/build/create-http.d.ts +49 -0
- package/build/create-http.js +108 -0
- package/build/create-http.js.map +1 -0
- package/build/create-http.test.js +137 -0
- package/build/create-http.test.js.map +1 -0
- package/build/create-stream.d.ts +35 -0
- package/build/create-stream.js +123 -0
- package/build/create-stream.js.map +1 -0
- package/build/create-stream.test.js +428 -0
- package/build/create-stream.test.js.map +1 -0
- package/build/create.d.ts +28 -0
- package/build/create.js +82 -0
- package/build/create.js.map +1 -0
- package/build/create.test.js +483 -0
- package/build/create.test.js.map +1 -0
- package/build/exports.d.ts +2 -0
- package/build/implementations/http/astro/index.test.js +20 -12
- package/build/implementations/http/astro/index.test.js.map +1 -1
- package/build/implementations/http/doc-registry.js +1 -1
- package/build/implementations/http/doc-registry.js.map +1 -1
- package/build/implementations/http/doc-registry.test.js +36 -5
- package/build/implementations/http/doc-registry.test.js.map +1 -1
- package/build/implementations/http/error-dispatch.d.ts +76 -0
- package/build/implementations/http/error-dispatch.js +77 -0
- package/build/implementations/http/error-dispatch.js.map +1 -0
- package/build/implementations/http/error-dispatch.test.js +254 -0
- package/build/implementations/http/error-dispatch.test.js.map +1 -0
- package/build/implementations/http/error-taxonomy.d.ts +5 -5
- package/build/implementations/http/hono/docs/http-doc.d.ts +6 -0
- package/build/implementations/http/hono/docs/http-doc.js +42 -0
- package/build/implementations/http/hono/docs/http-doc.js.map +1 -0
- package/build/implementations/http/hono/docs/http-stream-doc.d.ts +6 -0
- package/build/implementations/http/hono/docs/http-stream-doc.js +40 -0
- package/build/implementations/http/hono/docs/http-stream-doc.js.map +1 -0
- package/build/implementations/http/hono/docs/rpc-doc.d.ts +6 -0
- package/build/implementations/http/hono/docs/rpc-doc.js +24 -0
- package/build/implementations/http/hono/docs/rpc-doc.js.map +1 -0
- package/build/implementations/http/hono/docs/stream-doc.d.ts +6 -0
- package/build/implementations/http/hono/docs/stream-doc.js +42 -0
- package/build/implementations/http/hono/docs/stream-doc.js.map +1 -0
- package/build/implementations/http/hono/handlers/http-stream.d.ts +10 -0
- package/build/implementations/http/hono/handlers/http-stream.js +123 -0
- package/build/implementations/http/hono/handlers/http-stream.js.map +1 -0
- package/build/implementations/http/hono/handlers/http-stream.test.js +128 -0
- package/build/implementations/http/hono/handlers/http-stream.test.js.map +1 -0
- package/build/implementations/http/hono/handlers/http.d.ts +10 -0
- package/build/implementations/http/hono/handlers/http.js +115 -0
- package/build/implementations/http/hono/handlers/http.js.map +1 -0
- package/build/implementations/http/hono/handlers/http.test.js +118 -0
- package/build/implementations/http/hono/handlers/http.test.js.map +1 -0
- package/build/implementations/http/hono/handlers/rpc.d.ts +11 -0
- package/build/implementations/http/hono/handlers/rpc.js +32 -0
- package/build/implementations/http/hono/handlers/rpc.js.map +1 -0
- package/build/implementations/http/hono/handlers/rpc.test.js +73 -0
- package/build/implementations/http/hono/handlers/rpc.test.js.map +1 -0
- package/build/implementations/http/hono/handlers/stream.d.ts +23 -0
- package/build/implementations/http/hono/handlers/stream.js +147 -0
- package/build/implementations/http/hono/handlers/stream.js.map +1 -0
- package/build/implementations/http/hono/handlers/stream.test.d.ts +1 -0
- package/build/implementations/http/hono/handlers/stream.test.js +177 -0
- package/build/implementations/http/hono/handlers/stream.test.js.map +1 -0
- package/build/implementations/http/hono/index.d.ts +57 -0
- package/build/implementations/http/hono/index.js +149 -0
- package/build/implementations/http/hono/index.js.map +1 -0
- package/build/implementations/http/hono/index.test.d.ts +1 -0
- package/build/implementations/http/hono/index.test.js +274 -0
- package/build/implementations/http/hono/index.test.js.map +1 -0
- package/build/implementations/http/hono/path.d.ts +17 -0
- package/build/implementations/http/hono/path.js +39 -0
- package/build/implementations/http/hono/path.js.map +1 -0
- package/build/implementations/http/hono/path.test.d.ts +1 -0
- package/build/implementations/http/hono/path.test.js +83 -0
- package/build/implementations/http/hono/path.test.js.map +1 -0
- package/build/implementations/http/hono/types.d.ts +51 -0
- package/build/implementations/http/hono/types.js.map +1 -0
- package/build/implementations/http/on-request-error.test.js +6 -96
- package/build/implementations/http/on-request-error.test.js.map +1 -1
- package/build/implementations/http/route-errors.test.js +11 -59
- package/build/implementations/http/route-errors.test.js.map +1 -1
- package/build/implementations/types.d.ts +43 -9
- package/build/index.d.ts +124 -124
- package/build/index.js +10 -221
- package/build/index.js.map +1 -1
- package/build/index.test.js +20 -919
- package/build/index.test.js.map +1 -1
- package/build/migration.test.d.ts +1 -0
- package/build/migration.test.js +34 -0
- package/build/migration.test.js.map +1 -0
- package/build/schema/compute-schema.d.ts +11 -3
- package/build/schema/compute-schema.js +13 -7
- package/build/schema/compute-schema.js.map +1 -1
- package/build/schema/parser.d.ts +11 -3
- package/build/schema/parser.js +49 -9
- package/build/schema/parser.js.map +1 -1
- package/build/stack-utils.js +8 -0
- package/build/stack-utils.js.map +1 -1
- package/build/types.d.ts +142 -0
- package/build/types.js.map +1 -0
- package/docs/astro-adapter.md +5 -5
- package/docs/core.md +15 -17
- package/docs/http-integrations.md +83 -170
- package/docs/streaming.md +3 -60
- package/docs/superpowers/plans/2026-05-07-astro-adapter.md +2 -7
- package/docs/superpowers/plans/2026-05-08-create-http.md +3355 -0
- package/docs/superpowers/plans/2026-05-08-hono-app-builder-convergence.md +3365 -0
- package/docs/superpowers/specs/2026-05-07-astro-adapter-design.md +1 -3
- package/docs/superpowers/specs/2026-05-08-create-http-design.md +409 -0
- package/docs/superpowers/specs/2026-05-08-hono-app-builder-convergence-design.md +411 -0
- package/package.json +4 -22
- package/src/client/call.test.ts +26 -0
- package/src/client/call.ts +4 -1
- package/src/client/fetch-adapter.test.ts +14 -1
- package/src/client/fetch-adapter.ts +3 -1
- package/src/client/index.test.ts +7 -7
- package/src/client/request-builder.ts +2 -2
- package/src/client/stream.test.ts +39 -7
- package/src/client/stream.ts +16 -2
- package/src/client/typed-error-dispatch.test.ts +7 -97
- package/src/client/types.ts +21 -3
- package/src/codegen/__fixtures__/users-envelope.json +119 -38
- package/src/codegen/e2e.test.ts +452 -24
- package/src/codegen/emit-errors.integration.test.ts +1 -1
- package/src/codegen/emit-scope.test.ts +581 -110
- package/src/codegen/emit-scope.ts +390 -61
- package/src/codegen/emit-types.test.ts +73 -1
- package/src/codegen/emit-types.ts +82 -21
- package/src/codegen/pipeline.test.ts +7 -7
- package/src/codegen/resolve-envelope.test.ts +5 -5
- package/src/codegen/resolve-envelope.ts +1 -1
- package/src/codegen/targets/_shared/route-slots.test.ts +109 -26
- package/src/codegen/targets/_shared/route-slots.ts +48 -11
- package/src/codegen/targets/kotlin/__fixtures__/users-golden.kt +73 -0
- package/src/codegen/targets/kotlin/emit-route-kotlin.test.ts +100 -17
- package/src/codegen/targets/kotlin/emit-scope-kotlin.test.ts +9 -6
- package/src/codegen/targets/kotlin/integration.test.ts +19 -0
- package/src/codegen/targets/swift/__fixtures__/users-golden.swift +79 -0
- package/src/codegen/targets/swift/access-level.test.ts +8 -11
- package/src/codegen/targets/swift/emit-route-swift.test.ts +103 -20
- package/src/codegen/targets/swift/emit-scope-swift.test.ts +12 -9
- package/src/codegen/targets/swift/integration.test.ts +17 -0
- package/src/create-http-stream.test.ts +97 -0
- package/src/create-http-stream.ts +191 -0
- package/src/create-http.test.ts +163 -0
- package/src/create-http.ts +211 -0
- package/src/create-stream.test.ts +565 -0
- package/src/create-stream.ts +228 -0
- package/src/create.test.ts +658 -0
- package/src/create.ts +172 -0
- package/src/exports.ts +2 -0
- package/src/implementations/http/README.md +135 -95
- package/src/implementations/http/astro/README.md +4 -5
- package/src/implementations/http/astro/index.test.ts +25 -18
- package/src/implementations/http/doc-registry.test.ts +42 -5
- package/src/implementations/http/doc-registry.ts +1 -1
- package/src/implementations/http/error-dispatch.test.ts +283 -0
- package/src/implementations/http/error-dispatch.ts +176 -0
- package/src/implementations/http/error-taxonomy.ts +5 -5
- package/src/implementations/http/hono/docs/http-doc.ts +43 -0
- package/src/implementations/http/hono/docs/http-stream-doc.ts +44 -0
- package/src/implementations/http/hono/docs/rpc-doc.ts +34 -0
- package/src/implementations/http/hono/docs/stream-doc.ts +53 -0
- package/src/implementations/http/hono/handlers/http-stream.test.ts +150 -0
- package/src/implementations/http/hono/handlers/http-stream.ts +152 -0
- package/src/implementations/http/hono/handlers/http.test.ts +130 -0
- package/src/implementations/http/hono/handlers/http.ts +147 -0
- package/src/implementations/http/hono/handlers/rpc.test.ts +81 -0
- package/src/implementations/http/hono/handlers/rpc.ts +54 -0
- package/src/implementations/http/hono/handlers/stream.test.ts +198 -0
- package/src/implementations/http/hono/handlers/stream.ts +208 -0
- package/src/implementations/http/hono/index.test.ts +329 -0
- package/src/implementations/http/hono/index.ts +204 -0
- package/src/implementations/http/hono/path.test.ts +96 -0
- package/src/implementations/http/hono/path.ts +59 -0
- package/src/implementations/http/hono/types.ts +93 -0
- package/src/implementations/http/on-request-error.test.ts +10 -116
- package/src/implementations/http/route-errors.test.ts +11 -77
- package/src/implementations/types.ts +44 -9
- package/src/index.test.ts +22 -1249
- package/src/index.ts +49 -485
- package/src/migration.test.ts +48 -0
- package/src/schema/compute-schema.ts +26 -12
- package/src/schema/parser.ts +62 -12
- package/src/stack-utils.ts +8 -0
- package/src/types.ts +133 -0
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/express-rpc.md +0 -137
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-api.md +0 -173
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-rpc.md +0 -142
- package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-stream.md +0 -147
- package/build/implementations/http/express-rpc/error-taxonomy.test.js +0 -83
- package/build/implementations/http/express-rpc/error-taxonomy.test.js.map +0 -1
- package/build/implementations/http/express-rpc/index.d.ts +0 -125
- package/build/implementations/http/express-rpc/index.js +0 -216
- package/build/implementations/http/express-rpc/index.js.map +0 -1
- package/build/implementations/http/express-rpc/index.test.js +0 -684
- package/build/implementations/http/express-rpc/index.test.js.map +0 -1
- package/build/implementations/http/express-rpc/types.d.ts +0 -11
- package/build/implementations/http/express-rpc/types.js.map +0 -1
- package/build/implementations/http/hono-api/error-taxonomy.test.js +0 -137
- package/build/implementations/http/hono-api/error-taxonomy.test.js.map +0 -1
- package/build/implementations/http/hono-api/index.d.ts +0 -151
- package/build/implementations/http/hono-api/index.js +0 -344
- package/build/implementations/http/hono-api/index.js.map +0 -1
- package/build/implementations/http/hono-api/index.test.js +0 -992
- package/build/implementations/http/hono-api/index.test.js.map +0 -1
- package/build/implementations/http/hono-api/types.d.ts +0 -13
- package/build/implementations/http/hono-api/types.js.map +0 -1
- package/build/implementations/http/hono-rpc/error-taxonomy.test.js +0 -64
- package/build/implementations/http/hono-rpc/error-taxonomy.test.js.map +0 -1
- package/build/implementations/http/hono-rpc/index.d.ts +0 -130
- package/build/implementations/http/hono-rpc/index.js +0 -209
- package/build/implementations/http/hono-rpc/index.js.map +0 -1
- package/build/implementations/http/hono-rpc/index.test.js +0 -828
- package/build/implementations/http/hono-rpc/index.test.js.map +0 -1
- package/build/implementations/http/hono-rpc/types.d.ts +0 -11
- package/build/implementations/http/hono-rpc/types.js +0 -2
- package/build/implementations/http/hono-rpc/types.js.map +0 -1
- package/build/implementations/http/hono-stream/error-taxonomy.test.js +0 -159
- package/build/implementations/http/hono-stream/error-taxonomy.test.js.map +0 -1
- package/build/implementations/http/hono-stream/index.d.ts +0 -171
- package/build/implementations/http/hono-stream/index.js +0 -415
- package/build/implementations/http/hono-stream/index.js.map +0 -1
- package/build/implementations/http/hono-stream/index.test.js +0 -1383
- package/build/implementations/http/hono-stream/index.test.js.map +0 -1
- package/build/implementations/http/hono-stream/types.d.ts +0 -15
- package/build/implementations/http/hono-stream/types.js +0 -2
- package/build/implementations/http/hono-stream/types.js.map +0 -1
- package/src/implementations/http/express-rpc/README.md +0 -280
- package/src/implementations/http/express-rpc/error-taxonomy.test.ts +0 -103
- package/src/implementations/http/express-rpc/index.test.ts +0 -957
- package/src/implementations/http/express-rpc/index.ts +0 -327
- package/src/implementations/http/express-rpc/types.ts +0 -16
- package/src/implementations/http/hono-api/README.md +0 -284
- package/src/implementations/http/hono-api/error-taxonomy.test.ts +0 -179
- package/src/implementations/http/hono-api/index.test.ts +0 -1341
- package/src/implementations/http/hono-api/index.ts +0 -519
- package/src/implementations/http/hono-api/types.ts +0 -16
- package/src/implementations/http/hono-rpc/README.md +0 -357
- package/src/implementations/http/hono-rpc/error-taxonomy.test.ts +0 -82
- package/src/implementations/http/hono-rpc/index.test.ts +0 -1107
- package/src/implementations/http/hono-rpc/index.ts +0 -320
- package/src/implementations/http/hono-rpc/types.ts +0 -16
- package/src/implementations/http/hono-stream/README.md +0 -559
- package/src/implementations/http/hono-stream/error-taxonomy.test.ts +0 -178
- package/src/implementations/http/hono-stream/index.test.ts +0 -1804
- package/src/implementations/http/hono-stream/index.ts +0 -622
- package/src/implementations/http/hono-stream/types.ts +0 -20
- /package/build/{implementations/http/express-rpc/error-taxonomy.test.d.ts → create-http-stream.test.d.ts} +0 -0
- /package/build/{implementations/http/express-rpc/index.test.d.ts → create-http.test.d.ts} +0 -0
- /package/build/{implementations/http/hono-api/error-taxonomy.test.d.ts → create-stream.test.d.ts} +0 -0
- /package/build/{implementations/http/hono-api/index.test.d.ts → create.test.d.ts} +0 -0
- /package/build/implementations/http/{hono-rpc/error-taxonomy.test.d.ts → error-dispatch.test.d.ts} +0 -0
- /package/build/implementations/http/{hono-rpc/index.test.d.ts → hono/handlers/http-stream.test.d.ts} +0 -0
- /package/build/implementations/http/{hono-stream/error-taxonomy.test.d.ts → hono/handlers/http.test.d.ts} +0 -0
- /package/build/implementations/http/{hono-stream/index.test.d.ts → hono/handlers/rpc.test.d.ts} +0 -0
- /package/build/implementations/http/{express-rpc → hono}/types.js +0 -0
- /package/build/{implementations/http/hono-api/types.js → types.js} +0 -0
|
@@ -91,6 +91,45 @@ export interface ExtractedTypeOutput {
|
|
|
91
91
|
body: string
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Splits a block of ajsc output into individual top-level declarations.
|
|
96
|
+
*
|
|
97
|
+
* ajsc glues sibling extracted declarations with a single `\n`, but each
|
|
98
|
+
* declaration may itself span multiple lines (multi-line enums, object bodies
|
|
99
|
+
* with per-property JSDoc). A simple line/`export`-prefix split would therefore
|
|
100
|
+
* break multi-line declarations apart. Instead we walk lines tracking brace
|
|
101
|
+
* depth and close a declaration when depth returns to 0 on a line that ends in
|
|
102
|
+
* a statement terminator (`;` or `}`). Any leading comment lines (JSDoc) stay
|
|
103
|
+
* attached to the declaration that follows them.
|
|
104
|
+
*/
|
|
105
|
+
function splitTopLevelDeclarations(block: string): string[] {
|
|
106
|
+
const decls: string[] = []
|
|
107
|
+
let current: string[] = []
|
|
108
|
+
let depth = 0
|
|
109
|
+
|
|
110
|
+
const flush = () => {
|
|
111
|
+
const joined = current.join('\n').trim()
|
|
112
|
+
if (joined) decls.push(joined)
|
|
113
|
+
current = []
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
for (const line of block.split('\n')) {
|
|
117
|
+
current.push(line)
|
|
118
|
+
for (const ch of line) {
|
|
119
|
+
if (ch === '{') depth += 1
|
|
120
|
+
else if (ch === '}') depth -= 1
|
|
121
|
+
}
|
|
122
|
+
const trimmed = line.trimEnd()
|
|
123
|
+
if (depth <= 0 && (trimmed.endsWith(';') || trimmed.endsWith('}'))) {
|
|
124
|
+
flush()
|
|
125
|
+
depth = 0
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
flush()
|
|
129
|
+
|
|
130
|
+
return decls
|
|
131
|
+
}
|
|
132
|
+
|
|
94
133
|
/**
|
|
95
134
|
* Converts a JSON Schema to extracted TypeScript types using ajsc with
|
|
96
135
|
* `inlineTypes: false`. This produces named sub-types (objects, enums) that
|
|
@@ -122,13 +161,23 @@ export async function jsonSchemaToExtractedTypes(
|
|
|
122
161
|
)
|
|
123
162
|
}
|
|
124
163
|
|
|
125
|
-
// ajsc with inlineTypes: false produces
|
|
164
|
+
// ajsc with inlineTypes: false produces output like:
|
|
126
165
|
// export enum Status { Active = "active" }
|
|
127
166
|
// export type Contact = { name: string; };
|
|
167
|
+
//
|
|
128
168
|
// export type Root = { status: Status; contacts: Array<Contact>; };
|
|
129
169
|
//
|
|
130
|
-
//
|
|
170
|
+
// Crucially, *sibling* extracted declarations are joined by a SINGLE "\n"
|
|
171
|
+
// (one block) while the Root is separated by a blank line ("\n\n"). Splitting
|
|
172
|
+
// only on blank lines would therefore fuse two or more sibling declarations
|
|
173
|
+
// into one array element — and every downstream consumer (extractedDeclName,
|
|
174
|
+
// renameExtractedTypes, the namespace dedup) assumes one declaration per
|
|
175
|
+
// element, so the non-first siblings would be mis-parsed and emitted twice
|
|
176
|
+
// (`error TS2300: Duplicate identifier`). We split on blank lines first, then
|
|
177
|
+
// split each block into individual statements so each element holds exactly
|
|
178
|
+
// one declaration. The Root type is always the last declaration.
|
|
131
179
|
const blocks = code.split(/\n\n+/).map((b) => b.trim()).filter(Boolean)
|
|
180
|
+
const rawDecls = blocks.flatMap(splitTopLevelDeclarations)
|
|
132
181
|
|
|
133
182
|
const declarations: string[] = []
|
|
134
183
|
let body = ''
|
|
@@ -139,13 +188,13 @@ export async function jsonSchemaToExtractedTypes(
|
|
|
139
188
|
// declarations branch instead of being eaten as the body.
|
|
140
189
|
const rootDeclPattern = /^export\s+type\s+Root\s*=\s*/
|
|
141
190
|
|
|
142
|
-
for (const
|
|
143
|
-
if (rootDeclPattern.test(
|
|
191
|
+
for (const decl of rawDecls) {
|
|
192
|
+
if (rootDeclPattern.test(decl)) {
|
|
144
193
|
// Strip "export type Root = " prefix and trailing ";"
|
|
145
|
-
body =
|
|
194
|
+
body = decl.replace(rootDeclPattern, '').replace(/;\s*$/, '').trim()
|
|
146
195
|
} else {
|
|
147
196
|
// Sub-type or enum declaration — remove trailing ";" for consistency
|
|
148
|
-
declarations.push(
|
|
197
|
+
declarations.push(decl.replace(/;\s*$/, ''))
|
|
149
198
|
}
|
|
150
199
|
}
|
|
151
200
|
|
|
@@ -188,25 +237,28 @@ export function extractedDeclName(decl: string): string | undefined {
|
|
|
188
237
|
* alias is generated (`Params` → `ParamsInner`, then `ParamsInner2`, …) so
|
|
189
238
|
* the renamed type reads like a real, intentional name (not a placeholder).
|
|
190
239
|
* The declaration is rewritten with the new name and every word-boundary
|
|
191
|
-
* occurrence in `result.body`
|
|
192
|
-
*
|
|
240
|
+
* occurrence of the old name is substituted in `result.body` AND in every
|
|
241
|
+
* sibling declaration. The sibling patch matters because extracted sub-types
|
|
242
|
+
* reference each other (e.g. `Contact = { address: Address }`): renaming
|
|
243
|
+
* `Address` → `AddressInner` must update that reference too, otherwise the
|
|
244
|
+
* renamed type silently resolves to a different schema's sub-type of the same
|
|
245
|
+
* name (a latent wrong-type bug that only hides when the shapes happen to match).
|
|
193
246
|
*/
|
|
194
247
|
export function renameExtractedTypes(
|
|
195
248
|
result: ExtractedTypeOutput,
|
|
196
249
|
taken: Set<string>,
|
|
197
250
|
): ExtractedTypeOutput {
|
|
198
|
-
|
|
199
|
-
const declarations
|
|
251
|
+
// Work on a mutable copy so we can patch cross-references after renaming.
|
|
252
|
+
const declarations = [...result.declarations]
|
|
253
|
+
const renames = new Map<string, string>()
|
|
200
254
|
|
|
201
|
-
|
|
255
|
+
// Pass 1: decide renames and rewrite each declaration's leading identifier.
|
|
256
|
+
for (let i = 0; i < declarations.length; i += 1) {
|
|
257
|
+
const decl = declarations[i]!
|
|
202
258
|
const name = extractedDeclName(decl)
|
|
203
|
-
if (name == null)
|
|
204
|
-
declarations.push(decl)
|
|
205
|
-
continue
|
|
206
|
-
}
|
|
259
|
+
if (name == null) continue
|
|
207
260
|
if (!taken.has(name)) {
|
|
208
261
|
taken.add(name)
|
|
209
|
-
declarations.push(decl)
|
|
210
262
|
continue
|
|
211
263
|
}
|
|
212
264
|
|
|
@@ -220,16 +272,25 @@ export function renameExtractedTypes(
|
|
|
220
272
|
suffix += 1
|
|
221
273
|
}
|
|
222
274
|
taken.add(alias)
|
|
275
|
+
renames.set(name, alias)
|
|
223
276
|
|
|
224
|
-
|
|
225
|
-
const renamedDecl = decl.replace(
|
|
277
|
+
declarations[i] = decl.replace(
|
|
226
278
|
new RegExp(`^(export\\s+(?:type|enum|interface)\\s+)${name}\\b`),
|
|
227
279
|
`$1${alias}`,
|
|
228
280
|
)
|
|
229
|
-
|
|
281
|
+
}
|
|
230
282
|
|
|
231
|
-
|
|
232
|
-
|
|
283
|
+
// Pass 2: patch every reference to a renamed name — in the body and in every
|
|
284
|
+
// declaration body — so cross-references between sibling sub-types follow the
|
|
285
|
+
// rename. `\bAddress\b` does not match inside `AddressInner` (no word
|
|
286
|
+
// boundary between `s` and `I`), so already-renamed identifiers are untouched.
|
|
287
|
+
let body = result.body
|
|
288
|
+
for (const [name, alias] of renames) {
|
|
289
|
+
const re = new RegExp(`\\b${name}\\b`, 'g')
|
|
290
|
+
body = body.replace(re, alias)
|
|
291
|
+
for (let i = 0; i < declarations.length; i += 1) {
|
|
292
|
+
declarations[i] = declarations[i]!.replace(re, alias)
|
|
293
|
+
}
|
|
233
294
|
}
|
|
234
295
|
|
|
235
296
|
return { declarations, body }
|
|
@@ -375,7 +375,7 @@ describe('runPipeline (kotlin target)', () => {
|
|
|
375
375
|
scope: 'users',
|
|
376
376
|
method: 'GET',
|
|
377
377
|
fullPath: '/users/:id',
|
|
378
|
-
|
|
378
|
+
jsonSchema: { req: { pathParams: { type: 'object' } }, res: { body: { type: 'object' } } },
|
|
379
379
|
errors: [],
|
|
380
380
|
},
|
|
381
381
|
],
|
|
@@ -438,7 +438,7 @@ describe('runPipeline (kotlin target)', () => {
|
|
|
438
438
|
routes: [
|
|
439
439
|
{
|
|
440
440
|
kind: 'api', name: 'GetUser', scope: 'users', method: 'GET', fullPath: '/users/:id',
|
|
441
|
-
|
|
441
|
+
jsonSchema: { req: { pathParams: { type: 'object' } }, res: { body: { type: 'object' } } },
|
|
442
442
|
errors: [],
|
|
443
443
|
},
|
|
444
444
|
],
|
|
@@ -466,9 +466,9 @@ describe('runPipeline (kotlin target)', () => {
|
|
|
466
466
|
const envelope = {
|
|
467
467
|
basePath: '/api', headers: [], version: '1' as const, errors: [],
|
|
468
468
|
routes: [
|
|
469
|
-
{ kind: 'stream', name: 'WatchA', scope: 's', method: 'GET', path: '/a',
|
|
470
|
-
{ kind: 'stream', name: 'WatchB', scope: 's', method: 'GET', path: '/b',
|
|
471
|
-
{ kind: 'api', name: 'GetThing', scope: 's', method: 'GET', fullPath: '/c',
|
|
469
|
+
{ kind: 'stream', name: 'WatchA', scope: 's', method: 'GET', path: '/a', jsonSchema: {}, errors: [] },
|
|
470
|
+
{ kind: 'stream', name: 'WatchB', scope: 's', method: 'GET', path: '/b', jsonSchema: {}, errors: [] },
|
|
471
|
+
{ kind: 'api', name: 'GetThing', scope: 's', method: 'GET', fullPath: '/c', jsonSchema: { res: { body: { type: 'object' } } }, errors: [] },
|
|
472
472
|
],
|
|
473
473
|
} as any
|
|
474
474
|
await runPipeline({
|
|
@@ -493,7 +493,7 @@ describe('runPipeline (kotlin target)', () => {
|
|
|
493
493
|
try {
|
|
494
494
|
const envelope = {
|
|
495
495
|
basePath: '/api', headers: [], version: '1' as const, errors: [],
|
|
496
|
-
routes: [{ kind: 'api', name: 'X', scope: 's', method: 'GET', fullPath: '/x',
|
|
496
|
+
routes: [{ kind: 'api', name: 'X', scope: 's', method: 'GET', fullPath: '/x', jsonSchema: { res: { body: { type: 'object' } } }, errors: [] }],
|
|
497
497
|
} as any
|
|
498
498
|
await runPipeline({
|
|
499
499
|
envelope, outDir: 'out', dryRun: true,
|
|
@@ -518,7 +518,7 @@ describe('runPipeline (kotlin target)', () => {
|
|
|
518
518
|
|
|
519
519
|
const envelope = {
|
|
520
520
|
basePath: '/api', headers: [], version: '1' as const, errors: [],
|
|
521
|
-
routes: [{ kind: 'api', name: 'GetUser', scope: 'users', method: 'GET', fullPath: '/u',
|
|
521
|
+
routes: [{ kind: 'api', name: 'GetUser', scope: 'users', method: 'GET', fullPath: '/u', jsonSchema: { res: { body: { type: 'object' } } }, errors: [] }],
|
|
522
522
|
} as any
|
|
523
523
|
|
|
524
524
|
await runPipeline({
|
|
@@ -54,11 +54,11 @@ describe('resolveEnvelope', () => {
|
|
|
54
54
|
})
|
|
55
55
|
|
|
56
56
|
// Defensive (downstream bug repro): forgetting `builder.build()` is a common
|
|
57
|
-
// cause of an empty routes array because hono
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
57
|
+
// cause of an empty routes array because the hono builder only populates
|
|
58
|
+
// its `_docs` array inside `build()`. The current error message says
|
|
59
|
+
// "Register at least one procedure", which led the downstream dev to look
|
|
60
|
+
// in the wrong place. The message should mention `.build()` as a likely
|
|
61
|
+
// cause so the next person hits the right fix faster.
|
|
62
62
|
it('empty-routes error message mentions builder.build() as a likely cause', async () => {
|
|
63
63
|
const empty: DocEnvelope = { basePath: '', headers: [], errors: [], routes: [] }
|
|
64
64
|
await expect(resolveEnvelope({ envelope: empty })).rejects.toThrow(/\.build\(\)/)
|
|
@@ -55,7 +55,7 @@ export async function resolveEnvelope(input: ResolveInput): Promise<DocEnvelope>
|
|
|
55
55
|
throw new Error(
|
|
56
56
|
'[ts-procedures-codegen] DocEnvelope has an empty "routes" array. ' +
|
|
57
57
|
'Common causes: (1) you forgot to call `builder.build()` before passing ' +
|
|
58
|
-
'the builder to `DocRegistry.from(...)` — hono
|
|
58
|
+
'the builder to `DocRegistry.from(...)` — hono builders only populate ' +
|
|
59
59
|
'`docs` inside `build()`; (2) no procedures registered with the builder.'
|
|
60
60
|
)
|
|
61
61
|
}
|
|
@@ -2,54 +2,137 @@ import { describe, expect, it } from 'vitest'
|
|
|
2
2
|
import { extractRouteSlots } from './route-slots.js'
|
|
3
3
|
import type { AnyHttpRouteDoc } from '../../../implementations/types.js'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
// Helpers for constructing minimal route docs per kind
|
|
6
|
+
function apiRoute(jsonSchema: Record<string, unknown>): AnyHttpRouteDoc {
|
|
7
|
+
return { name: 'X', kind: 'api', method: 'get', path: '/x', fullPath: '/x', jsonSchema } as unknown as AnyHttpRouteDoc
|
|
8
|
+
}
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
function httpStreamRoute(jsonSchema: Record<string, unknown>): AnyHttpRouteDoc {
|
|
11
|
+
return { name: 'X', kind: 'http-stream', method: 'get', path: '/x', fullPath: '/x', streamMode: 'sse', jsonSchema } as unknown as AnyHttpRouteDoc
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function rpcRoute(jsonSchema: Record<string, unknown>): AnyHttpRouteDoc {
|
|
15
|
+
return { name: 'X', kind: 'rpc', method: 'post', path: '/x', scope: 'x', version: 1, jsonSchema } as unknown as AnyHttpRouteDoc
|
|
16
|
+
}
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
function streamRoute(jsonSchema: Record<string, unknown>): AnyHttpRouteDoc {
|
|
19
|
+
return { name: 'X', kind: 'stream', path: '/x', scope: 'x', version: 1, methods: ['get'], streamMode: 'sse', jsonSchema } as unknown as AnyHttpRouteDoc
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe('extractRouteSlots — api kind', () => {
|
|
23
|
+
it('returns no slots when jsonSchema is empty', () => {
|
|
24
|
+
expect(extractRouteSlots(apiRoute({}))).toEqual([])
|
|
15
25
|
})
|
|
16
26
|
|
|
17
|
-
it('returns the deterministic slot order: PathParams, Query, Body, Response', () => {
|
|
27
|
+
it('returns the deterministic slot order: PathParams, Query, Body, Headers, Response, ResponseHeaders', () => {
|
|
18
28
|
const slots = extractRouteSlots(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
body: { type: 'object',
|
|
22
|
-
query: { type: 'object',
|
|
23
|
-
pathParams: { type: 'object',
|
|
29
|
+
apiRoute({
|
|
30
|
+
req: {
|
|
31
|
+
body: { type: 'object', tag: 'body' },
|
|
32
|
+
query: { type: 'object', tag: 'query' },
|
|
33
|
+
pathParams: { type: 'object', tag: 'path' },
|
|
34
|
+
headers: { type: 'object', tag: 'headers' },
|
|
35
|
+
},
|
|
36
|
+
res: {
|
|
37
|
+
body: { type: 'object', tag: 'response' },
|
|
38
|
+
headers: { type: 'object', tag: 'resHeaders' },
|
|
24
39
|
},
|
|
25
|
-
returnType: { type: 'object', x: 'response' },
|
|
26
40
|
}),
|
|
27
41
|
)
|
|
28
|
-
expect(slots.map((s) => s.rootName)).toEqual(['PathParams', 'Query', 'Body', 'Response'])
|
|
42
|
+
expect(slots.map((s) => s.rootName)).toEqual(['PathParams', 'Query', 'Body', 'Headers', 'Response', 'ResponseHeaders'])
|
|
29
43
|
})
|
|
30
44
|
|
|
31
45
|
it('omits slots whose source is null or undefined', () => {
|
|
32
46
|
const slots = extractRouteSlots(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// returnType missing
|
|
47
|
+
apiRoute({
|
|
48
|
+
req: { pathParams: { type: 'object' }, query: null, body: undefined },
|
|
36
49
|
}),
|
|
37
50
|
)
|
|
38
51
|
expect(slots.map((s) => s.rootName)).toEqual(['PathParams'])
|
|
39
52
|
})
|
|
40
53
|
|
|
41
|
-
it('attaches
|
|
54
|
+
it('attaches source schemas verbatim', () => {
|
|
42
55
|
const path = { type: 'object', tag: 'p' }
|
|
43
|
-
const
|
|
44
|
-
const slots = extractRouteSlots(
|
|
56
|
+
const body = { type: 'object', tag: 'b' }
|
|
57
|
+
const slots = extractRouteSlots(apiRoute({ req: { pathParams: path, body }, res: {} }))
|
|
45
58
|
expect(slots).toEqual([
|
|
46
59
|
{ rootName: 'PathParams', source: path },
|
|
47
|
-
{ rootName: '
|
|
60
|
+
{ rootName: 'Body', source: body },
|
|
61
|
+
])
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('reads responseHeaders from res.headers', () => {
|
|
65
|
+
const resHeaders = { type: 'object', tag: 'rh' }
|
|
66
|
+
const slots = extractRouteSlots(apiRoute({ res: { headers: resHeaders } }))
|
|
67
|
+
expect(slots).toEqual([{ rootName: 'ResponseHeaders', source: resHeaders }])
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe('extractRouteSlots — http-stream kind', () => {
|
|
72
|
+
it('returns no slots when jsonSchema is empty', () => {
|
|
73
|
+
expect(extractRouteSlots(httpStreamRoute({}))).toEqual([])
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('returns the deterministic slot order: PathParams, Query, Body, Headers, ResponseHeaders, Yield, ReturnType', () => {
|
|
77
|
+
const slots = extractRouteSlots(
|
|
78
|
+
httpStreamRoute({
|
|
79
|
+
req: {
|
|
80
|
+
pathParams: { type: 'object', tag: 'path' },
|
|
81
|
+
query: { type: 'object', tag: 'query' },
|
|
82
|
+
body: { type: 'object', tag: 'body' },
|
|
83
|
+
headers: { type: 'object', tag: 'headers' },
|
|
84
|
+
},
|
|
85
|
+
res: { headers: { type: 'object', tag: 'resHeaders' } },
|
|
86
|
+
yield: { type: 'object', tag: 'yield' },
|
|
87
|
+
returnType: { type: 'object', tag: 'return' },
|
|
88
|
+
}),
|
|
89
|
+
)
|
|
90
|
+
expect(slots.map((s) => s.rootName)).toEqual([
|
|
91
|
+
'PathParams', 'Query', 'Body', 'Headers', 'ResponseHeaders', 'Yield', 'ReturnType',
|
|
48
92
|
])
|
|
49
93
|
})
|
|
50
94
|
|
|
51
|
-
it('
|
|
52
|
-
const
|
|
53
|
-
|
|
95
|
+
it('attaches yield and returnType sources correctly', () => {
|
|
96
|
+
const yieldSchema = { type: 'object', tag: 'y' }
|
|
97
|
+
const returnSchema = { type: 'object', tag: 'r' }
|
|
98
|
+
const slots = extractRouteSlots(httpStreamRoute({ yield: yieldSchema, returnType: returnSchema }))
|
|
99
|
+
expect(slots).toEqual([
|
|
100
|
+
{ rootName: 'Yield', source: yieldSchema },
|
|
101
|
+
{ rootName: 'ReturnType', source: returnSchema },
|
|
102
|
+
])
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
describe('extractRouteSlots — rpc kind', () => {
|
|
107
|
+
it('returns no slots when jsonSchema is empty', () => {
|
|
108
|
+
expect(extractRouteSlots(rpcRoute({}))).toEqual([])
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('maps body and response slots', () => {
|
|
112
|
+
const body = { type: 'object', tag: 'b' }
|
|
113
|
+
const response = { type: 'object', tag: 'r' }
|
|
114
|
+
const slots = extractRouteSlots(rpcRoute({ body, response }))
|
|
115
|
+
expect(slots).toEqual([
|
|
116
|
+
{ rootName: 'Body', source: body },
|
|
117
|
+
{ rootName: 'Response', source: response },
|
|
118
|
+
])
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
describe('extractRouteSlots — stream kind', () => {
|
|
123
|
+
it('returns no slots when jsonSchema is empty', () => {
|
|
124
|
+
expect(extractRouteSlots(streamRoute({}))).toEqual([])
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it('maps params→Body, yieldType→Yield, returnType→ReturnType', () => {
|
|
128
|
+
const params = { type: 'object', tag: 'p' }
|
|
129
|
+
const yieldType = { type: 'object', tag: 'y' }
|
|
130
|
+
const returnType = { type: 'object', tag: 'r' }
|
|
131
|
+
const slots = extractRouteSlots(streamRoute({ params, yieldType, returnType }))
|
|
132
|
+
expect(slots).toEqual([
|
|
133
|
+
{ rootName: 'Body', source: params },
|
|
134
|
+
{ rootName: 'Yield', source: yieldType },
|
|
135
|
+
{ rootName: 'ReturnType', source: returnType },
|
|
136
|
+
])
|
|
54
137
|
})
|
|
55
138
|
})
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { AnyHttpRouteDoc } from '../../../implementations/types.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* A "slot" is one of the deterministic schema sources a route exposes
|
|
5
|
-
*
|
|
6
|
-
* (`schema.returnType`). Targets emit one type per non-null slot.
|
|
4
|
+
* A "slot" is one of the deterministic schema sources a route exposes.
|
|
5
|
+
* Targets emit one type per non-null slot.
|
|
7
6
|
*/
|
|
8
7
|
export interface RouteSlot {
|
|
9
8
|
/** Stable identifier used as the emitted type's `rootTypeName`. */
|
|
@@ -15,18 +14,56 @@ export interface RouteSlot {
|
|
|
15
14
|
/**
|
|
16
15
|
* Returns the deterministic ordered slot list for a route, filtered to slots
|
|
17
16
|
* with non-null sources. Order is fixed at the module level for stable output.
|
|
17
|
+
*
|
|
18
|
+
* Kind dispatch:
|
|
19
|
+
* - `'api'` — reads from `jsonSchema.req` / `jsonSchema.res` (new envelope shape)
|
|
20
|
+
* - `'http-stream'` — reads from `jsonSchema.req` / `jsonSchema.res` / `jsonSchema.yield` / `jsonSchema.returnType`
|
|
21
|
+
* - `'rpc'` — reads from `jsonSchema.body` / `jsonSchema.response`
|
|
22
|
+
* - `'stream'` — reads from `jsonSchema.params` / `jsonSchema.yieldType` / `jsonSchema.returnType`
|
|
18
23
|
*/
|
|
19
24
|
export function extractRouteSlots(route: AnyHttpRouteDoc): RouteSlot[] {
|
|
20
|
-
const
|
|
21
|
-
const input = (schema.input ?? {}) as Record<string, unknown>
|
|
25
|
+
const kind = route.kind
|
|
22
26
|
|
|
23
27
|
// Order is load-bearing: targets emit slots in this sequence.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
let slots: RouteSlot[]
|
|
29
|
+
|
|
30
|
+
if (kind === 'api') {
|
|
31
|
+
const req = route.jsonSchema.req ?? {}
|
|
32
|
+
const res = route.jsonSchema.res ?? {}
|
|
33
|
+
slots = [
|
|
34
|
+
{ rootName: 'PathParams', source: req.pathParams },
|
|
35
|
+
{ rootName: 'Query', source: req.query },
|
|
36
|
+
{ rootName: 'Body', source: req.body },
|
|
37
|
+
{ rootName: 'Headers', source: req.headers },
|
|
38
|
+
{ rootName: 'Response', source: res.body },
|
|
39
|
+
{ rootName: 'ResponseHeaders', source: res.headers },
|
|
40
|
+
]
|
|
41
|
+
} else if (kind === 'http-stream') {
|
|
42
|
+
const req = route.jsonSchema.req ?? {}
|
|
43
|
+
const res = route.jsonSchema.res ?? {}
|
|
44
|
+
slots = [
|
|
45
|
+
{ rootName: 'PathParams', source: req.pathParams },
|
|
46
|
+
{ rootName: 'Query', source: req.query },
|
|
47
|
+
{ rootName: 'Body', source: req.body },
|
|
48
|
+
{ rootName: 'Headers', source: req.headers },
|
|
49
|
+
{ rootName: 'ResponseHeaders', source: res.headers },
|
|
50
|
+
{ rootName: 'Yield', source: route.jsonSchema.yield },
|
|
51
|
+
{ rootName: 'ReturnType', source: route.jsonSchema.returnType },
|
|
52
|
+
]
|
|
53
|
+
} else if (kind === 'rpc') {
|
|
54
|
+
slots = [
|
|
55
|
+
{ rootName: 'Body', source: route.jsonSchema.body },
|
|
56
|
+
{ rootName: 'Response', source: route.jsonSchema.response },
|
|
57
|
+
]
|
|
58
|
+
} else if (kind === 'stream') {
|
|
59
|
+
slots = [
|
|
60
|
+
{ rootName: 'Body', source: route.jsonSchema.params },
|
|
61
|
+
{ rootName: 'Yield', source: route.jsonSchema.yieldType },
|
|
62
|
+
{ rootName: 'ReturnType', source: route.jsonSchema.returnType },
|
|
63
|
+
]
|
|
64
|
+
} else {
|
|
65
|
+
slots = []
|
|
66
|
+
}
|
|
30
67
|
|
|
31
68
|
return slots.filter((s) => s.source != null)
|
|
32
69
|
}
|
|
@@ -118,4 +118,77 @@ object Users {
|
|
|
118
118
|
)
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
+
|
|
122
|
+
object DownloadUser {
|
|
123
|
+
const val method = "GET"
|
|
124
|
+
const val pathTemplate = "/users/{id}/download"
|
|
125
|
+
fun path(p: PathParams): String = "/users/${p.id}/download"
|
|
126
|
+
|
|
127
|
+
@Serializable
|
|
128
|
+
data class PathParams(
|
|
129
|
+
val id: String,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
@Serializable
|
|
133
|
+
data class Response(
|
|
134
|
+
val id: String,
|
|
135
|
+
val name: String,
|
|
136
|
+
@SerialName("created-at") @Contextual val createdAt: java.time.Instant,
|
|
137
|
+
val address: Address,
|
|
138
|
+
) {
|
|
139
|
+
@Serializable
|
|
140
|
+
data class Address(
|
|
141
|
+
val street: String,
|
|
142
|
+
val city: String,
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@Serializable
|
|
147
|
+
data class ResponseHeaders(
|
|
148
|
+
@SerialName("x-download-token") val xDownloadToken: String,
|
|
149
|
+
@SerialName("content-disposition") val contentDisposition: String? = null,
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
object WatchUsers {
|
|
154
|
+
const val method = "GET"
|
|
155
|
+
const val pathTemplate = "/users/watch"
|
|
156
|
+
const val path = "/users/watch"
|
|
157
|
+
|
|
158
|
+
@Serializable
|
|
159
|
+
data class Query(
|
|
160
|
+
val status: Status? = null,
|
|
161
|
+
val limit: Long? = null,
|
|
162
|
+
) {
|
|
163
|
+
@Serializable
|
|
164
|
+
enum class Status {
|
|
165
|
+
@SerialName("active") ACTIVE,
|
|
166
|
+
@SerialName("inactive") INACTIVE,
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@Serializable
|
|
171
|
+
data class ResponseHeaders(
|
|
172
|
+
@SerialName("x-download-token") val xDownloadToken: String,
|
|
173
|
+
@SerialName("content-disposition") val contentDisposition: String? = null,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
@Serializable
|
|
177
|
+
data class Yield(
|
|
178
|
+
val id: String,
|
|
179
|
+
val event: Event,
|
|
180
|
+
) {
|
|
181
|
+
@Serializable
|
|
182
|
+
enum class Event {
|
|
183
|
+
@SerialName("created") CREATED,
|
|
184
|
+
@SerialName("updated") UPDATED,
|
|
185
|
+
@SerialName("deleted") DELETED,
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@Serializable
|
|
190
|
+
data class ReturnType(
|
|
191
|
+
val count: Long,
|
|
192
|
+
)
|
|
193
|
+
}
|
|
121
194
|
}
|