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
package/README.md
CHANGED
|
@@ -1,146 +1,211 @@
|
|
|
1
1
|
# ts-procedures
|
|
2
2
|
|
|
3
|
-
A TypeScript RPC framework that creates type-safe, schema-validated procedure
|
|
3
|
+
A TypeScript RPC framework that creates type-safe, schema-validated procedure
|
|
4
|
+
calls from a single function definition. Define procedures once on the server
|
|
5
|
+
and get full type inference, runtime validation, HTTP serving, and generated
|
|
6
|
+
clients (TypeScript, Kotlin, Swift) — with typed errors end to end.
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
2. Auto generated documentation and client api spec
|
|
9
|
-
3. Fast and performant
|
|
10
|
-
4. Excellent DX (and agent documentation)
|
|
8
|
+
```ts
|
|
9
|
+
import { Type } from 'typebox'
|
|
10
|
+
import { Procedures } from 'ts-procedures'
|
|
11
11
|
|
|
12
|
+
type Ctx = { db: Db }
|
|
13
|
+
const { Create } = Procedures<Ctx>()
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
export const { GetUser } = Create(
|
|
16
|
+
'GetUser',
|
|
17
|
+
{
|
|
18
|
+
schema: {
|
|
19
|
+
params: Type.Object({ id: Type.String() }),
|
|
20
|
+
returnType: Type.Object({ id: Type.String(), name: Type.String() }),
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
async (ctx, params) => {
|
|
24
|
+
const user = await ctx.db.users.find(params.id)
|
|
25
|
+
if (!user) throw ctx.error('User not found', { id: params.id })
|
|
26
|
+
return user
|
|
27
|
+
},
|
|
28
|
+
)
|
|
14
29
|
|
|
15
|
-
|
|
16
|
-
|
|
30
|
+
// Directly callable (great for tests), fully typed:
|
|
31
|
+
await GetUser({ db }, { id: 'u1' })
|
|
17
32
|
```
|
|
18
33
|
|
|
19
|
-
The
|
|
20
|
-
install only what each one needs:
|
|
34
|
+
## The four procedure kinds
|
|
21
35
|
|
|
22
|
-
|
|
|
36
|
+
| Creator | Kind | Shape |
|
|
23
37
|
|---|---|---|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
38
|
+
| `Create` | `rpc` | `(ctx, params) => Promise<T>` — POST, body in/JSON out |
|
|
39
|
+
| `CreateStream` | `rpc-stream` | async generator — SSE (or text) stream |
|
|
40
|
+
| `CreateHttp` | `http` | REST route with per-channel input (`pathParams`, `query`, `body`, `headers`) |
|
|
41
|
+
| `CreateHttpStream` | `http-stream` | REST route streaming SSE, optional initial headers |
|
|
28
42
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
## Quick Start
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
import { Procedures } from 'ts-procedures'
|
|
37
|
-
import { Type } from 'typebox'
|
|
43
|
+
Every creator returns `{ [name]: handler, procedure: handler, info }`: the
|
|
44
|
+
named handler for direct calls, and `info` for introspection (computed JSON
|
|
45
|
+
Schema, validators, your extended config).
|
|
38
46
|
|
|
39
|
-
|
|
40
|
-
const {
|
|
47
|
+
```ts
|
|
48
|
+
const { CreateHttp } = Procedures<Ctx>({ http: { pathPrefix: '/v1', scope: 'users' } })
|
|
41
49
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
'GetUser',
|
|
50
|
+
export const { UpdateUser } = CreateHttp(
|
|
51
|
+
'UpdateUser',
|
|
45
52
|
{
|
|
46
|
-
|
|
53
|
+
path: '/users/:id',
|
|
54
|
+
method: 'put',
|
|
55
|
+
errors: ['NotFound'], // taxonomy keys → typed client errors
|
|
47
56
|
schema: {
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
req: {
|
|
58
|
+
pathParams: Type.Object({ id: Type.String() }),
|
|
59
|
+
body: Type.Object({ name: Type.String() }),
|
|
60
|
+
},
|
|
61
|
+
res: { body: Type.Object({ id: Type.String(), name: Type.String() }) },
|
|
50
62
|
},
|
|
51
63
|
},
|
|
52
|
-
async (ctx,
|
|
53
|
-
|
|
54
|
-
// returnType is inferred as { id: string; name: string }
|
|
55
|
-
return { id: params.userId, name: 'John Doe' }
|
|
56
|
-
},
|
|
64
|
+
async (ctx, req) => ctx.db.users.update(req.pathParams.id, req.body),
|
|
57
65
|
)
|
|
58
|
-
|
|
59
|
-
// Call the procedure directly
|
|
60
|
-
const user = await GetUser({}, { userId: '123' })
|
|
61
|
-
// Or use the generic reference
|
|
62
|
-
const user2 = await procedure({}, { userId: '456' })
|
|
63
66
|
```
|
|
64
67
|
|
|
65
|
-
##
|
|
68
|
+
## Serving over HTTP (Hono)
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
```ts
|
|
71
|
+
import { Hono } from 'hono'
|
|
72
|
+
import { HonoAppBuilder, defineErrorTaxonomy } from 'ts-procedures/hono'
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const api = new HonoAPIAppBuilder({ app, errors, queryParser }).register(F2, ctx2)
|
|
73
|
-
const stream = new HonoStreamAppBuilder({ app, errors, onMidStreamError }).register(F3, ctx3)
|
|
74
|
+
const errors = defineErrorTaxonomy({
|
|
75
|
+
NotFound: { class: NotFoundError, statusCode: 404 },
|
|
76
|
+
})
|
|
74
77
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
api: { queryParser },
|
|
80
|
-
stream: { onMidStreamError },
|
|
81
|
-
}).register(F1, ctx1).register(F2, ctx2).register(F3, ctx3)
|
|
78
|
+
const builder = new HonoAppBuilder({ pathPrefix: '/api', errors })
|
|
79
|
+
.register(factory, (c) => ({ db: makeDb(c) })) // context per request (sync or async)
|
|
80
|
+
|
|
81
|
+
const app = builder.build() // a Hono app — mount anywhere Hono runs
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
One builder serves all four kinds. Config is stratified: kind-specific blocks
|
|
85
|
+
(`rpc.onSuccess`, `api.queryParser`, `stream.defaultStreamMode` /
|
|
86
|
+
`onStreamStart` / `onStreamEnd` / `onMidStreamError`) plus cross-cutting
|
|
87
|
+
error handling (`errors` taxonomy, `unknownError`, imperative `onError`,
|
|
88
|
+
`onRequestError` observer) and lifecycle (`onRequestStart/End`).
|
|
85
89
|
|
|
86
|
-
|
|
90
|
+
An Astro adapter ships too: `createAstroHandler` from `ts-procedures/astro`
|
|
91
|
+
serves built Hono apps from an Astro catch-all route.
|
|
87
92
|
|
|
88
|
-
|
|
93
|
+
### Error taxonomy
|
|
89
94
|
|
|
90
|
-
|
|
95
|
+
Declarative, typo-proof error handling: map error classes (or predicates) to
|
|
96
|
+
status codes and wire bodies once, and the same source of truth drives runtime
|
|
97
|
+
responses, envelope docs, and generated typed client errors.
|
|
91
98
|
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
```ts
|
|
100
|
+
const errors = defineErrorTaxonomy({
|
|
101
|
+
NotFound: { class: NotFoundError, statusCode: 404 },
|
|
102
|
+
UseCase: { class: UseCaseError, statusCode: 422, toResponse: (e) => ({ message: e.publicMessage }) },
|
|
103
|
+
PgUnique: { match: (e): e is DatabaseError => isPgError(e, '23505'), statusCode: 409 },
|
|
104
|
+
})
|
|
105
|
+
```
|
|
96
106
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// Input channels: pathParams, query, body, headers (schema.req)
|
|
101
|
-
// Response: schema.res.body (docs) + schema.res.headers (makes handler return { body, headers })
|
|
102
|
-
API.CreateHttp('GetUser', {
|
|
103
|
-
path: '/users/:id',
|
|
104
|
-
method: 'get',
|
|
105
|
-
schema: {
|
|
106
|
-
req: { pathParams: Type.Object({ id: Type.String() }) },
|
|
107
|
-
res: { body: Type.Object({ id: Type.String(), name: Type.String() }) },
|
|
108
|
-
},
|
|
109
|
-
}, async (ctx, { pathParams }) => fetchUser(pathParams.id))
|
|
107
|
+
Subclasses are checked before base classes automatically (topological sort);
|
|
108
|
+
`{ name }` is injected into bodies so client dispatch always works; framework
|
|
109
|
+
defaults (`ProcedureValidationError` → 400, etc.) layer underneath yours.
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
path: '/users',
|
|
113
|
-
method: 'post',
|
|
114
|
-
schema: {
|
|
115
|
-
req: { body: Type.Object({ name: Type.String(), email: Type.String() }) },
|
|
116
|
-
},
|
|
117
|
-
}, async (ctx, { body }) => createUser(body))
|
|
111
|
+
## Generated clients
|
|
118
112
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
.build()
|
|
122
|
-
// GET /api/users/:id → 200, POST /api/users → 201
|
|
123
|
-
```
|
|
113
|
+
Codegen consumes a `DocEnvelope` — from a live URL or a file written with
|
|
114
|
+
`writeDocEnvelope(builder, 'envelope.json')`:
|
|
124
115
|
|
|
125
|
-
|
|
116
|
+
```bash
|
|
117
|
+
npx ts-procedures-codegen --url http://localhost:3000/api/docs --out src/generated
|
|
118
|
+
# or offline:
|
|
119
|
+
npx ts-procedures-codegen --file envelope.json --out src/generated
|
|
120
|
+
```
|
|
126
121
|
|
|
127
|
-
|
|
122
|
+
```ts
|
|
123
|
+
import { createApiClient } from './generated'
|
|
128
124
|
|
|
129
|
-
|
|
125
|
+
const api = createApiClient({ basePath: 'https://api.example.com' })
|
|
130
126
|
|
|
131
|
-
|
|
127
|
+
const user = await api.users.GetUser({ id: 'u1' }) // throws typed errors
|
|
128
|
+
const result = await api.users.GetUser.safe({ id: 'u1' }) // Result<T, E> instead
|
|
132
129
|
|
|
133
|
-
|
|
130
|
+
for await (const event of api.users.WatchUsers({})) { ... } // TypedStream
|
|
131
|
+
```
|
|
134
132
|
|
|
135
|
-
- **
|
|
133
|
+
- **Typed errors:** routes declaring `errors: [...]` get real error classes —
|
|
134
|
+
`catch (e) { if (e instanceof ApiErrors.NotFound) ... }` — plus a named
|
|
135
|
+
`Errors` union per route.
|
|
136
|
+
- **Self-contained by default:** the generated directory bundles its own
|
|
137
|
+
runtime (`_client.ts` / `_types.ts`); no runtime dependency on this package.
|
|
138
|
+
- **Shared models:** schemas carrying `$id` are hoisted once into `_models.ts`
|
|
139
|
+
(or re-exported from your own package via `--shared-models-module`).
|
|
140
|
+
- **Kotlin / Swift:** `--target kotlin --kotlin-package com.example.api` or
|
|
141
|
+
`--target swift` emit types + route constants/path builders for mobile teams
|
|
142
|
+
(they own the HTTP layer).
|
|
143
|
+
- Watch mode, config file (`ts-procedures-codegen.config.json`), strict flags
|
|
144
|
+
with did-you-mean, orphaned-file pruning — see `npx ts-procedures-codegen --help`.
|
|
145
|
+
|
|
146
|
+
## Validation & schemas
|
|
147
|
+
|
|
148
|
+
- TypeBox is built in (`import { Type } from 'typebox'`); `schema.params` /
|
|
149
|
+
`schema.req.*` are validated at runtime with AJV (`allErrors`, `coerceTypes`,
|
|
150
|
+
`removeAdditional`); `schema.returnType` / `schema.res` document and drive
|
|
151
|
+
codegen.
|
|
152
|
+
- Customize AJV per factory: `Procedures({ validation: { ajv: {...} } })`.
|
|
153
|
+
- Skip per-call validation for trusted internal factories:
|
|
154
|
+
`Procedures({ validation: false })` (schemas still computed; bad schemas
|
|
155
|
+
still fail fast at registration).
|
|
156
|
+
- Plug in another schema library with a 3-line `SchemaAdapter`
|
|
157
|
+
(`Procedures({ schema: { adapters: [zodAdapter] } })`).
|
|
158
|
+
|
|
159
|
+
## Streaming
|
|
160
|
+
|
|
161
|
+
Stream handlers always receive `ctx.signal` — it aborts on client disconnect,
|
|
162
|
+
and with reason `'stream-completed'` on normal completion. Yields become SSE
|
|
163
|
+
events (customize with `sse(data, { event, id, retry })`); the generator's
|
|
164
|
+
return value arrives as the `event: 'return'` payload, surfaced by generated
|
|
165
|
+
clients as `await stream.result`. Opt into per-yield validation with
|
|
166
|
+
`validateYields: true`.
|
|
167
|
+
|
|
168
|
+
## Build your own server adapter
|
|
169
|
+
|
|
170
|
+
Everything the Hono adapter uses lives in `ts-procedures/server`, framework-free:
|
|
171
|
+
route-doc builders, taxonomy dispatch (data in, data out), request channel
|
|
172
|
+
extraction (`RequestSource`), SSE metadata, `DocRegistry`. A Fastify or Express
|
|
173
|
+
adapter is a few thin handlers — `src/adapters/hono/` is the reference
|
|
174
|
+
implementation.
|
|
175
|
+
|
|
176
|
+
## Subpaths
|
|
177
|
+
|
|
178
|
+
| Import | Contents |
|
|
179
|
+
|---|---|
|
|
180
|
+
| `ts-procedures` | `Procedures`, error classes, schema utilities, `writeDocEnvelope` |
|
|
181
|
+
| `ts-procedures/hono` | `HonoAppBuilder`, `defineErrorTaxonomy`, `sse`, `DocRegistry` |
|
|
182
|
+
| `ts-procedures/astro` | `createAstroHandler`, `getAstroContext` |
|
|
183
|
+
| `ts-procedures/server` | Transport-agnostic adapter toolkit |
|
|
184
|
+
| `ts-procedures/http` | HTTP doc/config types (type-only) |
|
|
185
|
+
| `ts-procedures/http-docs` | `DocRegistry` |
|
|
186
|
+
| `ts-procedures/http-errors` | Error taxonomy helpers |
|
|
187
|
+
| `ts-procedures/client` | Runtime client (`createClient`, adapters, hooks, errors) |
|
|
188
|
+
| `ts-procedures/codegen` | `generateClient` programmatic API |
|
|
189
|
+
|
|
190
|
+
## AI assistant setup
|
|
191
|
+
|
|
192
|
+
The package ships rules and skills for Claude Code, Cursor, and GitHub
|
|
193
|
+
Copilot so your AI tooling knows the framework's patterns and footguns:
|
|
136
194
|
|
|
137
|
-
|
|
195
|
+
```bash
|
|
196
|
+
npx ts-procedures-setup # all targets
|
|
197
|
+
npx ts-procedures-setup claude # Claude Code only
|
|
198
|
+
npx ts-procedures-setup --dry-run # preview
|
|
199
|
+
```
|
|
138
200
|
|
|
139
|
-
|
|
201
|
+
Installed files auto-update on subsequent `npm install` via the package's
|
|
202
|
+
postinstall hook.
|
|
140
203
|
|
|
141
|
-
|
|
204
|
+
## Migrating from v8
|
|
142
205
|
|
|
143
|
-
|
|
206
|
+
Generated client output is byte-identical to v8.6.0 — consumers have nothing
|
|
207
|
+
to do. Server-side breaking changes are small and mechanical; see
|
|
208
|
+
[docs/migration-v8-to-v9.md](docs/migration-v8-to-v9.md).
|
|
144
209
|
|
|
145
210
|
## License
|
|
146
211
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-procedures",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"description": "AI coding assistant plugin for ts-procedures — a TypeScript RPC framework for type-safe, schema-validated procedure calls with automatic validation, streaming support, and HTTP framework integrations."
|
|
5
5
|
}
|
|
@@ -32,14 +32,16 @@ When asked to plan an API or procedure set:
|
|
|
32
32
|
- Handlers receive `(ctx, params)` where ctx includes base context + `error()` function + optional `signal`.
|
|
33
33
|
- Stream handlers always get `ctx.signal` (guaranteed `AbortSignal`). Standard handlers get it when provided by the HTTP implementation.
|
|
34
34
|
- Pass `signal` to all downstream async calls (fetch, database queries) for cancellation support.
|
|
35
|
-
- `onCreate` callback on the factory enables framework integration — use it for route registration, middleware setup, or documentation generation.
|
|
35
|
+
- `onCreate` callback on the factory enables framework integration — use it for route registration, middleware setup, or documentation generation. Every registration carries a `kind` discriminant (`'rpc' | 'rpc-stream' | 'http' | 'http-stream'`). For a full custom server adapter, build on the transport-agnostic `ts-procedures/server` toolkit (route-doc builders, error dispatch, request channel extraction, SSE sequencing).
|
|
36
36
|
- `getProcedures()` returns all registered procedures for introspection (OpenAPI generation, testing, etc.).
|
|
37
|
-
- AJV is configured with `allErrors: true`, `coerceTypes: true`, `removeAdditional: true
|
|
38
|
-
-
|
|
39
|
-
-
|
|
37
|
+
- AJV is configured with `allErrors: true`, `coerceTypes: true`, `removeAdditional: true` — customizable per factory via `Procedures({ validation: { ajv } })`; `validation: false` skips per-call validation for trusted internal factories only.
|
|
38
|
+
- TypeBox is the built-in schema library; other libraries plug in via `Procedures({ schema: { adapters: [SchemaAdapter] } })` (runtime validation + docs only — `Infer<T>` works only for TypeBox).
|
|
39
|
+
- `Procedures({ http: { pathPrefix, scope } })` sets factory-level defaults for `CreateHttp` / `CreateHttpStream` routes (per-route values win).
|
|
40
|
+
- `schema.params` and `schema.req` are mutually exclusive — defining both throws `ProcedureRegistrationError`.
|
|
41
|
+
- Path param names in route template (`:id`) must match `schema.req.pathParams` property names.
|
|
40
42
|
- Use `DocRegistry` to compose route docs from multiple builders — never manually wire `/docs` endpoints. Pass your taxonomy directly: `new DocRegistry({ errors: appErrors })` — framework defaults are auto-merged and deduped. For errors outside your taxonomy (middleware, infrastructure, doc-only), chain `.documentError(...docs)`.
|
|
41
43
|
- Two first-class peer error-handling modes: **declarative taxonomy** (`defineErrorTaxonomy` + `errors` config) OR **imperative callback** (`onError`). Neither is deprecated. Pick the taxonomy for structured apps with typed client dispatch; pick `onError` for simple apps or full response control. Mixing both is allowed — the taxonomy handles what it covers, `onError` handles the tail. The anti-pattern is `instanceof` ladders inside `onError` (see anti-pattern #20 in the skill reference) — that's exactly what the taxonomy expresses declaratively.
|
|
42
|
-
- Per-route `errors: ['UseCaseError', ...]` narrows typed errors on the generated client.
|
|
44
|
+
- Per-route `errors: ['UseCaseError', ...]` narrows typed errors on the generated client. For compile-time typo protection, narrow `RPCConfig<keyof typeof appErrors & string>` on RPC factories; on `CreateHttp` routes attach `satisfies (keyof typeof appErrors & string)[]` to the `errors` array (an explicit generic would bind `TName` and break `schema.req`/`schema.res` inference).
|
|
43
45
|
- Generated `_errors.ts` emits real runtime classes extending `${Service}ProcedureError` — consumers catch with `instanceof ${Service}Errors.${Name}` and access `err.body`, `err.status`, `err.procedureName`, `err.scope`. Use the generated `create${Service}Client(config)` factory to wire the error registry automatically.
|
|
44
46
|
|
|
45
47
|
## Context Design Patterns
|
|
@@ -66,11 +68,10 @@ interface AppConfig extends RPCConfig {
|
|
|
66
68
|
version: number
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
// REST-style: path
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
71
|
+
// REST-style: no extended config needed — path, method, scope, errors are
|
|
72
|
+
// first-class fields on the CreateHttp / CreateHttpStream config itself.
|
|
73
|
+
const API = Procedures<AppContext>()
|
|
74
|
+
API.CreateHttp('GetUser', { path: '/users/:id', method: 'get', schema: { /* req/res */ } }, handler)
|
|
74
75
|
```
|
|
75
76
|
|
|
76
77
|
## Output Format
|
|
@@ -39,7 +39,7 @@ This skill has three modes, selected by the **first whitespace-delimited word of
|
|
|
39
39
|
Load the right reference for your task:
|
|
40
40
|
|
|
41
41
|
- **Writing new procedures or HTTP routes?** Read [patterns.md](patterns.md) — prescribed code examples for every procedure type and HTTP integration
|
|
42
|
-
- **Reviewing or debugging existing code?** Read [anti-patterns.md](anti-patterns.md) —
|
|
42
|
+
- **Reviewing or debugging existing code?** Read [anti-patterns.md](anti-patterns.md) — 23 common mistakes with before/after fixes and severity ratings
|
|
43
43
|
- **Need exact API signatures or type definitions?** Read [api-reference.md](api-reference.md) — complete API documentation with type signatures for every export
|
|
44
44
|
- **Generating a Kotlin client for Android/JVM consumers?** See the **Kotlin Client Codegen** section below — it covers `--target kotlin` end-to-end.
|
|
45
45
|
- **Generating a Swift client for iOS/macOS/Apple-platform consumers?** See the **Swift Client Codegen** section below — it covers `--target swift` end-to-end.
|
|
@@ -47,7 +47,7 @@ Load the right reference for your task:
|
|
|
47
47
|
## Core Flow
|
|
48
48
|
|
|
49
49
|
```
|
|
50
|
-
Procedures<TContext, TExtendedConfig>(
|
|
50
|
+
Procedures<TContext, TExtendedConfig>(options?)
|
|
51
51
|
|
|
|
52
52
|
Create(name, config, handler) --> Standard async procedure
|
|
53
53
|
CreateStream(name, config, handler) --> Streaming async generator
|
|
@@ -58,21 +58,29 @@ Returns: { [name]: handler, procedure: handler, info: metadata }
|
|
|
58
58
|
## Factory API
|
|
59
59
|
|
|
60
60
|
```typescript
|
|
61
|
-
const { Create, CreateStream, getProcedures, getProcedure, removeProcedure, clear } =
|
|
61
|
+
const { Create, CreateStream, CreateHttp, CreateHttpStream, getProcedures, getProcedure, removeProcedure, clear } =
|
|
62
62
|
Procedures<TContext, TExtendedConfig>({
|
|
63
|
-
onCreate: (procedure) => { /* called on each registration */ }
|
|
63
|
+
onCreate: (procedure) => { /* called on each registration — narrow on procedure.kind */ },
|
|
64
|
+
validation: false, // optional: skip per-call AJV (replaces v8 noRuntimeValidation)
|
|
65
|
+
// validation: { ajv: { coerceTypes: false } }, // or per-factory AJV options / instance
|
|
66
|
+
schema: { adapters: [myZodAdapter] }, // optional: plug in other schema libraries (TypeBox built in)
|
|
67
|
+
http: { pathPrefix: '/v1', scope: 'billing' }, // optional: CreateHttp/CreateHttpStream defaults (per-route wins)
|
|
64
68
|
})
|
|
65
69
|
```
|
|
66
70
|
|
|
67
71
|
| Method | Purpose |
|
|
68
72
|
|--------|---------|
|
|
69
|
-
| `Create(name, config, handler)` | Register standard async procedure |
|
|
70
|
-
| `CreateStream(name, config, handler)` | Register streaming procedure (async generator) |
|
|
73
|
+
| `Create(name, config, handler)` | Register standard async procedure (`kind: 'rpc'`) |
|
|
74
|
+
| `CreateStream(name, config, handler)` | Register streaming procedure (async generator, `kind: 'rpc-stream'`) |
|
|
75
|
+
| `CreateHttp(name, config, handler)` | Register REST-style HTTP procedure (`kind: 'http'`) |
|
|
76
|
+
| `CreateHttpStream(name, config, handler)` | Register streaming HTTP procedure (`kind: 'http-stream'`) |
|
|
71
77
|
| `getProcedures()` | Returns array of all registered procedures |
|
|
72
78
|
| `getProcedure(name)` | Get single procedure by name |
|
|
73
79
|
| `removeProcedure(name)` | Remove procedure by name |
|
|
74
80
|
| `clear()` | Remove all procedures |
|
|
75
81
|
|
|
82
|
+
Every registration (and every creator's `info`) carries a `kind` discriminant: `'rpc' | 'rpc-stream' | 'http' | 'http-stream'`. Registering the same name twice throws `ProcedureRegistrationError`.
|
|
83
|
+
|
|
76
84
|
## Context
|
|
77
85
|
|
|
78
86
|
Handlers receive `(ctx, params)` where ctx includes:
|
|
@@ -94,7 +102,9 @@ Uses **TypeBox** for schema definitions (`import { Type } from 'typebox'`):
|
|
|
94
102
|
| `schema.yieldType` | Validated only if `validateYields: true` in CreateStream config |
|
|
95
103
|
| `schema.req` | Structured multi-channel HTTP input (`pathParams`, `query`, `body`, `headers`) — available on `CreateHttp` / `CreateHttpStream` only |
|
|
96
104
|
|
|
97
|
-
AJV config: `allErrors: true`, `coerceTypes: true`, `removeAdditional: true`
|
|
105
|
+
AJV config: `allErrors: true`, `coerceTypes: true`, `removeAdditional: true` — customizable per factory via `Procedures({ validation: { ajv } })` (options merged over the defaults, or a configured `Ajv` instance).
|
|
106
|
+
|
|
107
|
+
TypeBox is the only built-in schema library. Other libraries plug in via the 3-member `SchemaAdapter` interface (`{ name, detect, toJsonSchema }`) passed as `Procedures({ schema: { adapters: [...] } })` — custom adapters get runtime validation + docs, but compile-time inference (`Infer<T>`) works only for TypeBox.
|
|
98
108
|
|
|
99
109
|
> **Composing schemas:** the bundled TypeBox does **not** export `Type.Composite`. Extend a schema with a flat property spread — `Type.Object({ ...Base.properties, name: Type.String() })` — which also keeps the generated JSON Schema a single `object` instead of an `allOf`.
|
|
100
110
|
|
|
@@ -108,7 +118,7 @@ AJV config: `allErrors: true`, `coerceTypes: true`, `removeAdditional: true`
|
|
|
108
118
|
| `ProcedureRegistrationError` | Invalid schema at registration time | `procedureName`, `message` |
|
|
109
119
|
| `${Service}ProcedureError` (generated, client) | Base class for all generated client error classes | `status`, `procedureName`, `scope`, `body` |
|
|
110
120
|
|
|
111
|
-
All errors include `definedAt` (file:line:column) and enhanced stack traces pointing to the procedure definition location.
|
|
121
|
+
All errors include `definedAt` (file:line:column) and enhanced stack traces pointing to the procedure definition location. Every framework error also carries a `kind` discriminant (`'procedure' | 'validation' | 'yield-validation' | 'registration'`) as an alternative to `instanceof`.
|
|
112
122
|
|
|
113
123
|
## Error Taxonomy (HTTP builders)
|
|
114
124
|
|
|
@@ -136,6 +146,8 @@ Full contract: `docs/http-integrations.md § Error Handling` (canonical) and `ap
|
|
|
136
146
|
| `HonoAppBuilder` | `ts-procedures/hono` | RPC, REST-style HTTP, and streaming (SSE / newline-JSON) — one builder dispatches all four procedure kinds |
|
|
137
147
|
| `DocRegistry` | `ts-procedures/http-docs` | Compose route docs from multiple builders (single-app users can also call `builder.toDocEnvelope()`) |
|
|
138
148
|
|
|
149
|
+
Building on another framework (Fastify, Express, raw http, ...)? Use the transport-agnostic **`ts-procedures/server`** toolkit — route-doc builders, data-in/data-out error dispatch (`dispatchPreStreamError` / `dispatchMidStreamError`), `RequestSource` channel extraction, `SseEventSequencer`, `DocRegistry`. A custom adapter is ~4 thin handlers; `src/adapters/hono/` is the reference. See `api-reference.md § Server Toolkit`.
|
|
150
|
+
|
|
139
151
|
### Route Path Format (RPC)
|
|
140
152
|
|
|
141
153
|
```
|
|
@@ -154,7 +166,7 @@ const app = new HonoAppBuilder({ pathPrefix: '/api' })
|
|
|
154
166
|
|
|
155
167
|
### Lifecycle Hooks (HTTP builders)
|
|
156
168
|
|
|
157
|
-
For `HonoAppBuilder
|
|
169
|
+
For `HonoAppBuilder`, hooks are stratified: cross-cutting hooks live at the top level, kind-specific hooks live inside `rpc:` / `api:` / `stream:` blocks.
|
|
158
170
|
|
|
159
171
|
| Hook | Block | When |
|
|
160
172
|
|------|-------|------|
|
|
@@ -203,7 +215,8 @@ The npm package ships user-facing documentation with narrative explanations and
|
|
|
203
215
|
| `docs/client-error-handling.md` | **Canonical guide** for 7.0+ client error surface: normalized error classes, `.safe()` Result API, `ClientErrorMap` augmentation, custom `ErrorClassifier`, migration from `ClientRequestError`. |
|
|
204
216
|
| `docs/codegen-kotlin.md` | Kotlin target consumer setup (Gradle deps, contextual serializers, sealed interfaces) |
|
|
205
217
|
| `docs/codegen-swift.md` | Swift target consumer setup (SPM/Xcode integration, JSONDecoder config, discriminated unions, error dispatch patterns) |
|
|
206
|
-
| `
|
|
218
|
+
| `docs/migration-v8-to-v9.md` | Every v8 → v9 breaking change with before/after (`validation: false` replaces `noRuntimeValidation`, Suretype removal, `kind` discriminants, `ts-procedures/server`) |
|
|
219
|
+
| `CHANGELOG.md` | Release notes — see `[9.0.0]` for the factory options bag, `SchemaAdapter`, the `ts-procedures/server` toolkit, and SSE wire normalization. See `[7.0.0]` for the safe-result API, new error classes, and `ClientRequestError` → `ClientHttpError` rename. See `[6.0.0]` for the peer error-handling model (taxonomy + `onError` + `onRequestError`). |
|
|
207
220
|
|
|
208
221
|
## Workflow
|
|
209
222
|
|
|
@@ -222,9 +235,9 @@ Parse the remainder of `$ARGUMENTS` (everything after `review`) as a file or dir
|
|
|
222
235
|
### Instructions
|
|
223
236
|
|
|
224
237
|
1. Read the target file(s).
|
|
225
|
-
2. Identify ts-procedures imports (`ts-procedures`, `ts-procedures/hono`, `ts-procedures/http`, `ts-procedures/http-docs`, `ts-procedures/http-errors`, `ts-procedures/client`, `ts-procedures/codegen`) to determine file types.
|
|
238
|
+
2. Identify ts-procedures imports (`ts-procedures`, `ts-procedures/hono`, `ts-procedures/astro`, `ts-procedures/server`, `ts-procedures/http`, `ts-procedures/http-docs`, `ts-procedures/http-errors`, `ts-procedures/client`, `ts-procedures/codegen`) to determine file types.
|
|
226
239
|
3. Check each file against the categorized checklist in [checklist.md](checklist.md).
|
|
227
|
-
4. For detailed code examples of each violation pattern, reference [anti-patterns.md](anti-patterns.md) — it shows
|
|
240
|
+
4. For detailed code examples of each violation pattern, reference [anti-patterns.md](anti-patterns.md) — it shows 23 common mistakes with before/after code fixes and severity ratings.
|
|
228
241
|
5. Output findings grouped by severity.
|
|
229
242
|
|
|
230
243
|
### Output Format
|
|
@@ -397,7 +397,7 @@ Create('GetUser', {
|
|
|
397
397
|
}, handler)
|
|
398
398
|
```
|
|
399
399
|
|
|
400
|
-
**Why:** ts-procedures detects
|
|
400
|
+
**Why:** ts-procedures detects schemas via the adapter chain — the built-in `typeboxAdapter` recognizes TypeBox's `~kind` marker. Plain JSON Schema objects are not recognized (no adapter matches) and will throw `ProcedureRegistrationError`. If you must use another schema library, register a custom `SchemaAdapter` via `Procedures({ schema: { adapters: [...] } })` instead of passing raw objects.
|
|
401
401
|
|
|
402
402
|
---
|
|
403
403
|
|
|
@@ -705,17 +705,17 @@ Or use the `.safe()` sibling for exhaustive Result-based narrowing (see `pattern
|
|
|
705
705
|
|
|
706
706
|
---
|
|
707
707
|
|
|
708
|
-
## 22. Using `
|
|
708
|
+
## 22. Using `validation: false` on a public-facing factory
|
|
709
709
|
|
|
710
|
-
**Problem:** Setting `Procedures({ config: { noRuntimeValidation: true }
|
|
710
|
+
**Problem:** Setting `Procedures({ validation: false })` (which replaces v8's `config: { noRuntimeValidation: true }`) on a factory whose procedures are exposed via HTTP, mounted on a public surface, or invoked with caller-supplied JSON. Schema validation is the only thing standing between untyped wire data and your handlers — turning it off lets malformed payloads reach business logic.
|
|
711
711
|
|
|
712
712
|
```typescript
|
|
713
713
|
// BAD — these procedures are mounted on Hono and called by browsers
|
|
714
|
-
const {
|
|
714
|
+
const { CreateHttp } = Procedures({ validation: false })
|
|
715
715
|
|
|
716
|
-
const { CreateUser } =
|
|
716
|
+
const { CreateUser } = CreateHttp('CreateUser', {
|
|
717
717
|
path: '/users', method: 'post',
|
|
718
|
-
schema: {
|
|
718
|
+
schema: { req: { body: Type.Object({ email: Type.String() }) } },
|
|
719
719
|
}, async (ctx, { body }) => {
|
|
720
720
|
// body.email is typed `string`, but at runtime it can be anything —
|
|
721
721
|
// the request validator was disabled at the factory level.
|
|
@@ -730,12 +730,10 @@ const { CreateUser } = Create('CreateUser', {
|
|
|
730
730
|
const { Create: CreatePublic } = Procedures()
|
|
731
731
|
|
|
732
732
|
// GOOD — internal factory used only from already-validated callers
|
|
733
|
-
const { Create: CreateInternal } = Procedures({
|
|
734
|
-
config: { noRuntimeValidation: true },
|
|
735
|
-
})
|
|
733
|
+
const { Create: CreateInternal } = Procedures({ validation: false })
|
|
736
734
|
```
|
|
737
735
|
|
|
738
|
-
**Why:** `
|
|
736
|
+
**Why:** `validation: false` skips both `schema.params` and `schema.req` AJV runs for every procedure on the factory — there is no per-procedure escape hatch (JSON Schema and validators are still computed at registration, so bad schemas still fail fast). TypeScript types still flow, but TS types vanish at runtime. AJV is also what enforces `coerceTypes` and `removeAdditional`; once disabled, extra wire fields will leak through and string/number coercion stops happening. The safe default — validation on — is expressed by leaving the option unset; the only opt-out value is the explicit literal `false`.
|
|
739
737
|
|
|
740
738
|
---
|
|
741
739
|
|
|
@@ -800,9 +798,9 @@ API.CreateHttp('GetUser', {
|
|
|
800
798
|
| 15 | Manual doc building instead of extendProcedureDoc | Fragile, incomplete documentation | SUGGESTION |
|
|
801
799
|
| 16 | Manual /docs endpoint instead of DocRegistry | Duplicated boilerplate, missing error schemas | SUGGESTION |
|
|
802
800
|
| 17 | Unhandled async context factory | Request crashes | WARNING |
|
|
803
|
-
| 18 | Both schema.params and schema.
|
|
801
|
+
| 18 | Both schema.params and schema.req | ProcedureRegistrationError at startup | CRITICAL |
|
|
804
802
|
| 19 | Mismatched path param names | Build-time error or confusing validation failures | CRITICAL |
|
|
805
803
|
| 20 | Hand-writing onError instanceof ladders | Drifting response shapes, untyped client errors | WARNING |
|
|
806
804
|
| 21 | Catching raw DOMException/TypeError from generated callables | Framework normalizes these; raw platform errors won't reach catch blocks after 7.0.0 | WARNING |
|
|
807
|
-
| 22 | `
|
|
805
|
+
| 22 | `validation: false` on a public-facing factory | Untrusted wire data reaches handlers without AJV; coerceTypes/removeAdditional also disabled | CRITICAL |
|
|
808
806
|
| 23 | Using `Create` for HTTP routes (v8+) | ProcedureRegistrationError at startup; HTTP fields require `CreateHttp` / `CreateHttpStream` | CRITICAL |
|