zod-codegen 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## <small>1.2.2 (2025-11-19)</small>
|
|
2
|
+
|
|
3
|
+
- Merge pull request #35 from julienandreu/fix/generate-typescript-type-aliases ([b8d9250](https://github.com/julienandreu/zod-codegen/commit/b8d9250)), closes [#35](https://github.com/julienandreu/zod-codegen/issues/35)
|
|
4
|
+
- fix: generate TypeScript type aliases alongside Zod schemas ([7032a69](https://github.com/julienandreu/zod-codegen/commit/7032a69))
|
|
5
|
+
|
|
1
6
|
## <small>1.2.1 (2025-11-19)</small>
|
|
2
7
|
|
|
3
8
|
- Merge pull request #33 from julienandreu/fix/add-z-infer-to-response-types ([a14d81c](https://github.com/julienandreu/zod-codegen/commit/a14d81c)), closes [#33](https://github.com/julienandreu/zod-codegen/issues/33)
|
|
@@ -40,6 +40,7 @@ export class TypeScriptCodeGeneratorService {
|
|
|
40
40
|
buildAST(openapi) {
|
|
41
41
|
const imports = this.importBuilder.buildImports();
|
|
42
42
|
const schemas = this.buildSchemas(openapi);
|
|
43
|
+
const schemaTypeAliases = this.buildSchemaTypeAliases(schemas);
|
|
43
44
|
const serverConfig = this.buildServerConfiguration(openapi);
|
|
44
45
|
const clientClass = this.buildClientClass(openapi, schemas);
|
|
45
46
|
return [
|
|
@@ -47,6 +48,7 @@ export class TypeScriptCodeGeneratorService {
|
|
|
47
48
|
...imports,
|
|
48
49
|
this.createComment('Components schemas'),
|
|
49
50
|
...Object.values(schemas),
|
|
51
|
+
...schemaTypeAliases,
|
|
50
52
|
...serverConfig,
|
|
51
53
|
this.createComment('Client class'),
|
|
52
54
|
clientClass,
|
|
@@ -68,6 +70,12 @@ export class TypeScriptCodeGeneratorService {
|
|
|
68
70
|
};
|
|
69
71
|
}, {});
|
|
70
72
|
}
|
|
73
|
+
buildSchemaTypeAliases(schemas) {
|
|
74
|
+
return Object.keys(schemas).map((name) => {
|
|
75
|
+
const sanitizedName = this.typeBuilder.sanitizeIdentifier(name);
|
|
76
|
+
return ts.factory.createTypeAliasDeclaration([ts.factory.createToken(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(sanitizedName), undefined, ts.factory.createTypeReferenceNode(ts.factory.createQualifiedName(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('infer')), [ts.factory.createTypeQueryNode(ts.factory.createIdentifier(sanitizedName), undefined)]));
|
|
77
|
+
});
|
|
78
|
+
}
|
|
71
79
|
buildClientClass(openapi, schemas) {
|
|
72
80
|
const clientName = this.generateClientName(openapi.info.title);
|
|
73
81
|
const methods = this.buildClientMethods(openapi, schemas);
|
|
@@ -516,36 +524,34 @@ export class TypeScriptCodeGeneratorService {
|
|
|
516
524
|
}
|
|
517
525
|
const responseSchema = response.content['application/json'].schema;
|
|
518
526
|
const typeName = this.getSchemaTypeName(responseSchema, schemas);
|
|
519
|
-
const inferredType = this.wrapTypeWithZInfer(typeName, schemas);
|
|
520
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [inferredType]);
|
|
521
|
-
}
|
|
522
|
-
wrapTypeWithZInfer(typeName, schemas) {
|
|
523
|
-
// Primitive types and Record types don't need z.infer
|
|
524
|
-
const primitiveTypes = ['string', 'number', 'boolean', 'unknown'];
|
|
525
|
-
if (primitiveTypes.includes(typeName) || typeName.startsWith('Record<')) {
|
|
526
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined);
|
|
527
|
-
}
|
|
528
527
|
// Handle array types like "Pet[]"
|
|
529
528
|
if (typeName.endsWith('[]')) {
|
|
530
529
|
const itemTypeName = typeName.slice(0, -2);
|
|
531
530
|
const sanitizedItemTypeName = this.typeBuilder.sanitizeIdentifier(itemTypeName);
|
|
532
|
-
// Check if the item type is a custom schema
|
|
531
|
+
// Check if the item type is a custom schema (we have a type alias for it)
|
|
533
532
|
if (schemas[sanitizedItemTypeName]) {
|
|
534
|
-
//
|
|
535
|
-
|
|
536
|
-
|
|
533
|
+
// Use the type alias directly (it already uses z.infer)
|
|
534
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
535
|
+
ts.factory.createArrayTypeNode(ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedItemTypeName), undefined)),
|
|
536
|
+
]);
|
|
537
537
|
}
|
|
538
|
-
// If it's a primitive array,
|
|
539
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(
|
|
538
|
+
// If it's a primitive array, use the type name as-is
|
|
539
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
540
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined),
|
|
541
|
+
]);
|
|
540
542
|
}
|
|
541
|
-
// Handle custom schema types
|
|
542
543
|
const sanitizedTypeName = this.typeBuilder.sanitizeIdentifier(typeName);
|
|
544
|
+
// Check if it's a custom schema type (we have a type alias for it)
|
|
543
545
|
if (schemas[sanitizedTypeName]) {
|
|
544
|
-
//
|
|
545
|
-
return ts.factory.createTypeReferenceNode(ts.factory.
|
|
546
|
+
// Use the type name directly (we have a type alias that already uses z.infer)
|
|
547
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
548
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedTypeName), undefined),
|
|
549
|
+
]);
|
|
546
550
|
}
|
|
547
|
-
//
|
|
548
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(
|
|
551
|
+
// For primitive types and Record types, use the type name directly
|
|
552
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
553
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined),
|
|
554
|
+
]);
|
|
549
555
|
}
|
|
550
556
|
buildServerConfiguration(openapi) {
|
|
551
557
|
const servers = openapi.servers;
|
package/package.json
CHANGED
|
@@ -53,6 +53,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
53
53
|
private buildAST(openapi: OpenApiSpecType): ts.Statement[] {
|
|
54
54
|
const imports = this.importBuilder.buildImports();
|
|
55
55
|
const schemas = this.buildSchemas(openapi);
|
|
56
|
+
const schemaTypeAliases = this.buildSchemaTypeAliases(schemas);
|
|
56
57
|
const serverConfig = this.buildServerConfiguration(openapi);
|
|
57
58
|
const clientClass = this.buildClientClass(openapi, schemas);
|
|
58
59
|
|
|
@@ -61,6 +62,7 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
61
62
|
...imports,
|
|
62
63
|
this.createComment('Components schemas'),
|
|
63
64
|
...Object.values(schemas),
|
|
65
|
+
...schemaTypeAliases,
|
|
64
66
|
...serverConfig,
|
|
65
67
|
this.createComment('Client class'),
|
|
66
68
|
clientClass,
|
|
@@ -97,6 +99,21 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
97
99
|
}, {});
|
|
98
100
|
}
|
|
99
101
|
|
|
102
|
+
private buildSchemaTypeAliases(schemas: Record<string, ts.VariableStatement>): ts.TypeAliasDeclaration[] {
|
|
103
|
+
return Object.keys(schemas).map((name) => {
|
|
104
|
+
const sanitizedName = this.typeBuilder.sanitizeIdentifier(name);
|
|
105
|
+
return ts.factory.createTypeAliasDeclaration(
|
|
106
|
+
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
|
107
|
+
ts.factory.createIdentifier(sanitizedName),
|
|
108
|
+
undefined,
|
|
109
|
+
ts.factory.createTypeReferenceNode(
|
|
110
|
+
ts.factory.createQualifiedName(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('infer')),
|
|
111
|
+
[ts.factory.createTypeQueryNode(ts.factory.createIdentifier(sanitizedName), undefined)],
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
100
117
|
private buildClientClass(
|
|
101
118
|
openapi: OpenApiSpecType,
|
|
102
119
|
schemas: Record<string, ts.VariableStatement>,
|
|
@@ -1264,48 +1281,41 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1264
1281
|
|
|
1265
1282
|
const responseSchema = response.content['application/json'].schema;
|
|
1266
1283
|
const typeName = this.getSchemaTypeName(responseSchema, schemas);
|
|
1267
|
-
const inferredType = this.wrapTypeWithZInfer(typeName, schemas);
|
|
1268
|
-
|
|
1269
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [inferredType]);
|
|
1270
|
-
}
|
|
1271
|
-
|
|
1272
|
-
private wrapTypeWithZInfer(typeName: string, schemas: Record<string, ts.VariableStatement>): ts.TypeNode {
|
|
1273
|
-
// Primitive types and Record types don't need z.infer
|
|
1274
|
-
const primitiveTypes = ['string', 'number', 'boolean', 'unknown'];
|
|
1275
|
-
if (primitiveTypes.includes(typeName) || typeName.startsWith('Record<')) {
|
|
1276
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined);
|
|
1277
|
-
}
|
|
1278
1284
|
|
|
1279
1285
|
// Handle array types like "Pet[]"
|
|
1280
1286
|
if (typeName.endsWith('[]')) {
|
|
1281
1287
|
const itemTypeName = typeName.slice(0, -2);
|
|
1282
1288
|
const sanitizedItemTypeName = this.typeBuilder.sanitizeIdentifier(itemTypeName);
|
|
1283
1289
|
|
|
1284
|
-
// Check if the item type is a custom schema
|
|
1290
|
+
// Check if the item type is a custom schema (we have a type alias for it)
|
|
1285
1291
|
if (schemas[sanitizedItemTypeName]) {
|
|
1286
|
-
//
|
|
1287
|
-
|
|
1288
|
-
ts.factory.
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
+
// Use the type alias directly (it already uses z.infer)
|
|
1293
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1294
|
+
ts.factory.createArrayTypeNode(
|
|
1295
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedItemTypeName), undefined),
|
|
1296
|
+
),
|
|
1297
|
+
]);
|
|
1292
1298
|
}
|
|
1293
|
-
// If it's a primitive array,
|
|
1294
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(
|
|
1299
|
+
// If it's a primitive array, use the type name as-is
|
|
1300
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1301
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined),
|
|
1302
|
+
]);
|
|
1295
1303
|
}
|
|
1296
1304
|
|
|
1297
|
-
// Handle custom schema types
|
|
1298
1305
|
const sanitizedTypeName = this.typeBuilder.sanitizeIdentifier(typeName);
|
|
1306
|
+
|
|
1307
|
+
// Check if it's a custom schema type (we have a type alias for it)
|
|
1299
1308
|
if (schemas[sanitizedTypeName]) {
|
|
1300
|
-
//
|
|
1301
|
-
return ts.factory.createTypeReferenceNode(
|
|
1302
|
-
ts.factory.
|
|
1303
|
-
|
|
1304
|
-
);
|
|
1309
|
+
// Use the type name directly (we have a type alias that already uses z.infer)
|
|
1310
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1311
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(sanitizedTypeName), undefined),
|
|
1312
|
+
]);
|
|
1305
1313
|
}
|
|
1306
1314
|
|
|
1307
|
-
//
|
|
1308
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(
|
|
1315
|
+
// For primitive types and Record types, use the type name directly
|
|
1316
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1317
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined),
|
|
1318
|
+
]);
|
|
1309
1319
|
}
|
|
1310
1320
|
|
|
1311
1321
|
private buildServerConfiguration(openapi: OpenApiSpecType): ts.Statement[] {
|