ts-procedures 8.5.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (635) hide show
  1. package/README.md +166 -101
  2. package/agent_config/claude-code/.claude-plugin/plugin.json +1 -1
  3. package/agent_config/claude-code/agents/ts-procedures-architect.md +11 -10
  4. package/agent_config/claude-code/skills/ts-procedures/SKILL.md +25 -12
  5. package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +10 -12
  6. package/agent_config/claude-code/skills/ts-procedures/api-reference.md +141 -45
  7. package/agent_config/claude-code/skills/ts-procedures/checklist.md +7 -6
  8. package/agent_config/claude-code/skills/ts-procedures/patterns.md +45 -6
  9. package/agent_config/claude-code/skills/ts-procedures/templates/client.md +1 -1
  10. package/agent_config/claude-code/skills/ts-procedures/templates/hono.md +1 -1
  11. package/agent_config/copilot/copilot-instructions.md +50 -33
  12. package/agent_config/cursor/cursorrules +50 -33
  13. package/build/adapters/astro/astro-context.js.map +1 -0
  14. package/build/adapters/astro/create-handler.js.map +1 -0
  15. package/build/adapters/astro/index.js.map +1 -0
  16. package/build/{implementations/http → adapters}/astro/index.test.js +1 -1
  17. package/build/adapters/astro/index.test.js.map +1 -0
  18. package/build/adapters/astro/rewrite-request.js.map +1 -0
  19. package/build/adapters/hono/envelope-parity.test.js +98 -0
  20. package/build/adapters/hono/envelope-parity.test.js.map +1 -0
  21. package/build/{implementations/http → adapters}/hono/handlers/http-stream.d.ts +1 -1
  22. package/build/adapters/hono/handlers/http-stream.js +55 -0
  23. package/build/adapters/hono/handlers/http-stream.js.map +1 -0
  24. package/build/{implementations/http → adapters}/hono/handlers/http-stream.test.js +1 -1
  25. package/build/adapters/hono/handlers/http-stream.test.js.map +1 -0
  26. package/build/{implementations/http → adapters}/hono/handlers/http.d.ts +1 -1
  27. package/build/adapters/hono/handlers/http.js +50 -0
  28. package/build/adapters/hono/handlers/http.js.map +1 -0
  29. package/build/{implementations/http → adapters}/hono/handlers/http.test.js +1 -1
  30. package/build/adapters/hono/handlers/http.test.js.map +1 -0
  31. package/build/{implementations/http → adapters}/hono/handlers/rpc.d.ts +2 -2
  32. package/build/adapters/hono/handlers/rpc.js +23 -0
  33. package/build/adapters/hono/handlers/rpc.js.map +1 -0
  34. package/build/{implementations/http → adapters}/hono/handlers/rpc.test.js +1 -1
  35. package/build/adapters/hono/handlers/rpc.test.js.map +1 -0
  36. package/build/adapters/hono/handlers/stream.d.ts +12 -0
  37. package/build/adapters/hono/handlers/stream.js +89 -0
  38. package/build/adapters/hono/handlers/stream.js.map +1 -0
  39. package/build/{implementations/http → adapters}/hono/handlers/stream.test.js +3 -2
  40. package/build/adapters/hono/handlers/stream.test.js.map +1 -0
  41. package/build/{implementations/http → adapters}/hono/index.d.ts +24 -12
  42. package/build/{implementations/http → adapters}/hono/index.js +19 -8
  43. package/build/adapters/hono/index.js.map +1 -0
  44. package/build/{implementations/http → adapters}/hono/index.test.js +2 -4
  45. package/build/adapters/hono/index.test.js.map +1 -0
  46. package/build/{implementations/http → adapters/hono}/on-request-error.test.js +2 -2
  47. package/build/adapters/hono/on-request-error.test.js.map +1 -0
  48. package/build/adapters/hono/request.d.ts +7 -0
  49. package/build/adapters/hono/request.js +22 -0
  50. package/build/adapters/hono/request.js.map +1 -0
  51. package/build/{implementations/http → adapters/hono}/route-errors.test.js +4 -4
  52. package/build/adapters/hono/route-errors.test.js.map +1 -0
  53. package/build/adapters/hono/types.d.ts +55 -0
  54. package/build/adapters/hono/types.js +19 -0
  55. package/build/adapters/hono/types.js.map +1 -0
  56. package/build/client/freeze.test.js +39 -0
  57. package/build/client/freeze.test.js.map +1 -0
  58. package/build/client/typed-error-dispatch.test.js +2 -2
  59. package/build/client/typed-error-dispatch.test.js.map +1 -1
  60. package/build/codegen/__fixtures__/make-envelope.d.ts +1 -1
  61. package/build/codegen/bin/cli.d.ts +5 -0
  62. package/build/codegen/bin/cli.js +139 -182
  63. package/build/codegen/bin/cli.js.map +1 -1
  64. package/build/codegen/bin/cli.test.js +12 -2
  65. package/build/codegen/bin/cli.test.js.map +1 -1
  66. package/build/codegen/bin/flag-specs.d.ts +9 -0
  67. package/build/codegen/bin/flag-specs.js +33 -31
  68. package/build/codegen/bin/flag-specs.js.map +1 -1
  69. package/build/codegen/bin/flag-specs.test.js +14 -1
  70. package/build/codegen/bin/flag-specs.test.js.map +1 -1
  71. package/build/codegen/collect-models.d.ts +1 -1
  72. package/build/codegen/emit/api-route.d.ts +8 -0
  73. package/build/codegen/emit/api-route.js +156 -0
  74. package/build/codegen/emit/api-route.js.map +1 -0
  75. package/build/codegen/emit/context.d.ts +30 -0
  76. package/build/codegen/emit/context.js +2 -0
  77. package/build/codegen/emit/context.js.map +1 -0
  78. package/build/codegen/emit/declarations.d.ts +24 -0
  79. package/build/codegen/emit/declarations.js +48 -0
  80. package/build/codegen/emit/declarations.js.map +1 -0
  81. package/build/codegen/emit/format-types.d.ts +61 -0
  82. package/build/codegen/emit/format-types.js +188 -0
  83. package/build/codegen/emit/format-types.js.map +1 -0
  84. package/build/codegen/emit/http-stream-route.d.ts +7 -0
  85. package/build/codegen/emit/http-stream-route.js +138 -0
  86. package/build/codegen/emit/http-stream-route.js.map +1 -0
  87. package/build/codegen/emit/route-shared.d.ts +35 -0
  88. package/build/codegen/emit/route-shared.js +88 -0
  89. package/build/codegen/emit/route-shared.js.map +1 -0
  90. package/build/codegen/emit/rpc-route.d.ts +7 -0
  91. package/build/codegen/emit/rpc-route.js +37 -0
  92. package/build/codegen/emit/rpc-route.js.map +1 -0
  93. package/build/codegen/emit/scope-file.d.ts +39 -0
  94. package/build/codegen/emit/scope-file.js +166 -0
  95. package/build/codegen/emit/scope-file.js.map +1 -0
  96. package/build/codegen/emit/stream-route.d.ts +7 -0
  97. package/build/codegen/emit/stream-route.js +62 -0
  98. package/build/codegen/emit/stream-route.js.map +1 -0
  99. package/build/codegen/emit-errors.d.ts +1 -1
  100. package/build/codegen/emit-errors.integration.test.js +1 -1
  101. package/build/codegen/emit-errors.integration.test.js.map +1 -1
  102. package/build/codegen/emit-index.js +13 -0
  103. package/build/codegen/emit-index.js.map +1 -1
  104. package/build/codegen/emit-index.test.js +25 -0
  105. package/build/codegen/emit-index.test.js.map +1 -1
  106. package/build/codegen/emit-scope.d.ts +13 -30
  107. package/build/codegen/emit-scope.js +15 -807
  108. package/build/codegen/emit-scope.js.map +1 -1
  109. package/build/codegen/emit-scope.test.js +86 -4
  110. package/build/codegen/emit-scope.test.js.map +1 -1
  111. package/build/codegen/goldens.test.js +69 -0
  112. package/build/codegen/goldens.test.js.map +1 -0
  113. package/build/codegen/group-routes.d.ts +1 -1
  114. package/build/codegen/pipeline.d.ts +1 -1
  115. package/build/codegen/resolve-envelope.d.ts +1 -1
  116. package/build/codegen/targets/_shared/error-schemas.d.ts +1 -1
  117. package/build/codegen/targets/_shared/route-slots.d.ts +1 -1
  118. package/build/codegen/targets/_shared/target-run.d.ts +1 -1
  119. package/build/codegen/targets/kotlin/emit-route-kotlin.d.ts +1 -1
  120. package/build/codegen/targets/swift/emit-route-swift.d.ts +1 -1
  121. package/build/core/create-http-stream.d.ts +50 -0
  122. package/build/core/create-http-stream.js +108 -0
  123. package/build/core/create-http-stream.js.map +1 -0
  124. package/build/{create-http-stream.test.js → core/create-http-stream.test.js} +1 -1
  125. package/build/core/create-http-stream.test.js.map +1 -0
  126. package/build/core/create-http.d.ts +51 -0
  127. package/build/core/create-http.js +65 -0
  128. package/build/core/create-http.js.map +1 -0
  129. package/build/{create-http.test.js → core/create-http.test.js} +13 -4
  130. package/build/core/create-http.test.js.map +1 -0
  131. package/build/core/create-stream.d.ts +26 -0
  132. package/build/core/create-stream.js +80 -0
  133. package/build/core/create-stream.js.map +1 -0
  134. package/build/{create-stream.test.js → core/create-stream.test.js} +23 -28
  135. package/build/core/create-stream.test.js.map +1 -0
  136. package/build/core/create.d.ts +22 -0
  137. package/build/core/create.js +71 -0
  138. package/build/core/create.js.map +1 -0
  139. package/build/{create.test.js → core/create.test.js} +25 -46
  140. package/build/core/create.test.js.map +1 -0
  141. package/build/core/definition-site.d.ts +24 -0
  142. package/build/{stack-utils.js → core/definition-site.js} +20 -20
  143. package/build/core/definition-site.js.map +1 -0
  144. package/build/{stack-utils.test.js → core/definition-site.test.js} +12 -3
  145. package/build/core/definition-site.test.js.map +1 -0
  146. package/build/{errors.d.ts → core/errors.d.ts} +19 -8
  147. package/build/{errors.js → core/errors.js} +21 -26
  148. package/build/core/errors.js.map +1 -0
  149. package/build/core/errors.test.js.map +1 -0
  150. package/build/core/factory-options.test.js +82 -0
  151. package/build/core/factory-options.test.js.map +1 -0
  152. package/build/core/http-route.d.ts +13 -0
  153. package/build/core/http-route.js +54 -0
  154. package/build/core/http-route.js.map +1 -0
  155. package/build/core/internal.d.ts +72 -0
  156. package/build/core/internal.js +128 -0
  157. package/build/core/internal.js.map +1 -0
  158. package/build/{migration.test.js → core/migration.test.js} +17 -1
  159. package/build/core/migration.test.js.map +1 -0
  160. package/build/core/procedures.d.ts +143 -0
  161. package/build/core/procedures.js +64 -0
  162. package/build/core/procedures.js.map +1 -0
  163. package/build/{index.test.js → core/procedures.test.js} +14 -11
  164. package/build/core/procedures.test.js.map +1 -0
  165. package/build/core/types.d.ts +182 -0
  166. package/build/{schema → core}/types.js.map +1 -1
  167. package/build/exports.d.ts +31 -11
  168. package/build/exports.js +23 -8
  169. package/build/exports.js.map +1 -1
  170. package/build/schema/adapter.d.ts +35 -0
  171. package/build/schema/adapter.js +13 -0
  172. package/build/schema/adapter.js.map +1 -0
  173. package/build/schema/adapter.test.js +53 -0
  174. package/build/schema/adapter.test.js.map +1 -0
  175. package/build/schema/compile.d.ts +37 -0
  176. package/build/schema/compile.js +38 -0
  177. package/build/schema/compile.js.map +1 -0
  178. package/build/schema/compile.test.js +78 -0
  179. package/build/schema/compile.test.js.map +1 -0
  180. package/build/schema/compute-schema.d.ts +47 -37
  181. package/build/schema/compute-schema.js +86 -29
  182. package/build/schema/compute-schema.js.map +1 -1
  183. package/build/schema/compute-schema.test.js +158 -40
  184. package/build/schema/compute-schema.test.js.map +1 -1
  185. package/build/schema/json-schema.d.ts +17 -0
  186. package/build/schema/json-schema.js +2 -0
  187. package/build/schema/json-schema.js.map +1 -0
  188. package/build/schema/typebox.d.ts +11 -0
  189. package/build/schema/typebox.js +24 -0
  190. package/build/schema/typebox.js.map +1 -0
  191. package/build/schema/typebox.test.js +34 -0
  192. package/build/schema/typebox.test.js.map +1 -0
  193. package/build/server/context.d.ts +8 -0
  194. package/build/server/context.js +7 -0
  195. package/build/server/context.js.map +1 -0
  196. package/build/server/context.test.js +16 -0
  197. package/build/server/context.test.js.map +1 -0
  198. package/build/{doc-envelope.d.ts → server/doc-envelope.d.ts} +1 -1
  199. package/build/server/doc-envelope.js.map +1 -0
  200. package/build/server/doc-envelope.test.d.ts +1 -0
  201. package/build/server/doc-envelope.test.js.map +1 -0
  202. package/build/{implementations/http → server}/doc-registry.d.ts +7 -2
  203. package/build/{implementations/http → server}/doc-registry.js +9 -5
  204. package/build/server/doc-registry.js.map +1 -0
  205. package/build/server/doc-registry.test.d.ts +1 -0
  206. package/build/{implementations/http → server}/doc-registry.test.js +27 -24
  207. package/build/server/doc-registry.test.js.map +1 -0
  208. package/build/server/docs/docs.test.d.ts +1 -0
  209. package/build/server/docs/docs.test.js +237 -0
  210. package/build/server/docs/docs.test.js.map +1 -0
  211. package/build/{implementations/http/hono → server}/docs/http-doc.d.ts +2 -2
  212. package/build/{implementations/http/hono → server}/docs/http-doc.js +1 -1
  213. package/build/server/docs/http-doc.js.map +1 -0
  214. package/build/{implementations/http/hono → server}/docs/http-stream-doc.d.ts +2 -2
  215. package/build/{implementations/http/hono → server}/docs/http-stream-doc.js +1 -1
  216. package/build/server/docs/http-stream-doc.js.map +1 -0
  217. package/build/{implementations/http/hono → server}/docs/rpc-doc.d.ts +2 -2
  218. package/build/{implementations/http/hono → server}/docs/rpc-doc.js +1 -1
  219. package/build/server/docs/rpc-doc.js.map +1 -0
  220. package/build/{implementations/http/hono → server}/docs/stream-doc.d.ts +2 -2
  221. package/build/{implementations/http/hono → server}/docs/stream-doc.js +1 -1
  222. package/build/server/docs/stream-doc.js.map +1 -0
  223. package/build/server/errors/dispatch.d.ts +96 -0
  224. package/build/{implementations/http/error-dispatch.js → server/errors/dispatch.js} +20 -10
  225. package/build/server/errors/dispatch.js.map +1 -0
  226. package/build/server/errors/dispatch.test.d.ts +1 -0
  227. package/build/server/errors/dispatch.test.js +418 -0
  228. package/build/server/errors/dispatch.test.js.map +1 -0
  229. package/build/{implementations/http/error-taxonomy.d.ts → server/errors/taxonomy.d.ts} +8 -17
  230. package/build/{implementations/http/error-taxonomy.js → server/errors/taxonomy.js} +6 -15
  231. package/build/server/errors/taxonomy.js.map +1 -0
  232. package/build/server/errors/taxonomy.test.d.ts +1 -0
  233. package/build/{implementations/http/error-taxonomy.test.js → server/errors/taxonomy.test.js} +45 -39
  234. package/build/server/errors/taxonomy.test.js.map +1 -0
  235. package/build/server/index.d.ts +29 -0
  236. package/build/server/index.js +27 -0
  237. package/build/server/index.js.map +1 -0
  238. package/build/server/no-framework-imports.test.d.ts +1 -0
  239. package/build/server/no-framework-imports.test.js +40 -0
  240. package/build/server/no-framework-imports.test.js.map +1 -0
  241. package/build/{implementations/http/hono/path.d.ts → server/paths.d.ts} +2 -3
  242. package/build/{implementations/http/hono/path.js → server/paths.js} +1 -1
  243. package/build/server/paths.js.map +1 -0
  244. package/build/server/paths.test.d.ts +1 -0
  245. package/build/server/paths.test.js +111 -0
  246. package/build/server/paths.test.js.map +1 -0
  247. package/build/server/request/params.d.ts +29 -0
  248. package/build/server/request/params.js +43 -0
  249. package/build/server/request/params.js.map +1 -0
  250. package/build/server/request/params.test.d.ts +1 -0
  251. package/build/server/request/params.test.js +91 -0
  252. package/build/server/request/params.test.js.map +1 -0
  253. package/build/server/request/query.d.ts +9 -0
  254. package/build/server/request/query.js +22 -0
  255. package/build/server/request/query.js.map +1 -0
  256. package/build/server/request/query.test.d.ts +1 -0
  257. package/build/server/request/query.test.js +60 -0
  258. package/build/server/request/query.test.js.map +1 -0
  259. package/build/server/sse.d.ts +70 -0
  260. package/build/server/sse.js +94 -0
  261. package/build/server/sse.js.map +1 -0
  262. package/build/server/sse.test.d.ts +1 -0
  263. package/build/server/sse.test.js +98 -0
  264. package/build/server/sse.test.js.map +1 -0
  265. package/build/{implementations → server}/types.d.ts +17 -15
  266. package/build/{implementations → server}/types.js.map +1 -1
  267. package/docs/astro-adapter.md +8 -9
  268. package/docs/client-and-codegen.md +4 -4
  269. package/docs/client-error-handling.md +92 -5
  270. package/docs/codegen-kotlin.md +2 -3
  271. package/docs/codegen-swift.md +1 -2
  272. package/docs/core.md +135 -54
  273. package/docs/http-integrations.md +83 -6
  274. package/docs/migration-v8-to-v9.md +192 -0
  275. package/docs/plans/2026-06-09-v9-rewrite.md +130 -0
  276. package/docs/specs/2026-06-09-v9-rewrite-design.md +221 -0
  277. package/docs/streaming.md +12 -0
  278. package/package.json +23 -47
  279. package/src/{implementations/http → adapters}/astro/index.test.ts +2 -2
  280. package/src/adapters/hono/__fixtures__/parity-envelope.json +389 -0
  281. package/src/adapters/hono/envelope-parity.test.ts +126 -0
  282. package/src/{implementations/http → adapters}/hono/handlers/http-stream.test.ts +1 -1
  283. package/src/adapters/hono/handlers/http-stream.ts +73 -0
  284. package/src/{implementations/http → adapters}/hono/handlers/http.test.ts +1 -1
  285. package/src/adapters/hono/handlers/http.ts +70 -0
  286. package/src/{implementations/http → adapters}/hono/handlers/rpc.test.ts +2 -2
  287. package/src/adapters/hono/handlers/rpc.ts +39 -0
  288. package/src/{implementations/http → adapters}/hono/handlers/stream.test.ts +4 -3
  289. package/src/{implementations/http → adapters}/hono/handlers/stream.ts +19 -92
  290. package/src/{implementations/http → adapters}/hono/index.test.ts +14 -16
  291. package/src/{implementations/http → adapters}/hono/index.ts +35 -30
  292. package/src/{implementations/http → adapters/hono}/on-request-error.test.ts +3 -3
  293. package/src/adapters/hono/request.ts +28 -0
  294. package/src/{implementations/http → adapters/hono}/route-errors.test.ts +5 -5
  295. package/src/{implementations/http → adapters}/hono/types.ts +43 -20
  296. package/src/client/freeze.test.ts +41 -0
  297. package/src/client/typed-error-dispatch.test.ts +3 -3
  298. package/src/codegen/__fixtures__/make-envelope.ts +1 -1
  299. package/src/codegen/__fixtures__/models-envelope.json +310 -0
  300. package/src/codegen/__fixtures__/users-envelope.json +9 -0
  301. package/src/codegen/__goldens__/MANIFEST.json +85 -0
  302. package/src/codegen/__goldens__/kotlin-default--models/Billing.kt +112 -0
  303. package/src/codegen/__goldens__/kotlin-default--models/BillingReports.kt +26 -0
  304. package/src/codegen/__goldens__/kotlin-default--models/Orders.kt +88 -0
  305. package/src/codegen/__goldens__/kotlin-default--users/Users.kt +189 -0
  306. package/src/codegen/__goldens__/swift-default--models/Billing.swift +97 -0
  307. package/src/codegen/__goldens__/swift-default--models/BillingReports.swift +20 -0
  308. package/src/codegen/__goldens__/swift-default--models/Orders.swift +81 -0
  309. package/src/codegen/__goldens__/swift-default--users/Users.swift +204 -0
  310. package/src/codegen/__goldens__/ts-default--models/_client.ts +1319 -0
  311. package/src/codegen/__goldens__/ts-default--models/_errors.ts +90 -0
  312. package/src/codegen/__goldens__/ts-default--models/_models.ts +10 -0
  313. package/src/codegen/__goldens__/ts-default--models/_types.ts +502 -0
  314. package/src/codegen/__goldens__/ts-default--models/billing-reports.ts +29 -0
  315. package/src/codegen/__goldens__/ts-default--models/billing.ts +67 -0
  316. package/src/codegen/__goldens__/ts-default--models/index.ts +48 -0
  317. package/src/codegen/__goldens__/ts-default--models/orders.ts +80 -0
  318. package/src/codegen/__goldens__/ts-default--users/_client.ts +1319 -0
  319. package/src/codegen/__goldens__/ts-default--users/_errors.ts +90 -0
  320. package/src/codegen/__goldens__/ts-default--users/_types.ts +502 -0
  321. package/src/codegen/__goldens__/ts-default--users/index.ts +38 -0
  322. package/src/codegen/__goldens__/ts-default--users/users.ts +169 -0
  323. package/src/codegen/__goldens__/ts-external-runtime--models/_errors.ts +90 -0
  324. package/src/codegen/__goldens__/ts-external-runtime--models/_models.ts +10 -0
  325. package/src/codegen/__goldens__/ts-external-runtime--models/billing-reports.ts +29 -0
  326. package/src/codegen/__goldens__/ts-external-runtime--models/billing.ts +67 -0
  327. package/src/codegen/__goldens__/ts-external-runtime--models/index.ts +48 -0
  328. package/src/codegen/__goldens__/ts-external-runtime--models/orders.ts +80 -0
  329. package/src/codegen/__goldens__/ts-external-runtime--users/_errors.ts +90 -0
  330. package/src/codegen/__goldens__/ts-external-runtime--users/index.ts +38 -0
  331. package/src/codegen/__goldens__/ts-external-runtime--users/users.ts +169 -0
  332. package/src/codegen/__goldens__/ts-flat--models/_client.ts +1319 -0
  333. package/src/codegen/__goldens__/ts-flat--models/_errors.ts +87 -0
  334. package/src/codegen/__goldens__/ts-flat--models/_models.ts +10 -0
  335. package/src/codegen/__goldens__/ts-flat--models/_types.ts +502 -0
  336. package/src/codegen/__goldens__/ts-flat--models/billing-reports.ts +28 -0
  337. package/src/codegen/__goldens__/ts-flat--models/billing.ts +51 -0
  338. package/src/codegen/__goldens__/ts-flat--models/index.ts +42 -0
  339. package/src/codegen/__goldens__/ts-flat--models/orders.ts +73 -0
  340. package/src/codegen/__goldens__/ts-flat--users/_client.ts +1319 -0
  341. package/src/codegen/__goldens__/ts-flat--users/_errors.ts +87 -0
  342. package/src/codegen/__goldens__/ts-flat--users/_types.ts +502 -0
  343. package/src/codegen/__goldens__/ts-flat--users/index.ts +34 -0
  344. package/src/codegen/__goldens__/ts-flat--users/users.ts +126 -0
  345. package/src/codegen/__goldens__/ts-no-share-models--models/_client.ts +1319 -0
  346. package/src/codegen/__goldens__/ts-no-share-models--models/_errors.ts +90 -0
  347. package/src/codegen/__goldens__/ts-no-share-models--models/_types.ts +502 -0
  348. package/src/codegen/__goldens__/ts-no-share-models--models/billing-reports.ts +29 -0
  349. package/src/codegen/__goldens__/ts-no-share-models--models/billing.ts +111 -0
  350. package/src/codegen/__goldens__/ts-no-share-models--models/index.ts +48 -0
  351. package/src/codegen/__goldens__/ts-no-share-models--models/orders.ts +112 -0
  352. package/src/codegen/__goldens__/ts-no-share-models--users/_client.ts +1319 -0
  353. package/src/codegen/__goldens__/ts-no-share-models--users/_errors.ts +90 -0
  354. package/src/codegen/__goldens__/ts-no-share-models--users/_types.ts +502 -0
  355. package/src/codegen/__goldens__/ts-no-share-models--users/index.ts +38 -0
  356. package/src/codegen/__goldens__/ts-no-share-models--users/users.ts +169 -0
  357. package/src/codegen/__goldens__/ts-shared-models-module--models/_client.ts +1319 -0
  358. package/src/codegen/__goldens__/ts-shared-models-module--models/_errors.ts +90 -0
  359. package/src/codegen/__goldens__/ts-shared-models-module--models/_models.ts +7 -0
  360. package/src/codegen/__goldens__/ts-shared-models-module--models/_types.ts +502 -0
  361. package/src/codegen/__goldens__/ts-shared-models-module--models/billing-reports.ts +29 -0
  362. package/src/codegen/__goldens__/ts-shared-models-module--models/billing.ts +67 -0
  363. package/src/codegen/__goldens__/ts-shared-models-module--models/index.ts +48 -0
  364. package/src/codegen/__goldens__/ts-shared-models-module--models/orders.ts +80 -0
  365. package/src/codegen/bin/cli.test.ts +13 -2
  366. package/src/codegen/bin/cli.ts +181 -144
  367. package/src/codegen/bin/flag-specs.test.ts +16 -1
  368. package/src/codegen/bin/flag-specs.ts +43 -31
  369. package/src/codegen/bundle-size.test.ts +1 -1
  370. package/src/codegen/collect-models.ts +1 -1
  371. package/src/codegen/e2e.test.ts +1 -1
  372. package/src/codegen/emit/api-route.ts +184 -0
  373. package/src/codegen/emit/context.ts +32 -0
  374. package/src/codegen/emit/declarations.ts +49 -0
  375. package/src/codegen/emit/format-types.ts +232 -0
  376. package/src/codegen/emit/http-stream-route.ts +162 -0
  377. package/src/codegen/emit/route-shared.ts +102 -0
  378. package/src/codegen/emit/rpc-route.ts +49 -0
  379. package/src/codegen/emit/scope-file.ts +226 -0
  380. package/src/codegen/emit/stream-route.ts +81 -0
  381. package/src/codegen/emit-errors.integration.test.ts +2 -2
  382. package/src/codegen/emit-errors.test.ts +1 -1
  383. package/src/codegen/emit-errors.ts +1 -1
  384. package/src/codegen/emit-index.test.ts +34 -0
  385. package/src/codegen/emit-index.ts +19 -0
  386. package/src/codegen/emit-scope.test.ts +96 -6
  387. package/src/codegen/emit-scope.ts +15 -1003
  388. package/src/codegen/goldens.test.ts +89 -0
  389. package/src/codegen/group-routes.test.ts +1 -1
  390. package/src/codegen/group-routes.ts +1 -1
  391. package/src/codegen/pipeline.test.ts +1 -1
  392. package/src/codegen/pipeline.ts +1 -1
  393. package/src/codegen/resolve-envelope.test.ts +1 -1
  394. package/src/codegen/resolve-envelope.ts +1 -1
  395. package/src/codegen/targets/_shared/error-schemas.test.ts +1 -1
  396. package/src/codegen/targets/_shared/error-schemas.ts +1 -1
  397. package/src/codegen/targets/_shared/route-slots.test.ts +1 -1
  398. package/src/codegen/targets/_shared/route-slots.ts +1 -1
  399. package/src/codegen/targets/_shared/target-run.ts +1 -1
  400. package/src/codegen/targets/kotlin/__fixtures__/users-golden.kt +6 -0
  401. package/src/codegen/targets/kotlin/emit-route-kotlin.test.ts +1 -1
  402. package/src/codegen/targets/kotlin/emit-route-kotlin.ts +1 -1
  403. package/src/codegen/targets/kotlin/emit-scope-kotlin.test.ts +1 -1
  404. package/src/codegen/targets/swift/__fixtures__/users-golden.swift +6 -0
  405. package/src/codegen/targets/swift/access-level.test.ts +1 -1
  406. package/src/codegen/targets/swift/emit-route-swift.test.ts +1 -1
  407. package/src/codegen/targets/swift/emit-route-swift.ts +1 -1
  408. package/src/codegen/targets/swift/emit-scope-swift.test.ts +1 -1
  409. package/src/codegen/targets/ts/shared-models.test.ts +1 -1
  410. package/src/{create-http-stream.test.ts → core/create-http-stream.test.ts} +1 -1
  411. package/src/core/create-http-stream.ts +207 -0
  412. package/src/{create-http.test.ts → core/create-http.test.ts} +15 -4
  413. package/src/core/create-http.ts +126 -0
  414. package/src/{create-stream.test.ts → core/create-stream.test.ts} +28 -31
  415. package/src/core/create-stream.ts +142 -0
  416. package/src/{create.test.ts → core/create.test.ts} +25 -57
  417. package/src/core/create.ts +121 -0
  418. package/src/{stack-utils.test.ts → core/definition-site.test.ts} +14 -3
  419. package/src/{stack-utils.ts → core/definition-site.ts} +20 -23
  420. package/src/{errors.test.ts → core/errors.test.ts} +1 -1
  421. package/src/{errors.ts → core/errors.ts} +30 -28
  422. package/src/core/factory-options.test.ts +112 -0
  423. package/src/core/http-route.ts +73 -0
  424. package/src/core/internal.ts +203 -0
  425. package/src/{migration.test.ts → core/migration.test.ts} +23 -1
  426. package/src/{index.test.ts → core/procedures.test.ts} +13 -11
  427. package/src/core/procedures.ts +75 -0
  428. package/src/core/types.ts +195 -0
  429. package/src/exports.ts +60 -11
  430. package/src/schema/adapter.test.ts +58 -0
  431. package/src/schema/adapter.ts +45 -0
  432. package/src/schema/compile.test.ts +95 -0
  433. package/src/schema/compile.ts +64 -0
  434. package/src/schema/compute-schema.test.ts +222 -41
  435. package/src/schema/compute-schema.ts +145 -71
  436. package/src/schema/json-schema.ts +21 -0
  437. package/src/schema/typebox.test.ts +40 -0
  438. package/src/schema/typebox.ts +27 -0
  439. package/src/server/context.test.ts +22 -0
  440. package/src/server/context.ts +18 -0
  441. package/src/{doc-envelope.test.ts → server/doc-envelope.test.ts} +2 -2
  442. package/src/{doc-envelope.ts → server/doc-envelope.ts} +1 -1
  443. package/src/{implementations/http → server}/doc-registry.test.ts +32 -26
  444. package/src/{implementations/http → server}/doc-registry.ts +11 -7
  445. package/src/server/docs/docs.test.ts +287 -0
  446. package/src/{implementations/http/hono → server}/docs/http-doc.ts +3 -3
  447. package/src/{implementations/http/hono → server}/docs/http-stream-doc.ts +3 -3
  448. package/src/{implementations/http/hono → server}/docs/rpc-doc.ts +3 -3
  449. package/src/{implementations/http/hono → server}/docs/stream-doc.ts +3 -3
  450. package/src/server/errors/dispatch.test.ts +450 -0
  451. package/src/server/errors/dispatch.ts +189 -0
  452. package/src/{implementations/http/error-taxonomy.test.ts → server/errors/taxonomy.test.ts} +45 -39
  453. package/src/{implementations/http/error-taxonomy.ts → server/errors/taxonomy.ts} +8 -17
  454. package/src/server/index.ts +29 -0
  455. package/src/server/no-framework-imports.test.ts +43 -0
  456. package/src/server/paths.test.ts +141 -0
  457. package/src/{implementations/http/hono/path.ts → server/paths.ts} +2 -13
  458. package/src/server/request/params.test.ts +143 -0
  459. package/src/server/request/params.ts +68 -0
  460. package/src/server/request/query.test.ts +70 -0
  461. package/src/server/request/query.ts +24 -0
  462. package/src/server/sse.test.ts +113 -0
  463. package/src/server/sse.ts +117 -0
  464. package/src/{implementations → server}/types.ts +17 -16
  465. package/build/create-http-stream.d.ts +0 -58
  466. package/build/create-http-stream.js +0 -122
  467. package/build/create-http-stream.js.map +0 -1
  468. package/build/create-http-stream.test.js.map +0 -1
  469. package/build/create-http.d.ts +0 -49
  470. package/build/create-http.js +0 -108
  471. package/build/create-http.js.map +0 -1
  472. package/build/create-http.test.js.map +0 -1
  473. package/build/create-stream.d.ts +0 -35
  474. package/build/create-stream.js +0 -123
  475. package/build/create-stream.js.map +0 -1
  476. package/build/create-stream.test.js.map +0 -1
  477. package/build/create.d.ts +0 -28
  478. package/build/create.js +0 -82
  479. package/build/create.js.map +0 -1
  480. package/build/create.test.js.map +0 -1
  481. package/build/doc-envelope.js.map +0 -1
  482. package/build/doc-envelope.test.js.map +0 -1
  483. package/build/errors.js.map +0 -1
  484. package/build/errors.test.js.map +0 -1
  485. package/build/implementations/http/astro/astro-context.js.map +0 -1
  486. package/build/implementations/http/astro/create-handler.js.map +0 -1
  487. package/build/implementations/http/astro/index.js.map +0 -1
  488. package/build/implementations/http/astro/index.test.js.map +0 -1
  489. package/build/implementations/http/astro/rewrite-request.js.map +0 -1
  490. package/build/implementations/http/doc-registry.js.map +0 -1
  491. package/build/implementations/http/doc-registry.test.js.map +0 -1
  492. package/build/implementations/http/error-dispatch.d.ts +0 -76
  493. package/build/implementations/http/error-dispatch.js.map +0 -1
  494. package/build/implementations/http/error-dispatch.test.js +0 -254
  495. package/build/implementations/http/error-dispatch.test.js.map +0 -1
  496. package/build/implementations/http/error-taxonomy.js.map +0 -1
  497. package/build/implementations/http/error-taxonomy.test.js.map +0 -1
  498. package/build/implementations/http/hono/docs/http-doc.js.map +0 -1
  499. package/build/implementations/http/hono/docs/http-stream-doc.js.map +0 -1
  500. package/build/implementations/http/hono/docs/rpc-doc.js.map +0 -1
  501. package/build/implementations/http/hono/docs/stream-doc.js.map +0 -1
  502. package/build/implementations/http/hono/handlers/http-stream.js +0 -123
  503. package/build/implementations/http/hono/handlers/http-stream.js.map +0 -1
  504. package/build/implementations/http/hono/handlers/http-stream.test.js.map +0 -1
  505. package/build/implementations/http/hono/handlers/http.js +0 -110
  506. package/build/implementations/http/hono/handlers/http.js.map +0 -1
  507. package/build/implementations/http/hono/handlers/http.test.js.map +0 -1
  508. package/build/implementations/http/hono/handlers/rpc.js +0 -32
  509. package/build/implementations/http/hono/handlers/rpc.js.map +0 -1
  510. package/build/implementations/http/hono/handlers/rpc.test.js.map +0 -1
  511. package/build/implementations/http/hono/handlers/stream.d.ts +0 -23
  512. package/build/implementations/http/hono/handlers/stream.js +0 -147
  513. package/build/implementations/http/hono/handlers/stream.js.map +0 -1
  514. package/build/implementations/http/hono/handlers/stream.test.js.map +0 -1
  515. package/build/implementations/http/hono/index.js.map +0 -1
  516. package/build/implementations/http/hono/index.test.js.map +0 -1
  517. package/build/implementations/http/hono/path.js.map +0 -1
  518. package/build/implementations/http/hono/path.test.js +0 -83
  519. package/build/implementations/http/hono/path.test.js.map +0 -1
  520. package/build/implementations/http/hono/types.d.ts +0 -51
  521. package/build/implementations/http/hono/types.js.map +0 -1
  522. package/build/implementations/http/on-request-error.test.js.map +0 -1
  523. package/build/implementations/http/route-errors.test.js.map +0 -1
  524. package/build/index.d.ts +0 -175
  525. package/build/index.js +0 -47
  526. package/build/index.js.map +0 -1
  527. package/build/index.test.js.map +0 -1
  528. package/build/migration.test.js.map +0 -1
  529. package/build/schema/extract-json-schema.d.ts +0 -2
  530. package/build/schema/extract-json-schema.js +0 -12
  531. package/build/schema/extract-json-schema.js.map +0 -1
  532. package/build/schema/extract-json-schema.test.js +0 -23
  533. package/build/schema/extract-json-schema.test.js.map +0 -1
  534. package/build/schema/parser.d.ts +0 -36
  535. package/build/schema/parser.js +0 -210
  536. package/build/schema/parser.js.map +0 -1
  537. package/build/schema/parser.test.js +0 -120
  538. package/build/schema/parser.test.js.map +0 -1
  539. package/build/schema/resolve-schema-lib.d.ts +0 -12
  540. package/build/schema/resolve-schema-lib.js +0 -11
  541. package/build/schema/resolve-schema-lib.js.map +0 -1
  542. package/build/schema/resolve-schema-lib.test.js +0 -17
  543. package/build/schema/resolve-schema-lib.test.js.map +0 -1
  544. package/build/schema/types.d.ts +0 -8
  545. package/build/schema/types.js +0 -2
  546. package/build/stack-utils.d.ts +0 -25
  547. package/build/stack-utils.js.map +0 -1
  548. package/build/stack-utils.test.js.map +0 -1
  549. package/build/types.d.ts +0 -142
  550. package/build/types.js +0 -2
  551. package/build/types.js.map +0 -1
  552. package/docs/decisions/2026-06-02-monorepo-split-evaluation.md +0 -80
  553. package/docs/handoffs/ajsc-named-type-collision.md +0 -134
  554. package/docs/handoffs/ajsc-named-type-support.md +0 -181
  555. package/docs/handoffs/shared-models-auto-resolve-response.md +0 -181
  556. package/docs/npm-workspaces-migration-plan.md +0 -611
  557. package/docs/superpowers/plans/2026-04-24-doc-registry-simplification.md +0 -886
  558. package/docs/superpowers/plans/2026-04-24-kotlin-codegen-target.md +0 -1265
  559. package/docs/superpowers/plans/2026-04-25-ajsc-v7-kotlin-polish.md +0 -1993
  560. package/docs/superpowers/plans/2026-04-29-safe-result-api.md +0 -2293
  561. package/docs/superpowers/plans/2026-05-07-astro-adapter.md +0 -1391
  562. package/docs/superpowers/plans/2026-05-08-create-http.md +0 -3355
  563. package/docs/superpowers/plans/2026-05-08-hono-app-builder-convergence.md +0 -3365
  564. package/docs/superpowers/plans/2026-06-05-dx-feedback-round.md +0 -1292
  565. package/docs/superpowers/plans/2026-06-06-shared-models-convention-and-diagnostics.md +0 -659
  566. package/docs/superpowers/specs/2026-04-24-kotlin-swift-codegen-design.md +0 -401
  567. package/docs/superpowers/specs/2026-04-25-ajsc-v7-kotlin-polish-design.md +0 -314
  568. package/docs/superpowers/specs/2026-04-25-swift-codegen-design.md +0 -264
  569. package/docs/superpowers/specs/2026-04-29-safe-result-api-design.md +0 -324
  570. package/docs/superpowers/specs/2026-05-07-astro-adapter-design.md +0 -252
  571. package/docs/superpowers/specs/2026-05-08-create-http-design.md +0 -409
  572. package/docs/superpowers/specs/2026-05-08-hono-app-builder-convergence-design.md +0 -411
  573. package/docs/superpowers/specs/2026-06-05-dx-feedback-round-design.md +0 -285
  574. package/src/create-http-stream.ts +0 -191
  575. package/src/create-http.ts +0 -210
  576. package/src/create-stream.ts +0 -228
  577. package/src/create.ts +0 -172
  578. package/src/implementations/http/README.md +0 -390
  579. package/src/implementations/http/error-dispatch.test.ts +0 -283
  580. package/src/implementations/http/error-dispatch.ts +0 -176
  581. package/src/implementations/http/hono/handlers/http-stream.ts +0 -152
  582. package/src/implementations/http/hono/handlers/http.ts +0 -145
  583. package/src/implementations/http/hono/handlers/rpc.ts +0 -54
  584. package/src/implementations/http/hono/path.test.ts +0 -96
  585. package/src/index.ts +0 -101
  586. package/src/schema/extract-json-schema.test.ts +0 -25
  587. package/src/schema/extract-json-schema.ts +0 -15
  588. package/src/schema/parser.test.ts +0 -182
  589. package/src/schema/parser.ts +0 -265
  590. package/src/schema/resolve-schema-lib.test.ts +0 -19
  591. package/src/schema/resolve-schema-lib.ts +0 -29
  592. package/src/schema/types.ts +0 -20
  593. package/src/types.ts +0 -133
  594. /package/build/{implementations/http → adapters}/astro/astro-context.d.ts +0 -0
  595. /package/build/{implementations/http → adapters}/astro/astro-context.js +0 -0
  596. /package/build/{implementations/http → adapters}/astro/create-handler.d.ts +0 -0
  597. /package/build/{implementations/http → adapters}/astro/create-handler.js +0 -0
  598. /package/build/{implementations/http → adapters}/astro/index.d.ts +0 -0
  599. /package/build/{implementations/http → adapters}/astro/index.js +0 -0
  600. /package/build/{implementations/http → adapters}/astro/index.test.d.ts +0 -0
  601. /package/build/{implementations/http → adapters}/astro/rewrite-request.d.ts +0 -0
  602. /package/build/{implementations/http → adapters}/astro/rewrite-request.js +0 -0
  603. /package/build/{create-http-stream.test.d.ts → adapters/hono/envelope-parity.test.d.ts} +0 -0
  604. /package/build/{implementations/http → adapters}/hono/handlers/http-stream.test.d.ts +0 -0
  605. /package/build/{implementations/http → adapters}/hono/handlers/http.test.d.ts +0 -0
  606. /package/build/{implementations/http → adapters}/hono/handlers/rpc.test.d.ts +0 -0
  607. /package/build/{implementations/http → adapters}/hono/handlers/stream.test.d.ts +0 -0
  608. /package/build/{implementations/http → adapters}/hono/index.test.d.ts +0 -0
  609. /package/build/{implementations/http → adapters/hono}/on-request-error.test.d.ts +0 -0
  610. /package/build/{implementations/http → adapters/hono}/route-errors.test.d.ts +0 -0
  611. /package/build/{create-http.test.d.ts → client/freeze.test.d.ts} +0 -0
  612. /package/build/{create-stream.test.d.ts → codegen/goldens.test.d.ts} +0 -0
  613. /package/build/{create.test.d.ts → core/create-http-stream.test.d.ts} +0 -0
  614. /package/build/{doc-envelope.test.d.ts → core/create-http.test.d.ts} +0 -0
  615. /package/build/{errors.test.d.ts → core/create-stream.test.d.ts} +0 -0
  616. /package/build/{implementations/http/doc-registry.test.d.ts → core/create.test.d.ts} +0 -0
  617. /package/build/{implementations/http/error-dispatch.test.d.ts → core/definition-site.test.d.ts} +0 -0
  618. /package/build/{implementations/http/error-taxonomy.test.d.ts → core/errors.test.d.ts} +0 -0
  619. /package/build/{errors.test.js → core/errors.test.js} +0 -0
  620. /package/build/{implementations/http/hono/path.test.d.ts → core/factory-options.test.d.ts} +0 -0
  621. /package/build/{migration.test.d.ts → core/migration.test.d.ts} +0 -0
  622. /package/build/{index.test.d.ts → core/procedures.test.d.ts} +0 -0
  623. /package/build/{implementations/http/hono → core}/types.js +0 -0
  624. /package/build/schema/{extract-json-schema.test.d.ts → adapter.test.d.ts} +0 -0
  625. /package/build/schema/{parser.test.d.ts → compile.test.d.ts} +0 -0
  626. /package/build/schema/{resolve-schema-lib.test.d.ts → typebox.test.d.ts} +0 -0
  627. /package/build/{stack-utils.test.d.ts → server/context.test.d.ts} +0 -0
  628. /package/build/{doc-envelope.js → server/doc-envelope.js} +0 -0
  629. /package/build/{doc-envelope.test.js → server/doc-envelope.test.js} +0 -0
  630. /package/build/{implementations → server}/types.js +0 -0
  631. /package/src/{implementations/http → adapters}/astro/README.md +0 -0
  632. /package/src/{implementations/http → adapters}/astro/astro-context.ts +0 -0
  633. /package/src/{implementations/http → adapters}/astro/create-handler.ts +0 -0
  634. /package/src/{implementations/http → adapters}/astro/index.ts +0 -0
  635. /package/src/{implementations/http → adapters}/astro/rewrite-request.ts +0 -0
