@cerios/openapi-to-zod 0.1.1 → 0.2.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.
- package/dist/cli.js +194 -38
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +195 -47
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +14 -12
- package/dist/index.d.ts +14 -12
- package/dist/index.js +190 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +191 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -17
package/dist/index.d.mts
CHANGED
|
@@ -243,16 +243,6 @@ interface OpenAPISpec {
|
|
|
243
243
|
* - 'sequential': Process specs one at a time (safer for resource constraints)
|
|
244
244
|
*/
|
|
245
245
|
type ExecutionMode = "parallel" | "sequential";
|
|
246
|
-
/**
|
|
247
|
-
* Configuration for a single OpenAPI spec
|
|
248
|
-
* Extends GeneratorOptions with all the same properties
|
|
249
|
-
*/
|
|
250
|
-
interface SpecConfig extends GeneratorOptions {
|
|
251
|
-
/**
|
|
252
|
-
* Optional name/identifier for this spec (for logging purposes)
|
|
253
|
-
*/
|
|
254
|
-
name?: string;
|
|
255
|
-
}
|
|
256
246
|
/**
|
|
257
247
|
* Root configuration file structure
|
|
258
248
|
*/
|
|
@@ -266,7 +256,7 @@ interface ConfigFile {
|
|
|
266
256
|
* Array of OpenAPI specifications to process
|
|
267
257
|
* Each spec must have input and output paths
|
|
268
258
|
*/
|
|
269
|
-
specs:
|
|
259
|
+
specs: GeneratorOptions[];
|
|
270
260
|
/**
|
|
271
261
|
* Execution mode for batch processing
|
|
272
262
|
* @default "parallel"
|
|
@@ -315,6 +305,10 @@ declare class ZodSchemaGenerator {
|
|
|
315
305
|
* @returns The generated TypeScript code as a string
|
|
316
306
|
*/
|
|
317
307
|
generateString(): string;
|
|
308
|
+
/**
|
|
309
|
+
* Ensure directory exists for a file path
|
|
310
|
+
*/
|
|
311
|
+
private ensureDirectoryExists;
|
|
318
312
|
/**
|
|
319
313
|
* Generate the complete output file
|
|
320
314
|
*/
|
|
@@ -367,6 +361,14 @@ declare class ZodSchemaGenerator {
|
|
|
367
361
|
* Generate schema for a component
|
|
368
362
|
*/
|
|
369
363
|
private generateComponentSchema;
|
|
364
|
+
/**
|
|
365
|
+
* Generate query parameter schemas for each operation
|
|
366
|
+
*/
|
|
367
|
+
private generateQueryParameterSchemas;
|
|
368
|
+
/**
|
|
369
|
+
* Generate Zod type for a query parameter schema
|
|
370
|
+
*/
|
|
371
|
+
private generateQueryParamType;
|
|
370
372
|
/**
|
|
371
373
|
* Generate native TypeScript enum
|
|
372
374
|
*/
|
|
@@ -398,4 +400,4 @@ declare class ZodSchemaGenerator {
|
|
|
398
400
|
private generateStats;
|
|
399
401
|
}
|
|
400
402
|
|
|
401
|
-
export { CircularReferenceError, CliOptionsError, type ConfigFile, ConfigValidationError, type ExecutionMode, FileOperationError, GeneratorError, type GeneratorOptions, type OpenAPISpec, SchemaGenerationError,
|
|
403
|
+
export { CircularReferenceError, CliOptionsError, type ConfigFile, ConfigValidationError, type ExecutionMode, FileOperationError, GeneratorError, type GeneratorOptions, type OpenAPISpec, SchemaGenerationError, SpecValidationError, ZodSchemaGenerator, defineConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -243,16 +243,6 @@ interface OpenAPISpec {
|
|
|
243
243
|
* - 'sequential': Process specs one at a time (safer for resource constraints)
|
|
244
244
|
*/
|
|
245
245
|
type ExecutionMode = "parallel" | "sequential";
|
|
246
|
-
/**
|
|
247
|
-
* Configuration for a single OpenAPI spec
|
|
248
|
-
* Extends GeneratorOptions with all the same properties
|
|
249
|
-
*/
|
|
250
|
-
interface SpecConfig extends GeneratorOptions {
|
|
251
|
-
/**
|
|
252
|
-
* Optional name/identifier for this spec (for logging purposes)
|
|
253
|
-
*/
|
|
254
|
-
name?: string;
|
|
255
|
-
}
|
|
256
246
|
/**
|
|
257
247
|
* Root configuration file structure
|
|
258
248
|
*/
|
|
@@ -266,7 +256,7 @@ interface ConfigFile {
|
|
|
266
256
|
* Array of OpenAPI specifications to process
|
|
267
257
|
* Each spec must have input and output paths
|
|
268
258
|
*/
|
|
269
|
-
specs:
|
|
259
|
+
specs: GeneratorOptions[];
|
|
270
260
|
/**
|
|
271
261
|
* Execution mode for batch processing
|
|
272
262
|
* @default "parallel"
|
|
@@ -315,6 +305,10 @@ declare class ZodSchemaGenerator {
|
|
|
315
305
|
* @returns The generated TypeScript code as a string
|
|
316
306
|
*/
|
|
317
307
|
generateString(): string;
|
|
308
|
+
/**
|
|
309
|
+
* Ensure directory exists for a file path
|
|
310
|
+
*/
|
|
311
|
+
private ensureDirectoryExists;
|
|
318
312
|
/**
|
|
319
313
|
* Generate the complete output file
|
|
320
314
|
*/
|
|
@@ -367,6 +361,14 @@ declare class ZodSchemaGenerator {
|
|
|
367
361
|
* Generate schema for a component
|
|
368
362
|
*/
|
|
369
363
|
private generateComponentSchema;
|
|
364
|
+
/**
|
|
365
|
+
* Generate query parameter schemas for each operation
|
|
366
|
+
*/
|
|
367
|
+
private generateQueryParameterSchemas;
|
|
368
|
+
/**
|
|
369
|
+
* Generate Zod type for a query parameter schema
|
|
370
|
+
*/
|
|
371
|
+
private generateQueryParamType;
|
|
370
372
|
/**
|
|
371
373
|
* Generate native TypeScript enum
|
|
372
374
|
*/
|
|
@@ -398,4 +400,4 @@ declare class ZodSchemaGenerator {
|
|
|
398
400
|
private generateStats;
|
|
399
401
|
}
|
|
400
402
|
|
|
401
|
-
export { CircularReferenceError, CliOptionsError, type ConfigFile, ConfigValidationError, type ExecutionMode, FileOperationError, GeneratorError, type GeneratorOptions, type OpenAPISpec, SchemaGenerationError,
|
|
403
|
+
export { CircularReferenceError, CliOptionsError, type ConfigFile, ConfigValidationError, type ExecutionMode, FileOperationError, GeneratorError, type GeneratorOptions, type OpenAPISpec, SchemaGenerationError, SpecValidationError, ZodSchemaGenerator, defineConfig };
|
package/dist/index.js
CHANGED
|
@@ -93,6 +93,7 @@ var ConfigurationError = class extends GeneratorError {
|
|
|
93
93
|
|
|
94
94
|
// src/generator.ts
|
|
95
95
|
var import_node_fs = require("fs");
|
|
96
|
+
var import_node_path = require("path");
|
|
96
97
|
var import_yaml = require("yaml");
|
|
97
98
|
|
|
98
99
|
// src/utils/name-utils.ts
|
|
@@ -146,7 +147,7 @@ function generateEnum(name, values, options) {
|
|
|
146
147
|
const enumCode = `export enum ${enumName} {
|
|
147
148
|
${enumEntries}
|
|
148
149
|
}`;
|
|
149
|
-
const schemaCode2 = `export const ${schemaName} = z.
|
|
150
|
+
const schemaCode2 = `export const ${schemaName} = z.nativeEnum(${enumName});`;
|
|
150
151
|
const typeCode2 = `export type ${name} = z.infer<typeof ${schemaName}>;`;
|
|
151
152
|
return { enumCode, schemaCode: schemaCode2, typeCode: typeCode2 };
|
|
152
153
|
}
|
|
@@ -329,20 +330,20 @@ function generateArrayValidation(schema, context) {
|
|
|
329
330
|
}
|
|
330
331
|
|
|
331
332
|
// src/validators/composition-validator.ts
|
|
332
|
-
function generateUnion(schemas, discriminator, isNullable2, context, options) {
|
|
333
|
+
function generateUnion(schemas, discriminator, isNullable2, context, options, currentSchema) {
|
|
333
334
|
if (discriminator) {
|
|
334
335
|
let resolvedSchemas = schemas;
|
|
335
336
|
if ((options == null ? void 0 : options.discriminatorMapping) && context.resolveDiscriminatorMapping) {
|
|
336
337
|
resolvedSchemas = context.resolveDiscriminatorMapping(options.discriminatorMapping, schemas);
|
|
337
338
|
}
|
|
338
|
-
let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s));
|
|
339
|
+
let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema));
|
|
339
340
|
if (options == null ? void 0 : options.passthrough) {
|
|
340
341
|
schemaStrings2 = schemaStrings2.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
|
|
341
342
|
}
|
|
342
343
|
const union2 = `z.discriminatedUnion("${discriminator}", [${schemaStrings2.join(", ")}])`;
|
|
343
344
|
return wrapNullable(union2, isNullable2);
|
|
344
345
|
}
|
|
345
|
-
let schemaStrings = schemas.map((s) => context.generatePropertySchema(s));
|
|
346
|
+
let schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema));
|
|
346
347
|
if (options == null ? void 0 : options.passthrough) {
|
|
347
348
|
schemaStrings = schemaStrings.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
|
|
348
349
|
}
|
|
@@ -1175,7 +1176,8 @@ var _PropertyGenerator = class _PropertyGenerator {
|
|
|
1175
1176
|
{
|
|
1176
1177
|
passthrough: needsPassthrough,
|
|
1177
1178
|
discriminatorMapping: (_c = schema.discriminator) == null ? void 0 : _c.mapping
|
|
1178
|
-
}
|
|
1179
|
+
},
|
|
1180
|
+
currentSchema
|
|
1179
1181
|
);
|
|
1180
1182
|
if (schema.unevaluatedProperties !== void 0) {
|
|
1181
1183
|
composition = this.applyUnevaluatedProperties(composition, schema);
|
|
@@ -1195,7 +1197,8 @@ var _PropertyGenerator = class _PropertyGenerator {
|
|
|
1195
1197
|
{
|
|
1196
1198
|
passthrough: needsPassthrough,
|
|
1197
1199
|
discriminatorMapping: (_e = schema.discriminator) == null ? void 0 : _e.mapping
|
|
1198
|
-
}
|
|
1200
|
+
},
|
|
1201
|
+
currentSchema
|
|
1199
1202
|
);
|
|
1200
1203
|
if (schema.unevaluatedProperties !== void 0) {
|
|
1201
1204
|
composition = this.applyUnevaluatedProperties(composition, schema);
|
|
@@ -1366,10 +1369,13 @@ var ZodSchemaGenerator = class {
|
|
|
1366
1369
|
}
|
|
1367
1370
|
for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
|
|
1368
1371
|
if (schema.enum) {
|
|
1369
|
-
const
|
|
1370
|
-
|
|
1372
|
+
const context = this.schemaUsageMap.get(name);
|
|
1373
|
+
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
1374
|
+
if (resolvedOptions.enumType === "typescript") {
|
|
1375
|
+
this.generateNativeEnum(name, schema);
|
|
1376
|
+
} else {
|
|
1371
1377
|
const { enumCode } = generateEnum(name, schema.enum, {
|
|
1372
|
-
enumType:
|
|
1378
|
+
enumType: "zod",
|
|
1373
1379
|
prefix: this.options.prefix,
|
|
1374
1380
|
suffix: this.options.suffix
|
|
1375
1381
|
});
|
|
@@ -1377,14 +1383,13 @@ var ZodSchemaGenerator = class {
|
|
|
1377
1383
|
this.enums.set(name, enumCode);
|
|
1378
1384
|
this.needsZodImport = true;
|
|
1379
1385
|
}
|
|
1380
|
-
} else {
|
|
1381
|
-
this.generateNativeEnum(name, schema);
|
|
1382
1386
|
}
|
|
1383
1387
|
}
|
|
1384
1388
|
}
|
|
1385
1389
|
for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
|
|
1386
1390
|
this.generateComponentSchema(name, schema);
|
|
1387
1391
|
}
|
|
1392
|
+
this.generateQueryParameterSchemas();
|
|
1388
1393
|
const orderedSchemaNames = this.topologicalSort();
|
|
1389
1394
|
const output = ["// Auto-generated by @cerios/openapi-to-zod", "// Do not edit this file manually", ""];
|
|
1390
1395
|
if (this.options.showStats === true) {
|
|
@@ -1395,12 +1400,8 @@ var ZodSchemaGenerator = class {
|
|
|
1395
1400
|
output.push('import { z } from "zod";');
|
|
1396
1401
|
output.push("");
|
|
1397
1402
|
}
|
|
1398
|
-
if (this.
|
|
1399
|
-
output.push("// Enums");
|
|
1400
|
-
for (const enumCode of this.enums.values()) {
|
|
1401
|
-
output.push(enumCode);
|
|
1402
|
-
output.push("");
|
|
1403
|
-
}
|
|
1403
|
+
if (this.nativeEnums.size > 0) {
|
|
1404
|
+
output.push("// Native Enums");
|
|
1404
1405
|
for (const enumCode of this.nativeEnums.values()) {
|
|
1405
1406
|
output.push(enumCode);
|
|
1406
1407
|
output.push("");
|
|
@@ -1408,9 +1409,13 @@ var ZodSchemaGenerator = class {
|
|
|
1408
1409
|
}
|
|
1409
1410
|
output.push("// Schemas and Types");
|
|
1410
1411
|
for (const name of orderedSchemaNames) {
|
|
1412
|
+
const enumCode = this.enums.get(name);
|
|
1411
1413
|
const schemaCode = this.schemas.get(name);
|
|
1412
1414
|
const typeCode = this.types.get(name);
|
|
1413
|
-
if (
|
|
1415
|
+
if (enumCode) {
|
|
1416
|
+
output.push(enumCode);
|
|
1417
|
+
output.push("");
|
|
1418
|
+
} else if (schemaCode) {
|
|
1414
1419
|
output.push(schemaCode);
|
|
1415
1420
|
if (!schemaCode.includes(`export type ${name}`)) {
|
|
1416
1421
|
const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
|
|
@@ -1424,6 +1429,15 @@ var ZodSchemaGenerator = class {
|
|
|
1424
1429
|
}
|
|
1425
1430
|
return output.join("\n");
|
|
1426
1431
|
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Ensure directory exists for a file path
|
|
1434
|
+
*/
|
|
1435
|
+
ensureDirectoryExists(filePath) {
|
|
1436
|
+
const dir = (0, import_node_path.dirname)(filePath);
|
|
1437
|
+
if (!(0, import_node_fs.existsSync)(dir)) {
|
|
1438
|
+
(0, import_node_fs.mkdirSync)(dir, { recursive: true });
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1427
1441
|
/**
|
|
1428
1442
|
* Generate the complete output file
|
|
1429
1443
|
*/
|
|
@@ -1435,6 +1449,7 @@ var ZodSchemaGenerator = class {
|
|
|
1435
1449
|
);
|
|
1436
1450
|
}
|
|
1437
1451
|
const output = this.generateString();
|
|
1452
|
+
this.ensureDirectoryExists(this.options.output);
|
|
1438
1453
|
(0, import_node_fs.writeFileSync)(this.options.output, output);
|
|
1439
1454
|
}
|
|
1440
1455
|
/**
|
|
@@ -1738,10 +1753,19 @@ var ZodSchemaGenerator = class {
|
|
|
1738
1753
|
const context = this.schemaUsageMap.get(name);
|
|
1739
1754
|
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
1740
1755
|
if (schema.enum) {
|
|
1741
|
-
|
|
1742
|
-
|
|
1756
|
+
const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
1757
|
+
if (resolvedOptions.enumType === "typescript") {
|
|
1758
|
+
const { schemaCode, typeCode } = generateEnum(name, schema.enum, {
|
|
1759
|
+
enumType: "typescript",
|
|
1760
|
+
prefix: this.options.prefix,
|
|
1761
|
+
suffix: this.options.suffix
|
|
1762
|
+
});
|
|
1763
|
+
const enumSchemaCode = `${jsdoc}${schemaCode}
|
|
1764
|
+
${typeCode}`;
|
|
1765
|
+
this.schemas.set(name, enumSchemaCode);
|
|
1766
|
+
} else {
|
|
1743
1767
|
const { enumCode, schemaCode, typeCode } = generateEnum(name, schema.enum, {
|
|
1744
|
-
enumType:
|
|
1768
|
+
enumType: "zod",
|
|
1745
1769
|
prefix: this.options.prefix,
|
|
1746
1770
|
suffix: this.options.suffix
|
|
1747
1771
|
});
|
|
@@ -1800,6 +1824,133 @@ ${typeCode}`;
|
|
|
1800
1824
|
this.schemas.set(name, zodSchemaCode);
|
|
1801
1825
|
}
|
|
1802
1826
|
}
|
|
1827
|
+
/**
|
|
1828
|
+
* Generate query parameter schemas for each operation
|
|
1829
|
+
*/
|
|
1830
|
+
generateQueryParameterSchemas() {
|
|
1831
|
+
var _a;
|
|
1832
|
+
if (!this.spec.paths) {
|
|
1833
|
+
return;
|
|
1834
|
+
}
|
|
1835
|
+
for (const [_path, pathItem] of Object.entries(this.spec.paths)) {
|
|
1836
|
+
if (!pathItem || typeof pathItem !== "object") continue;
|
|
1837
|
+
const methods = ["get", "post", "put", "patch", "delete", "head", "options"];
|
|
1838
|
+
for (const method of methods) {
|
|
1839
|
+
const operation = pathItem[method];
|
|
1840
|
+
if (!operation) continue;
|
|
1841
|
+
if (!operation.operationId || !operation.parameters || !Array.isArray(operation.parameters)) {
|
|
1842
|
+
continue;
|
|
1843
|
+
}
|
|
1844
|
+
const queryParams = operation.parameters.filter(
|
|
1845
|
+
(param) => param && typeof param === "object" && param.in === "query"
|
|
1846
|
+
);
|
|
1847
|
+
if (queryParams.length === 0) {
|
|
1848
|
+
continue;
|
|
1849
|
+
}
|
|
1850
|
+
const pascalOperationId = operation.operationId.includes("-") ? toPascalCase(operation.operationId) : operation.operationId.charAt(0).toUpperCase() + operation.operationId.slice(1);
|
|
1851
|
+
const schemaName = `${pascalOperationId}QueryParams`;
|
|
1852
|
+
if (!this.schemaDependencies.has(schemaName)) {
|
|
1853
|
+
this.schemaDependencies.set(schemaName, /* @__PURE__ */ new Set());
|
|
1854
|
+
}
|
|
1855
|
+
const properties = {};
|
|
1856
|
+
const required = [];
|
|
1857
|
+
for (const param of queryParams) {
|
|
1858
|
+
const paramName = param.name;
|
|
1859
|
+
const isRequired = param.required === true;
|
|
1860
|
+
const paramSchema = param.schema;
|
|
1861
|
+
if (!paramSchema) continue;
|
|
1862
|
+
let zodType = this.generateQueryParamType(paramSchema, param);
|
|
1863
|
+
if (paramSchema.type === "array" && paramSchema.items) {
|
|
1864
|
+
const itemType = this.generateQueryParamType(paramSchema.items, param);
|
|
1865
|
+
zodType = `z.array(${itemType})`;
|
|
1866
|
+
}
|
|
1867
|
+
if (param.description && this.requestOptions.includeDescriptions) {
|
|
1868
|
+
if (this.requestOptions.useDescribe) {
|
|
1869
|
+
zodType = `${zodType}.describe(${JSON.stringify(param.description)})`;
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
if (!isRequired) {
|
|
1873
|
+
zodType = `${zodType}.optional()`;
|
|
1874
|
+
}
|
|
1875
|
+
properties[paramName] = zodType;
|
|
1876
|
+
if (isRequired) {
|
|
1877
|
+
required.push(paramName);
|
|
1878
|
+
}
|
|
1879
|
+
if (paramSchema.$ref) {
|
|
1880
|
+
const refName = resolveRef(paramSchema.$ref);
|
|
1881
|
+
(_a = this.schemaDependencies.get(schemaName)) == null ? void 0 : _a.add(refName);
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
const objectMode = this.requestOptions.mode;
|
|
1885
|
+
const zodMethod = objectMode === "strict" ? "strictObject" : objectMode === "loose" ? "looseObject" : "object";
|
|
1886
|
+
const propsCode = Object.entries(properties).map(([key, value]) => {
|
|
1887
|
+
const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key);
|
|
1888
|
+
const quotedKey = needsQuotes ? `"${key}"` : key;
|
|
1889
|
+
return ` ${quotedKey}: ${value}`;
|
|
1890
|
+
}).join(",\n");
|
|
1891
|
+
const schemaCode = `z.${zodMethod}({
|
|
1892
|
+
${propsCode}
|
|
1893
|
+
})`;
|
|
1894
|
+
const operationName = pascalOperationId;
|
|
1895
|
+
const prefixedName = this.options.prefix ? `${toPascalCase(this.options.prefix)}${operationName}` : operationName;
|
|
1896
|
+
const suffixedName = this.options.suffix ? `${prefixedName}${toPascalCase(this.options.suffix)}` : prefixedName;
|
|
1897
|
+
const camelCaseSchemaName = `${suffixedName.charAt(0).toLowerCase() + suffixedName.slice(1)}QueryParamsSchema`;
|
|
1898
|
+
const jsdoc = `/**
|
|
1899
|
+
* Query parameters for ${operation.operationId}
|
|
1900
|
+
*/
|
|
1901
|
+
`;
|
|
1902
|
+
const fullSchemaCode = `${jsdoc}export const ${camelCaseSchemaName} = ${schemaCode};`;
|
|
1903
|
+
this.schemas.set(schemaName, fullSchemaCode);
|
|
1904
|
+
this.needsZodImport = true;
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
/**
|
|
1909
|
+
* Generate Zod type for a query parameter schema
|
|
1910
|
+
*/
|
|
1911
|
+
generateQueryParamType(schema, param) {
|
|
1912
|
+
if (schema.$ref) {
|
|
1913
|
+
const refName = resolveRef(schema.$ref);
|
|
1914
|
+
const schemaName = toCamelCase(refName, { prefix: this.options.prefix, suffix: this.options.suffix });
|
|
1915
|
+
return `${schemaName}Schema`;
|
|
1916
|
+
}
|
|
1917
|
+
if (schema.enum) {
|
|
1918
|
+
const enumValues = schema.enum.map((v) => typeof v === "string" ? `"${v}"` : v).join(", ");
|
|
1919
|
+
return `z.enum([${enumValues}])`;
|
|
1920
|
+
}
|
|
1921
|
+
const type = schema.type;
|
|
1922
|
+
if (type === "string") {
|
|
1923
|
+
let zodType = "z.string()";
|
|
1924
|
+
if (schema.minLength !== void 0) zodType = `${zodType}.min(${schema.minLength})`;
|
|
1925
|
+
if (schema.maxLength !== void 0) zodType = `${zodType}.max(${schema.maxLength})`;
|
|
1926
|
+
if (schema.pattern) zodType = `${zodType}.regex(/${schema.pattern}/)`;
|
|
1927
|
+
if (schema.format === "email") zodType = `${zodType}.email()`;
|
|
1928
|
+
if (schema.format === "uri" || schema.format === "url") zodType = `${zodType}.url()`;
|
|
1929
|
+
if (schema.format === "uuid") zodType = `${zodType}.uuid()`;
|
|
1930
|
+
return zodType;
|
|
1931
|
+
}
|
|
1932
|
+
if (type === "number" || type === "integer") {
|
|
1933
|
+
let zodType = type === "integer" ? "z.number().int()" : "z.number()";
|
|
1934
|
+
if (schema.minimum !== void 0) {
|
|
1935
|
+
zodType = schema.exclusiveMinimum ? `${zodType}.gt(${schema.minimum})` : `${zodType}.gte(${schema.minimum})`;
|
|
1936
|
+
}
|
|
1937
|
+
if (schema.maximum !== void 0) {
|
|
1938
|
+
zodType = schema.exclusiveMaximum ? `${zodType}.lt(${schema.maximum})` : `${zodType}.lte(${schema.maximum})`;
|
|
1939
|
+
}
|
|
1940
|
+
return zodType;
|
|
1941
|
+
}
|
|
1942
|
+
if (type === "boolean") {
|
|
1943
|
+
return "z.boolean()";
|
|
1944
|
+
}
|
|
1945
|
+
if (type === "array" && schema.items) {
|
|
1946
|
+
const itemType = this.generateQueryParamType(schema.items, param);
|
|
1947
|
+
let arrayType = `z.array(${itemType})`;
|
|
1948
|
+
if (schema.minItems !== void 0) arrayType = `${arrayType}.min(${schema.minItems})`;
|
|
1949
|
+
if (schema.maxItems !== void 0) arrayType = `${arrayType}.max(${schema.maxItems})`;
|
|
1950
|
+
return arrayType;
|
|
1951
|
+
}
|
|
1952
|
+
return "z.unknown()";
|
|
1953
|
+
}
|
|
1803
1954
|
/**
|
|
1804
1955
|
* Generate native TypeScript enum
|
|
1805
1956
|
*/
|
|
@@ -1810,8 +1961,8 @@ ${typeCode}`;
|
|
|
1810
1961
|
const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
1811
1962
|
if (resolvedOptions.nativeEnumType === "enum") {
|
|
1812
1963
|
const enumName = `${name}Enum`;
|
|
1813
|
-
const members = schema.enum.map((value
|
|
1814
|
-
const key = typeof value === "string" ? this.toEnumKey(value) : `
|
|
1964
|
+
const members = schema.enum.map((value) => {
|
|
1965
|
+
const key = typeof value === "string" ? this.toEnumKey(value) : `N${value}`;
|
|
1815
1966
|
const val = typeof value === "string" ? `"${value}"` : value;
|
|
1816
1967
|
return ` ${key} = ${val}`;
|
|
1817
1968
|
}).join(",\n");
|
|
@@ -1954,7 +2105,11 @@ ${props.join("\n")}
|
|
|
1954
2105
|
const visited = /* @__PURE__ */ new Set();
|
|
1955
2106
|
const visiting = /* @__PURE__ */ new Set();
|
|
1956
2107
|
const aliases = [];
|
|
2108
|
+
const circularDeps = /* @__PURE__ */ new Set();
|
|
1957
2109
|
const codeCache = /* @__PURE__ */ new Map();
|
|
2110
|
+
for (const [name, code] of this.enums) {
|
|
2111
|
+
codeCache.set(name, code);
|
|
2112
|
+
}
|
|
1958
2113
|
for (const [name, code] of this.schemas) {
|
|
1959
2114
|
codeCache.set(name, code);
|
|
1960
2115
|
}
|
|
@@ -1964,6 +2119,7 @@ ${props.join("\n")}
|
|
|
1964
2119
|
const visit = (name) => {
|
|
1965
2120
|
if (visited.has(name)) return;
|
|
1966
2121
|
if (visiting.has(name)) {
|
|
2122
|
+
circularDeps.add(name);
|
|
1967
2123
|
return;
|
|
1968
2124
|
}
|
|
1969
2125
|
visiting.add(name);
|
|
@@ -1978,19 +2134,27 @@ ${props.join("\n")}
|
|
|
1978
2134
|
const deps = this.schemaDependencies.get(name);
|
|
1979
2135
|
if (deps && deps.size > 0) {
|
|
1980
2136
|
for (const dep of deps) {
|
|
1981
|
-
if (this.schemas.has(dep) || this.types.has(dep)) {
|
|
2137
|
+
if (this.enums.has(dep) || this.schemas.has(dep) || this.types.has(dep)) {
|
|
1982
2138
|
visit(dep);
|
|
1983
2139
|
}
|
|
1984
2140
|
}
|
|
1985
2141
|
}
|
|
1986
2142
|
visiting.delete(name);
|
|
1987
2143
|
visited.add(name);
|
|
1988
|
-
|
|
2144
|
+
if (!circularDeps.has(name)) {
|
|
2145
|
+
sorted.push(name);
|
|
2146
|
+
}
|
|
1989
2147
|
};
|
|
1990
|
-
const allNames = /* @__PURE__ */ new Set([...this.schemas.keys(), ...this.types.keys()]);
|
|
2148
|
+
const allNames = /* @__PURE__ */ new Set([...this.enums.keys(), ...this.schemas.keys(), ...this.types.keys()]);
|
|
1991
2149
|
for (const name of allNames) {
|
|
1992
2150
|
visit(name);
|
|
1993
2151
|
}
|
|
2152
|
+
for (const name of circularDeps) {
|
|
2153
|
+
if (!visited.has(name)) {
|
|
2154
|
+
sorted.push(name);
|
|
2155
|
+
visited.add(name);
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
1994
2158
|
return [...sorted, ...aliases];
|
|
1995
2159
|
}
|
|
1996
2160
|
/**
|