ts-procedures 8.6.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (627) hide show
  1. package/README.md +166 -101
  2. package/agent_config/claude-code/.claude-plugin/plugin.json +1 -1
  3. package/agent_config/claude-code/agents/ts-procedures-architect.md +11 -10
  4. package/agent_config/claude-code/skills/ts-procedures/SKILL.md +25 -12
  5. package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +10 -12
  6. package/agent_config/claude-code/skills/ts-procedures/api-reference.md +141 -45
  7. package/agent_config/claude-code/skills/ts-procedures/checklist.md +7 -6
  8. package/agent_config/claude-code/skills/ts-procedures/patterns.md +45 -6
  9. package/agent_config/claude-code/skills/ts-procedures/templates/client.md +1 -1
  10. package/agent_config/claude-code/skills/ts-procedures/templates/hono.md +1 -1
  11. package/agent_config/copilot/copilot-instructions.md +50 -33
  12. package/agent_config/cursor/cursorrules +50 -33
  13. package/build/adapters/astro/astro-context.js.map +1 -0
  14. package/build/adapters/astro/create-handler.js.map +1 -0
  15. package/build/adapters/astro/index.js.map +1 -0
  16. package/build/{implementations/http → adapters}/astro/index.test.js +1 -1
  17. package/build/adapters/astro/index.test.js.map +1 -0
  18. package/build/adapters/astro/rewrite-request.js.map +1 -0
  19. package/build/adapters/hono/envelope-parity.test.js +98 -0
  20. package/build/adapters/hono/envelope-parity.test.js.map +1 -0
  21. package/build/{implementations/http → adapters}/hono/handlers/http-stream.d.ts +1 -1
  22. package/build/adapters/hono/handlers/http-stream.js +55 -0
  23. package/build/adapters/hono/handlers/http-stream.js.map +1 -0
  24. package/build/{implementations/http → adapters}/hono/handlers/http-stream.test.js +1 -1
  25. package/build/adapters/hono/handlers/http-stream.test.js.map +1 -0
  26. package/build/{implementations/http → adapters}/hono/handlers/http.d.ts +1 -1
  27. package/build/adapters/hono/handlers/http.js +50 -0
  28. package/build/adapters/hono/handlers/http.js.map +1 -0
  29. package/build/{implementations/http → adapters}/hono/handlers/http.test.js +1 -1
  30. package/build/adapters/hono/handlers/http.test.js.map +1 -0
  31. package/build/{implementations/http → adapters}/hono/handlers/rpc.d.ts +2 -2
  32. package/build/adapters/hono/handlers/rpc.js +23 -0
  33. package/build/adapters/hono/handlers/rpc.js.map +1 -0
  34. package/build/{implementations/http → adapters}/hono/handlers/rpc.test.js +1 -1
  35. package/build/adapters/hono/handlers/rpc.test.js.map +1 -0
  36. package/build/adapters/hono/handlers/stream.d.ts +12 -0
  37. package/build/adapters/hono/handlers/stream.js +89 -0
  38. package/build/adapters/hono/handlers/stream.js.map +1 -0
  39. package/build/{implementations/http → adapters}/hono/handlers/stream.test.js +3 -2
  40. package/build/adapters/hono/handlers/stream.test.js.map +1 -0
  41. package/build/{implementations/http → adapters}/hono/index.d.ts +24 -12
  42. package/build/{implementations/http → adapters}/hono/index.js +19 -8
  43. package/build/adapters/hono/index.js.map +1 -0
  44. package/build/{implementations/http → adapters}/hono/index.test.js +2 -4
  45. package/build/adapters/hono/index.test.js.map +1 -0
  46. package/build/{implementations/http → adapters/hono}/on-request-error.test.js +2 -2
  47. package/build/adapters/hono/on-request-error.test.js.map +1 -0
  48. package/build/adapters/hono/request.d.ts +7 -0
  49. package/build/adapters/hono/request.js +22 -0
  50. package/build/adapters/hono/request.js.map +1 -0
  51. package/build/{implementations/http → adapters/hono}/route-errors.test.js +4 -4
  52. package/build/adapters/hono/route-errors.test.js.map +1 -0
  53. package/build/adapters/hono/types.d.ts +55 -0
  54. package/build/adapters/hono/types.js +19 -0
  55. package/build/adapters/hono/types.js.map +1 -0
  56. package/build/client/freeze.test.js +39 -0
  57. package/build/client/freeze.test.js.map +1 -0
  58. package/build/client/typed-error-dispatch.test.js +2 -2
  59. package/build/client/typed-error-dispatch.test.js.map +1 -1
  60. package/build/codegen/__fixtures__/make-envelope.d.ts +1 -1
  61. package/build/codegen/bin/cli.d.ts +5 -0
  62. package/build/codegen/bin/cli.js +139 -182
  63. package/build/codegen/bin/cli.js.map +1 -1
  64. package/build/codegen/bin/cli.test.js +12 -2
  65. package/build/codegen/bin/cli.test.js.map +1 -1
  66. package/build/codegen/bin/flag-specs.d.ts +9 -0
  67. package/build/codegen/bin/flag-specs.js +33 -31
  68. package/build/codegen/bin/flag-specs.js.map +1 -1
  69. package/build/codegen/bin/flag-specs.test.js +14 -1
  70. package/build/codegen/bin/flag-specs.test.js.map +1 -1
  71. package/build/codegen/collect-models.d.ts +1 -1
  72. package/build/codegen/emit/api-route.d.ts +8 -0
  73. package/build/codegen/emit/api-route.js +156 -0
  74. package/build/codegen/emit/api-route.js.map +1 -0
  75. package/build/codegen/emit/context.d.ts +30 -0
  76. package/build/codegen/emit/context.js +2 -0
  77. package/build/codegen/emit/context.js.map +1 -0
  78. package/build/codegen/emit/declarations.d.ts +24 -0
  79. package/build/codegen/emit/declarations.js +48 -0
  80. package/build/codegen/emit/declarations.js.map +1 -0
  81. package/build/codegen/emit/format-types.d.ts +61 -0
  82. package/build/codegen/emit/format-types.js +188 -0
  83. package/build/codegen/emit/format-types.js.map +1 -0
  84. package/build/codegen/emit/http-stream-route.d.ts +7 -0
  85. package/build/codegen/emit/http-stream-route.js +138 -0
  86. package/build/codegen/emit/http-stream-route.js.map +1 -0
  87. package/build/codegen/emit/route-shared.d.ts +35 -0
  88. package/build/codegen/emit/route-shared.js +88 -0
  89. package/build/codegen/emit/route-shared.js.map +1 -0
  90. package/build/codegen/emit/rpc-route.d.ts +7 -0
  91. package/build/codegen/emit/rpc-route.js +37 -0
  92. package/build/codegen/emit/rpc-route.js.map +1 -0
  93. package/build/codegen/emit/scope-file.d.ts +39 -0
  94. package/build/codegen/emit/scope-file.js +166 -0
  95. package/build/codegen/emit/scope-file.js.map +1 -0
  96. package/build/codegen/emit/stream-route.d.ts +7 -0
  97. package/build/codegen/emit/stream-route.js +62 -0
  98. package/build/codegen/emit/stream-route.js.map +1 -0
  99. package/build/codegen/emit-errors.d.ts +1 -1
  100. package/build/codegen/emit-errors.integration.test.js +1 -1
  101. package/build/codegen/emit-errors.integration.test.js.map +1 -1
  102. package/build/codegen/emit-scope.d.ts +13 -30
  103. package/build/codegen/emit-scope.js +15 -844
  104. package/build/codegen/emit-scope.js.map +1 -1
  105. package/build/codegen/goldens.test.js +69 -0
  106. package/build/codegen/goldens.test.js.map +1 -0
  107. package/build/codegen/group-routes.d.ts +1 -1
  108. package/build/codegen/pipeline.d.ts +1 -1
  109. package/build/codegen/resolve-envelope.d.ts +1 -1
  110. package/build/codegen/targets/_shared/error-schemas.d.ts +1 -1
  111. package/build/codegen/targets/_shared/route-slots.d.ts +1 -1
  112. package/build/codegen/targets/_shared/target-run.d.ts +1 -1
  113. package/build/codegen/targets/kotlin/emit-route-kotlin.d.ts +1 -1
  114. package/build/codegen/targets/swift/emit-route-swift.d.ts +1 -1
  115. package/build/core/create-http-stream.d.ts +50 -0
  116. package/build/core/create-http-stream.js +108 -0
  117. package/build/core/create-http-stream.js.map +1 -0
  118. package/build/{create-http-stream.test.js → core/create-http-stream.test.js} +1 -1
  119. package/build/core/create-http-stream.test.js.map +1 -0
  120. package/build/core/create-http.d.ts +51 -0
  121. package/build/core/create-http.js +65 -0
  122. package/build/core/create-http.js.map +1 -0
  123. package/build/{create-http.test.js → core/create-http.test.js} +13 -4
  124. package/build/core/create-http.test.js.map +1 -0
  125. package/build/core/create-stream.d.ts +26 -0
  126. package/build/core/create-stream.js +80 -0
  127. package/build/core/create-stream.js.map +1 -0
  128. package/build/{create-stream.test.js → core/create-stream.test.js} +23 -28
  129. package/build/core/create-stream.test.js.map +1 -0
  130. package/build/core/create.d.ts +22 -0
  131. package/build/core/create.js +71 -0
  132. package/build/core/create.js.map +1 -0
  133. package/build/{create.test.js → core/create.test.js} +25 -46
  134. package/build/core/create.test.js.map +1 -0
  135. package/build/core/definition-site.d.ts +24 -0
  136. package/build/{stack-utils.js → core/definition-site.js} +20 -20
  137. package/build/core/definition-site.js.map +1 -0
  138. package/build/{stack-utils.test.js → core/definition-site.test.js} +12 -3
  139. package/build/core/definition-site.test.js.map +1 -0
  140. package/build/{errors.d.ts → core/errors.d.ts} +19 -8
  141. package/build/{errors.js → core/errors.js} +21 -26
  142. package/build/core/errors.js.map +1 -0
  143. package/build/core/errors.test.js.map +1 -0
  144. package/build/core/factory-options.test.js +82 -0
  145. package/build/core/factory-options.test.js.map +1 -0
  146. package/build/core/http-route.d.ts +13 -0
  147. package/build/core/http-route.js +54 -0
  148. package/build/core/http-route.js.map +1 -0
  149. package/build/core/internal.d.ts +72 -0
  150. package/build/core/internal.js +128 -0
  151. package/build/core/internal.js.map +1 -0
  152. package/build/{migration.test.js → core/migration.test.js} +17 -1
  153. package/build/core/migration.test.js.map +1 -0
  154. package/build/core/procedures.d.ts +143 -0
  155. package/build/core/procedures.js +64 -0
  156. package/build/core/procedures.js.map +1 -0
  157. package/build/{index.test.js → core/procedures.test.js} +14 -11
  158. package/build/core/procedures.test.js.map +1 -0
  159. package/build/core/types.d.ts +182 -0
  160. package/build/{schema → core}/types.js.map +1 -1
  161. package/build/exports.d.ts +31 -11
  162. package/build/exports.js +23 -8
  163. package/build/exports.js.map +1 -1
  164. package/build/schema/adapter.d.ts +35 -0
  165. package/build/schema/adapter.js +13 -0
  166. package/build/schema/adapter.js.map +1 -0
  167. package/build/schema/adapter.test.js +53 -0
  168. package/build/schema/adapter.test.js.map +1 -0
  169. package/build/schema/compile.d.ts +37 -0
  170. package/build/schema/compile.js +38 -0
  171. package/build/schema/compile.js.map +1 -0
  172. package/build/schema/compile.test.js +78 -0
  173. package/build/schema/compile.test.js.map +1 -0
  174. package/build/schema/compute-schema.d.ts +47 -37
  175. package/build/schema/compute-schema.js +86 -29
  176. package/build/schema/compute-schema.js.map +1 -1
  177. package/build/schema/compute-schema.test.js +158 -40
  178. package/build/schema/compute-schema.test.js.map +1 -1
  179. package/build/schema/json-schema.d.ts +17 -0
  180. package/build/schema/json-schema.js +2 -0
  181. package/build/schema/json-schema.js.map +1 -0
  182. package/build/schema/typebox.d.ts +11 -0
  183. package/build/schema/typebox.js +24 -0
  184. package/build/schema/typebox.js.map +1 -0
  185. package/build/schema/typebox.test.js +34 -0
  186. package/build/schema/typebox.test.js.map +1 -0
  187. package/build/server/context.d.ts +8 -0
  188. package/build/server/context.js +7 -0
  189. package/build/server/context.js.map +1 -0
  190. package/build/server/context.test.js +16 -0
  191. package/build/server/context.test.js.map +1 -0
  192. package/build/{doc-envelope.d.ts → server/doc-envelope.d.ts} +1 -1
  193. package/build/server/doc-envelope.js.map +1 -0
  194. package/build/server/doc-envelope.test.d.ts +1 -0
  195. package/build/server/doc-envelope.test.js.map +1 -0
  196. package/build/{implementations/http → server}/doc-registry.d.ts +7 -2
  197. package/build/{implementations/http → server}/doc-registry.js +9 -5
  198. package/build/server/doc-registry.js.map +1 -0
  199. package/build/server/doc-registry.test.d.ts +1 -0
  200. package/build/{implementations/http → server}/doc-registry.test.js +27 -24
  201. package/build/server/doc-registry.test.js.map +1 -0
  202. package/build/server/docs/docs.test.d.ts +1 -0
  203. package/build/server/docs/docs.test.js +237 -0
  204. package/build/server/docs/docs.test.js.map +1 -0
  205. package/build/{implementations/http/hono → server}/docs/http-doc.d.ts +2 -2
  206. package/build/{implementations/http/hono → server}/docs/http-doc.js +1 -1
  207. package/build/server/docs/http-doc.js.map +1 -0
  208. package/build/{implementations/http/hono → server}/docs/http-stream-doc.d.ts +2 -2
  209. package/build/{implementations/http/hono → server}/docs/http-stream-doc.js +1 -1
  210. package/build/server/docs/http-stream-doc.js.map +1 -0
  211. package/build/{implementations/http/hono → server}/docs/rpc-doc.d.ts +2 -2
  212. package/build/{implementations/http/hono → server}/docs/rpc-doc.js +1 -1
  213. package/build/server/docs/rpc-doc.js.map +1 -0
  214. package/build/{implementations/http/hono → server}/docs/stream-doc.d.ts +2 -2
  215. package/build/{implementations/http/hono → server}/docs/stream-doc.js +1 -1
  216. package/build/server/docs/stream-doc.js.map +1 -0
  217. package/build/server/errors/dispatch.d.ts +96 -0
  218. package/build/{implementations/http/error-dispatch.js → server/errors/dispatch.js} +20 -10
  219. package/build/server/errors/dispatch.js.map +1 -0
  220. package/build/server/errors/dispatch.test.d.ts +1 -0
  221. package/build/server/errors/dispatch.test.js +418 -0
  222. package/build/server/errors/dispatch.test.js.map +1 -0
  223. package/build/{implementations/http/error-taxonomy.d.ts → server/errors/taxonomy.d.ts} +8 -17
  224. package/build/{implementations/http/error-taxonomy.js → server/errors/taxonomy.js} +6 -15
  225. package/build/server/errors/taxonomy.js.map +1 -0
  226. package/build/server/errors/taxonomy.test.d.ts +1 -0
  227. package/build/{implementations/http/error-taxonomy.test.js → server/errors/taxonomy.test.js} +45 -39
  228. package/build/server/errors/taxonomy.test.js.map +1 -0
  229. package/build/server/index.d.ts +29 -0
  230. package/build/server/index.js +27 -0
  231. package/build/server/index.js.map +1 -0
  232. package/build/server/no-framework-imports.test.d.ts +1 -0
  233. package/build/server/no-framework-imports.test.js +40 -0
  234. package/build/server/no-framework-imports.test.js.map +1 -0
  235. package/build/{implementations/http/hono/path.d.ts → server/paths.d.ts} +2 -3
  236. package/build/{implementations/http/hono/path.js → server/paths.js} +1 -1
  237. package/build/server/paths.js.map +1 -0
  238. package/build/server/paths.test.d.ts +1 -0
  239. package/build/server/paths.test.js +111 -0
  240. package/build/server/paths.test.js.map +1 -0
  241. package/build/server/request/params.d.ts +29 -0
  242. package/build/server/request/params.js +43 -0
  243. package/build/server/request/params.js.map +1 -0
  244. package/build/server/request/params.test.d.ts +1 -0
  245. package/build/server/request/params.test.js +91 -0
  246. package/build/server/request/params.test.js.map +1 -0
  247. package/build/server/request/query.d.ts +9 -0
  248. package/build/server/request/query.js +22 -0
  249. package/build/server/request/query.js.map +1 -0
  250. package/build/server/request/query.test.d.ts +1 -0
  251. package/build/server/request/query.test.js +60 -0
  252. package/build/server/request/query.test.js.map +1 -0
  253. package/build/server/sse.d.ts +70 -0
  254. package/build/server/sse.js +94 -0
  255. package/build/server/sse.js.map +1 -0
  256. package/build/server/sse.test.d.ts +1 -0
  257. package/build/server/sse.test.js +98 -0
  258. package/build/server/sse.test.js.map +1 -0
  259. package/build/{implementations → server}/types.d.ts +17 -15
  260. package/build/{implementations → server}/types.js.map +1 -1
  261. package/docs/astro-adapter.md +8 -9
  262. package/docs/client-and-codegen.md +4 -4
  263. package/docs/client-error-handling.md +5 -5
  264. package/docs/codegen-kotlin.md +2 -3
  265. package/docs/codegen-swift.md +1 -2
  266. package/docs/core.md +135 -54
  267. package/docs/http-integrations.md +58 -6
  268. package/docs/migration-v8-to-v9.md +192 -0
  269. package/docs/plans/2026-06-09-v9-rewrite.md +130 -0
  270. package/docs/specs/2026-06-09-v9-rewrite-design.md +221 -0
  271. package/docs/streaming.md +12 -0
  272. package/package.json +23 -47
  273. package/src/{implementations/http → adapters}/astro/index.test.ts +2 -2
  274. package/src/adapters/hono/__fixtures__/parity-envelope.json +389 -0
  275. package/src/adapters/hono/envelope-parity.test.ts +126 -0
  276. package/src/{implementations/http → adapters}/hono/handlers/http-stream.test.ts +1 -1
  277. package/src/adapters/hono/handlers/http-stream.ts +73 -0
  278. package/src/{implementations/http → adapters}/hono/handlers/http.test.ts +1 -1
  279. package/src/adapters/hono/handlers/http.ts +70 -0
  280. package/src/{implementations/http → adapters}/hono/handlers/rpc.test.ts +2 -2
  281. package/src/adapters/hono/handlers/rpc.ts +39 -0
  282. package/src/{implementations/http → adapters}/hono/handlers/stream.test.ts +4 -3
  283. package/src/{implementations/http → adapters}/hono/handlers/stream.ts +19 -92
  284. package/src/{implementations/http → adapters}/hono/index.test.ts +14 -16
  285. package/src/{implementations/http → adapters}/hono/index.ts +35 -30
  286. package/src/{implementations/http → adapters/hono}/on-request-error.test.ts +3 -3
  287. package/src/adapters/hono/request.ts +28 -0
  288. package/src/{implementations/http → adapters/hono}/route-errors.test.ts +5 -5
  289. package/src/{implementations/http → adapters}/hono/types.ts +43 -20
  290. package/src/client/freeze.test.ts +41 -0
  291. package/src/client/typed-error-dispatch.test.ts +3 -3
  292. package/src/codegen/__fixtures__/make-envelope.ts +1 -1
  293. package/src/codegen/__fixtures__/models-envelope.json +310 -0
  294. package/src/codegen/__goldens__/MANIFEST.json +85 -0
  295. package/src/codegen/__goldens__/kotlin-default--models/Billing.kt +112 -0
  296. package/src/codegen/__goldens__/kotlin-default--models/BillingReports.kt +26 -0
  297. package/src/codegen/__goldens__/kotlin-default--models/Orders.kt +88 -0
  298. package/src/codegen/__goldens__/kotlin-default--users/Users.kt +189 -0
  299. package/src/codegen/__goldens__/swift-default--models/Billing.swift +97 -0
  300. package/src/codegen/__goldens__/swift-default--models/BillingReports.swift +20 -0
  301. package/src/codegen/__goldens__/swift-default--models/Orders.swift +81 -0
  302. package/src/codegen/__goldens__/swift-default--users/Users.swift +204 -0
  303. package/src/codegen/__goldens__/ts-default--models/_client.ts +1319 -0
  304. package/src/codegen/__goldens__/ts-default--models/_errors.ts +90 -0
  305. package/src/codegen/__goldens__/ts-default--models/_models.ts +10 -0
  306. package/src/codegen/__goldens__/ts-default--models/_types.ts +502 -0
  307. package/src/codegen/__goldens__/ts-default--models/billing-reports.ts +29 -0
  308. package/src/codegen/__goldens__/ts-default--models/billing.ts +67 -0
  309. package/src/codegen/__goldens__/ts-default--models/index.ts +48 -0
  310. package/src/codegen/__goldens__/ts-default--models/orders.ts +80 -0
  311. package/src/codegen/__goldens__/ts-default--users/_client.ts +1319 -0
  312. package/src/codegen/__goldens__/ts-default--users/_errors.ts +90 -0
  313. package/src/codegen/__goldens__/ts-default--users/_types.ts +502 -0
  314. package/src/codegen/__goldens__/ts-default--users/index.ts +38 -0
  315. package/src/codegen/__goldens__/ts-default--users/users.ts +169 -0
  316. package/src/codegen/__goldens__/ts-external-runtime--models/_errors.ts +90 -0
  317. package/src/codegen/__goldens__/ts-external-runtime--models/_models.ts +10 -0
  318. package/src/codegen/__goldens__/ts-external-runtime--models/billing-reports.ts +29 -0
  319. package/src/codegen/__goldens__/ts-external-runtime--models/billing.ts +67 -0
  320. package/src/codegen/__goldens__/ts-external-runtime--models/index.ts +48 -0
  321. package/src/codegen/__goldens__/ts-external-runtime--models/orders.ts +80 -0
  322. package/src/codegen/__goldens__/ts-external-runtime--users/_errors.ts +90 -0
  323. package/src/codegen/__goldens__/ts-external-runtime--users/index.ts +38 -0
  324. package/src/codegen/__goldens__/ts-external-runtime--users/users.ts +169 -0
  325. package/src/codegen/__goldens__/ts-flat--models/_client.ts +1319 -0
  326. package/src/codegen/__goldens__/ts-flat--models/_errors.ts +87 -0
  327. package/src/codegen/__goldens__/ts-flat--models/_models.ts +10 -0
  328. package/src/codegen/__goldens__/ts-flat--models/_types.ts +502 -0
  329. package/src/codegen/__goldens__/ts-flat--models/billing-reports.ts +28 -0
  330. package/src/codegen/__goldens__/ts-flat--models/billing.ts +51 -0
  331. package/src/codegen/__goldens__/ts-flat--models/index.ts +42 -0
  332. package/src/codegen/__goldens__/ts-flat--models/orders.ts +73 -0
  333. package/src/codegen/__goldens__/ts-flat--users/_client.ts +1319 -0
  334. package/src/codegen/__goldens__/ts-flat--users/_errors.ts +87 -0
  335. package/src/codegen/__goldens__/ts-flat--users/_types.ts +502 -0
  336. package/src/codegen/__goldens__/ts-flat--users/index.ts +34 -0
  337. package/src/codegen/__goldens__/ts-flat--users/users.ts +126 -0
  338. package/src/codegen/__goldens__/ts-no-share-models--models/_client.ts +1319 -0
  339. package/src/codegen/__goldens__/ts-no-share-models--models/_errors.ts +90 -0
  340. package/src/codegen/__goldens__/ts-no-share-models--models/_types.ts +502 -0
  341. package/src/codegen/__goldens__/ts-no-share-models--models/billing-reports.ts +29 -0
  342. package/src/codegen/__goldens__/ts-no-share-models--models/billing.ts +111 -0
  343. package/src/codegen/__goldens__/ts-no-share-models--models/index.ts +48 -0
  344. package/src/codegen/__goldens__/ts-no-share-models--models/orders.ts +112 -0
  345. package/src/codegen/__goldens__/ts-no-share-models--users/_client.ts +1319 -0
  346. package/src/codegen/__goldens__/ts-no-share-models--users/_errors.ts +90 -0
  347. package/src/codegen/__goldens__/ts-no-share-models--users/_types.ts +502 -0
  348. package/src/codegen/__goldens__/ts-no-share-models--users/index.ts +38 -0
  349. package/src/codegen/__goldens__/ts-no-share-models--users/users.ts +169 -0
  350. package/src/codegen/__goldens__/ts-shared-models-module--models/_client.ts +1319 -0
  351. package/src/codegen/__goldens__/ts-shared-models-module--models/_errors.ts +90 -0
  352. package/src/codegen/__goldens__/ts-shared-models-module--models/_models.ts +7 -0
  353. package/src/codegen/__goldens__/ts-shared-models-module--models/_types.ts +502 -0
  354. package/src/codegen/__goldens__/ts-shared-models-module--models/billing-reports.ts +29 -0
  355. package/src/codegen/__goldens__/ts-shared-models-module--models/billing.ts +67 -0
  356. package/src/codegen/__goldens__/ts-shared-models-module--models/index.ts +48 -0
  357. package/src/codegen/__goldens__/ts-shared-models-module--models/orders.ts +80 -0
  358. package/src/codegen/bin/cli.test.ts +13 -2
  359. package/src/codegen/bin/cli.ts +181 -144
  360. package/src/codegen/bin/flag-specs.test.ts +16 -1
  361. package/src/codegen/bin/flag-specs.ts +43 -31
  362. package/src/codegen/bundle-size.test.ts +1 -1
  363. package/src/codegen/collect-models.ts +1 -1
  364. package/src/codegen/e2e.test.ts +1 -1
  365. package/src/codegen/emit/api-route.ts +184 -0
  366. package/src/codegen/emit/context.ts +32 -0
  367. package/src/codegen/emit/declarations.ts +49 -0
  368. package/src/codegen/emit/format-types.ts +232 -0
  369. package/src/codegen/emit/http-stream-route.ts +162 -0
  370. package/src/codegen/emit/route-shared.ts +102 -0
  371. package/src/codegen/emit/rpc-route.ts +49 -0
  372. package/src/codegen/emit/scope-file.ts +226 -0
  373. package/src/codegen/emit/stream-route.ts +81 -0
  374. package/src/codegen/emit-errors.integration.test.ts +2 -2
  375. package/src/codegen/emit-errors.test.ts +1 -1
  376. package/src/codegen/emit-errors.ts +1 -1
  377. package/src/codegen/emit-scope.test.ts +2 -2
  378. package/src/codegen/emit-scope.ts +15 -1048
  379. package/src/codegen/goldens.test.ts +89 -0
  380. package/src/codegen/group-routes.test.ts +1 -1
  381. package/src/codegen/group-routes.ts +1 -1
  382. package/src/codegen/pipeline.test.ts +1 -1
  383. package/src/codegen/pipeline.ts +1 -1
  384. package/src/codegen/resolve-envelope.test.ts +1 -1
  385. package/src/codegen/resolve-envelope.ts +1 -1
  386. package/src/codegen/targets/_shared/error-schemas.test.ts +1 -1
  387. package/src/codegen/targets/_shared/error-schemas.ts +1 -1
  388. package/src/codegen/targets/_shared/route-slots.test.ts +1 -1
  389. package/src/codegen/targets/_shared/route-slots.ts +1 -1
  390. package/src/codegen/targets/_shared/target-run.ts +1 -1
  391. package/src/codegen/targets/kotlin/emit-route-kotlin.test.ts +1 -1
  392. package/src/codegen/targets/kotlin/emit-route-kotlin.ts +1 -1
  393. package/src/codegen/targets/kotlin/emit-scope-kotlin.test.ts +1 -1
  394. package/src/codegen/targets/swift/access-level.test.ts +1 -1
  395. package/src/codegen/targets/swift/emit-route-swift.test.ts +1 -1
  396. package/src/codegen/targets/swift/emit-route-swift.ts +1 -1
  397. package/src/codegen/targets/swift/emit-scope-swift.test.ts +1 -1
  398. package/src/codegen/targets/ts/shared-models.test.ts +1 -1
  399. package/src/{create-http-stream.test.ts → core/create-http-stream.test.ts} +1 -1
  400. package/src/core/create-http-stream.ts +207 -0
  401. package/src/{create-http.test.ts → core/create-http.test.ts} +15 -4
  402. package/src/core/create-http.ts +126 -0
  403. package/src/{create-stream.test.ts → core/create-stream.test.ts} +28 -31
  404. package/src/core/create-stream.ts +142 -0
  405. package/src/{create.test.ts → core/create.test.ts} +25 -57
  406. package/src/core/create.ts +121 -0
  407. package/src/{stack-utils.test.ts → core/definition-site.test.ts} +14 -3
  408. package/src/{stack-utils.ts → core/definition-site.ts} +20 -23
  409. package/src/{errors.test.ts → core/errors.test.ts} +1 -1
  410. package/src/{errors.ts → core/errors.ts} +30 -28
  411. package/src/core/factory-options.test.ts +112 -0
  412. package/src/core/http-route.ts +73 -0
  413. package/src/core/internal.ts +203 -0
  414. package/src/{migration.test.ts → core/migration.test.ts} +23 -1
  415. package/src/{index.test.ts → core/procedures.test.ts} +13 -11
  416. package/src/core/procedures.ts +75 -0
  417. package/src/core/types.ts +195 -0
  418. package/src/exports.ts +60 -11
  419. package/src/schema/adapter.test.ts +58 -0
  420. package/src/schema/adapter.ts +45 -0
  421. package/src/schema/compile.test.ts +95 -0
  422. package/src/schema/compile.ts +64 -0
  423. package/src/schema/compute-schema.test.ts +222 -41
  424. package/src/schema/compute-schema.ts +145 -71
  425. package/src/schema/json-schema.ts +21 -0
  426. package/src/schema/typebox.test.ts +40 -0
  427. package/src/schema/typebox.ts +27 -0
  428. package/src/server/context.test.ts +22 -0
  429. package/src/server/context.ts +18 -0
  430. package/src/{doc-envelope.test.ts → server/doc-envelope.test.ts} +2 -2
  431. package/src/{doc-envelope.ts → server/doc-envelope.ts} +1 -1
  432. package/src/{implementations/http → server}/doc-registry.test.ts +32 -26
  433. package/src/{implementations/http → server}/doc-registry.ts +11 -7
  434. package/src/server/docs/docs.test.ts +287 -0
  435. package/src/{implementations/http/hono → server}/docs/http-doc.ts +3 -3
  436. package/src/{implementations/http/hono → server}/docs/http-stream-doc.ts +3 -3
  437. package/src/{implementations/http/hono → server}/docs/rpc-doc.ts +3 -3
  438. package/src/{implementations/http/hono → server}/docs/stream-doc.ts +3 -3
  439. package/src/server/errors/dispatch.test.ts +450 -0
  440. package/src/server/errors/dispatch.ts +189 -0
  441. package/src/{implementations/http/error-taxonomy.test.ts → server/errors/taxonomy.test.ts} +45 -39
  442. package/src/{implementations/http/error-taxonomy.ts → server/errors/taxonomy.ts} +8 -17
  443. package/src/server/index.ts +29 -0
  444. package/src/server/no-framework-imports.test.ts +43 -0
  445. package/src/server/paths.test.ts +141 -0
  446. package/src/{implementations/http/hono/path.ts → server/paths.ts} +2 -13
  447. package/src/server/request/params.test.ts +143 -0
  448. package/src/server/request/params.ts +68 -0
  449. package/src/server/request/query.test.ts +70 -0
  450. package/src/server/request/query.ts +24 -0
  451. package/src/server/sse.test.ts +113 -0
  452. package/src/server/sse.ts +117 -0
  453. package/src/{implementations → server}/types.ts +17 -16
  454. package/build/create-http-stream.d.ts +0 -58
  455. package/build/create-http-stream.js +0 -122
  456. package/build/create-http-stream.js.map +0 -1
  457. package/build/create-http-stream.test.js.map +0 -1
  458. package/build/create-http.d.ts +0 -49
  459. package/build/create-http.js +0 -108
  460. package/build/create-http.js.map +0 -1
  461. package/build/create-http.test.js.map +0 -1
  462. package/build/create-stream.d.ts +0 -35
  463. package/build/create-stream.js +0 -123
  464. package/build/create-stream.js.map +0 -1
  465. package/build/create-stream.test.js.map +0 -1
  466. package/build/create.d.ts +0 -28
  467. package/build/create.js +0 -82
  468. package/build/create.js.map +0 -1
  469. package/build/create.test.js.map +0 -1
  470. package/build/doc-envelope.js.map +0 -1
  471. package/build/doc-envelope.test.js.map +0 -1
  472. package/build/errors.js.map +0 -1
  473. package/build/errors.test.js.map +0 -1
  474. package/build/implementations/http/astro/astro-context.js.map +0 -1
  475. package/build/implementations/http/astro/create-handler.js.map +0 -1
  476. package/build/implementations/http/astro/index.js.map +0 -1
  477. package/build/implementations/http/astro/index.test.js.map +0 -1
  478. package/build/implementations/http/astro/rewrite-request.js.map +0 -1
  479. package/build/implementations/http/doc-registry.js.map +0 -1
  480. package/build/implementations/http/doc-registry.test.js.map +0 -1
  481. package/build/implementations/http/error-dispatch.d.ts +0 -76
  482. package/build/implementations/http/error-dispatch.js.map +0 -1
  483. package/build/implementations/http/error-dispatch.test.js +0 -254
  484. package/build/implementations/http/error-dispatch.test.js.map +0 -1
  485. package/build/implementations/http/error-taxonomy.js.map +0 -1
  486. package/build/implementations/http/error-taxonomy.test.js.map +0 -1
  487. package/build/implementations/http/hono/docs/http-doc.js.map +0 -1
  488. package/build/implementations/http/hono/docs/http-stream-doc.js.map +0 -1
  489. package/build/implementations/http/hono/docs/rpc-doc.js.map +0 -1
  490. package/build/implementations/http/hono/docs/stream-doc.js.map +0 -1
  491. package/build/implementations/http/hono/handlers/http-stream.js +0 -123
  492. package/build/implementations/http/hono/handlers/http-stream.js.map +0 -1
  493. package/build/implementations/http/hono/handlers/http-stream.test.js.map +0 -1
  494. package/build/implementations/http/hono/handlers/http.js +0 -110
  495. package/build/implementations/http/hono/handlers/http.js.map +0 -1
  496. package/build/implementations/http/hono/handlers/http.test.js.map +0 -1
  497. package/build/implementations/http/hono/handlers/rpc.js +0 -32
  498. package/build/implementations/http/hono/handlers/rpc.js.map +0 -1
  499. package/build/implementations/http/hono/handlers/rpc.test.js.map +0 -1
  500. package/build/implementations/http/hono/handlers/stream.d.ts +0 -23
  501. package/build/implementations/http/hono/handlers/stream.js +0 -147
  502. package/build/implementations/http/hono/handlers/stream.js.map +0 -1
  503. package/build/implementations/http/hono/handlers/stream.test.js.map +0 -1
  504. package/build/implementations/http/hono/index.js.map +0 -1
  505. package/build/implementations/http/hono/index.test.js.map +0 -1
  506. package/build/implementations/http/hono/path.js.map +0 -1
  507. package/build/implementations/http/hono/path.test.js +0 -83
  508. package/build/implementations/http/hono/path.test.js.map +0 -1
  509. package/build/implementations/http/hono/types.d.ts +0 -51
  510. package/build/implementations/http/hono/types.js.map +0 -1
  511. package/build/implementations/http/on-request-error.test.js.map +0 -1
  512. package/build/implementations/http/route-errors.test.js.map +0 -1
  513. package/build/index.d.ts +0 -175
  514. package/build/index.js +0 -47
  515. package/build/index.js.map +0 -1
  516. package/build/index.test.js.map +0 -1
  517. package/build/migration.test.js.map +0 -1
  518. package/build/schema/extract-json-schema.d.ts +0 -2
  519. package/build/schema/extract-json-schema.js +0 -12
  520. package/build/schema/extract-json-schema.js.map +0 -1
  521. package/build/schema/extract-json-schema.test.js +0 -23
  522. package/build/schema/extract-json-schema.test.js.map +0 -1
  523. package/build/schema/parser.d.ts +0 -36
  524. package/build/schema/parser.js +0 -210
  525. package/build/schema/parser.js.map +0 -1
  526. package/build/schema/parser.test.js +0 -120
  527. package/build/schema/parser.test.js.map +0 -1
  528. package/build/schema/resolve-schema-lib.d.ts +0 -12
  529. package/build/schema/resolve-schema-lib.js +0 -11
  530. package/build/schema/resolve-schema-lib.js.map +0 -1
  531. package/build/schema/resolve-schema-lib.test.js +0 -17
  532. package/build/schema/resolve-schema-lib.test.js.map +0 -1
  533. package/build/schema/types.d.ts +0 -8
  534. package/build/schema/types.js +0 -2
  535. package/build/stack-utils.d.ts +0 -25
  536. package/build/stack-utils.js.map +0 -1
  537. package/build/stack-utils.test.js.map +0 -1
  538. package/build/types.d.ts +0 -142
  539. package/build/types.js +0 -2
  540. package/build/types.js.map +0 -1
  541. package/docs/decisions/2026-06-02-monorepo-split-evaluation.md +0 -80
  542. package/docs/handoffs/2026-06-08-dx-round2-declines.md +0 -45
  543. package/docs/handoffs/ajsc-named-type-collision.md +0 -134
  544. package/docs/handoffs/ajsc-named-type-support.md +0 -181
  545. package/docs/handoffs/shared-models-auto-resolve-response.md +0 -181
  546. package/docs/npm-workspaces-migration-plan.md +0 -611
  547. package/docs/superpowers/plans/2026-04-24-doc-registry-simplification.md +0 -886
  548. package/docs/superpowers/plans/2026-04-24-kotlin-codegen-target.md +0 -1265
  549. package/docs/superpowers/plans/2026-04-25-ajsc-v7-kotlin-polish.md +0 -1993
  550. package/docs/superpowers/plans/2026-04-29-safe-result-api.md +0 -2293
  551. package/docs/superpowers/plans/2026-05-07-astro-adapter.md +0 -1391
  552. package/docs/superpowers/plans/2026-05-08-create-http.md +0 -3355
  553. package/docs/superpowers/plans/2026-05-08-hono-app-builder-convergence.md +0 -3365
  554. package/docs/superpowers/plans/2026-06-05-dx-feedback-round.md +0 -1292
  555. package/docs/superpowers/plans/2026-06-06-shared-models-convention-and-diagnostics.md +0 -659
  556. package/docs/superpowers/plans/2026-06-08-codegen-dx-surfacing.md +0 -428
  557. package/docs/superpowers/specs/2026-04-24-kotlin-swift-codegen-design.md +0 -401
  558. package/docs/superpowers/specs/2026-04-25-ajsc-v7-kotlin-polish-design.md +0 -314
  559. package/docs/superpowers/specs/2026-04-25-swift-codegen-design.md +0 -264
  560. package/docs/superpowers/specs/2026-04-29-safe-result-api-design.md +0 -324
  561. package/docs/superpowers/specs/2026-05-07-astro-adapter-design.md +0 -252
  562. package/docs/superpowers/specs/2026-05-08-create-http-design.md +0 -409
  563. package/docs/superpowers/specs/2026-05-08-hono-app-builder-convergence-design.md +0 -411
  564. package/docs/superpowers/specs/2026-06-05-dx-feedback-round-design.md +0 -285
  565. package/docs/superpowers/specs/2026-06-08-dx-feedback-round-2-design.md +0 -376
  566. package/src/create-http-stream.ts +0 -191
  567. package/src/create-http.ts +0 -210
  568. package/src/create-stream.ts +0 -228
  569. package/src/create.ts +0 -172
  570. package/src/implementations/http/README.md +0 -390
  571. package/src/implementations/http/error-dispatch.test.ts +0 -283
  572. package/src/implementations/http/error-dispatch.ts +0 -176
  573. package/src/implementations/http/hono/handlers/http-stream.ts +0 -152
  574. package/src/implementations/http/hono/handlers/http.ts +0 -145
  575. package/src/implementations/http/hono/handlers/rpc.ts +0 -54
  576. package/src/implementations/http/hono/path.test.ts +0 -96
  577. package/src/index.ts +0 -101
  578. package/src/schema/extract-json-schema.test.ts +0 -25
  579. package/src/schema/extract-json-schema.ts +0 -15
  580. package/src/schema/parser.test.ts +0 -182
  581. package/src/schema/parser.ts +0 -265
  582. package/src/schema/resolve-schema-lib.test.ts +0 -19
  583. package/src/schema/resolve-schema-lib.ts +0 -29
  584. package/src/schema/types.ts +0 -20
  585. package/src/types.ts +0 -133
  586. /package/build/{implementations/http → adapters}/astro/astro-context.d.ts +0 -0
  587. /package/build/{implementations/http → adapters}/astro/astro-context.js +0 -0
  588. /package/build/{implementations/http → adapters}/astro/create-handler.d.ts +0 -0
  589. /package/build/{implementations/http → adapters}/astro/create-handler.js +0 -0
  590. /package/build/{implementations/http → adapters}/astro/index.d.ts +0 -0
  591. /package/build/{implementations/http → adapters}/astro/index.js +0 -0
  592. /package/build/{implementations/http → adapters}/astro/index.test.d.ts +0 -0
  593. /package/build/{implementations/http → adapters}/astro/rewrite-request.d.ts +0 -0
  594. /package/build/{implementations/http → adapters}/astro/rewrite-request.js +0 -0
  595. /package/build/{create-http-stream.test.d.ts → adapters/hono/envelope-parity.test.d.ts} +0 -0
  596. /package/build/{implementations/http → adapters}/hono/handlers/http-stream.test.d.ts +0 -0
  597. /package/build/{implementations/http → adapters}/hono/handlers/http.test.d.ts +0 -0
  598. /package/build/{implementations/http → adapters}/hono/handlers/rpc.test.d.ts +0 -0
  599. /package/build/{implementations/http → adapters}/hono/handlers/stream.test.d.ts +0 -0
  600. /package/build/{implementations/http → adapters}/hono/index.test.d.ts +0 -0
  601. /package/build/{implementations/http → adapters/hono}/on-request-error.test.d.ts +0 -0
  602. /package/build/{implementations/http → adapters/hono}/route-errors.test.d.ts +0 -0
  603. /package/build/{create-http.test.d.ts → client/freeze.test.d.ts} +0 -0
  604. /package/build/{create-stream.test.d.ts → codegen/goldens.test.d.ts} +0 -0
  605. /package/build/{create.test.d.ts → core/create-http-stream.test.d.ts} +0 -0
  606. /package/build/{doc-envelope.test.d.ts → core/create-http.test.d.ts} +0 -0
  607. /package/build/{errors.test.d.ts → core/create-stream.test.d.ts} +0 -0
  608. /package/build/{implementations/http/doc-registry.test.d.ts → core/create.test.d.ts} +0 -0
  609. /package/build/{implementations/http/error-dispatch.test.d.ts → core/definition-site.test.d.ts} +0 -0
  610. /package/build/{implementations/http/error-taxonomy.test.d.ts → core/errors.test.d.ts} +0 -0
  611. /package/build/{errors.test.js → core/errors.test.js} +0 -0
  612. /package/build/{implementations/http/hono/path.test.d.ts → core/factory-options.test.d.ts} +0 -0
  613. /package/build/{migration.test.d.ts → core/migration.test.d.ts} +0 -0
  614. /package/build/{index.test.d.ts → core/procedures.test.d.ts} +0 -0
  615. /package/build/{implementations/http/hono → core}/types.js +0 -0
  616. /package/build/schema/{extract-json-schema.test.d.ts → adapter.test.d.ts} +0 -0
  617. /package/build/schema/{parser.test.d.ts → compile.test.d.ts} +0 -0
  618. /package/build/schema/{resolve-schema-lib.test.d.ts → typebox.test.d.ts} +0 -0
  619. /package/build/{stack-utils.test.d.ts → server/context.test.d.ts} +0 -0
  620. /package/build/{doc-envelope.js → server/doc-envelope.js} +0 -0
  621. /package/build/{doc-envelope.test.js → server/doc-envelope.test.js} +0 -0
  622. /package/build/{implementations → server}/types.js +0 -0
  623. /package/src/{implementations/http → adapters}/astro/README.md +0 -0
  624. /package/src/{implementations/http → adapters}/astro/astro-context.ts +0 -0
  625. /package/src/{implementations/http → adapters}/astro/create-handler.ts +0 -0
  626. /package/src/{implementations/http → adapters}/astro/index.ts +0 -0
  627. /package/src/{implementations/http → adapters}/astro/rewrite-request.ts +0 -0
