@cerios/openapi-to-zod 0.5.3 → 0.6.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/README.md +7 -16
- package/dist/cli.js +56 -325
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +56 -325
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +1 -77
- package/dist/index.d.ts +1 -77
- package/dist/index.js +51 -312
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +51 -312
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -100,34 +100,11 @@ function resolveRef(ref) {
|
|
|
100
100
|
|
|
101
101
|
// src/generators/enum-generator.ts
|
|
102
102
|
function generateEnum(name, values, options) {
|
|
103
|
-
const enumName = name.endsWith("EnumOptions") ? name.replace("EnumOptions", "Enum") : `${name}Enum`;
|
|
104
103
|
const schemaName = `${toCamelCase(name, options)}Schema`;
|
|
105
|
-
if (options.enumType === "typescript") {
|
|
106
|
-
const usedKeys = /* @__PURE__ */ new Set();
|
|
107
|
-
const enumEntries = values.map((value) => {
|
|
108
|
-
let key = toPascalCase(value);
|
|
109
|
-
if (usedKeys.has(key)) {
|
|
110
|
-
let counter = 2;
|
|
111
|
-
while (usedKeys.has(`${key}${counter}`)) {
|
|
112
|
-
counter++;
|
|
113
|
-
}
|
|
114
|
-
key = `${key}${counter}`;
|
|
115
|
-
}
|
|
116
|
-
usedKeys.add(key);
|
|
117
|
-
const stringValue = typeof value === "string" ? `"${value}"` : value;
|
|
118
|
-
return ` ${key} = ${stringValue},`;
|
|
119
|
-
}).join("\n");
|
|
120
|
-
const enumCode = `export enum ${enumName} {
|
|
121
|
-
${enumEntries}
|
|
122
|
-
}`;
|
|
123
|
-
const schemaCode2 = `export const ${schemaName} = z.nativeEnum(${enumName});`;
|
|
124
|
-
const typeCode2 = `export type ${name} = z.infer<typeof ${schemaName}>;`;
|
|
125
|
-
return { enumCode, schemaCode: schemaCode2, typeCode: typeCode2 };
|
|
126
|
-
}
|
|
127
104
|
const enumValues = values.map((v) => `"${v}"`).join(", ");
|
|
128
105
|
const schemaCode = `export const ${schemaName} = z.enum([${enumValues}]);`;
|
|
129
106
|
const typeCode = `export type ${name} = z.infer<typeof ${schemaName}>;`;
|
|
130
|
-
return {
|
|
107
|
+
return { schemaCode, typeCode };
|
|
131
108
|
}
|
|
132
109
|
|
|
133
110
|
// src/utils/string-utils.ts
|
|
@@ -1391,12 +1368,9 @@ var OpenApiGenerator = class {
|
|
|
1391
1368
|
constructor(options) {
|
|
1392
1369
|
this.schemas = /* @__PURE__ */ new Map();
|
|
1393
1370
|
this.types = /* @__PURE__ */ new Map();
|
|
1394
|
-
this.enums = /* @__PURE__ */ new Map();
|
|
1395
|
-
this.nativeEnums = /* @__PURE__ */ new Map();
|
|
1396
1371
|
this.schemaDependencies = /* @__PURE__ */ new Map();
|
|
1397
1372
|
this.schemaUsageMap = /* @__PURE__ */ new Map();
|
|
1398
|
-
this.
|
|
1399
|
-
this.needsZodImport = false;
|
|
1373
|
+
this.needsZodImport = true;
|
|
1400
1374
|
this.filterStats = createFilterStatistics();
|
|
1401
1375
|
var _a, _b, _c;
|
|
1402
1376
|
if (!options.input) {
|
|
@@ -1407,13 +1381,11 @@ var OpenApiGenerator = class {
|
|
|
1407
1381
|
input: options.input,
|
|
1408
1382
|
output: options.output,
|
|
1409
1383
|
includeDescriptions: (_a = options.includeDescriptions) != null ? _a : true,
|
|
1410
|
-
enumType: options.enumType || "zod",
|
|
1411
1384
|
useDescribe: (_b = options.useDescribe) != null ? _b : false,
|
|
1412
1385
|
schemaType: options.schemaType || "all",
|
|
1413
1386
|
prefix: options.prefix,
|
|
1414
1387
|
suffix: options.suffix,
|
|
1415
1388
|
showStats: (_c = options.showStats) != null ? _c : true,
|
|
1416
|
-
nativeEnumType: options.nativeEnumType || "union",
|
|
1417
1389
|
request: options.request,
|
|
1418
1390
|
response: options.response,
|
|
1419
1391
|
operationFilters: options.operationFilters
|
|
@@ -1473,7 +1445,6 @@ var OpenApiGenerator = class {
|
|
|
1473
1445
|
this.requestOptions = this.resolveOptionsForContext("request");
|
|
1474
1446
|
this.responseOptions = this.resolveOptionsForContext("response");
|
|
1475
1447
|
this.analyzeSchemaUsage();
|
|
1476
|
-
this.determineSchemaTypeModes();
|
|
1477
1448
|
this.propertyGenerator = new PropertyGenerator({
|
|
1478
1449
|
spec: this.spec,
|
|
1479
1450
|
schemaDependencies: this.schemaDependencies,
|
|
@@ -1481,8 +1452,6 @@ var OpenApiGenerator = class {
|
|
|
1481
1452
|
mode: this.requestOptions.mode,
|
|
1482
1453
|
includeDescriptions: this.requestOptions.includeDescriptions,
|
|
1483
1454
|
useDescribe: this.requestOptions.useDescribe,
|
|
1484
|
-
typeMode: this.requestOptions.typeMode,
|
|
1485
|
-
nativeEnumType: this.requestOptions.nativeEnumType,
|
|
1486
1455
|
namingOptions: {
|
|
1487
1456
|
prefix: this.options.prefix,
|
|
1488
1457
|
suffix: this.options.suffix
|
|
@@ -1498,25 +1467,6 @@ var OpenApiGenerator = class {
|
|
|
1498
1467
|
if (!((_a = this.spec.components) == null ? void 0 : _a.schemas)) {
|
|
1499
1468
|
throw new SpecValidationError("No schemas found in OpenAPI spec", { filePath: this.options.input });
|
|
1500
1469
|
}
|
|
1501
|
-
for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
|
|
1502
|
-
if (schema.enum) {
|
|
1503
|
-
const context = this.schemaUsageMap.get(name);
|
|
1504
|
-
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
1505
|
-
if (resolvedOptions.enumType === "typescript") {
|
|
1506
|
-
this.generateNativeEnum(name, schema);
|
|
1507
|
-
} else {
|
|
1508
|
-
const { enumCode } = generateEnum(name, schema.enum, {
|
|
1509
|
-
enumType: "zod",
|
|
1510
|
-
prefix: this.options.prefix,
|
|
1511
|
-
suffix: this.options.suffix
|
|
1512
|
-
});
|
|
1513
|
-
if (enumCode) {
|
|
1514
|
-
this.enums.set(name, enumCode);
|
|
1515
|
-
this.needsZodImport = true;
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
1470
|
for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
|
|
1521
1471
|
this.generateComponentSchema(name, schema);
|
|
1522
1472
|
}
|
|
@@ -1533,22 +1483,11 @@ var OpenApiGenerator = class {
|
|
|
1533
1483
|
output.push('import { z } from "zod";');
|
|
1534
1484
|
output.push("");
|
|
1535
1485
|
}
|
|
1536
|
-
if (this.nativeEnums.size > 0) {
|
|
1537
|
-
output.push("// Native Enums");
|
|
1538
|
-
for (const enumCode of this.nativeEnums.values()) {
|
|
1539
|
-
output.push(enumCode);
|
|
1540
|
-
output.push("");
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1543
1486
|
output.push("// Schemas and Types");
|
|
1544
1487
|
for (const name of orderedSchemaNames) {
|
|
1545
|
-
const enumCode = this.enums.get(name);
|
|
1546
1488
|
const schemaCode = this.schemas.get(name);
|
|
1547
1489
|
const typeCode = this.types.get(name);
|
|
1548
|
-
if (
|
|
1549
|
-
output.push(enumCode);
|
|
1550
|
-
output.push("");
|
|
1551
|
-
} else if (schemaCode) {
|
|
1490
|
+
if (schemaCode) {
|
|
1552
1491
|
output.push(schemaCode);
|
|
1553
1492
|
if (!schemaCode.includes(`export type ${name}`)) {
|
|
1554
1493
|
const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
|
|
@@ -1590,21 +1529,14 @@ var OpenApiGenerator = class {
|
|
|
1590
1529
|
/**
|
|
1591
1530
|
* Resolve options for a specific context (request or response)
|
|
1592
1531
|
* Nested options silently override root-level options
|
|
1593
|
-
* Response schemas always use 'inferred' mode (Zod schemas)
|
|
1594
1532
|
*/
|
|
1595
1533
|
resolveOptionsForContext(context) {
|
|
1596
|
-
var _a, _b, _c, _d, _e, _f
|
|
1534
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1597
1535
|
const contextOptions = context === "request" ? this.options.request : this.options.response;
|
|
1598
|
-
const nativeEnumType = context === "request" ? (_c = (_b = (_a = this.options.request) == null ? void 0 : _a.nativeEnumType) != null ? _b : this.options.nativeEnumType) != null ? _c : "union" : (_d = this.options.nativeEnumType) != null ? _d : "union";
|
|
1599
1536
|
return {
|
|
1600
|
-
mode: (
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
includeDescriptions: (_l = (_k = contextOptions == null ? void 0 : contextOptions.includeDescriptions) != null ? _k : this.options.includeDescriptions) != null ? _l : true,
|
|
1604
|
-
// Response schemas always use 'inferred' mode (Zod schemas are required)
|
|
1605
|
-
// Request schemas can optionally use 'native' mode
|
|
1606
|
-
typeMode: context === "response" ? "inferred" : (_n = (_m = this.options.request) == null ? void 0 : _m.typeMode) != null ? _n : "inferred",
|
|
1607
|
-
nativeEnumType
|
|
1537
|
+
mode: (_b = (_a = contextOptions == null ? void 0 : contextOptions.mode) != null ? _a : this.options.mode) != null ? _b : "normal",
|
|
1538
|
+
useDescribe: (_d = (_c = contextOptions == null ? void 0 : contextOptions.useDescribe) != null ? _c : this.options.useDescribe) != null ? _d : false,
|
|
1539
|
+
includeDescriptions: (_f = (_e = contextOptions == null ? void 0 : contextOptions.includeDescriptions) != null ? _e : this.options.includeDescriptions) != null ? _f : true
|
|
1608
1540
|
};
|
|
1609
1541
|
}
|
|
1610
1542
|
/**
|
|
@@ -1795,28 +1727,6 @@ var OpenApiGenerator = class {
|
|
|
1795
1727
|
detectCycle(name);
|
|
1796
1728
|
}
|
|
1797
1729
|
}
|
|
1798
|
-
/**
|
|
1799
|
-
* Determine the typeMode for each schema based on its usage context
|
|
1800
|
-
* Response schemas always use 'inferred' mode
|
|
1801
|
-
*/
|
|
1802
|
-
determineSchemaTypeModes() {
|
|
1803
|
-
var _a;
|
|
1804
|
-
for (const [name] of Object.entries(((_a = this.spec.components) == null ? void 0 : _a.schemas) || {})) {
|
|
1805
|
-
const context = this.schemaUsageMap.get(name);
|
|
1806
|
-
if (context === "request") {
|
|
1807
|
-
this.schemaTypeModeMap.set(name, this.requestOptions.typeMode);
|
|
1808
|
-
} else if (context === "response") {
|
|
1809
|
-
this.schemaTypeModeMap.set(name, "inferred");
|
|
1810
|
-
} else if (context === "both") {
|
|
1811
|
-
this.schemaTypeModeMap.set(name, "inferred");
|
|
1812
|
-
} else {
|
|
1813
|
-
this.schemaTypeModeMap.set(name, "inferred");
|
|
1814
|
-
}
|
|
1815
|
-
if (this.schemaTypeModeMap.get(name) === "inferred") {
|
|
1816
|
-
this.needsZodImport = true;
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
1730
|
/**
|
|
1821
1731
|
* Validate the OpenAPI specification
|
|
1822
1732
|
*/
|
|
@@ -1892,80 +1802,54 @@ var OpenApiGenerator = class {
|
|
|
1892
1802
|
if (!this.schemaDependencies.has(name)) {
|
|
1893
1803
|
this.schemaDependencies.set(name, /* @__PURE__ */ new Set());
|
|
1894
1804
|
}
|
|
1895
|
-
const typeMode = this.schemaTypeModeMap.get(name) || "inferred";
|
|
1896
1805
|
const context = this.schemaUsageMap.get(name);
|
|
1897
1806
|
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
1898
1807
|
if (schema.enum) {
|
|
1899
|
-
const
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
});
|
|
1906
|
-
const enumSchemaCode = `${jsdoc}${schemaCode}
|
|
1907
|
-
${typeCode}`;
|
|
1908
|
-
this.schemas.set(name, enumSchemaCode);
|
|
1909
|
-
} else {
|
|
1910
|
-
const { enumCode, schemaCode, typeCode } = generateEnum(name, schema.enum, {
|
|
1911
|
-
enumType: "zod",
|
|
1912
|
-
prefix: this.options.prefix,
|
|
1913
|
-
suffix: this.options.suffix
|
|
1914
|
-
});
|
|
1915
|
-
if (enumCode) {
|
|
1916
|
-
this.enums.set(name, enumCode);
|
|
1917
|
-
}
|
|
1918
|
-
const enumSchemaCode = `${jsdoc}${schemaCode}
|
|
1808
|
+
const jsdoc2 = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
1809
|
+
const { schemaCode, typeCode } = generateEnum(name, schema.enum, {
|
|
1810
|
+
prefix: this.options.prefix,
|
|
1811
|
+
suffix: this.options.suffix
|
|
1812
|
+
});
|
|
1813
|
+
const enumSchemaCode = `${jsdoc2}${schemaCode}
|
|
1919
1814
|
${typeCode}`;
|
|
1920
|
-
|
|
1921
|
-
}
|
|
1815
|
+
this.schemas.set(name, enumSchemaCode);
|
|
1922
1816
|
return;
|
|
1923
1817
|
}
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
const
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1818
|
+
const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
|
|
1819
|
+
const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
1820
|
+
if (schema.allOf && schema.allOf.length === 1 && schema.allOf[0].$ref) {
|
|
1821
|
+
const refName = resolveRef(schema.allOf[0].$ref);
|
|
1822
|
+
(_a = this.schemaDependencies.get(name)) == null ? void 0 : _a.add(refName);
|
|
1823
|
+
}
|
|
1824
|
+
this.propertyGenerator = new PropertyGenerator({
|
|
1825
|
+
spec: this.spec,
|
|
1826
|
+
schemaDependencies: this.schemaDependencies,
|
|
1827
|
+
schemaType: this.options.schemaType || "all",
|
|
1828
|
+
mode: resolvedOptions.mode,
|
|
1829
|
+
includeDescriptions: resolvedOptions.includeDescriptions,
|
|
1830
|
+
useDescribe: resolvedOptions.useDescribe,
|
|
1831
|
+
namingOptions: {
|
|
1832
|
+
prefix: this.options.prefix,
|
|
1833
|
+
suffix: this.options.suffix
|
|
1936
1834
|
}
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
});
|
|
1951
|
-
const isAlias = !!(schema.$ref && !schema.properties && !schema.allOf && !schema.oneOf && !schema.anyOf);
|
|
1952
|
-
const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
|
|
1953
|
-
const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;
|
|
1954
|
-
if (zodSchema.includes("z.discriminatedUnion(")) {
|
|
1955
|
-
const match = zodSchema.match(/z\.discriminatedUnion\([^,]+,\s*\[([^\]]+)\]/);
|
|
1956
|
-
if (match) {
|
|
1957
|
-
const refs = match[1].split(",").map((ref) => ref.trim());
|
|
1958
|
-
for (const ref of refs) {
|
|
1959
|
-
const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
|
|
1960
|
-
if (depMatch) {
|
|
1961
|
-
const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
|
|
1962
|
-
(_b = this.schemaDependencies.get(name)) == null ? void 0 : _b.add(depName);
|
|
1963
|
-
}
|
|
1835
|
+
});
|
|
1836
|
+
const isAlias = !!(schema.$ref && !schema.properties && !schema.allOf && !schema.oneOf && !schema.anyOf);
|
|
1837
|
+
const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
|
|
1838
|
+
const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;
|
|
1839
|
+
if (zodSchema.includes("z.discriminatedUnion(")) {
|
|
1840
|
+
const match = zodSchema.match(/z\.discriminatedUnion\([^,]+,\s*\[([^\]]+)\]/);
|
|
1841
|
+
if (match) {
|
|
1842
|
+
const refs = match[1].split(",").map((ref) => ref.trim());
|
|
1843
|
+
for (const ref of refs) {
|
|
1844
|
+
const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
|
|
1845
|
+
if (depMatch) {
|
|
1846
|
+
const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
|
|
1847
|
+
(_b = this.schemaDependencies.get(name)) == null ? void 0 : _b.add(depName);
|
|
1964
1848
|
}
|
|
1965
1849
|
}
|
|
1966
1850
|
}
|
|
1967
|
-
this.schemas.set(name, zodSchemaCode);
|
|
1968
1851
|
}
|
|
1852
|
+
this.schemas.set(name, zodSchemaCode);
|
|
1969
1853
|
}
|
|
1970
1854
|
/**
|
|
1971
1855
|
* Generate query parameter schemas for each operation
|
|
@@ -2171,151 +2055,11 @@ ${propsCode}
|
|
|
2171
2055
|
}
|
|
2172
2056
|
return "z.unknown()";
|
|
2173
2057
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
const context = this.schemaUsageMap.get(name);
|
|
2180
|
-
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
2181
|
-
const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
2182
|
-
if (resolvedOptions.nativeEnumType === "enum") {
|
|
2183
|
-
const enumName = `${name}Enum`;
|
|
2184
|
-
const members = schema.enum.map((value) => {
|
|
2185
|
-
const key = typeof value === "string" ? this.toEnumKey(value) : `N${value}`;
|
|
2186
|
-
const val = typeof value === "string" ? `"${value}"` : value;
|
|
2187
|
-
return ` ${key} = ${val}`;
|
|
2188
|
-
}).join(",\n");
|
|
2189
|
-
const enumCode = `${jsdoc}export enum ${enumName} {
|
|
2190
|
-
${members}
|
|
2191
|
-
}`;
|
|
2192
|
-
this.nativeEnums.set(name, enumCode);
|
|
2193
|
-
const typeCode = `export type ${name} = ${enumName};`;
|
|
2194
|
-
this.types.set(name, typeCode);
|
|
2195
|
-
} else {
|
|
2196
|
-
const unionType = schema.enum.map((v) => typeof v === "string" ? `"${v}"` : v).join(" | ");
|
|
2197
|
-
const typeCode = `${jsdoc}export type ${name} = ${unionType};`;
|
|
2198
|
-
this.types.set(name, typeCode);
|
|
2199
|
-
}
|
|
2200
|
-
}
|
|
2201
|
-
/**
|
|
2202
|
-
* Convert string to valid enum key
|
|
2203
|
-
*/
|
|
2204
|
-
toEnumKey(value) {
|
|
2205
|
-
const cleaned = value.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2206
|
-
const pascalCase = cleaned.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
|
|
2207
|
-
return pascalCase || "Value";
|
|
2208
|
-
}
|
|
2209
|
-
/**
|
|
2210
|
-
* Add constraint annotations to JSDoc for native types
|
|
2211
|
-
*/
|
|
2212
|
-
addConstraintsToJSDoc(jsdoc, schema, includeDescriptions) {
|
|
2213
|
-
if (!includeDescriptions) return jsdoc;
|
|
2214
|
-
const constraints = [];
|
|
2215
|
-
if (schema.minLength !== void 0) constraints.push(`@minLength ${schema.minLength}`);
|
|
2216
|
-
if (schema.maxLength !== void 0) constraints.push(`@maxLength ${schema.maxLength}`);
|
|
2217
|
-
if (schema.pattern) constraints.push(`@pattern ${schema.pattern}`);
|
|
2218
|
-
if (schema.minimum !== void 0) constraints.push(`@minimum ${schema.minimum}`);
|
|
2219
|
-
if (schema.maximum !== void 0) constraints.push(`@maximum ${schema.maximum}`);
|
|
2220
|
-
if (schema.minItems !== void 0) constraints.push(`@minItems ${schema.minItems}`);
|
|
2221
|
-
if (schema.maxItems !== void 0) constraints.push(`@maxItems ${schema.maxItems}`);
|
|
2222
|
-
if (schema.minProperties !== void 0) constraints.push(`@minProperties ${schema.minProperties}`);
|
|
2223
|
-
if (schema.maxProperties !== void 0) constraints.push(`@maxProperties ${schema.maxProperties}`);
|
|
2224
|
-
if (schema.multipleOf !== void 0) constraints.push(`@multipleOf ${schema.multipleOf}`);
|
|
2225
|
-
if (schema.format) constraints.push(`@format ${schema.format}`);
|
|
2226
|
-
if (constraints.length === 0) return jsdoc;
|
|
2227
|
-
if (jsdoc) {
|
|
2228
|
-
const lines = jsdoc.trim().split("\n");
|
|
2229
|
-
if (lines[0] === "/**" && lines[lines.length - 1] === " */") {
|
|
2230
|
-
const newLines = [...lines.slice(0, -1), ...constraints.map((c) => ` * ${c}`), " */\n"];
|
|
2231
|
-
return newLines.join("\n");
|
|
2232
|
-
}
|
|
2233
|
-
const content = jsdoc.replace("/** ", "").replace(" */\n", "");
|
|
2234
|
-
return `/**
|
|
2235
|
-
* ${content}
|
|
2236
|
-
${constraints.map((c) => ` * ${c}`).join("\n")}
|
|
2237
|
-
*/
|
|
2238
|
-
`;
|
|
2239
|
-
}
|
|
2240
|
-
return `/**
|
|
2241
|
-
${constraints.map((c) => ` * ${c}`).join("\n")}
|
|
2242
|
-
*/
|
|
2243
|
-
`;
|
|
2244
|
-
}
|
|
2245
|
-
/**
|
|
2246
|
-
* Generate native TypeScript type definition from OpenAPI schema
|
|
2247
|
-
*/
|
|
2248
|
-
generateNativeTypeDefinition(schema, _schemaName) {
|
|
2249
|
-
if (schema.$ref) {
|
|
2250
|
-
return resolveRef(schema.$ref);
|
|
2251
|
-
}
|
|
2252
|
-
if (schema.const !== void 0) {
|
|
2253
|
-
return typeof schema.const === "string" ? `"${schema.const}"` : String(schema.const);
|
|
2254
|
-
}
|
|
2255
|
-
const isNullable2 = schema.nullable || Array.isArray(schema.type) && schema.type.includes("null");
|
|
2256
|
-
const wrapNullable2 = (type) => isNullable2 ? `(${type}) | null` : type;
|
|
2257
|
-
const primaryType = Array.isArray(schema.type) ? schema.type.find((t) => t !== "null") : schema.type;
|
|
2258
|
-
switch (primaryType) {
|
|
2259
|
-
case "string":
|
|
2260
|
-
return wrapNullable2("string");
|
|
2261
|
-
case "number":
|
|
2262
|
-
case "integer":
|
|
2263
|
-
return wrapNullable2("number");
|
|
2264
|
-
case "boolean":
|
|
2265
|
-
return wrapNullable2("boolean");
|
|
2266
|
-
case "array":
|
|
2267
|
-
if (schema.items) {
|
|
2268
|
-
const itemType = this.generateNativeTypeDefinition(schema.items);
|
|
2269
|
-
return wrapNullable2(`${itemType}[]`);
|
|
2270
|
-
}
|
|
2271
|
-
return wrapNullable2("unknown[]");
|
|
2272
|
-
case "object":
|
|
2273
|
-
return wrapNullable2(this.generateObjectType(schema));
|
|
2274
|
-
default:
|
|
2275
|
-
if (schema.allOf) {
|
|
2276
|
-
const types = schema.allOf.map((s) => this.generateNativeTypeDefinition(s));
|
|
2277
|
-
return wrapNullable2(types.join(" & "));
|
|
2278
|
-
}
|
|
2279
|
-
if (schema.oneOf || schema.anyOf) {
|
|
2280
|
-
const schemas = schema.oneOf || schema.anyOf || [];
|
|
2281
|
-
const types = schemas.map((s) => this.generateNativeTypeDefinition(s));
|
|
2282
|
-
return wrapNullable2(types.join(" | "));
|
|
2283
|
-
}
|
|
2284
|
-
return wrapNullable2("unknown");
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
/**
|
|
2288
|
-
* Generate TypeScript object type definition
|
|
2289
|
-
*/
|
|
2290
|
-
generateObjectType(schema) {
|
|
2291
|
-
if (!schema.properties || Object.keys(schema.properties).length === 0) {
|
|
2292
|
-
return "Record<string, unknown>";
|
|
2293
|
-
}
|
|
2294
|
-
const context = this.schemaUsageMap.get(schema.$ref ? resolveRef(schema.$ref) : "");
|
|
2295
|
-
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
2296
|
-
const required = new Set(schema.required || []);
|
|
2297
|
-
const props = [];
|
|
2298
|
-
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
2299
|
-
const propType = this.generateNativeTypeDefinition(propSchema);
|
|
2300
|
-
const optional = !required.has(propName) ? "?" : "";
|
|
2301
|
-
let propJsdoc = generateJSDoc(propSchema, propName, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
2302
|
-
if (resolvedOptions.includeDescriptions && !propJsdoc) {
|
|
2303
|
-
propJsdoc = this.addConstraintsToJSDoc("", propSchema, resolvedOptions.includeDescriptions);
|
|
2304
|
-
} else if (propJsdoc && resolvedOptions.includeDescriptions) {
|
|
2305
|
-
propJsdoc = this.addConstraintsToJSDoc(propJsdoc, propSchema, resolvedOptions.includeDescriptions);
|
|
2306
|
-
}
|
|
2307
|
-
if (propJsdoc) {
|
|
2308
|
-
const cleanJsdoc = propJsdoc.trimEnd();
|
|
2309
|
-
props.push(` ${cleanJsdoc}
|
|
2310
|
-
${propName}${optional}: ${propType};`);
|
|
2311
|
-
} else {
|
|
2312
|
-
props.push(` ${propName}${optional}: ${propType};`);
|
|
2313
|
-
}
|
|
2314
|
-
}
|
|
2315
|
-
return `{
|
|
2316
|
-
${props.join("\n")}
|
|
2317
|
-
}`;
|
|
2318
|
-
}
|
|
2058
|
+
// REMOVED: generateNativeEnum method - no longer needed as we only generate Zod schemas
|
|
2059
|
+
// REMOVED: toEnumKey method - was only used by generateNativeEnum
|
|
2060
|
+
// REMOVED: addConstraintsToJSDoc method - was only used for native TypeScript types
|
|
2061
|
+
// REMOVED: generateNativeTypeDefinition method - was only used for native TypeScript types
|
|
2062
|
+
// REMOVED: generateObjectType method - was only used for native TypeScript types
|
|
2319
2063
|
/**
|
|
2320
2064
|
* Topological sort for schema dependencies
|
|
2321
2065
|
* Returns schemas in the order they should be declared
|
|
@@ -2327,9 +2071,6 @@ ${props.join("\n")}
|
|
|
2327
2071
|
const aliases = [];
|
|
2328
2072
|
const circularDeps = /* @__PURE__ */ new Set();
|
|
2329
2073
|
const codeCache = /* @__PURE__ */ new Map();
|
|
2330
|
-
for (const [name, code] of this.enums) {
|
|
2331
|
-
codeCache.set(name, code);
|
|
2332
|
-
}
|
|
2333
2074
|
for (const [name, code] of this.schemas) {
|
|
2334
2075
|
codeCache.set(name, code);
|
|
2335
2076
|
}
|
|
@@ -2354,7 +2095,7 @@ ${props.join("\n")}
|
|
|
2354
2095
|
const deps = this.schemaDependencies.get(name);
|
|
2355
2096
|
if (deps && deps.size > 0) {
|
|
2356
2097
|
for (const dep of deps) {
|
|
2357
|
-
if (this.
|
|
2098
|
+
if (this.schemas.has(dep) || this.types.has(dep)) {
|
|
2358
2099
|
visit(dep);
|
|
2359
2100
|
}
|
|
2360
2101
|
}
|
|
@@ -2365,7 +2106,7 @@ ${props.join("\n")}
|
|
|
2365
2106
|
sorted.push(name);
|
|
2366
2107
|
}
|
|
2367
2108
|
};
|
|
2368
|
-
const allNames = /* @__PURE__ */ new Set([...this.
|
|
2109
|
+
const allNames = /* @__PURE__ */ new Set([...this.schemas.keys(), ...this.types.keys()]);
|
|
2369
2110
|
for (const name of allNames) {
|
|
2370
2111
|
visit(name);
|
|
2371
2112
|
}
|
|
@@ -2383,7 +2124,6 @@ ${props.join("\n")}
|
|
|
2383
2124
|
generateStats() {
|
|
2384
2125
|
const stats = {
|
|
2385
2126
|
totalSchemas: this.schemas.size,
|
|
2386
|
-
enums: this.enums.size,
|
|
2387
2127
|
withCircularRefs: 0,
|
|
2388
2128
|
withDiscriminators: 0,
|
|
2389
2129
|
withConstraints: 0
|
|
@@ -2398,7 +2138,6 @@ ${props.join("\n")}
|
|
|
2398
2138
|
const output = [
|
|
2399
2139
|
"// Generation Statistics:",
|
|
2400
2140
|
`// Total schemas: ${stats.totalSchemas}`,
|
|
2401
|
-
`// Enums: ${stats.enums}`,
|
|
2402
2141
|
`// Circular references: ${stats.withCircularRefs}`,
|
|
2403
2142
|
`// Discriminated unions: ${stats.withDiscriminators}`,
|
|
2404
2143
|
`// With constraints: ${stats.withConstraints}`
|