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.
- package/README.md +150 -0
- package/agent_config/claude-code/skills/guide/api-reference.md +177 -0
- package/agent_config/claude-code/skills/guide/patterns.md +107 -0
- package/agent_config/copilot/copilot-instructions.md +80 -0
- package/agent_config/cursor/cursorrules +80 -0
- package/build/client/call.d.ts +14 -0
- package/build/client/call.js +47 -0
- package/build/client/call.js.map +1 -0
- package/build/client/call.test.d.ts +1 -0
- package/build/client/call.test.js +124 -0
- package/build/client/call.test.js.map +1 -0
- package/build/client/errors.d.ts +25 -0
- package/build/client/errors.js +33 -0
- package/build/client/errors.js.map +1 -0
- package/build/client/errors.test.d.ts +1 -0
- package/build/client/errors.test.js +41 -0
- package/build/client/errors.test.js.map +1 -0
- package/build/client/fetch-adapter.d.ts +12 -0
- package/build/client/fetch-adapter.js +156 -0
- package/build/client/fetch-adapter.js.map +1 -0
- package/build/client/fetch-adapter.test.d.ts +1 -0
- package/build/client/fetch-adapter.test.js +271 -0
- package/build/client/fetch-adapter.test.js.map +1 -0
- package/build/client/hooks.d.ts +17 -0
- package/build/client/hooks.js +40 -0
- package/build/client/hooks.js.map +1 -0
- package/build/client/hooks.test.d.ts +1 -0
- package/build/client/hooks.test.js +163 -0
- package/build/client/hooks.test.js.map +1 -0
- package/build/client/index.d.ts +22 -0
- package/build/client/index.js +67 -0
- package/build/client/index.js.map +1 -0
- package/build/client/index.test.d.ts +1 -0
- package/build/client/index.test.js +231 -0
- package/build/client/index.test.js.map +1 -0
- package/build/client/request-builder.d.ts +13 -0
- package/build/client/request-builder.js +53 -0
- package/build/client/request-builder.js.map +1 -0
- package/build/client/request-builder.test.d.ts +1 -0
- package/build/client/request-builder.test.js +160 -0
- package/build/client/request-builder.test.js.map +1 -0
- package/build/client/stream.d.ts +27 -0
- package/build/client/stream.js +118 -0
- package/build/client/stream.js.map +1 -0
- package/build/client/stream.test.d.ts +1 -0
- package/build/client/stream.test.js +228 -0
- package/build/client/stream.test.js.map +1 -0
- package/build/client/types.d.ts +78 -0
- package/build/client/types.js +3 -0
- package/build/client/types.js.map +1 -0
- package/build/codegen/bin/cli.d.ts +17 -0
- package/build/codegen/bin/cli.js +149 -0
- package/build/codegen/bin/cli.js.map +1 -0
- package/build/codegen/bin/cli.test.d.ts +1 -0
- package/build/codegen/bin/cli.test.js +83 -0
- package/build/codegen/bin/cli.test.js.map +1 -0
- package/build/codegen/e2e.test.d.ts +1 -0
- package/build/codegen/e2e.test.js +321 -0
- package/build/codegen/e2e.test.js.map +1 -0
- package/build/codegen/emit-errors.d.ts +9 -0
- package/build/codegen/emit-errors.js +30 -0
- package/build/codegen/emit-errors.js.map +1 -0
- package/build/codegen/emit-errors.test.d.ts +1 -0
- package/build/codegen/emit-errors.test.js +110 -0
- package/build/codegen/emit-errors.test.js.map +1 -0
- package/build/codegen/emit-index.d.ts +6 -0
- package/build/codegen/emit-index.js +49 -0
- package/build/codegen/emit-index.js.map +1 -0
- package/build/codegen/emit-index.test.d.ts +1 -0
- package/build/codegen/emit-index.test.js +83 -0
- package/build/codegen/emit-index.test.js.map +1 -0
- package/build/codegen/emit-scope.d.ts +6 -0
- package/build/codegen/emit-scope.js +194 -0
- package/build/codegen/emit-scope.js.map +1 -0
- package/build/codegen/emit-scope.test.d.ts +1 -0
- package/build/codegen/emit-scope.test.js +276 -0
- package/build/codegen/emit-scope.test.js.map +1 -0
- package/build/codegen/emit-types.d.ts +14 -0
- package/build/codegen/emit-types.js +40 -0
- package/build/codegen/emit-types.js.map +1 -0
- package/build/codegen/emit-types.test.d.ts +1 -0
- package/build/codegen/emit-types.test.js +82 -0
- package/build/codegen/emit-types.test.js.map +1 -0
- package/build/codegen/group-routes.d.ts +23 -0
- package/build/codegen/group-routes.js +46 -0
- package/build/codegen/group-routes.js.map +1 -0
- package/build/codegen/group-routes.test.d.ts +1 -0
- package/build/codegen/group-routes.test.js +131 -0
- package/build/codegen/group-routes.test.js.map +1 -0
- package/build/codegen/index.d.ts +11 -0
- package/build/codegen/index.js +13 -0
- package/build/codegen/index.js.map +1 -0
- package/build/codegen/pipeline.d.ts +14 -0
- package/build/codegen/pipeline.js +49 -0
- package/build/codegen/pipeline.js.map +1 -0
- package/build/codegen/pipeline.test.d.ts +1 -0
- package/build/codegen/pipeline.test.js +151 -0
- package/build/codegen/pipeline.test.js.map +1 -0
- package/build/codegen/resolve-envelope.d.ts +7 -0
- package/build/codegen/resolve-envelope.js +26 -0
- package/build/codegen/resolve-envelope.js.map +1 -0
- package/build/codegen/resolve-envelope.test.d.ts +1 -0
- package/build/codegen/resolve-envelope.test.js +69 -0
- package/build/codegen/resolve-envelope.test.js.map +1 -0
- package/build/implementations/http/doc-registry.test.js +27 -1
- package/build/implementations/http/doc-registry.test.js.map +1 -1
- package/build/implementations/http/express-rpc/index.js +1 -0
- package/build/implementations/http/express-rpc/index.js.map +1 -1
- package/build/implementations/http/express-rpc/index.test.js +1 -1
- package/build/implementations/http/express-rpc/index.test.js.map +1 -1
- package/build/implementations/http/hono-api/index.js +2 -0
- package/build/implementations/http/hono-api/index.js.map +1 -1
- package/build/implementations/http/hono-api/index.test.js +9 -0
- package/build/implementations/http/hono-api/index.test.js.map +1 -1
- package/build/implementations/http/hono-rpc/index.js +1 -0
- package/build/implementations/http/hono-rpc/index.js.map +1 -1
- package/build/implementations/http/hono-rpc/index.test.js +1 -1
- package/build/implementations/http/hono-rpc/index.test.js.map +1 -1
- package/build/implementations/http/hono-stream/index.js +17 -1
- package/build/implementations/http/hono-stream/index.js.map +1 -1
- package/build/implementations/http/hono-stream/index.test.js +61 -0
- package/build/implementations/http/hono-stream/index.test.js.map +1 -1
- package/build/implementations/http/hono-stream/types.d.ts +4 -13
- package/build/implementations/types.d.ts +5 -0
- package/build/index.js +8 -1
- package/build/index.js.map +1 -1
- package/package.json +12 -2
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
+
import { generateClient } from './index.js';
|
|
3
|
+
import { mkdirSync, rmSync, readFileSync, existsSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Fixtures
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
const rpcRoute = {
|
|
10
|
+
kind: 'rpc',
|
|
11
|
+
name: 'GetUser',
|
|
12
|
+
path: '/users/1',
|
|
13
|
+
method: 'post',
|
|
14
|
+
scope: 'users',
|
|
15
|
+
version: 1,
|
|
16
|
+
jsonSchema: {
|
|
17
|
+
body: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: { id: { type: 'string' } },
|
|
20
|
+
required: ['id'],
|
|
21
|
+
},
|
|
22
|
+
response: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: { name: { type: 'string' }, email: { type: 'string' } },
|
|
25
|
+
required: ['name', 'email'],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
const apiRoute = {
|
|
30
|
+
kind: 'api',
|
|
31
|
+
name: 'UpdateUser',
|
|
32
|
+
path: '/users/:id',
|
|
33
|
+
fullPath: '/api/users/:id',
|
|
34
|
+
method: 'put',
|
|
35
|
+
scope: 'users',
|
|
36
|
+
jsonSchema: {
|
|
37
|
+
pathParams: {
|
|
38
|
+
type: 'object',
|
|
39
|
+
properties: { id: { type: 'string' } },
|
|
40
|
+
required: ['id'],
|
|
41
|
+
},
|
|
42
|
+
body: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: { name: { type: 'string' } },
|
|
45
|
+
required: ['name'],
|
|
46
|
+
},
|
|
47
|
+
response: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: { id: { type: 'string' }, name: { type: 'string' } },
|
|
50
|
+
required: ['id', 'name'],
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
const streamRoute = {
|
|
55
|
+
kind: 'stream',
|
|
56
|
+
name: 'WatchEvents',
|
|
57
|
+
path: '/events/stream',
|
|
58
|
+
methods: ['get'],
|
|
59
|
+
streamMode: 'sse',
|
|
60
|
+
scope: 'events',
|
|
61
|
+
version: 1,
|
|
62
|
+
jsonSchema: {
|
|
63
|
+
params: {
|
|
64
|
+
type: 'object',
|
|
65
|
+
properties: { filter: { type: 'string' } },
|
|
66
|
+
required: [],
|
|
67
|
+
},
|
|
68
|
+
// SSE envelope wrapping the actual yield payload
|
|
69
|
+
yieldType: {
|
|
70
|
+
type: 'object',
|
|
71
|
+
properties: {
|
|
72
|
+
data: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: { type: { type: 'string' }, payload: { type: 'string' } },
|
|
75
|
+
required: ['type'],
|
|
76
|
+
},
|
|
77
|
+
event: { type: 'string' },
|
|
78
|
+
id: { type: 'string' },
|
|
79
|
+
retry: { type: 'number' },
|
|
80
|
+
},
|
|
81
|
+
required: ['data'],
|
|
82
|
+
},
|
|
83
|
+
returnType: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: { count: { type: 'number' } },
|
|
86
|
+
required: ['count'],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
const procedureErrorDoc = {
|
|
91
|
+
name: 'ProcedureError',
|
|
92
|
+
statusCode: 500,
|
|
93
|
+
description: 'An error thrown from within a procedure handler via ctx.error().',
|
|
94
|
+
schema: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
properties: {
|
|
97
|
+
name: { type: 'string', const: 'ProcedureError' },
|
|
98
|
+
procedureName: { type: 'string' },
|
|
99
|
+
message: { type: 'string' },
|
|
100
|
+
meta: { type: 'object' },
|
|
101
|
+
},
|
|
102
|
+
required: ['name', 'procedureName', 'message'],
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
const validationErrorDoc = {
|
|
106
|
+
name: 'ProcedureValidationError',
|
|
107
|
+
statusCode: 400,
|
|
108
|
+
description: 'Schema validation failed for the procedure input parameters.',
|
|
109
|
+
schema: {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
name: { type: 'string', const: 'ProcedureValidationError' },
|
|
113
|
+
procedureName: { type: 'string' },
|
|
114
|
+
message: { type: 'string' },
|
|
115
|
+
},
|
|
116
|
+
required: ['name', 'procedureName', 'message'],
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
const envelope = {
|
|
120
|
+
basePath: '/api',
|
|
121
|
+
headers: [],
|
|
122
|
+
errors: [procedureErrorDoc, validationErrorDoc],
|
|
123
|
+
routes: [rpcRoute, apiRoute, streamRoute],
|
|
124
|
+
};
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// Helpers
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
function makeTmpDir() {
|
|
129
|
+
const dir = join(tmpdir(), `ts-proc-e2e-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
130
|
+
mkdirSync(dir, { recursive: true });
|
|
131
|
+
return dir;
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Tests
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
describe('E2E: generateClient full pipeline', () => {
|
|
137
|
+
let tmpDir;
|
|
138
|
+
afterEach(() => {
|
|
139
|
+
if (tmpDir && existsSync(tmpDir)) {
|
|
140
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// ── File existence ─────────────────────────────────────────────────────────
|
|
144
|
+
it('creates users.ts, events.ts, and index.ts', async () => {
|
|
145
|
+
tmpDir = makeTmpDir();
|
|
146
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
147
|
+
expect(existsSync(join(tmpDir, 'users.ts'))).toBe(true);
|
|
148
|
+
expect(existsSync(join(tmpDir, 'events.ts'))).toBe(true);
|
|
149
|
+
expect(existsSync(join(tmpDir, 'index.ts'))).toBe(true);
|
|
150
|
+
});
|
|
151
|
+
// ── users.ts — RPC route ───────────────────────────────────────────────────
|
|
152
|
+
it('users.ts contains GetUserParams type', async () => {
|
|
153
|
+
tmpDir = makeTmpDir();
|
|
154
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
155
|
+
const content = readFileSync(join(tmpDir, 'users.ts'), 'utf-8');
|
|
156
|
+
expect(content).toContain('GetUserParams');
|
|
157
|
+
});
|
|
158
|
+
it('users.ts contains GetUserResponse type', async () => {
|
|
159
|
+
tmpDir = makeTmpDir();
|
|
160
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
161
|
+
const content = readFileSync(join(tmpDir, 'users.ts'), 'utf-8');
|
|
162
|
+
expect(content).toContain('GetUserResponse');
|
|
163
|
+
});
|
|
164
|
+
// ── users.ts — API route ───────────────────────────────────────────────────
|
|
165
|
+
it('users.ts contains UpdateUserParams type', async () => {
|
|
166
|
+
tmpDir = makeTmpDir();
|
|
167
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
168
|
+
const content = readFileSync(join(tmpDir, 'users.ts'), 'utf-8');
|
|
169
|
+
expect(content).toContain('UpdateUserParams');
|
|
170
|
+
});
|
|
171
|
+
it('users.ts contains UpdateUserResponse type', async () => {
|
|
172
|
+
tmpDir = makeTmpDir();
|
|
173
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
174
|
+
const content = readFileSync(join(tmpDir, 'users.ts'), 'utf-8');
|
|
175
|
+
expect(content).toContain('UpdateUserResponse');
|
|
176
|
+
});
|
|
177
|
+
it('users.ts API callable uses fullPath in the path field', async () => {
|
|
178
|
+
tmpDir = makeTmpDir();
|
|
179
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
180
|
+
const content = readFileSync(join(tmpDir, 'users.ts'), 'utf-8');
|
|
181
|
+
// fullPath ('/api/users/:id') should appear in the callable body
|
|
182
|
+
expect(content).toContain("path: '/api/users/:id'");
|
|
183
|
+
// bare path without prefix should NOT appear as path: value for the api route
|
|
184
|
+
expect(content).not.toContain("path: '/users/:id'");
|
|
185
|
+
});
|
|
186
|
+
it('users.ts exports bindUsersScope function', async () => {
|
|
187
|
+
tmpDir = makeTmpDir();
|
|
188
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
189
|
+
const content = readFileSync(join(tmpDir, 'users.ts'), 'utf-8');
|
|
190
|
+
expect(content).toContain('bindUsersScope');
|
|
191
|
+
});
|
|
192
|
+
it('users.ts uses client.call for RPC route', async () => {
|
|
193
|
+
tmpDir = makeTmpDir();
|
|
194
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
195
|
+
const content = readFileSync(join(tmpDir, 'users.ts'), 'utf-8');
|
|
196
|
+
expect(content).toContain('client.call');
|
|
197
|
+
});
|
|
198
|
+
// ── events.ts — Stream route ───────────────────────────────────────────────
|
|
199
|
+
it('events.ts contains WatchEventsYield type', async () => {
|
|
200
|
+
tmpDir = makeTmpDir();
|
|
201
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
202
|
+
const content = readFileSync(join(tmpDir, 'events.ts'), 'utf-8');
|
|
203
|
+
expect(content).toContain('WatchEventsYield');
|
|
204
|
+
});
|
|
205
|
+
it('events.ts contains WatchEventsReturn type', async () => {
|
|
206
|
+
tmpDir = makeTmpDir();
|
|
207
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
208
|
+
const content = readFileSync(join(tmpDir, 'events.ts'), 'utf-8');
|
|
209
|
+
expect(content).toContain('WatchEventsReturn');
|
|
210
|
+
});
|
|
211
|
+
it('events.ts imports TypedStream', async () => {
|
|
212
|
+
tmpDir = makeTmpDir();
|
|
213
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
214
|
+
const content = readFileSync(join(tmpDir, 'events.ts'), 'utf-8');
|
|
215
|
+
expect(content).toContain('TypedStream');
|
|
216
|
+
});
|
|
217
|
+
it('events.ts uses client.stream', async () => {
|
|
218
|
+
tmpDir = makeTmpDir();
|
|
219
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
220
|
+
const content = readFileSync(join(tmpDir, 'events.ts'), 'utf-8');
|
|
221
|
+
expect(content).toContain('client.stream');
|
|
222
|
+
});
|
|
223
|
+
it("events.ts callable has streamMode: 'sse'", async () => {
|
|
224
|
+
tmpDir = makeTmpDir();
|
|
225
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
226
|
+
const content = readFileSync(join(tmpDir, 'events.ts'), 'utf-8');
|
|
227
|
+
expect(content).toContain("streamMode: 'sse'");
|
|
228
|
+
});
|
|
229
|
+
it('events.ts SSE envelope is unwrapped — yield type does NOT contain event/id/retry fields', async () => {
|
|
230
|
+
tmpDir = makeTmpDir();
|
|
231
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
232
|
+
const content = readFileSync(join(tmpDir, 'events.ts'), 'utf-8');
|
|
233
|
+
// Extract the WatchEventsYield type declaration line
|
|
234
|
+
const yieldMatch = content.match(/export type WatchEventsYield = (.+)/);
|
|
235
|
+
expect(yieldMatch).not.toBeNull();
|
|
236
|
+
const yieldTypeBody = yieldMatch[1];
|
|
237
|
+
// The SSE envelope properties should not appear in the resolved yield type
|
|
238
|
+
expect(yieldTypeBody).not.toContain('event');
|
|
239
|
+
expect(yieldTypeBody).not.toContain('retry');
|
|
240
|
+
});
|
|
241
|
+
// ── index.ts ───────────────────────────────────────────────────────────────
|
|
242
|
+
it('index.ts contains createScopeBindings', async () => {
|
|
243
|
+
tmpDir = makeTmpDir();
|
|
244
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
245
|
+
const content = readFileSync(join(tmpDir, 'index.ts'), 'utf-8');
|
|
246
|
+
expect(content).toContain('createScopeBindings');
|
|
247
|
+
});
|
|
248
|
+
it('index.ts re-exports from users scope', async () => {
|
|
249
|
+
tmpDir = makeTmpDir();
|
|
250
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
251
|
+
const content = readFileSync(join(tmpDir, 'index.ts'), 'utf-8');
|
|
252
|
+
expect(content).toContain("from './users'");
|
|
253
|
+
});
|
|
254
|
+
it('index.ts re-exports from events scope', async () => {
|
|
255
|
+
tmpDir = makeTmpDir();
|
|
256
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
257
|
+
const content = readFileSync(join(tmpDir, 'index.ts'), 'utf-8');
|
|
258
|
+
expect(content).toContain("from './events'");
|
|
259
|
+
});
|
|
260
|
+
it('index.ts imports and uses bindUsersScope', async () => {
|
|
261
|
+
tmpDir = makeTmpDir();
|
|
262
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
263
|
+
const content = readFileSync(join(tmpDir, 'index.ts'), 'utf-8');
|
|
264
|
+
expect(content).toContain('bindUsersScope');
|
|
265
|
+
});
|
|
266
|
+
it('index.ts imports and uses bindEventsScope', async () => {
|
|
267
|
+
tmpDir = makeTmpDir();
|
|
268
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
269
|
+
const content = readFileSync(join(tmpDir, 'index.ts'), 'utf-8');
|
|
270
|
+
expect(content).toContain('bindEventsScope');
|
|
271
|
+
});
|
|
272
|
+
// ── _errors.ts ─────────────────────────────────────────────────────────────
|
|
273
|
+
it('_errors.ts file exists when envelope has errors with schemas', async () => {
|
|
274
|
+
tmpDir = makeTmpDir();
|
|
275
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
276
|
+
expect(existsSync(join(tmpDir, '_errors.ts'))).toBe(true);
|
|
277
|
+
});
|
|
278
|
+
it('_errors.ts contains ProcedureError type', async () => {
|
|
279
|
+
tmpDir = makeTmpDir();
|
|
280
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
281
|
+
const content = readFileSync(join(tmpDir, '_errors.ts'), 'utf-8');
|
|
282
|
+
expect(content).toContain('export type ProcedureError =');
|
|
283
|
+
});
|
|
284
|
+
it('_errors.ts contains ProcedureErrorUnion', async () => {
|
|
285
|
+
tmpDir = makeTmpDir();
|
|
286
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
287
|
+
const content = readFileSync(join(tmpDir, '_errors.ts'), 'utf-8');
|
|
288
|
+
expect(content).toContain('export type ProcedureErrorUnion =');
|
|
289
|
+
expect(content).toContain('ProcedureError');
|
|
290
|
+
expect(content).toContain('ProcedureValidationError');
|
|
291
|
+
});
|
|
292
|
+
it('index.ts re-exports from _errors when errors are present', async () => {
|
|
293
|
+
tmpDir = makeTmpDir();
|
|
294
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
295
|
+
const content = readFileSync(join(tmpDir, 'index.ts'), 'utf-8');
|
|
296
|
+
expect(content).toContain("export * from './_errors'");
|
|
297
|
+
});
|
|
298
|
+
it('_errors.ts is not generated when no errors have schemas', async () => {
|
|
299
|
+
tmpDir = makeTmpDir();
|
|
300
|
+
const envelopeNoErrors = { ...envelope, errors: [] };
|
|
301
|
+
await generateClient({ envelope: envelopeNoErrors, outDir: tmpDir });
|
|
302
|
+
expect(existsSync(join(tmpDir, '_errors.ts'))).toBe(false);
|
|
303
|
+
});
|
|
304
|
+
it('index.ts does not re-export _errors when no errors are present', async () => {
|
|
305
|
+
tmpDir = makeTmpDir();
|
|
306
|
+
const envelopeNoErrors = { ...envelope, errors: [] };
|
|
307
|
+
await generateClient({ envelope: envelopeNoErrors, outDir: tmpDir });
|
|
308
|
+
const content = readFileSync(join(tmpDir, 'index.ts'), 'utf-8');
|
|
309
|
+
expect(content).not.toContain("_errors");
|
|
310
|
+
});
|
|
311
|
+
// ── Auto-generated headers ─────────────────────────────────────────────────
|
|
312
|
+
it('all generated files have the auto-generated header comment', async () => {
|
|
313
|
+
tmpDir = makeTmpDir();
|
|
314
|
+
await generateClient({ envelope, outDir: tmpDir });
|
|
315
|
+
for (const file of ['users.ts', 'events.ts', 'index.ts', '_errors.ts']) {
|
|
316
|
+
const content = readFileSync(join(tmpDir, file), 'utf-8');
|
|
317
|
+
expect(content).toContain('// Auto-generated by ts-procedures-codegen — do not edit');
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
//# sourceMappingURL=e2e.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e.test.js","sourceRoot":"","sources":["../../src/codegen/e2e.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type AjscOptions } from './emit-types.js';
|
|
2
|
+
import type { ErrorDoc } from '../implementations/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generates a TypeScript file with error type declarations from the DocEnvelope.errors array.
|
|
5
|
+
*
|
|
6
|
+
* Only errors with a `schema` property are included. If no errors have schemas,
|
|
7
|
+
* returns `undefined` (no file generated).
|
|
8
|
+
*/
|
|
9
|
+
export declare function emitErrorsFile(errors: ErrorDoc[], ajscOpts?: AjscOptions, _clientImportPath?: string): Promise<string | undefined>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsonSchemaToTypeString } from './emit-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates a TypeScript file with error type declarations from the DocEnvelope.errors array.
|
|
4
|
+
*
|
|
5
|
+
* Only errors with a `schema` property are included. If no errors have schemas,
|
|
6
|
+
* returns `undefined` (no file generated).
|
|
7
|
+
*/
|
|
8
|
+
export async function emitErrorsFile(errors, ajscOpts, _clientImportPath) {
|
|
9
|
+
// Filter to only errors that have a schema
|
|
10
|
+
const errorsWithSchema = errors.filter((e) => e.schema != null);
|
|
11
|
+
if (errorsWithSchema.length === 0) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
const typeLines = [];
|
|
15
|
+
for (const error of errorsWithSchema) {
|
|
16
|
+
const typeDecl = await jsonSchemaToTypeString(error.name, error.schema, ajscOpts);
|
|
17
|
+
if (typeDecl != null) {
|
|
18
|
+
typeLines.push(`/** ${error.description} (HTTP ${error.statusCode}) */`);
|
|
19
|
+
typeLines.push(typeDecl);
|
|
20
|
+
typeLines.push('');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Discriminated union of all error types
|
|
24
|
+
const unionMembers = errorsWithSchema.map((e) => e.name).join(' | ');
|
|
25
|
+
typeLines.push(`export type ProcedureErrorUnion = ${unionMembers}`);
|
|
26
|
+
typeLines.push('');
|
|
27
|
+
const body = typeLines.join('\n');
|
|
28
|
+
return ['// Auto-generated by ts-procedures-codegen — do not edit', '', body].join('\n');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=emit-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-errors.js","sourceRoot":"","sources":["../../src/codegen/emit-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAoB,MAAM,iBAAiB,CAAA;AAG1E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAkB,EAClB,QAAsB,EACtB,iBAA0B;IAE1B,2CAA2C;IAC3C,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAuD,EAAE,CAChG,CAAC,CAAC,MAAM,IAAI,IAAI,CACjB,CAAA;IAED,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,MAAM,SAAS,GAAa,EAAE,CAAA;IAE9B,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QACjF,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,SAAS,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,WAAW,UAAU,KAAK,CAAC,UAAU,MAAM,CAAC,CAAA;YACxE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACxB,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACpE,SAAS,CAAC,IAAI,CAAC,qCAAqC,YAAY,EAAE,CAAC,CAAA;IACnE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAElB,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEjC,OAAO,CAAC,0DAA0D,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC1F,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
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], { enumStyle: 'union' });
|
|
106
|
+
expect(result).toBeDefined();
|
|
107
|
+
expect(result).toContain('export type ProcedureError =');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# 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,6 @@
|
|
|
1
|
+
import type { ScopeGroup } from './group-routes.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates a barrel index file that re-exports all scope files and provides
|
|
4
|
+
* a `createScopeBindings` factory function.
|
|
5
|
+
*/
|
|
6
|
+
export declare function emitIndexFile(groups: ScopeGroup[], clientImportPath?: string, hasErrors?: boolean): string;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Helpers
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/** Converts a string to PascalCase (splits on whitespace, hyphens, underscores). */
|
|
5
|
+
function toPascalCase(str) {
|
|
6
|
+
return str
|
|
7
|
+
.split(/[\s\-_]+/)
|
|
8
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
9
|
+
.join('');
|
|
10
|
+
}
|
|
11
|
+
/** Derives the bind function name from a camelCase scope identifier. */
|
|
12
|
+
function bindFunctionName(camelCase) {
|
|
13
|
+
return `bind${toPascalCase(camelCase)}Scope`;
|
|
14
|
+
}
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// emitIndexFile
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/**
|
|
19
|
+
* Generates a barrel index file that re-exports all scope files and provides
|
|
20
|
+
* a `createScopeBindings` factory function.
|
|
21
|
+
*/
|
|
22
|
+
export function emitIndexFile(groups, clientImportPath = 'ts-procedures/client', hasErrors = false) {
|
|
23
|
+
const bindImports = groups
|
|
24
|
+
.map((g) => `import { ${bindFunctionName(g.camelCase)} } from './${g.scopeKey}'`)
|
|
25
|
+
.join('\n');
|
|
26
|
+
const scopeReExports = groups
|
|
27
|
+
.map((g) => `export * from './${g.scopeKey}'`)
|
|
28
|
+
.join('\n');
|
|
29
|
+
const errorsReExport = hasErrors ? `export * from './_errors'` : '';
|
|
30
|
+
const reExports = [scopeReExports, errorsReExport].filter(Boolean).join('\n');
|
|
31
|
+
const scopeBindings = groups
|
|
32
|
+
.map((g) => ` ${g.camelCase}: ${bindFunctionName(g.camelCase)}(client),`)
|
|
33
|
+
.join('\n');
|
|
34
|
+
return [
|
|
35
|
+
'// Auto-generated by ts-procedures-codegen — do not edit',
|
|
36
|
+
`import type { ClientInstance } from '${clientImportPath}'`,
|
|
37
|
+
bindImports,
|
|
38
|
+
'',
|
|
39
|
+
reExports,
|
|
40
|
+
'',
|
|
41
|
+
'export function createScopeBindings(client: ClientInstance) {',
|
|
42
|
+
' return {',
|
|
43
|
+
scopeBindings,
|
|
44
|
+
' }',
|
|
45
|
+
'}',
|
|
46
|
+
'',
|
|
47
|
+
].join('\n');
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=emit-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-index.js","sourceRoot":"","sources":["../../src/codegen/emit-index.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,oFAAoF;AACpF,SAAS,YAAY,CAAC,GAAW;IAC/B,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,wEAAwE;AACxE,SAAS,gBAAgB,CAAC,SAAiB;IACzC,OAAO,OAAO,YAAY,CAAC,SAAS,CAAC,OAAO,CAAA;AAC9C,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,MAAoB,EAAE,gBAAgB,GAAG,sBAAsB,EAAE,SAAS,GAAG,KAAK;IAC9G,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,0DAA0D;QAC1D,wCAAwC,gBAAgB,GAAG;QAC3D,WAAW;QACX,EAAE;QACF,SAAS;QACT,EAAE;QACF,+DAA+D;QAC/D,YAAY;QACZ,aAAa;QACb,KAAK;QACL,GAAG;QACH,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|