@@ -0,0 +1,91 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { BODY_METHODS, defaultSuccessStatus, extractReqChannels } from './params.js';
3
+ import { parseQueryNative } from './query.js';
4
+ function makeSource(overrides) {
5
+ return {
6
+ pathParams: () => ({ id: '42' }),
7
+ url: () => 'http://localhost/users/42?limit=10&tag=a&tag=b',
8
+ json: async () => ({ name: 'Ada' }),
9
+ headers: () => ({ 'x-api-key': 'secret' }),
10
+ ...overrides,
11
+ };
12
+ }
13
+ describe('extractReqChannels', () => {
14
+ test('extracts only the declared channels', async () => {
15
+ const params = await extractReqChannels(makeSource(), 'get', { query: {} }, parseQueryNative);
16
+ expect(Object.keys(params)).toEqual(['query']);
17
+ expect(params.query).toEqual({ limit: '10', tag: ['a', 'b'] });
18
+ });
19
+ test('extracts pathParams channel', async () => {
20
+ const params = await extractReqChannels(makeSource(), 'get', { pathParams: {} }, parseQueryNative);
21
+ expect(params).toEqual({ pathParams: { id: '42' } });
22
+ });
23
+ test('extracts headers channel (lowercased keys come from the source)', async () => {
24
+ const params = await extractReqChannels(makeSource(), 'get', { headers: {} }, parseQueryNative);
25
+ expect(params).toEqual({ headers: { 'x-api-key': 'secret' } });
26
+ });
27
+ test('extracts all four channels for a body-carrying method', async () => {
28
+ const params = await extractReqChannels(makeSource(), 'post', { pathParams: {}, query: {}, body: {}, headers: {} }, parseQueryNative);
29
+ expect(params).toEqual({
30
+ pathParams: { id: '42' },
31
+ query: { limit: '10', tag: ['a', 'b'] },
32
+ body: { name: 'Ada' },
33
+ headers: { 'x-api-key': 'secret' },
34
+ });
35
+ });
36
+ test.each(['post', 'put', 'patch'])('parses the body for %s', async (method) => {
37
+ const params = await extractReqChannels(makeSource(), method, { body: {} }, parseQueryNative);
38
+ expect(params.body).toEqual({ name: 'Ada' });
39
+ });
40
+ test.each(['get', 'head', 'delete'])('skips the body for %s (never calls source.json)', async (method) => {
41
+ let jsonCalled = false;
42
+ const source = makeSource({
43
+ json: async () => {
44
+ jsonCalled = true;
45
+ return {};
46
+ },
47
+ });
48
+ const params = await extractReqChannels(source, method, { body: {} }, parseQueryNative);
49
+ expect(jsonCalled).toBe(false);
50
+ expect('body' in params).toBe(false);
51
+ });
52
+ test('JSON parse failure yields {} so validation reports the missing fields', async () => {
53
+ const source = makeSource({
54
+ json: async () => {
55
+ throw new SyntaxError('Unexpected token');
56
+ },
57
+ });
58
+ const params = await extractReqChannels(source, 'post', { body: {} }, parseQueryNative);
59
+ expect(params.body).toEqual({});
60
+ });
61
+ test('unknown channel is set to undefined (key present, no extraction)', async () => {
62
+ const params = await extractReqChannels(makeSource(), 'get', { cookies: {} }, parseQueryNative);
63
+ expect('cookies' in params).toBe(true);
64
+ expect(params.cookies).toBeUndefined();
65
+ });
66
+ test('empty schema extracts nothing', async () => {
67
+ const params = await extractReqChannels(makeSource(), 'post', {}, parseQueryNative);
68
+ expect(params).toEqual({});
69
+ });
70
+ test('custom query parser is used for the query channel', async () => {
71
+ const params = await extractReqChannels(makeSource(), 'get', { query: {} }, (raw) => ({ raw }));
72
+ expect(params.query).toEqual({ raw: 'limit=10&tag=a&tag=b' });
73
+ });
74
+ });
75
+ describe('BODY_METHODS', () => {
76
+ test('contains exactly post, put, patch', () => {
77
+ expect(BODY_METHODS).toEqual(['post', 'put', 'patch']);
78
+ });
79
+ });
80
+ describe('defaultSuccessStatus', () => {
81
+ test('post → 201', () => {
82
+ expect(defaultSuccessStatus('post')).toBe(201);
83
+ });
84
+ test('delete → 204', () => {
85
+ expect(defaultSuccessStatus('delete')).toBe(204);
86
+ });
87
+ test.each(['get', 'put', 'patch', 'head'])('%s → 200', (method) => {
88
+ expect(defaultSuccessStatus(method)).toBe(200);
89
+ });
90
+ });
91
+ //# sourceMappingURL=params.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"params.test.js","sourceRoot":"","sources":["../../../src/server/request/params.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** Parses a raw query string into a params record. */
2
+ export type QueryParser = (queryString: string) => Record<string, unknown>;
3
+ /**
4
+ * Default query parser using URLSearchParams. Multi-value keys become arrays;
5
+ * single-value keys remain scalars (matches browser-native behavior).
6
+ */
7
+ export declare function parseQueryNative(queryString: string): Record<string, unknown>;
8
+ /** Extracts and parses the query string portion of a URL (empty object when none). */
9
+ export declare function extractQuery(url: string, parser: QueryParser): Record<string, unknown>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Default query parser using URLSearchParams. Multi-value keys become arrays;
3
+ * single-value keys remain scalars (matches browser-native behavior).
4
+ */
5
+ export function parseQueryNative(queryString) {
6
+ const sp = new URLSearchParams(queryString);
7
+ const result = {};
8
+ for (const key of new Set(sp.keys())) {
9
+ const values = sp.getAll(key);
10
+ result[key] = values.length > 1 ? values : values[0];
11
+ }
12
+ return result;
13
+ }
14
+ /** Extracts and parses the query string portion of a URL (empty object when none). */
15
+ export function extractQuery(url, parser) {
16
+ const q = url.indexOf('?');
17
+ if (q === -1)
18
+ return {};
19
+ const raw = url.slice(q + 1);
20
+ return raw ? parser(raw) : {};
21
+ }
22
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/server/request/query.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,WAAW,CAAC,CAAA;IAC3C,MAAM,MAAM,GAA4B,EAAE,CAAA;IAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC7B,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,MAAmB;IAC3D,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC1B,IAAI,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,CAAA;IACvB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAC5B,OAAO,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAC/B,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,60 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { extractQuery, parseQueryNative } from './query.js';
3
+ describe('parseQueryNative', () => {
4
+ test('single-value keys remain scalars', () => {
5
+ expect(parseQueryNative('a=1&b=two')).toEqual({ a: '1', b: 'two' });
6
+ });
7
+ test('multi-value keys become arrays', () => {
8
+ expect(parseQueryNative('tag=a&tag=b&tag=c')).toEqual({ tag: ['a', 'b', 'c'] });
9
+ });
10
+ test('mixes scalars and arrays', () => {
11
+ expect(parseQueryNative('limit=10&tag=a&tag=b')).toEqual({ limit: '10', tag: ['a', 'b'] });
12
+ });
13
+ test('empty string parses to an empty object', () => {
14
+ expect(parseQueryNative('')).toEqual({});
15
+ });
16
+ test('decodes URL-encoded values (URLSearchParams semantics)', () => {
17
+ expect(parseQueryNative('q=hello%20world&plus=a+b')).toEqual({
18
+ q: 'hello world',
19
+ plus: 'a b',
20
+ });
21
+ });
22
+ test('key without a value yields an empty string', () => {
23
+ expect(parseQueryNative('flag')).toEqual({ flag: '' });
24
+ });
25
+ });
26
+ describe('extractQuery', () => {
27
+ test('parses the query portion of a URL', () => {
28
+ expect(extractQuery('http://localhost/users?limit=10&tag=a', parseQueryNative)).toEqual({
29
+ limit: '10',
30
+ tag: 'a',
31
+ });
32
+ });
33
+ test('returns {} when the URL has no "?"', () => {
34
+ expect(extractQuery('http://localhost/users', parseQueryNative)).toEqual({});
35
+ });
36
+ test('returns {} for a trailing "?" with an empty query', () => {
37
+ expect(extractQuery('http://localhost/users?', parseQueryNative)).toEqual({});
38
+ });
39
+ test('custom parser receives the raw query string and its result passes through', () => {
40
+ let receivedRaw;
41
+ const custom = (raw) => {
42
+ receivedRaw = raw;
43
+ return { parsed: true };
44
+ };
45
+ const result = extractQuery('http://localhost/p?a=1&b=2', custom);
46
+ expect(receivedRaw).toBe('a=1&b=2');
47
+ expect(result).toEqual({ parsed: true });
48
+ });
49
+ test('custom parser is NOT invoked when there is no query string', () => {
50
+ let called = false;
51
+ const custom = (raw) => {
52
+ called = true;
53
+ return { raw };
54
+ };
55
+ expect(extractQuery('http://localhost/p', custom)).toEqual({});
56
+ expect(extractQuery('http://localhost/p?', custom)).toEqual({});
57
+ expect(called).toBe(false);
58
+ });
59
+ });
60
+ //# sourceMappingURL=query.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.test.js","sourceRoot":"","sources":["../../../src/server/request/query.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * SSE metadata attachment, shared by every server adapter's stream handlers.
3
+ */
4
+ export type SSEOptions = {
5
+ event?: string;
6
+ id?: string;
7
+ retry?: number;
8
+ };
9
+ /**
10
+ * Marks an object yield as an SSE event with custom metadata. Stream handlers
11
+ * read this metadata to set the SSE `event:`, `id:`, and `retry:` fields:
12
+ *
13
+ * ```ts
14
+ * yield sse({ progress: 0.5 }, { event: 'progress', id: 'p-1' })
15
+ * ```
16
+ *
17
+ * The value is returned unchanged — metadata rides in a WeakMap, never on
18
+ * the payload.
19
+ */
20
+ export declare function sse<T extends object>(data: T, options?: SSEOptions): T;
21
+ /** Reads metadata attached via {@link sse}. Undefined for plain values. */
22
+ export declare function getSSEMeta(value: unknown): SSEOptions | undefined;
23
+ /** One wire-ready SSE event, as handed to the adapter's write function. */
24
+ export type SseEvent = {
25
+ data: string;
26
+ event: string;
27
+ id: string;
28
+ retry?: number;
29
+ };
30
+ /** Adapter-provided sink (e.g. Hono's `stream.writeSSE`). */
31
+ export type SseWrite = (event: SseEvent) => void | Promise<void>;
32
+ /** Yield payloads: strings pass through, `null`/`undefined` become empty data. */
33
+ export declare function serializeSseValue(value: unknown): string;
34
+ /**
35
+ * The SSE wire protocol shared by every stream handler: auto-incrementing
36
+ * event ids, `sse()` metadata overrides, the `event: 'return'` envelope for
37
+ * the generator's return value, and the error-event shape after mid-stream
38
+ * dispatch. Adapters supply only the framework write function.
39
+ */
40
+ export declare class SseEventSequencer {
41
+ private readonly write;
42
+ /** Event name for yields without `sse()` metadata — the procedure name. */
43
+ private readonly defaultEvent;
44
+ private eventId;
45
+ constructor(write: SseWrite,
46
+ /** Event name for yields without `sse()` metadata — the procedure name. */
47
+ defaultEvent: string);
48
+ /** Writes one yielded value; `sse()` metadata overrides event/id/retry. */
49
+ writeYield(value: unknown): Promise<void>;
50
+ /**
51
+ * Writes the generator's return value as the `event: 'return'` payload
52
+ * (clients resolve it via `TypedStream.result`). Skipped for `undefined` —
53
+ * a `void` generator produces no return event.
54
+ */
55
+ writeReturn(value: unknown): Promise<void>;
56
+ /**
57
+ * Writes a dispatched mid-stream error. `sse()` metadata on the payload
58
+ * (attachable inside `onMidStreamError`) wins over the dispatcher's event.
59
+ */
60
+ writeError(dispatched: {
61
+ data: unknown;
62
+ sseEvent?: string;
63
+ }): Promise<void>;
64
+ /**
65
+ * Drives a complete stream: every yield, then the return event. Errors from
66
+ * the iterator propagate to the caller, which dispatches them and writes the
67
+ * result via {@link writeError} (the id sequence continues across the two).
68
+ */
69
+ pump(iterator: AsyncIterator<unknown, unknown>): Promise<void>;
70
+ }
@@ -0,0 +1,94 @@
1
+ const sseMetadata = new WeakMap();
2
+ /**
3
+ * Marks an object yield as an SSE event with custom metadata. Stream handlers
4
+ * read this metadata to set the SSE `event:`, `id:`, and `retry:` fields:
5
+ *
6
+ * ```ts
7
+ * yield sse({ progress: 0.5 }, { event: 'progress', id: 'p-1' })
8
+ * ```
9
+ *
10
+ * The value is returned unchanged — metadata rides in a WeakMap, never on
11
+ * the payload.
12
+ */
13
+ export function sse(data, options) {
14
+ sseMetadata.set(data, options ?? {});
15
+ return data;
16
+ }
17
+ /** Reads metadata attached via {@link sse}. Undefined for plain values. */
18
+ export function getSSEMeta(value) {
19
+ if (typeof value === 'object' && value !== null) {
20
+ return sseMetadata.get(value);
21
+ }
22
+ return undefined;
23
+ }
24
+ /** Yield payloads: strings pass through, `null`/`undefined` become empty data. */
25
+ export function serializeSseValue(value) {
26
+ if (typeof value === 'string')
27
+ return value;
28
+ return value != null ? JSON.stringify(value) : '';
29
+ }
30
+ /**
31
+ * The SSE wire protocol shared by every stream handler: auto-incrementing
32
+ * event ids, `sse()` metadata overrides, the `event: 'return'` envelope for
33
+ * the generator's return value, and the error-event shape after mid-stream
34
+ * dispatch. Adapters supply only the framework write function.
35
+ */
36
+ export class SseEventSequencer {
37
+ write;
38
+ defaultEvent;
39
+ eventId = 0;
40
+ constructor(write,
41
+ /** Event name for yields without `sse()` metadata — the procedure name. */
42
+ defaultEvent) {
43
+ this.write = write;
44
+ this.defaultEvent = defaultEvent;
45
+ }
46
+ /** Writes one yielded value; `sse()` metadata overrides event/id/retry. */
47
+ async writeYield(value) {
48
+ const meta = getSSEMeta(value);
49
+ await this.write({
50
+ data: serializeSseValue(value),
51
+ event: meta?.event ?? this.defaultEvent,
52
+ id: meta?.id ?? String(this.eventId++),
53
+ ...(meta?.retry !== undefined && { retry: meta.retry }),
54
+ });
55
+ }
56
+ /**
57
+ * Writes the generator's return value as the `event: 'return'` payload
58
+ * (clients resolve it via `TypedStream.result`). Skipped for `undefined` —
59
+ * a `void` generator produces no return event.
60
+ */
61
+ async writeReturn(value) {
62
+ if (value === undefined)
63
+ return;
64
+ const data = typeof value === 'string' ? value : JSON.stringify(value);
65
+ await this.write({ data, event: 'return', id: String(this.eventId++) });
66
+ }
67
+ /**
68
+ * Writes a dispatched mid-stream error. `sse()` metadata on the payload
69
+ * (attachable inside `onMidStreamError`) wins over the dispatcher's event.
70
+ */
71
+ async writeError(dispatched) {
72
+ const meta = getSSEMeta(dispatched.data);
73
+ await this.write({
74
+ data: serializeSseValue(dispatched.data),
75
+ event: meta?.event ?? dispatched.sseEvent ?? 'error',
76
+ id: meta?.id ?? String(this.eventId++),
77
+ ...(meta?.retry !== undefined && { retry: meta.retry }),
78
+ });
79
+ }
80
+ /**
81
+ * Drives a complete stream: every yield, then the return event. Errors from
82
+ * the iterator propagate to the caller, which dispatches them and writes the
83
+ * result via {@link writeError} (the id sequence continues across the two).
84
+ */
85
+ async pump(iterator) {
86
+ let result = await iterator.next();
87
+ while (!result.done) {
88
+ await this.writeYield(result.value);
89
+ result = await iterator.next();
90
+ }
91
+ await this.writeReturn(result.value);
92
+ }
93
+ }
94
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/server/sse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,98 @@
1
+ import { describe, expect, it, test } from 'vitest';
2
+ import { SseEventSequencer, getSSEMeta, serializeSseValue, sse } from './sse.js';
3
+ describe('sse', () => {
4
+ test('returns the value unchanged (same reference)', () => {
5
+ const payload = { progress: 0.5 };
6
+ const result = sse(payload, { event: 'progress' });
7
+ expect(result).toBe(payload);
8
+ // Metadata rides in a WeakMap — never on the payload itself.
9
+ expect(Object.keys(result)).toEqual(['progress']);
10
+ });
11
+ test('getSSEMeta round-trips the attached options', () => {
12
+ const payload = sse({ progress: 0.5 }, { event: 'progress', id: 'p-1', retry: 3000 });
13
+ expect(getSSEMeta(payload)).toEqual({ event: 'progress', id: 'p-1', retry: 3000 });
14
+ });
15
+ test('defaults to {} when no options are given', () => {
16
+ const payload = sse({ done: true });
17
+ expect(getSSEMeta(payload)).toEqual({});
18
+ });
19
+ test('metadata is per-object — two payloads keep separate options', () => {
20
+ const a = sse({ n: 1 }, { event: 'a' });
21
+ const b = sse({ n: 2 }, { event: 'b' });
22
+ expect(getSSEMeta(a)).toEqual({ event: 'a' });
23
+ expect(getSSEMeta(b)).toEqual({ event: 'b' });
24
+ });
25
+ });
26
+ describe('getSSEMeta', () => {
27
+ test('returns undefined for plain (undecorated) objects', () => {
28
+ expect(getSSEMeta({ progress: 0.5 })).toBeUndefined();
29
+ });
30
+ test('returns undefined for primitives', () => {
31
+ expect(getSSEMeta('text')).toBeUndefined();
32
+ expect(getSSEMeta(42)).toBeUndefined();
33
+ expect(getSSEMeta(true)).toBeUndefined();
34
+ expect(getSSEMeta(undefined)).toBeUndefined();
35
+ });
36
+ test('returns undefined for null', () => {
37
+ expect(getSSEMeta(null)).toBeUndefined();
38
+ });
39
+ });
40
+ describe('SseEventSequencer', () => {
41
+ function collector() {
42
+ const written = [];
43
+ return { written, write: (e) => void written.push(e) };
44
+ }
45
+ async function* gen(values, ret) {
46
+ for (const v of values)
47
+ yield v;
48
+ return ret;
49
+ }
50
+ it('writes yields with the default event and auto-incrementing ids', async () => {
51
+ const { written, write } = collector();
52
+ await new SseEventSequencer(write, 'Watch').pump(gen([{ a: 1 }, { a: 2 }]));
53
+ expect(written).toEqual([
54
+ { data: '{"a":1}', event: 'Watch', id: '0' },
55
+ { data: '{"a":2}', event: 'Watch', id: '1' },
56
+ ]);
57
+ });
58
+ it('sse() metadata overrides event/id/retry on yields', async () => {
59
+ const { written, write } = collector();
60
+ const tagged = sse({ p: 1 }, { event: 'progress', id: 'p-1', retry: 5 });
61
+ await new SseEventSequencer(write, 'Watch').pump(gen([tagged, { p: 2 }]));
62
+ expect(written[0]).toEqual({ data: '{"p":1}', event: 'progress', id: 'p-1', retry: 5 });
63
+ // counter not consumed by the custom id — next auto id is still 0
64
+ expect(written[1]).toEqual({ data: '{"p":2}', event: 'Watch', id: '0' });
65
+ });
66
+ it('emits the return value as event: return and skips undefined returns', async () => {
67
+ const { written, write } = collector();
68
+ await new SseEventSequencer(write, 'W').pump(gen([1], { total: 1 }));
69
+ expect(written[1]).toEqual({ data: '{"total":1}', event: 'return', id: '1' });
70
+ const second = collector();
71
+ await new SseEventSequencer(second.write, 'W').pump(gen([1]));
72
+ expect(second.written).toHaveLength(1);
73
+ });
74
+ it('writeError continues the id sequence and honors dispatched/meta events', async () => {
75
+ const { written, write } = collector();
76
+ const seq = new SseEventSequencer(write, 'W');
77
+ await seq.writeYield('x');
78
+ await seq.writeError({ data: { error: 'boom' }, sseEvent: 'error' });
79
+ expect(written[1]).toEqual({ data: '{"error":"boom"}', event: 'error', id: '1' });
80
+ await seq.writeError({ data: sse({ msg: 'm' }, { event: 'custom-fail' }) });
81
+ expect(written[2].event).toBe('custom-fail');
82
+ });
83
+ it('serializeSseValue: strings pass through, null/undefined become empty', () => {
84
+ expect(serializeSseValue('raw')).toBe('raw');
85
+ expect(serializeSseValue(null)).toBe('');
86
+ expect(serializeSseValue(undefined)).toBe('');
87
+ expect(serializeSseValue(7)).toBe('7');
88
+ });
89
+ it('propagates iterator errors to the caller (dispatch happens outside)', async () => {
90
+ const { write } = collector();
91
+ async function* boom() {
92
+ yield 1;
93
+ throw new Error('mid');
94
+ }
95
+ await expect(new SseEventSequencer(write, 'W').pump(boom())).rejects.toThrow('mid');
96
+ });
97
+ });
98
+ //# sourceMappingURL=sse.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.test.js","sourceRoot":"","sources":["../../src/server/sse.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,13 @@
1
- import type { Procedures } from '../index.js';
2
- import type { ErrorTaxonomy } from './http/error-taxonomy.js';
1
+ /**
2
+ * Transport-agnostic HTTP server types.
3
+ *
4
+ * The doc shapes here (`*RouteDoc`, `DocEnvelope`, `ErrorDoc`, `HeaderDoc`)
5
+ * are a FROZEN wire contract: they are the input to client codegen, and v9
6
+ * guarantees byte-identical generated output vs v8. Do not change field names,
7
+ * optionality, or nesting without re-validating the codegen goldens.
8
+ */
9
+ import type { ProcedureKind } from '../core/types.js';
10
+ import type { ErrorTaxonomy } from './errors/taxonomy.js';
3
11
  /**
4
12
  * @typeParam TErrorKey - Union of valid taxonomy keys. Defaults to `string`
5
13
  * (unconstrained). Narrow it by passing `keyof typeof yourTaxonomy & string`
@@ -15,10 +23,6 @@ export interface RPCConfig<TErrorKey extends string = string> {
15
23
  */
