ts-procedures 7.3.0 → 8.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 (325) hide show
  1. package/README.md +65 -3
  2. package/agent_config/claude-code/agents/ts-procedures-architect.md +6 -8
  3. package/agent_config/claude-code/skills/ts-procedures/SKILL.md +30 -33
  4. package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +104 -53
  5. package/agent_config/claude-code/skills/ts-procedures/api-reference.md +205 -232
  6. package/agent_config/claude-code/skills/ts-procedures/patterns.md +80 -153
  7. package/agent_config/claude-code/skills/ts-procedures-review/SKILL.md +1 -1
  8. package/agent_config/claude-code/skills/ts-procedures-review/checklist.md +4 -5
  9. package/agent_config/claude-code/skills/ts-procedures-scaffold/SKILL.md +4 -7
  10. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono.md +223 -0
  11. package/agent_config/copilot/copilot-instructions.md +34 -48
  12. package/agent_config/cursor/cursorrules +34 -48
  13. package/build/client/call.js +4 -1
  14. package/build/client/call.js.map +1 -1
  15. package/build/client/call.test.js +23 -0
  16. package/build/client/call.test.js.map +1 -1
  17. package/build/client/fetch-adapter.js +3 -1
  18. package/build/client/fetch-adapter.js.map +1 -1
  19. package/build/client/fetch-adapter.test.js +11 -1
  20. package/build/client/fetch-adapter.test.js.map +1 -1
  21. package/build/client/index.test.js +7 -7
  22. package/build/client/index.test.js.map +1 -1
  23. package/build/client/request-builder.d.ts +1 -1
  24. package/build/client/request-builder.js +2 -2
  25. package/build/client/request-builder.js.map +1 -1
  26. package/build/client/stream.js +13 -2
  27. package/build/client/stream.js.map +1 -1
  28. package/build/client/stream.test.js +32 -7
  29. package/build/client/stream.test.js.map +1 -1
  30. package/build/client/typed-error-dispatch.test.js +8 -92
  31. package/build/client/typed-error-dispatch.test.js.map +1 -1
  32. package/build/client/types.d.ts +21 -3
  33. package/build/codegen/bin/cli.js +0 -0
  34. package/build/codegen/e2e.test.js +87 -23
  35. package/build/codegen/e2e.test.js.map +1 -1
  36. package/build/codegen/emit-errors.integration.test.js +1 -1
  37. package/build/codegen/emit-errors.integration.test.js.map +1 -1
  38. package/build/codegen/emit-scope.js +308 -47
  39. package/build/codegen/emit-scope.js.map +1 -1
  40. package/build/codegen/emit-scope.test.js +363 -110
  41. package/build/codegen/emit-scope.test.js.map +1 -1
  42. package/build/codegen/pipeline.test.js +7 -7
  43. package/build/codegen/pipeline.test.js.map +1 -1
  44. package/build/codegen/resolve-envelope.js +1 -1
  45. package/build/codegen/resolve-envelope.js.map +1 -1
  46. package/build/codegen/resolve-envelope.test.js +5 -5
  47. package/build/codegen/resolve-envelope.test.js.map +1 -1
  48. package/build/codegen/targets/_shared/route-slots.d.ts +8 -3
  49. package/build/codegen/targets/_shared/route-slots.js +49 -8
  50. package/build/codegen/targets/_shared/route-slots.js.map +1 -1
  51. package/build/codegen/targets/_shared/route-slots.test.js +99 -26
  52. package/build/codegen/targets/_shared/route-slots.test.js.map +1 -1
  53. package/build/codegen/targets/kotlin/emit-route-kotlin.test.js +88 -17
  54. package/build/codegen/targets/kotlin/emit-route-kotlin.test.js.map +1 -1
  55. package/build/codegen/targets/kotlin/emit-scope-kotlin.test.js +9 -6
  56. package/build/codegen/targets/kotlin/emit-scope-kotlin.test.js.map +1 -1
  57. package/build/codegen/targets/kotlin/integration.test.js +6 -0
  58. package/build/codegen/targets/kotlin/integration.test.js.map +1 -1
  59. package/build/codegen/targets/swift/access-level.test.js +8 -11
  60. package/build/codegen/targets/swift/access-level.test.js.map +1 -1
  61. package/build/codegen/targets/swift/emit-route-swift.test.js +91 -20
  62. package/build/codegen/targets/swift/emit-route-swift.test.js.map +1 -1
  63. package/build/codegen/targets/swift/emit-scope-swift.test.js +12 -9
  64. package/build/codegen/targets/swift/emit-scope-swift.test.js.map +1 -1
  65. package/build/codegen/targets/swift/integration.test.js +6 -0
  66. package/build/codegen/targets/swift/integration.test.js.map +1 -1
  67. package/build/create-http-stream.d.ts +58 -0
  68. package/build/create-http-stream.js +122 -0
  69. package/build/create-http-stream.js.map +1 -0
  70. package/build/create-http-stream.test.js +88 -0
  71. package/build/create-http-stream.test.js.map +1 -0
  72. package/build/create-http.d.ts +49 -0
  73. package/build/create-http.js +108 -0
  74. package/build/create-http.js.map +1 -0
  75. package/build/create-http.test.js +137 -0
  76. package/build/create-http.test.js.map +1 -0
  77. package/build/create-stream.d.ts +35 -0
  78. package/build/create-stream.js +123 -0
  79. package/build/create-stream.js.map +1 -0
  80. package/build/create-stream.test.js +428 -0
  81. package/build/create-stream.test.js.map +1 -0
  82. package/build/create.d.ts +28 -0
  83. package/build/create.js +82 -0
  84. package/build/create.js.map +1 -0
  85. package/build/create.test.js +483 -0
  86. package/build/create.test.js.map +1 -0
  87. package/build/exports.d.ts +2 -0
  88. package/build/implementations/http/astro/index.test.js +20 -12
  89. package/build/implementations/http/astro/index.test.js.map +1 -1
  90. package/build/implementations/http/doc-registry.js +1 -1
  91. package/build/implementations/http/doc-registry.js.map +1 -1
  92. package/build/implementations/http/doc-registry.test.js +36 -5
  93. package/build/implementations/http/doc-registry.test.js.map +1 -1
  94. package/build/implementations/http/error-dispatch.d.ts +76 -0
  95. package/build/implementations/http/error-dispatch.js +77 -0
  96. package/build/implementations/http/error-dispatch.js.map +1 -0
  97. package/build/implementations/http/error-dispatch.test.js +254 -0
  98. package/build/implementations/http/error-dispatch.test.js.map +1 -0
  99. package/build/implementations/http/error-taxonomy.d.ts +5 -5
  100. package/build/implementations/http/hono/docs/http-doc.d.ts +6 -0
  101. package/build/implementations/http/hono/docs/http-doc.js +42 -0
  102. package/build/implementations/http/hono/docs/http-doc.js.map +1 -0
  103. package/build/implementations/http/hono/docs/http-stream-doc.d.ts +6 -0
  104. package/build/implementations/http/hono/docs/http-stream-doc.js +40 -0
  105. package/build/implementations/http/hono/docs/http-stream-doc.js.map +1 -0
  106. package/build/implementations/http/hono/docs/rpc-doc.d.ts +6 -0
  107. package/build/implementations/http/hono/docs/rpc-doc.js +24 -0
  108. package/build/implementations/http/hono/docs/rpc-doc.js.map +1 -0
  109. package/build/implementations/http/hono/docs/stream-doc.d.ts +6 -0
  110. package/build/implementations/http/hono/docs/stream-doc.js +42 -0
  111. package/build/implementations/http/hono/docs/stream-doc.js.map +1 -0
  112. package/build/implementations/http/hono/handlers/http-stream.d.ts +10 -0
  113. package/build/implementations/http/hono/handlers/http-stream.js +123 -0
  114. package/build/implementations/http/hono/handlers/http-stream.js.map +1 -0
  115. package/build/implementations/http/hono/handlers/http-stream.test.js +128 -0
  116. package/build/implementations/http/hono/handlers/http-stream.test.js.map +1 -0
  117. package/build/implementations/http/hono/handlers/http.d.ts +10 -0
  118. package/build/implementations/http/hono/handlers/http.js +115 -0
  119. package/build/implementations/http/hono/handlers/http.js.map +1 -0
  120. package/build/implementations/http/hono/handlers/http.test.js +118 -0
  121. package/build/implementations/http/hono/handlers/http.test.js.map +1 -0
  122. package/build/implementations/http/hono/handlers/rpc.d.ts +11 -0
  123. package/build/implementations/http/hono/handlers/rpc.js +32 -0
  124. package/build/implementations/http/hono/handlers/rpc.js.map +1 -0
  125. package/build/implementations/http/hono/handlers/rpc.test.js +73 -0
  126. package/build/implementations/http/hono/handlers/rpc.test.js.map +1 -0
  127. package/build/implementations/http/hono/handlers/stream.d.ts +23 -0
  128. package/build/implementations/http/hono/handlers/stream.js +147 -0
  129. package/build/implementations/http/hono/handlers/stream.js.map +1 -0
  130. package/build/implementations/http/hono/handlers/stream.test.d.ts +1 -0
  131. package/build/implementations/http/hono/handlers/stream.test.js +177 -0
  132. package/build/implementations/http/hono/handlers/stream.test.js.map +1 -0
  133. package/build/implementations/http/hono/index.d.ts +57 -0
  134. package/build/implementations/http/hono/index.js +149 -0
  135. package/build/implementations/http/hono/index.js.map +1 -0
  136. package/build/implementations/http/hono/index.test.d.ts +1 -0
  137. package/build/implementations/http/hono/index.test.js +274 -0
  138. package/build/implementations/http/hono/index.test.js.map +1 -0
  139. package/build/implementations/http/hono/path.d.ts +17 -0
  140. package/build/implementations/http/hono/path.js +39 -0
  141. package/build/implementations/http/hono/path.js.map +1 -0
  142. package/build/implementations/http/hono/path.test.d.ts +1 -0
  143. package/build/implementations/http/hono/path.test.js +83 -0
  144. package/build/implementations/http/hono/path.test.js.map +1 -0
  145. package/build/implementations/http/hono/types.d.ts +51 -0
  146. package/build/implementations/http/hono/types.js.map +1 -0
  147. package/build/implementations/http/on-request-error.test.js +6 -96
  148. package/build/implementations/http/on-request-error.test.js.map +1 -1
  149. package/build/implementations/http/route-errors.test.js +11 -59
  150. package/build/implementations/http/route-errors.test.js.map +1 -1
  151. package/build/implementations/types.d.ts +43 -9
  152. package/build/index.d.ts +124 -124
  153. package/build/index.js +10 -221
  154. package/build/index.js.map +1 -1
  155. package/build/index.test.js +20 -919
  156. package/build/index.test.js.map +1 -1
  157. package/build/migration.test.d.ts +1 -0
  158. package/build/migration.test.js +34 -0
  159. package/build/migration.test.js.map +1 -0
  160. package/build/schema/compute-schema.d.ts +11 -3
  161. package/build/schema/compute-schema.js +13 -7
  162. package/build/schema/compute-schema.js.map +1 -1
  163. package/build/schema/parser.d.ts +11 -3
  164. package/build/schema/parser.js +49 -9
  165. package/build/schema/parser.js.map +1 -1
  166. package/build/stack-utils.js +8 -0
  167. package/build/stack-utils.js.map +1 -1
  168. package/build/types.d.ts +142 -0
  169. package/build/types.js.map +1 -0
  170. package/docs/astro-adapter.md +5 -5
  171. package/docs/core.md +15 -17
  172. package/docs/http-integrations.md +83 -170
  173. package/docs/streaming.md +3 -60
  174. package/docs/superpowers/plans/2026-05-07-astro-adapter.md +2 -7
  175. package/docs/superpowers/plans/2026-05-08-create-http.md +3355 -0
  176. package/docs/superpowers/plans/2026-05-08-hono-app-builder-convergence.md +3365 -0
  177. package/docs/superpowers/specs/2026-05-07-astro-adapter-design.md +1 -3
  178. package/docs/superpowers/specs/2026-05-08-create-http-design.md +409 -0
  179. package/docs/superpowers/specs/2026-05-08-hono-app-builder-convergence-design.md +411 -0
  180. package/package.json +4 -22
  181. package/src/client/call.test.ts +26 -0
  182. package/src/client/call.ts +4 -1
  183. package/src/client/fetch-adapter.test.ts +14 -1
  184. package/src/client/fetch-adapter.ts +3 -1
  185. package/src/client/index.test.ts +7 -7
  186. package/src/client/request-builder.ts +2 -2
  187. package/src/client/stream.test.ts +39 -7
  188. package/src/client/stream.ts +16 -2
  189. package/src/client/typed-error-dispatch.test.ts +7 -97
  190. package/src/client/types.ts +21 -3
  191. package/src/codegen/__fixtures__/users-envelope.json +119 -38
  192. package/src/codegen/e2e.test.ts +98 -24
  193. package/src/codegen/emit-errors.integration.test.ts +1 -1
  194. package/src/codegen/emit-scope.test.ts +395 -110
  195. package/src/codegen/emit-scope.ts +350 -55
  196. package/src/codegen/pipeline.test.ts +7 -7
  197. package/src/codegen/resolve-envelope.test.ts +5 -5
  198. package/src/codegen/resolve-envelope.ts +1 -1
  199. package/src/codegen/targets/_shared/route-slots.test.ts +109 -26
  200. package/src/codegen/targets/_shared/route-slots.ts +48 -11
  201. package/src/codegen/targets/kotlin/__fixtures__/users-golden.kt +73 -0
  202. package/src/codegen/targets/kotlin/emit-route-kotlin.test.ts +100 -17
  203. package/src/codegen/targets/kotlin/emit-scope-kotlin.test.ts +9 -6
  204. package/src/codegen/targets/kotlin/integration.test.ts +19 -0
  205. package/src/codegen/targets/swift/__fixtures__/users-golden.swift +79 -0
  206. package/src/codegen/targets/swift/access-level.test.ts +8 -11
  207. package/src/codegen/targets/swift/emit-route-swift.test.ts +103 -20
  208. package/src/codegen/targets/swift/emit-scope-swift.test.ts +12 -9
  209. package/src/codegen/targets/swift/integration.test.ts +17 -0
  210. package/src/create-http-stream.test.ts +97 -0
  211. package/src/create-http-stream.ts +191 -0
  212. package/src/create-http.test.ts +163 -0
  213. package/src/create-http.ts +211 -0
  214. package/src/create-stream.test.ts +565 -0
  215. package/src/create-stream.ts +228 -0
  216. package/src/create.test.ts +658 -0
  217. package/src/create.ts +172 -0
  218. package/src/exports.ts +2 -0
  219. package/src/implementations/http/README.md +135 -95
  220. package/src/implementations/http/astro/README.md +4 -5
  221. package/src/implementations/http/astro/index.test.ts +25 -18
  222. package/src/implementations/http/doc-registry.test.ts +42 -5
  223. package/src/implementations/http/doc-registry.ts +1 -1
  224. package/src/implementations/http/error-dispatch.test.ts +283 -0
  225. package/src/implementations/http/error-dispatch.ts +176 -0
  226. package/src/implementations/http/error-taxonomy.ts +5 -5
  227. package/src/implementations/http/hono/docs/http-doc.ts +43 -0
  228. package/src/implementations/http/hono/docs/http-stream-doc.ts +44 -0
  229. package/src/implementations/http/hono/docs/rpc-doc.ts +34 -0
  230. package/src/implementations/http/hono/docs/stream-doc.ts +53 -0
  231. package/src/implementations/http/hono/handlers/http-stream.test.ts +150 -0
  232. package/src/implementations/http/hono/handlers/http-stream.ts +152 -0
  233. package/src/implementations/http/hono/handlers/http.test.ts +130 -0
  234. package/src/implementations/http/hono/handlers/http.ts +147 -0
  235. package/src/implementations/http/hono/handlers/rpc.test.ts +81 -0
  236. package/src/implementations/http/hono/handlers/rpc.ts +54 -0
  237. package/src/implementations/http/hono/handlers/stream.test.ts +198 -0
  238. package/src/implementations/http/hono/handlers/stream.ts +208 -0
  239. package/src/implementations/http/hono/index.test.ts +329 -0
  240. package/src/implementations/http/hono/index.ts +204 -0
  241. package/src/implementations/http/hono/path.test.ts +96 -0
  242. package/src/implementations/http/hono/path.ts +59 -0
  243. package/src/implementations/http/hono/types.ts +93 -0
  244. package/src/implementations/http/on-request-error.test.ts +10 -116
  245. package/src/implementations/http/route-errors.test.ts +11 -77
  246. package/src/implementations/types.ts +44 -9
  247. package/src/index.test.ts +22 -1249
  248. package/src/index.ts +49 -485
  249. package/src/migration.test.ts +48 -0
  250. package/src/schema/compute-schema.ts +26 -12
  251. package/src/schema/parser.ts +62 -12
  252. package/src/stack-utils.ts +8 -0
  253. package/src/types.ts +133 -0
  254. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/express-rpc.md +0 -137
  255. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-api.md +0 -173
  256. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-rpc.md +0 -142
  257. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-stream.md +0 -147
  258. package/build/implementations/http/express-rpc/error-taxonomy.test.js +0 -83
  259. package/build/implementations/http/express-rpc/error-taxonomy.test.js.map +0 -1
  260. package/build/implementations/http/express-rpc/index.d.ts +0 -125
  261. package/build/implementations/http/express-rpc/index.js +0 -216
  262. package/build/implementations/http/express-rpc/index.js.map +0 -1
  263. package/build/implementations/http/express-rpc/index.test.js +0 -684
  264. package/build/implementations/http/express-rpc/index.test.js.map +0 -1
  265. package/build/implementations/http/express-rpc/types.d.ts +0 -11
  266. package/build/implementations/http/express-rpc/types.js.map +0 -1
  267. package/build/implementations/http/hono-api/error-taxonomy.test.js +0 -137
  268. package/build/implementations/http/hono-api/error-taxonomy.test.js.map +0 -1
  269. package/build/implementations/http/hono-api/index.d.ts +0 -151
  270. package/build/implementations/http/hono-api/index.js +0 -344
  271. package/build/implementations/http/hono-api/index.js.map +0 -1
  272. package/build/implementations/http/hono-api/index.test.js +0 -992
  273. package/build/implementations/http/hono-api/index.test.js.map +0 -1
  274. package/build/implementations/http/hono-api/types.d.ts +0 -13
  275. package/build/implementations/http/hono-api/types.js.map +0 -1
  276. package/build/implementations/http/hono-rpc/error-taxonomy.test.js +0 -64
  277. package/build/implementations/http/hono-rpc/error-taxonomy.test.js.map +0 -1
  278. package/build/implementations/http/hono-rpc/index.d.ts +0 -130
  279. package/build/implementations/http/hono-rpc/index.js +0 -209
  280. package/build/implementations/http/hono-rpc/index.js.map +0 -1
  281. package/build/implementations/http/hono-rpc/index.test.js +0 -828
  282. package/build/implementations/http/hono-rpc/index.test.js.map +0 -1
  283. package/build/implementations/http/hono-rpc/types.d.ts +0 -11
  284. package/build/implementations/http/hono-rpc/types.js +0 -2
  285. package/build/implementations/http/hono-rpc/types.js.map +0 -1
  286. package/build/implementations/http/hono-stream/error-taxonomy.test.js +0 -159
  287. package/build/implementations/http/hono-stream/error-taxonomy.test.js.map +0 -1
  288. package/build/implementations/http/hono-stream/index.d.ts +0 -171
  289. package/build/implementations/http/hono-stream/index.js +0 -415
  290. package/build/implementations/http/hono-stream/index.js.map +0 -1
  291. package/build/implementations/http/hono-stream/index.test.js +0 -1383
  292. package/build/implementations/http/hono-stream/index.test.js.map +0 -1
  293. package/build/implementations/http/hono-stream/types.d.ts +0 -15
  294. package/build/implementations/http/hono-stream/types.js +0 -2
  295. package/build/implementations/http/hono-stream/types.js.map +0 -1
  296. package/src/implementations/http/express-rpc/README.md +0 -280
  297. package/src/implementations/http/express-rpc/error-taxonomy.test.ts +0 -103
  298. package/src/implementations/http/express-rpc/index.test.ts +0 -957
  299. package/src/implementations/http/express-rpc/index.ts +0 -327
  300. package/src/implementations/http/express-rpc/types.ts +0 -16
  301. package/src/implementations/http/hono-api/README.md +0 -284
  302. package/src/implementations/http/hono-api/error-taxonomy.test.ts +0 -179
  303. package/src/implementations/http/hono-api/index.test.ts +0 -1341
  304. package/src/implementations/http/hono-api/index.ts +0 -519
  305. package/src/implementations/http/hono-api/types.ts +0 -16
  306. package/src/implementations/http/hono-rpc/README.md +0 -357
  307. package/src/implementations/http/hono-rpc/error-taxonomy.test.ts +0 -82
  308. package/src/implementations/http/hono-rpc/index.test.ts +0 -1107
  309. package/src/implementations/http/hono-rpc/index.ts +0 -320
  310. package/src/implementations/http/hono-rpc/types.ts +0 -16
  311. package/src/implementations/http/hono-stream/README.md +0 -559
  312. package/src/implementations/http/hono-stream/error-taxonomy.test.ts +0 -178
  313. package/src/implementations/http/hono-stream/index.test.ts +0 -1804
  314. package/src/implementations/http/hono-stream/index.ts +0 -622
  315. package/src/implementations/http/hono-stream/types.ts +0 -20
  316. /package/build/{implementations/http/express-rpc/error-taxonomy.test.d.ts → create-http-stream.test.d.ts} +0 -0
  317. /package/build/{implementations/http/express-rpc/index.test.d.ts → create-http.test.d.ts} +0 -0
  318. /package/build/{implementations/http/hono-api/error-taxonomy.test.d.ts → create-stream.test.d.ts} +0 -0
  319. /package/build/{implementations/http/hono-api/index.test.d.ts → create.test.d.ts} +0 -0
  320. /package/build/implementations/http/{hono-rpc/error-taxonomy.test.d.ts → error-dispatch.test.d.ts} +0 -0
  321. /package/build/implementations/http/{hono-rpc/index.test.d.ts → hono/handlers/http-stream.test.d.ts} +0 -0
  322. /package/build/implementations/http/{hono-stream/error-taxonomy.test.d.ts → hono/handlers/http.test.d.ts} +0 -0
  323. /package/build/implementations/http/{hono-stream/index.test.d.ts → hono/handlers/rpc.test.d.ts} +0 -0
  324. /package/build/implementations/http/{express-rpc → hono}/types.js +0 -0
  325. /package/build/{implementations/http/hono-api/types.js → types.js} +0 -0
