ts-procedures 5.5.0 → 5.6.0-beta.1

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 (127) hide show
  1. package/README.md +150 -0
  2. package/agent_config/claude-code/skills/guide/api-reference.md +177 -0
  3. package/agent_config/claude-code/skills/guide/patterns.md +107 -0
  4. package/agent_config/copilot/copilot-instructions.md +80 -0
  5. package/agent_config/cursor/cursorrules +80 -0
  6. package/build/client/call.d.ts +14 -0
  7. package/build/client/call.js +47 -0
  8. package/build/client/call.js.map +1 -0
  9. package/build/client/call.test.d.ts +1 -0
  10. package/build/client/call.test.js +124 -0
  11. package/build/client/call.test.js.map +1 -0
  12. package/build/client/errors.d.ts +25 -0
  13. package/build/client/errors.js +33 -0
  14. package/build/client/errors.js.map +1 -0
  15. package/build/client/errors.test.d.ts +1 -0
  16. package/build/client/errors.test.js +41 -0
  17. package/build/client/errors.test.js.map +1 -0
  18. package/build/client/fetch-adapter.d.ts +12 -0
  19. package/build/client/fetch-adapter.js +156 -0
  20. package/build/client/fetch-adapter.js.map +1 -0
  21. package/build/client/fetch-adapter.test.d.ts +1 -0
  22. package/build/client/fetch-adapter.test.js +271 -0
  23. package/build/client/fetch-adapter.test.js.map +1 -0
  24. package/build/client/hooks.d.ts +17 -0
  25. package/build/client/hooks.js +40 -0
  26. package/build/client/hooks.js.map +1 -0
  27. package/build/client/hooks.test.d.ts +1 -0
  28. package/build/client/hooks.test.js +163 -0
  29. package/build/client/hooks.test.js.map +1 -0
  30. package/build/client/index.d.ts +22 -0
  31. package/build/client/index.js +67 -0
  32. package/build/client/index.js.map +1 -0
  33. package/build/client/index.test.d.ts +1 -0
  34. package/build/client/index.test.js +231 -0
  35. package/build/client/index.test.js.map +1 -0
  36. package/build/client/request-builder.d.ts +13 -0
  37. package/build/client/request-builder.js +53 -0
  38. package/build/client/request-builder.js.map +1 -0
  39. package/build/client/request-builder.test.d.ts +1 -0
  40. package/build/client/request-builder.test.js +160 -0
  41. package/build/client/request-builder.test.js.map +1 -0
  42. package/build/client/stream.d.ts +27 -0
  43. package/build/client/stream.js +118 -0
  44. package/build/client/stream.js.map +1 -0
  45. package/build/client/stream.test.d.ts +1 -0
  46. package/build/client/stream.test.js +228 -0
  47. package/build/client/stream.test.js.map +1 -0
  48. package/build/client/types.d.ts +78 -0
  49. package/build/client/types.js +3 -0
  50. package/build/client/types.js.map +1 -0
  51. package/build/codegen/bin/cli.d.ts +17 -0
  52. package/build/codegen/bin/cli.js +149 -0
  53. package/build/codegen/bin/cli.js.map +1 -0
  54. package/build/codegen/bin/cli.test.d.ts +1 -0
  55. package/build/codegen/bin/cli.test.js +83 -0
  56. package/build/codegen/bin/cli.test.js.map +1 -0
  57. package/build/codegen/e2e.test.d.ts +1 -0
  58. package/build/codegen/e2e.test.js +321 -0
  59. package/build/codegen/e2e.test.js.map +1 -0
  60. package/build/codegen/emit-errors.d.ts +9 -0
  61. package/build/codegen/emit-errors.js +30 -0
  62. package/build/codegen/emit-errors.js.map +1 -0
  63. package/build/codegen/emit-errors.test.d.ts +1 -0
  64. package/build/codegen/emit-errors.test.js +110 -0
  65. package/build/codegen/emit-errors.test.js.map +1 -0
  66. package/build/codegen/emit-index.d.ts +6 -0
  67. package/build/codegen/emit-index.js +49 -0
  68. package/build/codegen/emit-index.js.map +1 -0
  69. package/build/codegen/emit-index.test.d.ts +1 -0
  70. package/build/codegen/emit-index.test.js +83 -0
  71. package/build/codegen/emit-index.test.js.map +1 -0
  72. package/build/codegen/emit-scope.d.ts +6 -0
  73. package/build/codegen/emit-scope.js +194 -0
  74. package/build/codegen/emit-scope.js.map +1 -0
  75. package/build/codegen/emit-scope.test.d.ts +1 -0
  76. package/build/codegen/emit-scope.test.js +276 -0
  77. package/build/codegen/emit-scope.test.js.map +1 -0
  78. package/build/codegen/emit-types.d.ts +14 -0
  79. package/build/codegen/emit-types.js +40 -0
  80. package/build/codegen/emit-types.js.map +1 -0
  81. package/build/codegen/emit-types.test.d.ts +1 -0
  82. package/build/codegen/emit-types.test.js +82 -0
  83. package/build/codegen/emit-types.test.js.map +1 -0
  84. package/build/codegen/group-routes.d.ts +23 -0
  85. package/build/codegen/group-routes.js +46 -0
  86. package/build/codegen/group-routes.js.map +1 -0
  87. package/build/codegen/group-routes.test.d.ts +1 -0
  88. package/build/codegen/group-routes.test.js +131 -0
  89. package/build/codegen/group-routes.test.js.map +1 -0
  90. package/build/codegen/index.d.ts +11 -0
  91. package/build/codegen/index.js +13 -0
  92. package/build/codegen/index.js.map +1 -0
  93. package/build/codegen/pipeline.d.ts +14 -0
  94. package/build/codegen/pipeline.js +49 -0
  95. package/build/codegen/pipeline.js.map +1 -0
  96. package/build/codegen/pipeline.test.d.ts +1 -0
  97. package/build/codegen/pipeline.test.js +151 -0
  98. package/build/codegen/pipeline.test.js.map +1 -0
  99. package/build/codegen/resolve-envelope.d.ts +7 -0
  100. package/build/codegen/resolve-envelope.js +26 -0
  101. package/build/codegen/resolve-envelope.js.map +1 -0
  102. package/build/codegen/resolve-envelope.test.d.ts +1 -0
  103. package/build/codegen/resolve-envelope.test.js +69 -0
  104. package/build/codegen/resolve-envelope.test.js.map +1 -0
  105. package/build/implementations/http/doc-registry.test.js +27 -1
  106. package/build/implementations/http/doc-registry.test.js.map +1 -1
  107. package/build/implementations/http/express-rpc/index.js +1 -0
  108. package/build/implementations/http/express-rpc/index.js.map +1 -1
  109. package/build/implementations/http/express-rpc/index.test.js +1 -1
  110. package/build/implementations/http/express-rpc/index.test.js.map +1 -1
  111. package/build/implementations/http/hono-api/index.js +2 -0
  112. package/build/implementations/http/hono-api/index.js.map +1 -1
  113. package/build/implementations/http/hono-api/index.test.js +9 -0
  114. package/build/implementations/http/hono-api/index.test.js.map +1 -1
  115. package/build/implementations/http/hono-rpc/index.js +1 -0
  116. package/build/implementations/http/hono-rpc/index.js.map +1 -1
  117. package/build/implementations/http/hono-rpc/index.test.js +1 -1
  118. package/build/implementations/http/hono-rpc/index.test.js.map +1 -1
  119. package/build/implementations/http/hono-stream/index.js +17 -1
  120. package/build/implementations/http/hono-stream/index.js.map +1 -1
  121. package/build/implementations/http/hono-stream/index.test.js +61 -0
  122. package/build/implementations/http/hono-stream/index.test.js.map +1 -1
  123. package/build/implementations/http/hono-stream/types.d.ts +4 -13
  124. package/build/implementations/types.d.ts +5 -0
  125. package/build/index.js +8 -1
  126. package/build/index.js.map +1 -1
  127. package/package.json +12 -2
