zod-codegen 1.6.3 → 1.7.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/.github/workflows/ci.yml +50 -48
- package/.github/workflows/release.yml +13 -3
- package/.husky/commit-msg +1 -1
- package/.husky/pre-commit +1 -1
- package/.lintstagedrc.json +5 -1
- package/.nvmrc +1 -1
- package/.prettierrc.json +12 -5
- package/CHANGELOG.md +17 -0
- package/CONTRIBUTING.md +12 -12
- package/EXAMPLES.md +135 -57
- package/PERFORMANCE.md +4 -4
- package/README.md +87 -64
- package/SECURITY.md +1 -1
- package/dist/src/cli.js +11 -18
- package/dist/src/generator.d.ts +2 -2
- package/dist/src/generator.d.ts.map +1 -1
- package/dist/src/generator.js +5 -3
- package/dist/src/interfaces/code-generator.d.ts.map +1 -1
- package/dist/src/services/code-generator.service.d.ts +3 -1
- package/dist/src/services/code-generator.service.d.ts.map +1 -1
- package/dist/src/services/code-generator.service.js +236 -219
- package/dist/src/services/file-reader.service.d.ts +2 -0
- package/dist/src/services/file-reader.service.d.ts.map +1 -1
- package/dist/src/services/file-reader.service.js +25 -11
- package/dist/src/services/file-writer.service.d.ts.map +1 -1
- package/dist/src/services/file-writer.service.js +2 -2
- package/dist/src/services/import-builder.service.d.ts.map +1 -1
- package/dist/src/services/import-builder.service.js +3 -3
- package/dist/src/services/type-builder.service.d.ts.map +1 -1
- package/dist/src/types/generator-options.d.ts.map +1 -1
- package/dist/src/types/openapi.d.ts.map +1 -1
- package/dist/src/types/openapi.js +20 -20
- package/dist/src/utils/error-handler.d.ts.map +1 -1
- package/dist/src/utils/naming-convention.d.ts.map +1 -1
- package/dist/src/utils/naming-convention.js +6 -3
- package/dist/src/utils/signal-handler.d.ts.map +1 -1
- package/dist/tests/integration/cli-comprehensive.test.d.ts +2 -0
- package/dist/tests/integration/cli-comprehensive.test.d.ts.map +1 -0
- package/dist/tests/integration/cli-comprehensive.test.js +123 -0
- package/dist/tests/integration/cli.test.d.ts +2 -0
- package/dist/tests/integration/cli.test.d.ts.map +1 -0
- package/dist/tests/integration/cli.test.js +25 -0
- package/dist/tests/integration/error-scenarios.test.d.ts +2 -0
- package/dist/tests/integration/error-scenarios.test.d.ts.map +1 -0
- package/dist/tests/integration/error-scenarios.test.js +169 -0
- package/dist/tests/integration/snapshots.test.d.ts +2 -0
- package/dist/tests/integration/snapshots.test.d.ts.map +1 -0
- package/dist/tests/integration/snapshots.test.js +100 -0
- package/dist/tests/unit/code-generator-edge-cases.test.d.ts +2 -0
- package/dist/tests/unit/code-generator-edge-cases.test.d.ts.map +1 -0
- package/dist/tests/unit/code-generator-edge-cases.test.js +506 -0
- package/dist/tests/unit/code-generator.test.d.ts +2 -0
- package/dist/tests/unit/code-generator.test.d.ts.map +1 -0
- package/dist/tests/unit/code-generator.test.js +1364 -0
- package/dist/tests/unit/file-reader.test.d.ts +2 -0
- package/dist/tests/unit/file-reader.test.d.ts.map +1 -0
- package/dist/tests/unit/file-reader.test.js +153 -0
- package/dist/tests/unit/generator.test.d.ts +2 -0
- package/dist/tests/unit/generator.test.d.ts.map +1 -0
- package/dist/tests/unit/generator.test.js +119 -0
- package/dist/tests/unit/naming-convention.test.d.ts +2 -0
- package/dist/tests/unit/naming-convention.test.d.ts.map +1 -0
- package/dist/tests/unit/naming-convention.test.js +256 -0
- package/dist/tests/unit/reporter.test.d.ts +2 -0
- package/dist/tests/unit/reporter.test.d.ts.map +1 -0
- package/dist/tests/unit/reporter.test.js +44 -0
- package/dist/tests/unit/type-builder.test.d.ts +2 -0
- package/dist/tests/unit/type-builder.test.d.ts.map +1 -0
- package/dist/tests/unit/type-builder.test.js +108 -0
- package/dist/vitest.config.d.ts.map +1 -1
- package/dist/vitest.config.js +10 -20
- package/eslint.config.mjs +38 -28
- package/examples/.gitkeep +1 -1
- package/examples/README.md +4 -2
- package/examples/petstore/README.md +18 -17
- package/examples/petstore/{type.ts → api.ts} +158 -74
- package/examples/petstore/authenticated-usage.ts +6 -4
- package/examples/petstore/basic-usage.ts +4 -3
- package/examples/petstore/error-handling-usage.ts +84 -0
- package/examples/petstore/retry-handler-usage.ts +11 -18
- package/examples/petstore/server-variables-usage.ts +10 -10
- package/examples/pokeapi/README.md +8 -8
- package/examples/pokeapi/api.ts +218 -0
- package/examples/pokeapi/basic-usage.ts +3 -2
- package/examples/pokeapi/custom-client.ts +5 -4
- package/package.json +17 -21
- package/src/cli.ts +20 -25
- package/src/generator.ts +13 -11
- package/src/interfaces/code-generator.ts +1 -1
- package/src/services/code-generator.service.ts +799 -1120
- package/src/services/file-reader.service.ts +35 -15
- package/src/services/file-writer.service.ts +7 -7
- package/src/services/import-builder.service.ts +9 -13
- package/src/services/type-builder.service.ts +8 -19
- package/src/types/generator-options.ts +1 -1
- package/src/types/openapi.ts +22 -22
- package/src/utils/error-handler.ts +2 -2
- package/src/utils/naming-convention.ts +13 -10
- package/src/utils/reporter.ts +2 -2
- package/src/utils/signal-handler.ts +7 -8
- package/tests/integration/cli-comprehensive.test.ts +53 -31
- package/tests/integration/cli.test.ts +5 -5
- package/tests/integration/error-scenarios.test.ts +20 -26
- package/tests/integration/snapshots.test.ts +19 -23
- package/tests/unit/code-generator-edge-cases.test.ts +133 -133
- package/tests/unit/code-generator.test.ts +431 -330
- package/tests/unit/file-reader.test.ts +58 -18
- package/tests/unit/generator.test.ts +30 -18
- package/tests/unit/naming-convention.test.ts +27 -27
- package/tests/unit/type-builder.test.ts +2 -2
- package/tsconfig.json +5 -3
- package/vitest.config.ts +11 -21
- package/dist/scripts/update-manifest.d.ts +0 -14
- package/dist/scripts/update-manifest.d.ts.map +0 -1
- package/dist/scripts/update-manifest.js +0 -33
- package/dist/src/assets/manifest.json +0 -5
- package/examples/pokeapi/type.ts +0 -109
- package/generated/type.ts +0 -371
- package/scripts/update-manifest.ts +0 -49
- package/src/assets/manifest.json +0 -5
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
import jp from 'jsonpath';
|
|
2
1
|
import * as ts from 'typescript';
|
|
3
|
-
import {z} from 'zod';
|
|
4
|
-
import type {CodeGenerator, SchemaBuilder} from '../interfaces/code-generator';
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
7
|
-
import {MethodSchema, Reference, SchemaProperties} from '../types/openapi';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
type NamingConvention,
|
|
12
|
-
type OperationDetails,
|
|
13
|
-
type OperationNameTransformer,
|
|
14
|
-
transformNamingConvention,
|
|
15
|
-
} from '../utils/naming-convention';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { CodeGenerator, SchemaBuilder } from '../interfaces/code-generator';
|
|
4
|
+
import type { GeneratorOptions } from '../types/generator-options';
|
|
5
|
+
import type { MethodSchemaType, OpenApiSpecType, ReferenceType } from '../types/openapi';
|
|
6
|
+
import { MethodSchema, Reference, SchemaProperties } from '../types/openapi';
|
|
7
|
+
import { type NamingConvention, type OperationDetails, type OperationNameTransformer, transformNamingConvention } from '../utils/naming-convention';
|
|
8
|
+
import { TypeScriptImportBuilderService } from './import-builder.service';
|
|
9
|
+
import { TypeScriptTypeBuilderService } from './type-builder.service';
|
|
16
10
|
|
|
17
11
|
export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuilder {
|
|
18
12
|
private readonly typeBuilder = new TypeScriptTypeBuilderService();
|
|
19
13
|
private readonly importBuilder = new TypeScriptImportBuilderService();
|
|
20
|
-
private readonly printer = ts.createPrinter({newLine: ts.NewLineKind.LineFeed});
|
|
14
|
+
private readonly printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
21
15
|
private readonly namingConvention: NamingConvention | undefined;
|
|
22
16
|
private readonly operationNameTransformer: OperationNameTransformer | undefined;
|
|
23
17
|
|
|
@@ -32,11 +26,40 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
32
26
|
|
|
33
27
|
private readonly ZodAST = z.object({
|
|
34
28
|
type: z.enum(['string', 'number', 'boolean', 'object', 'array', 'unknown', 'record']),
|
|
35
|
-
args: z.array(z.unknown()).optional()
|
|
29
|
+
args: z.array(z.unknown()).optional()
|
|
36
30
|
});
|
|
37
31
|
|
|
32
|
+
private extractSchemaReferences(schema: unknown): string[] {
|
|
33
|
+
const references = new Set<string>();
|
|
34
|
+
|
|
35
|
+
const walk = (node: unknown): void => {
|
|
36
|
+
if (Array.isArray(node)) {
|
|
37
|
+
for (const item of node) {
|
|
38
|
+
walk(item);
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (node === null || typeof node !== 'object') {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
for (const [key, value] of Object.entries(node as Record<string, unknown>)) {
|
|
48
|
+
if (key === '$ref' && typeof value === 'string' && value.startsWith('#/components/schemas/')) {
|
|
49
|
+
references.add(value.replace('#/components/schemas/', ''));
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
walk(value);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
walk(schema);
|
|
58
|
+
return [...references];
|
|
59
|
+
}
|
|
60
|
+
|
|
38
61
|
generate(spec: OpenApiSpecType): string {
|
|
39
|
-
const file = ts.createSourceFile('
|
|
62
|
+
const file = ts.createSourceFile('api.ts', '', ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
|
|
40
63
|
const nodes = this.buildAST(spec);
|
|
41
64
|
return this.printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(nodes), file);
|
|
42
65
|
}
|
|
@@ -86,8 +109,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
86
109
|
...Object.values(schemas),
|
|
87
110
|
...schemaTypeAliases,
|
|
88
111
|
...serverConfig,
|
|
112
|
+
this.buildResponseValidationErrorClass(),
|
|
89
113
|
this.createComment('Client class'),
|
|
90
|
-
clientClass
|
|
114
|
+
clientClass
|
|
91
115
|
];
|
|
92
116
|
}
|
|
93
117
|
|
|
@@ -102,7 +126,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
102
126
|
|
|
103
127
|
return sortedSchemaNames.reduce<Record<string, ts.VariableStatement>>((schemaRegistered, name) => {
|
|
104
128
|
const schema = openapi.components?.schemas?.[name];
|
|
105
|
-
if (!schema)
|
|
129
|
+
if (!schema) {
|
|
130
|
+
return schemaRegistered;
|
|
131
|
+
}
|
|
106
132
|
|
|
107
133
|
// Set context for current schema being built
|
|
108
134
|
this.currentSchemaName = name;
|
|
@@ -115,29 +141,21 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
115
141
|
const sanitizedName = this.typeBuilder.sanitizeIdentifier(name);
|
|
116
142
|
|
|
117
143
|
// Add type annotation: z.ZodType<Name>
|
|
118
|
-
const typeAnnotation = ts.factory.createTypeReferenceNode(
|
|
119
|
-
ts.factory.
|
|
120
|
-
|
|
121
|
-
);
|
|
144
|
+
const typeAnnotation = ts.factory.createTypeReferenceNode(ts.factory.createQualifiedName(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('ZodType')), [
|
|
145
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedName), undefined)
|
|
146
|
+
]);
|
|
122
147
|
|
|
123
148
|
const variableStatement = ts.factory.createVariableStatement(
|
|
124
149
|
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
125
150
|
ts.factory.createVariableDeclarationList(
|
|
126
|
-
[
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
undefined,
|
|
130
|
-
typeAnnotation,
|
|
131
|
-
schemaExpression,
|
|
132
|
-
),
|
|
133
|
-
],
|
|
134
|
-
ts.NodeFlags.Const,
|
|
135
|
-
),
|
|
151
|
+
[ts.factory.createVariableDeclaration(ts.factory.createIdentifier(sanitizedName), undefined, typeAnnotation, schemaExpression)],
|
|
152
|
+
ts.NodeFlags.Const
|
|
153
|
+
)
|
|
136
154
|
);
|
|
137
155
|
|
|
138
156
|
return {
|
|
139
157
|
...schemaRegistered,
|
|
140
|
-
[name]: variableStatement
|
|
158
|
+
[name]: variableStatement
|
|
141
159
|
};
|
|
142
160
|
}, {});
|
|
143
161
|
}
|
|
@@ -160,7 +178,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
160
178
|
|
|
161
179
|
for (const name of sortedSchemaNames) {
|
|
162
180
|
const schema = openapi.components?.schemas?.[name];
|
|
163
|
-
if (!schema)
|
|
181
|
+
if (!schema) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
164
184
|
|
|
165
185
|
const sanitizedName = this.typeBuilder.sanitizeIdentifier(name);
|
|
166
186
|
const safeSchema = SchemaProperties.safeParse(schema);
|
|
@@ -172,8 +192,8 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
172
192
|
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
173
193
|
ts.factory.createIdentifier(sanitizedName),
|
|
174
194
|
undefined,
|
|
175
|
-
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)
|
|
176
|
-
)
|
|
195
|
+
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)
|
|
196
|
+
)
|
|
177
197
|
);
|
|
178
198
|
continue;
|
|
179
199
|
}
|
|
@@ -189,12 +209,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
189
209
|
|
|
190
210
|
// For all other types (enums, arrays, unions, etc.), create a type alias
|
|
191
211
|
statements.push(
|
|
192
|
-
ts.factory.createTypeAliasDeclaration(
|
|
193
|
-
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
194
|
-
ts.factory.createIdentifier(sanitizedName),
|
|
195
|
-
undefined,
|
|
196
|
-
typeNode,
|
|
197
|
-
),
|
|
212
|
+
ts.factory.createTypeAliasDeclaration([ts.factory.createToken(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(sanitizedName), undefined, typeNode)
|
|
198
213
|
);
|
|
199
214
|
}
|
|
200
215
|
|
|
@@ -214,7 +229,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
214
229
|
|
|
215
230
|
// Handle $ref
|
|
216
231
|
if (this.isReference(prop)) {
|
|
217
|
-
const {$ref = ''} = Reference.parse(prop);
|
|
232
|
+
const { $ref = '' } = Reference.parse(prop);
|
|
218
233
|
const refName = $ref.split('/').pop() ?? 'never';
|
|
219
234
|
const sanitizedRefName = this.typeBuilder.sanitizeIdentifier(refName);
|
|
220
235
|
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedRefName), undefined);
|
|
@@ -259,17 +274,14 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
259
274
|
return ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(val, true));
|
|
260
275
|
} else if (typeof val === 'number') {
|
|
261
276
|
if (val < 0) {
|
|
262
|
-
return ts.factory.createLiteralTypeNode(
|
|
263
|
-
ts.factory.createPrefixUnaryExpression(
|
|
264
|
-
ts.SyntaxKind.MinusToken,
|
|
265
|
-
ts.factory.createNumericLiteral(String(Math.abs(val))),
|
|
266
|
-
),
|
|
267
|
-
);
|
|
277
|
+
return ts.factory.createLiteralTypeNode(ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, ts.factory.createNumericLiteral(String(Math.abs(val)))));
|
|
268
278
|
}
|
|
279
|
+
|
|
269
280
|
return ts.factory.createLiteralTypeNode(ts.factory.createNumericLiteral(String(val)));
|
|
270
281
|
} else if (typeof val === 'boolean') {
|
|
271
282
|
return ts.factory.createLiteralTypeNode(val ? ts.factory.createTrue() : ts.factory.createFalse());
|
|
272
283
|
}
|
|
284
|
+
|
|
273
285
|
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
|
|
274
286
|
});
|
|
275
287
|
return ts.factory.createUnionTypeNode(literalTypes);
|
|
@@ -285,9 +297,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
285
297
|
case 'boolean':
|
|
286
298
|
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
|
|
287
299
|
case 'array': {
|
|
288
|
-
const itemsType = prop['items']
|
|
289
|
-
? this.buildTypeNode(prop['items'])
|
|
290
|
-
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
|
|
300
|
+
const itemsType = prop['items'] ? this.buildTypeNode(prop['items']) : ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
|
|
291
301
|
return ts.factory.createArrayTypeNode(itemsType);
|
|
292
302
|
}
|
|
293
303
|
case 'object': {
|
|
@@ -301,7 +311,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
301
311
|
// Empty object or additionalProperties - use Record<string, unknown>
|
|
302
312
|
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Record'), [
|
|
303
313
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
304
|
-
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)
|
|
314
|
+
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)
|
|
305
315
|
]);
|
|
306
316
|
}
|
|
307
317
|
default:
|
|
@@ -321,7 +331,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
321
331
|
undefined,
|
|
322
332
|
ts.factory.createIdentifier(name),
|
|
323
333
|
isRequired ? undefined : ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
324
|
-
typeNode
|
|
334
|
+
typeNode
|
|
325
335
|
);
|
|
326
336
|
});
|
|
327
337
|
|
|
@@ -343,23 +353,106 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
343
353
|
undefined,
|
|
344
354
|
ts.factory.createIdentifier(propName),
|
|
345
355
|
isRequired ? undefined : ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
346
|
-
typeNode
|
|
356
|
+
typeNode
|
|
347
357
|
);
|
|
348
358
|
});
|
|
349
359
|
|
|
350
|
-
return ts.factory.createInterfaceDeclaration(
|
|
351
|
-
|
|
352
|
-
|
|
360
|
+
return ts.factory.createInterfaceDeclaration([ts.factory.createToken(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(name), undefined, undefined, members);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
private buildResponseValidationErrorClass(): ts.ClassDeclaration {
|
|
364
|
+
const typeParamT = ts.factory.createTypeParameterDeclaration(undefined, 'T');
|
|
365
|
+
|
|
366
|
+
const responseProperty = ts.factory.createPropertyDeclaration(
|
|
367
|
+
[ts.factory.createToken(ts.SyntaxKind.ReadonlyKeyword)],
|
|
368
|
+
'response',
|
|
353
369
|
undefined,
|
|
370
|
+
ts.factory.createTypeReferenceNode('Response'),
|
|
371
|
+
undefined
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
const errorProperty = ts.factory.createPropertyDeclaration(
|
|
375
|
+
[ts.factory.createToken(ts.SyntaxKind.ReadonlyKeyword)],
|
|
376
|
+
'error',
|
|
377
|
+
undefined,
|
|
378
|
+
ts.factory.createTypeReferenceNode(ts.factory.createQualifiedName(ts.factory.createIdentifier('z'), 'ZodError'), [ts.factory.createTypeReferenceNode('T')]),
|
|
379
|
+
undefined
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
const constructorDecl = ts.factory.createConstructorDeclaration(
|
|
383
|
+
undefined,
|
|
384
|
+
[
|
|
385
|
+
ts.factory.createParameterDeclaration(undefined, undefined, 'message', undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)),
|
|
386
|
+
ts.factory.createParameterDeclaration(undefined, undefined, 'response', undefined, ts.factory.createTypeReferenceNode('Response')),
|
|
387
|
+
ts.factory.createParameterDeclaration(
|
|
388
|
+
undefined,
|
|
389
|
+
undefined,
|
|
390
|
+
'error',
|
|
391
|
+
undefined,
|
|
392
|
+
ts.factory.createTypeReferenceNode(ts.factory.createQualifiedName(ts.factory.createIdentifier('z'), 'ZodError'), [ts.factory.createTypeReferenceNode('T')])
|
|
393
|
+
)
|
|
394
|
+
],
|
|
395
|
+
ts.factory.createBlock(
|
|
396
|
+
[
|
|
397
|
+
ts.factory.createExpressionStatement(ts.factory.createCallExpression(ts.factory.createSuper(), undefined, [ts.factory.createIdentifier('message')])),
|
|
398
|
+
ts.factory.createExpressionStatement(
|
|
399
|
+
ts.factory.createBinaryExpression(
|
|
400
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), 'name'),
|
|
401
|
+
ts.SyntaxKind.EqualsToken,
|
|
402
|
+
ts.factory.createAsExpression(ts.factory.createStringLiteral('ResponseValidationError', true), ts.factory.createTypeReferenceNode('const'))
|
|
403
|
+
)
|
|
404
|
+
),
|
|
405
|
+
ts.factory.createExpressionStatement(
|
|
406
|
+
ts.factory.createBinaryExpression(
|
|
407
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), 'response'),
|
|
408
|
+
ts.SyntaxKind.EqualsToken,
|
|
409
|
+
ts.factory.createIdentifier('response')
|
|
410
|
+
)
|
|
411
|
+
),
|
|
412
|
+
ts.factory.createExpressionStatement(
|
|
413
|
+
ts.factory.createBinaryExpression(
|
|
414
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), 'error'),
|
|
415
|
+
ts.SyntaxKind.EqualsToken,
|
|
416
|
+
ts.factory.createIdentifier('error')
|
|
417
|
+
)
|
|
418
|
+
)
|
|
419
|
+
],
|
|
420
|
+
true
|
|
421
|
+
)
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
const dataGetter = ts.factory.createGetAccessorDeclaration(
|
|
354
425
|
undefined,
|
|
355
|
-
|
|
426
|
+
'data',
|
|
427
|
+
[],
|
|
428
|
+
ts.factory.createTypeReferenceNode('T'),
|
|
429
|
+
ts.factory.createBlock(
|
|
430
|
+
[
|
|
431
|
+
ts.factory.createReturnStatement(
|
|
432
|
+
ts.factory.createAsExpression(
|
|
433
|
+
ts.factory.createCallExpression(
|
|
434
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createThis(), 'response'), 'json'),
|
|
435
|
+
undefined,
|
|
436
|
+
[]
|
|
437
|
+
),
|
|
438
|
+
ts.factory.createTypeReferenceNode('T')
|
|
439
|
+
)
|
|
440
|
+
)
|
|
441
|
+
],
|
|
442
|
+
true
|
|
443
|
+
)
|
|
444
|
+
);
|
|
445
|
+
|
|
446
|
+
return ts.factory.createClassDeclaration(
|
|
447
|
+
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
448
|
+
'ResponseValidationError',
|
|
449
|
+
[typeParamT],
|
|
450
|
+
[ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier('Error'), undefined)])],
|
|
451
|
+
[responseProperty, errorProperty, constructorDecl, dataGetter]
|
|
356
452
|
);
|
|
357
453
|
}
|
|
358
454
|
|
|
359
|
-
private buildClientClass(
|
|
360
|
-
openapi: OpenApiSpecType,
|
|
361
|
-
schemas: Record<string, ts.VariableStatement>,
|
|
362
|
-
): ts.ClassDeclaration {
|
|
455
|
+
private buildClientClass(openapi: OpenApiSpecType, schemas: Record<string, ts.VariableStatement>): ts.ClassDeclaration {
|
|
363
456
|
const clientName = this.generateClientName(openapi.info.title);
|
|
364
457
|
const methods = this.buildClientMethods(openapi, schemas);
|
|
365
458
|
|
|
@@ -374,8 +467,8 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
374
467
|
this.buildGetBaseRequestOptionsMethod(),
|
|
375
468
|
this.buildHandleResponseMethod(),
|
|
376
469
|
this.buildHttpRequestMethod(),
|
|
377
|
-
...methods
|
|
378
|
-
]
|
|
470
|
+
...methods
|
|
471
|
+
]
|
|
379
472
|
);
|
|
380
473
|
}
|
|
381
474
|
|
|
@@ -393,8 +486,8 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
393
486
|
ts.factory.createIdentifier('options'),
|
|
394
487
|
undefined,
|
|
395
488
|
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('ClientOptions'), undefined),
|
|
396
|
-
undefined
|
|
397
|
-
)
|
|
489
|
+
undefined
|
|
490
|
+
)
|
|
398
491
|
],
|
|
399
492
|
ts.factory.createBlock(
|
|
400
493
|
[
|
|
@@ -408,72 +501,51 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
408
501
|
undefined,
|
|
409
502
|
ts.factory.createConditionalExpression(
|
|
410
503
|
ts.factory.createBinaryExpression(
|
|
411
|
-
ts.factory.createPropertyAccessExpression(
|
|
412
|
-
ts.factory.createIdentifier('options'),
|
|
413
|
-
ts.factory.createIdentifier('baseUrl'),
|
|
414
|
-
),
|
|
504
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('baseUrl')),
|
|
415
505
|
ts.factory.createToken(ts.SyntaxKind.ExclamationEqualsEqualsToken),
|
|
416
|
-
ts.factory.createNull()
|
|
506
|
+
ts.factory.createNull()
|
|
417
507
|
),
|
|
418
508
|
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
419
|
-
ts.factory.createPropertyAccessExpression(
|
|
420
|
-
ts.factory.createIdentifier('options'),
|
|
421
|
-
ts.factory.createIdentifier('baseUrl'),
|
|
422
|
-
),
|
|
509
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('baseUrl')),
|
|
423
510
|
ts.factory.createToken(ts.SyntaxKind.ColonToken),
|
|
424
511
|
ts.factory.createCallExpression(ts.factory.createIdentifier('resolveServerUrl'), undefined, [
|
|
425
|
-
ts.factory.createPropertyAccessExpression(
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
ts.factory.createIdentifier('options'),
|
|
431
|
-
ts.factory.createIdentifier('serverVariables'),
|
|
432
|
-
),
|
|
433
|
-
]),
|
|
434
|
-
),
|
|
435
|
-
),
|
|
512
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('serverIndex')),
|
|
513
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('serverVariables'))
|
|
514
|
+
])
|
|
515
|
+
)
|
|
516
|
+
)
|
|
436
517
|
],
|
|
437
|
-
ts.NodeFlags.Const
|
|
438
|
-
)
|
|
518
|
+
ts.NodeFlags.Const
|
|
519
|
+
)
|
|
439
520
|
),
|
|
440
521
|
ts.factory.createExpressionStatement(
|
|
441
522
|
ts.factory.createBinaryExpression(
|
|
442
|
-
ts.factory.createPropertyAccessExpression(
|
|
443
|
-
ts.factory.createThis(),
|
|
444
|
-
ts.factory.createPrivateIdentifier('#baseUrl'),
|
|
445
|
-
),
|
|
523
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), ts.factory.createPrivateIdentifier('#baseUrl')),
|
|
446
524
|
ts.factory.createToken(ts.SyntaxKind.EqualsToken),
|
|
447
|
-
ts.factory.createIdentifier('resolvedUrl')
|
|
448
|
-
)
|
|
449
|
-
)
|
|
525
|
+
ts.factory.createIdentifier('resolvedUrl')
|
|
526
|
+
)
|
|
527
|
+
)
|
|
450
528
|
],
|
|
451
|
-
true
|
|
452
|
-
)
|
|
529
|
+
true
|
|
530
|
+
)
|
|
453
531
|
);
|
|
454
532
|
} else {
|
|
455
533
|
// Fallback: simple baseUrl parameter
|
|
456
534
|
return ts.factory.createConstructorDeclaration(
|
|
457
535
|
undefined,
|
|
458
|
-
[
|
|
459
|
-
this.typeBuilder.createParameter('baseUrl', 'string', ts.factory.createStringLiteral('/', true)),
|
|
460
|
-
this.typeBuilder.createParameter('_', 'unknown', undefined, true),
|
|
461
|
-
],
|
|
536
|
+
[this.typeBuilder.createParameter('baseUrl', 'string', ts.factory.createStringLiteral('/', true)), this.typeBuilder.createParameter('_', 'unknown', undefined, true)],
|
|
462
537
|
ts.factory.createBlock(
|
|
463
538
|
[
|
|
464
539
|
ts.factory.createExpressionStatement(
|
|
465
540
|
ts.factory.createBinaryExpression(
|
|
466
|
-
ts.factory.createPropertyAccessExpression(
|
|
467
|
-
ts.factory.createThis(),
|
|
468
|
-
ts.factory.createPrivateIdentifier('#baseUrl'),
|
|
469
|
-
),
|
|
541
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), ts.factory.createPrivateIdentifier('#baseUrl')),
|
|
470
542
|
ts.factory.createToken(ts.SyntaxKind.EqualsToken),
|
|
471
|
-
ts.factory.createIdentifier('baseUrl')
|
|
472
|
-
)
|
|
473
|
-
)
|
|
543
|
+
ts.factory.createIdentifier('baseUrl')
|
|
544
|
+
)
|
|
545
|
+
)
|
|
474
546
|
],
|
|
475
|
-
true
|
|
476
|
-
)
|
|
547
|
+
true
|
|
548
|
+
)
|
|
477
549
|
);
|
|
478
550
|
}
|
|
479
551
|
}
|
|
@@ -491,14 +563,11 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
491
563
|
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('RequestInit'), undefined),
|
|
492
564
|
ts.factory.createUnionTypeNode([
|
|
493
565
|
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('method', true)),
|
|
494
|
-
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('body', true))
|
|
495
|
-
])
|
|
496
|
-
])
|
|
566
|
+
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('body', true))
|
|
567
|
+
])
|
|
568
|
+
])
|
|
497
569
|
]),
|
|
498
|
-
ts.factory.createBlock(
|
|
499
|
-
[ts.factory.createReturnStatement(ts.factory.createObjectLiteralExpression([], false))],
|
|
500
|
-
true,
|
|
501
|
-
),
|
|
570
|
+
ts.factory.createBlock([ts.factory.createReturnStatement(ts.factory.createObjectLiteralExpression([], false))], true)
|
|
502
571
|
);
|
|
503
572
|
}
|
|
504
573
|
|
|
@@ -513,15 +582,10 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
513
582
|
this.typeBuilder.createParameter('response', 'Response'),
|
|
514
583
|
this.typeBuilder.createParameter('method', 'string'),
|
|
515
584
|
this.typeBuilder.createParameter('path', 'string'),
|
|
516
|
-
this.typeBuilder.createParameter(
|
|
517
|
-
'options',
|
|
518
|
-
'{params?: Record<string, string | number | boolean>; data?: unknown; contentType?: string; headers?: Record<string, string>}',
|
|
519
|
-
),
|
|
585
|
+
this.typeBuilder.createParameter('options', '{params?: Record<string, string | number | boolean>; data?: unknown; contentType?: string; headers?: Record<string, string>}')
|
|
520
586
|
],
|
|
521
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
522
|
-
|
|
523
|
-
]),
|
|
524
|
-
ts.factory.createBlock([ts.factory.createReturnStatement(ts.factory.createIdentifier('response'))], true),
|
|
587
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Response'), undefined)]),
|
|
588
|
+
ts.factory.createBlock([ts.factory.createReturnStatement(ts.factory.createIdentifier('response'))], true)
|
|
525
589
|
);
|
|
526
590
|
}
|
|
527
591
|
|
|
@@ -539,12 +603,10 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
539
603
|
'options',
|
|
540
604
|
'{params?: Record<string, string | number | boolean>; data?: unknown; contentType?: string; headers?: Record<string, string>}',
|
|
541
605
|
ts.factory.createObjectLiteralExpression([], false),
|
|
542
|
-
false
|
|
543
|
-
)
|
|
606
|
+
false
|
|
607
|
+
)
|
|
544
608
|
],
|
|
545
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
546
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('T'), undefined),
|
|
547
|
-
]),
|
|
609
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('T'), undefined)]),
|
|
548
610
|
ts.factory.createBlock(
|
|
549
611
|
[
|
|
550
612
|
// Create initial URL object that we will use to build the final URL
|
|
@@ -558,15 +620,12 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
558
620
|
undefined,
|
|
559
621
|
ts.factory.createNewExpression(ts.factory.createIdentifier('URL'), undefined, [
|
|
560
622
|
ts.factory.createIdentifier('path'),
|
|
561
|
-
ts.factory.createPropertyAccessExpression(
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
),
|
|
565
|
-
]),
|
|
566
|
-
),
|
|
623
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), ts.factory.createPrivateIdentifier('#baseUrl'))
|
|
624
|
+
])
|
|
625
|
+
)
|
|
567
626
|
],
|
|
568
|
-
ts.NodeFlags.Const
|
|
569
|
-
)
|
|
627
|
+
ts.NodeFlags.Const
|
|
628
|
+
)
|
|
570
629
|
),
|
|
571
630
|
ts.factory.createVariableStatement(
|
|
572
631
|
undefined,
|
|
@@ -578,31 +637,20 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
578
637
|
undefined,
|
|
579
638
|
ts.factory.createConditionalExpression(
|
|
580
639
|
ts.factory.createBinaryExpression(
|
|
581
|
-
ts.factory.createPropertyAccessExpression(
|
|
582
|
-
ts.factory.createIdentifier('options'),
|
|
583
|
-
ts.factory.createIdentifier('params'),
|
|
584
|
-
),
|
|
640
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('params')),
|
|
585
641
|
ts.factory.createToken(ts.SyntaxKind.AmpersandAmpersandToken),
|
|
586
642
|
ts.factory.createBinaryExpression(
|
|
587
643
|
ts.factory.createPropertyAccessExpression(
|
|
588
644
|
ts.factory.createCallExpression(
|
|
589
|
-
ts.factory.createPropertyAccessExpression(
|
|
590
|
-
ts.factory.createIdentifier('Object'),
|
|
591
|
-
ts.factory.createIdentifier('keys'),
|
|
592
|
-
),
|
|
645
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('Object'), ts.factory.createIdentifier('keys')),
|
|
593
646
|
undefined,
|
|
594
|
-
[
|
|
595
|
-
ts.factory.createPropertyAccessExpression(
|
|
596
|
-
ts.factory.createIdentifier('options'),
|
|
597
|
-
ts.factory.createIdentifier('params'),
|
|
598
|
-
),
|
|
599
|
-
],
|
|
647
|
+
[ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('params'))]
|
|
600
648
|
),
|
|
601
|
-
ts.factory.createIdentifier('length')
|
|
649
|
+
ts.factory.createIdentifier('length')
|
|
602
650
|
),
|
|
603
651
|
ts.factory.createToken(ts.SyntaxKind.GreaterThanToken),
|
|
604
|
-
ts.factory.createNumericLiteral('0')
|
|
605
|
-
)
|
|
652
|
+
ts.factory.createNumericLiteral('0')
|
|
653
|
+
)
|
|
606
654
|
),
|
|
607
655
|
undefined,
|
|
608
656
|
ts.factory.createCallExpression(
|
|
@@ -621,19 +669,11 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
621
669
|
ts.factory.createCallExpression(
|
|
622
670
|
ts.factory.createPropertyAccessExpression(
|
|
623
671
|
ts.factory.createCallExpression(
|
|
624
|
-
ts.factory.createPropertyAccessExpression(
|
|
625
|
-
ts.factory.createIdentifier('Object'),
|
|
626
|
-
ts.factory.createIdentifier('entries'),
|
|
627
|
-
),
|
|
672
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('Object'), ts.factory.createIdentifier('entries')),
|
|
628
673
|
undefined,
|
|
629
|
-
[
|
|
630
|
-
ts.factory.createPropertyAccessExpression(
|
|
631
|
-
ts.factory.createIdentifier('options'),
|
|
632
|
-
ts.factory.createIdentifier('params'),
|
|
633
|
-
),
|
|
634
|
-
],
|
|
674
|
+
[ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('params'))]
|
|
635
675
|
),
|
|
636
|
-
ts.factory.createIdentifier('filter')
|
|
676
|
+
ts.factory.createIdentifier('filter')
|
|
637
677
|
),
|
|
638
678
|
undefined,
|
|
639
679
|
[
|
|
@@ -645,34 +685,24 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
645
685
|
undefined,
|
|
646
686
|
undefined,
|
|
647
687
|
ts.factory.createArrayBindingPattern([
|
|
648
|
-
ts.factory.createBindingElement(
|
|
649
|
-
|
|
650
|
-
undefined,
|
|
651
|
-
ts.factory.createIdentifier(''),
|
|
652
|
-
undefined,
|
|
653
|
-
),
|
|
654
|
-
ts.factory.createBindingElement(
|
|
655
|
-
undefined,
|
|
656
|
-
undefined,
|
|
657
|
-
ts.factory.createIdentifier('value'),
|
|
658
|
-
undefined,
|
|
659
|
-
),
|
|
688
|
+
ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier(''), undefined),
|
|
689
|
+
ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier('value'), undefined)
|
|
660
690
|
]),
|
|
661
691
|
undefined,
|
|
662
|
-
undefined
|
|
663
|
-
)
|
|
692
|
+
undefined
|
|
693
|
+
)
|
|
664
694
|
],
|
|
665
695
|
undefined,
|
|
666
696
|
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
667
697
|
ts.factory.createBinaryExpression(
|
|
668
698
|
ts.factory.createIdentifier('value'),
|
|
669
699
|
ts.SyntaxKind.ExclamationEqualsEqualsToken,
|
|
670
|
-
ts.factory.createIdentifier('undefined')
|
|
671
|
-
)
|
|
672
|
-
)
|
|
673
|
-
]
|
|
700
|
+
ts.factory.createIdentifier('undefined')
|
|
701
|
+
)
|
|
702
|
+
)
|
|
703
|
+
]
|
|
674
704
|
),
|
|
675
|
-
ts.factory.createIdentifier('forEach')
|
|
705
|
+
ts.factory.createIdentifier('forEach')
|
|
676
706
|
),
|
|
677
707
|
undefined,
|
|
678
708
|
[
|
|
@@ -684,22 +714,12 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
684
714
|
undefined,
|
|
685
715
|
undefined,
|
|
686
716
|
ts.factory.createArrayBindingPattern([
|
|
687
|
-
ts.factory.createBindingElement(
|
|
688
|
-
|
|
689
|
-
undefined,
|
|
690
|
-
ts.factory.createIdentifier('key'),
|
|
691
|
-
undefined,
|
|
692
|
-
),
|
|
693
|
-
ts.factory.createBindingElement(
|
|
694
|
-
undefined,
|
|
695
|
-
undefined,
|
|
696
|
-
ts.factory.createIdentifier('value'),
|
|
697
|
-
undefined,
|
|
698
|
-
),
|
|
717
|
+
ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier('key'), undefined),
|
|
718
|
+
ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier('value'), undefined)
|
|
699
719
|
]),
|
|
700
720
|
undefined,
|
|
701
|
-
undefined
|
|
702
|
-
)
|
|
721
|
+
undefined
|
|
722
|
+
)
|
|
703
723
|
],
|
|
704
724
|
undefined,
|
|
705
725
|
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
@@ -708,62 +728,49 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
708
728
|
ts.factory.createExpressionStatement(
|
|
709
729
|
ts.factory.createCallExpression(
|
|
710
730
|
ts.factory.createPropertyAccessExpression(
|
|
711
|
-
ts.factory.createPropertyAccessExpression(
|
|
712
|
-
|
|
713
|
-
ts.factory.createIdentifier('searchParams'),
|
|
714
|
-
),
|
|
715
|
-
ts.factory.createIdentifier('set'),
|
|
731
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('baseUrl'), ts.factory.createIdentifier('searchParams')),
|
|
732
|
+
ts.factory.createIdentifier('set')
|
|
716
733
|
),
|
|
717
734
|
undefined,
|
|
718
735
|
[
|
|
719
736
|
ts.factory.createIdentifier('key'),
|
|
720
|
-
ts.factory.createCallExpression(
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
),
|
|
725
|
-
],
|
|
726
|
-
),
|
|
727
|
-
),
|
|
737
|
+
ts.factory.createCallExpression(ts.factory.createIdentifier('String'), undefined, [ts.factory.createIdentifier('value')])
|
|
738
|
+
]
|
|
739
|
+
)
|
|
740
|
+
)
|
|
728
741
|
],
|
|
729
|
-
false
|
|
730
|
-
)
|
|
731
|
-
)
|
|
732
|
-
]
|
|
733
|
-
)
|
|
742
|
+
false
|
|
743
|
+
)
|
|
744
|
+
)
|
|
745
|
+
]
|
|
746
|
+
)
|
|
734
747
|
),
|
|
735
748
|
ts.factory.createReturnStatement(
|
|
736
749
|
ts.factory.createCallExpression(
|
|
737
|
-
ts.factory.createPropertyAccessExpression(
|
|
738
|
-
ts.factory.createIdentifier('baseUrl'),
|
|
739
|
-
ts.factory.createIdentifier('toString'),
|
|
740
|
-
),
|
|
750
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('baseUrl'), ts.factory.createIdentifier('toString')),
|
|
741
751
|
undefined,
|
|
742
|
-
[]
|
|
743
|
-
)
|
|
744
|
-
)
|
|
752
|
+
[]
|
|
753
|
+
)
|
|
754
|
+
)
|
|
745
755
|
],
|
|
746
|
-
true
|
|
747
|
-
)
|
|
748
|
-
)
|
|
756
|
+
true
|
|
757
|
+
)
|
|
758
|
+
)
|
|
749
759
|
),
|
|
750
760
|
undefined,
|
|
751
|
-
[]
|
|
761
|
+
[]
|
|
752
762
|
),
|
|
753
763
|
undefined,
|
|
754
764
|
ts.factory.createCallExpression(
|
|
755
|
-
ts.factory.createPropertyAccessExpression(
|
|
756
|
-
ts.factory.createIdentifier('baseUrl'),
|
|
757
|
-
ts.factory.createIdentifier('toString'),
|
|
758
|
-
),
|
|
765
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('baseUrl'), ts.factory.createIdentifier('toString')),
|
|
759
766
|
undefined,
|
|
760
|
-
[]
|
|
761
|
-
)
|
|
762
|
-
)
|
|
763
|
-
)
|
|
767
|
+
[]
|
|
768
|
+
)
|
|
769
|
+
)
|
|
770
|
+
)
|
|
764
771
|
],
|
|
765
|
-
ts.NodeFlags.Const
|
|
766
|
-
)
|
|
772
|
+
ts.NodeFlags.Const
|
|
773
|
+
)
|
|
767
774
|
),
|
|
768
775
|
// Get base request options (headers, signal, credentials, etc.)
|
|
769
776
|
ts.factory.createVariableStatement(
|
|
@@ -775,17 +782,14 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
775
782
|
undefined,
|
|
776
783
|
undefined,
|
|
777
784
|
ts.factory.createCallExpression(
|
|
778
|
-
ts.factory.createPropertyAccessExpression(
|
|
779
|
-
ts.factory.createThis(),
|
|
780
|
-
ts.factory.createIdentifier('getBaseRequestOptions'),
|
|
781
|
-
),
|
|
785
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), ts.factory.createIdentifier('getBaseRequestOptions')),
|
|
782
786
|
undefined,
|
|
783
|
-
[]
|
|
784
|
-
)
|
|
785
|
-
)
|
|
787
|
+
[]
|
|
788
|
+
)
|
|
789
|
+
)
|
|
786
790
|
],
|
|
787
|
-
ts.NodeFlags.Const
|
|
788
|
-
)
|
|
791
|
+
ts.NodeFlags.Const
|
|
792
|
+
)
|
|
789
793
|
),
|
|
790
794
|
// Build Content-Type header
|
|
791
795
|
ts.factory.createVariableStatement(
|
|
@@ -798,22 +802,19 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
798
802
|
undefined,
|
|
799
803
|
ts.factory.createConditionalExpression(
|
|
800
804
|
ts.factory.createBinaryExpression(
|
|
801
|
-
ts.factory.createPropertyAccessExpression(
|
|
802
|
-
ts.factory.createIdentifier('options'),
|
|
803
|
-
ts.factory.createIdentifier('contentType'),
|
|
804
|
-
),
|
|
805
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('contentType')),
|
|
805
806
|
ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken),
|
|
806
|
-
ts.factory.createStringLiteral('application/x-www-form-urlencoded', true)
|
|
807
|
+
ts.factory.createStringLiteral('application/x-www-form-urlencoded', true)
|
|
807
808
|
),
|
|
808
809
|
undefined,
|
|
809
810
|
ts.factory.createStringLiteral('application/x-www-form-urlencoded', true),
|
|
810
811
|
undefined,
|
|
811
|
-
ts.factory.createStringLiteral('application/json', true)
|
|
812
|
-
)
|
|
813
|
-
)
|
|
812
|
+
ts.factory.createStringLiteral('application/json', true)
|
|
813
|
+
)
|
|
814
|
+
)
|
|
814
815
|
],
|
|
815
|
-
ts.NodeFlags.Const
|
|
816
|
-
)
|
|
816
|
+
ts.NodeFlags.Const
|
|
817
|
+
)
|
|
817
818
|
),
|
|
818
819
|
// Merge headers: base headers, Content-Type, and request-specific headers
|
|
819
820
|
ts.factory.createVariableStatement(
|
|
@@ -826,25 +827,19 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
826
827
|
undefined,
|
|
827
828
|
ts.factory.createConditionalExpression(
|
|
828
829
|
ts.factory.createBinaryExpression(
|
|
829
|
-
ts.factory.createPropertyAccessExpression(
|
|
830
|
-
ts.factory.createIdentifier('baseOptions'),
|
|
831
|
-
ts.factory.createIdentifier('headers'),
|
|
832
|
-
),
|
|
830
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('baseOptions'), ts.factory.createIdentifier('headers')),
|
|
833
831
|
ts.factory.createToken(ts.SyntaxKind.ExclamationEqualsEqualsToken),
|
|
834
|
-
ts.factory.createIdentifier('undefined')
|
|
832
|
+
ts.factory.createIdentifier('undefined')
|
|
835
833
|
),
|
|
836
834
|
undefined,
|
|
837
|
-
ts.factory.createPropertyAccessExpression(
|
|
838
|
-
ts.factory.createIdentifier('baseOptions'),
|
|
839
|
-
ts.factory.createIdentifier('headers'),
|
|
840
|
-
),
|
|
835
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('baseOptions'), ts.factory.createIdentifier('headers')),
|
|
841
836
|
undefined,
|
|
842
|
-
ts.factory.createObjectLiteralExpression([], false)
|
|
843
|
-
)
|
|
844
|
-
)
|
|
837
|
+
ts.factory.createObjectLiteralExpression([], false)
|
|
838
|
+
)
|
|
839
|
+
)
|
|
845
840
|
],
|
|
846
|
-
ts.NodeFlags.Const
|
|
847
|
-
)
|
|
841
|
+
ts.NodeFlags.Const
|
|
842
|
+
)
|
|
848
843
|
),
|
|
849
844
|
ts.factory.createVariableStatement(
|
|
850
845
|
undefined,
|
|
@@ -855,46 +850,32 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
855
850
|
undefined,
|
|
856
851
|
undefined,
|
|
857
852
|
ts.factory.createCallExpression(
|
|
858
|
-
ts.factory.createPropertyAccessExpression(
|
|
859
|
-
ts.factory.createIdentifier('Object'),
|
|
860
|
-
ts.factory.createIdentifier('assign'),
|
|
861
|
-
),
|
|
853
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('Object'), ts.factory.createIdentifier('assign')),
|
|
862
854
|
undefined,
|
|
863
855
|
[
|
|
864
856
|
ts.factory.createObjectLiteralExpression([], false),
|
|
865
857
|
ts.factory.createIdentifier('baseHeaders'),
|
|
866
858
|
ts.factory.createObjectLiteralExpression(
|
|
867
|
-
[
|
|
868
|
-
|
|
869
|
-
ts.factory.createStringLiteral('Content-Type', true),
|
|
870
|
-
ts.factory.createIdentifier('contentType'),
|
|
871
|
-
),
|
|
872
|
-
],
|
|
873
|
-
false,
|
|
859
|
+
[ts.factory.createPropertyAssignment(ts.factory.createStringLiteral('Content-Type', true), ts.factory.createIdentifier('contentType'))],
|
|
860
|
+
false
|
|
874
861
|
),
|
|
875
862
|
ts.factory.createConditionalExpression(
|
|
876
863
|
ts.factory.createBinaryExpression(
|
|
877
|
-
ts.factory.createPropertyAccessExpression(
|
|
878
|
-
ts.factory.createIdentifier('options'),
|
|
879
|
-
ts.factory.createIdentifier('headers'),
|
|
880
|
-
),
|
|
864
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('headers')),
|
|
881
865
|
ts.factory.createToken(ts.SyntaxKind.ExclamationEqualsEqualsToken),
|
|
882
|
-
ts.factory.createIdentifier('undefined')
|
|
866
|
+
ts.factory.createIdentifier('undefined')
|
|
883
867
|
),
|
|
884
868
|
undefined,
|
|
885
|
-
ts.factory.createPropertyAccessExpression(
|
|
886
|
-
ts.factory.createIdentifier('options'),
|
|
887
|
-
ts.factory.createIdentifier('headers'),
|
|
888
|
-
),
|
|
869
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('headers')),
|
|
889
870
|
undefined,
|
|
890
|
-
ts.factory.createObjectLiteralExpression([], false)
|
|
891
|
-
)
|
|
892
|
-
]
|
|
893
|
-
)
|
|
894
|
-
)
|
|
871
|
+
ts.factory.createObjectLiteralExpression([], false)
|
|
872
|
+
)
|
|
873
|
+
]
|
|
874
|
+
)
|
|
875
|
+
)
|
|
895
876
|
],
|
|
896
|
-
ts.NodeFlags.Const
|
|
897
|
-
)
|
|
877
|
+
ts.NodeFlags.Const
|
|
878
|
+
)
|
|
898
879
|
),
|
|
899
880
|
// Build body with form-urlencoded support
|
|
900
881
|
ts.factory.createVariableStatement(
|
|
@@ -907,22 +888,16 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
907
888
|
undefined,
|
|
908
889
|
ts.factory.createConditionalExpression(
|
|
909
890
|
ts.factory.createBinaryExpression(
|
|
910
|
-
ts.factory.createPropertyAccessExpression(
|
|
911
|
-
ts.factory.createIdentifier('options'),
|
|
912
|
-
ts.factory.createIdentifier('data'),
|
|
913
|
-
),
|
|
891
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('data')),
|
|
914
892
|
ts.factory.createToken(ts.SyntaxKind.ExclamationEqualsEqualsToken),
|
|
915
|
-
ts.factory.createIdentifier('undefined')
|
|
893
|
+
ts.factory.createIdentifier('undefined')
|
|
916
894
|
),
|
|
917
895
|
undefined,
|
|
918
896
|
ts.factory.createConditionalExpression(
|
|
919
897
|
ts.factory.createBinaryExpression(
|
|
920
|
-
ts.factory.createPropertyAccessExpression(
|
|
921
|
-
ts.factory.createIdentifier('options'),
|
|
922
|
-
ts.factory.createIdentifier('contentType'),
|
|
923
|
-
),
|
|
898
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('contentType')),
|
|
924
899
|
ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken),
|
|
925
|
-
ts.factory.createStringLiteral('application/x-www-form-urlencoded', true)
|
|
900
|
+
ts.factory.createStringLiteral('application/x-www-form-urlencoded', true)
|
|
926
901
|
),
|
|
927
902
|
undefined,
|
|
928
903
|
// Form-urlencoded: convert object to URLSearchParams
|
|
@@ -944,33 +919,21 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
944
919
|
ts.factory.createIdentifier('params'),
|
|
945
920
|
undefined,
|
|
946
921
|
undefined,
|
|
947
|
-
ts.factory.createNewExpression(
|
|
948
|
-
|
|
949
|
-
undefined,
|
|
950
|
-
[],
|
|
951
|
-
),
|
|
952
|
-
),
|
|
922
|
+
ts.factory.createNewExpression(ts.factory.createIdentifier('URLSearchParams'), undefined, [])
|
|
923
|
+
)
|
|
953
924
|
],
|
|
954
|
-
ts.NodeFlags.Const
|
|
955
|
-
)
|
|
925
|
+
ts.NodeFlags.Const
|
|
926
|
+
)
|
|
956
927
|
),
|
|
957
928
|
ts.factory.createExpressionStatement(
|
|
958
929
|
ts.factory.createCallExpression(
|
|
959
930
|
ts.factory.createPropertyAccessExpression(
|
|
960
931
|
ts.factory.createCallExpression(
|
|
961
|
-
ts.factory.createPropertyAccessExpression(
|
|
962
|
-
ts.factory.createIdentifier('Object'),
|
|
963
|
-
ts.factory.createIdentifier('entries'),
|
|
964
|
-
),
|
|
932
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('Object'), ts.factory.createIdentifier('entries')),
|
|
965
933
|
undefined,
|
|
966
|
-
[
|
|
967
|
-
ts.factory.createPropertyAccessExpression(
|
|
968
|
-
ts.factory.createIdentifier('options'),
|
|
969
|
-
ts.factory.createIdentifier('data'),
|
|
970
|
-
),
|
|
971
|
-
],
|
|
934
|
+
[ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('data'))]
|
|
972
935
|
),
|
|
973
|
-
ts.factory.createIdentifier('forEach')
|
|
936
|
+
ts.factory.createIdentifier('forEach')
|
|
974
937
|
),
|
|
975
938
|
undefined,
|
|
976
939
|
[
|
|
@@ -982,22 +945,12 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
982
945
|
undefined,
|
|
983
946
|
undefined,
|
|
984
947
|
ts.factory.createArrayBindingPattern([
|
|
985
|
-
ts.factory.createBindingElement(
|
|
986
|
-
|
|
987
|
-
undefined,
|
|
988
|
-
ts.factory.createIdentifier('key'),
|
|
989
|
-
undefined,
|
|
990
|
-
),
|
|
991
|
-
ts.factory.createBindingElement(
|
|
992
|
-
undefined,
|
|
993
|
-
undefined,
|
|
994
|
-
ts.factory.createIdentifier('value'),
|
|
995
|
-
undefined,
|
|
996
|
-
),
|
|
948
|
+
ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier('key'), undefined),
|
|
949
|
+
ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier('value'), undefined)
|
|
997
950
|
]),
|
|
998
951
|
undefined,
|
|
999
|
-
undefined
|
|
1000
|
-
)
|
|
952
|
+
undefined
|
|
953
|
+
)
|
|
1001
954
|
],
|
|
1002
955
|
undefined,
|
|
1003
956
|
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
@@ -1005,69 +958,51 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1005
958
|
[
|
|
1006
959
|
ts.factory.createExpressionStatement(
|
|
1007
960
|
ts.factory.createCallExpression(
|
|
1008
|
-
ts.factory.createPropertyAccessExpression(
|
|
1009
|
-
ts.factory.createIdentifier('params'),
|
|
1010
|
-
ts.factory.createIdentifier('set'),
|
|
1011
|
-
),
|
|
961
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('params'), ts.factory.createIdentifier('set')),
|
|
1012
962
|
undefined,
|
|
1013
963
|
[
|
|
1014
964
|
ts.factory.createIdentifier('key'),
|
|
1015
|
-
ts.factory.createCallExpression(
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
),
|
|
1020
|
-
],
|
|
1021
|
-
),
|
|
1022
|
-
),
|
|
965
|
+
ts.factory.createCallExpression(ts.factory.createIdentifier('String'), undefined, [ts.factory.createIdentifier('value')])
|
|
966
|
+
]
|
|
967
|
+
)
|
|
968
|
+
)
|
|
1023
969
|
],
|
|
1024
|
-
false
|
|
1025
|
-
)
|
|
1026
|
-
)
|
|
1027
|
-
]
|
|
1028
|
-
)
|
|
970
|
+
false
|
|
971
|
+
)
|
|
972
|
+
)
|
|
973
|
+
]
|
|
974
|
+
)
|
|
1029
975
|
),
|
|
1030
976
|
ts.factory.createReturnStatement(
|
|
1031
977
|
ts.factory.createCallExpression(
|
|
1032
|
-
ts.factory.createPropertyAccessExpression(
|
|
1033
|
-
ts.factory.createIdentifier('params'),
|
|
1034
|
-
ts.factory.createIdentifier('toString'),
|
|
1035
|
-
),
|
|
978
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('params'), ts.factory.createIdentifier('toString')),
|
|
1036
979
|
undefined,
|
|
1037
|
-
[]
|
|
1038
|
-
)
|
|
1039
|
-
)
|
|
980
|
+
[]
|
|
981
|
+
)
|
|
982
|
+
)
|
|
1040
983
|
],
|
|
1041
|
-
false
|
|
1042
|
-
)
|
|
1043
|
-
)
|
|
984
|
+
false
|
|
985
|
+
)
|
|
986
|
+
)
|
|
1044
987
|
),
|
|
1045
988
|
undefined,
|
|
1046
|
-
[]
|
|
989
|
+
[]
|
|
1047
990
|
),
|
|
1048
991
|
undefined,
|
|
1049
992
|
// JSON: stringify the data
|
|
1050
993
|
ts.factory.createCallExpression(
|
|
1051
|
-
ts.factory.createPropertyAccessExpression(
|
|
1052
|
-
ts.factory.createIdentifier('JSON'),
|
|
1053
|
-
ts.factory.createIdentifier('stringify'),
|
|
1054
|
-
),
|
|
994
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('JSON'), ts.factory.createIdentifier('stringify')),
|
|
1055
995
|
undefined,
|
|
1056
|
-
[
|
|
1057
|
-
|
|
1058
|
-
ts.factory.createIdentifier('options'),
|
|
1059
|
-
ts.factory.createIdentifier('data'),
|
|
1060
|
-
),
|
|
1061
|
-
],
|
|
1062
|
-
),
|
|
996
|
+
[ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('options'), ts.factory.createIdentifier('data'))]
|
|
997
|
+
)
|
|
1063
998
|
),
|
|
1064
999
|
undefined,
|
|
1065
|
-
ts.factory.createNull()
|
|
1066
|
-
)
|
|
1067
|
-
)
|
|
1000
|
+
ts.factory.createNull()
|
|
1001
|
+
)
|
|
1002
|
+
)
|
|
1068
1003
|
],
|
|
1069
|
-
ts.NodeFlags.Const
|
|
1070
|
-
)
|
|
1004
|
+
ts.NodeFlags.Const
|
|
1005
|
+
)
|
|
1071
1006
|
),
|
|
1072
1007
|
// Make fetch request: merge base options with method, headers, and body
|
|
1073
1008
|
ts.factory.createVariableStatement(
|
|
@@ -1082,39 +1017,27 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1082
1017
|
ts.factory.createCallExpression(ts.factory.createIdentifier('fetch'), undefined, [
|
|
1083
1018
|
ts.factory.createIdentifier('url'),
|
|
1084
1019
|
ts.factory.createCallExpression(
|
|
1085
|
-
ts.factory.createPropertyAccessExpression(
|
|
1086
|
-
ts.factory.createIdentifier('Object'),
|
|
1087
|
-
ts.factory.createIdentifier('assign'),
|
|
1088
|
-
),
|
|
1020
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('Object'), ts.factory.createIdentifier('assign')),
|
|
1089
1021
|
undefined,
|
|
1090
1022
|
[
|
|
1091
1023
|
ts.factory.createObjectLiteralExpression([], false),
|
|
1092
1024
|
ts.factory.createIdentifier('baseOptions'),
|
|
1093
1025
|
ts.factory.createObjectLiteralExpression(
|
|
1094
1026
|
[
|
|
1095
|
-
ts.factory.createShorthandPropertyAssignment(
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
),
|
|
1099
|
-
ts.factory.createPropertyAssignment(
|
|
1100
|
-
ts.factory.createIdentifier('headers'),
|
|
1101
|
-
ts.factory.createIdentifier('headers'),
|
|
1102
|
-
),
|
|
1103
|
-
ts.factory.createPropertyAssignment(
|
|
1104
|
-
ts.factory.createIdentifier('body'),
|
|
1105
|
-
ts.factory.createIdentifier('body'),
|
|
1106
|
-
),
|
|
1027
|
+
ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier('method'), undefined),
|
|
1028
|
+
ts.factory.createPropertyAssignment(ts.factory.createIdentifier('headers'), ts.factory.createIdentifier('headers')),
|
|
1029
|
+
ts.factory.createPropertyAssignment(ts.factory.createIdentifier('body'), ts.factory.createIdentifier('body'))
|
|
1107
1030
|
],
|
|
1108
|
-
false
|
|
1109
|
-
)
|
|
1110
|
-
]
|
|
1111
|
-
)
|
|
1112
|
-
])
|
|
1113
|
-
)
|
|
1114
|
-
)
|
|
1031
|
+
false
|
|
1032
|
+
)
|
|
1033
|
+
]
|
|
1034
|
+
)
|
|
1035
|
+
])
|
|
1036
|
+
)
|
|
1037
|
+
)
|
|
1115
1038
|
],
|
|
1116
|
-
ts.NodeFlags.Const
|
|
1117
|
-
)
|
|
1039
|
+
ts.NodeFlags.Const
|
|
1040
|
+
)
|
|
1118
1041
|
),
|
|
1119
1042
|
// Handle response through hook (allows subclasses to intercept and modify response)
|
|
1120
1043
|
ts.factory.createVariableStatement(
|
|
@@ -1127,80 +1050,62 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1127
1050
|
undefined,
|
|
1128
1051
|
ts.factory.createAwaitExpression(
|
|
1129
1052
|
ts.factory.createCallExpression(
|
|
1130
|
-
ts.factory.createPropertyAccessExpression(
|
|
1131
|
-
ts.factory.createThis(),
|
|
1132
|
-
ts.factory.createIdentifier('handleResponse'),
|
|
1133
|
-
),
|
|
1053
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), ts.factory.createIdentifier('handleResponse')),
|
|
1134
1054
|
[ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('T'), undefined)],
|
|
1135
1055
|
[
|
|
1136
1056
|
ts.factory.createIdentifier('rawResponse'),
|
|
1137
1057
|
ts.factory.createIdentifier('method'),
|
|
1138
1058
|
ts.factory.createIdentifier('path'),
|
|
1139
|
-
ts.factory.createIdentifier('options')
|
|
1140
|
-
]
|
|
1141
|
-
)
|
|
1142
|
-
)
|
|
1143
|
-
)
|
|
1059
|
+
ts.factory.createIdentifier('options')
|
|
1060
|
+
]
|
|
1061
|
+
)
|
|
1062
|
+
)
|
|
1063
|
+
)
|
|
1144
1064
|
],
|
|
1145
|
-
ts.NodeFlags.Const
|
|
1146
|
-
)
|
|
1065
|
+
ts.NodeFlags.Const
|
|
1066
|
+
)
|
|
1147
1067
|
),
|
|
1148
1068
|
// Check response status
|
|
1149
1069
|
ts.factory.createIfStatement(
|
|
1150
1070
|
ts.factory.createPrefixUnaryExpression(
|
|
1151
1071
|
ts.SyntaxKind.ExclamationToken,
|
|
1152
|
-
ts.factory.createPropertyAccessExpression(
|
|
1153
|
-
ts.factory.createIdentifier('response'),
|
|
1154
|
-
ts.factory.createIdentifier('ok'),
|
|
1155
|
-
),
|
|
1072
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('response'), ts.factory.createIdentifier('ok'))
|
|
1156
1073
|
),
|
|
1157
1074
|
ts.factory.createThrowStatement(
|
|
1158
1075
|
ts.factory.createNewExpression(ts.factory.createIdentifier('Error'), undefined, [
|
|
1159
1076
|
ts.factory.createTemplateExpression(ts.factory.createTemplateHead('HTTP ', 'HTTP '), [
|
|
1160
1077
|
ts.factory.createTemplateSpan(
|
|
1161
|
-
ts.factory.createPropertyAccessExpression(
|
|
1162
|
-
|
|
1163
|
-
ts.factory.createIdentifier('status'),
|
|
1164
|
-
),
|
|
1165
|
-
ts.factory.createTemplateMiddle(': ', ': '),
|
|
1078
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('response'), ts.factory.createIdentifier('status')),
|
|
1079
|
+
ts.factory.createTemplateMiddle(': ', ': ')
|
|
1166
1080
|
),
|
|
1167
1081
|
ts.factory.createTemplateSpan(
|
|
1168
|
-
ts.factory.createPropertyAccessExpression(
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
),
|
|
1174
|
-
]),
|
|
1175
|
-
]),
|
|
1082
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('response'), ts.factory.createIdentifier('statusText')),
|
|
1083
|
+
ts.factory.createTemplateTail('', '')
|
|
1084
|
+
)
|
|
1085
|
+
])
|
|
1086
|
+
])
|
|
1176
1087
|
),
|
|
1177
|
-
undefined
|
|
1088
|
+
undefined
|
|
1178
1089
|
),
|
|
1179
1090
|
// Return parsed JSON
|
|
1180
1091
|
ts.factory.createReturnStatement(
|
|
1181
1092
|
ts.factory.createAwaitExpression(
|
|
1182
1093
|
ts.factory.createCallExpression(
|
|
1183
|
-
ts.factory.createPropertyAccessExpression(
|
|
1184
|
-
ts.factory.createIdentifier('response'),
|
|
1185
|
-
ts.factory.createIdentifier('json'),
|
|
1186
|
-
),
|
|
1094
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('response'), ts.factory.createIdentifier('json')),
|
|
1187
1095
|
undefined,
|
|
1188
|
-
[]
|
|
1189
|
-
)
|
|
1190
|
-
)
|
|
1191
|
-
)
|
|
1096
|
+
[]
|
|
1097
|
+
)
|
|
1098
|
+
)
|
|
1099
|
+
)
|
|
1192
1100
|
],
|
|
1193
|
-
true
|
|
1194
|
-
)
|
|
1101
|
+
true
|
|
1102
|
+
)
|
|
1195
1103
|
);
|
|
1196
1104
|
}
|
|
1197
1105
|
|
|
1198
|
-
private buildClientMethods(
|
|
1199
|
-
openapi: OpenApiSpecType,
|
|
1200
|
-
schemas: Record<string, ts.VariableStatement>,
|
|
1201
|
-
): ts.MethodDeclaration[] {
|
|
1106
|
+
private buildClientMethods(openapi: OpenApiSpecType, schemas: Record<string, ts.VariableStatement>): ts.MethodDeclaration[] {
|
|
1202
1107
|
// Track operation IDs to detect duplicates
|
|
1203
|
-
const operationIdMap = new Map<string, {method: string; path: string}[]>();
|
|
1108
|
+
const operationIdMap = new Map<string, { method: string; path: string }[]>();
|
|
1204
1109
|
|
|
1205
1110
|
// First pass: collect all operation IDs and their methods/paths
|
|
1206
1111
|
Object.entries(openapi.paths).forEach(([path, pathItem]) => {
|
|
@@ -1212,9 +1117,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1212
1117
|
const operationId = safeMethodSchema.operationId;
|
|
1213
1118
|
const existing = operationIdMap.get(operationId);
|
|
1214
1119
|
if (existing) {
|
|
1215
|
-
existing.push({method, path});
|
|
1120
|
+
existing.push({ method, path });
|
|
1216
1121
|
} else {
|
|
1217
|
-
operationIdMap.set(operationId, [{method, path}]);
|
|
1122
|
+
operationIdMap.set(operationId, [{ method, path }]);
|
|
1218
1123
|
}
|
|
1219
1124
|
}
|
|
1220
1125
|
});
|
|
@@ -1246,7 +1151,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1246
1151
|
// This will be handled in transformOperationName
|
|
1247
1152
|
const modifiedSchema = {
|
|
1248
1153
|
...safeMethodSchema,
|
|
1249
|
-
operationId: `${operationId}_${methodLower}
|
|
1154
|
+
operationId: `${operationId}_${methodLower}`
|
|
1250
1155
|
};
|
|
1251
1156
|
return this.buildEndpointMethod(method, path, modifiedSchema, schemas);
|
|
1252
1157
|
}
|
|
@@ -1273,9 +1178,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1273
1178
|
operationId,
|
|
1274
1179
|
method,
|
|
1275
1180
|
path,
|
|
1276
|
-
...(schema.tags !== undefined && {tags: schema.tags}),
|
|
1277
|
-
...(schema.summary !== undefined && {summary: schema.summary}),
|
|
1278
|
-
...(schema.description !== undefined && {description: schema.description})
|
|
1181
|
+
...(schema.tags !== undefined && { tags: schema.tags }),
|
|
1182
|
+
...(schema.summary !== undefined && { summary: schema.summary }),
|
|
1183
|
+
...(schema.description !== undefined && { description: schema.description })
|
|
1279
1184
|
};
|
|
1280
1185
|
transformed = this.operationNameTransformer(details);
|
|
1281
1186
|
} else if (this.namingConvention) {
|
|
@@ -1300,16 +1205,8 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1300
1205
|
return this.typeBuilder.sanitizeIdentifier(transformed);
|
|
1301
1206
|
}
|
|
1302
1207
|
|
|
1303
|
-
private buildEndpointMethod(
|
|
1304
|
-
|
|
1305
|
-
path: string,
|
|
1306
|
-
schema: MethodSchemaType,
|
|
1307
|
-
schemas: Record<string, ts.VariableStatement>,
|
|
1308
|
-
): ts.MethodDeclaration {
|
|
1309
|
-
const {parameters, pathParams, queryParams, hasRequestBody, contentType} = this.buildMethodParameters(
|
|
1310
|
-
schema,
|
|
1311
|
-
schemas,
|
|
1312
|
-
);
|
|
1208
|
+
private buildEndpointMethod(method: string, path: string, schema: MethodSchemaType, schemas: Record<string, ts.VariableStatement>): ts.MethodDeclaration {
|
|
1209
|
+
const { parameters, pathParams, queryParams, hasRequestBody, contentType } = this.buildMethodParameters(schema, schemas);
|
|
1313
1210
|
const responseType = this.getResponseType(schema, schemas);
|
|
1314
1211
|
const responseSchema = this.getResponseSchema(schema, schemas);
|
|
1315
1212
|
|
|
@@ -1324,40 +1221,28 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1324
1221
|
? ts.factory.createObjectLiteralExpression(
|
|
1325
1222
|
queryParams.map((param) => {
|
|
1326
1223
|
const paramName = this.typeBuilder.sanitizeIdentifier(param.name);
|
|
1327
|
-
return ts.factory.createPropertyAssignment(
|
|
1328
|
-
ts.factory.createStringLiteral(param.name, true),
|
|
1329
|
-
ts.factory.createIdentifier(paramName),
|
|
1330
|
-
);
|
|
1224
|
+
return ts.factory.createPropertyAssignment(ts.factory.createStringLiteral(param.name, true), ts.factory.createIdentifier(paramName));
|
|
1331
1225
|
}),
|
|
1332
|
-
false
|
|
1226
|
+
false
|
|
1333
1227
|
)
|
|
1334
1228
|
: undefined;
|
|
1335
1229
|
|
|
1336
1230
|
// Build request body
|
|
1337
|
-
const requestBodyExpression: ts.Expression | undefined = hasRequestBody
|
|
1338
|
-
? ts.factory.createIdentifier('body')
|
|
1339
|
-
: undefined;
|
|
1231
|
+
const requestBodyExpression: ts.Expression | undefined = hasRequestBody ? ts.factory.createIdentifier('body') : undefined;
|
|
1340
1232
|
|
|
1341
1233
|
// Build options object for makeRequest
|
|
1342
1234
|
const optionsProps: ts.ObjectLiteralElementLike[] = [];
|
|
1343
1235
|
if (queryParamsExpression) {
|
|
1344
|
-
optionsProps.push(
|
|
1345
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier('params'), queryParamsExpression),
|
|
1346
|
-
);
|
|
1236
|
+
optionsProps.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier('params'), queryParamsExpression));
|
|
1347
1237
|
}
|
|
1238
|
+
|
|
1348
1239
|
if (requestBodyExpression) {
|
|
1349
|
-
optionsProps.push(
|
|
1350
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier('data'), requestBodyExpression),
|
|
1351
|
-
);
|
|
1240
|
+
optionsProps.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier('data'), requestBodyExpression));
|
|
1352
1241
|
}
|
|
1242
|
+
|
|
1353
1243
|
// Add content type if it's form-urlencoded
|
|
1354
1244
|
if (hasRequestBody && contentType === 'application/x-www-form-urlencoded') {
|
|
1355
|
-
optionsProps.push(
|
|
1356
|
-
ts.factory.createPropertyAssignment(
|
|
1357
|
-
ts.factory.createIdentifier('contentType'),
|
|
1358
|
-
ts.factory.createStringLiteral('application/x-www-form-urlencoded', true),
|
|
1359
|
-
),
|
|
1360
|
-
);
|
|
1245
|
+
optionsProps.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier('contentType'), ts.factory.createStringLiteral('application/x-www-form-urlencoded', true)));
|
|
1361
1246
|
}
|
|
1362
1247
|
|
|
1363
1248
|
const optionsExpression = ts.factory.createObjectLiteralExpression(optionsProps, false);
|
|
@@ -1366,18 +1251,98 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1366
1251
|
const makeRequestCall = ts.factory.createCallExpression(
|
|
1367
1252
|
ts.factory.createPropertyAccessExpression(ts.factory.createThis(), ts.factory.createIdentifier('makeRequest')),
|
|
1368
1253
|
undefined,
|
|
1369
|
-
[ts.factory.createStringLiteral(method.toUpperCase(), true), pathExpression, optionsExpression]
|
|
1254
|
+
[ts.factory.createStringLiteral(method.toUpperCase(), true), pathExpression, optionsExpression]
|
|
1370
1255
|
);
|
|
1371
1256
|
|
|
1372
|
-
// Add Zod validation if we have a response schema
|
|
1373
1257
|
if (responseSchema) {
|
|
1374
|
-
const
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1258
|
+
const schemaName = responseSchema.text;
|
|
1259
|
+
const schemaNameLower = schemaName.charAt(0).toLowerCase() + schemaName.slice(1);
|
|
1260
|
+
const parsedVarName = `parsed${schemaName}`;
|
|
1261
|
+
|
|
1262
|
+
// const response = await this.makeRequest(...)
|
|
1263
|
+
statements.push(
|
|
1264
|
+
ts.factory.createVariableStatement(
|
|
1265
|
+
undefined,
|
|
1266
|
+
ts.factory.createVariableDeclarationList(
|
|
1267
|
+
[ts.factory.createVariableDeclaration('response', undefined, undefined, ts.factory.createAwaitExpression(makeRequestCall))],
|
|
1268
|
+
ts.NodeFlags.Const
|
|
1269
|
+
)
|
|
1270
|
+
)
|
|
1271
|
+
);
|
|
1272
|
+
|
|
1273
|
+
// const parsed{Name} = {Schema}.safeParse(response)
|
|
1274
|
+
statements.push(
|
|
1275
|
+
ts.factory.createVariableStatement(
|
|
1276
|
+
undefined,
|
|
1277
|
+
ts.factory.createVariableDeclarationList(
|
|
1278
|
+
[
|
|
1279
|
+
ts.factory.createVariableDeclaration(
|
|
1280
|
+
parsedVarName,
|
|
1281
|
+
undefined,
|
|
1282
|
+
undefined,
|
|
1283
|
+
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(responseSchema, ts.factory.createIdentifier('safeParse')), undefined, [
|
|
1284
|
+
ts.factory.createIdentifier('response')
|
|
1285
|
+
])
|
|
1286
|
+
)
|
|
1287
|
+
],
|
|
1288
|
+
ts.NodeFlags.Const
|
|
1289
|
+
)
|
|
1290
|
+
)
|
|
1291
|
+
);
|
|
1292
|
+
|
|
1293
|
+
// if (!parsed{Name}.success) { throw new ResponseValidationError<{Type}>(...) }
|
|
1294
|
+
statements.push(
|
|
1295
|
+
ts.factory.createIfStatement(
|
|
1296
|
+
ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.ExclamationToken, ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(parsedVarName), 'success')),
|
|
1297
|
+
ts.factory.createBlock(
|
|
1298
|
+
[
|
|
1299
|
+
ts.factory.createThrowStatement(
|
|
1300
|
+
ts.factory.createNewExpression(
|
|
1301
|
+
ts.factory.createIdentifier('ResponseValidationError'),
|
|
1302
|
+
[ts.factory.createTypeReferenceNode(schemaName)],
|
|
1303
|
+
[
|
|
1304
|
+
ts.factory.createTemplateExpression(ts.factory.createTemplateHead(`Invalid ${schemaNameLower}: `), [
|
|
1305
|
+
ts.factory.createTemplateSpan(
|
|
1306
|
+
ts.factory.createCallExpression(
|
|
1307
|
+
ts.factory.createPropertyAccessExpression(
|
|
1308
|
+
ts.factory.createCallExpression(
|
|
1309
|
+
ts.factory.createPropertyAccessExpression(
|
|
1310
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(parsedVarName), 'error'), 'errors'),
|
|
1311
|
+
'map'
|
|
1312
|
+
),
|
|
1313
|
+
undefined,
|
|
1314
|
+
[
|
|
1315
|
+
ts.factory.createArrowFunction(
|
|
1316
|
+
undefined,
|
|
1317
|
+
undefined,
|
|
1318
|
+
[ts.factory.createParameterDeclaration(undefined, undefined, 'error')],
|
|
1319
|
+
undefined,
|
|
1320
|
+
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
1321
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('error'), 'message')
|
|
1322
|
+
)
|
|
1323
|
+
]
|
|
1324
|
+
),
|
|
1325
|
+
'join'
|
|
1326
|
+
),
|
|
1327
|
+
undefined,
|
|
1328
|
+
[ts.factory.createStringLiteral(', ', true)]
|
|
1329
|
+
),
|
|
1330
|
+
ts.factory.createTemplateTail('')
|
|
1331
|
+
)
|
|
1332
|
+
]),
|
|
1333
|
+
ts.factory.createIdentifier('response'),
|
|
1334
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(parsedVarName), 'error')
|
|
1335
|
+
]
|
|
1336
|
+
)
|
|
1337
|
+
)
|
|
1338
|
+
],
|
|
1339
|
+
true
|
|
1340
|
+
)
|
|
1341
|
+
)
|
|
1378
1342
|
);
|
|
1379
1343
|
|
|
1380
|
-
|
|
1344
|
+
// return parsed{Name}.data
|
|
1345
|
+
statements.push(ts.factory.createReturnStatement(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(parsedVarName), 'data')));
|
|
1381
1346
|
} else {
|
|
1382
1347
|
statements.push(ts.factory.createReturnStatement(ts.factory.createAwaitExpression(makeRequestCall)));
|
|
1383
1348
|
}
|
|
@@ -1392,7 +1357,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1392
1357
|
undefined,
|
|
1393
1358
|
parameters,
|
|
1394
1359
|
responseType,
|
|
1395
|
-
ts.factory.createBlock(statements, true)
|
|
1360
|
+
ts.factory.createBlock(statements, true)
|
|
1396
1361
|
);
|
|
1397
1362
|
|
|
1398
1363
|
// Add JSDoc comment if summary or description exists
|
|
@@ -1401,22 +1366,17 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1401
1366
|
if (jsdocComment) {
|
|
1402
1367
|
// addSyntheticLeadingComment expects the comment content without delimiters
|
|
1403
1368
|
// and will wrap it in /** */ for JSDoc-style comments
|
|
1404
|
-
ts.addSyntheticLeadingComment(
|
|
1405
|
-
methodDeclaration,
|
|
1406
|
-
ts.SyntaxKind.MultiLineCommentTrivia,
|
|
1407
|
-
`*\n${jsdocComment}\n `,
|
|
1408
|
-
true,
|
|
1409
|
-
);
|
|
1369
|
+
ts.addSyntheticLeadingComment(methodDeclaration, ts.SyntaxKind.MultiLineCommentTrivia, `*\n${jsdocComment}\n `, true);
|
|
1410
1370
|
}
|
|
1411
1371
|
|
|
1412
1372
|
return methodDeclaration;
|
|
1413
1373
|
}
|
|
1414
1374
|
|
|
1415
|
-
private buildPathExpression(path: string, pathParams: {name: string; type: string}[]): ts.Expression {
|
|
1375
|
+
private buildPathExpression(path: string, pathParams: { name: string; type: string }[]): ts.Expression {
|
|
1416
1376
|
// Replace {param} with ${param} for template literal
|
|
1417
1377
|
const pathParamNames = new Set(pathParams.map((p) => p.name));
|
|
1418
1378
|
const pathParamRegex = /\{([^}]+)\}/g;
|
|
1419
|
-
const matches: {index: number; length: number; name: string}[] = [];
|
|
1379
|
+
const matches: { index: number; length: number; name: string }[] = [];
|
|
1420
1380
|
|
|
1421
1381
|
// Find all path parameters
|
|
1422
1382
|
for (const match of path.matchAll(pathParamRegex)) {
|
|
@@ -1426,7 +1386,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1426
1386
|
matches.push({
|
|
1427
1387
|
index: match.index,
|
|
1428
1388
|
length: match[0].length,
|
|
1429
|
-
name: paramName
|
|
1389
|
+
name: paramName
|
|
1430
1390
|
});
|
|
1431
1391
|
}
|
|
1432
1392
|
}
|
|
@@ -1447,19 +1407,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1447
1407
|
const after = isLast ? path.substring(m.index + m.length) : '';
|
|
1448
1408
|
|
|
1449
1409
|
if (isLast) {
|
|
1450
|
-
templateSpans.push(
|
|
1451
|
-
ts.factory.createTemplateSpan(
|
|
1452
|
-
ts.factory.createIdentifier(sanitizedName),
|
|
1453
|
-
ts.factory.createTemplateTail(after, after),
|
|
1454
|
-
),
|
|
1455
|
-
);
|
|
1410
|
+
templateSpans.push(ts.factory.createTemplateSpan(ts.factory.createIdentifier(sanitizedName), ts.factory.createTemplateTail(after, after)));
|
|
1456
1411
|
} else {
|
|
1457
|
-
templateSpans.push(
|
|
1458
|
-
ts.factory.createTemplateSpan(
|
|
1459
|
-
ts.factory.createIdentifier(sanitizedName),
|
|
1460
|
-
ts.factory.createTemplateMiddle(before, before),
|
|
1461
|
-
),
|
|
1462
|
-
);
|
|
1412
|
+
templateSpans.push(ts.factory.createTemplateSpan(ts.factory.createIdentifier(sanitizedName), ts.factory.createTemplateMiddle(before, before)));
|
|
1463
1413
|
}
|
|
1464
1414
|
|
|
1465
1415
|
lastIndex = m.index + m.length;
|
|
@@ -1469,23 +1419,24 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1469
1419
|
if (!firstMatch) {
|
|
1470
1420
|
return ts.factory.createStringLiteral(path, true);
|
|
1471
1421
|
}
|
|
1422
|
+
|
|
1472
1423
|
const head = path.substring(0, firstMatch.index);
|
|
1473
1424
|
return ts.factory.createTemplateExpression(ts.factory.createTemplateHead(head, head), templateSpans);
|
|
1474
1425
|
}
|
|
1475
1426
|
|
|
1476
1427
|
private buildMethodParameters(
|
|
1477
1428
|
schema: MethodSchemaType,
|
|
1478
|
-
schemas: Record<string, ts.VariableStatement
|
|
1429
|
+
schemas: Record<string, ts.VariableStatement>
|
|
1479
1430
|
): {
|
|
1480
1431
|
parameters: ts.ParameterDeclaration[];
|
|
1481
|
-
pathParams: {name: string; type: string}[];
|
|
1482
|
-
queryParams: {name: string; type: string; required: boolean}[];
|
|
1432
|
+
pathParams: { name: string; type: string }[];
|
|
1433
|
+
queryParams: { name: string; type: string; required: boolean }[];
|
|
1483
1434
|
hasRequestBody: boolean;
|
|
1484
1435
|
contentType: string;
|
|
1485
1436
|
} {
|
|
1486
1437
|
const parameters: ts.ParameterDeclaration[] = [];
|
|
1487
|
-
const pathParams: {name: string; type: string}[] = [];
|
|
1488
|
-
const queryParams: {name: string; type: string; required: boolean}[] = [];
|
|
1438
|
+
const pathParams: { name: string; type: string }[] = [];
|
|
1439
|
+
const queryParams: { name: string; type: string; required: boolean }[] = [];
|
|
1489
1440
|
|
|
1490
1441
|
// Extract path and query parameters
|
|
1491
1442
|
if (schema.parameters) {
|
|
@@ -1494,7 +1445,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1494
1445
|
const paramType = this.getParameterType(param.schema);
|
|
1495
1446
|
|
|
1496
1447
|
if (param.in === 'path') {
|
|
1497
|
-
pathParams.push({name: param.name, type: paramType});
|
|
1448
|
+
pathParams.push({ name: param.name, type: paramType });
|
|
1498
1449
|
parameters.push(this.typeBuilder.createParameter(paramName, paramType, undefined, false));
|
|
1499
1450
|
} else if (param.in === 'query') {
|
|
1500
1451
|
// Improve type inference for query parameters
|
|
@@ -1502,24 +1453,26 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1502
1453
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1503
1454
|
typeof param.schema === 'object' && param.schema !== null
|
|
1504
1455
|
? (() => {
|
|
1505
|
-
const paramSchema = param.schema as {type?: string; items?: unknown; enum?: unknown[]};
|
|
1456
|
+
const paramSchema = param.schema as { type?: string; items?: unknown; enum?: unknown[] };
|
|
1506
1457
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
1507
1458
|
if (paramSchema['type'] === 'array' && paramSchema['items']) {
|
|
1508
1459
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
1509
|
-
const itemSchema = paramSchema['items'] as {type?: string};
|
|
1460
|
+
const itemSchema = paramSchema['items'] as { type?: string };
|
|
1510
1461
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
1511
1462
|
if (itemSchema['type'] === 'string') {
|
|
1512
1463
|
return 'string[]' as const;
|
|
1513
1464
|
}
|
|
1465
|
+
|
|
1514
1466
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
1515
1467
|
if (itemSchema['type'] === 'number' || itemSchema['type'] === 'integer') {
|
|
1516
1468
|
return 'number[]' as const;
|
|
1517
1469
|
}
|
|
1518
1470
|
}
|
|
1471
|
+
|
|
1519
1472
|
return paramType;
|
|
1520
1473
|
})()
|
|
1521
1474
|
: paramType;
|
|
1522
|
-
queryParams.push({name: param.name, type: queryParamType, required: param.required ?? false});
|
|
1475
|
+
queryParams.push({ name: param.name, type: queryParamType, required: param.required ?? false });
|
|
1523
1476
|
parameters.push(this.typeBuilder.createParameter(paramName, queryParamType, undefined, !param.required));
|
|
1524
1477
|
}
|
|
1525
1478
|
}
|
|
@@ -1544,6 +1497,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1544
1497
|
const refName = ref.split('/').pop() ?? 'unknown';
|
|
1545
1498
|
return this.typeBuilder.sanitizeIdentifier(refName);
|
|
1546
1499
|
}
|
|
1500
|
+
|
|
1547
1501
|
// Fallback to getSchemaTypeName for non-ref schemas
|
|
1548
1502
|
return this.getSchemaTypeName(requestBodySchema, schemas);
|
|
1549
1503
|
})()
|
|
@@ -1553,12 +1507,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1553
1507
|
}
|
|
1554
1508
|
|
|
1555
1509
|
// Determine content type for request body
|
|
1556
|
-
const contentType =
|
|
1557
|
-
hasRequestBody && schema.requestBody?.content?.['application/x-www-form-urlencoded']
|
|
1558
|
-
? 'application/x-www-form-urlencoded'
|
|
1559
|
-
: 'application/json';
|
|
1510
|
+
const contentType = hasRequestBody && schema.requestBody?.content?.['application/x-www-form-urlencoded'] ? 'application/x-www-form-urlencoded' : 'application/json';
|
|
1560
1511
|
|
|
1561
|
-
return {parameters, pathParams, queryParams, hasRequestBody, contentType};
|
|
1512
|
+
return { parameters, pathParams, queryParams, hasRequestBody, contentType };
|
|
1562
1513
|
}
|
|
1563
1514
|
|
|
1564
1515
|
private getParameterType(schema: unknown): string {
|
|
@@ -1608,7 +1559,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1608
1559
|
return 'unknown';
|
|
1609
1560
|
}
|
|
1610
1561
|
|
|
1611
|
-
const schemaObj = schema as {$ref?: string; type?: string; items?: unknown};
|
|
1562
|
+
const schemaObj = schema as { $ref?: string; type?: string; items?: unknown };
|
|
1612
1563
|
|
|
1613
1564
|
// Check for $ref using both dot notation and bracket notation
|
|
1614
1565
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
@@ -1638,10 +1589,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1638
1589
|
}
|
|
1639
1590
|
}
|
|
1640
1591
|
|
|
1641
|
-
private getResponseSchema(
|
|
1642
|
-
schema: MethodSchemaType,
|
|
1643
|
-
_schemas: Record<string, ts.VariableStatement>,
|
|
1644
|
-
): ts.Identifier | undefined {
|
|
1592
|
+
private getResponseSchema(schema: MethodSchemaType, _schemas: Record<string, ts.VariableStatement>): ts.Identifier | undefined {
|
|
1645
1593
|
// Try to find a 200 response first, then 201, then default
|
|
1646
1594
|
const response200 = schema.responses?.['200'];
|
|
1647
1595
|
const response201 = schema.responses?.['201'];
|
|
@@ -1656,7 +1604,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1656
1604
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1657
1605
|
if (responseSchema !== null && typeof responseSchema === 'object' && '$ref' in responseSchema) {
|
|
1658
1606
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
1659
|
-
const ref = (responseSchema as {$ref: string})['$ref'];
|
|
1607
|
+
const ref = (responseSchema as { $ref: string })['$ref'];
|
|
1660
1608
|
if (typeof ref === 'string') {
|
|
1661
1609
|
const refName = ref.split('/').pop() ?? 'unknown';
|
|
1662
1610
|
return ts.factory.createIdentifier(this.typeBuilder.sanitizeIdentifier(refName));
|
|
@@ -1668,10 +1616,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1668
1616
|
return undefined;
|
|
1669
1617
|
}
|
|
1670
1618
|
|
|
1671
|
-
private getResponseType(
|
|
1672
|
-
schema: MethodSchemaType,
|
|
1673
|
-
schemas: Record<string, ts.VariableStatement>,
|
|
1674
|
-
): ts.TypeNode | undefined {
|
|
1619
|
+
private getResponseType(schema: MethodSchemaType, schemas: Record<string, ts.VariableStatement>): ts.TypeNode | undefined {
|
|
1675
1620
|
// Try to find a 200 response first, then 201, then default
|
|
1676
1621
|
const response200 = schema.responses?.['200'];
|
|
1677
1622
|
const response201 = schema.responses?.['201'];
|
|
@@ -1679,9 +1624,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1679
1624
|
|
|
1680
1625
|
const response = response200 ?? response201 ?? responseDefault;
|
|
1681
1626
|
if (!response?.content?.['application/json']?.schema) {
|
|
1682
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1683
|
-
ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword),
|
|
1684
|
-
]);
|
|
1627
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)]);
|
|
1685
1628
|
}
|
|
1686
1629
|
|
|
1687
1630
|
const responseSchema = response.content['application/json'].schema;
|
|
@@ -1696,15 +1639,12 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1696
1639
|
if (schemas[sanitizedItemTypeName]) {
|
|
1697
1640
|
// Use the type alias directly (it already uses z.infer)
|
|
1698
1641
|
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1699
|
-
ts.factory.createArrayTypeNode(
|
|
1700
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedItemTypeName), undefined),
|
|
1701
|
-
),
|
|
1642
|
+
ts.factory.createArrayTypeNode(ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedItemTypeName), undefined))
|
|
1702
1643
|
]);
|
|
1703
1644
|
}
|
|
1645
|
+
|
|
1704
1646
|
// If it's a primitive array, use the type name as-is
|
|
1705
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1706
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined),
|
|
1707
|
-
]);
|
|
1647
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined)]);
|
|
1708
1648
|
}
|
|
1709
1649
|
|
|
1710
1650
|
const sanitizedTypeName = this.typeBuilder.sanitizeIdentifier(typeName);
|
|
@@ -1713,14 +1653,12 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1713
1653
|
if (schemas[sanitizedTypeName]) {
|
|
1714
1654
|
// Use the type name directly (we have a type alias that already uses z.infer)
|
|
1715
1655
|
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1716
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedTypeName), undefined)
|
|
1656
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedTypeName), undefined)
|
|
1717
1657
|
]);
|
|
1718
1658
|
}
|
|
1719
1659
|
|
|
1720
1660
|
// For primitive types and Record types, use the type name directly
|
|
1721
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1722
|
-
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined),
|
|
1723
|
-
]);
|
|
1661
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined)]);
|
|
1724
1662
|
}
|
|
1725
1663
|
|
|
1726
1664
|
private buildServerConfiguration(openapi: OpenApiSpecType): ts.Statement[] {
|
|
@@ -1734,21 +1672,15 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1734
1672
|
|
|
1735
1673
|
// Build server configuration array
|
|
1736
1674
|
const serverConfigElements = servers.map((server) => {
|
|
1737
|
-
const properties: ts.PropertyAssignment[] = [
|
|
1738
|
-
ts.factory.createPropertyAssignment('url', ts.factory.createStringLiteral(server.url, true)),
|
|
1739
|
-
];
|
|
1675
|
+
const properties: ts.PropertyAssignment[] = [ts.factory.createPropertyAssignment('url', ts.factory.createStringLiteral(server.url, true))];
|
|
1740
1676
|
|
|
1741
1677
|
if (server.description) {
|
|
1742
|
-
properties.push(
|
|
1743
|
-
ts.factory.createPropertyAssignment('description', ts.factory.createStringLiteral(server.description, true)),
|
|
1744
|
-
);
|
|
1678
|
+
properties.push(ts.factory.createPropertyAssignment('description', ts.factory.createStringLiteral(server.description, true)));
|
|
1745
1679
|
}
|
|
1746
1680
|
|
|
1747
1681
|
if (server.variables && Object.keys(server.variables).length > 0) {
|
|
1748
1682
|
const variableProperties = Object.entries(server.variables).map(([varName, varDef]) => {
|
|
1749
|
-
const varProps: ts.PropertyAssignment[] = [
|
|
1750
|
-
ts.factory.createPropertyAssignment('default', ts.factory.createStringLiteral(varDef.default, true)),
|
|
1751
|
-
];
|
|
1683
|
+
const varProps: ts.PropertyAssignment[] = [ts.factory.createPropertyAssignment('default', ts.factory.createStringLiteral(varDef.default, true))];
|
|
1752
1684
|
|
|
1753
1685
|
if (varDef.enum && varDef.enum.length > 0) {
|
|
1754
1686
|
varProps.push(
|
|
@@ -1756,30 +1688,20 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1756
1688
|
'enum',
|
|
1757
1689
|
ts.factory.createArrayLiteralExpression(
|
|
1758
1690
|
varDef.enum.map((val) => ts.factory.createStringLiteral(val, true)),
|
|
1759
|
-
false
|
|
1760
|
-
)
|
|
1761
|
-
)
|
|
1691
|
+
false
|
|
1692
|
+
)
|
|
1693
|
+
)
|
|
1762
1694
|
);
|
|
1763
1695
|
}
|
|
1764
1696
|
|
|
1765
1697
|
if (varDef.description) {
|
|
1766
|
-
varProps.push(
|
|
1767
|
-
ts.factory.createPropertyAssignment(
|
|
1768
|
-
'description',
|
|
1769
|
-
ts.factory.createStringLiteral(varDef.description, true),
|
|
1770
|
-
),
|
|
1771
|
-
);
|
|
1698
|
+
varProps.push(ts.factory.createPropertyAssignment('description', ts.factory.createStringLiteral(varDef.description, true)));
|
|
1772
1699
|
}
|
|
1773
1700
|
|
|
1774
1701
|
return ts.factory.createPropertyAssignment(varName, ts.factory.createObjectLiteralExpression(varProps, true));
|
|
1775
1702
|
});
|
|
1776
1703
|
|
|
1777
|
-
properties.push(
|
|
1778
|
-
ts.factory.createPropertyAssignment(
|
|
1779
|
-
'variables',
|
|
1780
|
-
ts.factory.createObjectLiteralExpression(variableProperties, true),
|
|
1781
|
-
),
|
|
1782
|
-
);
|
|
1704
|
+
properties.push(ts.factory.createPropertyAssignment('variables', ts.factory.createObjectLiteralExpression(variableProperties, true)));
|
|
1783
1705
|
}
|
|
1784
1706
|
|
|
1785
1707
|
return ts.factory.createObjectLiteralExpression(properties, true);
|
|
@@ -1795,12 +1717,12 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1795
1717
|
ts.factory.createIdentifier('serverConfigurations'),
|
|
1796
1718
|
undefined,
|
|
1797
1719
|
undefined,
|
|
1798
|
-
ts.factory.createArrayLiteralExpression(serverConfigElements, false)
|
|
1799
|
-
)
|
|
1720
|
+
ts.factory.createArrayLiteralExpression(serverConfigElements, false)
|
|
1721
|
+
)
|
|
1800
1722
|
],
|
|
1801
|
-
ts.NodeFlags.Const
|
|
1802
|
-
)
|
|
1803
|
-
)
|
|
1723
|
+
ts.NodeFlags.Const
|
|
1724
|
+
)
|
|
1725
|
+
)
|
|
1804
1726
|
);
|
|
1805
1727
|
|
|
1806
1728
|
// Export default base URL (first server with default variables)
|
|
@@ -1810,17 +1732,10 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1810
1732
|
ts.factory.createVariableStatement(
|
|
1811
1733
|
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
1812
1734
|
ts.factory.createVariableDeclarationList(
|
|
1813
|
-
[
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
undefined,
|
|
1818
|
-
ts.factory.createStringLiteral(defaultBaseUrl, true),
|
|
1819
|
-
),
|
|
1820
|
-
],
|
|
1821
|
-
ts.NodeFlags.Const,
|
|
1822
|
-
),
|
|
1823
|
-
),
|
|
1735
|
+
[ts.factory.createVariableDeclaration(ts.factory.createIdentifier('defaultBaseUrl'), undefined, undefined, ts.factory.createStringLiteral(defaultBaseUrl, true))],
|
|
1736
|
+
ts.NodeFlags.Const
|
|
1737
|
+
)
|
|
1738
|
+
)
|
|
1824
1739
|
);
|
|
1825
1740
|
|
|
1826
1741
|
// Build ClientOptions type
|
|
@@ -1829,13 +1744,13 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1829
1744
|
undefined,
|
|
1830
1745
|
ts.factory.createIdentifier('baseUrl'),
|
|
1831
1746
|
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
1832
|
-
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
1747
|
+
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
1833
1748
|
),
|
|
1834
1749
|
ts.factory.createPropertySignature(
|
|
1835
1750
|
undefined,
|
|
1836
1751
|
ts.factory.createIdentifier('serverIndex'),
|
|
1837
1752
|
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
1838
|
-
ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)
|
|
1753
|
+
ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)
|
|
1839
1754
|
),
|
|
1840
1755
|
ts.factory.createPropertySignature(
|
|
1841
1756
|
undefined,
|
|
@@ -1843,9 +1758,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1843
1758
|
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
1844
1759
|
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Record'), [
|
|
1845
1760
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
1846
|
-
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
1847
|
-
])
|
|
1848
|
-
)
|
|
1761
|
+
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
1762
|
+
])
|
|
1763
|
+
)
|
|
1849
1764
|
];
|
|
1850
1765
|
|
|
1851
1766
|
statements.push(
|
|
@@ -1853,8 +1768,8 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1853
1768
|
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
1854
1769
|
ts.factory.createIdentifier('ClientOptions'),
|
|
1855
1770
|
undefined,
|
|
1856
|
-
ts.factory.createTypeLiteralNode(optionProperties)
|
|
1857
|
-
)
|
|
1771
|
+
ts.factory.createTypeLiteralNode(optionProperties)
|
|
1772
|
+
)
|
|
1858
1773
|
);
|
|
1859
1774
|
|
|
1860
1775
|
// Build resolveServerUrl helper function
|
|
@@ -1866,11 +1781,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1866
1781
|
private resolveServerUrl(
|
|
1867
1782
|
server: {
|
|
1868
1783
|
url: string;
|
|
1869
|
-
variables?:
|
|
1870
|
-
| Record<string, {default: string; enum?: string[] | undefined; description?: string | undefined}>
|
|
1871
|
-
| undefined;
|
|
1784
|
+
variables?: Record<string, { default: string; enum?: string[] | undefined; description?: string | undefined }> | undefined;
|
|
1872
1785
|
},
|
|
1873
|
-
variables: Record<string, string
|
|
1786
|
+
variables: Record<string, string>
|
|
1874
1787
|
): string {
|
|
1875
1788
|
let url = server.url;
|
|
1876
1789
|
|
|
@@ -1888,22 +1801,16 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1888
1801
|
servers: {
|
|
1889
1802
|
url: string;
|
|
1890
1803
|
description?: string | undefined;
|
|
1891
|
-
variables?:
|
|
1892
|
-
|
|
1893
|
-
| undefined;
|
|
1894
|
-
}[],
|
|
1804
|
+
variables?: Record<string, { default: string; enum?: string[] | undefined; description?: string | undefined }> | undefined;
|
|
1805
|
+
}[]
|
|
1895
1806
|
): ts.FunctionDeclaration {
|
|
1896
1807
|
// Build server configs array inline
|
|
1897
1808
|
const serverConfigElements = servers.map((server) => {
|
|
1898
|
-
const properties: ts.PropertyAssignment[] = [
|
|
1899
|
-
ts.factory.createPropertyAssignment('url', ts.factory.createStringLiteral(server.url, true)),
|
|
1900
|
-
];
|
|
1809
|
+
const properties: ts.PropertyAssignment[] = [ts.factory.createPropertyAssignment('url', ts.factory.createStringLiteral(server.url, true))];
|
|
1901
1810
|
|
|
1902
1811
|
if (server.variables && Object.keys(server.variables).length > 0) {
|
|
1903
1812
|
const variableProperties = Object.entries(server.variables).map(([varName, varDef]) => {
|
|
1904
|
-
const varProps: ts.PropertyAssignment[] = [
|
|
1905
|
-
ts.factory.createPropertyAssignment('default', ts.factory.createStringLiteral(varDef.default, true)),
|
|
1906
|
-
];
|
|
1813
|
+
const varProps: ts.PropertyAssignment[] = [ts.factory.createPropertyAssignment('default', ts.factory.createStringLiteral(varDef.default, true))];
|
|
1907
1814
|
|
|
1908
1815
|
if (varDef.enum && varDef.enum.length > 0) {
|
|
1909
1816
|
varProps.push(
|
|
@@ -1911,21 +1818,16 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1911
1818
|
'enum',
|
|
1912
1819
|
ts.factory.createArrayLiteralExpression(
|
|
1913
1820
|
varDef.enum.map((val) => ts.factory.createStringLiteral(val, true)),
|
|
1914
|
-
false
|
|
1915
|
-
)
|
|
1916
|
-
)
|
|
1821
|
+
false
|
|
1822
|
+
)
|
|
1823
|
+
)
|
|
1917
1824
|
);
|
|
1918
1825
|
}
|
|
1919
1826
|
|
|
1920
1827
|
return ts.factory.createPropertyAssignment(varName, ts.factory.createObjectLiteralExpression(varProps, true));
|
|
1921
1828
|
});
|
|
1922
1829
|
|
|
1923
|
-
properties.push(
|
|
1924
|
-
ts.factory.createPropertyAssignment(
|
|
1925
|
-
'variables',
|
|
1926
|
-
ts.factory.createObjectLiteralExpression(variableProperties, true),
|
|
1927
|
-
),
|
|
1928
|
-
);
|
|
1830
|
+
properties.push(ts.factory.createPropertyAssignment('variables', ts.factory.createObjectLiteralExpression(variableProperties, true)));
|
|
1929
1831
|
}
|
|
1930
1832
|
|
|
1931
1833
|
return ts.factory.createObjectLiteralExpression(properties, true);
|
|
@@ -1944,16 +1846,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1944
1846
|
ts.factory.createVariableStatement(
|
|
1945
1847
|
undefined,
|
|
1946
1848
|
ts.factory.createVariableDeclarationList(
|
|
1947
|
-
[
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
undefined,
|
|
1951
|
-
undefined,
|
|
1952
|
-
ts.factory.createArrayLiteralExpression(serverConfigElements, false),
|
|
1953
|
-
),
|
|
1954
|
-
],
|
|
1955
|
-
ts.NodeFlags.Const,
|
|
1956
|
-
),
|
|
1849
|
+
[ts.factory.createVariableDeclaration(configs, undefined, undefined, ts.factory.createArrayLiteralExpression(serverConfigElements, false))],
|
|
1850
|
+
ts.NodeFlags.Const
|
|
1851
|
+
)
|
|
1957
1852
|
),
|
|
1958
1853
|
// const idx = serverIndex ?? 0
|
|
1959
1854
|
ts.factory.createVariableStatement(
|
|
@@ -1967,19 +1862,19 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1967
1862
|
ts.factory.createBinaryExpression(
|
|
1968
1863
|
ts.factory.createIdentifier('serverIndex'),
|
|
1969
1864
|
ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
|
|
1970
|
-
ts.factory.createNumericLiteral('0')
|
|
1971
|
-
)
|
|
1972
|
-
)
|
|
1865
|
+
ts.factory.createNumericLiteral('0')
|
|
1866
|
+
)
|
|
1867
|
+
)
|
|
1973
1868
|
],
|
|
1974
|
-
ts.NodeFlags.Const
|
|
1975
|
-
)
|
|
1869
|
+
ts.NodeFlags.Const
|
|
1870
|
+
)
|
|
1976
1871
|
),
|
|
1977
1872
|
// if (idx < configs.length) { ... }
|
|
1978
1873
|
ts.factory.createIfStatement(
|
|
1979
1874
|
ts.factory.createBinaryExpression(
|
|
1980
1875
|
idx,
|
|
1981
1876
|
ts.factory.createToken(ts.SyntaxKind.LessThanToken),
|
|
1982
|
-
ts.factory.createPropertyAccessExpression(configs, ts.factory.createIdentifier('length'))
|
|
1877
|
+
ts.factory.createPropertyAccessExpression(configs, ts.factory.createIdentifier('length'))
|
|
1983
1878
|
),
|
|
1984
1879
|
ts.factory.createBlock(
|
|
1985
1880
|
[
|
|
@@ -1987,37 +1882,23 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1987
1882
|
ts.factory.createVariableStatement(
|
|
1988
1883
|
undefined,
|
|
1989
1884
|
ts.factory.createVariableDeclarationList(
|
|
1990
|
-
[
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
undefined,
|
|
1994
|
-
undefined,
|
|
1995
|
-
ts.factory.createElementAccessExpression(configs, idx),
|
|
1996
|
-
),
|
|
1997
|
-
],
|
|
1998
|
-
ts.NodeFlags.Const,
|
|
1999
|
-
),
|
|
1885
|
+
[ts.factory.createVariableDeclaration(config, undefined, undefined, ts.factory.createElementAccessExpression(configs, idx))],
|
|
1886
|
+
ts.NodeFlags.Const
|
|
1887
|
+
)
|
|
2000
1888
|
),
|
|
2001
1889
|
// let url = config.url
|
|
2002
1890
|
ts.factory.createVariableStatement(
|
|
2003
1891
|
undefined,
|
|
2004
1892
|
ts.factory.createVariableDeclarationList(
|
|
2005
|
-
[
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
undefined,
|
|
2009
|
-
undefined,
|
|
2010
|
-
ts.factory.createPropertyAccessExpression(config, ts.factory.createIdentifier('url')),
|
|
2011
|
-
),
|
|
2012
|
-
],
|
|
2013
|
-
ts.NodeFlags.Let,
|
|
2014
|
-
),
|
|
1893
|
+
[ts.factory.createVariableDeclaration(url, undefined, undefined, ts.factory.createPropertyAccessExpression(config, ts.factory.createIdentifier('url')))],
|
|
1894
|
+
ts.NodeFlags.Let
|
|
1895
|
+
)
|
|
2015
1896
|
),
|
|
2016
1897
|
// if (config.variables && serverVariables) { ... }
|
|
2017
1898
|
ts.factory.createIfStatement(
|
|
2018
1899
|
ts.factory.createLogicalAnd(
|
|
2019
1900
|
ts.factory.createPropertyAccessExpression(config, ts.factory.createIdentifier('variables')),
|
|
2020
|
-
ts.factory.createIdentifier('serverVariables')
|
|
1901
|
+
ts.factory.createIdentifier('serverVariables')
|
|
2021
1902
|
),
|
|
2022
1903
|
ts.factory.createBlock(
|
|
2023
1904
|
[
|
|
@@ -2029,21 +1910,18 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2029
1910
|
ts.factory.createVariableDeclaration(
|
|
2030
1911
|
ts.factory.createArrayBindingPattern([
|
|
2031
1912
|
ts.factory.createBindingElement(undefined, undefined, key),
|
|
2032
|
-
ts.factory.createBindingElement(undefined, undefined, value)
|
|
1913
|
+
ts.factory.createBindingElement(undefined, undefined, value)
|
|
2033
1914
|
]),
|
|
2034
1915
|
undefined,
|
|
2035
|
-
undefined
|
|
2036
|
-
)
|
|
1916
|
+
undefined
|
|
1917
|
+
)
|
|
2037
1918
|
],
|
|
2038
|
-
ts.NodeFlags.Const
|
|
1919
|
+
ts.NodeFlags.Const
|
|
2039
1920
|
),
|
|
2040
1921
|
ts.factory.createCallExpression(
|
|
2041
|
-
ts.factory.createPropertyAccessExpression(
|
|
2042
|
-
ts.factory.createIdentifier('Object'),
|
|
2043
|
-
ts.factory.createIdentifier('entries'),
|
|
2044
|
-
),
|
|
1922
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('Object'), ts.factory.createIdentifier('entries')),
|
|
2045
1923
|
undefined,
|
|
2046
|
-
[ts.factory.createIdentifier('serverVariables')]
|
|
1924
|
+
[ts.factory.createIdentifier('serverVariables')]
|
|
2047
1925
|
),
|
|
2048
1926
|
ts.factory.createBlock(
|
|
2049
1927
|
[
|
|
@@ -2051,45 +1929,35 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2051
1929
|
ts.factory.createBinaryExpression(
|
|
2052
1930
|
url,
|
|
2053
1931
|
ts.factory.createToken(ts.SyntaxKind.EqualsToken),
|
|
2054
|
-
ts.factory.createCallExpression(
|
|
2055
|
-
ts.factory.
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
ts.factory.
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
),
|
|
2068
|
-
ts.factory.createStringLiteral('g'),
|
|
2069
|
-
]),
|
|
2070
|
-
value,
|
|
2071
|
-
],
|
|
2072
|
-
),
|
|
2073
|
-
),
|
|
2074
|
-
),
|
|
1932
|
+
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(url, ts.factory.createIdentifier('replace')), undefined, [
|
|
1933
|
+
ts.factory.createNewExpression(ts.factory.createIdentifier('RegExp'), undefined, [
|
|
1934
|
+
ts.factory.createBinaryExpression(
|
|
1935
|
+
ts.factory.createBinaryExpression(ts.factory.createStringLiteral('\\{'), ts.factory.createToken(ts.SyntaxKind.PlusToken), key),
|
|
1936
|
+
ts.factory.createToken(ts.SyntaxKind.PlusToken),
|
|
1937
|
+
ts.factory.createStringLiteral('\\}')
|
|
1938
|
+
),
|
|
1939
|
+
ts.factory.createStringLiteral('g')
|
|
1940
|
+
]),
|
|
1941
|
+
value
|
|
1942
|
+
])
|
|
1943
|
+
)
|
|
1944
|
+
)
|
|
2075
1945
|
],
|
|
2076
|
-
true
|
|
2077
|
-
)
|
|
2078
|
-
)
|
|
1946
|
+
true
|
|
1947
|
+
)
|
|
1948
|
+
)
|
|
2079
1949
|
],
|
|
2080
|
-
true
|
|
2081
|
-
)
|
|
1950
|
+
true
|
|
1951
|
+
)
|
|
2082
1952
|
),
|
|
2083
1953
|
// return url
|
|
2084
|
-
ts.factory.createReturnStatement(url)
|
|
1954
|
+
ts.factory.createReturnStatement(url)
|
|
2085
1955
|
],
|
|
2086
|
-
true
|
|
2087
|
-
)
|
|
1956
|
+
true
|
|
1957
|
+
)
|
|
2088
1958
|
),
|
|
2089
1959
|
// return default (first server with defaults)
|
|
2090
|
-
ts.factory.createReturnStatement(
|
|
2091
|
-
ts.factory.createStringLiteral(servers[0] ? this.resolveServerUrl(servers[0], {}) : '/', true),
|
|
2092
|
-
),
|
|
1960
|
+
ts.factory.createReturnStatement(ts.factory.createStringLiteral(servers[0] ? this.resolveServerUrl(servers[0], {}) : '/', true))
|
|
2093
1961
|
];
|
|
2094
1962
|
|
|
2095
1963
|
return ts.factory.createFunctionDeclaration(
|
|
@@ -2103,11 +1971,8 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2103
1971
|
undefined,
|
|
2104
1972
|
ts.factory.createIdentifier('serverIndex'),
|
|
2105
1973
|
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
2106
|
-
ts.factory.createUnionTypeNode([
|
|
2107
|
-
|
|
2108
|
-
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),
|
|
2109
|
-
]),
|
|
2110
|
-
undefined,
|
|
1974
|
+
ts.factory.createUnionTypeNode([ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)]),
|
|
1975
|
+
undefined
|
|
2111
1976
|
),
|
|
2112
1977
|
ts.factory.createParameterDeclaration(
|
|
2113
1978
|
undefined,
|
|
@@ -2116,13 +1981,13 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2116
1981
|
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
2117
1982
|
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Record'), [
|
|
2118
1983
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
2119
|
-
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
1984
|
+
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
2120
1985
|
]),
|
|
2121
|
-
ts.factory.createObjectLiteralExpression([], false)
|
|
2122
|
-
)
|
|
1986
|
+
ts.factory.createObjectLiteralExpression([], false)
|
|
1987
|
+
)
|
|
2123
1988
|
],
|
|
2124
1989
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
2125
|
-
ts.factory.createBlock(bodyStatements, true)
|
|
1990
|
+
ts.factory.createBlock(bodyStatements, true)
|
|
2126
1991
|
);
|
|
2127
1992
|
}
|
|
2128
1993
|
|
|
@@ -2142,12 +2007,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2142
2007
|
/**
|
|
2143
2008
|
* Builds a JSDoc comment string from operation metadata
|
|
2144
2009
|
*/
|
|
2145
|
-
private buildJSDocComment(
|
|
2146
|
-
summary: string | undefined,
|
|
2147
|
-
description: string | undefined,
|
|
2148
|
-
schema: MethodSchemaType,
|
|
2149
|
-
responseType: ts.TypeNode | undefined,
|
|
2150
|
-
): string {
|
|
2010
|
+
private buildJSDocComment(summary: string | undefined, description: string | undefined, schema: MethodSchemaType, responseType: ts.TypeNode | undefined): string {
|
|
2151
2011
|
const lines: string[] = [];
|
|
2152
2012
|
|
|
2153
2013
|
// Add summary or description as the main comment
|
|
@@ -2168,6 +2028,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2168
2028
|
if (lines.length > 0) {
|
|
2169
2029
|
lines.push(' *');
|
|
2170
2030
|
}
|
|
2031
|
+
|
|
2171
2032
|
descLines.forEach((line) => {
|
|
2172
2033
|
lines.push(` * ${line.trim() || ''}`);
|
|
2173
2034
|
});
|
|
@@ -2179,6 +2040,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2179
2040
|
if (lines.length > 0) {
|
|
2180
2041
|
lines.push(' *');
|
|
2181
2042
|
}
|
|
2043
|
+
|
|
2182
2044
|
for (const param of schema.parameters) {
|
|
2183
2045
|
const paramName = this.typeBuilder.sanitizeIdentifier(param.name);
|
|
2184
2046
|
const paramDesc = param.description ? ` ${param.description}` : '';
|
|
@@ -2206,18 +2068,11 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2206
2068
|
) {
|
|
2207
2069
|
// Extract the inner type from Promise<T>
|
|
2208
2070
|
const innerType = responseType.typeArguments[0];
|
|
2209
|
-
returnTypeText = this.printer.printNode(
|
|
2210
|
-
ts.EmitHint.Unspecified,
|
|
2211
|
-
innerType,
|
|
2212
|
-
ts.createSourceFile('', '', ts.ScriptTarget.Latest),
|
|
2213
|
-
);
|
|
2071
|
+
returnTypeText = this.printer.printNode(ts.EmitHint.Unspecified, innerType, ts.createSourceFile('', '', ts.ScriptTarget.Latest));
|
|
2214
2072
|
} else {
|
|
2215
|
-
returnTypeText = this.printer.printNode(
|
|
2216
|
-
ts.EmitHint.Unspecified,
|
|
2217
|
-
responseType,
|
|
2218
|
-
ts.createSourceFile('', '', ts.ScriptTarget.Latest),
|
|
2219
|
-
);
|
|
2073
|
+
returnTypeText = this.printer.printNode(ts.EmitHint.Unspecified, responseType, ts.createSourceFile('', '', ts.ScriptTarget.Latest));
|
|
2220
2074
|
}
|
|
2075
|
+
|
|
2221
2076
|
lines.push(` * @returns {${returnTypeText}}`);
|
|
2222
2077
|
}
|
|
2223
2078
|
|
|
@@ -2236,37 +2091,28 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2236
2091
|
|
|
2237
2092
|
const initialExpression = !safeInitial.success
|
|
2238
2093
|
? ts.factory.createCallExpression(
|
|
2239
|
-
ts.factory.createPropertyAccessExpression(
|
|
2240
|
-
ts.factory.createIdentifier('z'),
|
|
2241
|
-
ts.factory.createIdentifier(this.ZodAST.shape.type.parse(initial)),
|
|
2242
|
-
),
|
|
2094
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier(this.ZodAST.shape.type.parse(initial))),
|
|
2243
2095
|
undefined,
|
|
2244
|
-
[]
|
|
2096
|
+
[]
|
|
2245
2097
|
)
|
|
2246
2098
|
: ts.factory.createCallExpression(
|
|
2247
|
-
ts.factory.createPropertyAccessExpression(
|
|
2248
|
-
ts.factory.createIdentifier('z'),
|
|
2249
|
-
ts.factory.createIdentifier(safeInitial.data.type),
|
|
2250
|
-
),
|
|
2099
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier(safeInitial.data.type)),
|
|
2251
2100
|
undefined,
|
|
2252
|
-
(safeInitial.data.args ?? []) as ts.Expression[]
|
|
2101
|
+
(safeInitial.data.args ?? []) as ts.Expression[]
|
|
2253
2102
|
);
|
|
2254
2103
|
|
|
2255
2104
|
return rest.reduce((expression, exp: unknown) => {
|
|
2256
2105
|
const safeExp = this.ZodAST.safeParse(exp);
|
|
2257
2106
|
return !safeExp.success
|
|
2258
2107
|
? ts.factory.createCallExpression(
|
|
2259
|
-
ts.factory.createPropertyAccessExpression(
|
|
2260
|
-
expression,
|
|
2261
|
-
ts.factory.createIdentifier(typeof exp === 'string' ? exp : String(exp)),
|
|
2262
|
-
),
|
|
2108
|
+
ts.factory.createPropertyAccessExpression(expression, ts.factory.createIdentifier(typeof exp === 'string' ? exp : String(exp))),
|
|
2263
2109
|
undefined,
|
|
2264
|
-
[]
|
|
2110
|
+
[]
|
|
2265
2111
|
)
|
|
2266
2112
|
: ts.factory.createCallExpression(
|
|
2267
2113
|
ts.factory.createPropertyAccessExpression(expression, ts.factory.createIdentifier(safeExp.data.type)),
|
|
2268
2114
|
undefined,
|
|
2269
|
-
(safeExp.data.args ?? []) as ts.Expression[]
|
|
2115
|
+
(safeExp.data.args ?? []) as ts.Expression[]
|
|
2270
2116
|
);
|
|
2271
2117
|
}, initialExpression);
|
|
2272
2118
|
}
|
|
@@ -2282,13 +2128,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2282
2128
|
|
|
2283
2129
|
if (this.isReference(prop)) {
|
|
2284
2130
|
const refSchema = this.buildFromReference(prop);
|
|
2285
|
-
return required
|
|
2286
|
-
? refSchema
|
|
2287
|
-
: ts.factory.createCallExpression(
|
|
2288
|
-
ts.factory.createPropertyAccessExpression(refSchema, ts.factory.createIdentifier('optional')),
|
|
2289
|
-
undefined,
|
|
2290
|
-
[],
|
|
2291
|
-
);
|
|
2131
|
+
return required ? refSchema : ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(refSchema, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2292
2132
|
}
|
|
2293
2133
|
|
|
2294
2134
|
if (prop['anyOf'] && Array.isArray(prop['anyOf']) && prop['anyOf'].length > 0) {
|
|
@@ -2316,21 +2156,14 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2316
2156
|
// Use z.enum() for string enums
|
|
2317
2157
|
const enumValues = prop['enum'].map((val) => ts.factory.createStringLiteral(val as string, true));
|
|
2318
2158
|
const enumExpression = ts.factory.createCallExpression(
|
|
2319
|
-
ts.factory.createPropertyAccessExpression(
|
|
2320
|
-
ts.factory.createIdentifier('z'),
|
|
2321
|
-
ts.factory.createIdentifier('enum'),
|
|
2322
|
-
),
|
|
2159
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('enum')),
|
|
2323
2160
|
undefined,
|
|
2324
|
-
[ts.factory.createArrayLiteralExpression(enumValues, false)]
|
|
2161
|
+
[ts.factory.createArrayLiteralExpression(enumValues, false)]
|
|
2325
2162
|
);
|
|
2326
2163
|
|
|
2327
2164
|
return required
|
|
2328
2165
|
? enumExpression
|
|
2329
|
-
: ts.factory.createCallExpression(
|
|
2330
|
-
ts.factory.createPropertyAccessExpression(enumExpression, ts.factory.createIdentifier('optional')),
|
|
2331
|
-
undefined,
|
|
2332
|
-
[],
|
|
2333
|
-
);
|
|
2166
|
+
: ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(enumExpression, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2334
2167
|
} else {
|
|
2335
2168
|
// Use z.union([z.literal(...), ...]) for numeric/boolean/mixed enums
|
|
2336
2169
|
const literalSchemas = prop['enum'].map((val) => {
|
|
@@ -2340,10 +2173,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2340
2173
|
} else if (typeof val === 'number') {
|
|
2341
2174
|
// Handle negative numbers correctly
|
|
2342
2175
|
if (val < 0) {
|
|
2343
|
-
literalValue = ts.factory.createPrefixUnaryExpression(
|
|
2344
|
-
ts.SyntaxKind.MinusToken,
|
|
2345
|
-
ts.factory.createNumericLiteral(String(Math.abs(val))),
|
|
2346
|
-
);
|
|
2176
|
+
literalValue = ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, ts.factory.createNumericLiteral(String(Math.abs(val))));
|
|
2347
2177
|
} else {
|
|
2348
2178
|
literalValue = ts.factory.createNumericLiteral(String(val));
|
|
2349
2179
|
}
|
|
@@ -2353,32 +2183,20 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2353
2183
|
literalValue = ts.factory.createStringLiteral(String(val), true);
|
|
2354
2184
|
}
|
|
2355
2185
|
|
|
2356
|
-
return ts.factory.createCallExpression(
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
ts.factory.createIdentifier('literal'),
|
|
2360
|
-
),
|
|
2361
|
-
undefined,
|
|
2362
|
-
[literalValue],
|
|
2363
|
-
);
|
|
2186
|
+
return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('literal')), undefined, [
|
|
2187
|
+
literalValue
|
|
2188
|
+
]);
|
|
2364
2189
|
});
|
|
2365
2190
|
|
|
2366
2191
|
const unionExpression = ts.factory.createCallExpression(
|
|
2367
|
-
ts.factory.createPropertyAccessExpression(
|
|
2368
|
-
ts.factory.createIdentifier('z'),
|
|
2369
|
-
ts.factory.createIdentifier('union'),
|
|
2370
|
-
),
|
|
2192
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('union')),
|
|
2371
2193
|
undefined,
|
|
2372
|
-
[ts.factory.createArrayLiteralExpression(literalSchemas, false)]
|
|
2194
|
+
[ts.factory.createArrayLiteralExpression(literalSchemas, false)]
|
|
2373
2195
|
);
|
|
2374
2196
|
|
|
2375
2197
|
return required
|
|
2376
2198
|
? unionExpression
|
|
2377
|
-
: ts.factory.createCallExpression(
|
|
2378
|
-
ts.factory.createPropertyAccessExpression(unionExpression, ts.factory.createIdentifier('optional')),
|
|
2379
|
-
undefined,
|
|
2380
|
-
[],
|
|
2381
|
-
);
|
|
2199
|
+
: ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(unionExpression, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2382
2200
|
}
|
|
2383
2201
|
}
|
|
2384
2202
|
|
|
@@ -2388,33 +2206,26 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2388
2206
|
let arraySchema = this.buildZodAST([
|
|
2389
2207
|
{
|
|
2390
2208
|
type: 'array',
|
|
2391
|
-
args: [itemsSchema]
|
|
2392
|
-
}
|
|
2209
|
+
args: [itemsSchema]
|
|
2210
|
+
}
|
|
2393
2211
|
]);
|
|
2394
2212
|
|
|
2395
2213
|
// Apply array constraints
|
|
2396
2214
|
if (typeof prop['minItems'] === 'number') {
|
|
2397
|
-
arraySchema = ts.factory.createCallExpression(
|
|
2398
|
-
ts.factory.
|
|
2399
|
-
|
|
2400
|
-
[ts.factory.createNumericLiteral(String(prop['minItems']))],
|
|
2401
|
-
);
|
|
2215
|
+
arraySchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(arraySchema, ts.factory.createIdentifier('min')), undefined, [
|
|
2216
|
+
ts.factory.createNumericLiteral(String(prop['minItems']))
|
|
2217
|
+
]);
|
|
2402
2218
|
}
|
|
2219
|
+
|
|
2403
2220
|
if (typeof prop['maxItems'] === 'number') {
|
|
2404
|
-
arraySchema = ts.factory.createCallExpression(
|
|
2405
|
-
ts.factory.
|
|
2406
|
-
|
|
2407
|
-
[ts.factory.createNumericLiteral(String(prop['maxItems']))],
|
|
2408
|
-
);
|
|
2221
|
+
arraySchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(arraySchema, ts.factory.createIdentifier('max')), undefined, [
|
|
2222
|
+
ts.factory.createNumericLiteral(String(prop['maxItems']))
|
|
2223
|
+
]);
|
|
2409
2224
|
}
|
|
2410
2225
|
|
|
2411
2226
|
return required
|
|
2412
2227
|
? arraySchema
|
|
2413
|
-
: ts.factory.createCallExpression(
|
|
2414
|
-
ts.factory.createPropertyAccessExpression(arraySchema, ts.factory.createIdentifier('optional')),
|
|
2415
|
-
undefined,
|
|
2416
|
-
[],
|
|
2417
|
-
);
|
|
2228
|
+
: ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(arraySchema, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2418
2229
|
}
|
|
2419
2230
|
case 'object': {
|
|
2420
2231
|
const propObj = prop satisfies {
|
|
@@ -2433,110 +2244,86 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2433
2244
|
args: [
|
|
2434
2245
|
ts.factory.createObjectLiteralExpression(
|
|
2435
2246
|
propertiesEntries.map(([name, propValue]): ts.ObjectLiteralElementLike => {
|
|
2436
|
-
return ts.factory.createPropertyAssignment(
|
|
2437
|
-
ts.factory.createIdentifier(name),
|
|
2438
|
-
this.buildProperty(propValue, propRequired.includes(name)),
|
|
2439
|
-
);
|
|
2247
|
+
return ts.factory.createPropertyAssignment(ts.factory.createIdentifier(name), this.buildProperty(propValue, propRequired.includes(name)));
|
|
2440
2248
|
}),
|
|
2441
|
-
true
|
|
2442
|
-
)
|
|
2443
|
-
]
|
|
2444
|
-
}
|
|
2249
|
+
true
|
|
2250
|
+
)
|
|
2251
|
+
]
|
|
2252
|
+
}
|
|
2445
2253
|
]);
|
|
2446
2254
|
|
|
2447
2255
|
// Apply object constraints
|
|
2448
2256
|
let constrainedSchema = objectSchema;
|
|
2449
2257
|
if (typeof prop['minProperties'] === 'number') {
|
|
2450
|
-
constrainedSchema = ts.factory.createCallExpression(
|
|
2451
|
-
ts.factory.
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
ts.factory.
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
ts.factory.
|
|
2463
|
-
ts.factory.createPropertyAccessExpression(
|
|
2464
|
-
ts.factory.createIdentifier('Object'),
|
|
2465
|
-
ts.factory.createIdentifier('keys'),
|
|
2466
|
-
),
|
|
2467
|
-
undefined,
|
|
2468
|
-
[ts.factory.createIdentifier('obj')],
|
|
2469
|
-
),
|
|
2470
|
-
ts.factory.createIdentifier('length'),
|
|
2471
|
-
),
|
|
2472
|
-
ts.factory.createToken(ts.SyntaxKind.GreaterThanEqualsToken),
|
|
2473
|
-
ts.factory.createNumericLiteral(String(prop['minProperties'])),
|
|
2474
|
-
),
|
|
2475
|
-
),
|
|
2476
|
-
ts.factory.createObjectLiteralExpression([
|
|
2477
|
-
ts.factory.createPropertyAssignment(
|
|
2478
|
-
ts.factory.createIdentifier('message'),
|
|
2479
|
-
ts.factory.createStringLiteral(
|
|
2480
|
-
`Object must have at least ${String(prop['minProperties'])} properties`,
|
|
2258
|
+
constrainedSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(constrainedSchema, ts.factory.createIdentifier('refine')), undefined, [
|
|
2259
|
+
ts.factory.createArrowFunction(
|
|
2260
|
+
undefined,
|
|
2261
|
+
undefined,
|
|
2262
|
+
[ts.factory.createParameterDeclaration(undefined, undefined, 'obj', undefined, undefined, undefined)],
|
|
2263
|
+
undefined,
|
|
2264
|
+
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
2265
|
+
ts.factory.createBinaryExpression(
|
|
2266
|
+
ts.factory.createPropertyAccessExpression(
|
|
2267
|
+
ts.factory.createCallExpression(
|
|
2268
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('Object'), ts.factory.createIdentifier('keys')),
|
|
2269
|
+
undefined,
|
|
2270
|
+
[ts.factory.createIdentifier('obj')]
|
|
2481
2271
|
),
|
|
2272
|
+
ts.factory.createIdentifier('length')
|
|
2482
2273
|
),
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2274
|
+
ts.factory.createToken(ts.SyntaxKind.GreaterThanEqualsToken),
|
|
2275
|
+
ts.factory.createNumericLiteral(String(prop['minProperties']))
|
|
2276
|
+
)
|
|
2277
|
+
),
|
|
2278
|
+
ts.factory.createObjectLiteralExpression([
|
|
2279
|
+
ts.factory.createPropertyAssignment(
|
|
2280
|
+
ts.factory.createIdentifier('message'),
|
|
2281
|
+
ts.factory.createStringLiteral(`Object must have at least ${String(prop['minProperties'])} properties`)
|
|
2282
|
+
)
|
|
2283
|
+
])
|
|
2284
|
+
]);
|
|
2486
2285
|
}
|
|
2286
|
+
|
|
2487
2287
|
if (typeof prop['maxProperties'] === 'number') {
|
|
2488
|
-
constrainedSchema = ts.factory.createCallExpression(
|
|
2489
|
-
ts.factory.
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
ts.factory.
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
ts.factory.
|
|
2501
|
-
ts.factory.createPropertyAccessExpression(
|
|
2502
|
-
ts.factory.createIdentifier('Object'),
|
|
2503
|
-
ts.factory.createIdentifier('keys'),
|
|
2504
|
-
),
|
|
2505
|
-
undefined,
|
|
2506
|
-
[ts.factory.createIdentifier('obj')],
|
|
2507
|
-
),
|
|
2508
|
-
ts.factory.createIdentifier('length'),
|
|
2509
|
-
),
|
|
2510
|
-
ts.factory.createToken(ts.SyntaxKind.LessThanEqualsToken),
|
|
2511
|
-
ts.factory.createNumericLiteral(String(prop['maxProperties'])),
|
|
2512
|
-
),
|
|
2513
|
-
),
|
|
2514
|
-
ts.factory.createObjectLiteralExpression([
|
|
2515
|
-
ts.factory.createPropertyAssignment(
|
|
2516
|
-
ts.factory.createIdentifier('message'),
|
|
2517
|
-
ts.factory.createStringLiteral(
|
|
2518
|
-
`Object must have at most ${String(prop['maxProperties'])} properties`,
|
|
2288
|
+
constrainedSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(constrainedSchema, ts.factory.createIdentifier('refine')), undefined, [
|
|
2289
|
+
ts.factory.createArrowFunction(
|
|
2290
|
+
undefined,
|
|
2291
|
+
undefined,
|
|
2292
|
+
[ts.factory.createParameterDeclaration(undefined, undefined, 'obj', undefined, undefined, undefined)],
|
|
2293
|
+
undefined,
|
|
2294
|
+
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
2295
|
+
ts.factory.createBinaryExpression(
|
|
2296
|
+
ts.factory.createPropertyAccessExpression(
|
|
2297
|
+
ts.factory.createCallExpression(
|
|
2298
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('Object'), ts.factory.createIdentifier('keys')),
|
|
2299
|
+
undefined,
|
|
2300
|
+
[ts.factory.createIdentifier('obj')]
|
|
2519
2301
|
),
|
|
2302
|
+
ts.factory.createIdentifier('length')
|
|
2520
2303
|
),
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2304
|
+
ts.factory.createToken(ts.SyntaxKind.LessThanEqualsToken),
|
|
2305
|
+
ts.factory.createNumericLiteral(String(prop['maxProperties']))
|
|
2306
|
+
)
|
|
2307
|
+
),
|
|
2308
|
+
ts.factory.createObjectLiteralExpression([
|
|
2309
|
+
ts.factory.createPropertyAssignment(
|
|
2310
|
+
ts.factory.createIdentifier('message'),
|
|
2311
|
+
ts.factory.createStringLiteral(`Object must have at most ${String(prop['maxProperties'])} properties`)
|
|
2312
|
+
)
|
|
2313
|
+
])
|
|
2314
|
+
]);
|
|
2524
2315
|
}
|
|
2525
2316
|
|
|
2526
2317
|
return required
|
|
2527
2318
|
? constrainedSchema
|
|
2528
|
-
: ts.factory.createCallExpression(
|
|
2529
|
-
ts.factory.createPropertyAccessExpression(constrainedSchema, ts.factory.createIdentifier('optional')),
|
|
2530
|
-
undefined,
|
|
2531
|
-
[],
|
|
2532
|
-
);
|
|
2319
|
+
: ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(constrainedSchema, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2533
2320
|
}
|
|
2534
2321
|
|
|
2535
2322
|
return this.buildZodAST([
|
|
2536
2323
|
{
|
|
2537
2324
|
type: 'record',
|
|
2538
|
-
args: [this.buildZodAST(['string']), this.buildZodAST(['unknown'])]
|
|
2539
|
-
}
|
|
2325
|
+
args: [this.buildZodAST(['string']), this.buildZodAST(['unknown'])]
|
|
2326
|
+
}
|
|
2540
2327
|
]);
|
|
2541
2328
|
}
|
|
2542
2329
|
case 'integer': {
|
|
@@ -2544,35 +2331,26 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2544
2331
|
|
|
2545
2332
|
// Apply number constraints
|
|
2546
2333
|
if (prop['minimum'] !== undefined && typeof prop['minimum'] === 'number') {
|
|
2547
|
-
const minValue =
|
|
2548
|
-
prop['exclusiveMinimum'] && typeof prop['exclusiveMinimum'] === 'boolean'
|
|
2549
|
-
? prop['minimum'] + 1
|
|
2550
|
-
: prop['minimum'];
|
|
2334
|
+
const minValue = prop['exclusiveMinimum'] && typeof prop['exclusiveMinimum'] === 'boolean' ? prop['minimum'] + 1 : prop['minimum'];
|
|
2551
2335
|
numberSchema = ts.factory.createCallExpression(
|
|
2552
2336
|
ts.factory.createPropertyAccessExpression(
|
|
2553
2337
|
numberSchema,
|
|
2554
|
-
ts.factory.createIdentifier(
|
|
2555
|
-
prop['exclusiveMinimum'] && typeof prop['exclusiveMinimum'] === 'boolean' ? 'gt' : 'gte',
|
|
2556
|
-
),
|
|
2338
|
+
ts.factory.createIdentifier(prop['exclusiveMinimum'] && typeof prop['exclusiveMinimum'] === 'boolean' ? 'gt' : 'gte')
|
|
2557
2339
|
),
|
|
2558
2340
|
undefined,
|
|
2559
|
-
[ts.factory.createNumericLiteral(String(minValue))]
|
|
2341
|
+
[ts.factory.createNumericLiteral(String(minValue))]
|
|
2560
2342
|
);
|
|
2561
2343
|
}
|
|
2344
|
+
|
|
2562
2345
|
if (prop['maximum'] !== undefined && typeof prop['maximum'] === 'number') {
|
|
2563
|
-
const maxValue =
|
|
2564
|
-
prop['exclusiveMaximum'] && typeof prop['exclusiveMaximum'] === 'boolean'
|
|
2565
|
-
? prop['maximum'] - 1
|
|
2566
|
-
: prop['maximum'];
|
|
2346
|
+
const maxValue = prop['exclusiveMaximum'] && typeof prop['exclusiveMaximum'] === 'boolean' ? prop['maximum'] - 1 : prop['maximum'];
|
|
2567
2347
|
numberSchema = ts.factory.createCallExpression(
|
|
2568
|
-
ts.factory.createPropertyAccessExpression(
|
|
2569
|
-
numberSchema,
|
|
2570
|
-
ts.factory.createIdentifier(prop['exclusiveMaximum'] ? 'lt' : 'lte'),
|
|
2571
|
-
),
|
|
2348
|
+
ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier(prop['exclusiveMaximum'] ? 'lt' : 'lte')),
|
|
2572
2349
|
undefined,
|
|
2573
|
-
[ts.factory.createNumericLiteral(String(maxValue))]
|
|
2350
|
+
[ts.factory.createNumericLiteral(String(maxValue))]
|
|
2574
2351
|
);
|
|
2575
2352
|
}
|
|
2353
|
+
|
|
2576
2354
|
if (typeof prop['multipleOf'] === 'number') {
|
|
2577
2355
|
const refineFunction = ts.factory.createArrowFunction(
|
|
2578
2356
|
undefined,
|
|
@@ -2584,67 +2362,53 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2584
2362
|
ts.factory.createBinaryExpression(
|
|
2585
2363
|
ts.factory.createIdentifier('val'),
|
|
2586
2364
|
ts.factory.createToken(ts.SyntaxKind.PercentToken),
|
|
2587
|
-
ts.factory.createNumericLiteral(String(prop['multipleOf']))
|
|
2365
|
+
ts.factory.createNumericLiteral(String(prop['multipleOf']))
|
|
2588
2366
|
),
|
|
2589
2367
|
ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken),
|
|
2590
|
-
ts.factory.createNumericLiteral('0')
|
|
2591
|
-
)
|
|
2368
|
+
ts.factory.createNumericLiteral('0')
|
|
2369
|
+
)
|
|
2592
2370
|
);
|
|
2593
2371
|
const refineOptions = ts.factory.createObjectLiteralExpression([
|
|
2594
2372
|
ts.factory.createPropertyAssignment(
|
|
2595
2373
|
ts.factory.createIdentifier('message'),
|
|
2596
|
-
ts.factory.createStringLiteral(`Number must be a multiple of ${String(prop['multipleOf'])}`)
|
|
2597
|
-
)
|
|
2374
|
+
ts.factory.createStringLiteral(`Number must be a multiple of ${String(prop['multipleOf'])}`)
|
|
2375
|
+
)
|
|
2376
|
+
]);
|
|
2377
|
+
numberSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier('refine')), undefined, [
|
|
2378
|
+
refineFunction,
|
|
2379
|
+
refineOptions
|
|
2598
2380
|
]);
|
|
2599
|
-
numberSchema = ts.factory.createCallExpression(
|
|
2600
|
-
ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier('refine')),
|
|
2601
|
-
undefined,
|
|
2602
|
-
[refineFunction, refineOptions],
|
|
2603
|
-
);
|
|
2604
2381
|
}
|
|
2605
2382
|
|
|
2606
2383
|
return required
|
|
2607
2384
|
? numberSchema
|
|
2608
|
-
: ts.factory.createCallExpression(
|
|
2609
|
-
ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier('optional')),
|
|
2610
|
-
undefined,
|
|
2611
|
-
[],
|
|
2612
|
-
);
|
|
2385
|
+
: ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2613
2386
|
}
|
|
2614
2387
|
case 'number': {
|
|
2615
2388
|
let numberSchema = this.buildZodAST(['number']);
|
|
2616
2389
|
|
|
2617
2390
|
// Apply number constraints
|
|
2618
2391
|
if (prop['minimum'] !== undefined && typeof prop['minimum'] === 'number') {
|
|
2619
|
-
const minValue =
|
|
2620
|
-
prop['exclusiveMinimum'] && typeof prop['exclusiveMinimum'] === 'boolean'
|
|
2621
|
-
? prop['minimum'] + 1
|
|
2622
|
-
: prop['minimum'];
|
|
2392
|
+
const minValue = prop['exclusiveMinimum'] && typeof prop['exclusiveMinimum'] === 'boolean' ? prop['minimum'] + 1 : prop['minimum'];
|
|
2623
2393
|
numberSchema = ts.factory.createCallExpression(
|
|
2624
2394
|
ts.factory.createPropertyAccessExpression(
|
|
2625
2395
|
numberSchema,
|
|
2626
|
-
ts.factory.createIdentifier(
|
|
2627
|
-
prop['exclusiveMinimum'] && typeof prop['exclusiveMinimum'] === 'boolean' ? 'gt' : 'gte',
|
|
2628
|
-
),
|
|
2396
|
+
ts.factory.createIdentifier(prop['exclusiveMinimum'] && typeof prop['exclusiveMinimum'] === 'boolean' ? 'gt' : 'gte')
|
|
2629
2397
|
),
|
|
2630
2398
|
undefined,
|
|
2631
|
-
[ts.factory.createNumericLiteral(String(minValue))]
|
|
2399
|
+
[ts.factory.createNumericLiteral(String(minValue))]
|
|
2632
2400
|
);
|
|
2633
2401
|
}
|
|
2402
|
+
|
|
2634
2403
|
if (prop['maximum'] !== undefined && typeof prop['maximum'] === 'number') {
|
|
2635
|
-
const maxValue =
|
|
2636
|
-
prop['exclusiveMaximum'] && typeof prop['exclusiveMaximum'] === 'boolean'
|
|
2637
|
-
? prop['maximum'] - 1
|
|
2638
|
-
: prop['maximum'];
|
|
2404
|
+
const maxValue = prop['exclusiveMaximum'] && typeof prop['exclusiveMaximum'] === 'boolean' ? prop['maximum'] - 1 : prop['maximum'];
|
|
2639
2405
|
numberSchema = ts.factory.createCallExpression(
|
|
2640
|
-
ts.factory.createPropertyAccessExpression(
|
|
2641
|
-
numberSchema,
|
|
2642
|
-
ts.factory.createIdentifier(prop['exclusiveMaximum'] ? 'lt' : 'lte'),
|
|
2643
|
-
),
|
|
2406
|
+
ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier(prop['exclusiveMaximum'] ? 'lt' : 'lte')),
|
|
2644
2407
|
undefined,
|
|
2645
|
-
[ts.factory.createNumericLiteral(String(maxValue))]
|
|
2408
|
+
[ts.factory.createNumericLiteral(String(maxValue))]
|
|
2646
2409
|
);
|
|
2647
2410
|
}
|
|
2411
|
+
|
|
2648
2412
|
if (typeof prop['multipleOf'] === 'number') {
|
|
2649
2413
|
const refineFunction = ts.factory.createArrowFunction(
|
|
2650
2414
|
undefined,
|
|
@@ -2656,32 +2420,27 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2656
2420
|
ts.factory.createBinaryExpression(
|
|
2657
2421
|
ts.factory.createIdentifier('val'),
|
|
2658
2422
|
ts.factory.createToken(ts.SyntaxKind.PercentToken),
|
|
2659
|
-
ts.factory.createNumericLiteral(String(prop['multipleOf']))
|
|
2423
|
+
ts.factory.createNumericLiteral(String(prop['multipleOf']))
|
|
2660
2424
|
),
|
|
2661
2425
|
ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken),
|
|
2662
|
-
ts.factory.createNumericLiteral('0')
|
|
2663
|
-
)
|
|
2426
|
+
ts.factory.createNumericLiteral('0')
|
|
2427
|
+
)
|
|
2664
2428
|
);
|
|
2665
2429
|
const refineOptions = ts.factory.createObjectLiteralExpression([
|
|
2666
2430
|
ts.factory.createPropertyAssignment(
|
|
2667
2431
|
ts.factory.createIdentifier('message'),
|
|
2668
|
-
ts.factory.createStringLiteral(`Number must be a multiple of ${String(prop['multipleOf'])}`)
|
|
2669
|
-
)
|
|
2432
|
+
ts.factory.createStringLiteral(`Number must be a multiple of ${String(prop['multipleOf'])}`)
|
|
2433
|
+
)
|
|
2434
|
+
]);
|
|
2435
|
+
numberSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier('refine')), undefined, [
|
|
2436
|
+
refineFunction,
|
|
2437
|
+
refineOptions
|
|
2670
2438
|
]);
|
|
2671
|
-
numberSchema = ts.factory.createCallExpression(
|
|
2672
|
-
ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier('refine')),
|
|
2673
|
-
undefined,
|
|
2674
|
-
[refineFunction, refineOptions],
|
|
2675
|
-
);
|
|
2676
2439
|
}
|
|
2677
2440
|
|
|
2678
2441
|
return required
|
|
2679
2442
|
? numberSchema
|
|
2680
|
-
: ts.factory.createCallExpression(
|
|
2681
|
-
ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier('optional')),
|
|
2682
|
-
undefined,
|
|
2683
|
-
[],
|
|
2684
|
-
);
|
|
2443
|
+
: ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(numberSchema, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2685
2444
|
}
|
|
2686
2445
|
case 'string': {
|
|
2687
2446
|
let stringSchema = this.buildZodAST(['string']);
|
|
@@ -2691,67 +2450,48 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2691
2450
|
switch (prop['format']) {
|
|
2692
2451
|
case 'email':
|
|
2693
2452
|
stringSchema = ts.factory.createCallExpression(
|
|
2694
|
-
ts.factory.createPropertyAccessExpression(
|
|
2695
|
-
ts.factory.createIdentifier('z'),
|
|
2696
|
-
ts.factory.createIdentifier('email'),
|
|
2697
|
-
),
|
|
2453
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('email')),
|
|
2698
2454
|
undefined,
|
|
2699
|
-
[]
|
|
2455
|
+
[]
|
|
2700
2456
|
);
|
|
2701
2457
|
break;
|
|
2702
2458
|
case 'uri':
|
|
2703
2459
|
case 'url':
|
|
2704
2460
|
stringSchema = ts.factory.createCallExpression(
|
|
2705
|
-
ts.factory.createPropertyAccessExpression(
|
|
2706
|
-
ts.factory.createIdentifier('z'),
|
|
2707
|
-
ts.factory.createIdentifier('url'),
|
|
2708
|
-
),
|
|
2461
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('url')),
|
|
2709
2462
|
undefined,
|
|
2710
|
-
[]
|
|
2463
|
+
[]
|
|
2711
2464
|
);
|
|
2712
2465
|
break;
|
|
2713
2466
|
case 'uuid':
|
|
2714
2467
|
stringSchema = ts.factory.createCallExpression(
|
|
2715
|
-
ts.factory.createPropertyAccessExpression(
|
|
2716
|
-
ts.factory.createIdentifier('z'),
|
|
2717
|
-
ts.factory.createIdentifier('uuid'),
|
|
2718
|
-
),
|
|
2468
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('uuid')),
|
|
2719
2469
|
undefined,
|
|
2720
|
-
[]
|
|
2470
|
+
[]
|
|
2721
2471
|
);
|
|
2722
2472
|
break;
|
|
2723
2473
|
case 'date-time':
|
|
2724
2474
|
stringSchema = ts.factory.createCallExpression(
|
|
2725
2475
|
ts.factory.createPropertyAccessExpression(
|
|
2726
|
-
ts.factory.createPropertyAccessExpression(
|
|
2727
|
-
|
|
2728
|
-
ts.factory.createIdentifier('iso'),
|
|
2729
|
-
),
|
|
2730
|
-
ts.factory.createIdentifier('datetime'),
|
|
2476
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('iso')),
|
|
2477
|
+
ts.factory.createIdentifier('datetime')
|
|
2731
2478
|
),
|
|
2732
2479
|
undefined,
|
|
2733
|
-
[this.buildDefaultValue({local: true})]
|
|
2480
|
+
[this.buildDefaultValue({ local: true })]
|
|
2734
2481
|
);
|
|
2735
2482
|
break;
|
|
2736
2483
|
case 'date':
|
|
2737
2484
|
stringSchema = ts.factory.createCallExpression(
|
|
2738
2485
|
ts.factory.createPropertyAccessExpression(
|
|
2739
|
-
ts.factory.createPropertyAccessExpression(
|
|
2740
|
-
|
|
2741
|
-
ts.factory.createIdentifier('iso'),
|
|
2742
|
-
),
|
|
2743
|
-
ts.factory.createIdentifier('date'),
|
|
2486
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('iso')),
|
|
2487
|
+
ts.factory.createIdentifier('date')
|
|
2744
2488
|
),
|
|
2745
2489
|
undefined,
|
|
2746
|
-
[]
|
|
2490
|
+
[]
|
|
2747
2491
|
);
|
|
2748
2492
|
break;
|
|
2749
2493
|
case 'time':
|
|
2750
|
-
stringSchema = ts.factory.createCallExpression(
|
|
2751
|
-
ts.factory.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('time')),
|
|
2752
|
-
undefined,
|
|
2753
|
-
[],
|
|
2754
|
-
);
|
|
2494
|
+
stringSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('time')), undefined, []);
|
|
2755
2495
|
break;
|
|
2756
2496
|
// Add more formats as needed
|
|
2757
2497
|
}
|
|
@@ -2759,74 +2499,49 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2759
2499
|
|
|
2760
2500
|
// Apply string constraints
|
|
2761
2501
|
if (typeof prop['minLength'] === 'number') {
|
|
2762
|
-
stringSchema = ts.factory.createCallExpression(
|
|
2763
|
-
ts.factory.
|
|
2764
|
-
|
|
2765
|
-
[ts.factory.createNumericLiteral(String(prop['minLength']))],
|
|
2766
|
-
);
|
|
2502
|
+
stringSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('min')), undefined, [
|
|
2503
|
+
ts.factory.createNumericLiteral(String(prop['minLength']))
|
|
2504
|
+
]);
|
|
2767
2505
|
}
|
|
2506
|
+
|
|
2768
2507
|
if (typeof prop['maxLength'] === 'number') {
|
|
2769
|
-
stringSchema = ts.factory.createCallExpression(
|
|
2770
|
-
ts.factory.
|
|
2771
|
-
|
|
2772
|
-
[ts.factory.createNumericLiteral(String(prop['maxLength']))],
|
|
2773
|
-
);
|
|
2508
|
+
stringSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('max')), undefined, [
|
|
2509
|
+
ts.factory.createNumericLiteral(String(prop['maxLength']))
|
|
2510
|
+
]);
|
|
2774
2511
|
}
|
|
2512
|
+
|
|
2775
2513
|
if (prop['pattern'] && typeof prop['pattern'] === 'string') {
|
|
2776
|
-
stringSchema = ts.factory.createCallExpression(
|
|
2777
|
-
ts.factory.
|
|
2778
|
-
|
|
2779
|
-
[
|
|
2780
|
-
ts.factory.createNewExpression(ts.factory.createIdentifier('RegExp'), undefined, [
|
|
2781
|
-
ts.factory.createStringLiteral(prop['pattern'], true),
|
|
2782
|
-
]),
|
|
2783
|
-
],
|
|
2784
|
-
);
|
|
2514
|
+
stringSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('regex')), undefined, [
|
|
2515
|
+
ts.factory.createNewExpression(ts.factory.createIdentifier('RegExp'), undefined, [ts.factory.createStringLiteral(prop['pattern'], true)])
|
|
2516
|
+
]);
|
|
2785
2517
|
}
|
|
2786
2518
|
|
|
2787
2519
|
// Apply default value if not required
|
|
2788
2520
|
if (!required && prop['default'] !== undefined) {
|
|
2789
2521
|
const defaultValue = this.buildDefaultValue(prop['default']);
|
|
2790
|
-
stringSchema = ts.factory.createCallExpression(
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
[defaultValue],
|
|
2794
|
-
);
|
|
2522
|
+
stringSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('default')), undefined, [
|
|
2523
|
+
defaultValue
|
|
2524
|
+
]);
|
|
2795
2525
|
}
|
|
2796
2526
|
|
|
2797
2527
|
return required
|
|
2798
2528
|
? stringSchema
|
|
2799
|
-
: ts.factory.createCallExpression(
|
|
2800
|
-
ts.factory.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('optional')),
|
|
2801
|
-
undefined,
|
|
2802
|
-
[],
|
|
2803
|
-
);
|
|
2529
|
+
: ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2804
2530
|
}
|
|
2805
2531
|
case 'boolean': {
|
|
2806
2532
|
let booleanSchema = this.buildZodAST(['boolean']);
|
|
2807
2533
|
|
|
2808
2534
|
// Apply default value if not required
|
|
2809
2535
|
if (!required && prop['default'] !== undefined) {
|
|
2810
|
-
const defaultValue =
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
: ts.factory.createFalse()
|
|
2815
|
-
: ts.factory.createFalse();
|
|
2816
|
-
booleanSchema = ts.factory.createCallExpression(
|
|
2817
|
-
ts.factory.createPropertyAccessExpression(booleanSchema, ts.factory.createIdentifier('default')),
|
|
2818
|
-
undefined,
|
|
2819
|
-
[defaultValue],
|
|
2820
|
-
);
|
|
2536
|
+
const defaultValue = typeof prop['default'] === 'boolean' ? (prop['default'] ? ts.factory.createTrue() : ts.factory.createFalse()) : ts.factory.createFalse();
|
|
2537
|
+
booleanSchema = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(booleanSchema, ts.factory.createIdentifier('default')), undefined, [
|
|
2538
|
+
defaultValue
|
|
2539
|
+
]);
|
|
2821
2540
|
}
|
|
2822
2541
|
|
|
2823
2542
|
return required
|
|
2824
2543
|
? booleanSchema
|
|
2825
|
-
: ts.factory.createCallExpression(
|
|
2826
|
-
ts.factory.createPropertyAccessExpression(booleanSchema, ts.factory.createIdentifier('optional')),
|
|
2827
|
-
undefined,
|
|
2828
|
-
[],
|
|
2829
|
-
);
|
|
2544
|
+
: ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(booleanSchema, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2830
2545
|
}
|
|
2831
2546
|
case 'unknown':
|
|
2832
2547
|
default:
|
|
@@ -2838,54 +2553,52 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2838
2553
|
if (typeof value === 'string') {
|
|
2839
2554
|
return ts.factory.createStringLiteral(value, true);
|
|
2840
2555
|
}
|
|
2556
|
+
|
|
2841
2557
|
if (typeof value === 'number') {
|
|
2842
2558
|
return ts.factory.createNumericLiteral(String(value));
|
|
2843
2559
|
}
|
|
2560
|
+
|
|
2844
2561
|
if (typeof value === 'boolean') {
|
|
2845
2562
|
return value ? ts.factory.createTrue() : ts.factory.createFalse();
|
|
2846
2563
|
}
|
|
2564
|
+
|
|
2847
2565
|
if (value === null) {
|
|
2848
2566
|
return ts.factory.createNull();
|
|
2849
2567
|
}
|
|
2568
|
+
|
|
2850
2569
|
if (Array.isArray(value)) {
|
|
2851
2570
|
return ts.factory.createArrayLiteralExpression(
|
|
2852
2571
|
value.map((item) => this.buildDefaultValue(item)),
|
|
2853
|
-
false
|
|
2572
|
+
false
|
|
2854
2573
|
);
|
|
2855
2574
|
}
|
|
2575
|
+
|
|
2856
2576
|
if (typeof value === 'object') {
|
|
2857
2577
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
2858
2578
|
if (value === null) {
|
|
2859
2579
|
return ts.factory.createNull();
|
|
2860
2580
|
}
|
|
2581
|
+
|
|
2861
2582
|
return ts.factory.createObjectLiteralExpression(
|
|
2862
|
-
Object.entries(value).map(([key, val]) =>
|
|
2863
|
-
|
|
2864
|
-
),
|
|
2865
|
-
true,
|
|
2583
|
+
Object.entries(value).map(([key, val]) => ts.factory.createPropertyAssignment(ts.factory.createIdentifier(key), this.buildDefaultValue(val))),
|
|
2584
|
+
true
|
|
2866
2585
|
);
|
|
2867
2586
|
}
|
|
2587
|
+
|
|
2868
2588
|
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
2869
2589
|
return ts.factory.createStringLiteral(String(value), true);
|
|
2870
2590
|
}
|
|
2591
|
+
|
|
2871
2592
|
// For objects and arrays, we need to handle them differently
|
|
2872
2593
|
// This should not happen in practice, but we handle it for type safety
|
|
2873
2594
|
return ts.factory.createStringLiteral(JSON.stringify(value), true);
|
|
2874
2595
|
}
|
|
2875
2596
|
|
|
2876
|
-
private handleLogicalOperator(
|
|
2877
|
-
operator: 'anyOf' | 'oneOf' | 'allOf' | 'not',
|
|
2878
|
-
schemas: unknown[],
|
|
2879
|
-
required: boolean,
|
|
2880
|
-
): ts.CallExpression {
|
|
2597
|
+
private handleLogicalOperator(operator: 'anyOf' | 'oneOf' | 'allOf' | 'not', schemas: unknown[], required: boolean): ts.CallExpression {
|
|
2881
2598
|
const logicalExpression = this.buildLogicalOperator(operator, schemas);
|
|
2882
2599
|
return required
|
|
2883
2600
|
? logicalExpression
|
|
2884
|
-
: ts.factory.createCallExpression(
|
|
2885
|
-
ts.factory.createPropertyAccessExpression(logicalExpression, ts.factory.createIdentifier('optional')),
|
|
2886
|
-
undefined,
|
|
2887
|
-
[],
|
|
2888
|
-
);
|
|
2601
|
+
: ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(logicalExpression, ts.factory.createIdentifier('optional')), undefined, []);
|
|
2889
2602
|
}
|
|
2890
2603
|
|
|
2891
2604
|
private buildLogicalOperator(operator: 'anyOf' | 'oneOf' | 'allOf' | 'not', schemas: unknown[]): ts.CallExpression {
|
|
@@ -2893,14 +2606,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2893
2606
|
case 'anyOf':
|
|
2894
2607
|
case 'oneOf': {
|
|
2895
2608
|
const unionSchemas = schemas.map((schema) => this.buildSchemaFromLogicalOperator(schema));
|
|
2896
|
-
return ts.factory.createCallExpression(
|
|
2897
|
-
ts.factory.
|
|
2898
|
-
|
|
2899
|
-
ts.factory.createIdentifier('union'),
|
|
2900
|
-
),
|
|
2901
|
-
undefined,
|
|
2902
|
-
[ts.factory.createArrayLiteralExpression(unionSchemas, false)],
|
|
2903
|
-
);
|
|
2609
|
+
return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('union')), undefined, [
|
|
2610
|
+
ts.factory.createArrayLiteralExpression(unionSchemas, false)
|
|
2611
|
+
]);
|
|
2904
2612
|
}
|
|
2905
2613
|
case 'allOf': {
|
|
2906
2614
|
if (schemas.length === 0) {
|
|
@@ -2911,12 +2619,9 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2911
2619
|
return schemas.slice(1).reduce<ts.Expression>((acc, schema) => {
|
|
2912
2620
|
const schemaExpression = this.buildSchemaFromLogicalOperator(schema);
|
|
2913
2621
|
return ts.factory.createCallExpression(
|
|
2914
|
-
ts.factory.createPropertyAccessExpression(
|
|
2915
|
-
ts.factory.createIdentifier('z'),
|
|
2916
|
-
ts.factory.createIdentifier('intersection'),
|
|
2917
|
-
),
|
|
2622
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('intersection')),
|
|
2918
2623
|
undefined,
|
|
2919
|
-
[acc, schemaExpression]
|
|
2624
|
+
[acc, schemaExpression]
|
|
2920
2625
|
);
|
|
2921
2626
|
}, firstSchema) as ts.CallExpression;
|
|
2922
2627
|
}
|
|
@@ -2924,11 +2629,8 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2924
2629
|
const notSchema = this.buildSchemaFromLogicalOperator(schemas[0]);
|
|
2925
2630
|
return ts.factory.createCallExpression(
|
|
2926
2631
|
ts.factory.createPropertyAccessExpression(
|
|
2927
|
-
ts.factory.createPropertyAccessExpression(
|
|
2928
|
-
|
|
2929
|
-
ts.factory.createIdentifier('any'),
|
|
2930
|
-
),
|
|
2931
|
-
ts.factory.createIdentifier('refine'),
|
|
2632
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('any')),
|
|
2633
|
+
ts.factory.createIdentifier('refine')
|
|
2932
2634
|
),
|
|
2933
2635
|
undefined,
|
|
2934
2636
|
[
|
|
@@ -2940,20 +2642,15 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2940
2642
|
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
2941
2643
|
ts.factory.createPrefixUnaryExpression(
|
|
2942
2644
|
ts.SyntaxKind.ExclamationToken,
|
|
2943
|
-
ts.factory.createCallExpression(
|
|
2944
|
-
ts.factory.
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
),
|
|
2948
|
-
),
|
|
2645
|
+
ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(notSchema, ts.factory.createIdentifier('safeParse')), undefined, [
|
|
2646
|
+
ts.factory.createIdentifier('val')
|
|
2647
|
+
])
|
|
2648
|
+
)
|
|
2949
2649
|
),
|
|
2950
2650
|
ts.factory.createObjectLiteralExpression([
|
|
2951
|
-
ts.factory.createPropertyAssignment(
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
),
|
|
2955
|
-
]),
|
|
2956
|
-
],
|
|
2651
|
+
ts.factory.createPropertyAssignment(ts.factory.createIdentifier('message'), ts.factory.createStringLiteral('Value must not match the excluded schema'))
|
|
2652
|
+
])
|
|
2653
|
+
]
|
|
2957
2654
|
);
|
|
2958
2655
|
}
|
|
2959
2656
|
default:
|
|
@@ -2977,7 +2674,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
2977
2674
|
|
|
2978
2675
|
private buildBasicTypeFromSchema(schema: unknown): ts.CallExpression | ts.Identifier {
|
|
2979
2676
|
if (typeof schema === 'object' && schema !== null && 'type' in schema) {
|
|
2980
|
-
const schemaObj = schema as {type: string; properties?: Record<string, unknown>; items?: unknown};
|
|
2677
|
+
const schemaObj = schema as { type: string; properties?: Record<string, unknown>; items?: unknown };
|
|
2981
2678
|
|
|
2982
2679
|
switch (schemaObj.type) {
|
|
2983
2680
|
case 'string':
|
|
@@ -3000,7 +2697,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
3000
2697
|
return this.buildZodAST(['unknown']);
|
|
3001
2698
|
}
|
|
3002
2699
|
|
|
3003
|
-
private buildObjectTypeFromSchema(schemaObj: {properties?: Record<string, unknown>}): ts.CallExpression {
|
|
2700
|
+
private buildObjectTypeFromSchema(schemaObj: { properties?: Record<string, unknown> }): ts.CallExpression {
|
|
3004
2701
|
const properties = Object.entries(schemaObj.properties ?? {});
|
|
3005
2702
|
|
|
3006
2703
|
if (properties.length > 0) {
|
|
@@ -3010,71 +2707,63 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
3010
2707
|
args: [
|
|
3011
2708
|
ts.factory.createObjectLiteralExpression(
|
|
3012
2709
|
properties.map(([name, property]): ts.ObjectLiteralElementLike => {
|
|
3013
|
-
return ts.factory.createPropertyAssignment(
|
|
3014
|
-
ts.factory.createIdentifier(name),
|
|
3015
|
-
this.buildSchemaFromLogicalOperator(property),
|
|
3016
|
-
);
|
|
2710
|
+
return ts.factory.createPropertyAssignment(ts.factory.createIdentifier(name), this.buildSchemaFromLogicalOperator(property));
|
|
3017
2711
|
}),
|
|
3018
|
-
true
|
|
3019
|
-
)
|
|
3020
|
-
]
|
|
3021
|
-
}
|
|
2712
|
+
true
|
|
2713
|
+
)
|
|
2714
|
+
]
|
|
2715
|
+
}
|
|
3022
2716
|
]);
|
|
3023
2717
|
}
|
|
3024
2718
|
|
|
3025
2719
|
return this.buildZodAST([
|
|
3026
2720
|
{
|
|
3027
2721
|
type: 'record',
|
|
3028
|
-
args: [this.buildZodAST(['string']), this.buildZodAST(['unknown'])]
|
|
3029
|
-
}
|
|
2722
|
+
args: [this.buildZodAST(['string']), this.buildZodAST(['unknown'])]
|
|
2723
|
+
}
|
|
3030
2724
|
]);
|
|
3031
2725
|
}
|
|
3032
2726
|
|
|
3033
|
-
private buildArrayTypeFromSchema(schemaObj: {items?: unknown}): ts.CallExpression {
|
|
2727
|
+
private buildArrayTypeFromSchema(schemaObj: { items?: unknown }): ts.CallExpression {
|
|
3034
2728
|
if (schemaObj.items) {
|
|
3035
2729
|
return this.buildZodAST([
|
|
3036
2730
|
{
|
|
3037
2731
|
type: 'array',
|
|
3038
|
-
args: [this.buildSchemaFromLogicalOperator(schemaObj.items)]
|
|
3039
|
-
}
|
|
2732
|
+
args: [this.buildSchemaFromLogicalOperator(schemaObj.items)]
|
|
2733
|
+
}
|
|
3040
2734
|
]);
|
|
3041
2735
|
}
|
|
2736
|
+
|
|
3042
2737
|
return this.buildZodAST(['array']);
|
|
3043
2738
|
}
|
|
3044
2739
|
|
|
3045
2740
|
private isReference(reference: unknown): reference is ReferenceType {
|
|
3046
2741
|
if (typeof reference === 'object' && reference !== null && '$ref' in reference) {
|
|
3047
|
-
const ref = reference satisfies {$ref?: unknown};
|
|
2742
|
+
const ref = reference satisfies { $ref?: unknown };
|
|
3048
2743
|
return typeof ref.$ref === 'string' && ref.$ref.length > 0;
|
|
3049
2744
|
}
|
|
2745
|
+
|
|
3050
2746
|
return false;
|
|
3051
2747
|
}
|
|
3052
2748
|
|
|
3053
2749
|
private buildFromReference(reference: ReferenceType): ts.CallExpression | ts.Identifier {
|
|
3054
|
-
const {$ref = ''} = Reference.parse(reference);
|
|
2750
|
+
const { $ref = '' } = Reference.parse(reference);
|
|
3055
2751
|
const refName = $ref.split('/').pop() ?? 'never';
|
|
3056
2752
|
const sanitizedRefName = this.typeBuilder.sanitizeIdentifier(refName);
|
|
3057
2753
|
|
|
3058
2754
|
// Check if this reference creates a circular dependency
|
|
3059
2755
|
if (this.isCircularReference(refName)) {
|
|
3060
2756
|
// Generate: z.lazy(() => RefSchema)
|
|
3061
|
-
return ts.factory.createCallExpression(
|
|
3062
|
-
ts.factory.
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
ts.factory.
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
[],
|
|
3072
|
-
undefined,
|
|
3073
|
-
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
3074
|
-
ts.factory.createIdentifier(sanitizedRefName),
|
|
3075
|
-
),
|
|
3076
|
-
],
|
|
3077
|
-
);
|
|
2757
|
+
return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('lazy')), undefined, [
|
|
2758
|
+
ts.factory.createArrowFunction(
|
|
2759
|
+
undefined,
|
|
2760
|
+
undefined,
|
|
2761
|
+
[],
|
|
2762
|
+
undefined,
|
|
2763
|
+
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
2764
|
+
ts.factory.createIdentifier(sanitizedRefName)
|
|
2765
|
+
)
|
|
2766
|
+
]);
|
|
3078
2767
|
}
|
|
3079
2768
|
|
|
3080
2769
|
return ts.factory.createIdentifier(sanitizedRefName);
|
|
@@ -3094,11 +2783,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
3094
2783
|
|
|
3095
2784
|
// Case 2: Reference to a schema that's part of a circular dependency chain
|
|
3096
2785
|
// and we're currently building a schema that's also in that chain
|
|
3097
|
-
if (
|
|
3098
|
-
this.circularSchemas.has(refName) &&
|
|
3099
|
-
this.currentSchemaName !== null &&
|
|
3100
|
-
this.circularSchemas.has(this.currentSchemaName)
|
|
3101
|
-
) {
|
|
2786
|
+
if (this.circularSchemas.has(refName) && this.currentSchemaName !== null && this.circularSchemas.has(this.currentSchemaName)) {
|
|
3102
2787
|
return true;
|
|
3103
2788
|
}
|
|
3104
2789
|
|
|
@@ -3116,11 +2801,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
3116
2801
|
// Build dependency graph
|
|
3117
2802
|
const graph = new Map<string, string[]>();
|
|
3118
2803
|
for (const [name, schema] of Object.entries(schemas)) {
|
|
3119
|
-
const dependencies =
|
|
3120
|
-
.query(schema, '$..["$ref"]')
|
|
3121
|
-
.filter((ref: string) => ref.startsWith('#/components/schemas/'))
|
|
3122
|
-
.map((ref: string) => ref.replace('#/components/schemas/', ''))
|
|
3123
|
-
.filter((dep: string) => dep in schemas);
|
|
2804
|
+
const dependencies = this.extractSchemaReferences(schema).filter((dep: string) => dep in schemas);
|
|
3124
2805
|
graph.set(name, dependencies);
|
|
3125
2806
|
}
|
|
3126
2807
|
|
|
@@ -3200,16 +2881,14 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
3200
2881
|
if (visiting.has(name)) {
|
|
3201
2882
|
return;
|
|
3202
2883
|
}
|
|
2884
|
+
|
|
3203
2885
|
if (visited.has(name)) {
|
|
3204
2886
|
return;
|
|
3205
2887
|
}
|
|
3206
2888
|
|
|
3207
2889
|
visiting.add(name);
|
|
3208
2890
|
const schema = schemas[name];
|
|
3209
|
-
const dependencies =
|
|
3210
|
-
.query(schema, '$..["$ref"]')
|
|
3211
|
-
.filter((ref: string) => ref.startsWith('#/components/schemas/'))
|
|
3212
|
-
.map((ref: string) => ref.replace('#/components/schemas/', ''));
|
|
2891
|
+
const dependencies = this.extractSchemaReferences(schema);
|
|
3213
2892
|
|
|
3214
2893
|
for (const dep of dependencies) {
|
|
3215
2894
|
if (schemas[dep]) {
|