ts-procedures 8.6.0 → 9.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/CHANGELOG.md +540 -0
- package/README.md +166 -101
- package/agent_config/claude-code/.claude-plugin/plugin.json +1 -1
- package/agent_config/claude-code/agents/ts-procedures-architect.md +11 -10
- package/agent_config/claude-code/skills/ts-procedures/SKILL.md +25 -12
- package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +10 -12
- package/agent_config/claude-code/skills/ts-procedures/api-reference.md +141 -45
- package/agent_config/claude-code/skills/ts-procedures/checklist.md +7 -6
- package/agent_config/claude-code/skills/ts-procedures/patterns.md +45 -6
- package/agent_config/claude-code/skills/ts-procedures/templates/client.md +1 -1
- package/agent_config/claude-code/skills/ts-procedures/templates/hono.md +1 -1
- package/agent_config/copilot/copilot-instructions.md +50 -33
- package/agent_config/cursor/cursorrules +50 -33
- package/build/adapters/astro/astro-context.js.map +1 -0
- package/build/adapters/astro/create-handler.js.map +1 -0
- package/build/adapters/astro/index.js.map +1 -0
- package/build/{implementations/http → adapters}/astro/index.test.js +1 -1
- package/build/adapters/astro/index.test.js.map +1 -0
- package/build/adapters/astro/rewrite-request.js.map +1 -0
- package/build/adapters/hono/envelope-parity.test.js +98 -0
- package/build/adapters/hono/envelope-parity.test.js.map +1 -0
- package/build/{implementations/http → adapters}/hono/handlers/http-stream.d.ts +1 -1
- package/build/adapters/hono/handlers/http-stream.js +55 -0
- package/build/adapters/hono/handlers/http-stream.js.map +1 -0
- package/build/{implementations/http → adapters}/hono/handlers/http-stream.test.js +1 -1
- package/build/adapters/hono/handlers/http-stream.test.js.map +1 -0
- package/build/{implementations/http → adapters}/hono/handlers/http.d.ts +1 -1
- package/build/adapters/hono/handlers/http.js +50 -0
- package/build/adapters/hono/handlers/http.js.map +1 -0
- package/build/{implementations/http → adapters}/hono/handlers/http.test.js +1 -1
- package/build/adapters/hono/handlers/http.test.js.map +1 -0
- package/build/{implementations/http → adapters}/hono/handlers/rpc.d.ts +2 -2
- package/build/adapters/hono/handlers/rpc.js +23 -0
- package/build/adapters/hono/handlers/rpc.js.map +1 -0
- package/build/{implementations/http → adapters}/hono/handlers/rpc.test.js +1 -1
- package/build/adapters/hono/handlers/rpc.test.js.map +1 -0
- package/build/adapters/hono/handlers/stream.d.ts +12 -0
- package/build/adapters/hono/handlers/stream.js +89 -0
- package/build/adapters/hono/handlers/stream.js.map +1 -0
- package/build/{implementations/http → adapters}/hono/handlers/stream.test.js +3 -2
- package/build/adapters/hono/handlers/stream.test.js.map +1 -0
- package/build/{implementations/http → adapters}/hono/index.d.ts +24 -12
- package/build/{implementations/http → adapters}/hono/index.js +19 -8
- package/build/adapters/hono/index.js.map +1 -0
- package/build/{implementations/http → adapters}/hono/index.test.js +2 -4
- package/build/adapters/hono/index.test.js.map +1 -0
- package/build/{implementations/http → adapters/hono}/on-request-error.test.js +2 -2
- package/build/adapters/hono/on-request-error.test.js.map +1 -0
- package/build/adapters/hono/request.d.ts +7 -0
- package/build/adapters/hono/request.js +22 -0
- package/build/adapters/hono/request.js.map +1 -0
- package/build/{implementations/http → adapters/hono}/route-errors.test.js +4 -4
- package/build/adapters/hono/route-errors.test.js.map +1 -0
- package/build/adapters/hono/types.d.ts +55 -0
- package/build/adapters/hono/types.js +19 -0
- package/build/adapters/hono/types.js.map +1 -0
- package/build/client/freeze.test.js +39 -0
- package/build/client/freeze.test.js.map +1 -0
- package/build/client/typed-error-dispatch.test.js +2 -2
- package/build/client/typed-error-dispatch.test.js.map +1 -1
- package/build/codegen/__fixtures__/make-envelope.d.ts +1 -1
- package/build/codegen/bin/cli.d.ts +5 -0
- package/build/codegen/bin/cli.js +139 -182
- package/build/codegen/bin/cli.js.map +1 -1
- package/build/codegen/bin/cli.test.js +12 -2
- package/build/codegen/bin/cli.test.js.map +1 -1
- package/build/codegen/bin/flag-specs.d.ts +9 -0
- package/build/codegen/bin/flag-specs.js +33 -31
- package/build/codegen/bin/flag-specs.js.map +1 -1
- package/build/codegen/bin/flag-specs.test.js +14 -1
- package/build/codegen/bin/flag-specs.test.js.map +1 -1
- package/build/codegen/collect-models.d.ts +1 -1
- package/build/codegen/emit/api-route.d.ts +8 -0
- package/build/codegen/emit/api-route.js +156 -0
- package/build/codegen/emit/api-route.js.map +1 -0
- package/build/codegen/emit/context.d.ts +30 -0
- package/build/codegen/emit/context.js +2 -0
- package/build/codegen/emit/context.js.map +1 -0
- package/build/codegen/emit/declarations.d.ts +24 -0
- package/build/codegen/emit/declarations.js +48 -0
- package/build/codegen/emit/declarations.js.map +1 -0
- package/build/codegen/emit/format-types.d.ts +61 -0
- package/build/codegen/emit/format-types.js +188 -0
- package/build/codegen/emit/format-types.js.map +1 -0
- package/build/codegen/emit/http-stream-route.d.ts +7 -0
- package/build/codegen/emit/http-stream-route.js +138 -0
- package/build/codegen/emit/http-stream-route.js.map +1 -0
- package/build/codegen/emit/route-shared.d.ts +37 -0
- package/build/codegen/emit/route-shared.js +88 -0
- package/build/codegen/emit/route-shared.js.map +1 -0
- package/build/codegen/emit/rpc-route.d.ts +7 -0
- package/build/codegen/emit/rpc-route.js +37 -0
- package/build/codegen/emit/rpc-route.js.map +1 -0
- package/build/codegen/emit/scope-file.d.ts +39 -0
- package/build/codegen/emit/scope-file.js +166 -0
- package/build/codegen/emit/scope-file.js.map +1 -0
- package/build/codegen/emit/stream-route.d.ts +7 -0
- package/build/codegen/emit/stream-route.js +62 -0
- package/build/codegen/emit/stream-route.js.map +1 -0
- package/build/codegen/emit-errors.d.ts +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.d.ts +13 -30
- package/build/codegen/emit-scope.js +15 -844
- package/build/codegen/emit-scope.js.map +1 -1
- package/build/codegen/emit-scope.test.js +67 -0
- package/build/codegen/emit-scope.test.js.map +1 -1
- package/build/codegen/goldens.test.js +69 -0
- package/build/codegen/goldens.test.js.map +1 -0
- package/build/codegen/group-routes.d.ts +1 -1
- package/build/codegen/pipeline.d.ts +1 -1
- package/build/codegen/resolve-envelope.d.ts +1 -1
- package/build/codegen/targets/_shared/error-schemas.d.ts +1 -1
- package/build/codegen/targets/_shared/route-slots.d.ts +1 -1
- package/build/codegen/targets/_shared/target-run.d.ts +1 -1
- package/build/codegen/targets/kotlin/emit-route-kotlin.d.ts +1 -1
- package/build/codegen/targets/swift/emit-route-swift.d.ts +1 -1
- package/build/core/create-http-stream.d.ts +50 -0
- package/build/core/create-http-stream.js +108 -0
- package/build/core/create-http-stream.js.map +1 -0
- package/build/{create-http-stream.test.js → core/create-http-stream.test.js} +1 -1
- package/build/core/create-http-stream.test.js.map +1 -0
- package/build/core/create-http.d.ts +51 -0
- package/build/core/create-http.js +65 -0
- package/build/core/create-http.js.map +1 -0
- package/build/{create-http.test.js → core/create-http.test.js} +27 -4
- package/build/core/create-http.test.js.map +1 -0
- package/build/core/create-stream.d.ts +26 -0
- package/build/core/create-stream.js +80 -0
- package/build/core/create-stream.js.map +1 -0
- package/build/{create-stream.test.js → core/create-stream.test.js} +23 -28
- package/build/core/create-stream.test.js.map +1 -0
- package/build/core/create.d.ts +22 -0
- package/build/core/create.js +71 -0
- package/build/core/create.js.map +1 -0
- package/build/{create.test.js → core/create.test.js} +25 -46
- package/build/core/create.test.js.map +1 -0
- package/build/core/definition-site.d.ts +24 -0
- package/build/{stack-utils.js → core/definition-site.js} +20 -20
- package/build/core/definition-site.js.map +1 -0
- package/build/{stack-utils.test.js → core/definition-site.test.js} +12 -3
- package/build/core/definition-site.test.js.map +1 -0
- package/build/{errors.d.ts → core/errors.d.ts} +19 -8
- package/build/{errors.js → core/errors.js} +21 -26
- package/build/core/errors.js.map +1 -0
- package/build/core/errors.test.js.map +1 -0
- package/build/core/factory-options.test.js +82 -0
- package/build/core/factory-options.test.js.map +1 -0
- package/build/core/http-route.d.ts +13 -0
- package/build/core/http-route.js +54 -0
- package/build/core/http-route.js.map +1 -0
- package/build/core/internal.d.ts +72 -0
- package/build/core/internal.js +128 -0
- package/build/core/internal.js.map +1 -0
- package/build/{migration.test.js → core/migration.test.js} +17 -1
- package/build/core/migration.test.js.map +1 -0
- package/build/core/procedures.d.ts +143 -0
- package/build/core/procedures.js +64 -0
- package/build/core/procedures.js.map +1 -0
- package/build/{index.test.js → core/procedures.test.js} +14 -11
- package/build/core/procedures.test.js.map +1 -0
- package/build/core/types.d.ts +183 -0
- package/build/{schema → core}/types.js.map +1 -1
- package/build/exports.d.ts +31 -11
- package/build/exports.js +23 -8
- package/build/exports.js.map +1 -1
- package/build/schema/adapter.d.ts +35 -0
- package/build/schema/adapter.js +13 -0
- package/build/schema/adapter.js.map +1 -0
- package/build/schema/adapter.test.js +53 -0
- package/build/schema/adapter.test.js.map +1 -0
- package/build/schema/compile.d.ts +37 -0
- package/build/schema/compile.js +38 -0
- package/build/schema/compile.js.map +1 -0
- package/build/schema/compile.test.js +78 -0
- package/build/schema/compile.test.js.map +1 -0
- package/build/schema/compute-schema.d.ts +47 -37
- package/build/schema/compute-schema.js +86 -29
- package/build/schema/compute-schema.js.map +1 -1
- package/build/schema/compute-schema.test.js +158 -40
- package/build/schema/compute-schema.test.js.map +1 -1
- package/build/schema/json-schema.d.ts +17 -0
- package/build/schema/json-schema.js +2 -0
- package/build/schema/json-schema.js.map +1 -0
- package/build/schema/typebox.d.ts +11 -0
- package/build/schema/typebox.js +24 -0
- package/build/schema/typebox.js.map +1 -0
- package/build/schema/typebox.test.js +34 -0
- package/build/schema/typebox.test.js.map +1 -0
- package/build/server/context.d.ts +8 -0
- package/build/server/context.js +7 -0
- package/build/server/context.js.map +1 -0
- package/build/server/context.test.js +16 -0
- package/build/server/context.test.js.map +1 -0
- package/build/{doc-envelope.d.ts → server/doc-envelope.d.ts} +1 -1
- package/build/server/doc-envelope.js.map +1 -0
- package/build/server/doc-envelope.test.d.ts +1 -0
- package/build/server/doc-envelope.test.js.map +1 -0
- package/build/{implementations/http → server}/doc-registry.d.ts +7 -2
- package/build/{implementations/http → server}/doc-registry.js +9 -5
- package/build/server/doc-registry.js.map +1 -0
- package/build/server/doc-registry.test.d.ts +1 -0
- package/build/{implementations/http → server}/doc-registry.test.js +27 -24
- package/build/server/doc-registry.test.js.map +1 -0
- package/build/server/docs/docs.test.d.ts +1 -0
- package/build/server/docs/docs.test.js +237 -0
- package/build/server/docs/docs.test.js.map +1 -0
- package/build/{implementations/http/hono → server}/docs/http-doc.d.ts +2 -2
- package/build/{implementations/http/hono → server}/docs/http-doc.js +1 -1
- package/build/server/docs/http-doc.js.map +1 -0
- package/build/{implementations/http/hono → server}/docs/http-stream-doc.d.ts +2 -2
- package/build/{implementations/http/hono → server}/docs/http-stream-doc.js +1 -1
- package/build/server/docs/http-stream-doc.js.map +1 -0
- package/build/{implementations/http/hono → server}/docs/rpc-doc.d.ts +2 -2
- package/build/{implementations/http/hono → server}/docs/rpc-doc.js +1 -1
- package/build/server/docs/rpc-doc.js.map +1 -0
- package/build/{implementations/http/hono → server}/docs/stream-doc.d.ts +2 -2
- package/build/{implementations/http/hono → server}/docs/stream-doc.js +1 -1
- package/build/server/docs/stream-doc.js.map +1 -0
- package/build/server/errors/dispatch.d.ts +96 -0
- package/build/{implementations/http/error-dispatch.js → server/errors/dispatch.js} +20 -10
- package/build/server/errors/dispatch.js.map +1 -0
- package/build/server/errors/dispatch.test.d.ts +1 -0
- package/build/server/errors/dispatch.test.js +418 -0
- package/build/server/errors/dispatch.test.js.map +1 -0
- package/build/{implementations/http/error-taxonomy.d.ts → server/errors/taxonomy.d.ts} +8 -17
- package/build/{implementations/http/error-taxonomy.js → server/errors/taxonomy.js} +6 -15
- package/build/server/errors/taxonomy.js.map +1 -0
- package/build/server/errors/taxonomy.test.d.ts +1 -0
- package/build/{implementations/http/error-taxonomy.test.js → server/errors/taxonomy.test.js} +45 -39
- package/build/server/errors/taxonomy.test.js.map +1 -0
- package/build/server/index.d.ts +29 -0
- package/build/server/index.js +27 -0
- package/build/server/index.js.map +1 -0
- package/build/server/no-framework-imports.test.d.ts +1 -0
- package/build/server/no-framework-imports.test.js +40 -0
- package/build/server/no-framework-imports.test.js.map +1 -0
- package/build/{implementations/http/hono/path.d.ts → server/paths.d.ts} +2 -3
- package/build/{implementations/http/hono/path.js → server/paths.js} +1 -1
- package/build/server/paths.js.map +1 -0
- package/build/server/paths.test.d.ts +1 -0
- package/build/server/paths.test.js +111 -0
- package/build/server/paths.test.js.map +1 -0
- package/build/server/request/params.d.ts +29 -0
- package/build/server/request/params.js +43 -0
- package/build/server/request/params.js.map +1 -0
- package/build/server/request/params.test.d.ts +1 -0
- package/build/server/request/params.test.js +91 -0
- package/build/server/request/params.test.js.map +1 -0
- package/build/server/request/query.d.ts +9 -0
- package/build/server/request/query.js +22 -0
- package/build/server/request/query.js.map +1 -0
- package/build/server/request/query.test.d.ts +1 -0
- package/build/server/request/query.test.js +60 -0
- package/build/server/request/query.test.js.map +1 -0
- package/build/server/sse.d.ts +70 -0
- package/build/server/sse.js +94 -0
- package/build/server/sse.js.map +1 -0
- package/build/server/sse.test.d.ts +1 -0
- package/build/server/sse.test.js +98 -0
- package/build/server/sse.test.js.map +1 -0
- package/build/{implementations → server}/types.d.ts +17 -15
- package/build/{implementations → server}/types.js.map +1 -1
- package/docs/astro-adapter.md +8 -9
- package/docs/client-and-codegen.md +10 -4
- package/docs/client-error-handling.md +5 -5
- package/docs/codegen-kotlin.md +2 -3
- package/docs/codegen-swift.md +1 -2
- package/docs/core.md +135 -54
- package/docs/http-integrations.md +58 -6
- package/docs/migration-v8-to-v9.md +200 -0
- package/docs/plans/2026-06-09-v9-rewrite.md +130 -0
- package/docs/specs/2026-06-09-v9-rewrite-design.md +221 -0
- package/docs/streaming.md +12 -0
- package/package.json +25 -48
- package/src/{implementations/http → adapters}/astro/index.test.ts +2 -2
- package/src/adapters/hono/__fixtures__/parity-envelope.json +389 -0
- package/src/adapters/hono/envelope-parity.test.ts +126 -0
- package/src/{implementations/http → adapters}/hono/handlers/http-stream.test.ts +1 -1
- package/src/adapters/hono/handlers/http-stream.ts +73 -0
- package/src/{implementations/http → adapters}/hono/handlers/http.test.ts +1 -1
- package/src/adapters/hono/handlers/http.ts +70 -0
- package/src/{implementations/http → adapters}/hono/handlers/rpc.test.ts +2 -2
- package/src/adapters/hono/handlers/rpc.ts +39 -0
- package/src/{implementations/http → adapters}/hono/handlers/stream.test.ts +4 -3
- package/src/{implementations/http → adapters}/hono/handlers/stream.ts +19 -92
- package/src/{implementations/http → adapters}/hono/index.test.ts +14 -16
- package/src/{implementations/http → adapters}/hono/index.ts +35 -30
- package/src/{implementations/http → adapters/hono}/on-request-error.test.ts +3 -3
- package/src/adapters/hono/request.ts +28 -0
- package/src/{implementations/http → adapters/hono}/route-errors.test.ts +5 -5
- package/src/{implementations/http → adapters}/hono/types.ts +43 -20
- package/src/client/freeze.test.ts +41 -0
- package/src/client/typed-error-dispatch.test.ts +3 -3
- package/src/codegen/__fixtures__/make-envelope.ts +1 -1
- package/src/codegen/__fixtures__/models-envelope.json +310 -0
- package/src/codegen/__goldens__/MANIFEST.json +85 -0
- package/src/codegen/__goldens__/kotlin-default--models/Billing.kt +112 -0
- package/src/codegen/__goldens__/kotlin-default--models/BillingReports.kt +26 -0
- package/src/codegen/__goldens__/kotlin-default--models/Orders.kt +88 -0
- package/src/codegen/__goldens__/kotlin-default--users/Users.kt +189 -0
- package/src/codegen/__goldens__/swift-default--models/Billing.swift +97 -0
- package/src/codegen/__goldens__/swift-default--models/BillingReports.swift +20 -0
- package/src/codegen/__goldens__/swift-default--models/Orders.swift +81 -0
- package/src/codegen/__goldens__/swift-default--users/Users.swift +204 -0
- package/src/codegen/__goldens__/ts-default--models/_client.ts +1319 -0
- package/src/codegen/__goldens__/ts-default--models/_errors.ts +90 -0
- package/src/codegen/__goldens__/ts-default--models/_models.ts +10 -0
- package/src/codegen/__goldens__/ts-default--models/_types.ts +502 -0
- package/src/codegen/__goldens__/ts-default--models/billing-reports.ts +29 -0
- package/src/codegen/__goldens__/ts-default--models/billing.ts +67 -0
- package/src/codegen/__goldens__/ts-default--models/index.ts +48 -0
- package/src/codegen/__goldens__/ts-default--models/orders.ts +80 -0
- package/src/codegen/__goldens__/ts-default--users/_client.ts +1319 -0
- package/src/codegen/__goldens__/ts-default--users/_errors.ts +90 -0
- package/src/codegen/__goldens__/ts-default--users/_types.ts +502 -0
- package/src/codegen/__goldens__/ts-default--users/index.ts +38 -0
- package/src/codegen/__goldens__/ts-default--users/users.ts +169 -0
- package/src/codegen/__goldens__/ts-external-runtime--models/_errors.ts +90 -0
- package/src/codegen/__goldens__/ts-external-runtime--models/_models.ts +10 -0
- package/src/codegen/__goldens__/ts-external-runtime--models/billing-reports.ts +29 -0
- package/src/codegen/__goldens__/ts-external-runtime--models/billing.ts +67 -0
- package/src/codegen/__goldens__/ts-external-runtime--models/index.ts +48 -0
- package/src/codegen/__goldens__/ts-external-runtime--models/orders.ts +80 -0
- package/src/codegen/__goldens__/ts-external-runtime--users/_errors.ts +90 -0
- package/src/codegen/__goldens__/ts-external-runtime--users/index.ts +38 -0
- package/src/codegen/__goldens__/ts-external-runtime--users/users.ts +169 -0
- package/src/codegen/__goldens__/ts-flat--models/_client.ts +1319 -0
- package/src/codegen/__goldens__/ts-flat--models/_errors.ts +87 -0
- package/src/codegen/__goldens__/ts-flat--models/_models.ts +10 -0
- package/src/codegen/__goldens__/ts-flat--models/_types.ts +502 -0
- package/src/codegen/__goldens__/ts-flat--models/billing-reports.ts +28 -0
- package/src/codegen/__goldens__/ts-flat--models/billing.ts +51 -0
- package/src/codegen/__goldens__/ts-flat--models/index.ts +42 -0
- package/src/codegen/__goldens__/ts-flat--models/orders.ts +73 -0
- package/src/codegen/__goldens__/ts-flat--users/_client.ts +1319 -0
- package/src/codegen/__goldens__/ts-flat--users/_errors.ts +87 -0
- package/src/codegen/__goldens__/ts-flat--users/_types.ts +502 -0
- package/src/codegen/__goldens__/ts-flat--users/index.ts +34 -0
- package/src/codegen/__goldens__/ts-flat--users/users.ts +126 -0
- package/src/codegen/__goldens__/ts-no-share-models--models/_client.ts +1319 -0
- package/src/codegen/__goldens__/ts-no-share-models--models/_errors.ts +90 -0
- package/src/codegen/__goldens__/ts-no-share-models--models/_types.ts +502 -0
- package/src/codegen/__goldens__/ts-no-share-models--models/billing-reports.ts +29 -0
- package/src/codegen/__goldens__/ts-no-share-models--models/billing.ts +111 -0
- package/src/codegen/__goldens__/ts-no-share-models--models/index.ts +48 -0
- package/src/codegen/__goldens__/ts-no-share-models--models/orders.ts +112 -0
- package/src/codegen/__goldens__/ts-no-share-models--users/_client.ts +1319 -0
- package/src/codegen/__goldens__/ts-no-share-models--users/_errors.ts +90 -0
- package/src/codegen/__goldens__/ts-no-share-models--users/_types.ts +502 -0
- package/src/codegen/__goldens__/ts-no-share-models--users/index.ts +38 -0
- package/src/codegen/__goldens__/ts-no-share-models--users/users.ts +169 -0
- package/src/codegen/__goldens__/ts-shared-models-module--models/_client.ts +1319 -0
- package/src/codegen/__goldens__/ts-shared-models-module--models/_errors.ts +90 -0
- package/src/codegen/__goldens__/ts-shared-models-module--models/_models.ts +7 -0
- package/src/codegen/__goldens__/ts-shared-models-module--models/_types.ts +502 -0
- package/src/codegen/__goldens__/ts-shared-models-module--models/billing-reports.ts +29 -0
- package/src/codegen/__goldens__/ts-shared-models-module--models/billing.ts +67 -0
- package/src/codegen/__goldens__/ts-shared-models-module--models/index.ts +48 -0
- package/src/codegen/__goldens__/ts-shared-models-module--models/orders.ts +80 -0
- package/src/codegen/bin/cli.test.ts +13 -2
- package/src/codegen/bin/cli.ts +181 -144
- package/src/codegen/bin/flag-specs.test.ts +16 -1
- package/src/codegen/bin/flag-specs.ts +43 -31
- package/src/codegen/bundle-size.test.ts +1 -1
- package/src/codegen/collect-models.ts +1 -1
- package/src/codegen/e2e.test.ts +1 -1
- package/src/codegen/emit/api-route.ts +184 -0
- package/src/codegen/emit/context.ts +32 -0
- package/src/codegen/emit/declarations.ts +49 -0
- package/src/codegen/emit/format-types.ts +232 -0
- package/src/codegen/emit/http-stream-route.ts +162 -0
- package/src/codegen/emit/route-shared.ts +104 -0
- package/src/codegen/emit/rpc-route.ts +49 -0
- package/src/codegen/emit/scope-file.ts +226 -0
- package/src/codegen/emit/stream-route.ts +81 -0
- package/src/codegen/emit-errors.integration.test.ts +2 -2
- package/src/codegen/emit-errors.test.ts +1 -1
- package/src/codegen/emit-errors.ts +1 -1
- package/src/codegen/emit-scope.test.ts +75 -2
- package/src/codegen/emit-scope.ts +15 -1048
- package/src/codegen/goldens.test.ts +89 -0
- package/src/codegen/group-routes.test.ts +1 -1
- package/src/codegen/group-routes.ts +1 -1
- package/src/codegen/pipeline.test.ts +1 -1
- package/src/codegen/pipeline.ts +1 -1
- package/src/codegen/resolve-envelope.test.ts +1 -1
- package/src/codegen/resolve-envelope.ts +1 -1
- package/src/codegen/targets/_shared/error-schemas.test.ts +1 -1
- package/src/codegen/targets/_shared/error-schemas.ts +1 -1
- package/src/codegen/targets/_shared/route-slots.test.ts +1 -1
- package/src/codegen/targets/_shared/route-slots.ts +1 -1
- package/src/codegen/targets/_shared/target-run.ts +1 -1
- package/src/codegen/targets/kotlin/emit-route-kotlin.test.ts +1 -1
- package/src/codegen/targets/kotlin/emit-route-kotlin.ts +1 -1
- package/src/codegen/targets/kotlin/emit-scope-kotlin.test.ts +1 -1
- package/src/codegen/targets/swift/access-level.test.ts +1 -1
- package/src/codegen/targets/swift/emit-route-swift.test.ts +1 -1
- package/src/codegen/targets/swift/emit-route-swift.ts +1 -1
- package/src/codegen/targets/swift/emit-scope-swift.test.ts +1 -1
- package/src/codegen/targets/ts/shared-models.test.ts +1 -1
- package/src/{create-http-stream.test.ts → core/create-http-stream.test.ts} +1 -1
- package/src/core/create-http-stream.ts +207 -0
- package/src/{create-http.test.ts → core/create-http.test.ts} +31 -4
- package/src/core/create-http.ts +126 -0
- package/src/{create-stream.test.ts → core/create-stream.test.ts} +28 -31
- package/src/core/create-stream.ts +142 -0
- package/src/{create.test.ts → core/create.test.ts} +25 -57
- package/src/core/create.ts +121 -0
- package/src/{stack-utils.test.ts → core/definition-site.test.ts} +14 -3
- package/src/{stack-utils.ts → core/definition-site.ts} +20 -23
- package/src/{errors.test.ts → core/errors.test.ts} +1 -1
- package/src/{errors.ts → core/errors.ts} +30 -28
- package/src/core/factory-options.test.ts +112 -0
- package/src/core/http-route.ts +73 -0
- package/src/core/internal.ts +203 -0
- package/src/{migration.test.ts → core/migration.test.ts} +23 -1
- package/src/{index.test.ts → core/procedures.test.ts} +13 -11
- package/src/core/procedures.ts +75 -0
- package/src/core/types.ts +196 -0
- package/src/exports.ts +60 -11
- package/src/schema/adapter.test.ts +58 -0
- package/src/schema/adapter.ts +45 -0
- package/src/schema/compile.test.ts +95 -0
- package/src/schema/compile.ts +64 -0
- package/src/schema/compute-schema.test.ts +222 -41
- package/src/schema/compute-schema.ts +145 -71
- package/src/schema/json-schema.ts +21 -0
- package/src/schema/typebox.test.ts +40 -0
- package/src/schema/typebox.ts +27 -0
- package/src/server/context.test.ts +22 -0
- package/src/server/context.ts +18 -0
- package/src/{doc-envelope.test.ts → server/doc-envelope.test.ts} +2 -2
- package/src/{doc-envelope.ts → server/doc-envelope.ts} +1 -1
- package/src/{implementations/http → server}/doc-registry.test.ts +32 -26
- package/src/{implementations/http → server}/doc-registry.ts +11 -7
- package/src/server/docs/docs.test.ts +287 -0
- package/src/{implementations/http/hono → server}/docs/http-doc.ts +3 -3
- package/src/{implementations/http/hono → server}/docs/http-stream-doc.ts +3 -3
- package/src/{implementations/http/hono → server}/docs/rpc-doc.ts +3 -3
- package/src/{implementations/http/hono → server}/docs/stream-doc.ts +3 -3
- package/src/server/errors/dispatch.test.ts +450 -0
- package/src/server/errors/dispatch.ts +189 -0
- package/src/{implementations/http/error-taxonomy.test.ts → server/errors/taxonomy.test.ts} +45 -39
- package/src/{implementations/http/error-taxonomy.ts → server/errors/taxonomy.ts} +8 -17
- package/src/server/index.ts +29 -0
- package/src/server/no-framework-imports.test.ts +43 -0
- package/src/server/paths.test.ts +141 -0
- package/src/{implementations/http/hono/path.ts → server/paths.ts} +2 -13
- package/src/server/request/params.test.ts +143 -0
- package/src/server/request/params.ts +68 -0
- package/src/server/request/query.test.ts +70 -0
- package/src/server/request/query.ts +24 -0
- package/src/server/sse.test.ts +113 -0
- package/src/server/sse.ts +117 -0
- package/src/{implementations → server}/types.ts +17 -16
- package/build/create-http-stream.d.ts +0 -58
- package/build/create-http-stream.js +0 -122
- package/build/create-http-stream.js.map +0 -1
- package/build/create-http-stream.test.js.map +0 -1
- package/build/create-http.d.ts +0 -49
- package/build/create-http.js +0 -108
- package/build/create-http.js.map +0 -1
- package/build/create-http.test.js.map +0 -1
- package/build/create-stream.d.ts +0 -35
- package/build/create-stream.js +0 -123
- package/build/create-stream.js.map +0 -1
- package/build/create-stream.test.js.map +0 -1
- package/build/create.d.ts +0 -28
- package/build/create.js +0 -82
- package/build/create.js.map +0 -1
- package/build/create.test.js.map +0 -1
- package/build/doc-envelope.js.map +0 -1
- package/build/doc-envelope.test.js.map +0 -1
- package/build/errors.js.map +0 -1
- package/build/errors.test.js.map +0 -1
- package/build/implementations/http/astro/astro-context.js.map +0 -1
- package/build/implementations/http/astro/create-handler.js.map +0 -1
- package/build/implementations/http/astro/index.js.map +0 -1
- package/build/implementations/http/astro/index.test.js.map +0 -1
- package/build/implementations/http/astro/rewrite-request.js.map +0 -1
- package/build/implementations/http/doc-registry.js.map +0 -1
- package/build/implementations/http/doc-registry.test.js.map +0 -1
- package/build/implementations/http/error-dispatch.d.ts +0 -76
- package/build/implementations/http/error-dispatch.js.map +0 -1
- package/build/implementations/http/error-dispatch.test.js +0 -254
- package/build/implementations/http/error-dispatch.test.js.map +0 -1
- package/build/implementations/http/error-taxonomy.js.map +0 -1
- package/build/implementations/http/error-taxonomy.test.js.map +0 -1
- package/build/implementations/http/hono/docs/http-doc.js.map +0 -1
- package/build/implementations/http/hono/docs/http-stream-doc.js.map +0 -1
- package/build/implementations/http/hono/docs/rpc-doc.js.map +0 -1
- package/build/implementations/http/hono/docs/stream-doc.js.map +0 -1
- package/build/implementations/http/hono/handlers/http-stream.js +0 -123
- package/build/implementations/http/hono/handlers/http-stream.js.map +0 -1
- package/build/implementations/http/hono/handlers/http-stream.test.js.map +0 -1
- package/build/implementations/http/hono/handlers/http.js +0 -110
- package/build/implementations/http/hono/handlers/http.js.map +0 -1
- package/build/implementations/http/hono/handlers/http.test.js.map +0 -1
- package/build/implementations/http/hono/handlers/rpc.js +0 -32
- package/build/implementations/http/hono/handlers/rpc.js.map +0 -1
- package/build/implementations/http/hono/handlers/rpc.test.js.map +0 -1
- package/build/implementations/http/hono/handlers/stream.d.ts +0 -23
- package/build/implementations/http/hono/handlers/stream.js +0 -147
- package/build/implementations/http/hono/handlers/stream.js.map +0 -1
- package/build/implementations/http/hono/handlers/stream.test.js.map +0 -1
- package/build/implementations/http/hono/index.js.map +0 -1
- package/build/implementations/http/hono/index.test.js.map +0 -1
- package/build/implementations/http/hono/path.js.map +0 -1
- package/build/implementations/http/hono/path.test.js +0 -83
- package/build/implementations/http/hono/path.test.js.map +0 -1
- package/build/implementations/http/hono/types.d.ts +0 -51
- package/build/implementations/http/hono/types.js.map +0 -1
- package/build/implementations/http/on-request-error.test.js.map +0 -1
- package/build/implementations/http/route-errors.test.js.map +0 -1
- package/build/index.d.ts +0 -175
- package/build/index.js +0 -47
- package/build/index.js.map +0 -1
- package/build/index.test.js.map +0 -1
- package/build/migration.test.js.map +0 -1
- package/build/schema/extract-json-schema.d.ts +0 -2
- package/build/schema/extract-json-schema.js +0 -12
- package/build/schema/extract-json-schema.js.map +0 -1
- package/build/schema/extract-json-schema.test.js +0 -23
- package/build/schema/extract-json-schema.test.js.map +0 -1
- package/build/schema/parser.d.ts +0 -36
- package/build/schema/parser.js +0 -210
- package/build/schema/parser.js.map +0 -1
- package/build/schema/parser.test.js +0 -120
- package/build/schema/parser.test.js.map +0 -1
- package/build/schema/resolve-schema-lib.d.ts +0 -12
- package/build/schema/resolve-schema-lib.js +0 -11
- package/build/schema/resolve-schema-lib.js.map +0 -1
- package/build/schema/resolve-schema-lib.test.js +0 -17
- package/build/schema/resolve-schema-lib.test.js.map +0 -1
- package/build/schema/types.d.ts +0 -8
- package/build/schema/types.js +0 -2
- package/build/stack-utils.d.ts +0 -25
- package/build/stack-utils.js.map +0 -1
- package/build/stack-utils.test.js.map +0 -1
- package/build/types.d.ts +0 -142
- package/build/types.js +0 -2
- package/build/types.js.map +0 -1
- package/docs/decisions/2026-06-02-monorepo-split-evaluation.md +0 -80
- package/docs/handoffs/2026-06-08-dx-round2-declines.md +0 -45
- package/docs/handoffs/ajsc-named-type-collision.md +0 -134
- package/docs/handoffs/ajsc-named-type-support.md +0 -181
- package/docs/handoffs/shared-models-auto-resolve-response.md +0 -181
- package/docs/npm-workspaces-migration-plan.md +0 -611
- package/docs/superpowers/plans/2026-04-24-doc-registry-simplification.md +0 -886
- package/docs/superpowers/plans/2026-04-24-kotlin-codegen-target.md +0 -1265
- package/docs/superpowers/plans/2026-04-25-ajsc-v7-kotlin-polish.md +0 -1993
- package/docs/superpowers/plans/2026-04-29-safe-result-api.md +0 -2293
- package/docs/superpowers/plans/2026-05-07-astro-adapter.md +0 -1391
- package/docs/superpowers/plans/2026-05-08-create-http.md +0 -3355
- package/docs/superpowers/plans/2026-05-08-hono-app-builder-convergence.md +0 -3365
- package/docs/superpowers/plans/2026-06-05-dx-feedback-round.md +0 -1292
- package/docs/superpowers/plans/2026-06-06-shared-models-convention-and-diagnostics.md +0 -659
- package/docs/superpowers/plans/2026-06-08-codegen-dx-surfacing.md +0 -428
- package/docs/superpowers/specs/2026-04-24-kotlin-swift-codegen-design.md +0 -401
- package/docs/superpowers/specs/2026-04-25-ajsc-v7-kotlin-polish-design.md +0 -314
- package/docs/superpowers/specs/2026-04-25-swift-codegen-design.md +0 -264
- package/docs/superpowers/specs/2026-04-29-safe-result-api-design.md +0 -324
- package/docs/superpowers/specs/2026-05-07-astro-adapter-design.md +0 -252
- package/docs/superpowers/specs/2026-05-08-create-http-design.md +0 -409
- package/docs/superpowers/specs/2026-05-08-hono-app-builder-convergence-design.md +0 -411
- package/docs/superpowers/specs/2026-06-05-dx-feedback-round-design.md +0 -285
- package/docs/superpowers/specs/2026-06-08-dx-feedback-round-2-design.md +0 -376
- package/src/create-http-stream.ts +0 -191
- package/src/create-http.ts +0 -210
- package/src/create-stream.ts +0 -228
- package/src/create.ts +0 -172
- package/src/implementations/http/README.md +0 -390
- package/src/implementations/http/error-dispatch.test.ts +0 -283
- package/src/implementations/http/error-dispatch.ts +0 -176
- package/src/implementations/http/hono/handlers/http-stream.ts +0 -152
- package/src/implementations/http/hono/handlers/http.ts +0 -145
- package/src/implementations/http/hono/handlers/rpc.ts +0 -54
- package/src/implementations/http/hono/path.test.ts +0 -96
- package/src/index.ts +0 -101
- package/src/schema/extract-json-schema.test.ts +0 -25
- package/src/schema/extract-json-schema.ts +0 -15
- package/src/schema/parser.test.ts +0 -182
- package/src/schema/parser.ts +0 -265
- package/src/schema/resolve-schema-lib.test.ts +0 -19
- package/src/schema/resolve-schema-lib.ts +0 -29
- package/src/schema/types.ts +0 -20
- package/src/types.ts +0 -133
- /package/build/{implementations/http → adapters}/astro/astro-context.d.ts +0 -0
- /package/build/{implementations/http → adapters}/astro/astro-context.js +0 -0
- /package/build/{implementations/http → adapters}/astro/create-handler.d.ts +0 -0
- /package/build/{implementations/http → adapters}/astro/create-handler.js +0 -0
- /package/build/{implementations/http → adapters}/astro/index.d.ts +0 -0
- /package/build/{implementations/http → adapters}/astro/index.js +0 -0
- /package/build/{implementations/http → adapters}/astro/index.test.d.ts +0 -0
- /package/build/{implementations/http → adapters}/astro/rewrite-request.d.ts +0 -0
- /package/build/{implementations/http → adapters}/astro/rewrite-request.js +0 -0
- /package/build/{create-http-stream.test.d.ts → adapters/hono/envelope-parity.test.d.ts} +0 -0
- /package/build/{implementations/http → adapters}/hono/handlers/http-stream.test.d.ts +0 -0
- /package/build/{implementations/http → adapters}/hono/handlers/http.test.d.ts +0 -0
- /package/build/{implementations/http → adapters}/hono/handlers/rpc.test.d.ts +0 -0
- /package/build/{implementations/http → adapters}/hono/handlers/stream.test.d.ts +0 -0
- /package/build/{implementations/http → adapters}/hono/index.test.d.ts +0 -0
- /package/build/{implementations/http → adapters/hono}/on-request-error.test.d.ts +0 -0
- /package/build/{implementations/http → adapters/hono}/route-errors.test.d.ts +0 -0
- /package/build/{create-http.test.d.ts → client/freeze.test.d.ts} +0 -0
- /package/build/{create-stream.test.d.ts → codegen/goldens.test.d.ts} +0 -0
- /package/build/{create.test.d.ts → core/create-http-stream.test.d.ts} +0 -0
- /package/build/{doc-envelope.test.d.ts → core/create-http.test.d.ts} +0 -0
- /package/build/{errors.test.d.ts → core/create-stream.test.d.ts} +0 -0
- /package/build/{implementations/http/doc-registry.test.d.ts → core/create.test.d.ts} +0 -0
- /package/build/{implementations/http/error-dispatch.test.d.ts → core/definition-site.test.d.ts} +0 -0
- /package/build/{implementations/http/error-taxonomy.test.d.ts → core/errors.test.d.ts} +0 -0
- /package/build/{errors.test.js → core/errors.test.js} +0 -0
- /package/build/{implementations/http/hono/path.test.d.ts → core/factory-options.test.d.ts} +0 -0
- /package/build/{migration.test.d.ts → core/migration.test.d.ts} +0 -0
- /package/build/{index.test.d.ts → core/procedures.test.d.ts} +0 -0
- /package/build/{implementations/http/hono → core}/types.js +0 -0
- /package/build/schema/{extract-json-schema.test.d.ts → adapter.test.d.ts} +0 -0
- /package/build/schema/{parser.test.d.ts → compile.test.d.ts} +0 -0
- /package/build/schema/{resolve-schema-lib.test.d.ts → typebox.test.d.ts} +0 -0
- /package/build/{stack-utils.test.d.ts → server/context.test.d.ts} +0 -0
- /package/build/{doc-envelope.js → server/doc-envelope.js} +0 -0
- /package/build/{doc-envelope.test.js → server/doc-envelope.test.js} +0 -0
- /package/build/{implementations → server}/types.js +0 -0
- /package/src/{implementations/http → adapters}/astro/README.md +0 -0
- /package/src/{implementations/http → adapters}/astro/astro-context.ts +0 -0
- /package/src/{implementations/http → adapters}/astro/create-handler.ts +0 -0
- /package/src/{implementations/http → adapters}/astro/index.ts +0 -0
- /package/src/{implementations/http → adapters}/astro/rewrite-request.ts +0 -0
|
@@ -10,7 +10,7 @@ ts-procedures can generate type-safe client SDKs directly from your server's `Do
|
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
|
-
**Step 1 — Serve your docs endpoint** (see [DocRegistry](./http-integrations.md#docregistry--composing-docs
|
|
13
|
+
**Step 1 — Serve your docs endpoint** (see [DocRegistry](./http-integrations.md#docregistry--composing-docs) for setup):
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
16
|
app.get('/docs', (c) => c.json(docs.toJSON()))
|
|
@@ -43,6 +43,10 @@ const api = createApiClient({
|
|
|
43
43
|
|
|
44
44
|
> **Note:** `basePath` must be the **origin only** (e.g. `http://localhost:3000`), not `http://localhost:3000/api`. Generated client paths already include the server's `pathPrefix` (e.g. `/api/...`), so putting the prefix in `basePath` too doubles it up to `/api/api/...`.
|
|
45
45
|
|
|
46
|
+
> **Browser + cross-origin basePath = CORS.** If the client runs in a browser on a different origin than `basePath` (e.g. Vite on `:5173`, API on `:3000`), the browser blocks every request unless the server sends CORS headers — and the failure is the generic `Failed to fetch`, not a CORS-specific error. For dev setups, the usual fix is a same-origin dev proxy (e.g. Vite's `server.proxy['/api'] → http://localhost:3000`) with an **empty** `basePath` — the generated route paths already carry the `/api/...` prefix, so the proxy match comes for free. Reserve an absolute `basePath` for genuinely separate origins, which then need server-side CORS.
|
|
47
|
+
|
|
48
|
+
> **Auth seams differ by transport.** The HTTP client's per-request hook (the `Authorization` header set in `onBeforeRequest` above) re-reads the token on every call, so rotation is automatic. A WebSocket transport can't set custom handshake headers from a browser, so realtime libraries (e.g. ts-channels) typically take the token as a `?token=` URL query fixed at client construction — rotating it means rebuilding that client. If you wire both transports, expect to inject the same session token through these two different seams.
|
|
49
|
+
|
|
46
50
|
```typescript
|
|
47
51
|
try {
|
|
48
52
|
const user = await api.users.GetUser({ pathParams: { id: '123' } })
|
|
@@ -267,7 +271,7 @@ const client = createClient({
|
|
|
267
271
|
})
|
|
268
272
|
```
|
|
269
273
|
|
|
270
|
-
The function form works everywhere a `headers` record does — client `defaults.headers` and per-call `options.headers` — and the same precedence applies: per-call headers (function or record) win over default headers, and route-declared headers from `schema.
|
|
274
|
+
The function form works everywhere a `headers` record does — client `defaults.headers` and per-call `options.headers` — and the same precedence applies: per-call headers (function or record) win over default headers, and route-declared headers from `schema.req.headers` win over both. A per-call function override:
|
|
271
275
|
|
|
272
276
|
```typescript
|
|
273
277
|
await client.users.GetUser(
|
|
@@ -489,7 +493,7 @@ Headers and signals combine across layers. From lowest to highest precedence (wi
|
|
|
489
493
|
1. Adapter config (e.g., `createFetchAdapter({ headers })`)
|
|
490
494
|
2. Client `defaults.headers` / `defaults.signal` / `defaults.timeout`
|
|
491
495
|
3. Per-call `options.headers` / `options.signal` / `options.timeout`
|
|
492
|
-
4. Route-declared headers from `schema.
|
|
496
|
+
4. Route-declared headers from `schema.req.headers` (part of the typed contract)
|
|
493
497
|
5. `onBeforeRequest` hook mutations — final say
|
|
494
498
|
|
|
495
499
|
## Streaming
|
|
@@ -534,6 +538,8 @@ await generateClient({
|
|
|
534
538
|
|
|
535
539
|
When `shareModels` is on (the default), the codegen pre-pass collects every subschema with a `$id` field, deduplicates them, and emits a single `_models.ts` hub. Every scope that references one of those types imports from `./_models` instead of inlining it — so the type is defined once and shared across scopes.
|
|
536
540
|
|
|
541
|
+
> **Limitation: record/index schemas can't be shared.** Sharing keys off `$id`, and a bare `Type.Record(...)` (JSON Schema `additionalProperties`) has no `$id` of its own — so a record type is always re-inlined at each use site, never hoisted into `_models.ts`. It still validates and types correctly; it just duplicates if referenced from multiple procedures. If a record type matters enough to share, wrap it in an `$id`-bearing model (e.g. give the object that carries it an `$id`, as `Thread` does for its `readCursors` map) and reference that.
|
|
542
|
+
|
|
537
543
|
### `sharedTypesImport` — per-`$id` override map
|
|
538
544
|
|
|
539
545
|
For each `$id` you'd rather import from your own package instead of generating locally, add an entry to `sharedTypesImport` in the config file:
|
|
@@ -650,4 +656,4 @@ import type {
|
|
|
650
656
|
import { generateClient } from 'ts-procedures/codegen'
|
|
651
657
|
```
|
|
652
658
|
|
|
653
|
-
> **Migration note:** `ClientRequestError` was renamed to `ClientHttpError` in 7.0.0. The old name is re-exported as a deprecated alias
|
|
659
|
+
> **Migration note:** `ClientRequestError` was renamed to `ClientHttpError` in 7.0.0. The old name is still re-exported as a deprecated alias. Update imports when possible.
|
|
@@ -45,7 +45,7 @@ All framework error classes are exported from `ts-procedures/client` (or from `.
|
|
|
45
45
|
|
|
46
46
|
Every class carries `cause` to surface the underlying platform error — typically a `TypeError` or `DOMException` — when one exists.
|
|
47
47
|
|
|
48
|
-
`ClientRequestError` is a deprecated alias for `ClientHttpError
|
|
48
|
+
`ClientRequestError` is a deprecated alias for `ClientHttpError` (renamed in 7.0.0) and will be removed in a future release. See the [migration guide](#8-migration-6x--7x) below.
|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
@@ -308,7 +308,7 @@ Three breaking changes in 7.0.0 affect error handling.
|
|
|
308
308
|
|
|
309
309
|
### 8a. `ClientRequestError` Renamed to `ClientHttpError`
|
|
310
310
|
|
|
311
|
-
`ClientRequestError` is a deprecated alias for `ClientHttpError`, retained for
|
|
311
|
+
`ClientRequestError` is a deprecated alias for `ClientHttpError`, retained for backward compatibility since 7.0.0.
|
|
312
312
|
|
|
313
313
|
**Action**: rename your imports from `ClientRequestError` to `ClientHttpError`. The `instanceof ClientRequestError` guard continues to work until the alias is removed.
|
|
314
314
|
|
|
@@ -412,9 +412,9 @@ A framework-level "skip `onError` for `.safe()`" toggle was deliberately deferre
|
|
|
412
412
|
|
|
413
413
|
## 10. Reference
|
|
414
414
|
|
|
415
|
-
-
|
|
416
|
-
- Client types and interfaces:
|
|
417
|
-
- Agent config patterns and anti-patterns: `agent_config/claude-code/skills/ts-procedures/patterns.md` and `anti-patterns.md`
|
|
415
|
+
- Codegen setup, per-call options, hooks, and typed-error wiring: [`docs/client-and-codegen.md`](./client-and-codegen.md)
|
|
416
|
+
- Client types and interfaces: package source under `src/client/` (`types.ts`, `errors.ts`, `error-dispatch.ts`)
|
|
417
|
+
- Agent config patterns and anti-patterns: [`agent_config/claude-code/skills/ts-procedures/patterns.md`](../agent_config/claude-code/skills/ts-procedures/patterns.md) and [`anti-patterns.md`](../agent_config/claude-code/skills/ts-procedures/anti-patterns.md)
|
|
418
418
|
|
|
419
419
|
---
|
|
420
420
|
|
package/docs/codegen-kotlin.md
CHANGED
|
@@ -141,7 +141,7 @@ Choosing the dispatch strategy (status-code based, body.name based, sealed-class
|
|
|
141
141
|
|
|
142
142
|
## Untagged unions
|
|
143
143
|
|
|
144
|
-
ajsc
|
|
144
|
+
ajsc's Kotlin emitter (as of the bundled 7.x) silently produces an empty `@Serializable data class` for any untagged `oneOf` schema, regardless of whether `--unsupported-unions fallback` is set. There is no "throws on default" mode for Kotlin (that's Swift behavior). The `--unsupported-unions` flag is currently a no-op for the Kotlin target.
|
|
145
145
|
|
|
146
146
|
For example, the schema `oneOf: [{ type: 'string' }, { type: 'integer' }]` with `rootTypeName: 'Mixed'` produces:
|
|
147
147
|
|
|
@@ -170,7 +170,6 @@ The following ajsc behaviors are intentional and documented; they are **not bugs
|
|
|
170
170
|
|
|
171
171
|
## Reference
|
|
172
172
|
|
|
173
|
-
- Spec: [`docs/superpowers/specs/2026-04-25-ajsc-v7-kotlin-polish-design.md`](./superpowers/specs/2026-04-25-ajsc-v7-kotlin-polish-design.md)
|
|
174
173
|
- For iOS / macOS / Apple-platform consumers, see [`docs/codegen-swift.md`](./codegen-swift.md) — same types-only design with Swift-specific flags and `Codable` setup notes.
|
|
175
174
|
- ajsc README: `node_modules/ajsc/README.md` (or [npmjs.com/package/ajsc](https://www.npmjs.com/package/ajsc))
|
|
176
|
-
- ts-procedures-codegen CLI flags:
|
|
175
|
+
- ts-procedures-codegen CLI flags: run `npx ts-procedures-codegen --help` for the full grouped flag catalog. Kotlin-specific flags: `--kotlin-package` (required), `--kotlin-serializer`, `--unsupported-unions`.
|
package/docs/codegen-swift.md
CHANGED
|
@@ -308,7 +308,6 @@ The following ajsc behaviors are intentional and documented; they are **not bugs
|
|
|
308
308
|
|
|
309
309
|
## Reference
|
|
310
310
|
|
|
311
|
-
- Spec: [`docs/superpowers/specs/2026-04-25-swift-codegen-design.md`](./superpowers/specs/2026-04-25-swift-codegen-design.md)
|
|
312
311
|
- For Kotlin / Android consumers, see [`docs/codegen-kotlin.md`](./codegen-kotlin.md) — same types-only design with Kotlin-specific flags and `kotlinx.serialization` setup notes.
|
|
313
312
|
- ajsc README: `node_modules/ajsc/README.md` (or [npmjs.com/package/ajsc](https://www.npmjs.com/package/ajsc))
|
|
314
|
-
- ts-procedures-codegen CLI flags:
|
|
313
|
+
- ts-procedures-codegen CLI flags: run `npx ts-procedures-codegen --help` for the full grouped flag catalog. Swift-specific flags: `--swift-serializer`, `--swift-access-level`, `--unsupported-unions`.
|
package/docs/core.md
CHANGED
|
@@ -6,21 +6,27 @@ ts-procedures creates type-safe, schema-validated procedure calls with a single
|
|
|
6
6
|
|
|
7
7
|
## Procedures Factory
|
|
8
8
|
|
|
9
|
-
The `Procedures()` function creates a factory for defining procedures. It accepts two generic type parameters:
|
|
9
|
+
The `Procedures()` function creates a factory for defining procedures. It accepts two generic type parameters and a flat options bag:
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
|
-
Procedures<TContext, TExtendedConfig>(
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
Procedures<TContext, TExtendedConfig>(options?: {
|
|
13
|
+
validation?: false | { ajv?: Ajv | AjvOptions }
|
|
14
|
+
schema?: { adapters?: SchemaAdapter[] }
|
|
15
|
+
http?: { pathPrefix?: string; scope?: string }
|
|
16
|
+
onCreate?: (procedure: AnyProcedureRegistration<TContext, TExtendedConfig>) => void
|
|
15
17
|
})
|
|
16
18
|
```
|
|
17
19
|
|
|
18
20
|
| Parameter | Description |
|
|
19
21
|
|-----------|----------------------------------------------------------------------------|
|
|
20
22
|
| `TContext` | The base context type passed to all handlers as the first parameter |
|
|
21
|
-
| `TExtendedConfig` | Additional configuration properties for all procedures `config` properties |
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
23
|
+
| `TExtendedConfig` | Additional configuration properties for all procedures `config` properties (applies to `Create` and `CreateStream`) |
|
|
24
|
+
| `options.validation` | `false` skips per-call AJV validation for the whole factory (see [Disabling Runtime Validation](#disabling-runtime-validation)); `{ ajv }` customizes AJV — options merged over the defaults, or a configured `Ajv` instance used as-is. Default: validation runs with the default AJV configuration. |
|
|
25
|
+
| `options.schema.adapters` | Plug in additional schema libraries via the `SchemaAdapter` interface. TypeBox is built in. See [Other Schema Libraries](#other-schema-libraries--schemaadapter). |
|
|
26
|
+
| `options.http` | Factory-level defaults for `CreateHttp` / `CreateHttpStream`: `pathPrefix` is prepended to every route's `path` at registration time (part of the route's identity, unlike a server builder's mount prefix), and `scope` is the default codegen scope for routes that don't set one. Per-route config always wins. |
|
|
27
|
+
| `options.onCreate` | Optional callback invoked when each procedure is registered (runtime) |
|
|
28
|
+
|
|
29
|
+
**Returns:** `Create`, `CreateStream`, `CreateHttp`, `CreateHttpStream`, plus introspection helpers `getProcedures()`, `getProcedure(name)`, `removeProcedure(name)`, and `clear()`.
|
|
24
30
|
|
|
25
31
|
## Create Function
|
|
26
32
|
|
|
@@ -33,27 +39,27 @@ Create(name, config, handler)
|
|
|
33
39
|
**Returns:**
|
|
34
40
|
- `{ [name]: handler }` - Named export for the handler
|
|
35
41
|
- `procedure` - Generic reference to the handler
|
|
36
|
-
- `info` - Procedure metadata (name, description, schema, `TExtendedConfig` properties, etc.)
|
|
42
|
+
- `info` - Procedure metadata (name, `kind: 'rpc'`, description, schema, `TExtendedConfig` properties, etc.)
|
|
37
43
|
|
|
38
|
-
##
|
|
44
|
+
## HTTP Procedures with CreateHttp
|
|
39
45
|
|
|
40
|
-
For HTTP APIs and other multi-channel transports, `
|
|
46
|
+
For HTTP APIs and other multi-channel transports, `CreateHttp` provides per-channel type safety via `schema.req`. Each key is an independently validated input channel:
|
|
41
47
|
|
|
42
48
|
```typescript
|
|
43
|
-
const {
|
|
49
|
+
const { CreateHttp } = Procedures<AppContext>()
|
|
44
50
|
|
|
45
|
-
const { UpdateUser } =
|
|
51
|
+
const { UpdateUser } = CreateHttp(
|
|
46
52
|
'UpdateUser',
|
|
47
53
|
{
|
|
48
54
|
path: '/users/:id',
|
|
49
55
|
method: 'put',
|
|
50
56
|
schema: {
|
|
51
|
-
|
|
57
|
+
req: {
|
|
52
58
|
pathParams: Type.Object({ id: Type.String() }),
|
|
53
59
|
query: Type.Object({ notify: Type.Optional(Type.Boolean()) }),
|
|
54
60
|
body: Type.Object({ name: Type.String(), email: Type.String() }),
|
|
55
61
|
},
|
|
56
|
-
|
|
62
|
+
res: { body: Type.Object({ ok: Type.Boolean() }) },
|
|
57
63
|
},
|
|
58
64
|
},
|
|
59
65
|
async (ctx, { pathParams, query, body }) => {
|
|
@@ -66,9 +72,13 @@ const { UpdateUser } = Create(
|
|
|
66
72
|
```
|
|
67
73
|
|
|
68
74
|
**Rules:**
|
|
69
|
-
- `schema.
|
|
70
|
-
-
|
|
71
|
-
-
|
|
75
|
+
- `schema.req` and `schema.params` are **mutually exclusive** — `schema.params` belongs to RPC procedures (`Create`/`CreateStream`), `schema.req` to HTTP procedures. Using `schema.params` on `CreateHttp` throws `ProcedureRegistrationError`.
|
|
76
|
+
- Valid channels are `pathParams`, `query`, `body`, and `headers`; each is validated independently with per-channel error messages.
|
|
77
|
+
- `schema.res.body` documents the response body (drives codegen); omit `schema.res` entirely for 204-style no-content routes.
|
|
78
|
+
- Factory-level `http.pathPrefix` / `http.scope` defaults apply; per-route config wins.
|
|
79
|
+
- For HTTP streaming routes, use `CreateHttpStream` — same `schema.req` channels plus `schema.yield`.
|
|
80
|
+
|
|
81
|
+
For routing, status codes, and error handling for HTTP procedures, see [HTTP Integrations](./http-integrations.md).
|
|
72
82
|
|
|
73
83
|
## CreateStream Function
|
|
74
84
|
|
|
@@ -98,10 +108,23 @@ When using the built-in HTTP implementation (Hono), `ctx.signal` is automaticall
|
|
|
98
108
|
**Returns:**
|
|
99
109
|
- `{ [name]: handler }` - Named generator export
|
|
100
110
|
- `procedure` - Generic reference to the generator
|
|
101
|
-
- `info` - Procedure meta with `
|
|
111
|
+
- `info` - Procedure meta with `kind: 'rpc-stream'`
|
|
102
112
|
|
|
103
113
|
For detailed streaming documentation (yield validation, abort signals, SSE integration), see [Streaming Procedures](./streaming.md).
|
|
104
114
|
|
|
115
|
+
## Procedure Kinds
|
|
116
|
+
|
|
117
|
+
Every registration — and every creator's `info` — carries a `kind` discriminant for type narrowing:
|
|
118
|
+
|
|
119
|
+
| Creator | `kind` |
|
|
120
|
+
|---------|--------|
|
|
121
|
+
| `Create` | `'rpc'` |
|
|
122
|
+
| `CreateStream` | `'rpc-stream'` |
|
|
123
|
+
| `CreateHttp` | `'http'` |
|
|
124
|
+
| `CreateHttpStream` | `'http-stream'` |
|
|
125
|
+
|
|
126
|
+
Branch on `kind` in `onCreate` callbacks and `getProcedures()` consumers to narrow a registration to its specific shape.
|
|
127
|
+
|
|
105
128
|
## Using Generics
|
|
106
129
|
|
|
107
130
|
### Base Context
|
|
@@ -161,6 +184,8 @@ const { AdminOnly } = Create(
|
|
|
161
184
|
console.log(AdminOnly.info.permissions) // ['admin']
|
|
162
185
|
```
|
|
163
186
|
|
|
187
|
+
`TExtendedConfig` applies to `Create` and `CreateStream`. `CreateHttp` / `CreateHttpStream` have their own fixed config shape (`path`, `method`, `successStatus`, `scope`, `errors`, `schema`).
|
|
188
|
+
|
|
164
189
|
### Combined Example
|
|
165
190
|
|
|
166
191
|
```typescript
|
|
@@ -177,8 +202,10 @@ interface ExtendedConfig {
|
|
|
177
202
|
const { Create, getProcedures } = Procedures<CustomContext, ExtendedConfig>({
|
|
178
203
|
onCreate: (procedure) => {
|
|
179
204
|
// Register with your framework
|
|
180
|
-
console.log(`Registered: ${procedure.name}`)
|
|
181
|
-
|
|
205
|
+
console.log(`Registered: ${procedure.name} (${procedure.kind})`)
|
|
206
|
+
if (procedure.kind === 'rpc') {
|
|
207
|
+
console.log(`Requires Auth: ${procedure.config.requiresAuth}`)
|
|
208
|
+
}
|
|
182
209
|
},
|
|
183
210
|
})
|
|
184
211
|
|
|
@@ -212,10 +239,31 @@ import { Type } from 'typebox'
|
|
|
212
239
|
schema: { params: Type.Object({ title: Type.String() }) }
|
|
213
240
|
```
|
|
214
241
|
|
|
215
|
-
TypeBox schemas are valid JSON Schema and work directly with AJV for runtime validation.
|
|
242
|
+
TypeBox schemas are valid JSON Schema and work directly with AJV for runtime validation. Handler param and return types are inferred from the schemas via `Infer<T>`.
|
|
216
243
|
|
|
217
244
|
> **Composing schemas:** the bundled typebox has no `Type.Composite`. Compose with a flat object spread instead — `Type.Object({ ...Base.properties, extra: Type.String() })` — which also keeps the emitted JSON Schema a single `object` rather than an `allOf`.
|
|
218
245
|
|
|
246
|
+
### Other Schema Libraries — SchemaAdapter
|
|
247
|
+
|
|
248
|
+
TypeBox is built in. To register procedures with another schema library, implement the 3-member `SchemaAdapter` interface and pass it to the factory:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import type { SchemaAdapter } from 'ts-procedures'
|
|
252
|
+
import * as z from 'zod'
|
|
253
|
+
|
|
254
|
+
const zodAdapter: SchemaAdapter = {
|
|
255
|
+
name: 'zod', // used in registration error messages
|
|
256
|
+
detect: (s) => s instanceof z.ZodType, // does this adapter recognize the schema?
|
|
257
|
+
toJsonSchema: (s) => z.toJSONSchema(s as z.ZodType), // convert to JSON Schema
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const { Create } = Procedures({ schema: { adapters: [zodAdapter] } })
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The framework only ever needs one thing from a schema object: its JSON Schema. Everything downstream (AJV validation, route docs, codegen) works on JSON Schema.
|
|
264
|
+
|
|
265
|
+
> **Note:** compile-time type inference (`Infer<T>`) is built in only for TypeBox. Custom adapters get runtime validation and docs, with params inferred as `unknown` unless you annotate handler types yourself.
|
|
266
|
+
|
|
219
267
|
### Validation Behavior
|
|
220
268
|
|
|
221
269
|
AJV is configured with:
|
|
@@ -223,21 +271,29 @@ AJV is configured with:
|
|
|
223
271
|
- `coerceTypes: true` - Automatically coerce types when possible
|
|
224
272
|
- `removeAdditional: true` - Strip properties not in schema
|
|
225
273
|
|
|
274
|
+
Each factory owns its own AJV compiler. Customize it via the `validation` option — pass AJV options to merge over the defaults, or a fully configured `Ajv` instance to use as-is:
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
const { Create } = Procedures({
|
|
278
|
+
validation: { ajv: { coerceTypes: false } },
|
|
279
|
+
})
|
|
280
|
+
```
|
|
281
|
+
|
|
226
282
|
**Note:** `schema.params` is validated at runtime. `schema.returnType` is for documentation/introspection only.
|
|
227
283
|
|
|
228
284
|
### Disabling Runtime Validation
|
|
229
285
|
|
|
230
|
-
For trusted internal callers — for example, a back-of-house factory whose inputs are already type-checked at build time and whose handlers are never invoked from public HTTP — pass `
|
|
286
|
+
For trusted internal callers — for example, a back-of-house factory whose inputs are already type-checked at build time and whose handlers are never invoked from public HTTP — pass `validation: false` when constructing the factory:
|
|
231
287
|
|
|
232
288
|
```typescript
|
|
233
289
|
const { Create, CreateStream } = Procedures({
|
|
234
|
-
|
|
290
|
+
validation: false,
|
|
235
291
|
})
|
|
236
292
|
```
|
|
237
293
|
|
|
238
|
-
When set, every procedure registered by this factory skips AJV validation of `schema.params` and `schema.
|
|
294
|
+
When set, every procedure registered by this factory skips AJV validation of `schema.params` and `schema.req` on every call. JSON Schema and validators are still computed at registration time (so bad schemas fail fast, and `info.schema` and codegen are unaffected) — only the per-call validator runs are bypassed.
|
|
239
295
|
|
|
240
|
-
**Use sparingly.** Do not enable this for procedures that accept input from public clients, untyped JSON bodies, or anything you do not control end-to-end.
|
|
296
|
+
**Use sparingly.** Do not enable this for procedures that accept input from public clients, untyped JSON bodies, or anything you do not control end-to-end.
|
|
241
297
|
|
|
242
298
|
This is independent of the per-call `ctx.isPrevalidated` escape hatch used by HTTP builders that have already validated upstream — both paths short-circuit the same validators.
|
|
243
299
|
|
|
@@ -267,11 +323,13 @@ Create(
|
|
|
267
323
|
| Error Class | Trigger |
|
|
268
324
|
|-------------|---------|
|
|
269
325
|
| ProcedureError | `ctx.error()` in handlers |
|
|
270
|
-
| ProcedureValidationError | Schema validation failure (params) |
|
|
326
|
+
| ProcedureValidationError | Schema validation failure (params / req channels) |
|
|
271
327
|
| ProcedureYieldValidationError | Yield validation failure (streaming with `validateYields: true`) |
|
|
272
|
-
| ProcedureRegistrationError | Invalid schema at registration |
|
|
328
|
+
| ProcedureRegistrationError | Invalid schema at registration; duplicate procedure name |
|
|
273
329
|
| `${Service}ProcedureError` (client-side) | Base class for every generated error class on the client — see [Client & Codegen → Typed Error Handling](./client-and-codegen.md#typed-error-handling) |
|
|
274
330
|
|
|
331
|
+
Every framework error also carries a `kind` field (`'procedure' | 'validation' | 'yield-validation' | 'registration'`) as an alternative to `instanceof` narrowing.
|
|
332
|
+
|
|
275
333
|
### Error Properties
|
|
276
334
|
|
|
277
335
|
```typescript
|
|
@@ -282,6 +340,7 @@ try {
|
|
|
282
340
|
console.log(e.procedureName) // 'MyProcedure'
|
|
283
341
|
console.log(e.message) // 'Resource not found'
|
|
284
342
|
console.log(e.meta) // { id: '123' }
|
|
343
|
+
console.log(e.kind) // 'procedure'
|
|
285
344
|
}
|
|
286
345
|
}
|
|
287
346
|
```
|
|
@@ -320,7 +379,7 @@ For streaming abort signal behavior (including `signal.reason` and consumer brea
|
|
|
320
379
|
|
|
321
380
|
### onCreate Callback
|
|
322
381
|
|
|
323
|
-
Register procedures with a custom framework via the `onCreate` callback. Each registration receives `{ name, handler, config }` so you can wire it into whatever router or framework you want:
|
|
382
|
+
Register procedures with a custom framework via the `onCreate` callback. Each registration receives `{ name, kind, handler, config }` so you can wire it into whatever router or framework you want:
|
|
324
383
|
|
|
325
384
|
```typescript
|
|
326
385
|
import { Hono } from 'hono'
|
|
@@ -347,7 +406,7 @@ const { Create } = Procedures<{ raw: unknown }>({
|
|
|
347
406
|
// Procedures are automatically registered as /rpc/GetUser, /rpc/CreateUser, etc.
|
|
348
407
|
```
|
|
349
408
|
|
|
350
|
-
For the built-in HTTP integration (RPC, RPC streams, REST, REST streams via `HonoAppBuilder`), see [HTTP Integrations](./http-integrations.md).
|
|
409
|
+
For the built-in HTTP integration (RPC, RPC streams, REST, REST streams via `HonoAppBuilder`), see [HTTP Integrations](./http-integrations.md). To build a full adapter for another framework (route docs, taxonomy dispatch, SSE), use the transport-agnostic [`ts-procedures/server` toolkit](./http-integrations.md#build-your-own-adapter--ts-proceduresserver) instead of hand-rolling everything in `onCreate`.
|
|
351
410
|
|
|
352
411
|
### Introspection with getProcedures()
|
|
353
412
|
|
|
@@ -359,12 +418,12 @@ const { Create, getProcedures } = Procedures()
|
|
|
359
418
|
Create('GetUser', { schema: { params: Type.Object({ id: Type.String() }) } }, async () => {})
|
|
360
419
|
Create('ListUsers', { schema: { params: Type.Object({}) } }, async () => {})
|
|
361
420
|
|
|
362
|
-
// Get all registered procedures
|
|
421
|
+
// Get all registered procedures (in registration order)
|
|
363
422
|
const procedures = getProcedures()
|
|
364
423
|
|
|
365
424
|
// Generate OpenAPI spec
|
|
366
|
-
for (const
|
|
367
|
-
console.log(`${
|
|
425
|
+
for (const p of procedures) {
|
|
426
|
+
console.log(`${p.name} (${p.kind}):`, p.config.schema)
|
|
368
427
|
}
|
|
369
428
|
```
|
|
370
429
|
|
|
@@ -374,7 +433,7 @@ Procedures return handlers that can be called directly in tests:
|
|
|
374
433
|
|
|
375
434
|
```typescript
|
|
376
435
|
import { describe, test, expect } from 'vitest'
|
|
377
|
-
import { Procedures } from 'ts-procedures'
|
|
436
|
+
import { Procedures, ProcedureValidationError } from 'ts-procedures'
|
|
378
437
|
import { Type } from 'typebox'
|
|
379
438
|
|
|
380
439
|
interface MyCustomContext {
|
|
@@ -393,13 +452,13 @@ const { GetUser, info } = Create(
|
|
|
393
452
|
},
|
|
394
453
|
},
|
|
395
454
|
async (ctx, params) => {
|
|
396
|
-
if (!
|
|
455
|
+
if (!ctx.userName || !ctx.userId) {
|
|
397
456
|
throw ctx.error('User is not authenticated')
|
|
398
457
|
}
|
|
399
458
|
|
|
400
459
|
return {
|
|
401
|
-
id:
|
|
402
|
-
name: params?.hideName ? '*******' :
|
|
460
|
+
id: ctx.userId,
|
|
461
|
+
name: params?.hideName ? '*******' : ctx.userName
|
|
403
462
|
}
|
|
404
463
|
},
|
|
405
464
|
)
|
|
@@ -432,24 +491,27 @@ describe('GetUser', () => {
|
|
|
432
491
|
|
|
433
492
|
## API Reference
|
|
434
493
|
|
|
435
|
-
### Procedures(
|
|
494
|
+
### Procedures(options?)
|
|
436
495
|
|
|
437
496
|
Creates a procedure factory.
|
|
438
497
|
|
|
439
498
|
**Parameters:**
|
|
440
|
-
- `
|
|
441
|
-
- `
|
|
499
|
+
- `options.validation` - `false` to skip per-call validation for the whole factory (see [Disabling Runtime Validation](#disabling-runtime-validation)), or `{ ajv }` to customize AJV (options merged over defaults, or an `Ajv` instance). Default: validation runs.
|
|
500
|
+
- `options.schema.adapters` - Additional schema-library adapters (see [Other Schema Libraries](#other-schema-libraries--schemaadapter))
|
|
501
|
+
- `options.http` - Factory-level `pathPrefix` / `scope` defaults for `CreateHttp` / `CreateHttpStream`
|
|
502
|
+
- `options.onCreate` - Callback invoked when each procedure is registered
|
|
442
503
|
|
|
443
504
|
**Returns:**
|
|
444
|
-
- `Create` -
|
|
445
|
-
- `getProcedures()` - Returns `Array` of all registered procedures
|
|
505
|
+
- `Create` / `CreateStream` / `CreateHttp` / `CreateHttpStream` - Functions to define procedures
|
|
506
|
+
- `getProcedures()` - Returns `Array` of all registered procedures (`{ name, kind, config, handler }`)
|
|
507
|
+
- `getProcedure(name)` / `removeProcedure(name)` / `clear()` - Registry helpers
|
|
446
508
|
|
|
447
509
|
### Create(name, config, handler)
|
|
448
510
|
|
|
449
511
|
Defines a procedure.
|
|
450
512
|
|
|
451
513
|
**Parameters:**
|
|
452
|
-
- `name` - Unique procedure name (becomes named export)
|
|
514
|
+
- `name` - Unique procedure name (becomes named export; registering the same name twice throws `ProcedureRegistrationError`)
|
|
453
515
|
- `config.description` - Optional description
|
|
454
516
|
- `config.schema.params` - TypeBox schema for params (validated at runtime)
|
|
455
517
|
- `config.schema.returnType` - TypeBox schema for return type (documentation only)
|
|
@@ -459,7 +521,7 @@ Defines a procedure.
|
|
|
459
521
|
**Returns:**
|
|
460
522
|
- `{ [name]: handler }` - Named handler export
|
|
461
523
|
- `procedure` - Generic handler reference
|
|
462
|
-
- `info` - Procedure metadata (name, description, schema, extended-config properties)
|
|
524
|
+
- `info` - Procedure metadata (name, `kind`, description, schema, extended-config properties)
|
|
463
525
|
|
|
464
526
|
### Type Exports
|
|
465
527
|
|
|
@@ -474,23 +536,42 @@ import {
|
|
|
474
536
|
ProcedureRegistrationError,
|
|
475
537
|
ProcedureYieldValidationError, // For streaming yield validation
|
|
476
538
|
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
539
|
+
// Schema utilities (low-level — the factory calls these for you)
|
|
540
|
+
extractJsonSchema, // extractJsonSchema(schema, adapters)
|
|
541
|
+
computeSchema, // computeSchema(name, schema, { adapters, compile })
|
|
542
|
+
createValidatorCompiler, // per-factory AJV compiler (no module singleton)
|
|
543
|
+
typeboxAdapter,
|
|
544
|
+
isTypeboxSchema,
|
|
545
|
+
DEFAULT_AJV_OPTIONS,
|
|
546
|
+
} from 'ts-procedures'
|
|
547
|
+
|
|
548
|
+
import type {
|
|
549
|
+
// Factory + registrations
|
|
550
|
+
ProceduresOptions,
|
|
551
|
+
ProcedureKind, // 'rpc' | 'rpc-stream' | 'http' | 'http-stream'
|
|
552
|
+
AnyProcedureRegistration,
|
|
480
553
|
TProcedureRegistration,
|
|
481
|
-
TStreamProcedureRegistration,
|
|
554
|
+
TStreamProcedureRegistration,
|
|
555
|
+
THttpProcedureRegistration,
|
|
556
|
+
THttpStreamProcedureRegistration,
|
|
557
|
+
TCreateHttpConfig,
|
|
558
|
+
TLocalContext,
|
|
559
|
+
TStreamContext, // Streaming context (AbortSignal always present)
|
|
482
560
|
TNoContextProvided,
|
|
561
|
+
HttpMethod,
|
|
562
|
+
HttpReturn,
|
|
483
563
|
|
|
484
|
-
//
|
|
485
|
-
|
|
486
|
-
schemaParser,
|
|
487
|
-
isTypeboxSchema,
|
|
564
|
+
// Errors
|
|
565
|
+
ProcedureErrorKind, // 'procedure' | 'validation' | 'yield-validation' | 'registration'
|
|
488
566
|
|
|
489
567
|
// Schema types
|
|
568
|
+
SchemaAdapter,
|
|
569
|
+
ValidationOptions,
|
|
570
|
+
Validate,
|
|
571
|
+
ValidatorCompiler,
|
|
572
|
+
Infer, // primary inference type (TypeBox-only)
|
|
573
|
+
TSchemaLib, // alias for Infer (kept for compatibility)
|
|
490
574
|
TJSONSchema,
|
|
491
|
-
TSchemaLib,
|
|
492
|
-
TSchemaLibGenerator, // AsyncGenerator type utility
|
|
493
|
-
TSchemaParsed,
|
|
494
575
|
TSchemaValidationError,
|
|
495
576
|
Prettify,
|
|
496
577
|
} from 'ts-procedures'
|
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
ts-procedures includes a built-in HTTP builder for Hono that handles routing, context resolution, lifecycle hooks, abort signals, and automatic route documentation. The builder reads procedures off the factory at registration time and mounts the matching routes when you call `build()`.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The machinery behind the builder — route-doc builders, error taxonomy dispatch, request channel extraction, SSE semantics — lives in the transport-agnostic [`ts-procedures/server` subpath](#build-your-own-adapter--ts-proceduresserver), so adapters for other frameworks are thin glue.
|
|
8
8
|
|
|
9
9
|
## Integrations at a Glance
|
|
10
10
|
|
|
11
11
|
| Integration | Export | Procedure kinds | Guide |
|
|
12
12
|
|-------------|--------|-----------------|-------|
|
|
13
|
-
| HonoAppBuilder | `ts-procedures/hono` | `rpc`, `rpc-stream`, `http`, `http-stream` |
|
|
13
|
+
| HonoAppBuilder | `ts-procedures/hono` | `rpc`, `rpc-stream`, `http`, `http-stream` | This page |
|
|
14
|
+
| Astro (catch-all over Hono apps) | `ts-procedures/astro` | all four | [Astro adapter walkthrough](./astro-adapter.md) |
|
|
15
|
+
| Build your own | `ts-procedures/server` | all four | [Build your own adapter](#build-your-own-adapter--ts-proceduresserver) |
|
|
14
16
|
|
|
15
17
|
## Hono
|
|
16
18
|
|
|
@@ -80,7 +82,7 @@ const app = new HonoAppBuilder({
|
|
|
80
82
|
|
|
81
83
|
`HonoAppBuilder`'s config is **stratified** — kind-specific knobs (`onSuccess`, `queryParser`, `defaultStreamMode`, `onStreamStart`, `onStreamEnd`, `onMidStreamError`) live inside the matching `rpc:` / `api:` / `stream:` block. Cross-cutting hooks (`onRequestStart`, `onRequestEnd`, `onRequestError`, `errors`, `unknownError`, `onError`) stay at the top level.
|
|
82
84
|
|
|
83
|
-
|
|
85
|
+
> **Two path prefixes, two meanings.** The builder's `pathPrefix` (above) is a deployment mount point — it does not appear in route docs' `path`. The factory-level `Procedures({ http: { pathPrefix } })` default, by contrast, is part of each route's **identity**: it is baked into `config.path` at registration time and shows up in route docs and generated clients. Use the factory default for API versioning (`/v1`), the builder prefix for where the app is mounted.
|
|
84
86
|
|
|
85
87
|
### No-content (204) procedures
|
|
86
88
|
|
|
@@ -200,7 +202,7 @@ procs.CreateHttp('GetUser', {
|
|
|
200
202
|
|
|
201
203
|
These per-route declarations flow into the DocEnvelope and drive typed `catch` blocks on generated clients — see [Client & Codegen → Typed Error Handling](./client-and-codegen.md#typed-error-handling).
|
|
202
204
|
|
|
203
|
-
**Tip:**
|
|
205
|
+
**Tip:** for RPC procedures (`Create` / `CreateStream`), whose `scope`/`version`/`errors` config comes from the factory's `TExtendedConfig`, you can bake the typo-checked keys into the whole factory with `Procedures<Ctx, RPCConfig<keyof typeof appErrors & string>>()` — individual `satisfies ErrorKey[]` annotations are then unnecessary. `CreateHttp` / `CreateHttpStream` carry their own fixed config shape, so HTTP routes declare errors per-route with the `satisfies` form above.
|
|
204
206
|
|
|
205
207
|
### Cross-cutting observability — `onRequestError`
|
|
206
208
|
|
|
@@ -226,6 +228,47 @@ The observer is awaited before the response is sent, and any error it throws is
|
|
|
226
228
|
|
|
227
229
|
Configuring only the taxonomy, only `onError`, both, or neither are all valid. When neither is configured the builder goes straight from step 1 to step 4.
|
|
228
230
|
|
|
231
|
+
## Build Your Own Adapter — `ts-procedures/server`
|
|
232
|
+
|
|
233
|
+
`HonoAppBuilder` is deliberately thin: everything framework-agnostic lives in the `ts-procedures/server` subpath, so an adapter for Fastify, Express, or raw `http` is ~4 thin handlers translating between your framework's request/response/streaming primitives and these helpers. Use `src/adapters/hono/` in the package source as the blueprint.
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import {
|
|
237
|
+
// Error dispatch — data-in/data-out, no framework Response types
|
|
238
|
+
dispatchPreStreamError, // → { type: 'body', statusCode, body } | { type: 'response', response }
|
|
239
|
+
dispatchMidStreamError, // → { data, sseEvent?, sseId?, sseRetry?, runOnCatch? }
|
|
240
|
+
|
|
241
|
+
// Request handling
|
|
242
|
+
extractReqChannels, // RequestSource → the declared schema.req channels
|
|
243
|
+
parseQueryNative, // default QueryParser
|
|
244
|
+
resolveFactoryContext, // runs your per-request context resolver
|
|
245
|
+
|
|
246
|
+
// SSE
|
|
247
|
+
SseEventSequencer, // shared yield/return/error event sequencing for both stream kinds
|
|
248
|
+
sse, getSSEMeta,
|
|
249
|
+
|
|
250
|
+
// Route docs
|
|
251
|
+
buildRpcRouteDoc,
|
|
252
|
+
buildStreamRouteDoc,
|
|
253
|
+
buildHttpRouteDoc,
|
|
254
|
+
buildHttpStreamRouteDoc,
|
|
255
|
+
makeRoutePath,
|
|
256
|
+
|
|
257
|
+
// Doc aggregation
|
|
258
|
+
DocRegistry,
|
|
259
|
+
writeDocEnvelope,
|
|
260
|
+
} from 'ts-procedures/server'
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Key contracts:
|
|
264
|
+
|
|
265
|
+
- **`dispatchPreStreamError` is transport-agnostic.** It returns plain data — `{ type: 'body', statusCode, body }` for taxonomy / `unknownError` / hard-default resolutions (serialize `body` as JSON with `statusCode`), or `{ type: 'response', response }` when the imperative `onError` callback produced a framework response (send as-is). Your adapter translates; the dispatch order is identical to the table above.
|
|
266
|
+
- **`extractReqChannels`** takes a `RequestSource` (a tiny interface your adapter implements over its request object) and returns only the channels the route declared in `schema.req`.
|
|
267
|
+
- **`SseEventSequencer`** owns yield/return/error event names, id sequencing, and the `event: 'return'` envelope, so every adapter's SSE wire format matches the Hono builder's byte-for-byte.
|
|
268
|
+
- Only the taxonomy callbacks' `raw` parameter is typed `unknown` at the server layer — it is your framework's request context; cast it in your adapter.
|
|
269
|
+
|
|
270
|
+
No framework imports are allowed inside `ts-procedures/server` (enforced by test), so depending on it never drags Hono into your bundle.
|
|
271
|
+
|
|
229
272
|
## DocRegistry — Composing Docs
|
|
230
273
|
|
|
231
274
|
For a single-builder app, the simplest path is `builder.toDocEnvelope({ basePath, errors })` — it wraps `DocRegistry` for you and produces the same envelope shape:
|
|
@@ -266,6 +309,8 @@ const docs = new DocRegistry({ errors: appErrors, basePath: '/api' })
|
|
|
266
309
|
|
|
267
310
|
`from()` stores a reference — routes are read lazily at `toJSON()` time, so builders can be registered before or after `.build()`. Supports optional `filter` and `transform` options for customizing output.
|
|
268
311
|
|
|
312
|
+
`http-stream` route docs include the route's `yield` and `res.headers` schemas. (Through v8, live envelopes silently dropped these for `http-stream` routes, so generated clients lost those types unless the envelope was hand-authored; v9 fixed this.)
|
|
313
|
+
|
|
269
314
|
The `DocRegistry` output is the input for [Client Code Generation](./client-and-codegen.md).
|
|
270
315
|
|
|
271
316
|
## Type Exports
|
|
@@ -285,6 +330,13 @@ import type {
|
|
|
285
330
|
} from 'ts-procedures/http'
|
|
286
331
|
|
|
287
332
|
// Hono builder + Hono-specific types
|
|
288
|
-
import { HonoAppBuilder } from 'ts-procedures/hono'
|
|
289
|
-
import type {
|
|
333
|
+
import { HonoAppBuilder, sse, defineErrorTaxonomy, DocRegistry } from 'ts-procedures/hono'
|
|
334
|
+
import type {
|
|
335
|
+
HonoAppBuilderConfig,
|
|
336
|
+
QueryParser,
|
|
337
|
+
OnRequestErrorContext,
|
|
338
|
+
ExtendProcedureDoc,
|
|
339
|
+
SSEOptions,
|
|
340
|
+
MidStreamErrorResult,
|
|
341
|
+
} from 'ts-procedures/hono'
|
|
290
342
|
```
|