ts-procedures 7.2.0 → 8.0.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 +139 -53
- package/agent_config/claude-code/skills/ts-procedures/api-reference.md +208 -231
- 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 +36 -48
- package/agent_config/cursor/cursorrules +36 -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 +87 -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 +308 -47
- package/build/codegen/emit-scope.js.map +1 -1
- package/build/codegen/emit-scope.test.js +363 -110
- package/build/codegen/emit-scope.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 +125 -115
- package/build/index.js +10 -222
- package/build/index.js.map +1 -1
- package/build/index.test.js +30 -822
- 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 +34 -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 +98 -24
- package/src/codegen/emit-errors.integration.test.ts +1 -1
- package/src/codegen/emit-scope.test.ts +395 -110
- package/src/codegen/emit-scope.ts +350 -55
- 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 +35 -1091
- package/src/index.ts +50 -474
- 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
|
@@ -7,6 +7,9 @@ Factory function that creates a scoped procedure registration system.
|
|
|
7
7
|
```typescript
|
|
8
8
|
function Procedures<TContext = unknown, TExtendedConfig = unknown>(
|
|
9
9
|
builder?: {
|
|
10
|
+
config?: {
|
|
11
|
+
noRuntimeValidation?: true
|
|
12
|
+
}
|
|
10
13
|
onCreate?: (procedure: {
|
|
11
14
|
name: string
|
|
12
15
|
isStream?: boolean
|
|
@@ -26,14 +29,17 @@ function Procedures<TContext = unknown, TExtendedConfig = unknown>(
|
|
|
26
29
|
|
|
27
30
|
### Parameters
|
|
28
31
|
|
|
32
|
+
- `builder.config.noRuntimeValidation` — When `true`, every procedure registered through this factory skips AJV validation at call time. Applies to all four creators: `Create` and `CreateStream` skip `schema.params` validation; `CreateHttp` and `CreateHttpStream` skip per-channel `schema.req.{pathParams,query,body,headers}` validation. JSON Schema is still computed at registration time, so `info.schema` and codegen are unaffected. Shape is `noRuntimeValidation?: true` — only `true` is accepted, making the opt-out explicit. Use only for trusted internal factories whose callers are already type-checked at build time; do **not** enable for procedures that accept input from public clients or untyped JSON bodies.
|
|
29
33
|
- `builder.onCreate` — Called each time a procedure is registered. Use for framework integration, route registration, or logging.
|
|
30
34
|
|
|
31
35
|
### Return Value
|
|
32
36
|
|
|
33
37
|
| Method | Description |
|
|
34
38
|
|--------|-------------|
|
|
35
|
-
| `Create(name, config, handler)` | Register a standard async procedure |
|
|
36
|
-
| `CreateStream(name, config, handler)` | Register a streaming async generator procedure |
|
|
39
|
+
| `Create(name, config, handler)` | Register a standard async RPC procedure |
|
|
40
|
+
| `CreateStream(name, config, handler)` | Register a streaming async generator RPC procedure |
|
|
41
|
+
| `CreateHttp(name, config, handler)` | Register a unary HTTP procedure (`path`, `method`, `schema.req`, `schema.res`) |
|
|
42
|
+
| `CreateHttpStream(name, config, handler)` | Register a streaming HTTP procedure |
|
|
37
43
|
| `getProcedures()` | Returns array of all registered procedure metadata |
|
|
38
44
|
| `getProcedure(name)` | Returns single procedure by name, or `undefined` |
|
|
39
45
|
| `removeProcedure(name)` | Removes procedure, returns `true` if found |
|
|
@@ -90,7 +96,7 @@ function Create<TName extends string, TParams, TReturnType>(
|
|
|
90
96
|
|----------|------|-------------|
|
|
91
97
|
| `...TContext` | varies | All base context fields |
|
|
92
98
|
| `error(message, meta?)` | `Function` | Creates `ProcedureError` — throw this for business logic errors |
|
|
93
|
-
| `signal?` | `AbortSignal` | Present when HTTP implementation injects it (
|
|
99
|
+
| `signal?` | `AbortSignal` | Present when HTTP implementation injects it (`HonoAppBuilder` does this automatically) |
|
|
94
100
|
|
|
95
101
|
|
|
96
102
|
### Return Value
|
|
@@ -99,31 +105,6 @@ function Create<TName extends string, TParams, TReturnType>(
|
|
|
99
105
|
- `{ procedure: handler }` — Same handler under a fixed key
|
|
100
106
|
- `{ info: metadata }` — Registration metadata with computed JSON schemas and validation functions
|
|
101
107
|
|
|
102
|
-
### schema.input (Structured Multi-Channel Input)
|
|
103
|
-
|
|
104
|
-
`schema.input` is an alternative to `schema.params` for multi-channel input. Mutually exclusive with `schema.params`.
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
Create('UpdateUser', {
|
|
108
|
-
path: '/users/:id',
|
|
109
|
-
method: 'put',
|
|
110
|
-
schema: {
|
|
111
|
-
input: {
|
|
112
|
-
pathParams: Type.Object({ id: Type.String() }),
|
|
113
|
-
body: Type.Object({ name: Type.String() }),
|
|
114
|
-
},
|
|
115
|
-
returnType: Type.Object({ ok: Type.Boolean() }),
|
|
116
|
-
},
|
|
117
|
-
}, async (ctx, { pathParams, body }) => {
|
|
118
|
-
// Each channel independently typed via TInput generic
|
|
119
|
-
return { ok: true }
|
|
120
|
-
})
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
- Each key in `input` is independently validated with per-channel error messages
|
|
124
|
-
- `ProcedureRegistrationError` thrown at registration if both `params` and `input` defined
|
|
125
|
-
- `TInput` generic inferred from `schema.input` — handler params type computed as `{ [K in keyof TInput]: TSchemaLib<TInput[K]> }`
|
|
126
|
-
|
|
127
108
|
### Throws
|
|
128
109
|
|
|
129
110
|
- `ProcedureRegistrationError` — If schema extraction/compilation fails, or duplicate name
|
|
@@ -195,6 +176,85 @@ When `validateYields: true`:
|
|
|
195
176
|
|
|
196
177
|
---
|
|
197
178
|
|
|
179
|
+
## CreateHttp\<TName, TReq, TRes, TErrorKey\>(name, config, handler)
|
|
180
|
+
|
|
181
|
+
Registers a unary HTTP procedure (v8+). First-class surface for REST-style routes with per-channel input (`schema.req`) and structured response (`schema.res`).
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
function CreateHttp<
|
|
185
|
+
TName extends string,
|
|
186
|
+
TReq extends { pathParams?: unknown; query?: unknown; body?: unknown; headers?: unknown } = {},
|
|
187
|
+
TRes extends { body?: unknown; headers?: unknown } = {},
|
|
188
|
+
TErrorKey extends string = string
|
|
189
|
+
>(
|
|
190
|
+
name: TName,
|
|
191
|
+
config: {
|
|
192
|
+
path: string
|
|
193
|
+
method: HttpMethod
|
|
194
|
+
successStatus?: number
|
|
195
|
+
scope?: string
|
|
196
|
+
errors?: TErrorKey[]
|
|
197
|
+
description?: string
|
|
198
|
+
schema: {
|
|
199
|
+
req?: TReq
|
|
200
|
+
res?: TRes
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
handler: (
|
|
204
|
+
ctx: TContext & TLocalContext,
|
|
205
|
+
req: { [K in keyof TReq]: TSchemaLib<TReq[K]> }
|
|
206
|
+
) => Promise<HttpReturn<TRes>>
|
|
207
|
+
): {
|
|
208
|
+
[K in TName]: typeof handler
|
|
209
|
+
procedure: typeof handler
|
|
210
|
+
info: THttpProcedureRegistration
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Parameters
|
|
215
|
+
|
|
216
|
+
- `config.path` — Route path. Supports Hono-style path params (`:id`).
|
|
217
|
+
- `config.method` — HTTP method.
|
|
218
|
+
- `config.schema.req` — Per-channel input schemas. Channels: `pathParams`, `query`, `body`, `headers`. Each channel independently validated.
|
|
219
|
+
- `config.schema.res.body` — Response body schema (documentation; not runtime-validated).
|
|
220
|
+
- `config.schema.res.headers` — When declared, handler **must** return `{ body, headers }` instead of the body bare. The builder reads `headers` and forwards them to the HTTP response.
|
|
221
|
+
- `config.errors` — Taxonomy keys this route may emit (populates DocEnvelope for codegen).
|
|
222
|
+
|
|
223
|
+
### Return Shape
|
|
224
|
+
|
|
225
|
+
- **No `schema.res.headers`:** handler returns body bare (`T`).
|
|
226
|
+
- **`schema.res.headers` declared:** handler returns `{ body: B, headers: H }`.
|
|
227
|
+
|
|
228
|
+
### Throws
|
|
229
|
+
|
|
230
|
+
- `ProcedureRegistrationError` — Path param names don't match `schema.req.pathParams`; or `schema.params` provided on a `CreateHttp` call (wrong creator).
|
|
231
|
+
- `ProcedureValidationError` — At call time if any req channel fails validation.
|
|
232
|
+
- `ProcedureError` — At call time if handler throws.
|
|
233
|
+
|
|
234
|
+
### Example
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
const API = Procedures<AppContext>()
|
|
238
|
+
|
|
239
|
+
API.CreateHttp('GetUser', {
|
|
240
|
+
path: '/users/:id',
|
|
241
|
+
method: 'get',
|
|
242
|
+
schema: {
|
|
243
|
+
req: {
|
|
244
|
+
pathParams: Type.Object({ id: Type.String() }),
|
|
245
|
+
query: Type.Object({ include: Type.Optional(Type.String()) }),
|
|
246
|
+
},
|
|
247
|
+
res: {
|
|
248
|
+
body: Type.Object({ id: Type.String(), name: Type.String() }),
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
}, async (ctx, { pathParams, query }) => {
|
|
252
|
+
return await fetchUser(pathParams.id, { include: query.include })
|
|
253
|
+
})
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
198
258
|
## Error Classes
|
|
199
259
|
|
|
200
260
|
### ProcedureError
|
|
@@ -246,7 +306,7 @@ class ProcedureYieldValidationError extends ProcedureError {
|
|
|
246
306
|
|
|
247
307
|
### ProcedureRegistrationError extends ProcedureError
|
|
248
308
|
|
|
249
|
-
Thrown at registration time
|
|
309
|
+
Thrown at registration time. Common v8 sources: schema extraction/compilation failure, duplicate procedure name, using the removed v7 `schema.input` field (rejected with a migration message pointing to `CreateHttp` / `CreateHttpStream`), declaring both `schema.params` and `schema.req` on the same procedure (mutually exclusive — RPC vs HTTP), passing `schema.params` to `CreateHttp` / `CreateHttpStream` (use `schema.req.body` or `schema.req.query` instead), and path/schema mismatches on HTTP procedures (path declares params not in `schema.req.pathParams`, or vice versa).
|
|
250
310
|
|
|
251
311
|
```typescript
|
|
252
312
|
class ProcedureRegistrationError extends ProcedureError {
|
|
@@ -258,7 +318,7 @@ class ProcedureRegistrationError extends ProcedureError {
|
|
|
258
318
|
|
|
259
319
|
## Error Taxonomy API
|
|
260
320
|
|
|
261
|
-
Exported from `ts-procedures/http-errors` (and re-exported from
|
|
321
|
+
Exported from `ts-procedures/http-errors` (and re-exported from `ts-procedures/hono`).
|
|
262
322
|
|
|
263
323
|
### defineErrorTaxonomy(entries)
|
|
264
324
|
|
|
@@ -630,136 +690,90 @@ Maps schema type to inferred TypeScript type:
|
|
|
630
690
|
|
|
631
691
|
---
|
|
632
692
|
|
|
633
|
-
##
|
|
634
|
-
|
|
635
|
-
HTTP implementation for Express.
|
|
636
|
-
|
|
637
|
-
```typescript
|
|
638
|
-
class ExpressRPCAppBuilder {
|
|
639
|
-
constructor(config?: {
|
|
640
|
-
app?: express.Express
|
|
641
|
-
pathPrefix?: string
|
|
642
|
-
onRequestStart?: (req: express.Request) => void
|
|
643
|
-
onRequestEnd?: (req: express.Request, res: express.Response) => void
|
|
644
|
-
onSuccess?: (procedure: TProcedureRegistration, req: express.Request, res: express.Response) => void
|
|
645
|
-
// Error handling — two peer modes plus a cross-cutting observer.
|
|
646
|
-
errors?: ErrorTaxonomy
|
|
647
|
-
unknownError?: UnknownErrorConfig
|
|
648
|
-
onError?: (procedure: TProcedureRegistration, req: express.Request, res: express.Response, error: Error) => void
|
|
649
|
-
onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
|
|
650
|
-
})
|
|
651
|
-
|
|
652
|
-
register<TFactory>(
|
|
653
|
-
factory: TFactory,
|
|
654
|
-
factoryContext: Context | ((req: Request) => Context | Promise<Context>),
|
|
655
|
-
extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
|
|
656
|
-
): this
|
|
657
|
-
|
|
658
|
-
build(): express.Application
|
|
659
|
-
|
|
660
|
-
static makeRPCHttpRoutePath(params: { name: string; config: RPCConfig; prefix?: string }): string
|
|
693
|
+
## HonoAppBuilder\<TStreamErrorData\>
|
|
661
694
|
|
|
662
|
-
|
|
663
|
-
get docs(): RPCHttpRouteDoc[]
|
|
664
|
-
}
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
`OnRequestErrorContext` for Express: `{ err: unknown; procedure: TProcedureRegistration; raw: { req, res } }`.
|
|
668
|
-
|
|
669
|
-
### Route Path
|
|
670
|
-
|
|
671
|
-
`POST {pathPrefix}/{scope}/{kebab-name}/{version}`
|
|
672
|
-
|
|
673
|
-
- `scope` can be string or string array (joined as path segments)
|
|
674
|
-
- Procedure name is converted to kebab-case
|
|
675
|
-
|
|
676
|
-
### Context Resolution
|
|
677
|
-
|
|
678
|
-
- Static object: `builder.register(factory, { userId: 'system' })`
|
|
679
|
-
- Sync function: `builder.register(factory, (req) => ({ auth: req.headers.authorization }))`
|
|
680
|
-
- Async function: `builder.register(factory, async (req) => ({ user: await getUser(req) }))`
|
|
681
|
-
|
|
682
|
-
### Signal Injection
|
|
683
|
-
|
|
684
|
-
Express builder creates a lazy AbortController and aborts on request close. The `signal` is injected into handler context automatically.
|
|
695
|
+
Unified Hono HTTP implementation for v8. A single builder dispatches all four procedure kinds (`Create` → RPC, `CreateStream` → streaming RPC, `CreateHttp` → REST-style, `CreateHttpStream` → streaming REST) from one `register()` call. Replaces v7's separate `HonoRPCAppBuilder` / `HonoStreamAppBuilder` / `HonoAPIAppBuilder` classes.
|
|
685
696
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
## HonoRPCAppBuilder
|
|
689
|
-
|
|
690
|
-
HTTP implementation for Hono. Same API as ExpressRPCAppBuilder but receives Hono `Context` instead of Express `Request`.
|
|
697
|
+
Config is **stratified**: cross-cutting fields live at the top level, kind-specific fields live in `rpc:` / `api:` / `stream:` blocks.
|
|
691
698
|
|
|
692
699
|
```typescript
|
|
693
|
-
class
|
|
700
|
+
class HonoAppBuilder<TStreamErrorData = unknown> {
|
|
694
701
|
constructor(config?: {
|
|
702
|
+
// Cross-cutting (apply to every kind)
|
|
695
703
|
app?: Hono
|
|
696
704
|
pathPrefix?: string
|
|
697
|
-
|
|
698
|
-
onRequestEnd?: (c: Context) => void
|
|
699
|
-
onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
|
|
705
|
+
|
|
700
706
|
// Error handling — two peer modes plus a cross-cutting observer.
|
|
701
707
|
errors?: ErrorTaxonomy
|
|
702
708
|
unknownError?: UnknownErrorConfig
|
|
703
|
-
onError?:
|
|
709
|
+
onError?: PreStreamOnError // imperative pre-stream / unary handler
|
|
704
710
|
onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
|
|
705
|
-
})
|
|
706
711
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
|
|
711
|
-
): this
|
|
712
|
-
|
|
713
|
-
build(): Hono
|
|
714
|
-
get app(): Hono
|
|
715
|
-
get docs(): RPCHttpRouteDoc[]
|
|
716
|
-
}
|
|
717
|
-
```
|
|
718
|
-
|
|
719
|
-
`OnRequestErrorContext` for Hono RPC: `{ err: unknown; procedure: TProcedureRegistration; raw: Context }`.
|
|
720
|
-
|
|
721
|
-
### Signal Injection
|
|
722
|
-
|
|
723
|
-
Uses `c.req.raw.signal` — the native Request signal from the Hono context.
|
|
724
|
-
|
|
725
|
-
---
|
|
712
|
+
// Lifecycle (every kind)
|
|
713
|
+
onRequestStart?: (c: Context) => void
|
|
714
|
+
onRequestEnd?: (c: Context) => void
|
|
726
715
|
|
|
727
|
-
|
|
716
|
+
// RPC-specific (Create procedures)
|
|
717
|
+
rpc?: {
|
|
718
|
+
onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
|
|
719
|
+
}
|
|
728
720
|
|
|
729
|
-
|
|
721
|
+
// HTTP-specific (CreateHttp procedures)
|
|
722
|
+
api?: {
|
|
723
|
+
queryParser?: (queryString: string) => Record<string, unknown>
|
|
724
|
+
onSuccess?: (procedure: THttpProcedureRegistration, c: Context) => void
|
|
725
|
+
}
|
|
730
726
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
727
|
+
// Stream-specific (CreateStream + CreateHttpStream procedures)
|
|
728
|
+
stream?: {
|
|
729
|
+
defaultStreamMode?: StreamMode // 'sse' | 'text', default 'sse'
|
|
730
|
+
onStreamStart?: (
|
|
731
|
+
procedure: TStreamProcedureRegistration | THttpStreamProcedureRegistration,
|
|
732
|
+
c: Context,
|
|
733
|
+
streamMode: StreamMode,
|
|
734
|
+
) => void
|
|
735
|
+
onStreamEnd?: (
|
|
736
|
+
procedure: TStreamProcedureRegistration | THttpStreamProcedureRegistration,
|
|
737
|
+
c: Context,
|
|
738
|
+
streamMode: StreamMode,
|
|
739
|
+
) => void
|
|
740
|
+
onMidStreamError?: (
|
|
741
|
+
procedure: TStreamProcedureRegistration | THttpStreamProcedureRegistration,
|
|
742
|
+
c: Context,
|
|
743
|
+
error: Error,
|
|
744
|
+
) => MidStreamErrorResult<TStreamErrorData> | undefined
|
|
745
|
+
}
|
|
746
746
|
})
|
|
747
747
|
|
|
748
748
|
register<TFactory>(
|
|
749
749
|
factory: TFactory,
|
|
750
750
|
factoryContext: Context | ((c: HonoContext) => Context | Promise<Context>),
|
|
751
751
|
options?: {
|
|
752
|
-
streamMode?: StreamMode
|
|
752
|
+
streamMode?: StreamMode // per-registration override of stream.defaultStreamMode
|
|
753
753
|
extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
|
|
754
754
|
}
|
|
755
755
|
): this
|
|
756
756
|
|
|
757
757
|
build(): Hono
|
|
758
|
+
toDocEnvelope(config?: DocRegistryConfig): DocEnvelope // single-app convenience
|
|
759
|
+
|
|
758
760
|
get app(): Hono
|
|
759
|
-
get docs():
|
|
761
|
+
get docs(): AnyHttpRouteDoc[] // mixed RPC / HTTP / Stream route docs
|
|
760
762
|
}
|
|
761
763
|
```
|
|
762
764
|
|
|
765
|
+
`OnRequestErrorContext`: `{ err: unknown; procedure: AnyProcedureRegistration; raw: Context }`.
|
|
766
|
+
|
|
767
|
+
### Top-level keys (the only keys allowed at the root of the config)
|
|
768
|
+
|
|
769
|
+
`app`, `pathPrefix`, `errors`, `unknownError`, `onError`, `onRequestError`, `onRequestStart`, `onRequestEnd`, `rpc`, `api`, `stream`. Anything else is a typo or v7 vestige — `queryParser`, `onSuccess`, `defaultStreamMode`, `onStreamStart`, `onStreamEnd`, `onMidStreamError` belong inside their kind block, not at the root.
|
|
770
|
+
|
|
771
|
+
### Error Handling
|
|
772
|
+
|
|
773
|
+
- **RPC + HTTP (unary):** `errors` taxonomy or `onError` callback. Observe via `onRequestError`.
|
|
774
|
+
- **Pre-stream errors** (validation, context resolution failures before the first yield): Returns a JSON error response — no streaming started. Same dispatch as unary: `errors` taxonomy or `onError` callback. Observe via `onRequestError`.
|
|
775
|
+
- **Mid-stream errors** (generator throws after the first yield): Yields error as final event, closes stream. Configure via `stream.onMidStreamError` (the only mid-stream path — the HTTP status is already committed).
|
|
776
|
+
|
|
763
777
|
### Stream Modes
|
|
764
778
|
|
|
765
779
|
**SSE mode** (`'sse'`):
|
|
@@ -783,12 +797,14 @@ function sse<T extends object>(data: T, options?: {
|
|
|
783
797
|
}): T
|
|
784
798
|
```
|
|
785
799
|
|
|
786
|
-
### HTTP Methods
|
|
800
|
+
### HTTP Methods (RPC streams)
|
|
787
801
|
|
|
788
|
-
|
|
802
|
+
For `CreateStream` procedures (RPC-style streams), both GET and POST are registered:
|
|
789
803
|
- **GET**: params extracted from query string
|
|
790
804
|
- **POST**: params extracted from JSON body
|
|
791
805
|
|
|
806
|
+
For `CreateHttpStream`, the method comes from `config.method` (no auto-pairing).
|
|
807
|
+
|
|
792
808
|
### MidStreamErrorResult
|
|
793
809
|
|
|
794
810
|
```typescript
|
|
@@ -798,63 +814,22 @@ type MidStreamErrorResult<TErrorData = unknown> = {
|
|
|
798
814
|
}
|
|
799
815
|
```
|
|
800
816
|
|
|
801
|
-
###
|
|
802
|
-
|
|
803
|
-
- **Pre-stream errors** (validation, context): Returns a JSON error response (no streaming started). Handle via either peer mode — `errors` taxonomy or `onError` callback. Observe via `onRequestError`.
|
|
804
|
-
- **Mid-stream errors** (generator throws): Yields error as final event, closes stream. Handle via `onMidStreamError` (the only mid-stream path — the HTTP status is already committed).
|
|
805
|
-
|
|
806
|
-
---
|
|
817
|
+
### Route Paths
|
|
807
818
|
|
|
808
|
-
|
|
819
|
+
- **RPC (`Create`):** `POST {pathPrefix}/{scope}/{kebab-name}/{version}` (auto-generated).
|
|
820
|
+
- **RPC stream (`CreateStream`):** `GET|POST {pathPrefix}/{scope}/{kebab-name}/{version}`.
|
|
821
|
+
- **HTTP (`CreateHttp` / `CreateHttpStream`):** developer-defined via `config.path` — no auto-generation. Supports Hono path params (`:id`). Final path is `{pathPrefix}{path}` — e.g., `/api/users/:id`.
|
|
809
822
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
```typescript
|
|
813
|
-
class HonoAPIAppBuilder {
|
|
814
|
-
constructor(config?: {
|
|
815
|
-
app?: Hono
|
|
816
|
-
pathPrefix?: string
|
|
817
|
-
queryParser?: (queryString: string) => Record<string, unknown>
|
|
818
|
-
onRequestStart?: (c: Context) => void
|
|
819
|
-
onRequestEnd?: (c: Context) => void
|
|
820
|
-
onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
|
|
821
|
-
// Error handling — two peer modes plus a cross-cutting observer.
|
|
822
|
-
errors?: ErrorTaxonomy
|
|
823
|
-
unknownError?: UnknownErrorConfig
|
|
824
|
-
onError?: (procedure: TProcedureRegistration, c: Context, error: Error) => Response | Promise<Response>
|
|
825
|
-
onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
|
|
826
|
-
})
|
|
827
|
-
|
|
828
|
-
register<TFactory>(
|
|
829
|
-
factory: TFactory,
|
|
830
|
-
factoryContext: Context | ((c: HonoContext) => Context | Promise<Context>),
|
|
831
|
-
extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
|
|
832
|
-
): this
|
|
833
|
-
|
|
834
|
-
build(): Hono
|
|
835
|
-
get app(): Hono
|
|
836
|
-
get docs(): APIHttpRouteDoc[]
|
|
837
|
-
}
|
|
838
|
-
```
|
|
839
|
-
|
|
840
|
-
`OnRequestErrorContext` for Hono API: `{ err: unknown; procedure: TProcedureRegistration; raw: Context }`.
|
|
841
|
-
|
|
842
|
-
### Route Path
|
|
843
|
-
|
|
844
|
-
Developer-defined via `APIConfig.path` — no auto-generation. Supports Hono path params (`:id`).
|
|
845
|
-
|
|
846
|
-
`{pathPrefix}{path}` — e.g., `/api/users/:id`
|
|
847
|
-
|
|
848
|
-
### Input Channel Extraction
|
|
823
|
+
### Input Channel Extraction (`schema.req` — `CreateHttp` only)
|
|
849
824
|
|
|
850
825
|
| Channel | HTTP Source | Used For |
|
|
851
826
|
|---------|-----------|----------|
|
|
852
827
|
| `pathParams` | URL path parameters (`c.req.param()`) | `/users/:id` → `{ id: '...' }` |
|
|
853
|
-
| `query` | Query string (parsed via
|
|
828
|
+
| `query` | Query string (parsed via `api.queryParser` or native `URLSearchParams`) | `?page=2` → `{ page: 2 }` |
|
|
854
829
|
| `body` | JSON request body (POST/PUT/PATCH only) | `{ name: 'John' }` |
|
|
855
830
|
| `headers` | Request headers (AJV strips non-declared) | `{ 'x-api-key': '...' }` |
|
|
856
831
|
|
|
857
|
-
### Default Success Status
|
|
832
|
+
### Default Success Status (`CreateHttp`)
|
|
858
833
|
|
|
859
834
|
| Method | Default Status |
|
|
860
835
|
|--------|---------------|
|
|
@@ -862,14 +837,14 @@ Developer-defined via `APIConfig.path` — no auto-generation. Supports Hono pat
|
|
|
862
837
|
| DELETE | 204 (no body) |
|
|
863
838
|
| Others | 200 |
|
|
864
839
|
|
|
865
|
-
Override with `
|
|
840
|
+
Override with `config.successStatus` on the `CreateHttp` config.
|
|
866
841
|
|
|
867
|
-
### Build-Time Validation
|
|
842
|
+
### Build-Time Validation (`CreateHttp`)
|
|
868
843
|
|
|
869
|
-
- Path param names in path template must match `schema.
|
|
870
|
-
- `schema.
|
|
871
|
-
- Path has `:param` but `schema.
|
|
872
|
-
- Property name mismatch →
|
|
844
|
+
- Path param names in path template must match `schema.req.pathParams` property names
|
|
845
|
+
- `schema.req.pathParams` defined but path has no `:param` segments → error
|
|
846
|
+
- Path has `:param` but `schema.req.pathParams` missing → error
|
|
847
|
+
- Property name mismatch → `ProcedureRegistrationError` at registration time
|
|
873
848
|
|
|
874
849
|
### Query Parsing
|
|
875
850
|
|
|
@@ -887,13 +862,15 @@ It does **not** interpret bracket/dot syntax — those stay as part of the liter
|
|
|
887
862
|
| `?user.name=John` | `{ 'user.name': 'John' }` | `{ user: { name: 'John' } }` |
|
|
888
863
|
| `?tags=a,b,c` | `{ tags: 'a,b,c' }` | `{ tags: ['a', 'b', 'c'] }` |
|
|
889
864
|
|
|
890
|
-
For nested/bracket/dot/CSV parsing, install `qs` and opt in via `queryParser`:
|
|
865
|
+
For nested/bracket/dot/CSV parsing, install `qs` and opt in via `api.queryParser`:
|
|
891
866
|
|
|
892
867
|
```typescript
|
|
893
868
|
import qs from 'qs'
|
|
894
869
|
|
|
895
|
-
new
|
|
896
|
-
|
|
870
|
+
new HonoAppBuilder({
|
|
871
|
+
api: {
|
|
872
|
+
queryParser: (raw) => qs.parse(raw) as Record<string, unknown>,
|
|
873
|
+
},
|
|
897
874
|
})
|
|
898
875
|
```
|
|
899
876
|
|
|
@@ -901,6 +878,10 @@ new HonoAPIAppBuilder({
|
|
|
901
878
|
|
|
902
879
|
Uses `c.req.raw.signal` — native Request signal from Hono context.
|
|
903
880
|
|
|
881
|
+
### Single-App Doc Envelope
|
|
882
|
+
|
|
883
|
+
For apps that build all routes through one `HonoAppBuilder`, `builder.toDocEnvelope()` returns the full `DocEnvelope` directly — no `DocRegistry` wiring needed. `DocRegistry` is still preferred for multi-app aggregation.
|
|
884
|
+
|
|
904
885
|
---
|
|
905
886
|
|
|
906
887
|
## HTTP Types
|
|
@@ -949,48 +930,53 @@ interface StreamHttpRouteDoc extends RPCConfig {
|
|
|
949
930
|
}
|
|
950
931
|
```
|
|
951
932
|
|
|
952
|
-
###
|
|
933
|
+
### TCreateHttpConfig (v8)
|
|
934
|
+
|
|
935
|
+
Config type for `CreateHttp`. HTTP fields are first-class — no `APIConfig` type parameter needed on the factory.
|
|
953
936
|
|
|
954
937
|
```typescript
|
|
955
|
-
|
|
956
|
-
interface APIConfig<TErrorKey extends string = string> {
|
|
938
|
+
type TCreateHttpConfig<TReq, TRes, TErrorKey extends string = string> = {
|
|
957
939
|
path: string
|
|
958
|
-
method:
|
|
940
|
+
method: HttpMethod
|
|
959
941
|
successStatus?: number
|
|
960
942
|
scope?: string
|
|
961
943
|
errors?: TErrorKey[]
|
|
944
|
+
description?: string
|
|
945
|
+
schema: {
|
|
946
|
+
req?: TReq // per-channel input: { pathParams?, query?, body?, headers? }
|
|
947
|
+
res?: TRes // structured response: { body?, headers? }
|
|
948
|
+
}
|
|
962
949
|
}
|
|
963
950
|
```
|
|
964
951
|
|
|
965
|
-
### APIHttpRouteDoc
|
|
952
|
+
### APIHttpRouteDoc (v8)
|
|
966
953
|
|
|
967
954
|
```typescript
|
|
968
|
-
interface APIHttpRouteDoc
|
|
955
|
+
interface APIHttpRouteDoc {
|
|
969
956
|
name: string
|
|
957
|
+
kind: 'http'
|
|
958
|
+
path: string
|
|
970
959
|
fullPath: string
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
body?: Record<string, unknown>
|
|
975
|
-
headers?: Record<string, unknown>
|
|
976
|
-
response?: Record<string, unknown>
|
|
977
|
-
}
|
|
960
|
+
method: HttpMethod
|
|
961
|
+
successStatus?: number
|
|
962
|
+
scope?: string
|
|
978
963
|
errors?: string[]
|
|
964
|
+
jsonSchema?: {
|
|
965
|
+
req?: {
|
|
966
|
+
pathParams?: Record<string, unknown>
|
|
967
|
+
query?: Record<string, unknown>
|
|
968
|
+
body?: Record<string, unknown>
|
|
969
|
+
headers?: Record<string, unknown>
|
|
970
|
+
}
|
|
971
|
+
res?: {
|
|
972
|
+
body?: Record<string, unknown>
|
|
973
|
+
headers?: Record<string, unknown>
|
|
974
|
+
}
|
|
975
|
+
}
|
|
979
976
|
}
|
|
980
977
|
```
|
|
981
978
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
Channel constraint helper type. Use with `satisfies` for compile-time validation of channel names.
|
|
985
|
-
|
|
986
|
-
```typescript
|
|
987
|
-
type APIInput<T extends {
|
|
988
|
-
pathParams?: unknown
|
|
989
|
-
query?: unknown
|
|
990
|
-
body?: unknown
|
|
991
|
-
headers?: unknown
|
|
992
|
-
}> = T
|
|
993
|
-
```
|
|
979
|
+
> **v7 → v8 migration:** `APIConfig` and `APIInput` are removed. Replace `Procedures<Ctx, APIConfig>()` with `Procedures<Ctx>()` and replace `.Create(` with `.CreateHttp(`. Replace `schema.input` with `schema.req`.
|
|
994
980
|
|
|
995
981
|
### HttpMethod
|
|
996
982
|
|
|
@@ -1033,7 +1019,7 @@ class DocRegistry {
|
|
|
1033
1019
|
|
|
1034
1020
|
### DocSource
|
|
1035
1021
|
|
|
1036
|
-
Any object with a `readonly docs` array.
|
|
1022
|
+
Any object with a `readonly docs` array. The built-in `HonoAppBuilder` satisfies this interface.
|
|
1037
1023
|
|
|
1038
1024
|
```typescript
|
|
1039
1025
|
interface DocSource<T = AnyHttpRouteDoc> {
|
|
@@ -1331,7 +1317,7 @@ interface TypedStream<TYield, TReturn> extends AsyncIterable<TYield> {
|
|
|
1331
1317
|
### Type Parameters
|
|
1332
1318
|
|
|
1333
1319
|
- `TYield` — Type of each yielded value (from `schema.yieldType`)
|
|
1334
|
-
- `TReturn` — Type of the stream's return value (from `schema.returnType`). Sent as `event: 'return'` SSE message by `
|
|
1320
|
+
- `TReturn` — Type of the stream's return value (from `schema.returnType`). Sent as `event: 'return'` SSE message by `HonoAppBuilder`.
|
|
1335
1321
|
|
|
1336
1322
|
### Key Behavior
|
|
1337
1323
|
|
|
@@ -1412,7 +1398,7 @@ Inside factory-context closures, read Astro's APIContext via `getAstroContext`:
|
|
|
1412
1398
|
```ts
|
|
1413
1399
|
import { getAstroContext } from 'ts-procedures/astro'
|
|
1414
1400
|
|
|
1415
|
-
new
|
|
1401
|
+
new HonoAppBuilder()
|
|
1416
1402
|
.register(usersAPI, (c) => {
|
|
1417
1403
|
const astro = getAstroContext(c)
|
|
1418
1404
|
return { db, user: astro.locals.user ?? null }
|
|
@@ -1424,7 +1410,7 @@ Multi-app: pass an array; first non-404 response wins. All-404 falls back to the
|
|
|
1424
1410
|
|
|
1425
1411
|
Constraints:
|
|
1426
1412
|
- Astro 5+ in SSR (or `prerender = false`).
|
|
1427
|
-
-
|
|
1413
|
+
- Hono builders only — the adapter accepts `Request`/`Response` apps.
|
|
1428
1414
|
|
|
1429
1415
|
---
|
|
1430
1416
|
|
|
@@ -1459,20 +1445,11 @@ import { captureDefinitionInfo, formatDefinitionInfo } from 'ts-procedures'
|
|
|
1459
1445
|
import type { DefinitionLocation, DefinitionInfo } from 'ts-procedures'
|
|
1460
1446
|
|
|
1461
1447
|
// HTTP types (types only, no runtime)
|
|
1462
|
-
import type { RPCConfig, RPCHttpRouteDoc, StreamHttpRouteDoc, StreamMode,
|
|
1463
|
-
|
|
1464
|
-
// Express RPC
|
|
1465
|
-
import { ExpressRPCAppBuilder } from 'ts-procedures/express-rpc'
|
|
1466
|
-
|
|
1467
|
-
// Hono RPC
|
|
1468
|
-
import { HonoRPCAppBuilder } from 'ts-procedures/hono-rpc'
|
|
1469
|
-
|
|
1470
|
-
// Hono Streaming
|
|
1471
|
-
import { HonoStreamAppBuilder, sse } from 'ts-procedures/hono-stream'
|
|
1448
|
+
import type { RPCConfig, RPCHttpRouteDoc, StreamHttpRouteDoc, StreamMode, HttpMethod } from 'ts-procedures/http'
|
|
1449
|
+
// Note: APIConfig and APIInput are removed in v8. Use CreateHttp with schema.req / schema.res instead.
|
|
1472
1450
|
|
|
1473
|
-
// Hono
|
|
1474
|
-
import {
|
|
1475
|
-
import type { APIConfig, APIHttpRouteDoc, APIInput, HttpMethod } from 'ts-procedures/hono-api'
|
|
1451
|
+
// Hono — single unified builder dispatches RPC, HTTP, and streaming kinds
|
|
1452
|
+
import { HonoAppBuilder, sse } from 'ts-procedures/hono'
|
|
1476
1453
|
|
|
1477
1454
|
// Client
|
|
1478
1455
|
import {
|