@@ -1,6 +1,10 @@
1
1
  /**
2
- * Represents a specific location in source code where a procedure was defined.
2
+ * Captures WHERE a procedure was defined (file:line:column) at registration
3
+ * time, so every error a procedure ever throws can point back to its
4
+ * definition site — not just the call site.
3
5
  */
6
+
7
+ /** A specific location in source code where a procedure was defined. */
4
8
  export type DefinitionLocation = {
5
9
  file: string
6
10
  line: number
@@ -8,21 +12,19 @@ export type DefinitionLocation = {
8
12
  raw: string
9
13
  }
10
14
 
11
- /**
12
- * Contains information about where a procedure was defined.
13
- */
15
+ /** Definition-site info attached to registrations and errors. */
14
16
  export type DefinitionInfo = {
15
17
  definedAt?: DefinitionLocation
16
18
  definitionStack?: string
17
19
  }
18
20
 
19
21
  /**
20
- * Internal ts-procedures files that should be skipped when finding user code.
21
- * Only skip the core library files, not test files or user code.
22
+ * Library-internal files skipped when walking the stack for the user's frame.
23
+ * Only core library files never test files or user code.
22
24
  */
23
25
  const INTERNAL_FILES = [
24
- '/index.ts',
25
- '/index.js',
26
+ '/procedures.ts',
27
+ '/procedures.js',
26
28
  '/create.ts',
27
29
  '/create.js',
28
30
  '/create-stream.ts',
@@ -31,19 +33,21 @@ const INTERNAL_FILES = [
31
33
  '/create-http.js',
32
34
  '/create-http-stream.ts',
33
35
  '/create-http-stream.js',
36
+ '/internal.ts',
37
+ '/internal.js',
34
38
  '/errors.ts',
35
39
  '/errors.js',
36
- '/stack-utils.ts',
37
- '/stack-utils.js',
40
+ '/definition-site.ts',
41
+ '/definition-site.js',
38
42
  '/compute-schema.ts',
39
43
  '/compute-schema.js',
40
- '/parser.ts',
41
- '/parser.js',
44
+ '/compile.ts',
45
+ '/compile.js',
42
46
  ]
43
47
 
44
48
  /**
45
- * Captures the stack trace at the call site and extracts the definition location.
46
- * Finds the first stack frame outside of ts-procedures internal files.
49
+ * Captures the stack trace at the call site and extracts the definition
50
+ * location: the first stack frame outside ts-procedures internals.
47
51
  */
48
52
  export function captureDefinitionInfo(): DefinitionInfo {
49
53
  const err = new Error()
@@ -55,8 +59,6 @@ export function captureDefinitionInfo(): DefinitionInfo {
55
59
 
56
60
  const lines = stack.split('\n')
57
61
 
58
- // Find the first frame that's not from ts-procedures internals
59
- // Skip the first line (Error message) and frames from this module
60
62
  let userFrame: string | undefined
61
63
 
62
64
  for (let i = 1; i < lines.length; i++) {
@@ -64,13 +66,11 @@ export function captureDefinitionInfo(): DefinitionInfo {
64
66
  if (!rawLine) continue
65
67
  const line = rawLine.trim()
66
68
 
67
- // Skip empty or invalid frames
68
69
  if (!line.startsWith('at ')) {
69
70
  continue
70
71
  }
71
72
 
72
- // Skip frames from ts-procedures internal source files
73
- const isInternalFile = INTERNAL_FILES.some(file => line.includes(file))
73
+ const isInternalFile = INTERNAL_FILES.some((file) => line.includes(file))
74
74
  if (isInternalFile) {
75
75
  continue
76
76
  }
@@ -109,7 +109,6 @@ export function captureDefinitionInfo(): DefinitionInfo {
109
109
  * - "at /path/to/file.ts:10:5"
110
110
  */
111
111
  function parseStackFrame(frame: string): DefinitionLocation | undefined {
112
- // Match patterns like "(path:line:column)" or just "path:line:column"
113
112
  const match = frame.match(/\(([^)]+):(\d+):(\d+)\)$/) || frame.match(/at ([^:]+):(\d+):(\d+)$/)
114
113
 
115
114
  if (match && match[1] && match[2] && match[3]) {
@@ -124,9 +123,7 @@ function parseStackFrame(frame: string): DefinitionLocation | undefined {
124
123
  return undefined
125
124
  }
126
125
 
127
- /**
128
- * Formats definition info for appending to error stacks.
129
- */
126
+ /** Formats definition info for appending to error stacks. */
130
127
  export function formatDefinitionInfo(info: DefinitionInfo, procedureName: string): string | undefined {
131
128
  if (!info.definedAt) {
132
129
  return undefined
@@ -4,7 +4,7 @@ import {
4
4
  ProcedureValidationError,
5
5
  ProcedureRegistrationError,
6
6
  } from './errors.js'
7
- import type { DefinitionInfo } from './stack-utils.js'
7
+ import type { DefinitionInfo } from './definition-site.js'
8
8
 
9
9
  describe('Error Classes', () => {
10
10
  test('ProcedureError has correct properties', () => {
@@ -1,9 +1,19 @@
1
- import type { TSchemaValidationError } from './schema/parser.js'
2
- import type { DefinitionInfo, DefinitionLocation} from './stack-utils.js';
3
- import { formatDefinitionInfo } from './stack-utils.js'
4
1
  import { kebabCase } from 'es-toolkit/string'
2
+ import type { TSchemaValidationError } from '../schema/compile.js'
3
+ import type { DefinitionInfo, DefinitionLocation } from './definition-site.js'
4
+ import { formatDefinitionInfo } from './definition-site.js'
5
5
 
6
+ /** Discriminant carried by every framework error (alternative to `instanceof`). */
7
+ export type ProcedureErrorKind = 'procedure' | 'validation' | 'yield-validation' | 'registration'
8
+
9
+ /**
10
+ * Base error for everything the framework throws. Produced by `ctx.error()`
11
+ * in handlers, and used to box non-ProcedureError throws (with the original
12
+ * error as `cause`). Carries the procedure's definition site so stack traces
13
+ * point at the definition, not just the call.
14
+ */
6
15
  export class ProcedureError extends Error {
16
+ readonly kind: ProcedureErrorKind = 'procedure'
7
17
  cause?: unknown
8
18
  readonly definedAt?: DefinitionLocation
9
19
  readonly definitionStack?: string
@@ -12,8 +22,7 @@ export class ProcedureError extends Error {
12
22
  readonly procedureName: string,
13
23
  readonly message: string,
14
24
  readonly meta?: object,
15
- // Used for error stack trace details
16
- definitionInfo?: DefinitionInfo
25
+ definitionInfo?: DefinitionInfo,
17
26
  ) {
18
27
  super(message)
19
28
  this.name = 'ProcedureError'
@@ -25,12 +34,10 @@ export class ProcedureError extends Error {
25
34
  }
26
35
 
27
36
  // https://www.dannyguo.com/blog/how-to-fix-instanceof-not-working-for-custom-errors-in-typescript/
28
- Object.setPrototypeOf(this, ProcedureError.prototype)
37
+ Object.setPrototypeOf(this, new.target.prototype)
29
38
  }
30
39
 
31
- /**
32
- * Returns a formatted string showing where the procedure was defined.
33
- */
40
+ /** Returns `file:line:column` of the procedure definition, when captured. */
34
41
  getDefinitionLocation(): string | undefined {
35
42
  if (!this.definedAt) {
36
43
  return undefined
@@ -38,9 +45,7 @@ export class ProcedureError extends Error {
38
45
  return `${this.definedAt.file}:${this.definedAt.line}:${this.definedAt.column}`
39
46
  }
40
47
 
41
- /**
42
- * Enhances the error stack with definition location information.
43
- */
48
+ /** Appends the definition-site section to the error stack. */
44
49
  private enhanceStack(): void {
45
50
  if (!this.stack || !this.definedAt) {
46
51
  return
@@ -48,7 +53,7 @@ export class ProcedureError extends Error {
48
53
 
49
54
  const definitionSection = formatDefinitionInfo(
50
55
  { definedAt: this.definedAt, definitionStack: this.definitionStack },
51
- this.procedureName
56
+ this.procedureName,
52
57
  )
53
58
 
54
59
  if (definitionSection) {
@@ -57,52 +62,49 @@ export class ProcedureError extends Error {
57
62
  }
58
63
  }
59
64
 
65
+ /** Schema validation failure for params / req channels (400 in the default taxonomy). */
60
66
  export class ProcedureValidationError extends ProcedureError {
67
+ override readonly kind = 'validation'
68
+
61
69
  constructor(
62
70
  readonly procedureName: string,
63
71
  message: string,
64
72
  readonly errors?: TSchemaValidationError[],
65
- // Used for error stack trace details
66
- definitionInfo?: DefinitionInfo
73
+ definitionInfo?: DefinitionInfo,
67
74
  ) {
68
75
  const readableErrors = errors
69
76
  ?.map((err) => `- ${kebabCase(err.instancePath).replace('-', '.')} ${err.message}`)
70
77
  .join(', ')
71
78
  super(procedureName, message + ' ' + readableErrors, { errors }, definitionInfo)
72
79
  this.name = 'ProcedureValidationError'
73
-
74
- // https://www.dannyguo.com/blog/how-to-fix-instanceof-not-working-for-custom-errors-in-typescript/
75
- Object.setPrototypeOf(this, ProcedureValidationError.prototype)
76
80
  }
77
81
  }
78
82
 
83
+ /** Invalid registration: bad schema, duplicate name, misplaced config fields. */
79
84
  export class ProcedureRegistrationError extends ProcedureError {
85
+ override readonly kind = 'registration'
86
+
80
87
  constructor(
81
88
  readonly procedureName: string,
82
89
  message: string,
83
- // Used for error stack trace details
84
- definitionInfo?: DefinitionInfo
90
+ definitionInfo?: DefinitionInfo,
85
91
  ) {
86
92
  super(procedureName, message, undefined, definitionInfo)
87
93
  this.name = 'ProcedureRegistrationError'
88
-
89
- // https://www.dannyguo.com/blog/how-to-fix-instanceof-not-working-for-custom-errors-in-typescript/
90
- Object.setPrototypeOf(this, ProcedureRegistrationError.prototype)
91
94
  }
92
95
  }
93
96
 
97
+ /** Stream yield failed schema validation (only with `validateYields: true`). */
94
98
  export class ProcedureYieldValidationError extends ProcedureError {
99
+ override readonly kind = 'yield-validation'
100
+
95
101
  constructor(
96
102
  readonly procedureName: string,
97
103
  message: string,
98
104
  readonly errors?: TSchemaValidationError[],
99
- // Used for error stack trace details
100
- definitionInfo?: DefinitionInfo
105
+ definitionInfo?: DefinitionInfo,
101
106
  ) {
102
107
  super(procedureName, message, undefined, definitionInfo)
103
108
  this.name = 'ProcedureYieldValidationError'
104
-
105
- // https://www.dannyguo.com/blog/how-to-fix-instanceof-not-working-for-custom-errors-in-typescript/
106
- Object.setPrototypeOf(this, ProcedureYieldValidationError.prototype)
107
109
  }
108
110
  }
@@ -0,0 +1,112 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { Type } from 'typebox'
3
+ import { Procedures } from './procedures.js'
4
+ import { ProcedureValidationError } from './errors.js'
5
+ import type { SchemaAdapter } from '../schema/adapter.js'
6
+
7
+ describe('Procedures factory options (new in v9)', () => {
8
+ describe('schema.adapters', () => {
9
+ // A minimal stand-in for a zod/valibot-style adapter: schema objects carry
10
+ // their JSON Schema under a custom marker key.
11
+ const fakeLibAdapter: SchemaAdapter = {
12
+ name: 'fake-lib',
13
+ detect: (s): boolean =>
14
+ typeof s === 'object' && s !== null && '__fakeJsonSchema' in s,
15
+ toJsonSchema: (s) => (s as { __fakeJsonSchema: Record<string, any> }).__fakeJsonSchema,
16
+ }
17
+ const fakeSchema = {
18
+ __fakeJsonSchema: {
19
+ type: 'object',
20
+ properties: { id: { type: 'string' } },
21
+ required: ['id'],
22
+ },
23
+ }
24
+
25
+ it('registers and validates with a custom schema adapter', async () => {
26
+ const { Create } = Procedures({ schema: { adapters: [fakeLibAdapter] } })
27
+ const { GetThing } = Create('GetThing', { schema: { params: fakeSchema } }, async (_ctx, params) => params)
28
+
29
+ await expect(GetThing({}, { id: 'a' } as never)).resolves.toEqual({ id: 'a' })
30
+ await expect(GetThing({}, {} as never)).rejects.toThrow(ProcedureValidationError)
31
+ })
32
+
33
+ it('custom adapters take precedence over the built-in TypeBox adapter', () => {
34
+ // An adapter that recognizes EVERYTHING and maps to a permissive schema —
35
+ // if it runs first, a TypeBox schema never reaches the typebox adapter.
36
+ const greedy: SchemaAdapter = {
37
+ name: 'greedy',
38
+ detect: () => true,
39
+ toJsonSchema: () => ({ type: 'object' }),
40
+ }
41
+ const { Create } = Procedures({ schema: { adapters: [greedy] } })
42
+ const { Info } = { Info: Create('Info', { schema: { params: Type.Object({ n: Type.Number() }) } }, async () => 'ok') }
43
+ expect(Info.info.schema.params).toEqual({ type: 'object' })
44
+ })
45
+
46
+ it('TypeBox keeps working with custom adapters present', async () => {
47
+ const { Create } = Procedures({ schema: { adapters: [fakeLibAdapter] } })
48
+ const { Echo } = Create('Echo', { schema: { params: Type.Object({ n: Type.Number() }) } }, async (_ctx, p) => p)
49
+ await expect(Echo({}, { n: 1 })).resolves.toEqual({ n: 1 })
50
+ })
51
+ })
52
+
53
+ describe('validation.ajv', () => {
54
+ it('merges custom AJV options over the defaults', async () => {
55
+ const { Create } = Procedures({ validation: { ajv: { coerceTypes: false } } })
56
+ const { Strict } = Create('Strict', { schema: { params: Type.Object({ n: Type.Number() }) } }, async (_ctx, p) => p)
57
+
58
+ // Default config would coerce '1' → 1; with coerceTypes off it must fail.
59
+ await expect(Strict({}, { n: '1' } as never)).rejects.toThrow(ProcedureValidationError)
60
+ await expect(Strict({}, { n: 1 })).resolves.toEqual({ n: 1 })
61
+ })
62
+ })
63
+
64
+ describe('http defaults', () => {
65
+ const reqId = { req: { pathParams: Type.Object({ id: Type.String() }) } }
66
+
67
+ it('applies pathPrefix and scope to CreateHttp routes', () => {
68
+ const { CreateHttp } = Procedures({ http: { pathPrefix: '/v1', scope: 'billing' } })
69
+ const { info } = CreateHttp(
70
+ 'GetInvoice',
71
+ { path: '/invoices/:id', method: 'get', schema: reqId },
72
+ async () => undefined,
73
+ )
74
+ expect(info.path).toBe('/v1/invoices/:id')
75
+ expect(info.scope).toBe('billing')
76
+ })
77
+
78
+ it('per-route scope wins over the factory default', () => {
79
+ const { CreateHttp } = Procedures({ http: { scope: 'billing' } })
80
+ const { info } = CreateHttp(
81
+ 'GetReport',
82
+ { path: '/reports', method: 'get', scope: 'reports', schema: {} },
83
+ async () => undefined,
84
+ )
85
+ expect(info.scope).toBe('reports')
86
+ expect(info.path).toBe('/reports')
87
+ })
88
+
89
+ it('applies pathPrefix to CreateHttpStream routes', () => {
90
+ const { CreateHttpStream } = Procedures({ http: { pathPrefix: 'v1' } })
91
+ const { info } = CreateHttpStream(
92
+ 'Watch',
93
+ { path: 'watch', method: 'get', schema: {} },
94
+ // eslint-disable-next-line require-yield
95
+ async function* () { return undefined },
96
+ )
97
+ // both prefix and path get normalized to a single joining slash
98
+ expect(info.path).toBe('/v1/watch')
99
+ })
100
+
101
+ it('path-param consistency is checked against the prefixed path', () => {
102
+ const { CreateHttp } = Procedures({ http: { pathPrefix: '/v1' } })
103
+ expect(() =>
104
+ CreateHttp(
105
+ 'Bad',
106
+ { path: '/things/:id', method: 'get', schema: {} },
107
+ async () => undefined,
108
+ ),
109
+ ).toThrow(/path parameters \[id\] but schema\.req\.pathParams is not defined/)
110
+ })
111
+ })
112
+ })
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Route-shape helpers shared by CreateHttp and CreateHttpStream.
3
+ */
4
+ import { ProcedureRegistrationError } from './errors.js'
5
+ import type { DefinitionInfo } from './definition-site.js'
6
+
7
+ const PATH_PARAM_RE = /:([a-zA-Z_][a-zA-Z0-9_]*)/g
8
+
9
+ export function extractPathParamNames(path: string): string[] {
10
+ const matches = path.match(PATH_PARAM_RE)
11
+ return matches ? matches.map((m) => m.slice(1)) : []
12
+ }
13
+
14
+ /**
15
+ * Applies the factory-level `http.pathPrefix` default to a route path.
16
+ * Both sides are normalized to exactly one joining `/`.
17
+ */
18
+ export function applyPathPrefix(prefix: string | undefined, path: string): string {
19
+ if (!prefix) return path
20
+ const normalizedPrefix = prefix.startsWith('/') ? prefix : `/${prefix}`
21
+ const trimmedPrefix = normalizedPrefix.endsWith('/') ? normalizedPrefix.slice(0, -1) : normalizedPrefix
22
+ const normalizedPath = path.startsWith('/') ? path : `/${path}`
23
+ return `${trimmedPrefix}${normalizedPath}`
24
+ }
25
+
26
+ /**
27
+ * Registration-time guard: the `:params` in the path and the keys of
28
+ * `schema.req.pathParams` must agree exactly. Catches typos where a handler
29
+ * would silently receive `undefined` for a misspelled param.
30
+ */
31
+ export function checkPathParamConsistency(
32
+ procedureName: string,
33
+ path: string,
34
+ pathParamsSchema: Record<string, unknown> | undefined,
35
+ definitionInfo: DefinitionInfo,
36
+ ): void {
37
+ const pathParamNames = extractPathParamNames(path)
38
+ const hasPathParams = pathParamNames.length > 0
39
+ const hasSchema = pathParamsSchema !== undefined
40
+
41
+ if (hasPathParams && !hasSchema) {
42
+ throw new ProcedureRegistrationError(
43
+ procedureName,
44
+ `Path "${path}" has path parameters [${pathParamNames.join(', ')}] but schema.req.pathParams is not defined.`,
45
+ definitionInfo,
46
+ )
47
+ }
48
+ if (!hasPathParams && hasSchema) {
49
+ throw new ProcedureRegistrationError(
50
+ procedureName,
51
+ `schema.req.pathParams is defined but path "${path}" has no path parameters.`,
52
+ definitionInfo,
53
+ )
54
+ }
55
+ if (hasPathParams && hasSchema) {
56
+ const schemaProperties = (pathParamsSchema as { properties?: Record<string, unknown> }).properties
57
+ if (schemaProperties) {
58
+ const schemaKeys = Object.keys(schemaProperties)
59
+ const missing = pathParamNames.filter((p) => !schemaKeys.includes(p))
60
+ const extra = schemaKeys.filter((k) => !pathParamNames.includes(k))
61
+ if (missing.length > 0 || extra.length > 0) {
62
+ const parts: string[] = []
63
+ if (missing.length > 0) parts.push(`path has [${missing.join(', ')}] missing from schema`)
64
+ if (extra.length > 0) parts.push(`schema has [${extra.join(', ')}] not in path`)
65
+ throw new ProcedureRegistrationError(
66
+ procedureName,
67
+ `Path param mismatch for "${procedureName}": ${parts.join('; ')}.`,
68
+ definitionInfo,
69
+ )
70
+ }
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Shared machinery for the four creators. Everything here is package-private:
3
+ * the public API is `Procedures()` and the creators it returns.
4
+ */
5
+ import { ProcedureError, ProcedureRegistrationError, ProcedureValidationError, ProcedureYieldValidationError } from './errors.js'
6
+ import type { DefinitionInfo } from './definition-site.js'
7
+ import type { AnyProcedureRegistration } from './types.js'
8
+ import type { SchemaAdapter } from '../schema/adapter.js'
9
+ import type { Validate, ValidatorCompiler } from '../schema/compile.js'
10
+
11
+ /**
12
+ * Everything a creator needs from its owning factory, resolved once in
13
+ * `Procedures()`.
14
+ */
15
+ export type FactoryRuntime<TContext, TExtendedConfig> = {
16
+ registry: Map<string, AnyProcedureRegistration<TContext, TExtendedConfig>>
17
+ onCreate?: (procedure: AnyProcedureRegistration<TContext, TExtendedConfig>) => void
18
+ /** True when the factory was created with `validation: false`. */
19
+ skipValidation: boolean
20
+ adapters: readonly SchemaAdapter[]
21
+ compile: ValidatorCompiler
22
+ httpDefaults?: { pathPrefix?: string; scope?: string }
23
+ }
24
+
25
+ const HTTP_FIELDS = ['path', 'method', 'req', 'res', 'successStatus'] as const
26
+
27
+ /** Create/CreateStream reject HTTP-only config fields with a pointer to CreateHttp. */
28
+ export function assertNoHttpFields(
29
+ creatorName: 'Create' | 'CreateStream',
30
+ procedureName: string,
31
+ config: Record<string, unknown>,
32
+ definitionInfo: DefinitionInfo,
33
+ ): void {
34
+ const presentHttpFields = HTTP_FIELDS.filter((f) => config[f] !== undefined)
35
+ if (presentHttpFields.length > 0) {
36
+ throw new ProcedureRegistrationError(
37
+ procedureName,
38
+ `HTTP fields require CreateHttp / CreateHttpStream. Procedure "${procedureName}" has [${presentHttpFields.join(', ')}] which are not valid on ${creatorName}.`,
39
+ definitionInfo,
40
+ )
41
+ }
42
+ }
43
+
44
+ /** Duplicate names fail fast, BEFORE schema computation. */
45
+ export function assertNotDuplicate(
46
+ registry: Map<string, unknown>,
47
+ name: string,
48
+ definitionInfo: DefinitionInfo,
49
+ ): void {
50
+ if (registry.has(name)) {
51
+ throw new ProcedureRegistrationError(
52
+ name,
53
+ `Procedure with name ${name} is already registered`,
54
+ definitionInfo,
55
+ )
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Should this call skip runtime validation? Either the caller already
61
+ * validated (`ctx.isPrevalidated`, set by HTTP builders) or the whole factory
62
+ * opted out (`validation: false`).
63
+ */
64
+ export function shouldSkipValidation(ctx: unknown, runtime: { skipValidation: boolean }): boolean {
65
+ return Boolean((ctx as { isPrevalidated?: boolean })?.isPrevalidated) || runtime.skipValidation
66
+ }
67
+
68
+ /** Validates RPC params; throws `ProcedureValidationError` on failure. */
69
+ export function validateParams(
70
+ name: string,
71
+ validate: Validate | undefined,
72
+ params: unknown,
73
+ definitionInfo: DefinitionInfo,
74
+ ): void {
75
+ if (!validate) return
76
+ const { errors } = validate(params)
77
+ if (errors) {
78
+ throw new ProcedureValidationError(name, `Validation error for ${name}`, errors, definitionInfo)
79
+ }
80
+ }
81
+
82
+ /** Validates each HTTP req channel independently; error messages name the channel. */
83
+ export function validateReqChannels(
84
+ name: string,
85
+ validators: Record<string, Validate> | undefined,
86
+ req: unknown,
87
+ definitionInfo: DefinitionInfo,
88
+ ): void {
89
+ if (!validators) return
90
+ for (const [channel, validate] of Object.entries(validators)) {
91
+ const channelValue = (req as Record<string, unknown> | undefined)?.[channel]
92
+ const { errors } = validate(channelValue)
93
+ if (errors) {
94
+ throw new ProcedureValidationError(
95
+ name,
96
+ `Validation error for ${name} in req.${channel}`,
97
+ errors,
98
+ definitionInfo,
99
+ )
100
+ }
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Boxes a non-ProcedureError thrown by a unary handler into a ProcedureError
106
+ * (original error as `cause`), preserving the original stack and appending
107
+ * the definition site. ProcedureErrors pass through untouched.
108
+ */
109
+ export function toProcedureError(
110
+ name: string,
111
+ definitionInfo: DefinitionInfo,
112
+ error: any,
113
+ ): ProcedureError {
114
+ if (error instanceof ProcedureError) return error
115
+ const err = new ProcedureError(
116
+ name,
117
+ `Error in handler for ${name} - ${error?.message}`,
118
+ undefined,
119
+ definitionInfo,
120
+ )
121
+ err.cause = error
122
+ if (error?.stack && definitionInfo.definedAt) {
123
+ const { file, line, column } = definitionInfo.definedAt
124
+ err.stack =
125
+ error.stack + `\n--- Procedure "${name}" defined at ---\n at ${file}:${line}:${column}`
126
+ } else if (error?.stack) {
127
+ err.stack = error.stack
128
+ }
129
+ return err
130
+ }
131
+
132
+ /** Appends the definition site to a thrown error's stack, in place. */
133
+ export function appendDefinitionSite(error: any, name: string, definitionInfo: DefinitionInfo): void {
134
+ if (definitionInfo.definedAt && error && typeof error.stack === 'string') {
135
+ const { file, line, column } = definitionInfo.definedAt
136
+ error.stack = `${error.stack}\n--- Procedure "${name}" defined at ---\n at ${file}:${line}:${column}`
137
+ }
138
+ }
139
+
140
+ /** Combines an incoming (e.g. HTTP request) signal with the stream's own controller. */
141
+ export function combineSignals(incoming: AbortSignal | undefined, own: AbortSignal): AbortSignal {
142
+ return incoming ? AbortSignal.any([incoming, own]) : own
143
+ }
144
+
145
+ /**
146
+ * Drives a user stream iterator with the framework guarantees shared by
147
+ * CreateStream and CreateHttpStream:
148
+ * - optional per-yield validation (`validateYields: true`)
149
+ * - errors get the definition site appended to their stack — but keep their
150
+ * original class, so HTTP taxonomies and typed-error dispatch see the real
151
+ * thrown value
152
+ * - on ANY exit, the user iterator's `return()` runs (its `finally` blocks
153
+ * fire on early consumer close) and the controller aborts with reason
154
+ * `'stream-completed'` so handlers can distinguish completion from client
155
+ * disconnect
156
+ * - the user generator's return value is propagated (becomes the
157
+ * `event: 'return'` SSE payload downstream)
158
+ */
159
+ export async function* iterateWithGuards(
160
+ userIterator: AsyncIterator<any, any, unknown>,
161
+ options: {
162
+ name: string
163
+ validateYields: boolean
164
+ validateYield: Validate | undefined
165
+ abortController: AbortController
166
+ definitionInfo: DefinitionInfo
167
+ },
168
+ ): AsyncGenerator<any, any, unknown> {
169
+ const { name, validateYields, validateYield, abortController, definitionInfo } = options
170
+ try {
171
+ let result = await userIterator.next()
172
+ while (!result.done) {
173
+ const value = result.value
174
+ if (validateYields && validateYield) {
175
+ const { errors } = validateYield(value)
176
+ if (errors) {
177
+ throw new ProcedureYieldValidationError(
178
+ name,
179
+ `Yield validation error for ${name}`,
180
+ errors,
181
+ definitionInfo,
182
+ )
183
+ }
184
+ }
185
+ yield value
186
+ result = await userIterator.next()
187
+ }
188
+ return result.value
189
+ } catch (error: any) {
190
+ appendDefinitionSite(error, name, definitionInfo)
191
+ throw error
192
+ } finally {
193
+ // Propagate `.return()` to the user generator so its `finally` blocks run
194
+ // when the consumer closes the stream early. No-op when iteration already
195
+ // completed.
196
+ try {
197
+ await userIterator.return?.(undefined)
198
+ } catch {
199
+ // Swallow — cleanup must not mask the primary error path
200
+ }
201
+ abortController.abort('stream-completed')
202
+ }
203
+ }
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest'
2
- import { Procedures } from './index.js'
2
+ import { Procedures } from './procedures.js'
3
3
  import { ProcedureRegistrationError } from './errors.js'
4
4
  import { Type } from 'typebox'
5
5
 
@@ -24,6 +24,28 @@ describe('v7 → v8 migration errors', () => {
24
24
  })
25
25
  })
26
26
 
27
+ describe('schema.params rejected on HTTP creators', () => {
28
+ it('CreateHttp rejects schema.params with migration message', () => {
29
+ const procs = Procedures()
30
+ expect(() =>
31
+ procs.CreateHttp('LegacyHttp', {
32
+ path: '/x', method: 'get',
33
+ schema: { params: Type.Object({}) } as any,
34
+ }, async () => undefined)
35
+ ).toThrow(/Use schema.req.body \(or schema.req.query\) instead of schema.params/)
36
+ })
37
+
38
+ it('CreateHttpStream rejects schema.params with migration message', () => {
39
+ const procs = Procedures()
40
+ expect(() =>
41
+ procs.CreateHttpStream('LegacyHttpStream', {
42
+ path: '/x', method: 'get',
43
+ schema: { params: Type.Object({}), yield: Type.Number() } as any,
44
+ }, async function* () {})
45
+ ).toThrow(/Use schema.req.body \(or schema.req.query\) instead of schema.params/)
46
+ })
47
+ })
48
+
27
49
  describe('HTTP fields rejected on RPC creators', () => {
28
50
  const HTTP_FIELDS = ['path', 'method', 'req', 'res', 'successStatus'] as const
29
51