ts-procedures 5.9.1 → 5.10.2

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 (305) hide show
  1. package/README.md +1 -1
  2. package/agent_config/bin/postinstall.mjs +3 -3
  3. package/agent_config/bin/setup.mjs +22 -11
  4. package/agent_config/claude-code/agents/ts-procedures-architect.md +46 -101
  5. package/agent_config/claude-code/skills/{guide → ts-procedures}/SKILL.md +50 -35
  6. package/agent_config/claude-code/skills/{guide → ts-procedures}/anti-patterns.md +6 -5
  7. package/agent_config/claude-code/skills/{guide → ts-procedures}/api-reference.md +60 -49
  8. package/agent_config/claude-code/skills/ts-procedures-review/SKILL.md +48 -0
  9. package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/SKILL.md +19 -24
  10. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/client.md +115 -0
  11. package/agent_config/lib/install-claude.mjs +35 -87
  12. package/build/src/client/call.d.ts +14 -0
  13. package/build/src/client/call.js +47 -0
  14. package/build/src/client/call.js.map +1 -0
  15. package/build/src/client/call.test.d.ts +1 -0
  16. package/build/src/client/call.test.js +124 -0
  17. package/build/src/client/call.test.js.map +1 -0
  18. package/build/src/client/errors.d.ts +25 -0
  19. package/build/src/client/errors.js +33 -0
  20. package/build/src/client/errors.js.map +1 -0
  21. package/build/src/client/errors.test.d.ts +1 -0
  22. package/build/src/client/errors.test.js +41 -0
  23. package/build/src/client/errors.test.js.map +1 -0
  24. package/build/src/client/fetch-adapter.d.ts +12 -0
  25. package/build/src/client/fetch-adapter.js +156 -0
  26. package/build/src/client/fetch-adapter.js.map +1 -0
  27. package/build/src/client/fetch-adapter.test.d.ts +1 -0
  28. package/build/src/client/fetch-adapter.test.js +271 -0
  29. package/build/src/client/fetch-adapter.test.js.map +1 -0
  30. package/build/src/client/hooks.d.ts +17 -0
  31. package/build/src/client/hooks.js +40 -0
  32. package/build/src/client/hooks.js.map +1 -0
  33. package/build/src/client/hooks.test.d.ts +1 -0
  34. package/build/src/client/hooks.test.js +163 -0
  35. package/build/src/client/hooks.test.js.map +1 -0
  36. package/build/src/client/index.d.ts +22 -0
  37. package/build/src/client/index.js +67 -0
  38. package/build/src/client/index.js.map +1 -0
  39. package/build/src/client/index.test.d.ts +1 -0
  40. package/build/src/client/index.test.js +231 -0
  41. package/build/src/client/index.test.js.map +1 -0
  42. package/build/src/client/request-builder.d.ts +13 -0
  43. package/build/src/client/request-builder.js +53 -0
  44. package/build/src/client/request-builder.js.map +1 -0
  45. package/build/src/client/request-builder.test.d.ts +1 -0
  46. package/build/src/client/request-builder.test.js +160 -0
  47. package/build/src/client/request-builder.test.js.map +1 -0
  48. package/build/src/client/stream.d.ts +27 -0
  49. package/build/src/client/stream.js +118 -0
  50. package/build/src/client/stream.js.map +1 -0
  51. package/build/src/client/stream.test.d.ts +1 -0
  52. package/build/src/client/stream.test.js +228 -0
  53. package/build/src/client/stream.test.js.map +1 -0
  54. package/build/src/client/types.d.ts +78 -0
  55. package/build/src/client/types.js +3 -0
  56. package/build/src/client/types.js.map +1 -0
  57. package/build/src/codegen/bin/cli.d.ts +45 -0
  58. package/build/src/codegen/bin/cli.js +246 -0
  59. package/build/src/codegen/bin/cli.js.map +1 -0
  60. package/build/src/codegen/bin/cli.test.d.ts +1 -0
  61. package/build/src/codegen/bin/cli.test.js +220 -0
  62. package/build/src/codegen/bin/cli.test.js.map +1 -0
  63. package/build/src/codegen/constants.d.ts +1 -0
  64. package/build/src/codegen/constants.js +2 -0
  65. package/build/src/codegen/constants.js.map +1 -0
  66. package/build/src/codegen/e2e.test.d.ts +1 -0
  67. package/build/src/codegen/e2e.test.js +464 -0
  68. package/build/src/codegen/e2e.test.js.map +1 -0
  69. package/build/src/codegen/emit-client-runtime.d.ts +9 -0
  70. package/build/src/codegen/emit-client-runtime.js +99 -0
  71. package/build/src/codegen/emit-client-runtime.js.map +1 -0
  72. package/build/src/codegen/emit-client-runtime.test.d.ts +1 -0
  73. package/build/src/codegen/emit-client-runtime.test.js +78 -0
  74. package/build/src/codegen/emit-client-runtime.test.js.map +1 -0
  75. package/build/src/codegen/emit-client-types.d.ts +8 -0
  76. package/build/src/codegen/emit-client-types.js +25 -0
  77. package/build/src/codegen/emit-client-types.js.map +1 -0
  78. package/build/src/codegen/emit-client-types.test.d.ts +1 -0
  79. package/build/src/codegen/emit-client-types.test.js +33 -0
  80. package/build/src/codegen/emit-client-types.test.js.map +1 -0
  81. package/build/src/codegen/emit-errors.d.ts +19 -0
  82. package/build/src/codegen/emit-errors.js +59 -0
  83. package/build/src/codegen/emit-errors.js.map +1 -0
  84. package/build/src/codegen/emit-errors.test.d.ts +1 -0
  85. package/build/src/codegen/emit-errors.test.js +175 -0
  86. package/build/src/codegen/emit-errors.test.js.map +1 -0
  87. package/build/src/codegen/emit-index.d.ts +12 -0
  88. package/build/src/codegen/emit-index.js +41 -0
  89. package/build/src/codegen/emit-index.js.map +1 -0
  90. package/build/src/codegen/emit-index.test.d.ts +1 -0
  91. package/build/src/codegen/emit-index.test.js +106 -0
  92. package/build/src/codegen/emit-index.test.js.map +1 -0
  93. package/build/src/codegen/emit-scope.d.ts +15 -0
  94. package/build/src/codegen/emit-scope.js +299 -0
  95. package/build/src/codegen/emit-scope.js.map +1 -0
  96. package/build/src/codegen/emit-scope.test.d.ts +1 -0
  97. package/build/src/codegen/emit-scope.test.js +559 -0
  98. package/build/src/codegen/emit-scope.test.js.map +1 -0
  99. package/build/src/codegen/emit-types.d.ts +43 -0
  100. package/build/src/codegen/emit-types.js +111 -0
  101. package/build/src/codegen/emit-types.js.map +1 -0
  102. package/build/src/codegen/emit-types.test.d.ts +1 -0
  103. package/build/src/codegen/emit-types.test.js +184 -0
  104. package/build/src/codegen/emit-types.test.js.map +1 -0
  105. package/build/src/codegen/group-routes.d.ts +23 -0
  106. package/build/src/codegen/group-routes.js +46 -0
  107. package/build/src/codegen/group-routes.js.map +1 -0
  108. package/build/src/codegen/group-routes.test.d.ts +1 -0
  109. package/build/src/codegen/group-routes.test.js +131 -0
  110. package/build/src/codegen/group-routes.test.js.map +1 -0
  111. package/build/src/codegen/index.d.ts +15 -0
  112. package/build/src/codegen/index.js +16 -0
  113. package/build/src/codegen/index.js.map +1 -0
  114. package/build/src/codegen/naming.d.ts +7 -0
  115. package/build/src/codegen/naming.js +21 -0
  116. package/build/src/codegen/naming.js.map +1 -0
  117. package/build/src/codegen/naming.test.d.ts +1 -0
  118. package/build/src/codegen/naming.test.js +40 -0
  119. package/build/src/codegen/naming.test.js.map +1 -0
  120. package/build/src/codegen/pipeline.d.ts +17 -0
  121. package/build/src/codegen/pipeline.js +78 -0
  122. package/build/src/codegen/pipeline.js.map +1 -0
  123. package/build/src/codegen/pipeline.test.d.ts +1 -0
  124. package/build/src/codegen/pipeline.test.js +269 -0
  125. package/build/src/codegen/pipeline.test.js.map +1 -0
  126. package/build/src/codegen/resolve-envelope.d.ts +7 -0
  127. package/build/src/codegen/resolve-envelope.js +46 -0
  128. package/build/src/codegen/resolve-envelope.js.map +1 -0
  129. package/build/src/codegen/resolve-envelope.test.d.ts +1 -0
  130. package/build/src/codegen/resolve-envelope.test.js +69 -0
  131. package/build/src/codegen/resolve-envelope.test.js.map +1 -0
  132. package/build/src/errors.d.ts +33 -0
  133. package/build/src/errors.js +91 -0
  134. package/build/src/errors.js.map +1 -0
  135. package/build/src/errors.test.d.ts +1 -0
  136. package/build/src/errors.test.js +122 -0
  137. package/build/src/errors.test.js.map +1 -0
  138. package/build/src/exports.d.ts +7 -0
  139. package/build/src/exports.js +8 -0
  140. package/build/src/exports.js.map +1 -0
  141. package/build/src/implementations/http/doc-registry.d.ts +12 -0
  142. package/build/src/implementations/http/doc-registry.js +114 -0
  143. package/build/src/implementations/http/doc-registry.js.map +1 -0
  144. package/build/src/implementations/http/doc-registry.test.d.ts +1 -0
  145. package/build/src/implementations/http/doc-registry.test.js +347 -0
  146. package/build/src/implementations/http/doc-registry.test.js.map +1 -0
  147. package/build/src/implementations/http/express-rpc/index.d.ts +94 -0
  148. package/build/src/implementations/http/express-rpc/index.js +185 -0
  149. package/build/src/implementations/http/express-rpc/index.js.map +1 -0
  150. package/build/src/implementations/http/express-rpc/index.test.d.ts +1 -0
  151. package/build/src/implementations/http/express-rpc/index.test.js +684 -0
  152. package/build/src/implementations/http/express-rpc/index.test.js.map +1 -0
  153. package/build/src/implementations/http/express-rpc/types.d.ts +11 -0
  154. package/build/src/implementations/http/express-rpc/types.js +2 -0
  155. package/build/src/implementations/http/express-rpc/types.js.map +1 -0
  156. package/build/src/implementations/http/hono-api/index.d.ts +102 -0
  157. package/build/src/implementations/http/hono-api/index.js +341 -0
  158. package/build/src/implementations/http/hono-api/index.js.map +1 -0
  159. package/build/src/implementations/http/hono-api/index.test.d.ts +1 -0
  160. package/build/src/implementations/http/hono-api/index.test.js +992 -0
  161. package/build/src/implementations/http/hono-api/index.test.js.map +1 -0
  162. package/build/src/implementations/http/hono-api/types.d.ts +13 -0
  163. package/build/src/implementations/http/hono-api/types.js +2 -0
  164. package/build/src/implementations/http/hono-api/types.js.map +1 -0
  165. package/build/src/implementations/http/hono-rpc/index.d.ts +92 -0
  166. package/build/src/implementations/http/hono-rpc/index.js +161 -0
  167. package/build/src/implementations/http/hono-rpc/index.js.map +1 -0
  168. package/build/src/implementations/http/hono-rpc/index.test.d.ts +1 -0
  169. package/build/src/implementations/http/hono-rpc/index.test.js +803 -0
  170. package/build/src/implementations/http/hono-rpc/index.test.js.map +1 -0
  171. package/build/src/implementations/http/hono-rpc/types.d.ts +11 -0
  172. package/build/src/implementations/http/hono-rpc/types.js +2 -0
  173. package/build/src/implementations/http/hono-rpc/types.js.map +1 -0
  174. package/build/src/implementations/http/hono-stream/index.d.ts +120 -0
  175. package/build/src/implementations/http/hono-stream/index.js +309 -0
  176. package/build/src/implementations/http/hono-stream/index.js.map +1 -0
  177. package/build/src/implementations/http/hono-stream/index.test.d.ts +1 -0
  178. package/build/src/implementations/http/hono-stream/index.test.js +1356 -0
  179. package/build/src/implementations/http/hono-stream/index.test.js.map +1 -0
  180. package/build/src/implementations/http/hono-stream/types.d.ts +15 -0
  181. package/build/src/implementations/http/hono-stream/types.js +2 -0
  182. package/build/src/implementations/http/hono-stream/types.js.map +1 -0
  183. package/build/src/implementations/types.d.ts +142 -0
  184. package/build/src/implementations/types.js +2 -0
  185. package/build/src/implementations/types.js.map +1 -0
  186. package/build/src/index.d.ts +165 -0
  187. package/build/src/index.js +253 -0
  188. package/build/src/index.js.map +1 -0
  189. package/build/src/index.test.d.ts +1 -0
  190. package/build/src/index.test.js +890 -0
  191. package/build/src/index.test.js.map +1 -0
  192. package/build/src/schema/compute-schema.d.ts +35 -0
  193. package/build/src/schema/compute-schema.js +41 -0
  194. package/build/src/schema/compute-schema.js.map +1 -0
  195. package/build/src/schema/compute-schema.test.d.ts +1 -0
  196. package/build/src/schema/compute-schema.test.js +107 -0
  197. package/build/src/schema/compute-schema.test.js.map +1 -0
  198. package/build/src/schema/extract-json-schema.d.ts +2 -0
  199. package/build/src/schema/extract-json-schema.js +12 -0
  200. package/build/src/schema/extract-json-schema.js.map +1 -0
  201. package/build/src/schema/extract-json-schema.test.d.ts +1 -0
  202. package/build/src/schema/extract-json-schema.test.js +23 -0
  203. package/build/src/schema/extract-json-schema.test.js.map +1 -0
  204. package/build/src/schema/parser.d.ts +28 -0
  205. package/build/src/schema/parser.js +170 -0
  206. package/build/src/schema/parser.js.map +1 -0
  207. package/build/src/schema/parser.test.d.ts +1 -0
  208. package/build/src/schema/parser.test.js +120 -0
  209. package/build/src/schema/parser.test.js.map +1 -0
  210. package/build/src/schema/resolve-schema-lib.d.ts +12 -0
  211. package/build/src/schema/resolve-schema-lib.js +11 -0
  212. package/build/src/schema/resolve-schema-lib.js.map +1 -0
  213. package/build/src/schema/resolve-schema-lib.test.d.ts +1 -0
  214. package/build/src/schema/resolve-schema-lib.test.js +17 -0
  215. package/build/src/schema/resolve-schema-lib.test.js.map +1 -0
  216. package/build/src/schema/types.d.ts +8 -0
  217. package/build/src/schema/types.js +2 -0
  218. package/build/src/schema/types.js.map +1 -0
  219. package/build/src/stack-utils.d.ts +25 -0
  220. package/build/src/stack-utils.js +95 -0
  221. package/build/src/stack-utils.js.map +1 -0
  222. package/build/src/stack-utils.test.d.ts +1 -0
  223. package/build/src/stack-utils.test.js +80 -0
  224. package/build/src/stack-utils.test.js.map +1 -0
  225. package/docs/ai-agent-setup.md +7 -6
  226. package/docs/core.md +5 -9
  227. package/docs/streaming.md +9 -9
  228. package/package.json +2 -13
  229. package/src/client/call.test.ts +162 -0
  230. package/src/client/errors.test.ts +43 -0
  231. package/src/client/fetch-adapter.test.ts +340 -0
  232. package/src/client/hooks.test.ts +191 -0
  233. package/src/client/index.test.ts +290 -0
  234. package/src/client/request-builder.test.ts +184 -0
  235. package/src/client/stream.test.ts +331 -0
  236. package/src/codegen/bin/cli.test.ts +260 -0
  237. package/src/codegen/bin/cli.ts +282 -0
  238. package/src/codegen/constants.ts +1 -0
  239. package/src/codegen/e2e.test.ts +565 -0
  240. package/src/codegen/emit-client-runtime.test.ts +93 -0
  241. package/src/codegen/emit-client-runtime.ts +114 -0
  242. package/src/codegen/emit-client-types.test.ts +39 -0
  243. package/src/codegen/emit-client-types.ts +27 -0
  244. package/src/codegen/emit-errors.test.ts +202 -0
  245. package/src/codegen/emit-errors.ts +80 -0
  246. package/src/codegen/emit-index.test.ts +127 -0
  247. package/src/codegen/emit-index.ts +58 -0
  248. package/src/codegen/emit-scope.test.ts +624 -0
  249. package/src/codegen/emit-scope.ts +389 -0
  250. package/src/codegen/emit-types.test.ts +205 -0
  251. package/src/codegen/emit-types.ts +158 -0
  252. package/src/codegen/group-routes.test.ts +159 -0
  253. package/src/codegen/group-routes.ts +61 -0
  254. package/src/codegen/index.ts +30 -0
  255. package/src/codegen/naming.test.ts +50 -0
  256. package/src/codegen/naming.ts +25 -0
  257. package/src/codegen/pipeline.test.ts +316 -0
  258. package/src/codegen/pipeline.ts +108 -0
  259. package/src/codegen/resolve-envelope.test.ts +76 -0
  260. package/src/codegen/resolve-envelope.ts +61 -0
  261. package/src/errors.test.ts +163 -0
  262. package/src/errors.ts +107 -0
  263. package/src/exports.ts +7 -0
  264. package/src/implementations/http/doc-registry.test.ts +415 -0
  265. package/src/implementations/http/doc-registry.ts +143 -0
  266. package/src/implementations/http/express-rpc/README.md +6 -6
  267. package/src/implementations/http/express-rpc/index.test.ts +957 -0
  268. package/src/implementations/http/express-rpc/index.ts +266 -0
  269. package/src/implementations/http/express-rpc/types.ts +16 -0
  270. package/src/implementations/http/hono-api/index.test.ts +1341 -0
  271. package/src/implementations/http/hono-api/index.ts +463 -0
  272. package/src/implementations/http/hono-api/types.ts +16 -0
  273. package/src/implementations/http/hono-rpc/README.md +6 -6
  274. package/src/implementations/http/hono-rpc/index.test.ts +1075 -0
  275. package/src/implementations/http/hono-rpc/index.ts +238 -0
  276. package/src/implementations/http/hono-rpc/types.ts +16 -0
  277. package/src/implementations/http/hono-stream/README.md +12 -12
  278. package/src/implementations/http/hono-stream/index.test.ts +1768 -0
  279. package/src/implementations/http/hono-stream/index.ts +456 -0
  280. package/src/implementations/http/hono-stream/types.ts +20 -0
  281. package/src/implementations/types.ts +174 -0
  282. package/src/index.test.ts +1185 -0
  283. package/src/index.ts +522 -0
  284. package/src/schema/compute-schema.test.ts +128 -0
  285. package/src/schema/compute-schema.ts +88 -0
  286. package/src/schema/extract-json-schema.test.ts +25 -0
  287. package/src/schema/extract-json-schema.ts +15 -0
  288. package/src/schema/parser.test.ts +182 -0
  289. package/src/schema/parser.ts +215 -0
  290. package/src/schema/resolve-schema-lib.test.ts +19 -0
  291. package/src/schema/resolve-schema-lib.ts +29 -0
  292. package/src/schema/types.ts +20 -0
  293. package/src/stack-utils.test.ts +94 -0
  294. package/src/stack-utils.ts +129 -0
  295. package/agent_config/claude-code/skills/review/SKILL.md +0 -53
  296. package/docs/superpowers/plans/2026-03-30-client-codegen.md +0 -2833
  297. package/docs/superpowers/specs/2026-03-30-client-codegen-design.md +0 -632
  298. /package/agent_config/claude-code/skills/{guide → ts-procedures}/patterns.md +0 -0
  299. /package/agent_config/claude-code/skills/{review → ts-procedures-review}/checklist.md +0 -0
  300. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/express-rpc.md +0 -0
  301. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/hono-api.md +0 -0
  302. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/hono-rpc.md +0 -0
  303. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/hono-stream.md +0 -0
  304. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/procedure.md +0 -0
  305. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/stream-procedure.md +0 -0