@@ -0,0 +1,40 @@
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
+ /**
14
+ * Converts a JSON Schema to a TypeScript type string using ajsc.
15
+ *
16
+ * Returns `export type ${typeName} = ${code}` where code is the inline type
17
+ * body from TypescriptConverter with inlineTypes: true.
18
+ *
19
+ * Returns undefined for undefined or null schema.
20
+ */
21
+ export async function jsonSchemaToTypeString(typeName, schema, options) {
22
+ if (schema == null)
23
+ return undefined;
24
+ await validateAjscFormat();
25
+ const { TypescriptConverter } = await import('ajsc');
26
+ const converter = new TypescriptConverter(schema, {
27
+ ...options,
28
+ inlineTypes: true,
29
+ });
30
+ let code = converter.code.trim();
31
+ if (!code) {
32
+ throw new Error(`[ts-procedures-codegen] ajsc produced empty output for type "${typeName}". Schema: ${JSON.stringify(schema)}`);
33
+ }
34
+ // Strip any 'export type X = ' or 'type X = ' prefix ajsc might add
35
+ code = code.replace(/^(?:export\s+)?type\s+\w+\s*=\s*/, '');
36
+ // Remove trailing semicolons and newlines
37
+ code = code.replace(/;\s*$/, '').trim();
38
+ return `export type ${typeName} = ${code}`;
39
+ }
40
+ //# sourceMappingURL=emit-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-types.js","sourceRoot":"","sources":["../../src/codegen/emit-types.ts"],"names":[],"mappings":"AAMA,IAAI,aAAa,GAAG,KAAK,CAAA;AACzB,KAAK,UAAU,kBAAkB;IAC/B,IAAI,aAAa;QAAE,OAAM;IACzB,aAAa,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;IACpD,MAAM,KAAK,GAAG,IAAI,mBAAmB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;IAChF,MAAM,SAAS,GAAI,KAAK,CAAC,IAAe,CAAC,IAAI,EAAE,CAAA;IAC/C,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,gHAAgH,SAAS,GAAG,CAAC,CAAA;IAC5I,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAAgB,EAChB,MAA2C,EAC3C,OAAqB;IAErB,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IAEpC,MAAM,kBAAkB,EAAE,CAAA;IAE1B,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;IAEpD,MAAM,SAAS,GAAG,IAAI,mBAAmB,CAAC,MAAiC,EAAE;QAC3E,GAAG,OAAO;QACV,WAAW,EAAE,IAAI;KAClB,CAAC,CAAA;IAEF,IAAI,IAAI,GAAI,SAAS,CAAC,IAAe,CAAC,IAAI,EAAE,CAAA;IAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,gEAAgE,QAAQ,cAAc,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAC/G,CAAA;IACH,CAAC;IACD,oEAAoE;IACpE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,kCAAkC,EAAE,EAAE,CAAC,CAAA;IAC3D,0CAA0C;IAC1C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAEvC,OAAO,eAAe,QAAQ,MAAM,IAAI,EAAE,CAAA;AAC5C,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,82 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { jsonSchemaToTypeString } 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('strips "export type Root = " prefix and does not double-wrap', async () => {
63
+ vi.resetModules();
64
+ vi.doMock('ajsc', () => ({
65
+ TypescriptConverter: class {
66
+ code;
67
+ constructor(_schema, _opts) {
68
+ this.code = '\n\nexport type Root = { id: string; };\n';
69
+ }
70
+ },
71
+ }));
72
+ const { jsonSchemaToTypeString: fn } = await import('./emit-types.js');
73
+ const result = await fn('MyType', { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] });
74
+ // Should be the clean body, not double-wrapped
75
+ expect(result).toBe('export type MyType = { id: string; }');
76
+ expect(result).not.toContain('export type Root');
77
+ expect(result).not.toContain('export type MyType = export type');
78
+ vi.doUnmock('ajsc');
79
+ vi.resetModules();
80
+ });
81
+ });
82
+ //# 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,11 @@
1
+ import { type ResolveInput } from './resolve-envelope.js';
2
+ import type { AjscOptions } from './emit-types.js';
3
+ export interface GenerateClientOptions extends ResolveInput {
4
+ outDir: string;
5
+ ajsc?: AjscOptions;
6
+ clientImportPath?: string;
7
+ dryRun?: boolean;
8
+ }
9
+ export declare function generateClient(options: GenerateClientOptions): Promise<void>;
10
+ export type { AjscOptions } from './emit-types.js';
11
+ export type { ResolveInput } from './resolve-envelope.js';
@@ -0,0 +1,13 @@
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
+ await runPipeline({
6
+ envelope,
7
+ outDir: options.outDir,
8
+ ajsc: options.ajsc,
9
+ clientImportPath: options.clientImportPath,
10
+ dryRun: options.dryRun,
11
+ });
12
+ }
13
+ //# 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,EAAE,MAAM,eAAe,CAAA;AAU3C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA8B;IACjE,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAA;IAC/C,MAAM,WAAW,CAAC;QAChB,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;KACvB,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { DocEnvelope } from '../implementations/types.js';
2
+ import type { AjscOptions } from './emit-types.js';
3
+ export interface PipelineOptions {
4
+ envelope: DocEnvelope;
5
+ outDir: string;
6
+ ajsc?: AjscOptions;
7
+ clientImportPath?: string;
8
+ dryRun?: boolean;
9
+ }
10
+ export interface GeneratedFile {
11
+ path: string;
12
+ code: string;
13
+ }
14
+ export declare function runPipeline(options: PipelineOptions): Promise<GeneratedFile[]>;
@@ -0,0 +1,49 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { createHash } from 'node:crypto';
4
+ import { groupRoutesByScope } from './group-routes.js';
5
+ import { emitScopeFile } from './emit-scope.js';
6
+ import { emitIndexFile } from './emit-index.js';
7
+ import { emitErrorsFile } from './emit-errors.js';
8
+ export async function runPipeline(options) {
9
+ const { envelope, outDir, ajsc: ajscOpts, clientImportPath, dryRun = false } = options;
10
+ const hash = createHash('md5').update(JSON.stringify(envelope)).digest('hex');
11
+ const hashComment = `// Source hash: ${hash}`;
12
+ const groups = groupRoutesByScope(envelope.routes);
13
+ const groupArray = Array.from(groups.values());
14
+ const files = [];
15
+ for (const group of groupArray) {
16
+ const rawCode = await emitScopeFile(group, ajscOpts, clientImportPath);
17
+ const lines = rawCode.split('\n');
18
+ lines.splice(1, 0, hashComment);
19
+ const code = lines.join('\n');
20
+ files.push({ path: join(outDir, `${group.scopeKey}.ts`), code });
21
+ }
22
+ const errorsCode = await emitErrorsFile(envelope.errors, ajscOpts, clientImportPath);
23
+ const hasErrors = errorsCode != null;
24
+ if (errorsCode != null) {
25
+ const errorsLines = errorsCode.split('\n');
26
+ errorsLines.splice(1, 0, hashComment);
27
+ const errorsWithHash = errorsLines.join('\n');
28
+ files.push({ path: join(outDir, '_errors.ts'), code: errorsWithHash });
29
+ }
30
+ const rawIndexCode = emitIndexFile(groupArray, clientImportPath, hasErrors);
31
+ const indexLines = rawIndexCode.split('\n');
32
+ indexLines.splice(1, 0, hashComment);
33
+ const indexCode = indexLines.join('\n');
34
+ files.push({ path: join(outDir, 'index.ts'), code: indexCode });
35
+ if (dryRun) {
36
+ for (const file of files) {
37
+ const bytes = Buffer.byteLength(file.code, 'utf-8');
38
+ console.log(`[dry-run] Would write: ${file.path} (${bytes} bytes)`);
39
+ }
40
+ }
41
+ else {
42
+ await mkdir(outDir, { recursive: true });
43
+ for (const file of files) {
44
+ await writeFile(file.path, file.code, 'utf-8');
45
+ }
46
+ }
47
+ return files;
48
+ }
49
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/codegen/pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,151 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import { generateClient } from './index.js';
3
+ import { runPipeline } from './pipeline.js';
4
+ import { mkdirSync, rmSync, readFileSync, existsSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { tmpdir } from 'node:os';
7
+ // ---------------------------------------------------------------------------
8
+ // Fixtures
9
+ // ---------------------------------------------------------------------------
10
+ const envelope = {
11
+ basePath: '/api',
12
+ headers: [],
13
+ errors: [],
14
+ routes: [
15
+ {
16
+ kind: 'rpc',
17
+ name: 'GetUser',
18
+ path: '/users/1',
19
+ method: 'post',
20
+ scope: 'users',
21
+ version: 1,
22
+ jsonSchema: {
23
+ body: {
24
+ type: 'object',
25
+ properties: { id: { type: 'string' } },
26
+ required: ['id'],
27
+ },
28
+ response: {
29
+ type: 'object',
30
+ properties: { name: { type: 'string' } },
31
+ required: ['name'],
32
+ },
33
+ },
34
+ },
35
+ {
36
+ kind: 'rpc',
37
+ name: 'CreateInvoice',
38
+ path: '/billing/1',
39
+ method: 'post',
40
+ scope: 'billing',
41
+ version: 1,
42
+ jsonSchema: {
43
+ body: {
44
+ type: 'object',
45
+ properties: { amount: { type: 'number' } },
46
+ required: ['amount'],
47
+ },
48
+ response: {
49
+ type: 'object',
50
+ properties: { invoiceId: { type: 'string' } },
51
+ required: ['invoiceId'],
52
+ },
53
+ },
54
+ },
55
+ ],
56
+ };
57
+ // ---------------------------------------------------------------------------
58
+ // Helpers
59
+ // ---------------------------------------------------------------------------
60
+ function makeTmpDir() {
61
+ const dir = join(tmpdir(), `ts-proc-pipeline-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
62
+ mkdirSync(dir, { recursive: true });
63
+ return dir;
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // Tests
67
+ // ---------------------------------------------------------------------------
68
+ describe('generateClient pipeline', () => {
69
+ let tmpDir;
70
+ afterEach(() => {
71
+ if (tmpDir && existsSync(tmpDir)) {
72
+ rmSync(tmpDir, { recursive: true, force: true });
73
+ }
74
+ });
75
+ it('creates scope file for each unique scope (users.ts, billing.ts)', async () => {
76
+ tmpDir = makeTmpDir();
77
+ await generateClient({ envelope, outDir: tmpDir });
78
+ expect(existsSync(join(tmpDir, 'users.ts'))).toBe(true);
79
+ expect(existsSync(join(tmpDir, 'billing.ts'))).toBe(true);
80
+ });
81
+ it('creates index.ts', async () => {
82
+ tmpDir = makeTmpDir();
83
+ await generateClient({ envelope, outDir: tmpDir });
84
+ expect(existsSync(join(tmpDir, 'index.ts'))).toBe(true);
85
+ });
86
+ it('users.ts contains bindUsersScope function', async () => {
87
+ tmpDir = makeTmpDir();
88
+ await generateClient({ envelope, outDir: tmpDir });
89
+ const content = readFileSync(join(tmpDir, 'users.ts'), 'utf-8');
90
+ expect(content).toContain('bindUsersScope');
91
+ expect(content).toContain('GetUser');
92
+ });
93
+ it('billing.ts contains bindBillingScope function', async () => {
94
+ tmpDir = makeTmpDir();
95
+ await generateClient({ envelope, outDir: tmpDir });
96
+ const content = readFileSync(join(tmpDir, 'billing.ts'), 'utf-8');
97
+ expect(content).toContain('bindBillingScope');
98
+ expect(content).toContain('CreateInvoice');
99
+ });
100
+ it('index.ts exports from both scope files and has createScopeBindings', async () => {
101
+ tmpDir = makeTmpDir();
102
+ await generateClient({ envelope, outDir: tmpDir });
103
+ const content = readFileSync(join(tmpDir, 'index.ts'), 'utf-8');
104
+ expect(content).toContain("from './users'");
105
+ expect(content).toContain("from './billing'");
106
+ expect(content).toContain('createScopeBindings');
107
+ });
108
+ it('creates outDir if it does not exist', async () => {
109
+ tmpDir = makeTmpDir();
110
+ const nested = join(tmpDir, 'nested', 'output');
111
+ await generateClient({ envelope, outDir: nested });
112
+ expect(existsSync(join(nested, 'index.ts'))).toBe(true);
113
+ });
114
+ it('all generated files have the auto-generated header comment', async () => {
115
+ tmpDir = makeTmpDir();
116
+ await generateClient({ envelope, outDir: tmpDir });
117
+ for (const file of ['users.ts', 'billing.ts', 'index.ts']) {
118
+ const content = readFileSync(join(tmpDir, file), 'utf-8');
119
+ expect(content).toContain('// Auto-generated by ts-procedures-codegen — do not edit');
120
+ }
121
+ });
122
+ it('generated files include source hash comment', async () => {
123
+ tmpDir = makeTmpDir();
124
+ await generateClient({ envelope, outDir: tmpDir });
125
+ for (const file of ['users.ts', 'billing.ts', 'index.ts']) {
126
+ const content = readFileSync(join(tmpDir, file), 'utf-8');
127
+ const lines = content.split('\n');
128
+ expect(lines[1]).toMatch(/^\/\/ Source hash: [a-f0-9]{32}$/);
129
+ }
130
+ });
131
+ it('dry-run mode does not create files on disk', async () => {
132
+ tmpDir = makeTmpDir();
133
+ const dryDir = join(tmpDir, 'dry-output');
134
+ await runPipeline({ envelope, outDir: dryDir, dryRun: true });
135
+ expect(existsSync(dryDir)).toBe(false);
136
+ });
137
+ it('dry-run mode returns generated file entries', async () => {
138
+ tmpDir = makeTmpDir();
139
+ const dryDir = join(tmpDir, 'dry-output');
140
+ const files = await runPipeline({ envelope, outDir: dryDir, dryRun: true });
141
+ expect(files.length).toBe(3); // users.ts, billing.ts, index.ts
142
+ const paths = files.map((f) => f.path);
143
+ expect(paths).toContain(join(dryDir, 'users.ts'));
144
+ expect(paths).toContain(join(dryDir, 'billing.ts'));
145
+ expect(paths).toContain(join(dryDir, 'index.ts'));
146
+ for (const file of files) {
147
+ expect(file.code).toContain('// Auto-generated by ts-procedures-codegen — do not edit');
148
+ }
149
+ });
150
+ });
151
+ //# sourceMappingURL=pipeline.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.test.js","sourceRoot":"","sources":["../../src/codegen/pipeline.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { DocEnvelope } from '../implementations/types.js';
2
+ export interface ResolveInput {
3
+ url?: string;
4
+ file?: string;
5
+ envelope?: DocEnvelope;
6
+ }
7
+ export declare function resolveEnvelope(input: ResolveInput): Promise<DocEnvelope>;