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,390 +0,0 @@
1
- # HTTP Implementations
2
-
3
- HTTP implementation builders for `ts-procedures` that create type-safe, versioned endpoints with automatic path generation, schema-based validation, and route documentation.
4
-
5
- ## Available Implementations
6
-
7
- | Framework | Subpath | Description |
8
- |-----------|---------|-------------|
9
- | HonoAppBuilder | `ts-procedures/hono` | Unified Hono builder — dispatches RPC, RPC streams, REST, and REST streams from one `register()` call. Works on Bun, Deno, Cloudflare Workers, and Node.js. |
10
-
11
- `HonoAppBuilder` is a unified builder: one builder, one `app`, one set of cross-cutting hooks. The procedure kind drives behavior — pick the creator that matches the shape you need.
12
-
13
- ### Procedure kinds and which creator to use
14
-
15
- | Procedure kind | Created with | Config shape | Handler return | HTTP methods | Use case |
16
- |----------------|--------------|--------------|----------------|--------------|----------|
17
- | `rpc` | `Create()` | `RPCConfig` (`scope`, `version`) | `Promise<T>` | POST | Standard request/response |
18
- | `rpc-stream` | `CreateStream()` | `RPCConfig` | `AsyncGenerator<T>` | GET, POST | RPC-style streaming (SSE / text) |
19
- | `http` | `CreateHttp()` | `APIConfig` (`path`, `method`) | `Promise<T>` | GET, POST, PUT, DELETE, PATCH, HEAD | REST-style endpoint with `schema.req` channels |
20
- | `http-stream` | `CreateHttpStream()` | `APIConfig` | `AsyncGenerator<T>` | GET, POST | REST-style streaming endpoint |
21
-
22
- `HonoAppBuilder` accepts all four kinds from the same factory.
23
-
24
- ## Core Concepts
25
-
26
- ### Config Interfaces
27
-
28
- RPC and RPC-stream procedures share `RPCConfig`:
29
-
30
- ```typescript
31
- interface RPCConfig {
32
- scope: string | string[] // Route path segment(s)
33
- version: number // API version number
34
- errors?: string[] // Optional taxonomy keys for typed-client narrowing
35
- }
36
- ```
37
-
38
- REST-style procedures (`CreateHttp` / `CreateHttpStream`) use `APIConfig`:
39
-
40
- ```typescript
41
- interface APIConfig {
42
- path: string // Route path with Hono params (e.g., '/users/:id')
43
- method: HttpMethod // 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head'
44
- successStatus?: number // Default: POST→201, DELETE→204, others→200
45
- scope?: string // Optional grouping for codegen file emission
46
- errors?: string[]
47
- }
48
- ```
49
-
50
- API routes use developer-defined paths — no auto-generation from scope/version.
51
-
52
- ### Path Generation
53
-
54
- Routes are generated using kebab-case conversion:
55
-
56
- ```
57
- /{pathPrefix}/{scope...}/{procedureName}/{version}
58
- ```
59
-
60
- **Examples:**
61
-
62
- | Scope | Procedure Name | Version | Generated Path |
63
- |-------|----------------|---------|----------------|
64
- | `'users'` | `'Create'` | `1` | `/users/create/1` |
65
- | `'users'` | `'GetById'` | `1` | `/users/get-by-id/1` |
66
- | `['users', 'admin']` | `'List'` | `1` | `/users/admin/list/1` |
67
- | `['UserModule', 'permissions']` | `'Update'` | `2` | `/user-module/permissions/update/2` |
68
-
69
- **With pathPrefix `/api/v1`:**
70
-
71
- | Scope | Procedure Name | Version | Generated Path |
72
- |-------|----------------|---------|----------------|
73
- | `'users'` | `'Create'` | `1` | `/api/v1/users/create/1` |
74
- | `['users', 'admin']` | `'Delete'` | `2` | `/api/v1/users/admin/delete/2` |
75
-
76
- ### Context Resolution
77
-
78
- The `factoryContext` parameter supports three patterns:
79
-
80
- ```typescript
81
- // 1. Static object
82
- builder.register(Factory, { userId: 'static-123' })
83
-
84
- // 2. Sync function
85
- builder.register(Factory, (c) => ({
86
- userId: c.req.header('x-user-id')
87
- }))
88
-
89
- // 3. Async function
90
- builder.register(Factory, async (c) => {
91
- const user = await validateToken(c.req.header('authorization'))
92
- return { userId: user.id }
93
- })
94
- ```
95
-
96
- ### Abort Signal
97
-
98
- All HTTP implementations automatically inject an `AbortSignal` into the handler context as `ctx.signal`. This signal aborts when the client disconnects, enabling handlers to cancel in-flight work (fetch calls, database queries, etc.).
99
-
100
- | Framework | Procedure kind | Signal source | Behavior |
101
- |-----------|---------------|---------------|----------|
102
- | HonoAppBuilder | `rpc`, `http` | `c.req.raw.signal` | Web standard Request signal |
103
- | HonoAppBuilder | `rpc-stream`, `http-stream` | `c.req.raw.signal` | Combined with internal stream AbortController via `AbortSignal.any()` |
104
-
105
- For streaming procedures, `signal.reason` is `'stream-completed'` on normal completion, allowing handlers to distinguish from client disconnection.
106
-
107
- ### Error Handling
108
-
109
- Both builders support two peer error-handling modes — **declarative** (`errors` taxonomy + `unknownError`) and **imperative** (`onError` callback) — plus a cross-cutting `onRequestError` observer for logging, tracing, and metrics.
110
-
111
- Full spec (taxonomy shape, `toResponse`/`onCatch`/`match`, per-route narrowing, mid-stream caveats): **[docs/http-integrations.md § Error Handling](../../../docs/http-integrations.md#error-handling)**.
112
-
113
- ### Lifecycle Hooks
114
-
115
- `HonoAppBuilder`'s config is **stratified**: cross-cutting hooks live at the top level, kind-specific hooks live inside `rpc:`, `api:`, and `stream:` blocks.
116
-
117
- ```typescript
118
- new HonoAppBuilder({
119
- // Cross-cutting (every kind)
120
- onRequestStart, onRequestEnd, onRequestError,
121
- errors, unknownError, onError,
122
-
123
- // Kind-specific blocks
124
- rpc: { onSuccess },
125
- api: { queryParser, onSuccess },
126
- stream: { defaultStreamMode, onStreamStart, onStreamEnd, onMidStreamError },
127
- })
128
- ```
129
-
130
- **Non-streaming flow (`rpc`, `http`):**
131
-
132
- ```
133
- onRequestStart → handler → onSuccess → onRequestEnd
134
-
135
- (on error)
136
-
137
- onRequestError (observer)
138
-
139
- errors taxonomy / onError fallback
140
-
141
- onRequestEnd
142
- ```
143
-
144
- **Streaming flow (`rpc-stream`, `http-stream`):**
145
-
146
- ```
147
- onRequestStart → onStreamStart → [yields...] → onStreamEnd → onRequestEnd
148
-
149
- (on error)
150
-
151
- ┌──────────────────┴──────────────────┐
152
- ↓ (pre-stream — before onStreamStart) ↓ (mid-stream — after first yield)
153
- errors taxonomy / onError → onRequestEnd onMidStreamError → onStreamEnd → onRequestEnd
154
- ```
155
-
156
- Pre-stream errors short-circuit before `onStreamStart` fires, so `onStreamEnd` does **not** run on that path. Mid-stream errors run `onMidStreamError` and then still fire `onStreamEnd` because the stream had already started.
157
-
158
- | Hook | Config block | Triggers on |
159
- |------|--------------|-------------|
160
- | `onRequestStart` | top-level | Before route handler (every kind) |
161
- | `onRequestEnd` | top-level | After response sent (every kind) |
162
- | `onRequestError` | top-level | Cross-cutting observer — fires for every caught error before dispatch |
163
- | `onError` | top-level | Imperative pre-stream error callback — peer of `errors` taxonomy |
164
- | `errors` / `unknownError` | top-level | Declarative taxonomy dispatch |
165
- | `rpc.onSuccess` | `rpc:` | After successful RPC handler |
166
- | `api.onSuccess` | `api:` | After successful HTTP handler |
167
- | `api.queryParser` | `api:` | Custom query-string parser for HTTP routes |
168
- | `stream.defaultStreamMode` | `stream:` | Default mode (`'sse'` \| `'text'`) for both stream kinds |
169
- | `stream.onStreamStart` | `stream:` | Before first yield |
170
- | `stream.onStreamEnd` | `stream:` | After stream completes |
171
- | `stream.onMidStreamError` | `stream:` | On mid-stream error (generator throws after first yield) |
172
-
173
- ### Route Documentation
174
-
175
- Each registered procedure generates documentation accessible via `builder.docs`. Every doc carries a `kind` discriminant for reliable narrowing.
176
-
177
- **RPC (`RPCHttpRouteDoc`, `kind: 'rpc'`):**
178
-
179
- ```typescript
180
- interface RPCHttpRouteDoc {
181
- kind: 'rpc'
182
- name: string
183
- path: string
184
- method: 'post'
185
- scope: string | string[]
186
- version: number
187
- errors?: string[]
188
- jsonSchema: {
189
- body?: object // From schema.params
190
- response?: object // From schema.returnType
191
- }
192
- }
193
- ```
194
-
195
- **RPC stream (`StreamHttpRouteDoc`, `kind: 'stream'`):**
196
-
197
- ```typescript
198
- interface StreamHttpRouteDoc {
199
- kind: 'stream'
200
- name: string
201
- path: string
202
- methods: ('get' | 'post')[]
203
- streamMode: 'sse' | 'text'
204
- scope: string | string[]
205
- version: number
206
- errors?: string[]
207
- jsonSchema: {
208
- params?: object // From schema.params
209
- yieldType?: object // From schema.yieldType
210
- returnType?: object // From schema.returnType
211
- }
212
- }
213
- ```
214
-
215
- **REST (`APIHttpRouteDoc`, `kind: 'api'`):**
216
-
217
- ```typescript
218
- interface APIHttpRouteDoc {
219
- kind: 'api'
220
- name: string
221
- scope?: string
222
- path: string
223
- method: HttpMethod
224
- fullPath: string // Includes pathPrefix
225
- successStatus?: number
226
- errors?: string[]
227
- jsonSchema: {
228
- req?: {
229
- pathParams?: object // From schema.req.pathParams
230
- query?: object // From schema.req.query
231
- body?: object // From schema.req.body
232
- headers?: object // From schema.req.headers
233
- }
234
- res?: {
235
- body?: object // From schema.res.body
236
- headers?: object // From schema.res.headers
237
- }
238
- }
239
- }
240
- ```
241
-
242
- **REST stream (`HttpStreamRouteDoc`, `kind: 'http-stream'`):**
243
-
244
- ```typescript
245
- interface HttpStreamRouteDoc {
246
- kind: 'http-stream'
247
- name: string
248
- scope?: string
249
- path: string
250
- method: HttpMethod
251
- fullPath: string
252
- streamMode: 'sse' | 'text'
253
- errors?: string[]
254
- jsonSchema: {
255
- req?: {
256
- pathParams?: object
257
- query?: object
258
- body?: object
259
- headers?: object
260
- }
261
- res?: { headers?: object }
262
- yield?: object
263
- returnType?: object
264
- }
265
- }
266
- ```
267
-
268
- ### Builder Pattern
269
-
270
- Both builders follow the same pattern:
271
-
272
- ```typescript
273
- const builder = new HonoAppBuilder(config)
274
- .register(PublicFactory, publicContextResolver)
275
- .register(ProtectedFactory, protectedContextResolver)
276
-
277
- const app = builder.build()
278
- const docs = builder.docs
279
- ```
280
-
281
- `build()` is synchronous — it returns the framework app instance directly. Don't `await` the call.
282
-
283
- A single `HonoAppBuilder` registers procedures of every kind from the same factory and mounts them on one Hono `app`. The optional `app?: Hono` config lets you mount onto an existing Hono instance that already has custom middleware, health checks, or static routes; if omitted, the builder constructs its own.
284
-
285
- **Key methods:**
286
-
287
- | Method | Returns | Description |
288
- |--------|---------|-------------|
289
- | `register(factory, context, options?)` | `this` | Register a procedure factory |
290
- | `build()` | Framework app | Create routes and return the application |
291
-
292
- **Properties:**
293
-
294
- | Property | Type | Description |
295
- |----------|------|-------------|
296
- | `app` | Framework app | The underlying framework application |
297
- | `docs` | Route doc array | Route documentation, lazily computed on first read; `build()` also populates it. |
298
-
299
- ### DocRegistry
300
-
301
- For single-builder apps, prefer `builder.toDocEnvelope({ basePath, errors })` — it wraps `DocRegistry` for the common case and produces an envelope identical to the multi-app aggregator.
302
-
303
- For multi-app aggregation (e.g., two `HonoAppBuilder` instances mounted on different prefixes), `DocRegistry` composes route documentation from every source into one typed envelope:
304
-
305
- ```typescript
306
- import { DocRegistry } from 'ts-procedures/http-docs'
307
-
308
- const docs = new DocRegistry({
309
- basePath: '/api',
310
- errors: appErrors, // your ErrorTaxonomy — framework defaults auto-merged and deduped
311
- })
312
- .from(builderA)
313
- .from(builderB)
314
-
315
- app.get('/docs', (c) => c.json(docs.toJSON()))
316
- ```
317
-
318
- - `from()` stores a reference — routes are read lazily at `toJSON()` time
319
- - `toJSON()` supports optional `filter` and `transform` options
320
- - `errors` accepts an `ErrorTaxonomy` or raw `ErrorDoc[]`; framework defaults are auto-merged (opt out via `includeDefaults: false`)
321
- - Every builder satisfies the `DocSource` interface (`{ readonly docs: AnyHttpRouteDoc[] }`)
322
-
323
- ### Client Code Generation
324
-
325
- Generate type-safe client SDKs from your DocRegistry output. The codegen reads the `DocEnvelope` JSON and produces per-scope TypeScript files with typed params, response types, and callable functions.
326
-
327
- **Requirements:** every route needs a `scope` field for file grouping. RPC and stream routes carry `scope` via `RPCConfig`. REST routes (`CreateHttp` / `CreateHttpStream`) carry an optional `scope` directly on the procedure config:
328
-
329
- ```typescript
330
- procs.CreateHttp('GetUser', {
331
- path: '/users/:id',
332
- method: 'get',
333
- scope: 'users', // Used for codegen file grouping
334
- schema: { req: { pathParams: Type.Object({ id: Type.String() }) } },
335
- }, async (_, { pathParams }) => /* ... */)
336
- ```
337
-
338
- **Route-doc kinds and how the codegen consumes them:**
339
-
340
- | Doc kind | Source procedure | Params shape in generated callable | Generated callable |
341
- |----------|------------------|------------------------------------|--------------------|
342
- | `rpc` | `Create()` | `jsonSchema.body` → flat params | `client.call()` |
343
- | `api` | `CreateHttp()` | `jsonSchema.req.{pathParams,query,body,headers}` → structured params | `client.call()` |
344
- | `stream` | `CreateStream()` | `jsonSchema.params` → flat params | `client.stream()` |
345
- | `http-stream` | `CreateHttpStream()` | `jsonSchema.req.{pathParams,query,body,headers}` → structured params | `client.stream()` |
346
-
347
- **SSE return values:** Stream procedures that return a value have it sent as `event: 'return'` SSE message. The client's `TypedStream.result` promise resolves with this value.
348
-
349
- **SSE yieldType unwrapping:** Codegen detects the SSE envelope in `yieldType` and uses the inner `data` schema for the generated `Yield` type.
350
-
351
- **Kind discriminant:** All route docs include a `kind` field (`'rpc' | 'api' | 'stream' | 'http-stream'`) for reliable type narrowing in the codegen pipeline and consumer code.
352
-
353
- **Namespace types:** Use `--namespace-types` to wrap generated types in nested TS namespaces (`Scope.Route.Params`) instead of flat prefixed exports (`RouteParams`).
354
-
355
- **ajsc options:** `--enum-style`, `--depluralize`, `--array-item-naming`, `--uncountable-words` are passed through to the ajsc TypescriptConverter for JSON Schema → TypeScript conversion.
356
-
357
- **Self-contained mode:** Use `--self-contained` to emit `_types.ts` (all client type definitions) and `_client.ts` (runtime: `createClient`, `createFetchAdapter`, hooks, errors) into the output directory. All scope files and `index.ts` will import from `./_types` instead of `ts-procedures/client`, so consumers have no runtime dependency on `ts-procedures`. With this flag, `ts-procedures` can be a devDependency only.
358
-
359
- **Clean output directory:** Use `--clean-out-dir` (or `cleanOutDir: true` in the programmatic API) to recursively remove the output directory before writing, so scope files left over from deleted or renamed scopes are pruned. Skipped under `--dry-run`.
360
-
361
- ## TypeScript Types
362
-
363
- ```typescript
364
- import type {
365
- RPCConfig,
366
- RPCHttpRouteDoc,
367
- StreamHttpRouteDoc,
368
- HttpStreamRouteDoc,
369
- StreamMode,
370
- APIConfig,
371
- APIHttpRouteDoc,
372
- APIInput,
373
- HttpMethod,
374
- } from 'ts-procedures/http'
375
-
376
- // Client Runtime
377
- import { createClient, createFetchAdapter } from 'ts-procedures/client'
378
- import type {
379
- ClientAdapter,
380
- ClientHooks,
381
- TypedStream,
382
- ClientInstance,
383
- ProcedureCallDefaults,
384
- ProcedureCallOptions,
385
- RequestMeta,
386
- } from 'ts-procedures/client'
387
-
388
- // Code Generation (build-time only)
389
- import { generateClient } from 'ts-procedures/codegen'
390
- ```
@@ -1,283 +0,0 @@
1
- import { describe, expect, test, vi } from 'vitest'
2
- import { Hono } from 'hono'
3
- import { dispatchMidStreamError, dispatchPreStreamError } from './error-dispatch.js'
4
- import { defineErrorTaxonomy } from './error-taxonomy.js'
5
- import { ProcedureValidationError } from '../../errors.js'
6
-
7
- function makeContext() {
8
- return new Promise<import('hono').Context>((resolve) => {
9
- const app = new Hono()
10
- app.get('/', (c) => {
11
- resolve(c)
12
- return c.text('ok')
13
- })
14
- app.request('/')
15
- })
16
- }
17
-
18
- const dummyProcedure = {
19
- name: 'Test',
20
- kind: 'rpc',
21
- config: { scope: 'test', version: 1 },
22
- handler: async () => undefined,
23
- } as any
24
-
25
- describe('dispatchPreStreamError', () => {
26
- test('default taxonomy: ProcedureValidationError → 400', async () => {
27
- const c = await makeContext()
28
- const err = new ProcedureValidationError('Test', 'Validation error for Test', [
29
- { instancePath: '/x', message: 'expected number' } as any,
30
- ])
31
-
32
- const res = await dispatchPreStreamError({
33
- err,
34
- procedure: dummyProcedure,
35
- raw: c,
36
- cfg: {},
37
- })
38
-
39
- expect(res.status).toBe(400)
40
- const body = await res.json()
41
- expect(body.name).toBe('ProcedureValidationError')
42
- expect(body.procedureName).toBe('Test')
43
- })
44
-
45
- test('user taxonomy entry takes precedence', async () => {
46
- const c = await makeContext()
47
- class MyError extends Error {
48
- constructor(public reason: string) { super(reason) }
49
- }
50
- const errors = defineErrorTaxonomy({
51
- MyError: { class: MyError, statusCode: 422, toResponse: (e) => ({ name: 'MyError', reason: e.reason }) },
52
- })
53
-
54
- const res = await dispatchPreStreamError({
55
- err: new MyError('boom'),
56
- procedure: dummyProcedure,
57
- raw: c,
58
- cfg: { errors },
59
- })
60
-
61
- expect(res.status).toBe(422)
62
- expect(await res.json()).toEqual({ name: 'MyError', reason: 'boom' })
63
- })
64
-
65
- test('falls back to onError imperative callback', async () => {
66
- const c = await makeContext()
67
- const onError = vi.fn().mockResolvedValue(c.json({ ok: false }, 503))
68
-
69
- const res = await dispatchPreStreamError({
70
- err: new Error('unmatched'),
71
- procedure: dummyProcedure,
72
- raw: c,
73
- cfg: { onError: (proc, raw, e) => onError(proc, raw, e) },
74
- })
75
-
76
- expect(onError).toHaveBeenCalled()
77
- expect(res.status).toBe(503)
78
- })
79
-
80
- test('hard default 500 when nothing matches', async () => {
81
- const c = await makeContext()
82
- const res = await dispatchPreStreamError({
83
- err: new Error('boom'),
84
- procedure: dummyProcedure,
85
- raw: c,
86
- cfg: {},
87
- })
88
- expect(res.status).toBe(500)
89
- expect(await res.json()).toEqual({ error: 'boom' })
90
- })
91
-
92
- test('onRequestError observer fires before dispatch and is awaited', async () => {
93
- const c = await makeContext()
94
- const calls: string[] = []
95
- const onRequestError = vi.fn(async () => {
96
- calls.push('observer')
97
- })
98
- const errors = defineErrorTaxonomy({
99
- AnyError: {
100
- match: (e): e is Error => e instanceof Error,
101
- statusCode: 500,
102
- toResponse: () => {
103
- calls.push('toResponse')
104
- return { name: 'AnyError' }
105
- },
106
- },
107
- })
108
-
109
- await dispatchPreStreamError({
110
- err: new Error('x'),
111
- procedure: dummyProcedure,
112
- raw: c,
113
- cfg: { errors, onRequestError },
114
- })
115
-
116
- expect(calls).toEqual(['observer', 'toResponse'])
117
- expect(onRequestError).toHaveBeenCalledWith({ err: expect.any(Error), procedure: dummyProcedure, raw: c })
118
- })
119
-
120
- test('observer throw is swallowed and logged', async () => {
121
- const c = await makeContext()
122
- const consoleErr = vi.spyOn(console, 'error').mockImplementation(() => {})
123
- const onRequestError = vi.fn(() => { throw new Error('observer broke') })
124
-
125
- const res = await dispatchPreStreamError({
126
- err: new Error('x'),
127
- procedure: dummyProcedure,
128
- raw: c,
129
- cfg: { onRequestError },
130
- })
131
-
132
- expect(res.status).toBe(500)
133
- expect(consoleErr).toHaveBeenCalled()
134
- consoleErr.mockRestore()
135
- })
136
-
137
- test('taxonomy onCatch is fully awaited before the response body is written', async () => {
138
- const c = await makeContext()
139
- const calls: string[] = []
140
- class HookedError extends Error {}
141
- const errors = defineErrorTaxonomy({
142
- HookedError: {
143
- class: HookedError,
144
- statusCode: 500,
145
- toResponse: () => ({ name: 'HookedError' }),
146
- onCatch: async () => {
147
- // Awaiting an async setTimeout here means a non-awaiting dispatcher
148
- // would write the response BEFORE this push runs. The order we capture
149
- // in `calls` reveals which branch happened.
150
- await new Promise<void>((resolve) => setTimeout(resolve, 5))
151
- calls.push('oncatch-done')
152
- },
153
- },
154
- })
155
-
156
- // Spy on c.json: when the dispatcher writes the response, record where in
157
- // the timeline it happened relative to onCatch's push.
158
- const originalJson = c.json.bind(c) as (...args: any[]) => Response
159
- const jsonSpy = vi.fn((...args: any[]) => {
160
- calls.push('response-write')
161
- return originalJson(...args)
162
- })
163
- ;(c as any).json = jsonSpy
164
-
165
- const res = await dispatchPreStreamError({
166
- err: new HookedError('boom'),
167
- procedure: dummyProcedure,
168
- raw: c,
169
- cfg: { errors },
170
- })
171
-
172
- expect(res.status).toBe(500)
173
- expect(jsonSpy).toHaveBeenCalledTimes(1)
174
- // If the dispatcher awaits onCatch first, 'oncatch-done' precedes
175
- // 'response-write'. Without the await, the order would be reversed
176
- // (or 'oncatch-done' would land after the dispatcher returns).
177
- expect(calls).toEqual(['oncatch-done', 'response-write'])
178
- })
179
- })
180
-
181
- const streamProcedure = {
182
- name: 'Tail',
183
- kind: 'rpc-stream',
184
- config: { scope: 'logs', version: 1 },
185
- handler: async function* () {},
186
- } as any
187
-
188
- describe('dispatchMidStreamError', () => {
189
- test('uses taxonomy body when configured', async () => {
190
- const c = await makeContext()
191
- class MidErr extends Error {}
192
- const errors = defineErrorTaxonomy({
193
- MidErr: { class: MidErr, statusCode: 500, toResponse: () => ({ name: 'MidErr', detail: 'x' }) },
194
- })
195
-
196
- const result = await dispatchMidStreamError({
197
- err: new MidErr('mid'),
198
- procedure: streamProcedure,
199
- raw: c,
200
- cfg: { errors },
201
- })
202
-
203
- expect(result.data).toEqual({ name: 'MidErr', detail: 'x' })
204
- expect(result.sseEvent).toBe('error')
205
- expect(result.runOnCatch).toBeTypeOf('function')
206
- })
207
-
208
- test('falls back to onMidStreamError', async () => {
209
- const c = await makeContext()
210
- const result = await dispatchMidStreamError({
211
- err: new Error('boom'),
212
- procedure: streamProcedure,
213
- raw: c,
214
- cfg: {
215
- onMidStreamError: () => ({ data: { kind: 'fail', msg: 'boom' } }),
216
- },
217
- })
218
-
219
- expect(result.data).toEqual({ kind: 'fail', msg: 'boom' })
220
- expect(result.sseEvent).toBe('Tail') // procedure name override
221
- })
222
-
223
- test('hard default { error: msg } when nothing matches', async () => {
224
- const c = await makeContext()
225
- const result = await dispatchMidStreamError({
226
- err: new Error('plain'),
227
- procedure: streamProcedure,
228
- raw: c,
229
- cfg: {},
230
- })
231
-
232
- expect(result.data).toEqual({ error: 'plain' })
233
- expect(result.sseEvent).toBe('error')
234
- })
235
-
236
- test('onRequestError observer fires before dispatch (mid-stream form)', async () => {
237
- const c = await makeContext()
238
- const onRequestError = vi.fn(async () => {})
239
-
240
- await dispatchMidStreamError({
241
- err: new Error('x'),
242
- procedure: streamProcedure,
243
- raw: c,
244
- cfg: { onRequestError },
245
- })
246
-
247
- expect(onRequestError).toHaveBeenCalled()
248
- })
249
-
250
- test('returns a runOnCatch function that is invokable and awaits the taxonomy hook', async () => {
251
- const c = await makeContext()
252
- const calls: string[] = []
253
- class StreamErr extends Error {}
254
- const errors = defineErrorTaxonomy({
255
- StreamErr: {
256
- class: StreamErr,
257
- statusCode: 500,
258
- toResponse: () => ({ name: 'StreamErr' }),
259
- onCatch: async () => {
260
- await new Promise<void>((resolve) => setTimeout(resolve, 5))
261
- calls.push('oncatch-done')
262
- },
263
- },
264
- })
265
-
266
- // Mid-stream contract: the dispatcher does NOT call runOnCatch itself —
267
- // the caller (stream handler) decides when to invoke it. Verify the shape
268
- // and that awaiting it actually awaits the hook.
269
- const result = await dispatchMidStreamError({
270
- err: new StreamErr('mid'),
271
- procedure: streamProcedure,
272
- raw: c,
273
- cfg: { errors },
274
- })
275
-
276
- expect(result.runOnCatch).toBeTypeOf('function')
277
- // Hook has not yet run — caller hasn't invoked it.
278
- expect(calls).toEqual([])
279
-
280
- await result.runOnCatch!()
281
- expect(calls).toEqual(['oncatch-done'])
282
- })
283
- })