zod-codegen 1.6.3 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/.github/workflows/ci.yml +50 -48
  2. package/.github/workflows/release.yml +13 -3
  3. package/.husky/commit-msg +1 -1
  4. package/.husky/pre-commit +1 -1
  5. package/.lintstagedrc.json +5 -1
  6. package/.nvmrc +1 -1
  7. package/.prettierrc.json +12 -5
  8. package/CHANGELOG.md +11 -0
  9. package/CONTRIBUTING.md +12 -12
  10. package/EXAMPLES.md +135 -57
  11. package/PERFORMANCE.md +4 -4
  12. package/README.md +87 -64
  13. package/SECURITY.md +1 -1
  14. package/dist/src/cli.js +11 -18
  15. package/dist/src/generator.d.ts +2 -2
  16. package/dist/src/generator.d.ts.map +1 -1
  17. package/dist/src/generator.js +5 -3
  18. package/dist/src/interfaces/code-generator.d.ts.map +1 -1
  19. package/dist/src/services/code-generator.service.d.ts +3 -1
  20. package/dist/src/services/code-generator.service.d.ts.map +1 -1
  21. package/dist/src/services/code-generator.service.js +236 -219
  22. package/dist/src/services/file-reader.service.d.ts.map +1 -1
  23. package/dist/src/services/file-reader.service.js +1 -1
  24. package/dist/src/services/file-writer.service.d.ts.map +1 -1
  25. package/dist/src/services/file-writer.service.js +2 -2
  26. package/dist/src/services/import-builder.service.d.ts.map +1 -1
  27. package/dist/src/services/import-builder.service.js +3 -3
  28. package/dist/src/services/type-builder.service.d.ts.map +1 -1
  29. package/dist/src/types/generator-options.d.ts.map +1 -1
  30. package/dist/src/types/openapi.d.ts.map +1 -1
  31. package/dist/src/types/openapi.js +20 -20
  32. package/dist/src/utils/error-handler.d.ts.map +1 -1
  33. package/dist/src/utils/naming-convention.d.ts.map +1 -1
  34. package/dist/src/utils/naming-convention.js +6 -3
  35. package/dist/src/utils/signal-handler.d.ts.map +1 -1
  36. package/dist/tests/integration/cli-comprehensive.test.d.ts +2 -0
  37. package/dist/tests/integration/cli-comprehensive.test.d.ts.map +1 -0
  38. package/dist/tests/integration/cli-comprehensive.test.js +110 -0
  39. package/dist/tests/integration/cli.test.d.ts +2 -0
  40. package/dist/tests/integration/cli.test.d.ts.map +1 -0
  41. package/dist/tests/integration/cli.test.js +25 -0
  42. package/dist/tests/integration/error-scenarios.test.d.ts +2 -0
  43. package/dist/tests/integration/error-scenarios.test.d.ts.map +1 -0
  44. package/dist/tests/integration/error-scenarios.test.js +169 -0
  45. package/dist/tests/integration/snapshots.test.d.ts +2 -0
  46. package/dist/tests/integration/snapshots.test.d.ts.map +1 -0
  47. package/dist/tests/integration/snapshots.test.js +100 -0
  48. package/dist/tests/unit/code-generator-edge-cases.test.d.ts +2 -0
  49. package/dist/tests/unit/code-generator-edge-cases.test.d.ts.map +1 -0
  50. package/dist/tests/unit/code-generator-edge-cases.test.js +506 -0
  51. package/dist/tests/unit/code-generator.test.d.ts +2 -0
  52. package/dist/tests/unit/code-generator.test.d.ts.map +1 -0
  53. package/dist/tests/unit/code-generator.test.js +1364 -0
  54. package/dist/tests/unit/file-reader.test.d.ts +2 -0
  55. package/dist/tests/unit/file-reader.test.d.ts.map +1 -0
  56. package/dist/tests/unit/file-reader.test.js +125 -0
  57. package/dist/tests/unit/generator.test.d.ts +2 -0
  58. package/dist/tests/unit/generator.test.d.ts.map +1 -0
  59. package/dist/tests/unit/generator.test.js +119 -0
  60. package/dist/tests/unit/naming-convention.test.d.ts +2 -0
  61. package/dist/tests/unit/naming-convention.test.d.ts.map +1 -0
  62. package/dist/tests/unit/naming-convention.test.js +256 -0
  63. package/dist/tests/unit/reporter.test.d.ts +2 -0
  64. package/dist/tests/unit/reporter.test.d.ts.map +1 -0
  65. package/dist/tests/unit/reporter.test.js +44 -0
  66. package/dist/tests/unit/type-builder.test.d.ts +2 -0
  67. package/dist/tests/unit/type-builder.test.d.ts.map +1 -0
  68. package/dist/tests/unit/type-builder.test.js +108 -0
  69. package/dist/vitest.config.d.ts.map +1 -1
  70. package/dist/vitest.config.js +10 -20
  71. package/eslint.config.mjs +38 -28
  72. package/examples/.gitkeep +1 -1
  73. package/examples/README.md +4 -2
  74. package/examples/petstore/README.md +18 -17
  75. package/examples/petstore/{type.ts → api.ts} +158 -74
  76. package/examples/petstore/authenticated-usage.ts +6 -4
  77. package/examples/petstore/basic-usage.ts +4 -3
  78. package/examples/petstore/error-handling-usage.ts +84 -0
  79. package/examples/petstore/retry-handler-usage.ts +11 -18
  80. package/examples/petstore/server-variables-usage.ts +10 -10
  81. package/examples/pokeapi/README.md +8 -8
  82. package/examples/pokeapi/api.ts +218 -0
  83. package/examples/pokeapi/basic-usage.ts +3 -2
  84. package/examples/pokeapi/custom-client.ts +5 -4
  85. package/package.json +17 -21
  86. package/src/cli.ts +20 -25
  87. package/src/generator.ts +13 -11
  88. package/src/interfaces/code-generator.ts +1 -1
  89. package/src/services/code-generator.service.ts +799 -1120
  90. package/src/services/file-reader.service.ts +6 -5
  91. package/src/services/file-writer.service.ts +7 -7
  92. package/src/services/import-builder.service.ts +9 -13
  93. package/src/services/type-builder.service.ts +8 -19
  94. package/src/types/generator-options.ts +1 -1
  95. package/src/types/openapi.ts +22 -22
  96. package/src/utils/error-handler.ts +2 -2
  97. package/src/utils/naming-convention.ts +13 -10
  98. package/src/utils/reporter.ts +2 -2
  99. package/src/utils/signal-handler.ts +7 -8
  100. package/tests/integration/cli-comprehensive.test.ts +38 -32
  101. package/tests/integration/cli.test.ts +5 -5
  102. package/tests/integration/error-scenarios.test.ts +20 -26
  103. package/tests/integration/snapshots.test.ts +19 -23
  104. package/tests/unit/code-generator-edge-cases.test.ts +133 -133
  105. package/tests/unit/code-generator.test.ts +431 -330
  106. package/tests/unit/file-reader.test.ts +14 -14
  107. package/tests/unit/generator.test.ts +30 -18
  108. package/tests/unit/naming-convention.test.ts +27 -27
  109. package/tests/unit/type-builder.test.ts +2 -2
  110. package/tsconfig.json +5 -3
  111. package/vitest.config.ts +11 -21
  112. package/dist/scripts/update-manifest.d.ts +0 -14
  113. package/dist/scripts/update-manifest.d.ts.map +0 -1
  114. package/dist/scripts/update-manifest.js +0 -33
  115. package/dist/src/assets/manifest.json +0 -5
  116. package/examples/pokeapi/type.ts +0 -109
  117. package/generated/type.ts +0 -371
  118. package/scripts/update-manifest.ts +0 -49
  119. 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 {MethodSchemaType, OpenApiSpecType, ReferenceType} from '../types/openapi';
