ts-procedures 5.10.0 → 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 (233) hide show
  1. package/agent_config/bin/postinstall.mjs +3 -3
  2. package/agent_config/bin/setup.mjs +22 -11
  3. package/agent_config/claude-code/agents/ts-procedures-architect.md +2 -2
  4. package/agent_config/claude-code/skills/{guide → ts-procedures}/SKILL.md +1 -1
  5. package/agent_config/claude-code/skills/{review → ts-procedures-review}/SKILL.md +3 -3
  6. package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/SKILL.md +2 -2
  7. package/agent_config/lib/install-claude.mjs +35 -87
  8. package/build/src/client/call.d.ts +14 -0
  9. package/build/src/client/call.js +47 -0
  10. package/build/src/client/call.js.map +1 -0
  11. package/build/src/client/call.test.d.ts +1 -0
  12. package/build/src/client/call.test.js +124 -0
  13. package/build/src/client/call.test.js.map +1 -0
  14. package/build/src/client/errors.d.ts +25 -0
  15. package/build/src/client/errors.js +33 -0
  16. package/build/src/client/errors.js.map +1 -0
  17. package/build/src/client/errors.test.d.ts +1 -0
  18. package/build/src/client/errors.test.js +41 -0
  19. package/build/src/client/errors.test.js.map +1 -0
  20. package/build/src/client/fetch-adapter.d.ts +12 -0
  21. package/build/src/client/fetch-adapter.js +156 -0
  22. package/build/src/client/fetch-adapter.js.map +1 -0
  23. package/build/src/client/fetch-adapter.test.d.ts +1 -0
  24. package/build/src/client/fetch-adapter.test.js +271 -0
  25. package/build/src/client/fetch-adapter.test.js.map +1 -0
  26. package/build/src/client/hooks.d.ts +17 -0
  27. package/build/src/client/hooks.js +40 -0
  28. package/build/src/client/hooks.js.map +1 -0
  29. package/build/src/client/hooks.test.d.ts +1 -0
  30. package/build/src/client/hooks.test.js +163 -0
  31. package/build/src/client/hooks.test.js.map +1 -0
  32. package/build/src/client/index.d.ts +22 -0
  33. package/build/src/client/index.js +67 -0
  34. package/build/src/client/index.js.map +1 -0
  35. package/build/src/client/index.test.d.ts +1 -0
  36. package/build/src/client/index.test.js +231 -0
  37. package/build/src/client/index.test.js.map +1 -0
  38. package/build/src/client/request-builder.d.ts +13 -0
  39. package/build/src/client/request-builder.js +53 -0
  40. package/build/src/client/request-builder.js.map +1 -0
  41. package/build/src/client/request-builder.test.d.ts +1 -0
  42. package/build/src/client/request-builder.test.js +160 -0
  43. package/build/src/client/request-builder.test.js.map +1 -0
  44. package/build/src/client/stream.d.ts +27 -0
  45. package/build/src/client/stream.js +118 -0
  46. package/build/src/client/stream.js.map +1 -0
  47. package/build/src/client/stream.test.d.ts +1 -0
  48. package/build/src/client/stream.test.js +228 -0
  49. package/build/src/client/stream.test.js.map +1 -0
  50. package/build/src/client/types.d.ts +78 -0
  51. package/build/src/client/types.js +3 -0
  52. package/build/src/client/types.js.map +1 -0
  53. package/build/src/codegen/bin/cli.d.ts +45 -0
  54. package/build/src/codegen/bin/cli.js +246 -0
  55. package/build/src/codegen/bin/cli.js.map +1 -0
  56. package/build/src/codegen/bin/cli.test.d.ts +1 -0
  57. package/build/src/codegen/bin/cli.test.js +220 -0
  58. package/build/src/codegen/bin/cli.test.js.map +1 -0
  59. package/build/src/codegen/constants.d.ts +1 -0
  60. package/build/src/codegen/constants.js +2 -0
  61. package/build/src/codegen/constants.js.map +1 -0
  62. package/build/src/codegen/e2e.test.d.ts +1 -0
  63. package/build/src/codegen/e2e.test.js +464 -0
  64. package/build/src/codegen/e2e.test.js.map +1 -0
  65. package/build/src/codegen/emit-client-runtime.d.ts +9 -0
  66. package/build/src/codegen/emit-client-runtime.js +99 -0
  67. package/build/src/codegen/emit-client-runtime.js.map +1 -0
  68. package/build/src/codegen/emit-client-runtime.test.d.ts +1 -0
  69. package/build/src/codegen/emit-client-runtime.test.js +78 -0
  70. package/build/src/codegen/emit-client-runtime.test.js.map +1 -0
  71. package/build/src/codegen/emit-client-types.d.ts +8 -0
  72. package/build/src/codegen/emit-client-types.js +25 -0
  73. package/build/src/codegen/emit-client-types.js.map +1 -0
  74. package/build/src/codegen/emit-client-types.test.d.ts +1 -0
  75. package/build/src/codegen/emit-client-types.test.js +33 -0
  76. package/build/src/codegen/emit-client-types.test.js.map +1 -0
  77. package/build/src/codegen/emit-errors.d.ts +19 -0
  78. package/build/src/codegen/emit-errors.js +59 -0
  79. package/build/src/codegen/emit-errors.js.map +1 -0
  80. package/build/src/codegen/emit-errors.test.d.ts +1 -0
  81. package/build/src/codegen/emit-errors.test.js +175 -0
  82. package/build/src/codegen/emit-errors.test.js.map +1 -0
  83. package/build/src/codegen/emit-index.d.ts +12 -0
  84. package/build/src/codegen/emit-index.js +41 -0
  85. package/build/src/codegen/emit-index.js.map +1 -0
  86. package/build/src/codegen/emit-index.test.d.ts +1 -0
  87. package/build/src/codegen/emit-index.test.js +106 -0
  88. package/build/src/codegen/emit-index.test.js.map +1 -0
  89. package/build/src/codegen/emit-scope.d.ts +15 -0
  90. package/build/src/codegen/emit-scope.js +299 -0
  91. package/build/src/codegen/emit-scope.js.map +1 -0
  92. package/build/src/codegen/emit-scope.test.d.ts +1 -0
  93. package/build/src/codegen/emit-scope.test.js +559 -0
  94. package/build/src/codegen/emit-scope.test.js.map +1 -0
  95. package/build/src/codegen/emit-types.d.ts +43 -0
  96. package/build/src/codegen/emit-types.js +111 -0
  97. package/build/src/codegen/emit-types.js.map +1 -0
  98. package/build/src/codegen/emit-types.test.d.ts +1 -0
  99. package/build/src/codegen/emit-types.test.js +184 -0
  100. package/build/src/codegen/emit-types.test.js.map +1 -0
  101. package/build/src/codegen/group-routes.d.ts +23 -0
  102. package/build/src/codegen/group-routes.js +46 -0
  103. package/build/src/codegen/group-routes.js.map +1 -0
  104. package/build/src/codegen/group-routes.test.d.ts +1 -0
  105. package/build/src/codegen/group-routes.test.js +131 -0
  106. package/build/src/codegen/group-routes.test.js.map +1 -0
  107. package/build/src/codegen/index.d.ts +15 -0
  108. package/build/src/codegen/index.js +16 -0
  109. package/build/src/codegen/index.js.map +1 -0
  110. package/build/src/codegen/naming.d.ts +7 -0
  111. package/build/src/codegen/naming.js +21 -0
  112. package/build/src/codegen/naming.js.map +1 -0
  113. package/build/src/codegen/naming.test.d.ts +1 -0
  114. package/build/src/codegen/naming.test.js +40 -0
  115. package/build/src/codegen/naming.test.js.map +1 -0
  116. package/build/src/codegen/pipeline.d.ts +17 -0
  117. package/build/src/codegen/pipeline.js +78 -0
  118. package/build/src/codegen/pipeline.js.map +1 -0
  119. package/build/src/codegen/pipeline.test.d.ts +1 -0
  120. package/build/src/codegen/pipeline.test.js +269 -0
  121. package/build/src/codegen/pipeline.test.js.map +1 -0
  122. package/build/src/codegen/resolve-envelope.d.ts +7 -0
  123. package/build/src/codegen/resolve-envelope.js +46 -0
  124. package/build/src/codegen/resolve-envelope.js.map +1 -0
  125. package/build/src/codegen/resolve-envelope.test.d.ts +1 -0
  126. package/build/src/codegen/resolve-envelope.test.js +69 -0
  127. package/build/src/codegen/resolve-envelope.test.js.map +1 -0
  128. package/build/src/errors.d.ts +33 -0
  129. package/build/src/errors.js +91 -0
  130. package/build/src/errors.js.map +1 -0
  131. package/build/src/errors.test.d.ts +1 -0
  132. package/build/src/errors.test.js +122 -0
  133. package/build/src/errors.test.js.map +1 -0
  134. package/build/src/exports.d.ts +7 -0
  135. package/build/src/exports.js +8 -0
  136. package/build/src/exports.js.map +1 -0
  137. package/build/src/implementations/http/doc-registry.d.ts +12 -0
  138. package/build/src/implementations/http/doc-registry.js +114 -0
  139. package/build/src/implementations/http/doc-registry.js.map +1 -0
  140. package/build/src/implementations/http/doc-registry.test.d.ts +1 -0
  141. package/build/src/implementations/http/doc-registry.test.js +347 -0
  142. package/build/src/implementations/http/doc-registry.test.js.map +1 -0
  143. package/build/src/implementations/http/express-rpc/index.d.ts +94 -0
  144. package/build/src/implementations/http/express-rpc/index.js +185 -0
  145. package/build/src/implementations/http/express-rpc/index.js.map +1 -0
  146. package/build/src/implementations/http/express-rpc/index.test.d.ts +1 -0
  147. package/build/src/implementations/http/express-rpc/index.test.js +684 -0
  148. package/build/src/implementations/http/express-rpc/index.test.js.map +1 -0
  149. package/build/src/implementations/http/express-rpc/types.d.ts +11 -0
  150. package/build/src/implementations/http/express-rpc/types.js +2 -0
  151. package/build/src/implementations/http/express-rpc/types.js.map +1 -0
  152. package/build/src/implementations/http/hono-api/index.d.ts +102 -0
  153. package/build/src/implementations/http/hono-api/index.js +341 -0
  154. package/build/src/implementations/http/hono-api/index.js.map +1 -0
  155. package/build/src/implementations/http/hono-api/index.test.d.ts +1 -0
  156. package/build/src/implementations/http/hono-api/index.test.js +992 -0
  157. package/build/src/implementations/http/hono-api/index.test.js.map +1 -0
  158. package/build/src/implementations/http/hono-api/types.d.ts +13 -0
  159. package/build/src/implementations/http/hono-api/types.js +2 -0
  160. package/build/src/implementations/http/hono-api/types.js.map +1 -0
  161. package/build/src/implementations/http/hono-rpc/index.d.ts +92 -0
  162. package/build/src/implementations/http/hono-rpc/index.js +161 -0
  163. package/build/src/implementations/http/hono-rpc/index.js.map +1 -0
  164. package/build/src/implementations/http/hono-rpc/index.test.d.ts +1 -0
  165. package/build/src/implementations/http/hono-rpc/index.test.js +803 -0
  166. package/build/src/implementations/http/hono-rpc/index.test.js.map +1 -0
  167. package/build/src/implementations/http/hono-rpc/types.d.ts +11 -0
  168. package/build/src/implementations/http/hono-rpc/types.js +2 -0
  169. package/build/src/implementations/http/hono-rpc/types.js.map +1 -0
  170. package/build/src/implementations/http/hono-stream/index.d.ts +120 -0
  171. package/build/src/implementations/http/hono-stream/index.js +309 -0
  172. package/build/src/implementations/http/hono-stream/index.js.map +1 -0
  173. package/build/src/implementations/http/hono-stream/index.test.d.ts +1 -0
  174. package/build/src/implementations/http/hono-stream/index.test.js +1356 -0
  175. package/build/src/implementations/http/hono-stream/index.test.js.map +1 -0
  176. package/build/src/implementations/http/hono-stream/types.d.ts +15 -0
  177. package/build/src/implementations/http/hono-stream/types.js +2 -0
  178. package/build/src/implementations/http/hono-stream/types.js.map +1 -0
  179. package/build/src/implementations/types.d.ts +142 -0
  180. package/build/src/implementations/types.js +2 -0
  181. package/build/src/implementations/types.js.map +1 -0
  182. package/build/src/index.d.ts +165 -0
  183. package/build/src/index.js +253 -0
  184. package/build/src/index.js.map +1 -0
  185. package/build/src/index.test.d.ts +1 -0
  186. package/build/src/index.test.js +890 -0
  187. package/build/src/index.test.js.map +1 -0
  188. package/build/src/schema/compute-schema.d.ts +35 -0
  189. package/build/src/schema/compute-schema.js +41 -0
  190. package/build/src/schema/compute-schema.js.map +1 -0
  191. package/build/src/schema/compute-schema.test.d.ts +1 -0
  192. package/build/src/schema/compute-schema.test.js +107 -0
  193. package/build/src/schema/compute-schema.test.js.map +1 -0
  194. package/build/src/schema/extract-json-schema.d.ts +2 -0
  195. package/build/src/schema/extract-json-schema.js +12 -0
  196. package/build/src/schema/extract-json-schema.js.map +1 -0
  197. package/build/src/schema/extract-json-schema.test.d.ts +1 -0
  198. package/build/src/schema/extract-json-schema.test.js +23 -0
  199. package/build/src/schema/extract-json-schema.test.js.map +1 -0
  200. package/build/src/schema/parser.d.ts +28 -0
  201. package/build/src/schema/parser.js +170 -0
  202. package/build/src/schema/parser.js.map +1 -0
  203. package/build/src/schema/parser.test.d.ts +1 -0
  204. package/build/src/schema/parser.test.js +120 -0
  205. package/build/src/schema/parser.test.js.map +1 -0
  206. package/build/src/schema/resolve-schema-lib.d.ts +12 -0
  207. package/build/src/schema/resolve-schema-lib.js +11 -0
  208. package/build/src/schema/resolve-schema-lib.js.map +1 -0
  209. package/build/src/schema/resolve-schema-lib.test.d.ts +1 -0
  210. package/build/src/schema/resolve-schema-lib.test.js +17 -0
  211. package/build/src/schema/resolve-schema-lib.test.js.map +1 -0
  212. package/build/src/schema/types.d.ts +8 -0
  213. package/build/src/schema/types.js +2 -0
  214. package/build/src/schema/types.js.map +1 -0
  215. package/build/src/stack-utils.d.ts +25 -0
  216. package/build/src/stack-utils.js +95 -0
  217. package/build/src/stack-utils.js.map +1 -0
  218. package/build/src/stack-utils.test.d.ts +1 -0
  219. package/build/src/stack-utils.test.js +80 -0
  220. package/build/src/stack-utils.test.js.map +1 -0
  221. package/docs/ai-agent-setup.md +7 -6
  222. package/package.json +1 -1
  223. /package/agent_config/claude-code/skills/{guide → ts-procedures}/anti-patterns.md +0 -0
  224. /package/agent_config/claude-code/skills/{guide → ts-procedures}/api-reference.md +0 -0
  225. /package/agent_config/claude-code/skills/{guide → ts-procedures}/patterns.md +0 -0
  226. /package/agent_config/claude-code/skills/{review → ts-procedures-review}/checklist.md +0 -0
  227. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/client.md +0 -0
  228. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/express-rpc.md +0 -0
  229. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/hono-api.md +0 -0
  230. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/hono-rpc.md +0 -0
  231. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/hono-stream.md +0 -0
  232. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/procedure.md +0 -0
  233. /package/agent_config/claude-code/skills/{scaffold → ts-procedures-scaffold}/templates/stream-procedure.md +0 -0
