agency-lang 0.0.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 +7 -0
- package/dist/backends/baseGenerator.js +194 -0
- package/dist/backends/graphGenerator.integration.test.js +119 -0
- package/dist/backends/graphGenerator.js +308 -0
- package/dist/backends/index.js +3 -0
- package/dist/backends/typescriptGenerator/builtins.js +46 -0
- package/dist/backends/typescriptGenerator/typeToString.js +36 -0
- package/dist/backends/typescriptGenerator/typeToZodSchema.js +54 -0
- package/dist/backends/typescriptGenerator.integration.test.js +119 -0
- package/dist/backends/typescriptGenerator.js +340 -0
- package/dist/backends/typescriptGenerator.test.js +763 -0
- package/dist/backends/utils.js +6 -0
- package/dist/generate-graph-file.js +25 -0
- package/dist/generate-ts-file.js +26 -0
- package/dist/index.js +3 -0
- package/dist/parser.js +38 -0
- package/dist/parser.test.js +306 -0
- package/dist/parsers/access.js +19 -0
- package/dist/parsers/access.test.js +929 -0
- package/dist/parsers/assignment.js +8 -0
- package/dist/parsers/body.test.js +106 -0
- package/dist/parsers/comment.js +6 -0
- package/dist/parsers/comment.test.js +100 -0
- package/dist/parsers/dataStructures.js +14 -0
- package/dist/parsers/dataStructures.test.js +660 -0
- package/dist/parsers/function.js +22 -0
- package/dist/parsers/function.test.js +591 -0
- package/dist/parsers/functionCall.js +10 -0
- package/dist/parsers/functionCall.test.js +119 -0
- package/dist/parsers/importStatement.js +3 -0
- package/dist/parsers/importStatement.test.js +290 -0
- package/dist/parsers/literals.js +12 -0
- package/dist/parsers/literals.test.js +639 -0
- package/dist/parsers/matchBlock.js +24 -0
- package/dist/parsers/matchBlock.test.js +506 -0
- package/dist/parsers/parserUtils.js +2 -0
- package/dist/parsers/returnStatement.js +8 -0
- package/dist/parsers/tools.js +3 -0
- package/dist/parsers/tools.test.js +170 -0
- package/dist/parsers/typeHints.js +59 -0
- package/dist/parsers/typeHints.test.js +2754 -0
- package/dist/parsers/utils.js +5 -0
- package/dist/parsers/whileLoop.test.js +342 -0
- package/dist/templates/backends/graphGenerator/builtinTools.js +36 -0
- package/dist/templates/backends/graphGenerator/conditionalEdge.js +10 -0
- package/dist/templates/backends/graphGenerator/edge.js +10 -0
- package/dist/templates/backends/graphGenerator/goToNode.js +9 -0
- package/dist/templates/backends/graphGenerator/graphNode.js +15 -0
- package/dist/templates/backends/graphGenerator/imports.js +47 -0
- package/dist/templates/backends/graphGenerator/node.js +18 -0
- package/dist/templates/backends/graphGenerator/promptNode.js +16 -0
- package/dist/templates/backends/graphGenerator/startNode.js +10 -0
- package/dist/templates/backends/typescriptGenerator/builtinFunctions/fetch.js +17 -0
- package/dist/templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.js +17 -0
- package/dist/templates/backends/typescriptGenerator/builtinFunctions/input.js +21 -0
- package/dist/templates/backends/typescriptGenerator/builtinFunctions/read.js +13 -0
- package/dist/templates/backends/typescriptGenerator/builtinTools.js +36 -0
- package/dist/templates/backends/typescriptGenerator/functionDefinition.js +11 -0
- package/dist/templates/backends/typescriptGenerator/imports.js +25 -0
- package/dist/templates/backends/typescriptGenerator/promptFunction.js +76 -0
- package/dist/templates/backends/typescriptGenerator/tool.js +23 -0
- package/dist/templates/backends/typescriptGenerator/toolCall.js +35 -0
- package/dist/types/access.js +1 -0
- package/dist/types/dataStructures.js +1 -0
- package/dist/types/function.js +1 -0
- package/dist/types/graphNode.js +1 -0
- package/dist/types/importStatement.js +1 -0
- package/dist/types/literals.js +1 -0
- package/dist/types/matchBlock.js +1 -0
- package/dist/types/returnStatement.js +1 -0
- package/dist/types/tools.js +1 -0
- package/dist/types/typeHints.js +1 -0
- package/dist/types/whileLoop.js +1 -0
- package/dist/types.js +11 -0
- package/dist/utils.js +18 -0
- package/package.json +52 -0
|
@@ -0,0 +1,763 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { generateTypeScript } from "./typescriptGenerator.js";
|
|
3
|
+
describe("generateTypeScript - ObjectType support", () => {
|
|
4
|
+
describe("Object type hints generate correct Zod schemas", () => {
|
|
5
|
+
it("should generate zod schema for simple object type", () => {
|
|
6
|
+
const program = {
|
|
7
|
+
type: "agencyProgram",
|
|
8
|
+
nodes: [
|
|
9
|
+
{
|
|
10
|
+
type: "typeHint",
|
|
11
|
+
variableName: "point",
|
|
12
|
+
variableType: {
|
|
13
|
+
type: "objectType",
|
|
14
|
+
properties: [
|
|
15
|
+
{
|
|
16
|
+
key: "x",
|
|
17
|
+
value: { type: "primitiveType", value: "number" },
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
key: "y",
|
|
21
|
+
value: { type: "primitiveType", value: "number" },
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: "assignment",
|
|
28
|
+
variableName: "point",
|
|
29
|
+
value: {
|
|
30
|
+
type: "prompt",
|
|
31
|
+
segments: [
|
|
32
|
+
{
|
|
33
|
+
type: "text",
|
|
34
|
+
value: "generate coordinates",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
const result = generateTypeScript(program);
|
|
42
|
+
expect(result).toContain('z.object({ "x": z.number(), "y": z.number() })');
|
|
43
|
+
expect(result).toContain("{ x: number; y: number }");
|
|
44
|
+
});
|
|
45
|
+
it("should generate zod schema for object with different property types", () => {
|
|
46
|
+
const program = {
|
|
47
|
+
type: "agencyProgram",
|
|
48
|
+
nodes: [
|
|
49
|
+
{
|
|
50
|
+
type: "typeHint",
|
|
51
|
+
variableName: "user",
|
|
52
|
+
variableType: {
|
|
53
|
+
type: "objectType",
|
|
54
|
+
properties: [
|
|
55
|
+
{
|
|
56
|
+
key: "name",
|
|
57
|
+
value: { type: "primitiveType", value: "string" },
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
key: "age",
|
|
61
|
+
value: { type: "primitiveType", value: "number" },
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: "active",
|
|
65
|
+
value: { type: "primitiveType", value: "boolean" },
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: "assignment",
|
|
72
|
+
variableName: "user",
|
|
73
|
+
value: {
|
|
74
|
+
type: "prompt",
|
|
75
|
+
segments: [
|
|
76
|
+
{
|
|
77
|
+
type: "text",
|
|
78
|
+
value: "generate user",
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
const result = generateTypeScript(program);
|
|
86
|
+
expect(result).toContain('z.object({ "name": z.string(), "age": z.number(), "active": z.boolean() })');
|
|
87
|
+
expect(result).toContain("{ name: string; age: number; active: boolean }");
|
|
88
|
+
});
|
|
89
|
+
it("should generate zod schema for object with array properties", () => {
|
|
90
|
+
const program = {
|
|
91
|
+
type: "agencyProgram",
|
|
92
|
+
nodes: [
|
|
93
|
+
{
|
|
94
|
+
type: "typeHint",
|
|
95
|
+
variableName: "data",
|
|
96
|
+
variableType: {
|
|
97
|
+
type: "objectType",
|
|
98
|
+
properties: [
|
|
99
|
+
{
|
|
100
|
+
key: "items",
|
|
101
|
+
value: {
|
|
102
|
+
type: "arrayType",
|
|
103
|
+
elementType: { type: "primitiveType", value: "number" },
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
key: "tags",
|
|
108
|
+
value: {
|
|
109
|
+
type: "arrayType",
|
|
110
|
+
elementType: { type: "primitiveType", value: "string" },
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: "assignment",
|
|
118
|
+
variableName: "data",
|
|
119
|
+
value: {
|
|
120
|
+
type: "prompt",
|
|
121
|
+
segments: [
|
|
122
|
+
{
|
|
123
|
+
type: "text",
|
|
124
|
+
value: "generate data",
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
};
|
|
131
|
+
const result = generateTypeScript(program);
|
|
132
|
+
expect(result).toContain('z.object({ "items": z.array(z.number()), "tags": z.array(z.string()) })');
|
|
133
|
+
expect(result).toContain("{ items: number[]; tags: string[] }");
|
|
134
|
+
});
|
|
135
|
+
it("should generate zod schema for object with literal properties", () => {
|
|
136
|
+
const program = {
|
|
137
|
+
type: "agencyProgram",
|
|
138
|
+
nodes: [
|
|
139
|
+
{
|
|
140
|
+
type: "typeHint",
|
|
141
|
+
variableName: "config",
|
|
142
|
+
variableType: {
|
|
143
|
+
type: "objectType",
|
|
144
|
+
properties: [
|
|
145
|
+
{
|
|
146
|
+
key: "status",
|
|
147
|
+
value: { type: "stringLiteralType", value: "active" },
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
key: "count",
|
|
151
|
+
value: { type: "numberLiteralType", value: "42" },
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
key: "enabled",
|
|
155
|
+
value: { type: "booleanLiteralType", value: "true" },
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: "assignment",
|
|
162
|
+
variableName: "config",
|
|
163
|
+
value: {
|
|
164
|
+
type: "prompt",
|
|
165
|
+
segments: [
|
|
166
|
+
{
|
|
167
|
+
type: "text",
|
|
168
|
+
value: "generate config",
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
};
|
|
175
|
+
const result = generateTypeScript(program);
|
|
176
|
+
expect(result).toContain('z.object({ "status": z.literal("active"), "count": z.literal(42), "enabled": z.literal(true) })');
|
|
177
|
+
expect(result).toContain('{ status: "active"; count: 42; enabled: true }');
|
|
178
|
+
});
|
|
179
|
+
it("should generate zod schema for empty object", () => {
|
|
180
|
+
const program = {
|
|
181
|
+
type: "agencyProgram",
|
|
182
|
+
nodes: [
|
|
183
|
+
{
|
|
184
|
+
type: "typeHint",
|
|
185
|
+
variableName: "emptyObj",
|
|
186
|
+
variableType: {
|
|
187
|
+
type: "objectType",
|
|
188
|
+
properties: [],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
type: "assignment",
|
|
193
|
+
variableName: "emptyObj",
|
|
194
|
+
value: {
|
|
195
|
+
type: "prompt",
|
|
196
|
+
segments: [
|
|
197
|
+
{
|
|
198
|
+
type: "text",
|
|
199
|
+
value: "generate empty object",
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
};
|
|
206
|
+
const result = generateTypeScript(program);
|
|
207
|
+
expect(result).toContain("z.object({ })");
|
|
208
|
+
expect(result).toContain("{ }");
|
|
209
|
+
});
|
|
210
|
+
it("should generate zod schema for single property object", () => {
|
|
211
|
+
const program = {
|
|
212
|
+
type: "agencyProgram",
|
|
213
|
+
nodes: [
|
|
214
|
+
{
|
|
215
|
+
type: "typeHint",
|
|
216
|
+
variableName: "single",
|
|
217
|
+
variableType: {
|
|
218
|
+
type: "objectType",
|
|
219
|
+
properties: [
|
|
220
|
+
{
|
|
221
|
+
key: "value",
|
|
222
|
+
value: { type: "primitiveType", value: "string" },
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
type: "assignment",
|
|
229
|
+
variableName: "single",
|
|
230
|
+
value: {
|
|
231
|
+
type: "prompt",
|
|
232
|
+
segments: [
|
|
233
|
+
{
|
|
234
|
+
type: "text",
|
|
235
|
+
value: "generate single",
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
const result = generateTypeScript(program);
|
|
243
|
+
expect(result).toContain('z.object({ "value": z.string() })');
|
|
244
|
+
expect(result).toContain("{ value: string }");
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe("generateTypeScript - Type Alias support", () => {
|
|
249
|
+
describe("Type aliases generate correct TypeScript type definitions", () => {
|
|
250
|
+
it("should generate TypeScript type alias for primitive type", () => {
|
|
251
|
+
const program = {
|
|
252
|
+
type: "agencyProgram",
|
|
253
|
+
nodes: [
|
|
254
|
+
{
|
|
255
|
+
type: "typeAlias",
|
|
256
|
+
aliasName: "Name",
|
|
257
|
+
aliasedType: { type: "primitiveType", value: "string" },
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
};
|
|
261
|
+
const result = generateTypeScript(program);
|
|
262
|
+
expect(result).toContain("type Name = string;");
|
|
263
|
+
});
|
|
264
|
+
it("should generate TypeScript type alias for object type", () => {
|
|
265
|
+
const program = {
|
|
266
|
+
type: "agencyProgram",
|
|
267
|
+
nodes: [
|
|
268
|
+
{
|
|
269
|
+
type: "typeAlias",
|
|
270
|
+
aliasName: "Point",
|
|
271
|
+
aliasedType: {
|
|
272
|
+
type: "objectType",
|
|
273
|
+
properties: [
|
|
274
|
+
{
|
|
275
|
+
key: "x",
|
|
276
|
+
value: { type: "primitiveType", value: "number" },
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
key: "y",
|
|
280
|
+
value: { type: "primitiveType", value: "number" },
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
};
|
|
287
|
+
const result = generateTypeScript(program);
|
|
288
|
+
expect(result).toContain("type Point = { x: number; y: number };");
|
|
289
|
+
});
|
|
290
|
+
it("should generate TypeScript type alias for union type", () => {
|
|
291
|
+
const program = {
|
|
292
|
+
type: "agencyProgram",
|
|
293
|
+
nodes: [
|
|
294
|
+
{
|
|
295
|
+
type: "typeAlias",
|
|
296
|
+
aliasName: "StringOrNumber",
|
|
297
|
+
aliasedType: {
|
|
298
|
+
type: "unionType",
|
|
299
|
+
types: [
|
|
300
|
+
{ type: "primitiveType", value: "string" },
|
|
301
|
+
{ type: "primitiveType", value: "number" },
|
|
302
|
+
],
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
};
|
|
307
|
+
const result = generateTypeScript(program);
|
|
308
|
+
expect(result).toContain("type StringOrNumber = string | number;");
|
|
309
|
+
});
|
|
310
|
+
it("should use type alias in variable type hint and generate correct zod schema", () => {
|
|
311
|
+
const program = {
|
|
312
|
+
type: "agencyProgram",
|
|
313
|
+
nodes: [
|
|
314
|
+
{
|
|
315
|
+
type: "typeAlias",
|
|
316
|
+
aliasName: "Point",
|
|
317
|
+
aliasedType: {
|
|
318
|
+
type: "objectType",
|
|
319
|
+
properties: [
|
|
320
|
+
{
|
|
321
|
+
key: "x",
|
|
322
|
+
value: { type: "primitiveType", value: "number" },
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
key: "y",
|
|
326
|
+
value: { type: "primitiveType", value: "number" },
|
|
327
|
+
},
|
|
328
|
+
],
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
type: "typeHint",
|
|
333
|
+
variableName: "coords",
|
|
334
|
+
variableType: {
|
|
335
|
+
type: "typeAliasVariable",
|
|
336
|
+
aliasName: "Point",
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
type: "assignment",
|
|
341
|
+
variableName: "coords",
|
|
342
|
+
value: {
|
|
343
|
+
type: "prompt",
|
|
344
|
+
segments: [
|
|
345
|
+
{
|
|
346
|
+
type: "text",
|
|
347
|
+
value: "generate coordinates",
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
],
|
|
353
|
+
};
|
|
354
|
+
const result = generateTypeScript(program);
|
|
355
|
+
// Should generate type alias definition
|
|
356
|
+
expect(result).toContain("type Point = { x: number; y: number };");
|
|
357
|
+
// Should use Point as return type in function signature
|
|
358
|
+
expect(result).toContain("Promise<Point>");
|
|
359
|
+
// Should resolve Point to zod schema
|
|
360
|
+
expect(result).toContain('z.object({ "x": z.number(), "y": z.number() })');
|
|
361
|
+
});
|
|
362
|
+
it("should handle type alias used in union", () => {
|
|
363
|
+
const program = {
|
|
364
|
+
type: "agencyProgram",
|
|
365
|
+
nodes: [
|
|
366
|
+
{
|
|
367
|
+
type: "typeAlias",
|
|
368
|
+
aliasName: "Point",
|
|
369
|
+
aliasedType: {
|
|
370
|
+
type: "objectType",
|
|
371
|
+
properties: [
|
|
372
|
+
{
|
|
373
|
+
key: "x",
|
|
374
|
+
value: { type: "primitiveType", value: "number" },
|
|
375
|
+
},
|
|
376
|
+
],
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
type: "typeHint",
|
|
381
|
+
variableName: "data",
|
|
382
|
+
variableType: {
|
|
383
|
+
type: "unionType",
|
|
384
|
+
types: [
|
|
385
|
+
{ type: "primitiveType", value: "string" },
|
|
386
|
+
{
|
|
387
|
+
type: "typeAliasVariable",
|
|
388
|
+
aliasName: "Point",
|
|
389
|
+
},
|
|
390
|
+
],
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
type: "assignment",
|
|
395
|
+
variableName: "data",
|
|
396
|
+
value: {
|
|
397
|
+
type: "prompt",
|
|
398
|
+
segments: [
|
|
399
|
+
{
|
|
400
|
+
type: "text",
|
|
401
|
+
value: "generate data",
|
|
402
|
+
},
|
|
403
|
+
],
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
],
|
|
407
|
+
};
|
|
408
|
+
const result = generateTypeScript(program);
|
|
409
|
+
// Should generate type alias
|
|
410
|
+
expect(result).toContain("type Point = { x: number };");
|
|
411
|
+
// Should use Point in union type as return type
|
|
412
|
+
expect(result).toContain("Promise<string | Point>");
|
|
413
|
+
// Should resolve union with Point to zod schema
|
|
414
|
+
expect(result).toContain('z.union([z.string(), z.object({ "x": z.number() })])');
|
|
415
|
+
});
|
|
416
|
+
it("should handle type alias used in object property", () => {
|
|
417
|
+
const program = {
|
|
418
|
+
type: "agencyProgram",
|
|
419
|
+
nodes: [
|
|
420
|
+
{
|
|
421
|
+
type: "typeAlias",
|
|
422
|
+
aliasName: "Point",
|
|
423
|
+
aliasedType: {
|
|
424
|
+
type: "objectType",
|
|
425
|
+
properties: [
|
|
426
|
+
{
|
|
427
|
+
key: "x",
|
|
428
|
+
value: { type: "primitiveType", value: "number" },
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
key: "y",
|
|
432
|
+
value: { type: "primitiveType", value: "number" },
|
|
433
|
+
},
|
|
434
|
+
],
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
type: "typeHint",
|
|
439
|
+
variableName: "location",
|
|
440
|
+
variableType: {
|
|
441
|
+
type: "objectType",
|
|
442
|
+
properties: [
|
|
443
|
+
{
|
|
444
|
+
key: "coord",
|
|
445
|
+
value: {
|
|
446
|
+
type: "typeAliasVariable",
|
|
447
|
+
aliasName: "Point",
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
],
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
type: "assignment",
|
|
455
|
+
variableName: "location",
|
|
456
|
+
value: {
|
|
457
|
+
type: "prompt",
|
|
458
|
+
segments: [
|
|
459
|
+
{
|
|
460
|
+
type: "text",
|
|
461
|
+
value: "generate location",
|
|
462
|
+
},
|
|
463
|
+
],
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
],
|
|
467
|
+
};
|
|
468
|
+
const result = generateTypeScript(program);
|
|
469
|
+
// Should generate type alias
|
|
470
|
+
expect(result).toContain("type Point = { x: number; y: number };");
|
|
471
|
+
// Should use Point in object property type as return type
|
|
472
|
+
expect(result).toContain("Promise<{ coord: Point }>");
|
|
473
|
+
// Should resolve nested type alias
|
|
474
|
+
expect(result).toContain('z.object({ "coord": z.object({ "x": z.number(), "y": z.number() }) })');
|
|
475
|
+
});
|
|
476
|
+
it("should handle multiple type aliases", () => {
|
|
477
|
+
const program = {
|
|
478
|
+
type: "agencyProgram",
|
|
479
|
+
nodes: [
|
|
480
|
+
{
|
|
481
|
+
type: "typeAlias",
|
|
482
|
+
aliasName: "Point",
|
|
483
|
+
aliasedType: {
|
|
484
|
+
type: "objectType",
|
|
485
|
+
properties: [
|
|
486
|
+
{
|
|
487
|
+
key: "x",
|
|
488
|
+
value: { type: "primitiveType", value: "number" },
|
|
489
|
+
},
|
|
490
|
+
],
|
|
491
|
+
},
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
type: "typeAlias",
|
|
495
|
+
aliasName: "Line",
|
|
496
|
+
aliasedType: {
|
|
497
|
+
type: "objectType",
|
|
498
|
+
properties: [
|
|
499
|
+
{
|
|
500
|
+
key: "length",
|
|
501
|
+
value: { type: "primitiveType", value: "number" },
|
|
502
|
+
},
|
|
503
|
+
],
|
|
504
|
+
},
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
type: "typeHint",
|
|
508
|
+
variableName: "shape",
|
|
509
|
+
variableType: {
|
|
510
|
+
type: "unionType",
|
|
511
|
+
types: [
|
|
512
|
+
{
|
|
513
|
+
type: "typeAliasVariable",
|
|
514
|
+
aliasName: "Point",
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
type: "typeAliasVariable",
|
|
518
|
+
aliasName: "Line",
|
|
519
|
+
},
|
|
520
|
+
],
|
|
521
|
+
},
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
type: "assignment",
|
|
525
|
+
variableName: "shape",
|
|
526
|
+
value: {
|
|
527
|
+
type: "prompt",
|
|
528
|
+
segments: [
|
|
529
|
+
{
|
|
530
|
+
type: "text",
|
|
531
|
+
value: "generate shape",
|
|
532
|
+
},
|
|
533
|
+
],
|
|
534
|
+
},
|
|
535
|
+
},
|
|
536
|
+
],
|
|
537
|
+
};
|
|
538
|
+
const result = generateTypeScript(program);
|
|
539
|
+
// Should generate both type aliases
|
|
540
|
+
expect(result).toContain("type Point = { x: number };");
|
|
541
|
+
expect(result).toContain("type Line = { length: number };");
|
|
542
|
+
// Should use both in union as return type
|
|
543
|
+
expect(result).toContain("Promise<Point | Line>");
|
|
544
|
+
});
|
|
545
|
+
it("should generate type alias for array type", () => {
|
|
546
|
+
const program = {
|
|
547
|
+
type: "agencyProgram",
|
|
548
|
+
nodes: [
|
|
549
|
+
{
|
|
550
|
+
type: "typeAlias",
|
|
551
|
+
aliasName: "Numbers",
|
|
552
|
+
aliasedType: {
|
|
553
|
+
type: "arrayType",
|
|
554
|
+
elementType: { type: "primitiveType", value: "number" },
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
],
|
|
558
|
+
};
|
|
559
|
+
const result = generateTypeScript(program);
|
|
560
|
+
expect(result).toContain("type Numbers = number[];");
|
|
561
|
+
});
|
|
562
|
+
});
|
|
563
|
+
describe("Object properties with descriptions", () => {
|
|
564
|
+
it("should generate Zod schema with .describe() for single property with description", () => {
|
|
565
|
+
const program = {
|
|
566
|
+
type: "agencyProgram",
|
|
567
|
+
nodes: [
|
|
568
|
+
{
|
|
569
|
+
type: "typeHint",
|
|
570
|
+
variableName: "url",
|
|
571
|
+
variableType: {
|
|
572
|
+
type: "objectType",
|
|
573
|
+
properties: [
|
|
574
|
+
{
|
|
575
|
+
key: "hostname",
|
|
576
|
+
value: { type: "primitiveType", value: "string" },
|
|
577
|
+
description: "hostname of a url",
|
|
578
|
+
},
|
|
579
|
+
],
|
|
580
|
+
},
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
type: "assignment",
|
|
584
|
+
variableName: "url",
|
|
585
|
+
value: {
|
|
586
|
+
type: "prompt",
|
|
587
|
+
segments: [
|
|
588
|
+
{
|
|
589
|
+
type: "text",
|
|
590
|
+
value: "extract url",
|
|
591
|
+
},
|
|
592
|
+
],
|
|
593
|
+
},
|
|
594
|
+
},
|
|
595
|
+
],
|
|
596
|
+
};
|
|
597
|
+
const result = generateTypeScript(program);
|
|
598
|
+
expect(result).toContain('z.object({ "hostname": z.string().describe("hostname of a url") })');
|
|
599
|
+
});
|
|
600
|
+
it("should generate Zod schema with .describe() for multiple properties with descriptions", () => {
|
|
601
|
+
const program = {
|
|
602
|
+
type: "agencyProgram",
|
|
603
|
+
nodes: [
|
|
604
|
+
{
|
|
605
|
+
type: "typeHint",
|
|
606
|
+
variableName: "point",
|
|
607
|
+
variableType: {
|
|
608
|
+
type: "objectType",
|
|
609
|
+
properties: [
|
|
610
|
+
{
|
|
611
|
+
key: "x",
|
|
612
|
+
value: { type: "primitiveType", value: "number" },
|
|
613
|
+
description: "x coordinate",
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
key: "y",
|
|
617
|
+
value: { type: "primitiveType", value: "number" },
|
|
618
|
+
description: "y coordinate",
|
|
619
|
+
},
|
|
620
|
+
],
|
|
621
|
+
},
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
type: "assignment",
|
|
625
|
+
variableName: "point",
|
|
626
|
+
value: {
|
|
627
|
+
type: "prompt",
|
|
628
|
+
segments: [
|
|
629
|
+
{
|
|
630
|
+
type: "text",
|
|
631
|
+
value: "generate point",
|
|
632
|
+
},
|
|
633
|
+
],
|
|
634
|
+
},
|
|
635
|
+
},
|
|
636
|
+
],
|
|
637
|
+
};
|
|
638
|
+
const result = generateTypeScript(program);
|
|
639
|
+
expect(result).toContain('z.object({ "x": z.number().describe("x coordinate"), "y": z.number().describe("y coordinate") })');
|
|
640
|
+
});
|
|
641
|
+
it("should handle mix of properties with and without descriptions", () => {
|
|
642
|
+
const program = {
|
|
643
|
+
type: "agencyProgram",
|
|
644
|
+
nodes: [
|
|
645
|
+
{
|
|
646
|
+
type: "typeHint",
|
|
647
|
+
variableName: "user",
|
|
648
|
+
variableType: {
|
|
649
|
+
type: "objectType",
|
|
650
|
+
properties: [
|
|
651
|
+
{
|
|
652
|
+
key: "name",
|
|
653
|
+
value: { type: "primitiveType", value: "string" },
|
|
654
|
+
description: "user name",
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
key: "age",
|
|
658
|
+
value: { type: "primitiveType", value: "number" },
|
|
659
|
+
// No description
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
key: "active",
|
|
663
|
+
value: { type: "primitiveType", value: "boolean" },
|
|
664
|
+
description: "is user active",
|
|
665
|
+
},
|
|
666
|
+
],
|
|
667
|
+
},
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
type: "assignment",
|
|
671
|
+
variableName: "user",
|
|
672
|
+
value: {
|
|
673
|
+
type: "prompt",
|
|
674
|
+
segments: [
|
|
675
|
+
{
|
|
676
|
+
type: "text",
|
|
677
|
+
value: "generate user",
|
|
678
|
+
},
|
|
679
|
+
],
|
|
680
|
+
},
|
|
681
|
+
},
|
|
682
|
+
],
|
|
683
|
+
};
|
|
684
|
+
const result = generateTypeScript(program);
|
|
685
|
+
expect(result).toContain('z.object({ "name": z.string().describe("user name"), "age": z.number(), "active": z.boolean().describe("is user active") })');
|
|
686
|
+
});
|
|
687
|
+
it("should escape special characters in descriptions", () => {
|
|
688
|
+
const program = {
|
|
689
|
+
type: "agencyProgram",
|
|
690
|
+
nodes: [
|
|
691
|
+
{
|
|
692
|
+
type: "typeHint",
|
|
693
|
+
variableName: "data",
|
|
694
|
+
variableType: {
|
|
695
|
+
type: "objectType",
|
|
696
|
+
properties: [
|
|
697
|
+
{
|
|
698
|
+
key: "value",
|
|
699
|
+
value: { type: "primitiveType", value: "string" },
|
|
700
|
+
description: 'test "quotes" and \\backslashes\\',
|
|
701
|
+
},
|
|
702
|
+
],
|
|
703
|
+
},
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
type: "assignment",
|
|
707
|
+
variableName: "data",
|
|
708
|
+
value: {
|
|
709
|
+
type: "prompt",
|
|
710
|
+
segments: [
|
|
711
|
+
{
|
|
712
|
+
type: "text",
|
|
713
|
+
value: "generate data",
|
|
714
|
+
},
|
|
715
|
+
],
|
|
716
|
+
},
|
|
717
|
+
},
|
|
718
|
+
],
|
|
719
|
+
};
|
|
720
|
+
const result = generateTypeScript(program);
|
|
721
|
+
expect(result).toContain('z.object({ "value": z.string().describe("test \\"quotes\\" and \\\\backslashes\\\\") })');
|
|
722
|
+
});
|
|
723
|
+
it("should generate descriptions for array properties", () => {
|
|
724
|
+
const program = {
|
|
725
|
+
type: "agencyProgram",
|
|
726
|
+
nodes: [
|
|
727
|
+
{
|
|
728
|
+
type: "typeHint",
|
|
729
|
+
variableName: "items",
|
|
730
|
+
variableType: {
|
|
731
|
+
type: "objectType",
|
|
732
|
+
properties: [
|
|
733
|
+
{
|
|
734
|
+
key: "ids",
|
|
735
|
+
value: {
|
|
736
|
+
type: "arrayType",
|
|
737
|
+
elementType: { type: "primitiveType", value: "number" },
|
|
738
|
+
},
|
|
739
|
+
description: "list of item ids",
|
|
740
|
+
},
|
|
741
|
+
],
|
|
742
|
+
},
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
type: "assignment",
|
|
746
|
+
variableName: "items",
|
|
747
|
+
value: {
|
|
748
|
+
type: "prompt",
|
|
749
|
+
segments: [
|
|
750
|
+
{
|
|
751
|
+
type: "text",
|
|
752
|
+
value: "generate items",
|
|
753
|
+
},
|
|
754
|
+
],
|
|
755
|
+
},
|
|
756
|
+
},
|
|
757
|
+
],
|
|
758
|
+
};
|
|
759
|
+
const result = generateTypeScript(program);
|
|
760
|
+
expect(result).toContain('z.object({ "ids": z.array(z.number()).describe("list of item ids") })');
|
|
761
|
+
});
|
|
762
|
+
});
|
|
763
|
+
});
|