@@ -0,0 +1,238 @@
1
+ import { Hono, Context } from 'hono'
2
+ import { kebabCase } from 'es-toolkit/string'
3
+ import { TProcedureRegistration } from '../../../index.js'
4
+ import {
5
+ ExtractConfig,
6
+ ExtractContext,
7
+ ProceduresFactory,
8
+ RPCConfig,
9
+ RPCHttpRouteDoc,
10
+ } from '../../types.js'
11
+ import { castArray } from 'es-toolkit/compat'
12
+ import { HonoFactoryItem } from './types.js'
13
+
14
+ export type { RPCConfig, RPCHttpRouteDoc }
15
+
16
+ export type HonoRPCAppBuilderConfig = {
17
+ /**
18
+ * An existing Hono application instance to use.
19
+ * If not provided, a new instance will be created.
20
+ */
21
+ app?: Hono
22
+ /** Optional path prefix for all RPC routes. */
23
+ pathPrefix?: string
24
+ onRequestStart?: (c: Context) => void
25
+ onRequestEnd?: (c: Context) => void
26
+ onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
27
+ /**
28
+ * Error handler called when a procedure throws an error.
29
+ * @param procedure
30
+ * @param c
31
+ * @param error
32
+ */
33
+ onError?: (
34
+ procedure: TProcedureRegistration,
35
+ c: Context,
36
+ error: Error
37
+ ) => Response | Promise<Response>
38
+ }
39
+
40
+ /**
41
+ * Builder class for creating a Hono application with RPC routes.
42
+ *
43
+ * Usage:
44
+ * const PublicRPC = Procedures<PublicRPCContext, RPCConfig>()
45
+ * const ProtectedRPC = Procedures<ProtectedRPCContext, RPCConfig>()
46
+ *
47
+ * const rpcApp = new HonoRPCAppBuilder()
48
+ * .register(PublicRPC, (c): Promise<PublicRPCContext> => { /* context resolution logic * / })
49
+ * .register(ProtectedRPC, (c): Promise<ProtectedRPCContext> => { /* context resolution logic * / })
50
+ * .build();
51
+ *
52
+ * const app = rpcApp.app; // Hono application
53
+ * const docs = rpcApp.docs; // RPC route documentation
54
+ */
55
+ export class HonoRPCAppBuilder {
56
+ /**
57
+ * Constructor for HonoRPCAppBuilder.
58
+ *
59
+ * @param config
60
+ */
61
+ constructor(readonly config?: HonoRPCAppBuilderConfig) {
62
+ if (config?.app) {
63
+ this._app = config.app
64
+ }
65
+
66
+ if (config?.onRequestStart) {
67
+ this._app.use('*', async (c, next) => {
68
+ config.onRequestStart!(c)
69
+ await next()
70
+ })
71
+ }
72
+
73
+ if (config?.onRequestEnd) {
74
+ this._app.use('*', async (c, next) => {
75
+ await next()
76
+ config.onRequestEnd!(c)
77
+ })
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Generates the RPC route path based on the RPC configuration.
83
+ * The RPCConfig name can be a string or an array of strings to form nested paths.
84
+ *
85
+ * Example
86
+ * name: ['string', 'string-string', 'string']
87
+ * path: /string/string-string/string/version
88
+ * @param config
89
+ */
90
+ static makeRPCHttpRoutePath({
91
+ name,
92
+ config,
93
+ prefix,
94
+ }: {
95
+ name: string
96
+ prefix?: string
97
+ config: RPCConfig
98
+ }) {
99
+ const normalizedPrefix = prefix ? (prefix.startsWith('/') ? prefix : `/${prefix}`) : ''
100
+
101
+ return `${normalizedPrefix}/${castArray(config.scope).map(kebabCase).join('/')}/${kebabCase(name)}/${String(config.version).trim()}`
102
+ }
103
+
104
+ /**
105
+ * Instance method wrapper for makeRPCHttpRoutePath that uses the builder's pathPrefix.
106
+ * @param config - The RPC configuration
107
+ */
108
+ makeRPCHttpRoutePath(name: string, config: RPCConfig): string {
109
+ return HonoRPCAppBuilder.makeRPCHttpRoutePath({
110
+ name,
111
+ config,
112
+ prefix: this.config?.pathPrefix,
113
+ })
114
+ }
115
+
116
+ private factories: HonoFactoryItem<any>[] = []
117
+
118
+ private _app: Hono = new Hono()
119
+ private _docs: (RPCHttpRouteDoc & object)[] = []
120
+
121
+ get app(): Hono {
122
+ return this._app
123
+ }
124
+
125
+ get docs(): RPCHttpRouteDoc[] {
126
+ return this._docs
127
+ }
128
+
129
+ /**
130
+ * Registers a procedure factory with its context.
131
+ * @param factory - The procedure factory created by Procedures<Context, RPCConfig>()
132
+ * @param factoryContext - The context for procedure handlers. Can be a direct value,
133
+ * a sync function (c) => Context, or an async function (c) => Promise<Context>
134
+ * @param extendProcedureDoc - A custom function to extend the generated RPC route documentation for each procedure.
135
+ */
136
+ register<TFactory extends ProceduresFactory>(
137
+ factory: TFactory,
138
+ factoryContext:
139
+ | ExtractContext<TFactory>
140
+ | ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>),
141
+ extendProcedureDoc?: (params: {
142
+ /* RPC App builder base http route doc */
143
+ base: RPCHttpRouteDoc
144
+ /* Procedure registration */
145
+ procedure: TProcedureRegistration<any, ExtractConfig<TFactory>>
146
+ }) => Record<string, any>
147
+ ): this {
148
+ this.factories.push({ factory, factoryContext, extendProcedureDoc } as HonoFactoryItem<any>)
149
+ return this
150
+ }
151
+
152
+ /**
153
+ * Builds and returns the Hono application with registered RPC routes.
154
+ * @return Hono
155
+ */
156
+ build(): Hono {
157
+ this.factories.forEach(({ factory, factoryContext, extendProcedureDoc }) => {
158
+ factory.getProcedures().map((procedure: TProcedureRegistration<any, RPCConfig>) => {
159
+ const route = this.buildRpcHttpRouteDoc(procedure, extendProcedureDoc)
160
+
161
+ this._docs.push(route)
162
+
163
+ this._app.post(route.path, async (c) => {
164
+ try {
165
+ const context =
166
+ typeof factoryContext === 'function'
167
+ ? await factoryContext(c)
168
+ : (factoryContext as ExtractContext<typeof factory>)
169
+
170
+ // Hono uses c.req.json() for body parsing
171
+ const body = await c.req.json().catch(() => ({}))
172
+ const result = await procedure.handler({ ...context, signal: c.req.raw.signal }, body)
173
+
174
+ if (this.config?.onSuccess) {
175
+ this.config.onSuccess(procedure, c)
176
+ }
177
+
178
+ // Hono returns Response objects via c.json()
179
+ return c.json(result)
180
+ } catch (error) {
181
+ if (this.config?.onError) {
182
+ return this.config.onError(procedure, c, error as Error)
183
+ }
184
+ // Default error handling
185
+ return c.json({ error: (error as Error).message }, 500)
186
+ }
187
+ })
188
+ })
189
+ })
190
+
191
+ return this._app
192
+ }
193
+
194
+ /**
195
+ * Generates the RPC HTTP route for the given procedure.
196
+ * @param procedure
197
+ */
198
+ private buildRpcHttpRouteDoc(
199
+ procedure: TProcedureRegistration<any, RPCConfig>,
200
+ extendProcedureDoc: HonoFactoryItem['extendProcedureDoc']
201
+ ): RPCHttpRouteDoc {
202
+ const { config } = procedure
203
+ const path = HonoRPCAppBuilder.makeRPCHttpRoutePath({
204
+ name: procedure.name,
205
+ config,
206
+ prefix: this.config?.pathPrefix,
207
+ })
208
+ const method = 'post' as const // RPCs use POST method
209
+ const jsonSchema: { body?: Record<string, unknown>; response?: Record<string, unknown> } = {}
210
+
211
+ if (config.schema?.params) {
212
+ jsonSchema.body = config.schema.params
213
+ }
214
+ if (config.schema?.returnType) {
215
+ jsonSchema.response = config.schema.returnType
216
+ }
217
+
218
+ const base = {
219
+ kind: 'rpc' as const,
220
+ name: procedure.name,
221
+ version: config.version,
222
+ scope: config.scope,
223
+ path,
224
+ method,
225
+ jsonSchema,
226
+ }
227
+ let extendedDoc: object = {}
228
+
229
+ if (extendProcedureDoc) {
230
+ extendedDoc = extendProcedureDoc({ base, procedure })
231
+ }
232
+
233
+ return {
234
+ ...extendedDoc,
235
+ ...base,
236
+ }
237
+ }
238
+ }
@@ -0,0 +1,16 @@
1
+ import { ExtractConfig, ExtractContext, RPCConfig, RPCHttpRouteDoc } from '../../types.js'
2
+ import { Procedures, TProcedureRegistration } from '../../../index.js'
3
+ import { Context } from 'hono'
4
+
5
+ export type HonoFactoryItem<TFactory = ReturnType<typeof Procedures<any, RPCConfig>>> = {
6
+ factory: TFactory
7
+ factoryContext:
8
+ | ExtractContext<TFactory>
9
+ | ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>)
10
+ extendProcedureDoc?: (params: {
11
+ /* RPC App builder base http route doc */
12
+ base: RPCHttpRouteDoc
13
+ /* Procedure registration */
14
+ procedure: TProcedureRegistration<any, ExtractConfig<TFactory>>
15
+ }) => Record<string, any>
16
+ }
@@ -37,7 +37,7 @@ StreamRPC.CreateStream(
37
37
  scope: ['user', 'notifications'],
38
38
  version: 1,
39
39
  schema: {
40
- yieldType: v.object({ id: v.number(), message: v.string() }),
40
+ yieldType: Type.Object({ id: Type.Number(), message: Type.String() }),
41
41
  },
42
42
  },
43
43
  async function* (ctx) {
@@ -344,19 +344,19 @@ StreamRPC.CreateStream('WatchEvents', {
344
344
  scope: 'events',
345
345
  version: 1,
346
346
  schema: {
347
- params: v.object({ roomId: v.string() }),
347
+ params: Type.Object({ roomId: Type.String() }),
348
348
  // Union type: clients know exactly what to expect
349
- yieldType: v.union([
350
- v.object({
351
- type: v.literal('event'),
352
- eventType: v.string(),
353
- data: v.any()
349
+ yieldType: Type.Union([
350
+ Type.Object({
351
+ type: Type.Literal('event'),
352
+ eventType: Type.String(),
353
+ data: Type.Any()
354
354
  }),
355
- v.object({
356
- type: v.literal('error'),
357
- code: v.string(),
358
- message: v.string(),
359
- retryable: v.boolean()
355
+ Type.Object({
356
+ type: Type.Literal('error'),
357
+ code: Type.String(),
358
+ message: Type.String(),
359
+ retryable: Type.Boolean()
360
360
  })
361
361
  ])
362
362
  }