16
24
  errors?: TErrorKey[];
17
25
  }
18
- export type FactoryItem<C> = {
19
- factory: ReturnType<typeof Procedures<C, RPCConfig>>;
20
- factoryContext: (req: Request) => C;
21
- };
22
26
  export interface RPCHttpRouteDoc extends RPCConfig {
23
27
  kind: 'rpc';
24
28
  name: string;
@@ -39,7 +43,7 @@ export type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head';
39
43
  * typo protection on `errors`.
40
44
  */
41
45
  export interface APIConfig<TErrorKey extends string = string> {
42
- /** HTTP route path (supports Hono path params, e.g., '/users/:id') */
46
+ /** HTTP route path (supports path params, e.g., '/users/:id') */
43
47
  path: string;
44
48
  /** HTTP method for this endpoint */
45
49
  method: HttpMethod;
@@ -78,12 +82,12 @@ export interface APIHttpRouteDoc {
78
82
  };
79
83
  }
80
84
  /**
81
- * Constrains schema.input channel names to valid HTTP input sources.
82
- * Use with `satisfies` or as a type annotation to catch typos at compile time:
85
+ * Constrains `schema.req` channel names to valid HTTP input sources.
86
+ * Use with `satisfies` to catch typos at compile time:
83
87
  *
84
88
  * @example
85
89
  * schema: {
86
- * input: {
90
+ * req: {
87
91
  * pathParams: Type.Object({ id: Type.String() }),
88
92
  * qurey: Type.Object({ ... }), // TS error: 'qurey' not in APIInput
89
93
  * } satisfies APIInput
@@ -162,8 +166,7 @@ export type ExtractConfig<TFactory> = TFactory extends {
162
166
  export type ProceduresFactory = {
163
167
  getProcedures: () => Array<{
164
168
  name: string;
165
- kind?: import('../types.js').ProcedureKind;
166
- isStream?: boolean;
169
+ kind?: ProcedureKind;
167
170
  config: any;
168
171
  handler: (ctx: any, params?: any) => Promise<any> | AsyncGenerator<any, any, unknown>;
169
172
  }>;
@@ -177,9 +180,8 @@ export interface DocSource<T = AnyHttpRouteDoc> {
177
180
  readonly docs: T[];
178
181
  /**
179
182
  * Optional list of procedures that were registered with this builder but
180
- * couldn't be served by it (e.g. a streaming procedure registered with an
181
- * RPC builder). DocRegistry aggregates these across sources and warns at
182
- * `toJSON()` time so silently-dropped procedures don't slip through.
183
+ * couldn't be served by it. DocRegistry aggregates these across sources and
184
+ * warns at `toJSON()` time so silently-dropped procedures don't slip through.
183
185
  */
184
186
  readonly skippedProcedures?: {
185
187
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/implementations/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":""}
@@ -26,7 +26,6 @@ my-astro-app/
26
26
  ```ts
27
27
  // src/server/procedures/users.ts
28
28
  import { Procedures } from 'ts-procedures'
29
- import type { APIConfig } from 'ts-procedures/http'
30
29
  import { Type } from 'typebox'
31
30
 
32
31
  type UserContext = {
@@ -34,17 +33,17 @@ type UserContext = {
34
33
  currentUser: { id: string } | null
35
34
  }
36
35
 
37
- export const usersAPI = Procedures<UserContext, APIConfig>()
36
+ export const usersAPI = Procedures<UserContext>()
38
37
 
39
- usersAPI.Create(
38
+ usersAPI.CreateHttp(
40
39
  'GetUser',
41
40
  {
42
41
  path: '/users/:id',
43
42
  method: 'get',
44
43
  scope: 'users', // drives the generated client namespace: api.users.GetUser(...)
45
44
  schema: {
46
- input: { pathParams: Type.Object({ id: Type.String() }) },
47
- returnType: Type.Object({ id: Type.String(), name: Type.String() }),
45
+ req: { pathParams: Type.Object({ id: Type.String() }) },
46
+ res: { body: Type.Object({ id: Type.String(), name: Type.String() }) },
48
47
  },
49
48
  },
50
49
  async (ctx, { pathParams }) => {
@@ -128,8 +127,7 @@ The adapter does NOT couple to `DocRegistry`. Wire codegen separately, against t
128
127
 
129
128
  ```ts
130
129
  // scripts/build-docs.ts
131
- import { writeFileSync } from 'node:fs'
132
- import { DocRegistry } from 'ts-procedures/http-docs'
130
+ import { writeDocEnvelope } from 'ts-procedures'
133
131
  import { HonoAppBuilder } from 'ts-procedures/hono'
134
132
  import { usersAPI } from '../src/server/procedures/users'
135
133
 
@@ -138,10 +136,11 @@ import { usersAPI } from '../src/server/procedures/users'
138
136
  const builder = new HonoAppBuilder().register(usersAPI, () => ({} as never))
139
137
  builder.build()
140
138
 
141
- const envelope = new DocRegistry().from(builder).toEnvelope()
142
- writeFileSync('envelope.json', JSON.stringify(envelope, null, 2))
139
+ await writeDocEnvelope(builder, 'envelope.json')
143
140
  ```
144
141
 
142
+ `writeDocEnvelope` accepts a built `HonoAppBuilder` (it calls `toDocEnvelope()` for you), a `DocRegistry`, or a plain `DocEnvelope` object, and writes pretty JSON to disk.
143
+
145
144
  ### Wire it as an npm script
146
145
 
147
146
  ```jsonc