@@ -29,15 +29,17 @@ function Procedures<TContext = unknown, TExtendedConfig = unknown>(
29
29
 
30
30
  ### Parameters
31
31
 
32
- - `builder.config.noRuntimeValidation` — When `true`, every procedure registered through this factory skips AJV validation of `schema.params` and `schema.input` at call time (applies to both `Create` and `CreateStream`). JSON Schema is still computed at registration time, so `info.schema` and codegen are unaffected. Shape is `noRuntimeValidation?: true` — only `true` is accepted, making the opt-out explicit. Use only for trusted internal factories whose callers are already type-checked at build time; do **not** enable for procedures that accept input from public clients or untyped JSON bodies.
32
+ - `builder.config.noRuntimeValidation` — When `true`, every procedure registered through this factory skips AJV validation at call time. Applies to all four creators: `Create` and `CreateStream` skip `schema.params` validation; `CreateHttp` and `CreateHttpStream` skip per-channel `schema.req.{pathParams,query,body,headers}` validation. JSON Schema is still computed at registration time, so `info.schema` and codegen are unaffected. Shape is `noRuntimeValidation?: true` — only `true` is accepted, making the opt-out explicit. Use only for trusted internal factories whose callers are already type-checked at build time; do **not** enable for procedures that accept input from public clients or untyped JSON bodies.
33
33
  - `builder.onCreate` — Called each time a procedure is registered. Use for framework integration, route registration, or logging.
34
34
 
35
35
  ### Return Value
36
36
 
37
37
  | Method | Description |
38
38
  |--------|-------------|
39
- | `Create(name, config, handler)` | Register a standard async procedure |
40
- | `CreateStream(name, config, handler)` | Register a streaming async generator procedure |
39
+ | `Create(name, config, handler)` | Register a standard async RPC procedure |
40
+ | `CreateStream(name, config, handler)` | Register a streaming async generator RPC procedure |
41
+ | `CreateHttp(name, config, handler)` | Register a unary HTTP procedure (`path`, `method`, `schema.req`, `schema.res`) |
42
+ | `CreateHttpStream(name, config, handler)` | Register a streaming HTTP procedure |
41
43
  | `getProcedures()` | Returns array of all registered procedure metadata |
42
44
  | `getProcedure(name)` | Returns single procedure by name, or `undefined` |
43
45
  | `removeProcedure(name)` | Removes procedure, returns `true` if found |
@@ -94,7 +96,7 @@ function Create<TName extends string, TParams, TReturnType>(
94
96
  |----------|------|-------------|
95
97
  | `...TContext` | varies | All base context fields |
96
98
  | `error(message, meta?)` | `Function` | Creates `ProcedureError` — throw this for business logic errors |
97
- | `signal?` | `AbortSignal` | Present when HTTP implementation injects it (Express/Hono do this automatically) |
99
+ | `signal?` | `AbortSignal` | Present when HTTP implementation injects it (`HonoAppBuilder` does this automatically) |
98
100
 
99
101
 
100
102
  ### Return Value
@@ -103,31 +105,6 @@ function Create<TName extends string, TParams, TReturnType>(
103
105
  - `{ procedure: handler }` — Same handler under a fixed key
104
106
  - `{ info: metadata }` — Registration metadata with computed JSON schemas and validation functions
105
107
 
106
- ### schema.input (Structured Multi-Channel Input)
107
-
108
- `schema.input` is an alternative to `schema.params` for multi-channel input. Mutually exclusive with `schema.params`.
109
-
110
- ```typescript
111
- Create('UpdateUser', {
112
- path: '/users/:id',
113
- method: 'put',
114
- schema: {
115
- input: {
116
- pathParams: Type.Object({ id: Type.String() }),
117
- body: Type.Object({ name: Type.String() }),
118
- },
119
- returnType: Type.Object({ ok: Type.Boolean() }),
120
- },
121
- }, async (ctx, { pathParams, body }) => {
122
- // Each channel independently typed via TInput generic
123
- return { ok: true }
124
- })
125
- ```
126
-
127
- - Each key in `input` is independently validated with per-channel error messages
128
- - `ProcedureRegistrationError` thrown at registration if both `params` and `input` defined
129
- - `TInput` generic inferred from `schema.input` — handler params type computed as `{ [K in keyof TInput]: TSchemaLib<TInput[K]> }`
130
-
131
108
  ### Throws
132
109
 
133
110
  - `ProcedureRegistrationError` — If schema extraction/compilation fails, or duplicate name
@@ -199,6 +176,85 @@ When `validateYields: true`:
199
176
 
200
177
  ---
201
178
 
179
+ ## CreateHttp\<TName, TReq, TRes, TErrorKey\>(name, config, handler)
180
+
181
+ Registers a unary HTTP procedure (v8+). First-class surface for REST-style routes with per-channel input (`schema.req`) and structured response (`schema.res`).
182
+
183
+ ```typescript
184
+ function CreateHttp<
185
+ TName extends string,
186
+ TReq extends { pathParams?: unknown; query?: unknown; body?: unknown; headers?: unknown } = {},
187
+ TRes extends { body?: unknown; headers?: unknown } = {},
188
+ TErrorKey extends string = string
189
+ >(
190
+ name: TName,
191
+ config: {
192
+ path: string
193
+ method: HttpMethod
194
+ successStatus?: number
195
+ scope?: string
196
+ errors?: TErrorKey[]
197
+ description?: string
198
+ schema: {
199
+ req?: TReq
200
+ res?: TRes
201
+ }
202
+ },
203
+ handler: (
204
+ ctx: TContext & TLocalContext,
205
+ req: { [K in keyof TReq]: TSchemaLib<TReq[K]> }
206
+ ) => Promise<HttpReturn<TRes>>
207
+ ): {
208
+ [K in TName]: typeof handler
209
+ procedure: typeof handler
210
+ info: THttpProcedureRegistration
211
+ }
212
+ ```
213
+
214
+ ### Parameters
215
+
216
+ - `config.path` — Route path. Supports Hono-style path params (`:id`).
217
+ - `config.method` — HTTP method.
218
+ - `config.schema.req` — Per-channel input schemas. Channels: `pathParams`, `query`, `body`, `headers`. Each channel independently validated.
219
+ - `config.schema.res.body` — Response body schema (documentation; not runtime-validated).
220
+ - `config.schema.res.headers` — When declared, handler **must** return `{ body, headers }` instead of the body bare. The builder reads `headers` and forwards them to the HTTP response.
221
+ - `config.errors` — Taxonomy keys this route may emit (populates DocEnvelope for codegen).
222
+
223
+ ### Return Shape
224
+
225
+ - **No `schema.res.headers`:** handler returns body bare (`T`).
226
+ - **`schema.res.headers` declared:** handler returns `{ body: B, headers: H }`.
227
+
228
+ ### Throws
229
+
230
+ - `ProcedureRegistrationError` — Path param names don't match `schema.req.pathParams`; or `schema.params` provided on a `CreateHttp` call (wrong creator).
231
+ - `ProcedureValidationError` — At call time if any req channel fails validation.
232
+ - `ProcedureError` — At call time if handler throws.
233
+
234
+ ### Example
235
+
236
+ ```typescript
237
+ const API = Procedures<AppContext>()
238
+
239
+ API.CreateHttp('GetUser', {
240
+ path: '/users/:id',
241
+ method: 'get',
242
+ schema: {
243
+ req: {
244
+ pathParams: Type.Object({ id: Type.String() }),
245
+ query: Type.Object({ include: Type.Optional(Type.String()) }),
246
+ },
247
+ res: {
248
+ body: Type.Object({ id: Type.String(), name: Type.String() }),
249
+ },
250
+ },
251
+ }, async (ctx, { pathParams, query }) => {
252
+ return await fetchUser(pathParams.id, { include: query.include })
253
+ })
254
+ ```
255
+
256
+ ---
257
+
202
258
  ## Error Classes
203
259
 
204
260
  ### ProcedureError
@@ -250,7 +306,7 @@ class ProcedureYieldValidationError extends ProcedureError {
250
306
 
251
307
  ### ProcedureRegistrationError extends ProcedureError
252
308
 
253
- Thrown at registration time (schema extraction/compilation failure, duplicate name, or `schema.params` and `schema.input` both defined).
309
+ Thrown at registration time. Common v8 sources: schema extraction/compilation failure, duplicate procedure name, using the removed v7 `schema.input` field (rejected with a migration message pointing to `CreateHttp` / `CreateHttpStream`), declaring both `schema.params` and `schema.req` on the same procedure (mutually exclusive — RPC vs HTTP), passing `schema.params` to `CreateHttp` / `CreateHttpStream` (use `schema.req.body` or `schema.req.query` instead), and path/schema mismatches on HTTP procedures (path declares params not in `schema.req.pathParams`, or vice versa).
254
310
 
255
311
  ```typescript
256
312
  class ProcedureRegistrationError extends ProcedureError {
@@ -262,7 +318,7 @@ class ProcedureRegistrationError extends ProcedureError {
262
318
 
263
319
  ## Error Taxonomy API
264
320
 
265
- Exported from `ts-procedures/http-errors` (and re-exported from every HTTP builder subpath: `ts-procedures/hono-api`, `ts-procedures/hono-rpc`, `ts-procedures/express-rpc`, `ts-procedures/hono-stream`).
321
+ Exported from `ts-procedures/http-errors` (and re-exported from `ts-procedures/hono`).
266
322
 
267
323
  ### defineErrorTaxonomy(entries)
268
324
 
@@ -634,136 +690,90 @@ Maps schema type to inferred TypeScript type:
634
690
 
635
691
  ---
636
692
 
637
- ## ExpressRPCAppBuilder
638
-
639
- HTTP implementation for Express.
640
-
641
- ```typescript
642
- class ExpressRPCAppBuilder {
643
- constructor(config?: {
644
- app?: express.Express
645
- pathPrefix?: string
646
- onRequestStart?: (req: express.Request) => void
647
- onRequestEnd?: (req: express.Request, res: express.Response) => void
648
- onSuccess?: (procedure: TProcedureRegistration, req: express.Request, res: express.Response) => void
649
- // Error handling — two peer modes plus a cross-cutting observer.
650
- errors?: ErrorTaxonomy
651
- unknownError?: UnknownErrorConfig
652
- onError?: (procedure: TProcedureRegistration, req: express.Request, res: express.Response, error: Error) => void
653
- onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
654
- })
655
-
656
- register<TFactory>(
657
- factory: TFactory,
658
- factoryContext: Context | ((req: Request) => Context | Promise<Context>),
659
- extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
660
- ): this
661
-
662
- build(): express.Application
693
+ ## HonoAppBuilder\<TStreamErrorData\>
663
694
 
664
- static makeRPCHttpRoutePath(params: { name: string; config: RPCConfig; prefix?: string }): string
695
+ Unified Hono HTTP implementation for v8. A single builder dispatches all four procedure kinds (`Create` RPC, `CreateStream` streaming RPC, `CreateHttp` → REST-style, `CreateHttpStream` → streaming REST) from one `register()` call. Replaces v7's separate `HonoRPCAppBuilder` / `HonoStreamAppBuilder` / `HonoAPIAppBuilder` classes.
665
696
 
666
- get app(): express.Express
667
- get docs(): RPCHttpRouteDoc[]
668
- }
669
- ```
670
-
671
- `OnRequestErrorContext` for Express: `{ err: unknown; procedure: TProcedureRegistration; raw: { req, res } }`.
672
-
673
- ### Route Path
674
-
675
- `POST {pathPrefix}/{scope}/{kebab-name}/{version}`
676
-
677
- - `scope` can be string or string array (joined as path segments)
678
- - Procedure name is converted to kebab-case
679
-
680
- ### Context Resolution
681
-
682
- - Static object: `builder.register(factory, { userId: 'system' })`
683
- - Sync function: `builder.register(factory, (req) => ({ auth: req.headers.authorization }))`
684
- - Async function: `builder.register(factory, async (req) => ({ user: await getUser(req) }))`
685
-
686
- ### Signal Injection
687
-
688
- Express builder creates a lazy AbortController and aborts on request close. The `signal` is injected into handler context automatically.
689
-
690
- ---
691
-
692
- ## HonoRPCAppBuilder
693
-
694
- HTTP implementation for Hono. Same API as ExpressRPCAppBuilder but receives Hono `Context` instead of Express `Request`.
697
+ Config is **stratified**: cross-cutting fields live at the top level, kind-specific fields live in `rpc:` / `api:` / `stream:` blocks.
695
698
 
696
699
  ```typescript
697
- class HonoRPCAppBuilder {
700
+ class HonoAppBuilder<TStreamErrorData = unknown> {
698
701
  constructor(config?: {
702
+ // Cross-cutting (apply to every kind)
699
703
  app?: Hono
700
704
  pathPrefix?: string
701
- onRequestStart?: (c: Context) => void
702
- onRequestEnd?: (c: Context) => void
703
- onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
705
+
704
706
  // Error handling — two peer modes plus a cross-cutting observer.
705
707
  errors?: ErrorTaxonomy
706
708
  unknownError?: UnknownErrorConfig
707
- onError?: (procedure: TProcedureRegistration, c: Context, error: Error) => Response | Promise<Response>
709
+ onError?: PreStreamOnError // imperative pre-stream / unary handler
708
710
  onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
709
- })
710
-
711
- register<TFactory>(
712
- factory: TFactory,
713
- factoryContext: Context | ((c: HonoContext) => Context | Promise<Context>),
714
- extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
715
- ): this
716
-
717
- build(): Hono
718
- get app(): Hono
719
- get docs(): RPCHttpRouteDoc[]
720
- }
721
- ```
722
711
 
723
- `OnRequestErrorContext` for Hono RPC: `{ err: unknown; procedure: TProcedureRegistration; raw: Context }`.
724
-
725
- ### Signal Injection
726
-
727
- Uses `c.req.raw.signal` — the native Request signal from the Hono context.
728
-
729
- ---
712
+ // Lifecycle (every kind)
713
+ onRequestStart?: (c: Context) => void
714
+ onRequestEnd?: (c: Context) => void
730
715
 
731
- ## HonoStreamAppBuilder\<TErrorData\>
716
+ // RPC-specific (Create procedures)
717
+ rpc?: {
718
+ onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
719
+ }
732
720
 
733
- Streaming HTTP implementation for Hono. Supports SSE and text streaming modes.
721
+ // HTTP-specific (CreateHttp procedures)
722
+ api?: {
723
+ queryParser?: (queryString: string) => Record<string, unknown>
724
+ onSuccess?: (procedure: THttpProcedureRegistration, c: Context) => void
725
+ }
734
726
 
735
- ```typescript
736
- class HonoStreamAppBuilder<TErrorData = unknown> {
737
- constructor(config?: {
738
- app?: Hono
739
- pathPrefix?: string
740
- defaultStreamMode?: StreamMode // 'sse' | 'text', default 'sse'
741
- onRequestStart?: (c: Context) => void
742
- onRequestEnd?: (c: Context) => void
743
- onStreamStart?: (procedure: TStreamProcedureRegistration, c: Context, streamMode: StreamMode) => void
744
- onStreamEnd?: (procedure: TStreamProcedureRegistration, c: Context, streamMode: StreamMode) => void
745
- errors?: ErrorTaxonomy
746
- unknownError?: UnknownErrorConfig
747
- onError?: (procedure: TStreamProcedureRegistration, c: Context, error: Error) => Response | Promise<Response> // renamed from onPreStreamError in v6
748
- onRequestError?: (ctx: { err: unknown; procedure: TStreamProcedureRegistration; raw: Context }) => void | Promise<void>
749
- onMidStreamError?: (procedure: TStreamProcedureRegistration, c: Context, error: Error) => MidStreamErrorResult<TErrorData> | undefined
727
+ // Stream-specific (CreateStream + CreateHttpStream procedures)
728
+ stream?: {
729
+ defaultStreamMode?: StreamMode // 'sse' | 'text', default 'sse'
730
+ onStreamStart?: (
731
+ procedure: TStreamProcedureRegistration | THttpStreamProcedureRegistration,
732
+ c: Context,
733
+ streamMode: StreamMode,
734
+ ) => void
735
+ onStreamEnd?: (
736
+ procedure: TStreamProcedureRegistration | THttpStreamProcedureRegistration,
737
+ c: Context,
738
+ streamMode: StreamMode,
739
+ ) => void
740
+ onMidStreamError?: (
741
+ procedure: TStreamProcedureRegistration | THttpStreamProcedureRegistration,
742
+ c: Context,
743
+ error: Error,
744
+ ) => MidStreamErrorResult<TStreamErrorData> | undefined
745
+ }
750
746
  })
751
747
 
752
748
  register<TFactory>(
753
749
  factory: TFactory,
754
750
  factoryContext: Context | ((c: HonoContext) => Context | Promise<Context>),
755
751
  options?: {
756
- streamMode?: StreamMode
752
+ streamMode?: StreamMode // per-registration override of stream.defaultStreamMode
757
753
  extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
758
754
  }
759
755
  ): this
760
756
 
761
757
  build(): Hono
758
+ toDocEnvelope(config?: DocRegistryConfig): DocEnvelope // single-app convenience
759
+
762
760
  get app(): Hono
763
- get docs(): StreamHttpRouteDoc[]
761
+ get docs(): AnyHttpRouteDoc[] // mixed RPC / HTTP / Stream route docs
764
762
  }
765
763
  ```
766
764
 
765
+ `OnRequestErrorContext`: `{ err: unknown; procedure: AnyProcedureRegistration; raw: Context }`.
766
+
767
+ ### Top-level keys (the only keys allowed at the root of the config)
768
+
769
+ `app`, `pathPrefix`, `errors`, `unknownError`, `onError`, `onRequestError`, `onRequestStart`, `onRequestEnd`, `rpc`, `api`, `stream`. Anything else is a typo or v7 vestige — `queryParser`, `onSuccess`, `defaultStreamMode`, `onStreamStart`, `onStreamEnd`, `onMidStreamError` belong inside their kind block, not at the root.
770
+
771
+ ### Error Handling
772
+
773
+ - **RPC + HTTP (unary):** `errors` taxonomy or `onError` callback. Observe via `onRequestError`.
774
+ - **Pre-stream errors** (validation, context resolution failures before the first yield): Returns a JSON error response — no streaming started. Same dispatch as unary: `errors` taxonomy or `onError` callback. Observe via `onRequestError`.
775
+ - **Mid-stream errors** (generator throws after the first yield): Yields error as final event, closes stream. Configure via `stream.onMidStreamError` (the only mid-stream path — the HTTP status is already committed).
776
+
767
777
  ### Stream Modes
768
778
 
769
779
  **SSE mode** (`'sse'`):
@@ -787,12 +797,14 @@ function sse<T extends object>(data: T, options?: {
787
797
  }): T
788
798
  ```
789
799
 
790
- ### HTTP Methods
800
+ ### HTTP Methods (RPC streams)
791
801
 
792
- Both GET and POST are registered for each streaming procedure:
802
+ For `CreateStream` procedures (RPC-style streams), both GET and POST are registered:
793
803
  - **GET**: params extracted from query string
794
804
  - **POST**: params extracted from JSON body
795
805
 
806
+ For `CreateHttpStream`, the method comes from `config.method` (no auto-pairing).
807
+
796
808
  ### MidStreamErrorResult
797
809
 
798
810
  ```typescript
@@ -802,63 +814,22 @@ type MidStreamErrorResult<TErrorData = unknown> = {
802
814
  }
803
815
  ```
804
816
 
805
- ### Error Handling
806
-
807
- - **Pre-stream errors** (validation, context): Returns a JSON error response (no streaming started). Handle via either peer mode — `errors` taxonomy or `onError` callback. Observe via `onRequestError`.
808
- - **Mid-stream errors** (generator throws): Yields error as final event, closes stream. Handle via `onMidStreamError` (the only mid-stream path — the HTTP status is already committed).
809
-
810
- ---
817
+ ### Route Paths
811
818
 
812
- ## HonoAPIAppBuilder
819
+ - **RPC (`Create`):** `POST {pathPrefix}/{scope}/{kebab-name}/{version}` (auto-generated).
820
+ - **RPC stream (`CreateStream`):** `GET|POST {pathPrefix}/{scope}/{kebab-name}/{version}`.
821
+ - **HTTP (`CreateHttp` / `CreateHttpStream`):** developer-defined via `config.path` — no auto-generation. Supports Hono path params (`:id`). Final path is `{pathPrefix}{path}` — e.g., `/api/users/:id`.
813
822
 
814
- REST-style HTTP implementation for Hono. Routes by HTTP method with `schema.input` per-channel validation.
815
-
816
- ```typescript
817
- class HonoAPIAppBuilder {
818
- constructor(config?: {
819
- app?: Hono
820
- pathPrefix?: string
821
- queryParser?: (queryString: string) => Record<string, unknown>
822
- onRequestStart?: (c: Context) => void
823
- onRequestEnd?: (c: Context) => void
824
- onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
825
- // Error handling — two peer modes plus a cross-cutting observer.
826
- errors?: ErrorTaxonomy
827
- unknownError?: UnknownErrorConfig
828
- onError?: (procedure: TProcedureRegistration, c: Context, error: Error) => Response | Promise<Response>
829
- onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
830
- })
831
-
832
- register<TFactory>(
833
- factory: TFactory,
834
- factoryContext: Context | ((c: HonoContext) => Context | Promise<Context>),
835
- extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
836
- ): this
837
-
838
- build(): Hono
839
- get app(): Hono
840
- get docs(): APIHttpRouteDoc[]
841
- }
842
- ```
843
-
844
- `OnRequestErrorContext` for Hono API: `{ err: unknown; procedure: TProcedureRegistration; raw: Context }`.
845
-
846
- ### Route Path
847
-
848
- Developer-defined via `APIConfig.path` — no auto-generation. Supports Hono path params (`:id`).
849
-
850
- `{pathPrefix}{path}` — e.g., `/api/users/:id`
851
-
852
- ### Input Channel Extraction
823
+ ### Input Channel Extraction (`schema.req` `CreateHttp` only)
853
824
 
854
825
  | Channel | HTTP Source | Used For |
855
826
  |---------|-----------|----------|
856
827
  | `pathParams` | URL path parameters (`c.req.param()`) | `/users/:id` → `{ id: '...' }` |
857
- | `query` | Query string (parsed via config `queryParser` or native `URLSearchParams`) | `?page=2` → `{ page: 2 }` |
828
+ | `query` | Query string (parsed via `api.queryParser` or native `URLSearchParams`) | `?page=2` → `{ page: 2 }` |
858
829
  | `body` | JSON request body (POST/PUT/PATCH only) | `{ name: 'John' }` |
859
830
  | `headers` | Request headers (AJV strips non-declared) | `{ 'x-api-key': '...' }` |
860
831
 
861
- ### Default Success Status
832
+ ### Default Success Status (`CreateHttp`)
862
833
 
863
834
  | Method | Default Status |
864
835
  |--------|---------------|
@@ -866,14 +837,14 @@ Developer-defined via `APIConfig.path` — no auto-generation. Supports Hono pat
866
837
  | DELETE | 204 (no body) |
867
838
  | Others | 200 |
868
839
 
869
- Override with `APIConfig.successStatus`.
840
+ Override with `config.successStatus` on the `CreateHttp` config.
870
841
 
871
- ### Build-Time Validation
842
+ ### Build-Time Validation (`CreateHttp`)
872
843
 
873
- - Path param names in path template must match `schema.input.pathParams` property names
874
- - `schema.input.pathParams` defined but path has no `:param` segments → error
875
- - Path has `:param` but `schema.input.pathParams` missing → error
876
- - Property name mismatch → error with clear message
844
+ - Path param names in path template must match `schema.req.pathParams` property names
845
+ - `schema.req.pathParams` defined but path has no `:param` segments → error
846
+ - Path has `:param` but `schema.req.pathParams` missing → error
847
+ - Property name mismatch → `ProcedureRegistrationError` at registration time
877
848
 
878
849
  ### Query Parsing
879
850
 
@@ -891,13 +862,15 @@ It does **not** interpret bracket/dot syntax — those stay as part of the liter
891
862
  | `?user.name=John` | `{ 'user.name': 'John' }` | `{ user: { name: 'John' } }` |
892
863
  | `?tags=a,b,c` | `{ tags: 'a,b,c' }` | `{ tags: ['a', 'b', 'c'] }` |
893
864
 
894
- For nested/bracket/dot/CSV parsing, install `qs` and opt in via `queryParser`:
865
+ For nested/bracket/dot/CSV parsing, install `qs` and opt in via `api.queryParser`:
895
866
 
896
867
  ```typescript
897
868
  import qs from 'qs'
898
869
 
899
- new HonoAPIAppBuilder({
900
- queryParser: (raw) => qs.parse(raw) as Record<string, unknown>,
870
+ new HonoAppBuilder({
871
+ api: {
872
+ queryParser: (raw) => qs.parse(raw) as Record<string, unknown>,
873
+ },
901
874
  })
902
875
  ```
903
876
 
@@ -905,6 +878,10 @@ new HonoAPIAppBuilder({
905
878
 
906
879
  Uses `c.req.raw.signal` — native Request signal from Hono context.
907
880
 
881
+ ### Single-App Doc Envelope
882
+
883
+ For apps that build all routes through one `HonoAppBuilder`, `builder.toDocEnvelope()` returns the full `DocEnvelope` directly — no `DocRegistry` wiring needed. `DocRegistry` is still preferred for multi-app aggregation.
884
+
908
885
  ---
909
886
 
910
887
  ## HTTP Types
@@ -953,48 +930,53 @@ interface StreamHttpRouteDoc extends RPCConfig {
953
930
  }
954
931
  ```
955
932
 
956
- ### APIConfig
933
+ ### TCreateHttpConfig (v8)
934
+
935
+ Config type for `CreateHttp`. HTTP fields are first-class — no `APIConfig` type parameter needed on the factory.
957
936
 
958
937
  ```typescript
959
- // Generic over valid taxonomy keys same pattern as RPCConfig.
960
- interface APIConfig<TErrorKey extends string = string> {
938
+ type TCreateHttpConfig<TReq, TRes, TErrorKey extends string = string> = {
961
939
  path: string
962
- method: 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head'
940
+ method: HttpMethod
963
941
  successStatus?: number
964
942
  scope?: string
965
943
  errors?: TErrorKey[]
944
+ description?: string
945
+ schema: {
946
+ req?: TReq // per-channel input: { pathParams?, query?, body?, headers? }
947
+ res?: TRes // structured response: { body?, headers? }
948
+ }
966
949
  }
967
950
  ```
968
951
 
969
- ### APIHttpRouteDoc
952
+ ### APIHttpRouteDoc (v8)
970
953
 
971
954
  ```typescript
972
- interface APIHttpRouteDoc extends APIConfig {
955
+ interface APIHttpRouteDoc {
973
956
  name: string
957
+ kind: 'http'
958
+ path: string
974
959
  fullPath: string
975
- jsonSchema: {
976
- pathParams?: Record<string, unknown>
977
- query?: Record<string, unknown>
978
- body?: Record<string, unknown>
979
- headers?: Record<string, unknown>
980
- response?: Record<string, unknown>
981
- }
960
+ method: HttpMethod
961
+ successStatus?: number
962
+ scope?: string
982
963
  errors?: string[]
964
+ jsonSchema?: {
965
+ req?: {
966
+ pathParams?: Record<string, unknown>
967
+ query?: Record<string, unknown>
968
+ body?: Record<string, unknown>
969
+ headers?: Record<string, unknown>
970
+ }
971
+ res?: {
972
+ body?: Record<string, unknown>
973
+ headers?: Record<string, unknown>
974
+ }
975
+ }
983
976
  }
984
977
  ```
985
978
 
986
- ### APIInput
987
-
988
- Channel constraint helper type. Use with `satisfies` for compile-time validation of channel names.
989
-
990
- ```typescript
991
- type APIInput<T extends {
992
- pathParams?: unknown
993
- query?: unknown
994
- body?: unknown
995
- headers?: unknown
996
- }> = T
997
- ```
979
+ > **v7 → v8 migration:** `APIConfig` and `APIInput` are removed. Replace `Procedures<Ctx, APIConfig>()` with `Procedures<Ctx>()` and replace `.Create(` with `.CreateHttp(`. Replace `schema.input` with `schema.req`.
998
980
 
999
981
  ### HttpMethod
1000
982
 
@@ -1037,7 +1019,7 @@ class DocRegistry {
1037
1019
 
1038
1020
  ### DocSource
1039
1021
 
1040
- Any object with a `readonly docs` array. All four HTTP builders (`HonoRPCAppBuilder`, `HonoAPIAppBuilder`, `HonoStreamAppBuilder`, `ExpressRPCAppBuilder`) satisfy this interface.
1022
+ Any object with a `readonly docs` array. The built-in `HonoAppBuilder` satisfies this interface.
1041
1023
 
1042
1024
  ```typescript
1043
1025
  interface DocSource<T = AnyHttpRouteDoc> {
@@ -1335,7 +1317,7 @@ interface TypedStream<TYield, TReturn> extends AsyncIterable<TYield> {
1335
1317
  ### Type Parameters
1336
1318
 
1337
1319
  - `TYield` — Type of each yielded value (from `schema.yieldType`)
1338
- - `TReturn` — Type of the stream's return value (from `schema.returnType`). Sent as `event: 'return'` SSE message by `HonoStreamAppBuilder`.
1320
+ - `TReturn` — Type of the stream's return value (from `schema.returnType`). Sent as `event: 'return'` SSE message by `HonoAppBuilder`.
1339
1321
 
1340
1322
  ### Key Behavior
1341
1323
 
@@ -1416,7 +1398,7 @@ Inside factory-context closures, read Astro's APIContext via `getAstroContext`:
1416
1398
  ```ts
1417
1399
  import { getAstroContext } from 'ts-procedures/astro'
1418
1400
 
1419
- new HonoAPIAppBuilder()
1401
+ new HonoAppBuilder()
1420
1402
  .register(usersAPI, (c) => {
1421
1403
  const astro = getAstroContext(c)
1422
1404
  return { db, user: astro.locals.user ?? null }
@@ -1428,7 +1410,7 @@ Multi-app: pass an array; first non-404 response wins. All-404 falls back to the
1428
1410
 
1429
1411
  Constraints:
1430
1412
  - Astro 5+ in SSR (or `prerender = false`).
1431
- - Express builders are NOT supported by this adapter Hono builders only.
1413
+ - Hono builders only the adapter accepts `Request`/`Response` apps.
1432
1414
 
1433
1415
  ---
1434
1416
 
@@ -1463,20 +1445,11 @@ import { captureDefinitionInfo, formatDefinitionInfo } from 'ts-procedures'
1463
1445
  import type { DefinitionLocation, DefinitionInfo } from 'ts-procedures'
1464
1446
 
1465
1447
  // HTTP types (types only, no runtime)
1466
- import type { RPCConfig, RPCHttpRouteDoc, StreamHttpRouteDoc, StreamMode, APIConfig, APIHttpRouteDoc, APIInput, HttpMethod } from 'ts-procedures/http'
1467
-
1468
- // Express RPC
1469
- import { ExpressRPCAppBuilder } from 'ts-procedures/express-rpc'
1470
-
1471
- // Hono RPC
1472
- import { HonoRPCAppBuilder } from 'ts-procedures/hono-rpc'
1473
-
1474
- // Hono Streaming
1475
- import { HonoStreamAppBuilder, sse } from 'ts-procedures/hono-stream'
1448
+ import type { RPCConfig, RPCHttpRouteDoc, StreamHttpRouteDoc, StreamMode, HttpMethod } from 'ts-procedures/http'
1449
+ // Note: APIConfig and APIInput are removed in v8. Use CreateHttp with schema.req / schema.res instead.
1476
1450
 
1477
- // Hono API (REST-style)
1478
- import { HonoAPIAppBuilder } from 'ts-procedures/hono-api'
1479
- import type { APIConfig, APIHttpRouteDoc, APIInput, HttpMethod } from 'ts-procedures/hono-api'
1451
+ // Hono single unified builder dispatches RPC, HTTP, and streaming kinds
1452
+ import { HonoAppBuilder, sse } from 'ts-procedures/hono'
1480
1453
 
1481
1454
  // Client
1482
1455
  import {