ts-procedures 8.6.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 (627) 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-scope.d.ts +13 -30
  103. package/build/codegen/emit-scope.js +15 -844
  104. package/build/codegen/emit-scope.js.map +1 -1
  105. package/build/codegen/goldens.test.js +69 -0
  106. package/build/codegen/goldens.test.js.map +1 -0
  107. package/build/codegen/group-routes.d.ts +1 -1
  108. package/build/codegen/pipeline.d.ts +1 -1
  109. package/build/codegen/resolve-envelope.d.ts +1 -1
  110. package/build/codegen/targets/_shared/error-schemas.d.ts +1 -1
  111. package/build/codegen/targets/_shared/route-slots.d.ts +1 -1
  112. package/build/codegen/targets/_shared/target-run.d.ts +1 -1
  113. package/build/codegen/targets/kotlin/emit-route-kotlin.d.ts +1 -1
  114. package/build/codegen/targets/swift/emit-route-swift.d.ts +1 -1
  115. package/build/core/create-http-stream.d.ts +50 -0
  116. package/build/core/create-http-stream.js +108 -0
  117. package/build/core/create-http-stream.js.map +1 -0
  118. package/build/{create-http-stream.test.js → core/create-http-stream.test.js} +1 -1
  119. package/build/core/create-http-stream.test.js.map +1 -0
  120. package/build/core/create-http.d.ts +51 -0
  121. package/build/core/create-http.js +65 -0
  122. package/build/core/create-http.js.map +1 -0
  123. package/build/{create-http.test.js → core/create-http.test.js} +13 -4
  124. package/build/core/create-http.test.js.map +1 -0
  125. package/build/core/create-stream.d.ts +26 -0
  126. package/build/core/create-stream.js +80 -0
  127. package/build/core/create-stream.js.map +1 -0
  128. package/build/{create-stream.test.js → core/create-stream.test.js} +23 -28
  129. package/build/core/create-stream.test.js.map +1 -0
  130. package/build/core/create.d.ts +22 -0
  131. package/build/core/create.js +71 -0
  132. package/build/core/create.js.map +1 -0
  133. package/build/{create.test.js → core/create.test.js} +25 -46
  134. package/build/core/create.test.js.map +1 -0
  135. package/build/core/definition-site.d.ts +24 -0
  136. package/build/{stack-utils.js → core/definition-site.js} +20 -20
  137. package/build/core/definition-site.js.map +1 -0
  138. package/build/{stack-utils.test.js → core/definition-site.test.js} +12 -3
  139. package/build/core/definition-site.test.js.map +1 -0
  140. package/build/{errors.d.ts → core/errors.d.ts} +19 -8
  141. package/build/{errors.js → core/errors.js} +21 -26
  142. package/build/core/errors.js.map +1 -0
  143. package/build/core/errors.test.js.map +1 -0
  144. package/build/core/factory-options.test.js +82 -0
  145. package/build/core/factory-options.test.js.map +1 -0
  146. package/build/core/http-route.d.ts +13 -0
  147. package/build/core/http-route.js +54 -0
  148. package/build/core/http-route.js.map +1 -0
  149. package/build/core/internal.d.ts +72 -0
  150. package/build/core/internal.js +128 -0
  151. package/build/core/internal.js.map +1 -0
  152. package/build/{migration.test.js → core/migration.test.js} +17 -1
  153. package/build/core/migration.test.js.map +1 -0
  154. package/build/core/procedures.d.ts +143 -0
  155. package/build/core/procedures.js +64 -0
  156. package/build/core/procedures.js.map +1 -0
  157. package/build/{index.test.js → core/procedures.test.js} +14 -11
  158. package/build/core/procedures.test.js.map +1 -0
  159. package/build/core/types.d.ts +182 -0
  160. package/build/{schema → core}/types.js.map +1 -1
  161. package/build/exports.d.ts +31 -11
  162. package/build/exports.js +23 -8
  163. package/build/exports.js.map +1 -1
  164. package/build/schema/adapter.d.ts +35 -0
  165. package/build/schema/adapter.js +13 -0
  166. package/build/schema/adapter.js.map +1 -0
  167. package/build/schema/adapter.test.js +53 -0
  168. package/build/schema/adapter.test.js.map +1 -0
  169. package/build/schema/compile.d.ts +37 -0
  170. package/build/schema/compile.js +38 -0
  171. package/build/schema/compile.js.map +1 -0
  172. package/build/schema/compile.test.js +78 -0
  173. package/build/schema/compile.test.js.map +1 -0
  174. package/build/schema/compute-schema.d.ts +47 -37
  175. package/build/schema/compute-schema.js +86 -29
  176. package/build/schema/compute-schema.js.map +1 -1
  177. package/build/schema/compute-schema.test.js +158 -40
  178. package/build/schema/compute-schema.test.js.map +1 -1
  179. package/build/schema/json-schema.d.ts +17 -0
  180. package/build/schema/json-schema.js +2 -0
  181. package/build/schema/json-schema.js.map +1 -0
  182. package/build/schema/typebox.d.ts +11 -0
  183. package/build/schema/typebox.js +24 -0
  184. package/build/schema/typebox.js.map +1 -0
  185. package/build/schema/typebox.test.js +34 -0
  186. package/build/schema/typebox.test.js.map +1 -0
  187. package/build/server/context.d.ts +8 -0
  188. package/build/server/context.js +7 -0
  189. package/build/server/context.js.map +1 -0
  190. package/build/server/context.test.js +16 -0
  191. package/build/server/context.test.js.map +1 -0
  192. package/build/{doc-envelope.d.ts → server/doc-envelope.d.ts} +1 -1
  193. package/build/server/doc-envelope.js.map +1 -0
  194. package/build/server/doc-envelope.test.d.ts +1 -0
  195. package/build/server/doc-envelope.test.js.map +1 -0
  196. package/build/{implementations/http → server}/doc-registry.d.ts +7 -2
  197. package/build/{implementations/http → server}/doc-registry.js +9 -5
  198. package/build/server/doc-registry.js.map +1 -0
  199. package/build/server/doc-registry.test.d.ts +1 -0
  200. package/build/{implementations/http → server}/doc-registry.test.js +27 -24
  201. package/build/server/doc-registry.test.js.map +1 -0
  202. package/build/server/docs/docs.test.d.ts +1 -0
  203. package/build/server/docs/docs.test.js +237 -0
  204. package/build/server/docs/docs.test.js.map +1 -0
  205. package/build/{implementations/http/hono → server}/docs/http-doc.d.ts +2 -2
  206. package/build/{implementations/http/hono → server}/docs/http-doc.js +1 -1
  207. package/build/server/docs/http-doc.js.map +1 -0
  208. package/build/{implementations/http/hono → server}/docs/http-stream-doc.d.ts +2 -2
  209. package/build/{implementations/http/hono → server}/docs/http-stream-doc.js +1 -1
  210. package/build/server/docs/http-stream-doc.js.map +1 -0
  211. package/build/{implementations/http/hono → server}/docs/rpc-doc.d.ts +2 -2
  212. package/build/{implementations/http/hono → server}/docs/rpc-doc.js +1 -1
  213. package/build/server/docs/rpc-doc.js.map +1 -0
  214. package/build/{implementations/http/hono → server}/docs/stream-doc.d.ts +2 -2
  215. package/build/{implementations/http/hono → server}/docs/stream-doc.js +1 -1
  216. package/build/server/docs/stream-doc.js.map +1 -0
  217. package/build/server/errors/dispatch.d.ts +96 -0
  218. package/build/{implementations/http/error-dispatch.js → server/errors/dispatch.js} +20 -10
  219. package/build/server/errors/dispatch.js.map +1 -0
  220. package/build/server/errors/dispatch.test.d.ts +1 -0
  221. package/build/server/errors/dispatch.test.js +418 -0
  222. package/build/server/errors/dispatch.test.js.map +1 -0
  223. package/build/{implementations/http/error-taxonomy.d.ts → server/errors/taxonomy.d.ts} +8 -17
  224. package/build/{implementations/http/error-taxonomy.js → server/errors/taxonomy.js} +6 -15
  225. package/build/server/errors/taxonomy.js.map +1 -0
  226. package/build/server/errors/taxonomy.test.d.ts +1 -0
  227. package/build/{implementations/http/error-taxonomy.test.js → server/errors/taxonomy.test.js} +45 -39
  228. package/build/server/errors/taxonomy.test.js.map +1 -0
  229. package/build/server/index.d.ts +29 -0
  230. package/build/server/index.js +27 -0
  231. package/build/server/index.js.map +1 -0
  232. package/build/server/no-framework-imports.test.d.ts +1 -0
  233. package/build/server/no-framework-imports.test.js +40 -0
  234. package/build/server/no-framework-imports.test.js.map +1 -0
  235. package/build/{implementations/http/hono/path.d.ts → server/paths.d.ts} +2 -3
  236. package/build/{implementations/http/hono/path.js → server/paths.js} +1 -1
  237. package/build/server/paths.js.map +1 -0
  238. package/build/server/paths.test.d.ts +1 -0
  239. package/build/server/paths.test.js +111 -0
  240. package/build/server/paths.test.js.map +1 -0
  241. package/build/server/request/params.d.ts +29 -0
  242. package/build/server/request/params.js +43 -0
  243. package/build/server/request/params.js.map +1 -0
  244. package/build/server/request/params.test.d.ts +1 -0
  245. package/build/server/request/params.test.js +91 -0
  246. package/build/server/request/params.test.js.map +1 -0
  247. package/build/server/request/query.d.ts +9 -0
  248. package/build/server/request/query.js +22 -0
  249. package/build/server/request/query.js.map +1 -0
  250. package/build/server/request/query.test.d.ts +1 -0
  251. package/build/server/request/query.test.js +60 -0
  252. package/build/server/request/query.test.js.map +1 -0
  253. package/build/server/sse.d.ts +70 -0
  254. package/build/server/sse.js +94 -0
  255. package/build/server/sse.js.map +1 -0
  256. package/build/server/sse.test.d.ts +1 -0
  257. package/build/server/sse.test.js +98 -0
  258. package/build/server/sse.test.js.map +1 -0
  259. package/build/{implementations → server}/types.d.ts +17 -15
  260. package/build/{implementations → server}/types.js.map +1 -1
  261. package/docs/astro-adapter.md +8 -9
  262. package/docs/client-and-codegen.md +4 -4
  263. package/docs/client-error-handling.md +5 -5
  264. package/docs/codegen-kotlin.md +2 -3
  265. package/docs/codegen-swift.md +1 -2
  266. package/docs/core.md +135 -54
  267. package/docs/http-integrations.md +58 -6
  268. package/docs/migration-v8-to-v9.md +192 -0
  269. package/docs/plans/2026-06-09-v9-rewrite.md +130 -0
  270. package/docs/specs/2026-06-09-v9-rewrite-design.md +221 -0
  271. package/docs/streaming.md +12 -0
  272. package/package.json +23 -47
  273. package/src/{implementations/http → adapters}/astro/index.test.ts +2 -2
  274. package/src/adapters/hono/__fixtures__/parity-envelope.json +389 -0
  275. package/src/adapters/hono/envelope-parity.test.ts +126 -0
  276. package/src/{implementations/http → adapters}/hono/handlers/http-stream.test.ts +1 -1
  277. package/src/adapters/hono/handlers/http-stream.ts +73 -0
  278. package/src/{implementations/http → adapters}/hono/handlers/http.test.ts +1 -1
  279. package/src/adapters/hono/handlers/http.ts +70 -0
  280. package/src/{implementations/http → adapters}/hono/handlers/rpc.test.ts +2 -2
  281. package/src/adapters/hono/handlers/rpc.ts +39 -0
  282. package/src/{implementations/http → adapters}/hono/handlers/stream.test.ts +4 -3
  283. package/src/{implementations/http → adapters}/hono/handlers/stream.ts +19 -92
  284. package/src/{implementations/http → adapters}/hono/index.test.ts +14 -16
  285. package/src/{implementations/http → adapters}/hono/index.ts +35 -30
  286. package/src/{implementations/http → adapters/hono}/on-request-error.test.ts +3 -3
  287. package/src/adapters/hono/request.ts +28 -0
  288. package/src/{implementations/http → adapters/hono}/route-errors.test.ts +5 -5
  289. package/src/{implementations/http → adapters}/hono/types.ts +43 -20
  290. package/src/client/freeze.test.ts +41 -0
  291. package/src/client/typed-error-dispatch.test.ts +3 -3
  292. package/src/codegen/__fixtures__/make-envelope.ts +1 -1
  293. package/src/codegen/__fixtures__/models-envelope.json +310 -0
  294. package/src/codegen/__goldens__/MANIFEST.json +85 -0
  295. package/src/codegen/__goldens__/kotlin-default--models/Billing.kt +112 -0
  296. package/src/codegen/__goldens__/kotlin-default--models/BillingReports.kt +26 -0
  297. package/src/codegen/__goldens__/kotlin-default--models/Orders.kt +88 -0
  298. package/src/codegen/__goldens__/kotlin-default--users/Users.kt +189 -0
  299. package/src/codegen/__goldens__/swift-default--models/Billing.swift +97 -0
  300. package/src/codegen/__goldens__/swift-default--models/BillingReports.swift +20 -0
  301. package/src/codegen/__goldens__/swift-default--models/Orders.swift +81 -0
  302. package/src/codegen/__goldens__/swift-default--users/Users.swift +204 -0
  303. package/src/codegen/__goldens__/ts-default--models/_client.ts +1319 -0
  304. package/src/codegen/__goldens__/ts-default--models/_errors.ts +90 -0
  305. package/src/codegen/__goldens__/ts-default--models/_models.ts +10 -0
  306. package/src/codegen/__goldens__/ts-default--models/_types.ts +502 -0
  307. package/src/codegen/__goldens__/ts-default--models/billing-reports.ts +29 -0
  308. package/src/codegen/__goldens__/ts-default--models/billing.ts +67 -0
  309. package/src/codegen/__goldens__/ts-default--models/index.ts +48 -0
  310. package/src/codegen/__goldens__/ts-default--models/orders.ts +80 -0
  311. package/src/codegen/__goldens__/ts-default--users/_client.ts +1319 -0
  312. package/src/codegen/__goldens__/ts-default--users/_errors.ts +90 -0
  313. package/src/codegen/__goldens__/ts-default--users/_types.ts +502 -0
  314. package/src/codegen/__goldens__/ts-default--users/index.ts +38 -0
  315. package/src/codegen/__goldens__/ts-default--users/users.ts +169 -0
  316. package/src/codegen/__goldens__/ts-external-runtime--models/_errors.ts +90 -0
  317. package/src/codegen/__goldens__/ts-external-runtime--models/_models.ts +10 -0
  318. package/src/codegen/__goldens__/ts-external-runtime--models/billing-reports.ts +29 -0
  319. package/src/codegen/__goldens__/ts-external-runtime--models/billing.ts +67 -0
  320. package/src/codegen/__goldens__/ts-external-runtime--models/index.ts +48 -0
  321. package/src/codegen/__goldens__/ts-external-runtime--models/orders.ts +80 -0
  322. package/src/codegen/__goldens__/ts-external-runtime--users/_errors.ts +90 -0
  323. package/src/codegen/__goldens__/ts-external-runtime--users/index.ts +38 -0
  324. package/src/codegen/__goldens__/ts-external-runtime--users/users.ts +169 -0
  325. package/src/codegen/__goldens__/ts-flat--models/_client.ts +1319 -0
  326. package/src/codegen/__goldens__/ts-flat--models/_errors.ts +87 -0
  327. package/src/codegen/__goldens__/ts-flat--models/_models.ts +10 -0
  328. package/src/codegen/__goldens__/ts-flat--models/_types.ts +502 -0
  329. package/src/codegen/__goldens__/ts-flat--models/billing-reports.ts +28 -0
  330. package/src/codegen/__goldens__/ts-flat--models/billing.ts +51 -0
  331. package/src/codegen/__goldens__/ts-flat--models/index.ts +42 -0
  332. package/src/codegen/__goldens__/ts-flat--models/orders.ts +73 -0
  333. package/src/codegen/__goldens__/ts-flat--users/_client.ts +1319 -0
  334. package/src/codegen/__goldens__/ts-flat--users/_errors.ts +87 -0
  335. package/src/codegen/__goldens__/ts-flat--users/_types.ts +502 -0
  336. package/src/codegen/__goldens__/ts-flat--users/index.ts +34 -0
  337. package/src/codegen/__goldens__/ts-flat--users/users.ts +126 -0
  338. package/src/codegen/__goldens__/ts-no-share-models--models/_client.ts +1319 -0
  339. package/src/codegen/__goldens__/ts-no-share-models--models/_errors.ts +90 -0
  340. package/src/codegen/__goldens__/ts-no-share-models--models/_types.ts +502 -0
  341. package/src/codegen/__goldens__/ts-no-share-models--models/billing-reports.ts +29 -0
  342. package/src/codegen/__goldens__/ts-no-share-models--models/billing.ts +111 -0
  343. package/src/codegen/__goldens__/ts-no-share-models--models/index.ts +48 -0
  344. package/src/codegen/__goldens__/ts-no-share-models--models/orders.ts +112 -0
  345. package/src/codegen/__goldens__/ts-no-share-models--users/_client.ts +1319 -0
  346. package/src/codegen/__goldens__/ts-no-share-models--users/_errors.ts +90 -0
  347. package/src/codegen/__goldens__/ts-no-share-models--users/_types.ts +502 -0
  348. package/src/codegen/__goldens__/ts-no-share-models--users/index.ts +38 -0
  349. package/src/codegen/__goldens__/ts-no-share-models--users/users.ts +169 -0
  350. package/src/codegen/__goldens__/ts-shared-models-module--models/_client.ts +1319 -0
  351. package/src/codegen/__goldens__/ts-shared-models-module--models/_errors.ts +90 -0
  352. package/src/codegen/__goldens__/ts-shared-models-module--models/_models.ts +7 -0
  353. package/src/codegen/__goldens__/ts-shared-models-module--models/_types.ts +502 -0
  354. package/src/codegen/__goldens__/ts-shared-models-module--models/billing-reports.ts +29 -0
  355. package/src/codegen/__goldens__/ts-shared-models-module--models/billing.ts +67 -0
  356. package/src/codegen/__goldens__/ts-shared-models-module--models/index.ts +48 -0
  357. package/src/codegen/__goldens__/ts-shared-models-module--models/orders.ts +80 -0
  358. package/src/codegen/bin/cli.test.ts +13 -2
  359. package/src/codegen/bin/cli.ts +181 -144
  360. package/src/codegen/bin/flag-specs.test.ts +16 -1
  361. package/src/codegen/bin/flag-specs.ts +43 -31
  362. package/src/codegen/bundle-size.test.ts +1 -1
  363. package/src/codegen/collect-models.ts +1 -1
  364. package/src/codegen/e2e.test.ts +1 -1
  365. package/src/codegen/emit/api-route.ts +184 -0
  366. package/src/codegen/emit/context.ts +32 -0
  367. package/src/codegen/emit/declarations.ts +49 -0
  368. package/src/codegen/emit/format-types.ts +232 -0
  369. package/src/codegen/emit/http-stream-route.ts +162 -0
  370. package/src/codegen/emit/route-shared.ts +102 -0
  371. package/src/codegen/emit/rpc-route.ts +49 -0
  372. package/src/codegen/emit/scope-file.ts +226 -0
  373. package/src/codegen/emit/stream-route.ts +81 -0
  374. package/src/codegen/emit-errors.integration.test.ts +2 -2
  375. package/src/codegen/emit-errors.test.ts +1 -1
  376. package/src/codegen/emit-errors.ts +1 -1
  377. package/src/codegen/emit-scope.test.ts +2 -2
  378. package/src/codegen/emit-scope.ts +15 -1048
  379. package/src/codegen/goldens.test.ts +89 -0
  380. package/src/codegen/group-routes.test.ts +1 -1
  381. package/src/codegen/group-routes.ts +1 -1
  382. package/src/codegen/pipeline.test.ts +1 -1
  383. package/src/codegen/pipeline.ts +1 -1
  384. package/src/codegen/resolve-envelope.test.ts +1 -1
  385. package/src/codegen/resolve-envelope.ts +1 -1
  386. package/src/codegen/targets/_shared/error-schemas.test.ts +1 -1
  387. package/src/codegen/targets/_shared/error-schemas.ts +1 -1
  388. package/src/codegen/targets/_shared/route-slots.test.ts +1 -1
  389. package/src/codegen/targets/_shared/route-slots.ts +1 -1
  390. package/src/codegen/targets/_shared/target-run.ts +1 -1
  391. package/src/codegen/targets/kotlin/emit-route-kotlin.test.ts +1 -1
  392. package/src/codegen/targets/kotlin/emit-route-kotlin.ts +1 -1
  393. package/src/codegen/targets/kotlin/emit-scope-kotlin.test.ts +1 -1
  394. package/src/codegen/targets/swift/access-level.test.ts +1 -1
  395. package/src/codegen/targets/swift/emit-route-swift.test.ts +1 -1
  396. package/src/codegen/targets/swift/emit-route-swift.ts +1 -1
  397. package/src/codegen/targets/swift/emit-scope-swift.test.ts +1 -1
  398. package/src/codegen/targets/ts/shared-models.test.ts +1 -1
  399. package/src/{create-http-stream.test.ts → core/create-http-stream.test.ts} +1 -1
  400. package/src/core/create-http-stream.ts +207 -0
  401. package/src/{create-http.test.ts → core/create-http.test.ts} +15 -4
  402. package/src/core/create-http.ts +126 -0
  403. package/src/{create-stream.test.ts → core/create-stream.test.ts} +28 -31
  404. package/src/core/create-stream.ts +142 -0
  405. package/src/{create.test.ts → core/create.test.ts} +25 -57
  406. package/src/core/create.ts +121 -0
  407. package/src/{stack-utils.test.ts → core/definition-site.test.ts} +14 -3
  408. package/src/{stack-utils.ts → core/definition-site.ts} +20 -23
  409. package/src/{errors.test.ts → core/errors.test.ts} +1 -1
  410. package/src/{errors.ts → core/errors.ts} +30 -28
  411. package/src/core/factory-options.test.ts +112 -0
  412. package/src/core/http-route.ts +73 -0
  413. package/src/core/internal.ts +203 -0
  414. package/src/{migration.test.ts → core/migration.test.ts} +23 -1
  415. package/src/{index.test.ts → core/procedures.test.ts} +13 -11
  416. package/src/core/procedures.ts +75 -0
  417. package/src/core/types.ts +195 -0
  418. package/src/exports.ts +60 -11
  419. package/src/schema/adapter.test.ts +58 -0
  420. package/src/schema/adapter.ts +45 -0
  421. package/src/schema/compile.test.ts +95 -0
  422. package/src/schema/compile.ts +64 -0
  423. package/src/schema/compute-schema.test.ts +222 -41
  424. package/src/schema/compute-schema.ts +145 -71
  425. package/src/schema/json-schema.ts +21 -0
  426. package/src/schema/typebox.test.ts +40 -0
  427. package/src/schema/typebox.ts +27 -0
  428. package/src/server/context.test.ts +22 -0
  429. package/src/server/context.ts +18 -0
  430. package/src/{doc-envelope.test.ts → server/doc-envelope.test.ts} +2 -2
  431. package/src/{doc-envelope.ts → server/doc-envelope.ts} +1 -1
  432. package/src/{implementations/http → server}/doc-registry.test.ts +32 -26
  433. package/src/{implementations/http → server}/doc-registry.ts +11 -7
  434. package/src/server/docs/docs.test.ts +287 -0
  435. package/src/{implementations/http/hono → server}/docs/http-doc.ts +3 -3
  436. package/src/{implementations/http/hono → server}/docs/http-stream-doc.ts +3 -3
  437. package/src/{implementations/http/hono → server}/docs/rpc-doc.ts +3 -3
  438. package/src/{implementations/http/hono → server}/docs/stream-doc.ts +3 -3
  439. package/src/server/errors/dispatch.test.ts +450 -0
  440. package/src/server/errors/dispatch.ts +189 -0
  441. package/src/{implementations/http/error-taxonomy.test.ts → server/errors/taxonomy.test.ts} +45 -39
  442. package/src/{implementations/http/error-taxonomy.ts → server/errors/taxonomy.ts} +8 -17
  443. package/src/server/index.ts +29 -0
  444. package/src/server/no-framework-imports.test.ts +43 -0
  445. package/src/server/paths.test.ts +141 -0
  446. package/src/{implementations/http/hono/path.ts → server/paths.ts} +2 -13
  447. package/src/server/request/params.test.ts +143 -0
  448. package/src/server/request/params.ts +68 -0
  449. package/src/server/request/query.test.ts +70 -0
  450. package/src/server/request/query.ts +24 -0
  451. package/src/server/sse.test.ts +113 -0
  452. package/src/server/sse.ts +117 -0
  453. package/src/{implementations → server}/types.ts +17 -16
  454. package/build/create-http-stream.d.ts +0 -58
  455. package/build/create-http-stream.js +0 -122
  456. package/build/create-http-stream.js.map +0 -1
  457. package/build/create-http-stream.test.js.map +0 -1
  458. package/build/create-http.d.ts +0 -49
  459. package/build/create-http.js +0 -108
  460. package/build/create-http.js.map +0 -1
  461. package/build/create-http.test.js.map +0 -1
  462. package/build/create-stream.d.ts +0 -35
  463. package/build/create-stream.js +0 -123
  464. package/build/create-stream.js.map +0 -1
  465. package/build/create-stream.test.js.map +0 -1
  466. package/build/create.d.ts +0 -28
  467. package/build/create.js +0 -82
  468. package/build/create.js.map +0 -1
  469. package/build/create.test.js.map +0 -1
  470. package/build/doc-envelope.js.map +0 -1
  471. package/build/doc-envelope.test.js.map +0 -1
  472. package/build/errors.js.map +0 -1
  473. package/build/errors.test.js.map +0 -1
  474. package/build/implementations/http/astro/astro-context.js.map +0 -1
  475. package/build/implementations/http/astro/create-handler.js.map +0 -1
  476. package/build/implementations/http/astro/index.js.map +0 -1
  477. package/build/implementations/http/astro/index.test.js.map +0 -1
  478. package/build/implementations/http/astro/rewrite-request.js.map +0 -1
  479. package/build/implementations/http/doc-registry.js.map +0 -1
  480. package/build/implementations/http/doc-registry.test.js.map +0 -1
  481. package/build/implementations/http/error-dispatch.d.ts +0 -76
  482. package/build/implementations/http/error-dispatch.js.map +0 -1
  483. package/build/implementations/http/error-dispatch.test.js +0 -254
  484. package/build/implementations/http/error-dispatch.test.js.map +0 -1
  485. package/build/implementations/http/error-taxonomy.js.map +0 -1
  486. package/build/implementations/http/error-taxonomy.test.js.map +0 -1
  487. package/build/implementations/http/hono/docs/http-doc.js.map +0 -1
  488. package/build/implementations/http/hono/docs/http-stream-doc.js.map +0 -1
  489. package/build/implementations/http/hono/docs/rpc-doc.js.map +0 -1
  490. package/build/implementations/http/hono/docs/stream-doc.js.map +0 -1
  491. package/build/implementations/http/hono/handlers/http-stream.js +0 -123
  492. package/build/implementations/http/hono/handlers/http-stream.js.map +0 -1
  493. package/build/implementations/http/hono/handlers/http-stream.test.js.map +0 -1
  494. package/build/implementations/http/hono/handlers/http.js +0 -110
  495. package/build/implementations/http/hono/handlers/http.js.map +0 -1
  496. package/build/implementations/http/hono/handlers/http.test.js.map +0 -1
  497. package/build/implementations/http/hono/handlers/rpc.js +0 -32
  498. package/build/implementations/http/hono/handlers/rpc.js.map +0 -1
  499. package/build/implementations/http/hono/handlers/rpc.test.js.map +0 -1
  500. package/build/implementations/http/hono/handlers/stream.d.ts +0 -23
  501. package/build/implementations/http/hono/handlers/stream.js +0 -147
  502. package/build/implementations/http/hono/handlers/stream.js.map +0 -1
  503. package/build/implementations/http/hono/handlers/stream.test.js.map +0 -1
  504. package/build/implementations/http/hono/index.js.map +0 -1
  505. package/build/implementations/http/hono/index.test.js.map +0 -1
  506. package/build/implementations/http/hono/path.js.map +0 -1
  507. package/build/implementations/http/hono/path.test.js +0 -83
  508. package/build/implementations/http/hono/path.test.js.map +0 -1
  509. package/build/implementations/http/hono/types.d.ts +0 -51
  510. package/build/implementations/http/hono/types.js.map +0 -1
  511. package/build/implementations/http/on-request-error.test.js.map +0 -1
  512. package/build/implementations/http/route-errors.test.js.map +0 -1
  513. package/build/index.d.ts +0 -175
  514. package/build/index.js +0 -47
  515. package/build/index.js.map +0 -1
  516. package/build/index.test.js.map +0 -1
  517. package/build/migration.test.js.map +0 -1
  518. package/build/schema/extract-json-schema.d.ts +0 -2
  519. package/build/schema/extract-json-schema.js +0 -12
  520. package/build/schema/extract-json-schema.js.map +0 -1
  521. package/build/schema/extract-json-schema.test.js +0 -23
  522. package/build/schema/extract-json-schema.test.js.map +0 -1
  523. package/build/schema/parser.d.ts +0 -36
  524. package/build/schema/parser.js +0 -210
  525. package/build/schema/parser.js.map +0 -1
  526. package/build/schema/parser.test.js +0 -120
  527. package/build/schema/parser.test.js.map +0 -1
  528. package/build/schema/resolve-schema-lib.d.ts +0 -12
  529. package/build/schema/resolve-schema-lib.js +0 -11
  530. package/build/schema/resolve-schema-lib.js.map +0 -1
  531. package/build/schema/resolve-schema-lib.test.js +0 -17
  532. package/build/schema/resolve-schema-lib.test.js.map +0 -1
  533. package/build/schema/types.d.ts +0 -8
  534. package/build/schema/types.js +0 -2
  535. package/build/stack-utils.d.ts +0 -25
  536. package/build/stack-utils.js.map +0 -1
  537. package/build/stack-utils.test.js.map +0 -1
  538. package/build/types.d.ts +0 -142
  539. package/build/types.js +0 -2
  540. package/build/types.js.map +0 -1
  541. package/docs/decisions/2026-06-02-monorepo-split-evaluation.md +0 -80
  542. package/docs/handoffs/2026-06-08-dx-round2-declines.md +0 -45
  543. package/docs/handoffs/ajsc-named-type-collision.md +0 -134
  544. package/docs/handoffs/ajsc-named-type-support.md +0 -181
  545. package/docs/handoffs/shared-models-auto-resolve-response.md +0 -181
  546. package/docs/npm-workspaces-migration-plan.md +0 -611
  547. package/docs/superpowers/plans/2026-04-24-doc-registry-simplification.md +0 -886
  548. package/docs/superpowers/plans/2026-04-24-kotlin-codegen-target.md +0 -1265
  549. package/docs/superpowers/plans/2026-04-25-ajsc-v7-kotlin-polish.md +0 -1993
  550. package/docs/superpowers/plans/2026-04-29-safe-result-api.md +0 -2293
  551. package/docs/superpowers/plans/2026-05-07-astro-adapter.md +0 -1391
  552. package/docs/superpowers/plans/2026-05-08-create-http.md +0 -3355
  553. package/docs/superpowers/plans/2026-05-08-hono-app-builder-convergence.md +0 -3365
  554. package/docs/superpowers/plans/2026-06-05-dx-feedback-round.md +0 -1292
  555. package/docs/superpowers/plans/2026-06-06-shared-models-convention-and-diagnostics.md +0 -659
  556. package/docs/superpowers/plans/2026-06-08-codegen-dx-surfacing.md +0 -428
  557. package/docs/superpowers/specs/2026-04-24-kotlin-swift-codegen-design.md +0 -401
  558. package/docs/superpowers/specs/2026-04-25-ajsc-v7-kotlin-polish-design.md +0 -314
  559. package/docs/superpowers/specs/2026-04-25-swift-codegen-design.md +0 -264
  560. package/docs/superpowers/specs/2026-04-29-safe-result-api-design.md +0 -324
  561. package/docs/superpowers/specs/2026-05-07-astro-adapter-design.md +0 -252
  562. package/docs/superpowers/specs/2026-05-08-create-http-design.md +0 -409
  563. package/docs/superpowers/specs/2026-05-08-hono-app-builder-convergence-design.md +0 -411
  564. package/docs/superpowers/specs/2026-06-05-dx-feedback-round-design.md +0 -285
  565. package/docs/superpowers/specs/2026-06-08-dx-feedback-round-2-design.md +0 -376
  566. package/src/create-http-stream.ts +0 -191
  567. package/src/create-http.ts +0 -210
  568. package/src/create-stream.ts +0 -228
  569. package/src/create.ts +0 -172
  570. package/src/implementations/http/README.md +0 -390
  571. package/src/implementations/http/error-dispatch.test.ts +0 -283
  572. package/src/implementations/http/error-dispatch.ts +0 -176
  573. package/src/implementations/http/hono/handlers/http-stream.ts +0 -152
  574. package/src/implementations/http/hono/handlers/http.ts +0 -145
  575. package/src/implementations/http/hono/handlers/rpc.ts +0 -54
  576. package/src/implementations/http/hono/path.test.ts +0 -96
  577. package/src/index.ts +0 -101
  578. package/src/schema/extract-json-schema.test.ts +0 -25
  579. package/src/schema/extract-json-schema.ts +0 -15
  580. package/src/schema/parser.test.ts +0 -182
  581. package/src/schema/parser.ts +0 -265
  582. package/src/schema/resolve-schema-lib.test.ts +0 -19
  583. package/src/schema/resolve-schema-lib.ts +0 -29
  584. package/src/schema/types.ts +0 -20
  585. package/src/types.ts +0 -133
  586. /package/build/{implementations/http → adapters}/astro/astro-context.d.ts +0 -0
  587. /package/build/{implementations/http → adapters}/astro/astro-context.js +0 -0
  588. /package/build/{implementations/http → adapters}/astro/create-handler.d.ts +0 -0
  589. /package/build/{implementations/http → adapters}/astro/create-handler.js +0 -0
  590. /package/build/{implementations/http → adapters}/astro/index.d.ts +0 -0
  591. /package/build/{implementations/http → adapters}/astro/index.js +0 -0
  592. /package/build/{implementations/http → adapters}/astro/index.test.d.ts +0 -0
  593. /package/build/{implementations/http → adapters}/astro/rewrite-request.d.ts +0 -0
  594. /package/build/{implementations/http → adapters}/astro/rewrite-request.js +0 -0
  595. /package/build/{create-http-stream.test.d.ts → adapters/hono/envelope-parity.test.d.ts} +0 -0
  596. /package/build/{implementations/http → adapters}/hono/handlers/http-stream.test.d.ts +0 -0
  597. /package/build/{implementations/http → adapters}/hono/handlers/http.test.d.ts +0 -0
  598. /package/build/{implementations/http → adapters}/hono/handlers/rpc.test.d.ts +0 -0
  599. /package/build/{implementations/http → adapters}/hono/handlers/stream.test.d.ts +0 -0
  600. /package/build/{implementations/http → adapters}/hono/index.test.d.ts +0 -0
  601. /package/build/{implementations/http → adapters/hono}/on-request-error.test.d.ts +0 -0
  602. /package/build/{implementations/http → adapters/hono}/route-errors.test.d.ts +0 -0
  603. /package/build/{create-http.test.d.ts → client/freeze.test.d.ts} +0 -0
  604. /package/build/{create-stream.test.d.ts → codegen/goldens.test.d.ts} +0 -0
  605. /package/build/{create.test.d.ts → core/create-http-stream.test.d.ts} +0 -0
  606. /package/build/{doc-envelope.test.d.ts → core/create-http.test.d.ts} +0 -0
  607. /package/build/{errors.test.d.ts → core/create-stream.test.d.ts} +0 -0
  608. /package/build/{implementations/http/doc-registry.test.d.ts → core/create.test.d.ts} +0 -0
  609. /package/build/{implementations/http/error-dispatch.test.d.ts → core/definition-site.test.d.ts} +0 -0
  610. /package/build/{implementations/http/error-taxonomy.test.d.ts → core/errors.test.d.ts} +0 -0
  611. /package/build/{errors.test.js → core/errors.test.js} +0 -0
  612. /package/build/{implementations/http/hono/path.test.d.ts → core/factory-options.test.d.ts} +0 -0
  613. /package/build/{migration.test.d.ts → core/migration.test.d.ts} +0 -0
  614. /package/build/{index.test.d.ts → core/procedures.test.d.ts} +0 -0
  615. /package/build/{implementations/http/hono → core}/types.js +0 -0
  616. /package/build/schema/{extract-json-schema.test.d.ts → adapter.test.d.ts} +0 -0
  617. /package/build/schema/{parser.test.d.ts → compile.test.d.ts} +0 -0
  618. /package/build/schema/{resolve-schema-lib.test.d.ts → typebox.test.d.ts} +0 -0
  619. /package/build/{stack-utils.test.d.ts → server/context.test.d.ts} +0 -0
  620. /package/build/{doc-envelope.js → server/doc-envelope.js} +0 -0
  621. /package/build/{doc-envelope.test.js → server/doc-envelope.test.js} +0 -0
  622. /package/build/{implementations → server}/types.js +0 -0
  623. /package/src/{implementations/http → adapters}/astro/README.md +0 -0
  624. /package/src/{implementations/http → adapters}/astro/astro-context.ts +0 -0
  625. /package/src/{implementations/http → adapters}/astro/create-handler.ts +0 -0
  626. /package/src/{implementations/http → adapters}/astro/index.ts +0 -0
  627. /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