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,78 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { emitClientRuntimeFile } from './emit-client-runtime.js';
3
+ import { CODEGEN_HEADER } from './constants.js';
4
+ describe('emitClientRuntimeFile', () => {
5
+ it('returns a string', async () => {
6
+ const result = await emitClientRuntimeFile();
7
+ expect(typeof result).toBe('string');
8
+ });
9
+ it('contains the auto-generated header comment', async () => {
10
+ const result = await emitClientRuntimeFile();
11
+ expect(result.startsWith(CODEGEN_HEADER)).toBe(true);
12
+ });
13
+ it("imports from './_types' (not './types.js' or 'ts-procedures/client')", async () => {
14
+ const result = await emitClientRuntimeFile();
15
+ expect(result).toContain("from './_types'");
16
+ expect(result).not.toContain("from './types.js'");
17
+ expect(result).not.toContain("from 'ts-procedures/client'");
18
+ });
19
+ it('contains NO inter-file imports from sibling modules', async () => {
20
+ const result = await emitClientRuntimeFile();
21
+ const interFileImports = [
22
+ './errors.js',
23
+ './hooks.js',
24
+ './request-builder.js',
25
+ './call.js',
26
+ './stream.js',
27
+ './fetch-adapter.js',
28
+ ];
29
+ for (const mod of interFileImports) {
30
+ expect(result).not.toContain(`from '${mod}'`);
31
+ }
32
+ });
33
+ it('contains export function createClient', async () => {
34
+ const result = await emitClientRuntimeFile();
35
+ expect(result).toMatch(/export function createClient/);
36
+ });
37
+ it('contains export function createFetchAdapter', async () => {
38
+ const result = await emitClientRuntimeFile();
39
+ expect(result).toMatch(/export function createFetchAdapter/);
40
+ });
41
+ it('contains export class ClientRequestError', async () => {
42
+ const result = await emitClientRuntimeFile();
43
+ expect(result).toMatch(/export class ClientRequestError/);
44
+ });
45
+ it('contains export class ClientPathParamError', async () => {
46
+ const result = await emitClientRuntimeFile();
47
+ expect(result).toMatch(/export class ClientPathParamError/);
48
+ });
49
+ it('contains export class ClientStreamError', async () => {
50
+ const result = await emitClientRuntimeFile();
51
+ expect(result).toMatch(/export class ClientStreamError/);
52
+ });
53
+ it('contains export async function executeCall', async () => {
54
+ const result = await emitClientRuntimeFile();
55
+ expect(result).toMatch(/export async function executeCall/);
56
+ });
57
+ it('contains export async function executeStream', async () => {
58
+ const result = await emitClientRuntimeFile();
59
+ expect(result).toMatch(/export async function executeStream/);
60
+ });
61
+ it('contains export function createTypedStream', async () => {
62
+ const result = await emitClientRuntimeFile();
63
+ expect(result).toMatch(/export function createTypedStream/);
64
+ });
65
+ it('contains export interface FetchAdapterConfig', async () => {
66
+ const result = await emitClientRuntimeFile();
67
+ expect(result).toMatch(/export interface FetchAdapterConfig/);
68
+ });
69
+ it('does NOT contain export type { re-export blocks from index.ts barrel', async () => {
70
+ const result = await emitClientRuntimeFile();
71
+ expect(result).not.toMatch(/export type \{[\s\S]*?\} from/);
72
+ });
73
+ it('does NOT contain orphaned "Barrel exports" section comment', async () => {
74
+ const result = await emitClientRuntimeFile();
75
+ expect(result).not.toContain('// ── Barrel exports');
76
+ });
77
+ });
78
+ //# sourceMappingURL=emit-client-runtime.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-client-runtime.test.js","sourceRoot":"","sources":["../../../src/codegen/emit-client-runtime.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Reads `src/client/types.ts` from the package root and returns it as the
3
+ * content of a `_types.ts` file, prepended with the auto-generated header.
4
+ *
5
+ * This enables a self-contained codegen mode where consumers don't need
6
+ * `ts-procedures` as a runtime dependency.
7
+ */
8
+ export declare function emitClientTypesFile(): Promise<string>;
@@ -0,0 +1,25 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { readFile, access } from 'node:fs/promises';
4
+ import { CODEGEN_HEADER } from './constants.js';
5
+ /**
6
+ * Reads `src/client/types.ts` from the package root and returns it as the
7
+ * content of a `_types.ts` file, prepended with the auto-generated header.
8
+ *
9
+ * This enables a self-contained codegen mode where consumers don't need
10
+ * `ts-procedures` as a runtime dependency.
11
+ */
12
+ export async function emitClientTypesFile() {
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = dirname(__filename);
15
+ // Works from both src/codegen/ (source) and build/codegen/ (compiled)
16
+ const packageRoot = resolve(__dirname, '../..');
17
+ const typesPath = resolve(packageRoot, 'src/client/types.ts');
18
+ await access(typesPath).catch(() => {
19
+ throw new Error(`[ts-procedures-codegen] Cannot locate src/client/types.ts at expected path: ${typesPath}. ` +
20
+ `Ensure ts-procedures is installed correctly.`);
21
+ });
22
+ const content = await readFile(typesPath, 'utf-8');
23
+ return [CODEGEN_HEADER, '', content].join('\n');
24
+ }
25
+ //# sourceMappingURL=emit-client-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-client-types.js","sourceRoot":"","sources":["../../../src/codegen/emit-client-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACrC,sEAAsE;IACtE,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAA;IAC7D,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QACjC,MAAM,IAAI,KAAK,CACb,+EAA+E,SAAS,IAAI;YAC5F,8CAA8C,CAC/C,CAAA;IACH,CAAC,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAClD,OAAO,CAAC,cAAc,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACjD,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { emitClientTypesFile } from './emit-client-types.js';
6
+ import { CODEGEN_HEADER } from './constants.js';
7
+ describe('emitClientTypesFile', () => {
8
+ it('returns a string', async () => {
9
+ const result = await emitClientTypesFile();
10
+ expect(typeof result).toBe('string');
11
+ });
12
+ it('header is first line', async () => {
13
+ const result = await emitClientTypesFile();
14
+ expect(result.startsWith(CODEGEN_HEADER)).toBe(true);
15
+ });
16
+ it('no import statements', async () => {
17
+ const result = await emitClientTypesFile();
18
+ // types.ts has zero imports — the emitted file should be fully self-contained
19
+ expect(result).not.toMatch(/^import\s/m);
20
+ });
21
+ it('output content (after header) matches src/client/types.ts verbatim', async () => {
22
+ const result = await emitClientTypesFile();
23
+ const __filename = fileURLToPath(import.meta.url);
24
+ const __dirname = dirname(__filename);
25
+ const packageRoot = resolve(__dirname, '../..');
26
+ const typesPath = resolve(packageRoot, 'src/client/types.ts');
27
+ const typesContent = await readFile(typesPath, 'utf-8');
28
+ // The function prepends CODEGEN_HEADER + '\n' + '\n' before the file content
29
+ const expected = [CODEGEN_HEADER, '', typesContent].join('\n');
30
+ expect(result).toBe(expected);
31
+ });
32
+ });
33
+ //# sourceMappingURL=emit-client-types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-client-types.test.js","sourceRoot":"","sources":["../../../src/codegen/emit-client-types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAChC,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAA;QAC1C,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAA;QAC1C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAA;QAC1C,8EAA8E;QAC9E,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAA;QAE1C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;QACrC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAA;QAC7D,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAEvD,6EAA6E;QAC7E,MAAM,QAAQ,GAAG,CAAC,cAAc,EAAE,EAAE,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { type AjscOptions } from './emit-types.js';
2
+ import type { ErrorDoc } from '../implementations/types.js';
3
+ export interface EmitErrorsOptions {
4
+ ajsc?: AjscOptions;
5
+ clientImportPath?: string;
6
+ namespaceTypes?: boolean;
7
+ serviceName?: string;
8
+ }
9
+ /**
10
+ * Generates a TypeScript file with error type declarations from the DocEnvelope.errors array.
11
+ *
12
+ * Only errors with a `schema` property are included. If no errors have schemas,
13
+ * returns `undefined` (no file generated).
14
+ *
15
+ * When `namespaceTypes` is true, wraps in `export namespace Errors { ... }`
16
+ * (or `${ServiceName}Errors` with `serviceName`). The union type is similarly
17
+ * prefixed: `ProcedureErrorUnion` → `${ServiceName}ProcedureErrorUnion`.
18
+ */
19
+ export declare function emitErrorsFile(errors: ErrorDoc[], options?: EmitErrorsOptions): Promise<string | undefined>;
@@ -0,0 +1,59 @@
1
+ import { jsonSchemaToTypeString, jsonSchemaToExtractedTypes } from './emit-types.js';
2
+ import { CODEGEN_HEADER } from './constants.js';
3
+ import { toPascalCase } from './naming.js';
4
+ /**
5
+ * Generates a TypeScript file with error type declarations from the DocEnvelope.errors array.
6
+ *
7
+ * Only errors with a `schema` property are included. If no errors have schemas,
8
+ * returns `undefined` (no file generated).
9
+ *
10
+ * When `namespaceTypes` is true, wraps in `export namespace Errors { ... }`
11
+ * (or `${ServiceName}Errors` with `serviceName`). The union type is similarly
12
+ * prefixed: `ProcedureErrorUnion` → `${ServiceName}ProcedureErrorUnion`.
13
+ */
14
+ export async function emitErrorsFile(errors, options) {
15
+ const { ajsc: ajscOpts, namespaceTypes = false, serviceName } = options ?? {};
16
+ const servicePrefix = serviceName ? toPascalCase(serviceName) : '';
17
+ const namespaceName = servicePrefix ? `${servicePrefix}Errors` : 'Errors';
18
+ const unionName = servicePrefix ? `${servicePrefix}ProcedureErrorUnion` : 'ProcedureErrorUnion';
19
+ // Filter to only errors that have a schema
20
+ const errorsWithSchema = errors.filter((e) => e.schema != null);
21
+ if (errorsWithSchema.length === 0) {
22
+ return undefined;
23
+ }
24
+ const typeLines = [];
25
+ if (namespaceTypes) {
26
+ typeLines.push(`export namespace ${namespaceName} {`);
27
+ for (const error of errorsWithSchema) {
28
+ const result = await jsonSchemaToExtractedTypes(error.schema, ajscOpts);
29
+ if (result != null) {
30
+ typeLines.push(` /** ${error.description} (HTTP ${error.statusCode}) */`);
31
+ for (const decl of result.declarations) {
32
+ typeLines.push(` ${decl}`);
33
+ }
34
+ typeLines.push(` export type ${error.name} = ${result.body}`);
35
+ typeLines.push('');
36
+ }
37
+ }
38
+ const unionMembers = errorsWithSchema.map((e) => e.name).join(' | ');
39
+ typeLines.push(` export type ${unionName} = ${unionMembers}`);
40
+ typeLines.push('}');
41
+ typeLines.push('');
42
+ }
43
+ else {
44
+ for (const error of errorsWithSchema) {
45
+ const typeDecl = await jsonSchemaToTypeString(error.name, error.schema, ajscOpts);
46
+ if (typeDecl != null) {
47
+ typeLines.push(`/** ${error.description} (HTTP ${error.statusCode}) */`);
48
+ typeLines.push(typeDecl);
49
+ typeLines.push('');
50
+ }
51
+ }
52
+ const unionMembers = errorsWithSchema.map((e) => e.name).join(' | ');
53
+ typeLines.push(`export type ${unionName} = ${unionMembers}`);
54
+ typeLines.push('');
55
+ }
56
+ const body = typeLines.join('\n');
57
+ return [CODEGEN_HEADER, '', body].join('\n');
58
+ }
59
+ //# sourceMappingURL=emit-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-errors.js","sourceRoot":"","sources":["../../../src/codegen/emit-errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,175 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { emitErrorsFile } from './emit-errors.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Fixtures
5
+ // ---------------------------------------------------------------------------
6
+ const procedureErrorDoc = {
7
+ name: 'ProcedureError',
8
+ statusCode: 500,
9
+ description: 'An error thrown from within a procedure handler via ctx.error().',
10
+ schema: {
11
+ type: 'object',
12
+ properties: {
13
+ name: { type: 'string', const: 'ProcedureError' },
14
+ procedureName: { type: 'string' },
15
+ message: { type: 'string' },
16
+ meta: { type: 'object' },
17
+ },
18
+ required: ['name', 'procedureName', 'message'],
19
+ },
20
+ };
21
+ const validationErrorDoc = {
22
+ name: 'ProcedureValidationError',
23
+ statusCode: 400,
24
+ description: 'Schema validation failed for the procedure input parameters.',
25
+ schema: {
26
+ type: 'object',
27
+ properties: {
28
+ name: { type: 'string', const: 'ProcedureValidationError' },
29
+ procedureName: { type: 'string' },
30
+ message: { type: 'string' },
31
+ },
32
+ required: ['name', 'procedureName', 'message'],
33
+ },
34
+ };
35
+ const errorDocWithoutSchema = {
36
+ name: 'UnknownError',
37
+ statusCode: 503,
38
+ description: 'An unknown error occurred.',
39
+ // no schema
40
+ };
41
+ // ---------------------------------------------------------------------------
42
+ // Tests
43
+ // ---------------------------------------------------------------------------
44
+ describe('emitErrorsFile', () => {
45
+ it('generates types for errors with schemas', async () => {
46
+ const result = await emitErrorsFile([procedureErrorDoc, validationErrorDoc]);
47
+ expect(result).toBeDefined();
48
+ expect(result).toContain('export type ProcedureError =');
49
+ expect(result).toContain('export type ProcedureValidationError =');
50
+ });
51
+ it('generates ProcedureErrorUnion discriminated union', async () => {
52
+ const result = await emitErrorsFile([procedureErrorDoc, validationErrorDoc]);
53
+ expect(result).toBeDefined();
54
+ expect(result).toContain('export type ProcedureErrorUnion = ProcedureError | ProcedureValidationError');
55
+ });
56
+ it('includes JSDoc with statusCode and description', async () => {
57
+ const result = await emitErrorsFile([procedureErrorDoc]);
58
+ expect(result).toBeDefined();
59
+ expect(result).toContain('/** An error thrown from within a procedure handler via ctx.error(). (HTTP 500) */');
60
+ });
61
+ it('includes JSDoc before the type declaration', async () => {
62
+ const result = await emitErrorsFile([procedureErrorDoc]);
63
+ expect(result).toBeDefined();
64
+ const jsdocIdx = result.indexOf('/** An error thrown from within a procedure handler via ctx.error().');
65
+ const typeIdx = result.indexOf('export type ProcedureError =');
66
+ expect(jsdocIdx).toBeLessThan(typeIdx);
67
+ });
68
+ it('includes the auto-generated header comment', async () => {
69
+ const result = await emitErrorsFile([procedureErrorDoc]);
70
+ expect(result).toBeDefined();
71
+ expect(result).toContain('// Auto-generated by ts-procedures-codegen — do not edit');
72
+ });
73
+ it('returns undefined when no errors have schemas', async () => {
74
+ const result = await emitErrorsFile([errorDocWithoutSchema]);
75
+ expect(result).toBeUndefined();
76
+ });
77
+ it('returns undefined for empty errors array', async () => {
78
+ const result = await emitErrorsFile([]);
79
+ expect(result).toBeUndefined();
80
+ });
81
+ it('skips errors without schema, includes those with schema', async () => {
82
+ const result = await emitErrorsFile([procedureErrorDoc, errorDocWithoutSchema, validationErrorDoc]);
83
+ expect(result).toBeDefined();
84
+ expect(result).toContain('export type ProcedureError =');
85
+ expect(result).toContain('export type ProcedureValidationError =');
86
+ // UnknownError has no schema, so it should not appear as a type
87
+ expect(result).not.toContain('export type UnknownError =');
88
+ // But the union should only include the ones with schemas
89
+ expect(result).toContain('ProcedureError | ProcedureValidationError');
90
+ expect(result).not.toContain('UnknownError');
91
+ });
92
+ it('union type has single type when only one error has schema', async () => {
93
+ const result = await emitErrorsFile([procedureErrorDoc]);
94
+ expect(result).toBeDefined();
95
+ expect(result).toContain('export type ProcedureErrorUnion = ProcedureError');
96
+ });
97
+ it('union type does not include errros without schemas', async () => {
98
+ const result = await emitErrorsFile([procedureErrorDoc, errorDocWithoutSchema]);
99
+ expect(result).toBeDefined();
100
+ expect(result).not.toContain('UnknownError');
101
+ expect(result).toContain('export type ProcedureErrorUnion = ProcedureError');
102
+ });
103
+ it('respects ajscOpts passed to jsonSchemaToTypeString', async () => {
104
+ // Just verify it does not crash when options are passed — behavior is tested in emit-types.test.ts
105
+ const result = await emitErrorsFile([procedureErrorDoc], { ajsc: { enumStyle: 'union' } });
106
+ expect(result).toBeDefined();
107
+ expect(result).toContain('export type ProcedureError =');
108
+ });
109
+ describe('serviceName', () => {
110
+ it('uses Errors namespace by default', async () => {
111
+ const result = await emitErrorsFile([procedureErrorDoc, validationErrorDoc], { namespaceTypes: true });
112
+ expect(result).toContain('export namespace Errors {');
113
+ });
114
+ it('prefixes namespace with serviceName when provided', async () => {
115
+ const result = await emitErrorsFile([procedureErrorDoc, validationErrorDoc], { namespaceTypes: true, serviceName: 'Auth' });
116
+ expect(result).toContain('export namespace AuthErrors {');
117
+ expect(result).not.toContain('export namespace Errors {');
118
+ });
119
+ it('PascalCases a kebab-case serviceName for namespace', async () => {
120
+ const result = await emitErrorsFile([procedureErrorDoc], { namespaceTypes: true, serviceName: 'user-service' });
121
+ expect(result).toContain('export namespace UserServiceErrors {');
122
+ });
123
+ it('does not affect namespace when namespaceTypes is false', async () => {
124
+ const result = await emitErrorsFile([procedureErrorDoc], { namespaceTypes: false, serviceName: 'Auth' });
125
+ expect(result).toBeDefined();
126
+ expect(result).not.toContain('namespace');
127
+ });
128
+ it('prefixes ProcedureErrorUnion in flat mode when serviceName is set', async () => {
129
+ const result = await emitErrorsFile([procedureErrorDoc, validationErrorDoc], { namespaceTypes: false, serviceName: 'Auth' });
130
+ expect(result).toBeDefined();
131
+ expect(result).toContain('export type AuthProcedureErrorUnion = ProcedureError | ProcedureValidationError');
132
+ expect(result).not.toContain('export type ProcedureErrorUnion =');
133
+ });
134
+ it('prefixes ProcedureErrorUnion inside namespace when serviceName is set', async () => {
135
+ const result = await emitErrorsFile([procedureErrorDoc], { namespaceTypes: true, serviceName: 'Auth' });
136
+ expect(result).toBeDefined();
137
+ expect(result).toContain('AuthProcedureErrorUnion');
138
+ expect(result).not.toMatch(/\bexport type ProcedureErrorUnion\b/);
139
+ });
140
+ it('leaves ProcedureErrorUnion unprefixed when no serviceName', async () => {
141
+ const result = await emitErrorsFile([procedureErrorDoc], { namespaceTypes: false });
142
+ expect(result).toBeDefined();
143
+ expect(result).toContain('export type ProcedureErrorUnion = ProcedureError');
144
+ });
145
+ });
146
+ describe('namespaceTypes', () => {
147
+ it('wraps error types in export namespace Errors', async () => {
148
+ const result = await emitErrorsFile([procedureErrorDoc, validationErrorDoc], { namespaceTypes: true });
149
+ expect(result).toBeDefined();
150
+ expect(result).toContain('export namespace Errors {');
151
+ expect(result).toContain('export type ProcedureError =');
152
+ expect(result).toContain('export type ProcedureValidationError =');
153
+ });
154
+ it('places union inside the namespace', async () => {
155
+ const result = await emitErrorsFile([procedureErrorDoc, validationErrorDoc], { namespaceTypes: true });
156
+ expect(result).toBeDefined();
157
+ expect(result).toContain('export type ProcedureErrorUnion = ProcedureError | ProcedureValidationError');
158
+ // Union should be inside the namespace (indented)
159
+ const lines = result.split('\n');
160
+ const unionLine = lines.find((l) => l.includes('ProcedureErrorUnion'));
161
+ expect(unionLine).toMatch(/^\s+export type ProcedureErrorUnion/);
162
+ });
163
+ it('includes JSDoc inside namespace', async () => {
164
+ const result = await emitErrorsFile([procedureErrorDoc], { namespaceTypes: true });
165
+ expect(result).toBeDefined();
166
+ expect(result).toContain('(HTTP 500)');
167
+ });
168
+ it('flat mode does not wrap in namespace', async () => {
169
+ const result = await emitErrorsFile([procedureErrorDoc], { namespaceTypes: false });
170
+ expect(result).toBeDefined();
171
+ expect(result).not.toContain('export namespace Errors');
172
+ });
173
+ });
174
+ });
175
+ //# sourceMappingURL=emit-errors.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-errors.test.js","sourceRoot":"","sources":["../../../src/codegen/emit-errors.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ScopeGroup } from './group-routes.js';
2
+ export interface EmitIndexOptions {
3
+ clientImportPath?: string;
4
+ hasErrors?: boolean;
5
+ serviceName?: string;
6
+ }
7
+ /**
8
+ * Generates a barrel index file that re-exports all scope files and provides
9
+ * a factory function (`createScopeBindings`, or `create${ServiceName}Bindings`
10
+ * when `serviceName` is set).
11
+ */
12
+ export declare function emitIndexFile(groups: ScopeGroup[], options?: EmitIndexOptions): string;
@@ -0,0 +1,41 @@
1
+ import { CODEGEN_HEADER } from './constants.js';
2
+ import { toPascalCase } from './naming.js';
3
+ /** Derives the bind function name from a camelCase scope identifier. */
4
+ function bindFunctionName(camelCase) {
5
+ return `bind${toPascalCase(camelCase)}Scope`;
6
+ }
7
+ /**
8
+ * Generates a barrel index file that re-exports all scope files and provides
9
+ * a factory function (`createScopeBindings`, or `create${ServiceName}Bindings`
10
+ * when `serviceName` is set).
11
+ */
12
+ export function emitIndexFile(groups, options) {
13
+ const { clientImportPath = 'ts-procedures/client', hasErrors = false, serviceName } = options ?? {};
14
+ const factoryName = serviceName ? `create${toPascalCase(serviceName)}Bindings` : 'createScopeBindings';
15
+ const bindImports = groups
16
+ .map((g) => `import { ${bindFunctionName(g.camelCase)} } from './${g.scopeKey}'`)
17
+ .join('\n');
18
+ const scopeReExports = groups
19
+ .map((g) => `export * from './${g.scopeKey}'`)
20
+ .join('\n');
21
+ const errorsReExport = hasErrors ? `export * from './_errors'` : '';
22
+ const reExports = [scopeReExports, errorsReExport].filter(Boolean).join('\n');
23
+ const scopeBindings = groups
24
+ .map((g) => ` ${g.camelCase}: ${bindFunctionName(g.camelCase)}(client),`)
25
+ .join('\n');
26
+ return [
27
+ CODEGEN_HEADER,
28
+ `import type { ClientInstance } from '${clientImportPath}'`,
29
+ bindImports,
30
+ '',
31
+ reExports,
32
+ '',
33
+ `export function ${factoryName}(client: ClientInstance) {`,
34
+ ' return {',
35
+ scopeBindings,
36
+ ' }',
37
+ '}',
38
+ '',
39
+ ].join('\n');
40
+ }
41
+ //# sourceMappingURL=emit-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-index.js","sourceRoot":"","sources":["../../../src/codegen/emit-index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,wEAAwE;AACxE,SAAS,gBAAgB,CAAC,SAAiB;IACzC,OAAO,OAAO,YAAY,CAAC,SAAS,CAAC,OAAO,CAAA;AAC9C,CAAC;AAYD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,MAAoB,EAAE,OAA0B;IAC5E,MAAM,EAAE,gBAAgB,GAAG,sBAAsB,EAAE,SAAS,GAAG,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IACnG,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,YAAY,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,qBAAqB,CAAA;IACtG,MAAM,WAAW,GAAG,MAAM;SACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,QAAQ,GAAG,CAAC;SAChF,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,cAAc,GAAG,MAAM;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,QAAQ,GAAG,CAAC;SAC7C,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,cAAc,GAAG,SAAS,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,CAAA;IAEnE,MAAM,SAAS,GAAG,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE7E,MAAM,aAAa,GAAG,MAAM;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC;SAC3E,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,OAAO;QACL,cAAc;QACd,wCAAwC,gBAAgB,GAAG;QAC3D,WAAW;QACX,EAAE;QACF,SAAS;QACT,EAAE;QACF,mBAAmB,WAAW,4BAA4B;QAC1D,YAAY;QACZ,aAAa;QACb,KAAK;QACL,GAAG;QACH,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,106 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { emitIndexFile } from './emit-index.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Fixtures
5
+ // ---------------------------------------------------------------------------
6
+ const usersGroup = {
7
+ scopeKey: 'users',
8
+ camelCase: 'users',
9
+ routes: [],
10
+ };
11
+ const billingGroup = {
12
+ scopeKey: 'billing',
13
+ camelCase: 'billing',
14
+ routes: [],
15
+ };
16
+ const adminUsersGroup = {
17
+ scopeKey: 'admin-users',
18
+ camelCase: 'adminUsers',
19
+ routes: [],
20
+ };
21
+ // ---------------------------------------------------------------------------
22
+ // Tests
23
+ // ---------------------------------------------------------------------------
24
+ describe('emitIndexFile', () => {
25
+ it('includes the auto-generated header comment', () => {
26
+ const output = emitIndexFile([usersGroup]);
27
+ expect(output).toContain('// Auto-generated by ts-procedures-codegen — do not edit');
28
+ });
29
+ it('imports ClientInstance from ts-procedures/client', () => {
30
+ const output = emitIndexFile([usersGroup]);
31
+ expect(output).toContain("import type { ClientInstance } from 'ts-procedures/client'");
32
+ });
33
+ it('imports each bind function using the camelCase scope name', () => {
34
+ const output = emitIndexFile([usersGroup, billingGroup]);
35
+ expect(output).toContain("import { bindUsersScope } from './users'");
36
+ expect(output).toContain("import { bindBillingScope } from './billing'");
37
+ });
38
+ it('re-exports from each scope file', () => {
39
+ const output = emitIndexFile([usersGroup, billingGroup]);
40
+ expect(output).toContain("export * from './users'");
41
+ expect(output).toContain("export * from './billing'");
42
+ });
43
+ it('generates createScopeBindings with correct scope property names', () => {
44
+ const output = emitIndexFile([usersGroup, billingGroup]);
45
+ expect(output).toContain('export function createScopeBindings(client: ClientInstance)');
46
+ expect(output).toContain('users: bindUsersScope(client)');
47
+ expect(output).toContain('billing: bindBillingScope(client)');
48
+ });
49
+ it('uses camelCase as the property key in createScopeBindings', () => {
50
+ const output = emitIndexFile([adminUsersGroup]);
51
+ expect(output).toContain('adminUsers: bindAdminUsersScope(client)');
52
+ });
53
+ it('uses the scopeKey as the import path (not camelCase)', () => {
54
+ const output = emitIndexFile([adminUsersGroup]);
55
+ expect(output).toContain("import { bindAdminUsersScope } from './admin-users'");
56
+ expect(output).toContain("export * from './admin-users'");
57
+ });
58
+ it('handles a single scope group', () => {
59
+ const output = emitIndexFile([usersGroup]);
60
+ expect(output).toContain('bindUsersScope');
61
+ expect(output).toContain('users: bindUsersScope(client)');
62
+ });
63
+ it('places imports before re-exports before createScopeBindings', () => {
64
+ const output = emitIndexFile([usersGroup, billingGroup]);
65
+ const importIdx = output.indexOf("import { bindUsersScope }");
66
+ const reExportIdx = output.indexOf("export * from './users'");
67
+ const bindIdx = output.indexOf('export function createScopeBindings');
68
+ expect(importIdx).toBeLessThan(reExportIdx);
69
+ expect(reExportIdx).toBeLessThan(bindIdx);
70
+ });
71
+ describe('serviceName', () => {
72
+ it('uses createScopeBindings when serviceName is not provided', () => {
73
+ const output = emitIndexFile([usersGroup]);
74
+ expect(output).toContain('export function createScopeBindings(client: ClientInstance)');
75
+ });
76
+ it('uses create${ServiceName}Bindings when serviceName is provided', () => {
77
+ const output = emitIndexFile([usersGroup], { serviceName: 'Auth' });
78
+ expect(output).toContain('export function createAuthBindings(client: ClientInstance)');
79
+ expect(output).not.toContain('createScopeBindings');
80
+ });
81
+ it('PascalCases a kebab-case serviceName', () => {
82
+ const output = emitIndexFile([usersGroup], { serviceName: 'auth-service' });
83
+ expect(output).toContain('export function createAuthServiceBindings(client: ClientInstance)');
84
+ });
85
+ it('PascalCases an underscore-separated serviceName', () => {
86
+ const output = emitIndexFile([usersGroup], { serviceName: 'users_api' });
87
+ expect(output).toContain('export function createUsersApiBindings(client: ClientInstance)');
88
+ });
89
+ it('preserves already-PascalCased serviceName', () => {
90
+ const output = emitIndexFile([usersGroup, billingGroup], { serviceName: 'UsersApi' });
91
+ expect(output).toContain('export function createUsersApiBindings(client: ClientInstance)');
92
+ });
93
+ });
94
+ describe('clientImportPath', () => {
95
+ it('uses custom clientImportPath in import statement', () => {
96
+ const output = emitIndexFile([usersGroup], { clientImportPath: '@my-app/client' });
97
+ expect(output).toContain("import type { ClientInstance } from '@my-app/client'");
98
+ expect(output).not.toContain("from 'ts-procedures/client'");
99
+ });
100
+ it('defaults to ts-procedures/client when not specified', () => {
101
+ const output = emitIndexFile([usersGroup]);
102
+ expect(output).toContain("import type { ClientInstance } from 'ts-procedures/client'");
103
+ });
104
+ });
105
+ });
106
+ //# sourceMappingURL=emit-index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-index.test.js","sourceRoot":"","sources":["../../../src/codegen/emit-index.test.ts"],"names":[],"mappings":"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"}