6
- import type {GeneratorOptions} from '../types/generator-options';
7
- import {MethodSchema, Reference, SchemaProperties} from '../types/openapi';
8
- import {TypeScriptImportBuilderService} from './import-builder.service';
9
- import {TypeScriptTypeBuilderService} from './type-builder.service';
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('generated.ts', '', ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
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) return schemaRegistered;
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.createQualifiedName(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('ZodType')),
120
- [ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedName), undefined)],
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
- ts.factory.createVariableDeclaration(
128
- ts.factory.createIdentifier(sanitizedName),
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) continue;
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
- [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
352
- ts.factory.createIdentifier(name),
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
- members,
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
- ts.factory.createIdentifier('options'),
427
- ts.factory.createIdentifier('serverIndex'),
428
- ),
429
- ts.factory.createPropertyAccessExpression(
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
- ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Response'), undefined),
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
- ts.factory.createThis(),
563
- ts.factory.createPrivateIdentifier('#baseUrl'),
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
- undefined,
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
- undefined,
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
- ts.factory.createIdentifier('baseUrl'),
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
- ts.factory.createIdentifier('String'),
722
- undefined,
723
- [ts.factory.createIdentifier('value')],
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
- ts.factory.createPropertyAssignment(
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
- ts.factory.createIdentifier('URLSearchParams'),
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
- undefined,
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
- ts.factory.createIdentifier('String'),
1017
- undefined,
1018
- [ts.factory.createIdentifier('value')],
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
- ts.factory.createPropertyAccessExpression(
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
- ts.factory.createIdentifier('method'),
1097
- undefined,
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
- ts.factory.createIdentifier('response'),
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
- ts.factory.createIdentifier('response'),
1170
- ts.factory.createIdentifier('statusText'),
1171
- ),
1172
- ts.factory.createTemplateTail('', ''),
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
- method: string,
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 validateCall = ts.factory.createCallExpression(
1375
- ts.factory.createPropertyAccessExpression(responseSchema, ts.factory.createIdentifier('parse')),
1376
- undefined,
1377
- [ts.factory.createAwaitExpression(makeRequestCall)],
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
- statements.push(ts.factory.createReturnStatement(validateCall));
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
- ts.factory.createVariableDeclaration(
1815
- ts.factory.createIdentifier('defaultBaseUrl'),
1816
- undefined,
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
- | Record<string, {default: string; enum?: string[] | undefined; description?: string | undefined}>
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
- ts.factory.createVariableDeclaration(
1949
- configs,
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
- ts.factory.createVariableDeclaration(
1992
- config,
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
- ts.factory.createVariableDeclaration(
2007
- url,
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.createPropertyAccessExpression(url, ts.factory.createIdentifier('replace')),
2056
- undefined,
2057
- [
2058
- ts.factory.createNewExpression(ts.factory.createIdentifier('RegExp'), undefined, [
2059
- ts.factory.createBinaryExpression(
2060
- ts.factory.createBinaryExpression(
2061
- ts.factory.createStringLiteral('\\{'),
2062
- ts.factory.createToken(ts.SyntaxKind.PlusToken),
2063
- key,
2064
- ),
2065
- ts.factory.createToken(ts.SyntaxKind.PlusToken),
2066
- ts.factory.createStringLiteral('\\}'),
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
- ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
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
- ts.factory.createPropertyAccessExpression(
2358
- ts.factory.createIdentifier('z'),
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.createPropertyAccessExpression(arraySchema, ts.factory.createIdentifier('min')),
2399
- undefined,
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.createPropertyAccessExpression(arraySchema, ts.factory.createIdentifier('max')),
2406
- undefined,
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.createPropertyAccessExpression(constrainedSchema, ts.factory.createIdentifier('refine')),
2452
- undefined,
2453
- [
2454
- ts.factory.createArrowFunction(
2455
- undefined,
2456
- undefined,
2457
- [ts.factory.createParameterDeclaration(undefined, undefined, 'obj', undefined, undefined, undefined)],
2458
- undefined,
2459
- ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
2460
- ts.factory.createBinaryExpression(
2461
- ts.factory.createPropertyAccessExpression(
2462
- ts.factory.createCallExpression(
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.createPropertyAccessExpression(constrainedSchema, ts.factory.createIdentifier('refine')),
2490
- undefined,
2491
- [
2492
- ts.factory.createArrowFunction(
2493
- undefined,
2494
- undefined,
2495
- [ts.factory.createParameterDeclaration(undefined, undefined, 'obj', undefined, undefined, undefined)],
2496
- undefined,
2497
- ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
2498
- ts.factory.createBinaryExpression(
2499
- ts.factory.createPropertyAccessExpression(
2500
- ts.factory.createCallExpression(
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
- ts.factory.createIdentifier('z'),
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
- ts.factory.createIdentifier('z'),
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.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('min')),
2764
- undefined,
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.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('max')),
2771
- undefined,
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.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('regex')),
2778
- undefined,
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
- ts.factory.createPropertyAccessExpression(stringSchema, ts.factory.createIdentifier('default')),
2792
- undefined,
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
- typeof prop['default'] === 'boolean'
2812
- ? prop['default']
2813
- ? ts.factory.createTrue()
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
- ts.factory.createPropertyAssignment(ts.factory.createIdentifier(key), this.buildDefaultValue(val)),
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.createPropertyAccessExpression(
2898
- ts.factory.createIdentifier('z'),
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
- ts.factory.createIdentifier('z'),
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.createPropertyAccessExpression(notSchema, ts.factory.createIdentifier('safeParse')),
2945
- undefined,
2946
- [ts.factory.createIdentifier('val')],
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
- ts.factory.createIdentifier('message'),
2953
- ts.factory.createStringLiteral('Value must not match the excluded schema'),
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.createPropertyAccessExpression(
3063
- ts.factory.createIdentifier('z'),
3064
- ts.factory.createIdentifier('lazy'),
3065
- ),
3066
- undefined,
3067
- [
3068
- ts.factory.createArrowFunction(
3069
- undefined,
3070
- undefined,
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 = jp
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 = jp
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]) {