@@ -0,0 +1,111 @@
1
+ let ajscValidated = false;
2
+ async function validateAjscFormat() {
3
+ if (ajscValidated)
4
+ return;
5
+ ajscValidated = true;
6
+ const { TypescriptConverter } = await import('ajsc');
7
+ const probe = new TypescriptConverter({ type: 'string' }, { inlineTypes: true });
8
+ const probeCode = probe.code.trim();
9
+ if (probeCode !== 'string') {
10
+ console.warn(`[ts-procedures-codegen] ajsc output format may have changed. Expected "string" for { type: "string" }, got: "${probeCode}"`);
11
+ }
12
+ }
13
+ async function resolveTypeBody(schema, options) {
14
+ await validateAjscFormat();
15
+ const { TypescriptConverter } = await import('ajsc');
16
+ const converter = new TypescriptConverter(schema, {
17
+ ...options,
18
+ inlineTypes: true,
19
+ });
20
+ let code = converter.code.trim();
21
+ if (!code) {
22
+ throw new Error(`[ts-procedures-codegen] ajsc produced empty output. Schema: ${JSON.stringify(schema)}`);
23
+ }
24
+ // Strip any 'export type X = ' or 'type X = ' prefix ajsc might add
25
+ code = code.replace(/^(?:export\s+)?type\s+\w+\s*=\s*/, '');
26
+ // Remove trailing semicolons and newlines
27
+ code = code.replace(/;\s*$/, '').trim();
28
+ return code;
29
+ }
30
+ /**
31
+ * Converts a JSON Schema to a TypeScript type string using ajsc.
32
+ *
33
+ * Returns `export type ${typeName} = ${code}` where code is the inline type
34
+ * body from TypescriptConverter with inlineTypes: true.
35
+ *
36
+ * Returns undefined for undefined or null schema.
37
+ */
38
+ export async function jsonSchemaToTypeString(typeName, schema, options) {
39
+ if (schema == null)
40
+ return undefined;
41
+ const code = await resolveTypeBody(schema, options);
42
+ return `export type ${typeName} = ${code}`;
43
+ }
44
+ /**
45
+ * Converts a JSON Schema to a bare TypeScript type body using ajsc.
46
+ *
47
+ * Returns just the type literal (e.g., `{ id: string; }`) without any
48
+ * `export type Name =` wrapper. Used by flat mode in emit-scope.
49
+ *
50
+ * Returns undefined for undefined or null schema.
51
+ */
52
+ export async function jsonSchemaToTypeBody(schema, options) {
53
+ if (schema == null)
54
+ return undefined;
55
+ return resolveTypeBody(schema, options);
56
+ }
57
+ /**
58
+ * Converts a JSON Schema to extracted TypeScript types using ajsc with
59
+ * `inlineTypes: false`. This produces named sub-types (objects, enums) that
60
+ * are separated from the root type body.
61
+ *
62
+ * Used in namespace mode where sub-types live naturally inside the namespace
63
+ * and ajsc formatting options (enumStyle, depluralize, jsdoc, etc.) take effect.
64
+ *
65
+ * Returns undefined for undefined or null schema.
66
+ */
67
+ export async function jsonSchemaToExtractedTypes(schema, options) {
68
+ if (schema == null)
69
+ return undefined;
70
+ await validateAjscFormat();
71
+ const { TypescriptConverter } = await import('ajsc');
72
+ const converter = new TypescriptConverter(schema, {
73
+ ...options,
74
+ inlineTypes: false,
75
+ });
76
+ const code = converter.code.trim();
77
+ if (!code) {
78
+ throw new Error(`[ts-procedures-codegen] ajsc produced empty output. Schema: ${JSON.stringify(schema)}`);
79
+ }
80
+ // ajsc with inlineTypes: false produces blocks separated by blank lines:
81
+ // export enum Status { Active = "active" }
82
+ // export type Contact = { name: string; };
83
+ // export type Root = { status: Status; contacts: Array<Contact>; };
84
+ //
85
+ // The Root type is always the last declaration.
86
+ const blocks = code.split(/\n\n+/).map((b) => b.trim()).filter(Boolean);
87
+ const declarations = [];
88
+ let body = '';
89
+ for (const block of blocks) {
90
+ if (block.startsWith('export type Root')) {
91
+ // Strip "export type Root = " prefix and trailing ";"
92
+ body = block
93
+ .replace(/^export\s+type\s+Root\s*=\s*/, '')
94
+ .replace(/;\s*$/, '')
95
+ .trim();
96
+ }
97
+ else {
98
+ // Sub-type or enum declaration — remove trailing ";" for consistency
99
+ declarations.push(block.replace(/;\s*$/, ''));
100
+ }
101
+ }
102
+ if (!body) {
103
+ // Fallback: treat whole output as inline body
104
+ body = code
105
+ .replace(/^(?:export\s+)?type\s+\w+\s*=\s*/, '')
106
+ .replace(/;\s*$/, '')
107
+ .trim();
108
+ }
109
+ return { declarations, body };
110
+ }
111
+ //# sourceMappingURL=emit-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-types.js","sourceRoot":"","sources":["../../../src/codegen/emit-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,184 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { jsonSchemaToTypeString, jsonSchemaToTypeBody, jsonSchemaToExtractedTypes } from './emit-types.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Tests
5
+ // ---------------------------------------------------------------------------
6
+ describe('jsonSchemaToTypeString', () => {
7
+ it('converts a simple object schema with required fields', async () => {
8
+ const schema = {
9
+ type: 'object',
10
+ properties: {
11
+ id: { type: 'string' },
12
+ },
13
+ required: ['id'],
14
+ };
15
+ const result = await jsonSchemaToTypeString('MyType', schema);
16
+ expect(result).toBe('export type MyType = { id: string; }');
17
+ });
18
+ it('includes optional marker for non-required fields', async () => {
19
+ const schema = {
20
+ type: 'object',
21
+ properties: {
22
+ id: { type: 'string' },
23
+ name: { type: 'string' },
24
+ },
25
+ required: ['id'],
26
+ };
27
+ const result = await jsonSchemaToTypeString('User', schema);
28
+ expect(result).toBe('export type User = { id: string; name?: string; }');
29
+ });
30
+ it('converts a string enum schema', async () => {
31
+ const schema = {
32
+ type: 'string',
33
+ enum: ['a', 'b'],
34
+ };
35
+ const result = await jsonSchemaToTypeString('Status', schema);
36
+ expect(result).toBe('export type Status = "a" | "b"');
37
+ });
38
+ it('converts a plain string schema', async () => {
39
+ const schema = { type: 'string' };
40
+ const result = await jsonSchemaToTypeString('Id', schema);
41
+ expect(result).toBe('export type Id = string');
42
+ });
43
+ it('returns undefined for undefined schema', async () => {
44
+ const result = await jsonSchemaToTypeString('Missing', undefined);
45
+ expect(result).toBeUndefined();
46
+ });
47
+ it('uses the typeName in the export statement', async () => {
48
+ const schema = { type: 'number' };
49
+ const result = await jsonSchemaToTypeString('Count', schema);
50
+ expect(result).toMatch(/^export type Count = /);
51
+ });
52
+ it('handles already-clean inline output', async () => {
53
+ // Existing schemas still work — no regression
54
+ const schema = {
55
+ type: 'object',
56
+ properties: { id: { type: 'string' } },
57
+ required: ['id'],
58
+ };
59
+ const result = await jsonSchemaToTypeString('MyType', schema);
60
+ expect(result).toBe('export type MyType = { id: string; }');
61
+ });
62
+ it('returns undefined for null schema', async () => {
63
+ const result = await jsonSchemaToTypeString('Missing', null);
64
+ expect(result).toBeUndefined();
65
+ });
66
+ });
67
+ describe('jsonSchemaToTypeBody', () => {
68
+ it('returns bare type literal without export wrapper', async () => {
69
+ const schema = {
70
+ type: 'object',
71
+ properties: { id: { type: 'string' } },
72
+ required: ['id'],
73
+ };
74
+ const result = await jsonSchemaToTypeBody(schema);
75
+ expect(result).toBe('{ id: string; }');
76
+ });
77
+ it('returns undefined for undefined schema', async () => {
78
+ const result = await jsonSchemaToTypeBody(undefined);
79
+ expect(result).toBeUndefined();
80
+ });
81
+ it('returns plain type for scalar schema', async () => {
82
+ const result = await jsonSchemaToTypeBody({ type: 'string' });
83
+ expect(result).toBe('string');
84
+ });
85
+ it('returns union for enum schema', async () => {
86
+ const result = await jsonSchemaToTypeBody({ type: 'string', enum: ['a', 'b'] });
87
+ expect(result).toBe('"a" | "b"');
88
+ });
89
+ });
90
+ describe('jsonSchemaToExtractedTypes', () => {
91
+ it('returns undefined for undefined schema', async () => {
92
+ const result = await jsonSchemaToExtractedTypes(undefined);
93
+ expect(result).toBeUndefined();
94
+ });
95
+ it('extracts nested object types as declarations', async () => {
96
+ const schema = {
97
+ type: 'object',
98
+ properties: {
99
+ user: {
100
+ type: 'object',
101
+ properties: { name: { type: 'string' } },
102
+ required: ['name'],
103
+ },
104
+ },
105
+ required: ['user'],
106
+ };
107
+ const result = await jsonSchemaToExtractedTypes(schema);
108
+ expect(result).not.toBeUndefined();
109
+ expect(result.declarations.length).toBeGreaterThan(0);
110
+ expect(result.declarations.some((d) => d.includes('export type User'))).toBe(true);
111
+ expect(result.body).toContain('user: User');
112
+ });
113
+ it('returns empty declarations for flat schemas', async () => {
114
+ const schema = { type: 'string' };
115
+ const result = await jsonSchemaToExtractedTypes(schema);
116
+ expect(result).not.toBeUndefined();
117
+ expect(result.declarations).toEqual([]);
118
+ expect(result.body).toBe('string');
119
+ });
120
+ it('extracts enums with enumStyle: enum', async () => {
121
+ const schema = {
122
+ type: 'object',
123
+ properties: {
124
+ status: { type: 'string', enum: ['active', 'pending'] },
125
+ },
126
+ required: ['status'],
127
+ };
128
+ const result = await jsonSchemaToExtractedTypes(schema, { enumStyle: 'enum' });
129
+ expect(result).not.toBeUndefined();
130
+ expect(result.declarations.some((d) => d.includes('export enum Status'))).toBe(true);
131
+ expect(result.body).toContain('status: Status');
132
+ });
133
+ it('strips trailing semicolons from declarations', async () => {
134
+ const schema = {
135
+ type: 'object',
136
+ properties: {
137
+ item: {
138
+ type: 'object',
139
+ properties: { id: { type: 'string' } },
140
+ required: ['id'],
141
+ },
142
+ },
143
+ required: ['item'],
144
+ };
145
+ const result = await jsonSchemaToExtractedTypes(schema);
146
+ expect(result).not.toBeUndefined();
147
+ for (const decl of result.declarations) {
148
+ expect(decl.trimEnd()).not.toMatch(/;\s*$/);
149
+ }
150
+ });
151
+ it('body does not contain export type Root prefix', async () => {
152
+ const schema = {
153
+ type: 'object',
154
+ properties: { id: { type: 'string' } },
155
+ required: ['id'],
156
+ };
157
+ const result = await jsonSchemaToExtractedTypes(schema);
158
+ expect(result).not.toBeUndefined();
159
+ expect(result.body).not.toContain('export type Root');
160
+ expect(result.body).toContain('id: string');
161
+ });
162
+ });
163
+ describe('jsonSchemaToTypeString (prefix stripping)', () => {
164
+ it('strips "export type Root = " prefix and does not double-wrap', async () => {
165
+ vi.resetModules();
166
+ vi.doMock('ajsc', () => ({
167
+ TypescriptConverter: class {
168
+ code;
169
+ constructor(_schema, _opts) {
170
+ this.code = '\n\nexport type Root = { id: string; };\n';
171
+ }
172
+ },
173
+ }));
174
+ const { jsonSchemaToTypeString: fn } = await import('./emit-types.js');
175
+ const result = await fn('MyType', { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] });
176
+ // Should be the clean body, not double-wrapped
177
+ expect(result).toBe('export type MyType = { id: string; }');
178
+ expect(result).not.toContain('export type Root');
179
+ expect(result).not.toContain('export type MyType = export type');
180
+ vi.doUnmock('ajsc');
181
+ vi.resetModules();
182
+ });
183
+ });
184
+ //# sourceMappingURL=emit-types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-types.test.js","sourceRoot":"","sources":["../../../src/codegen/emit-types.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { AnyHttpRouteDoc } from '../implementations/types.js';
2
+ export interface ScopeGroup {
3
+ scopeKey: string;
4
+ camelCase: string;
5
+ routes: AnyHttpRouteDoc[];
6
+ }
7
+ /**
8
+ * Normalizes a scope value to a string key:
9
+ * - string → returned as-is
10
+ * - string[] → joined with '-'
11
+ * - undefined → 'default'
12
+ */
13
+ export declare function normalizeScope(scope: string | string[] | undefined): string;
14
+ /**
15
+ * Converts a hyphenated scope key to camelCase.
16
+ * e.g. 'admin-users' → 'adminUsers', 'users' → 'users'
17
+ */
18
+ export declare function scopeToCamelCase(scope: string): string;
19
+ /**
20
+ * Groups an array of route docs into a Map keyed by normalized scope.
21
+ * Routes without a scope emit a console.warn and are grouped under 'default'.
22
+ */
23
+ export declare function groupRoutesByScope(routes: AnyHttpRouteDoc[]): Map<string, ScopeGroup>;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Normalizes a scope value to a string key:
3
+ * - string → returned as-is
4
+ * - string[] → joined with '-'
5
+ * - undefined → 'default'
6
+ */
7
+ export function normalizeScope(scope) {
8
+ if (scope === undefined)
9
+ return 'default';
10
+ if (Array.isArray(scope))
11
+ return scope.join('-');
12
+ return scope;
13
+ }
14
+ /**
15
+ * Converts a hyphenated scope key to camelCase.
16
+ * e.g. 'admin-users' → 'adminUsers', 'users' → 'users'
17
+ */
18
+ export function scopeToCamelCase(scope) {
19
+ const parts = scope.split('-');
20
+ return parts
21
+ .map((part, index) => index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1))
22
+ .join('');
23
+ }
24
+ /**
25
+ * Groups an array of route docs into a Map keyed by normalized scope.
26
+ * Routes without a scope emit a console.warn and are grouped under 'default'.
27
+ */
28
+ export function groupRoutesByScope(routes) {
29
+ const groups = new Map();
30
+ for (const route of routes) {
31
+ const rawScope = 'scope' in route ? route.scope : undefined;
32
+ if (rawScope === undefined) {
33
+ console.warn(`[ts-procedures] Route "${route.name}" has no scope — it will be grouped under "default".`);
34
+ }
35
+ const scopeKey = normalizeScope(rawScope);
36
+ const camelCase = scopeToCamelCase(scopeKey);
37
+ let group = groups.get(scopeKey);
38
+ if (group === undefined) {
39
+ group = { scopeKey, camelCase, routes: [] };
40
+ groups.set(scopeKey, group);
41
+ }
42
+ group.routes.push(route);
43
+ }
44
+ return groups;
45
+ }
46
+ //# sourceMappingURL=group-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-routes.js","sourceRoot":"","sources":["../../../src/codegen/group-routes.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAoC;IACjE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACzC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC9B,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACnB,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAClE;SACA,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAyB;IAC1D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAA;IAE5C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,CAAE,KAAuC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;QAC9F,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CACV,0BAA0B,KAAK,CAAC,IAAI,sDAAsD,CAC3F,CAAA;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;QACzC,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAA;QAE5C,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;YAC3C,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAC7B,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1B,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,131 @@
1
+ import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
2
+ import { normalizeScope, scopeToCamelCase, groupRoutesByScope } from './group-routes.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Fixtures
5
+ // ---------------------------------------------------------------------------
6
+ const rpcRouteUsers = {
7
+ kind: 'rpc',
8
+ name: 'GetUser',
9
+ path: '/users/1',
10
+ method: 'post',
11
+ scope: 'users',
12
+ version: 1,
13
+ jsonSchema: {},
14
+ };
15
+ const rpcRouteAdmin = {
16
+ kind: 'rpc',
17
+ name: 'DeleteUser',
18
+ path: '/admin-users/1',
19
+ method: 'post',
20
+ scope: ['admin', 'users'],
21
+ version: 1,
22
+ jsonSchema: {},
23
+ };
24
+ const rpcRouteUsers2 = {
25
+ kind: 'rpc',
26
+ name: 'ListUsers',
27
+ path: '/users/1',
28
+ method: 'post',
29
+ scope: 'users',
30
+ version: 1,
31
+ jsonSchema: {},
32
+ };
33
+ const apiRouteNoScope = {
34
+ kind: 'api',
35
+ name: 'HealthCheck',
36
+ path: '/health',
37
+ method: 'get',
38
+ fullPath: '/api/health',
39
+ jsonSchema: {},
40
+ };
41
+ const apiRouteWithScope = {
42
+ kind: 'api',
43
+ name: 'ListPosts',
44
+ path: '/posts',
45
+ method: 'get',
46
+ fullPath: '/api/posts',
47
+ scope: 'posts',
48
+ jsonSchema: {},
49
+ };
50
+ // ---------------------------------------------------------------------------
51
+ // normalizeScope
52
+ // ---------------------------------------------------------------------------
53
+ describe('normalizeScope', () => {
54
+ it('returns a string scope as-is', () => {
55
+ expect(normalizeScope('users')).toBe('users');
56
+ });
57
+ it('joins a string array scope with hyphens', () => {
58
+ expect(normalizeScope(['admin', 'users'])).toBe('admin-users');
59
+ });
60
+ it('returns "default" for undefined scope', () => {
61
+ expect(normalizeScope(undefined)).toBe('default');
62
+ });
63
+ });
64
+ // ---------------------------------------------------------------------------
65
+ // scopeToCamelCase
66
+ // ---------------------------------------------------------------------------
67
+ describe('scopeToCamelCase', () => {
68
+ it('returns a single word as-is', () => {
69
+ expect(scopeToCamelCase('users')).toBe('users');
70
+ });
71
+ it('converts a hyphenated scope to camelCase', () => {
72
+ expect(scopeToCamelCase('admin-users')).toBe('adminUsers');
73
+ });
74
+ it('converts multi-segment hyphenated scope', () => {
75
+ expect(scopeToCamelCase('super-admin-users')).toBe('superAdminUsers');
76
+ });
77
+ });
78
+ // ---------------------------------------------------------------------------
79
+ // groupRoutesByScope
80
+ // ---------------------------------------------------------------------------
81
+ describe('groupRoutesByScope', () => {
82
+ beforeEach(() => {
83
+ vi.spyOn(console, 'warn').mockImplementation(() => { });
84
+ });
85
+ afterEach(() => {
86
+ vi.restoreAllMocks();
87
+ });
88
+ it('groups routes by their scope', () => {
89
+ const routes = [rpcRouteUsers, rpcRouteUsers2];
90
+ const groups = groupRoutesByScope(routes);
91
+ expect(groups.size).toBe(1);
92
+ expect(groups.has('users')).toBe(true);
93
+ const usersGroup = groups.get('users');
94
+ expect(usersGroup.scopeKey).toBe('users');
95
+ expect(usersGroup.camelCase).toBe('users');
96
+ expect(usersGroup.routes).toHaveLength(2);
97
+ });
98
+ it('handles array scopes by joining with hyphens', () => {
99
+ const routes = [rpcRouteAdmin];
100
+ const groups = groupRoutesByScope(routes);
101
+ expect(groups.has('admin-users')).toBe(true);
102
+ const group = groups.get('admin-users');
103
+ expect(group.scopeKey).toBe('admin-users');
104
+ expect(group.camelCase).toBe('adminUsers');
105
+ expect(group.routes).toHaveLength(1);
106
+ });
107
+ it('groups routes from multiple scopes', () => {
108
+ const routes = [rpcRouteUsers, rpcRouteAdmin, apiRouteWithScope];
109
+ const groups = groupRoutesByScope(routes);
110
+ expect(groups.size).toBe(3);
111
+ expect(groups.has('users')).toBe(true);
112
+ expect(groups.has('admin-users')).toBe(true);
113
+ expect(groups.has('posts')).toBe(true);
114
+ });
115
+ it('warns on missing scope and groups into "default"', () => {
116
+ const routes = [apiRouteNoScope];
117
+ const groups = groupRoutesByScope(routes);
118
+ expect(console.warn).toHaveBeenCalled();
119
+ expect(groups.has('default')).toBe(true);
120
+ const defaultGroup = groups.get('default');
121
+ expect(defaultGroup.scopeKey).toBe('default');
122
+ expect(defaultGroup.camelCase).toBe('default');
123
+ expect(defaultGroup.routes).toHaveLength(1);
124
+ });
125
+ it('does not warn when all routes have scopes', () => {
126
+ const routes = [rpcRouteUsers, apiRouteWithScope];
127
+ groupRoutesByScope(routes);
128
+ expect(console.warn).not.toHaveBeenCalled();
129
+ });
130
+ });
131
+ //# sourceMappingURL=group-routes.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-routes.test.js","sourceRoot":"","sources":["../../../src/codegen/group-routes.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { type ResolveInput } from './resolve-envelope.js';
2
+ import { type GeneratedFile } from './pipeline.js';
3
+ import type { AjscOptions } from './emit-types.js';
4
+ export interface GenerateClientOptions extends ResolveInput {
5
+ outDir: string;
6
+ ajsc?: AjscOptions;
7
+ clientImportPath?: string;
8
+ dryRun?: boolean;
9
+ namespaceTypes?: boolean;
10
+ selfContained?: boolean;
11
+ serviceName?: string;
12
+ }
13
+ export declare function generateClient(options: GenerateClientOptions): Promise<GeneratedFile[]>;
14
+ export type { AjscOptions } from './emit-types.js';
15
+ export type { ResolveInput } from './resolve-envelope.js';
@@ -0,0 +1,16 @@
1
+ import { resolveEnvelope } from './resolve-envelope.js';
2
+ import { runPipeline } from './pipeline.js';
3
+ export async function generateClient(options) {
4
+ const envelope = await resolveEnvelope(options);
5
+ return runPipeline({
6
+ envelope,
7
+ outDir: options.outDir,
8
+ ajsc: options.ajsc,
9
+ clientImportPath: options.clientImportPath,
10
+ dryRun: options.dryRun,
11
+ namespaceTypes: options.namespaceTypes,
12
+ selfContained: options.selfContained,
13
+ serviceName: options.serviceName,
14
+ });
15
+ }
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/codegen/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAqB,MAAM,uBAAuB,CAAA;AAC1E,OAAO,EAAE,WAAW,EAAsB,MAAM,eAAe,CAAA;AAa/D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA8B;IACjE,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAA;IAC/C,OAAO,WAAW,CAAC;QACjB,QAAQ;QACR,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ /** Converts a string to PascalCase (splits on whitespace, hyphens, underscores). */
2
+ export declare function toPascalCase(str: string): string;
3
+ /**
4
+ * Validates that a serviceName option is usable as a TypeScript identifier fragment.
5
+ * Throws a descriptive error if invalid.
6
+ */
7
+ export declare function validateServiceName(serviceName: string): void;
@@ -0,0 +1,21 @@
1
+ /** Converts a string to PascalCase (splits on whitespace, hyphens, underscores). */
2
+ export function toPascalCase(str) {
3
+ return str
4
+ .split(/[\s\-_]+/)
5
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
6
+ .join('');
7
+ }
8
+ /**
9
+ * Validates that a serviceName option is usable as a TypeScript identifier fragment.
10
+ * Throws a descriptive error if invalid.
11
+ */
12
+ export function validateServiceName(serviceName) {
13
+ const pascal = toPascalCase(serviceName);
14
+ if (pascal.length === 0) {
15
+ throw new Error(`[ts-procedures-codegen] --service-name value "${serviceName}" is empty or contains only separator characters.`);
16
+ }
17
+ if (/^\d/.test(pascal)) {
18
+ throw new Error(`[ts-procedures-codegen] --service-name value "${serviceName}" produces "${pascal}" which starts with a digit — provide a name that starts with a letter.`);
19
+ }
20
+ }
21
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../../src/codegen/naming.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,GAAG;SACP,KAAK,CAAC,UAAU,CAAC;SACjB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAmB;IACrD,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;IACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,iDAAiD,WAAW,mDAAmD,CAChH,CAAA;IACH,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,iDAAiD,WAAW,eAAe,MAAM,yEAAyE,CAC3J,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export {};