@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.js
CHANGED
|
@@ -131,34 +131,11 @@ function resolveRef(ref) {
|
|
|
131
131
|
|
|
132
132
|
// src/generators/enum-generator.ts
|
|
133
133
|
function generateEnum(name, values, options) {
|
|
134
|
-
const enumName = name.endsWith("EnumOptions") ? name.replace("EnumOptions", "Enum") : `${name}Enum`;
|
|
135
134
|
const schemaName = `${toCamelCase(name, options)}Schema`;
|
|
136
|
-
if (options.enumType === "typescript") {
|
|
137
|
-
const usedKeys = /* @__PURE__ */ new Set();
|
|
138
|
-
const enumEntries = values.map((value) => {
|
|
139
|
-
let key = toPascalCase(value);
|
|
140
|
-
if (usedKeys.has(key)) {
|
|
141
|
-
let counter = 2;
|
|
142
|
-
while (usedKeys.has(`${key}${counter}`)) {
|
|
143
|
-
counter++;
|
|
144
|
-
}
|
|
145
|
-
key = `${key}${counter}`;
|
|
146
|
-
}
|
|
147
|
-
usedKeys.add(key);
|
|
148
|
-
const stringValue = typeof value === "string" ? `"${value}"` : value;
|
|
149
|
-
return ` ${key} = ${stringValue},`;
|
|
150
|
-
}).join("\n");
|
|
151
|
-
const enumCode = `export enum ${enumName} {
|
|
152
|
-
${enumEntries}
|
|
153
|
-
}`;
|
|
154
|
-
const schemaCode2 = `export const ${schemaName} = z.nativeEnum(${enumName});`;
|
|
155
|
-
const typeCode2 = `export type ${name} = z.infer<typeof ${schemaName}>;`;
|
|
156
|
-
return { enumCode, schemaCode: schemaCode2, typeCode: typeCode2 };
|
|
157
|
-
}
|
|
158
135
|
const enumValues = values.map((v) => `"${v}"`).join(", ");
|
|
159
136
|
const schemaCode = `export const ${schemaName} = z.enum([${enumValues}]);`;
|
|
160
137
|
const typeCode = `export type ${name} = z.infer<typeof ${schemaName}>;`;
|
|
161
|
-
return {
|
|
138
|
+
return { schemaCode, typeCode };
|
|
162
139
|
}
|
|
163
140
|
|
|
164
141
|
// src/utils/string-utils.ts
|
|
@@ -1422,12 +1399,9 @@ var OpenApiGenerator = class {
|
|
|
1422
1399
|
constructor(options) {
|
|
1423
1400
|
this.schemas = /* @__PURE__ */ new Map();
|
|
1424
1401
|
this.types = /* @__PURE__ */ new Map();
|
|
1425
|
-
this.enums = /* @__PURE__ */ new Map();
|
|
1426
|
-
this.nativeEnums = /* @__PURE__ */ new Map();
|
|
1427
1402
|
this.schemaDependencies = /* @__PURE__ */ new Map();
|
|
1428
1403
|
this.schemaUsageMap = /* @__PURE__ */ new Map();
|
|
1429
|
-
this.
|
|
1430
|
-
this.needsZodImport = false;
|
|
1404
|
+
this.needsZodImport = true;
|
|
1431
1405
|
this.filterStats = createFilterStatistics();
|
|
1432
1406
|
var _a, _b, _c;
|
|
1433
1407
|
if (!options.input) {
|
|
@@ -1438,13 +1412,11 @@ var OpenApiGenerator = class {
|
|
|
1438
1412
|
input: options.input,
|
|
1439
1413
|
output: options.output,
|
|
1440
1414
|
includeDescriptions: (_a = options.includeDescriptions) != null ? _a : true,
|
|
1441
|
-
enumType: options.enumType || "zod",
|
|
1442
1415
|
useDescribe: (_b = options.useDescribe) != null ? _b : false,
|
|
1443
1416
|
schemaType: options.schemaType || "all",
|
|
1444
1417
|
prefix: options.prefix,
|
|
1445
1418
|
suffix: options.suffix,
|
|
1446
1419
|
showStats: (_c = options.showStats) != null ? _c : true,
|
|
1447
|
-
nativeEnumType: options.nativeEnumType || "union",
|
|
1448
1420
|
request: options.request,
|
|
1449
1421
|
response: options.response,
|
|
1450
1422
|
operationFilters: options.operationFilters
|
|
@@ -1504,7 +1476,6 @@ var OpenApiGenerator = class {
|
|
|
1504
1476
|
this.requestOptions = this.resolveOptionsForContext("request");
|
|
1505
1477
|
this.responseOptions = this.resolveOptionsForContext("response");
|
|
1506
1478
|
this.analyzeSchemaUsage();
|
|
1507
|
-
this.determineSchemaTypeModes();
|
|
1508
1479
|
this.propertyGenerator = new PropertyGenerator({
|
|
1509
1480
|
spec: this.spec,
|
|
1510
1481
|
schemaDependencies: this.schemaDependencies,
|
|
@@ -1512,8 +1483,6 @@ var OpenApiGenerator = class {
|
|
|
1512
1483
|
mode: this.requestOptions.mode,
|
|
1513
1484
|
includeDescriptions: this.requestOptions.includeDescriptions,
|
|
1514
1485
|
useDescribe: this.requestOptions.useDescribe,
|
|
1515
|
-
typeMode: this.requestOptions.typeMode,
|
|
1516
|
-
nativeEnumType: this.requestOptions.nativeEnumType,
|
|
1517
1486
|
namingOptions: {
|
|
1518
1487
|
prefix: this.options.prefix,
|
|
1519
1488
|
suffix: this.options.suffix
|
|
@@ -1529,25 +1498,6 @@ var OpenApiGenerator = class {
|
|
|
1529
1498
|
if (!((_a = this.spec.components) == null ? void 0 : _a.schemas)) {
|
|
1530
1499
|
throw new SpecValidationError("No schemas found in OpenAPI spec", { filePath: this.options.input });
|
|
1531
1500
|
}
|
|
1532
|
-
for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
|
|
1533
|
-
if (schema.enum) {
|
|
1534
|
-
const context = this.schemaUsageMap.get(name);
|
|
1535
|
-
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
1536
|
-
if (resolvedOptions.enumType === "typescript") {
|
|
1537
|
-
this.generateNativeEnum(name, schema);
|
|
1538
|
-
} else {
|
|
1539
|
-
const { enumCode } = generateEnum(name, schema.enum, {
|
|
1540
|
-
enumType: "zod",
|
|
1541
|
-
prefix: this.options.prefix,
|
|
1542
|
-
suffix: this.options.suffix
|
|
1543
|
-
});
|
|
1544
|
-
if (enumCode) {
|
|
1545
|
-
this.enums.set(name, enumCode);
|
|
1546
|
-
this.needsZodImport = true;
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
1501
|
for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
|
|
1552
1502
|
this.generateComponentSchema(name, schema);
|
|
1553
1503
|
}
|
|
@@ -1564,22 +1514,11 @@ var OpenApiGenerator = class {
|
|
|
1564
1514
|
output.push('import { z } from "zod";');
|
|
1565
1515
|
output.push("");
|
|
1566
1516
|
}
|
|
1567
|
-
if (this.nativeEnums.size > 0) {
|
|
1568
|
-
output.push("// Native Enums");
|
|
1569
|
-
for (const enumCode of this.nativeEnums.values()) {
|
|
1570
|
-
output.push(enumCode);
|
|
1571
|
-
output.push("");
|
|
1572
|
-
}
|
|
1573
|
-
}
|
|
1574
1517
|
output.push("// Schemas and Types");
|
|
1575
1518
|
for (const name of orderedSchemaNames) {
|
|
1576
|
-
const enumCode = this.enums.get(name);
|
|
1577
1519
|
const schemaCode = this.schemas.get(name);
|
|
1578
1520
|
const typeCode = this.types.get(name);
|
|
1579
|
-
if (
|
|
1580
|
-
output.push(enumCode);
|
|
1581
|
-
output.push("");
|
|
1582
|
-
} else if (schemaCode) {
|
|
1521
|
+
if (schemaCode) {
|
|
1583
1522
|
output.push(schemaCode);
|
|
1584
1523
|
if (!schemaCode.includes(`export type ${name}`)) {
|
|
1585
1524
|
const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
|
|
@@ -1621,21 +1560,14 @@ var OpenApiGenerator = class {
|
|
|
1621
1560
|
/**
|
|
1622
1561
|
* Resolve options for a specific context (request or response)
|
|
1623
1562
|
* Nested options silently override root-level options
|
|
1624
|
-
* Response schemas always use 'inferred' mode (Zod schemas)
|
|
1625
1563
|
*/
|
|
1626
1564
|
resolveOptionsForContext(context) {
|
|
1627
|
-
var _a, _b, _c, _d, _e, _f
|
|
1565
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1628
1566
|
const contextOptions = context === "request" ? this.options.request : this.options.response;
|
|
1629
|
-
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";
|
|
1630
1567
|
return {
|
|
1631
|
-
mode: (
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
includeDescriptions: (_l = (_k = contextOptions == null ? void 0 : contextOptions.includeDescriptions) != null ? _k : this.options.includeDescriptions) != null ? _l : true,
|
|
1635
|
-
// Response schemas always use 'inferred' mode (Zod schemas are required)
|
|
1636
|
-
// Request schemas can optionally use 'native' mode
|
|
1637
|
-
typeMode: context === "response" ? "inferred" : (_n = (_m = this.options.request) == null ? void 0 : _m.typeMode) != null ? _n : "inferred",
|
|
1638
|
-
nativeEnumType
|
|
1568
|
+
mode: (_b = (_a = contextOptions == null ? void 0 : contextOptions.mode) != null ? _a : this.options.mode) != null ? _b : "normal",
|
|
1569
|
+
useDescribe: (_d = (_c = contextOptions == null ? void 0 : contextOptions.useDescribe) != null ? _c : this.options.useDescribe) != null ? _d : false,
|
|
1570
|
+
includeDescriptions: (_f = (_e = contextOptions == null ? void 0 : contextOptions.includeDescriptions) != null ? _e : this.options.includeDescriptions) != null ? _f : true
|
|
1639
1571
|
};
|
|
1640
1572
|
}
|
|
1641
1573
|
/**
|
|
@@ -1826,28 +1758,6 @@ var OpenApiGenerator = class {
|
|
|
1826
1758
|
detectCycle(name);
|
|
1827
1759
|
}
|
|
1828
1760
|
}
|
|
1829
|
-
/**
|
|
1830
|
-
* Determine the typeMode for each schema based on its usage context
|
|
1831
|
-
* Response schemas always use 'inferred' mode
|
|
1832
|
-
*/
|
|
1833
|
-
determineSchemaTypeModes() {
|
|
1834
|
-
var _a;
|
|
1835
|
-
for (const [name] of Object.entries(((_a = this.spec.components) == null ? void 0 : _a.schemas) || {})) {
|
|
1836
|
-
const context = this.schemaUsageMap.get(name);
|
|
1837
|
-
if (context === "request") {
|
|
1838
|
-
this.schemaTypeModeMap.set(name, this.requestOptions.typeMode);
|
|
1839
|
-
} else if (context === "response") {
|
|
1840
|
-
this.schemaTypeModeMap.set(name, "inferred");
|
|
1841
|
-
} else if (context === "both") {
|
|
1842
|
-
this.schemaTypeModeMap.set(name, "inferred");
|
|
1843
|
-
} else {
|
|
1844
|
-
this.schemaTypeModeMap.set(name, "inferred");
|
|
1845
|
-
}
|
|
1846
|
-
if (this.schemaTypeModeMap.get(name) === "inferred") {
|
|
1847
|
-
this.needsZodImport = true;
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
1761
|
/**
|
|
1852
1762
|
* Validate the OpenAPI specification
|
|
1853
1763
|
*/
|
|
@@ -1923,80 +1833,54 @@ var OpenApiGenerator = class {
|
|
|
1923
1833
|
if (!this.schemaDependencies.has(name)) {
|
|
1924
1834
|
this.schemaDependencies.set(name, /* @__PURE__ */ new Set());
|
|
1925
1835
|
}
|
|
1926
|
-
const typeMode = this.schemaTypeModeMap.get(name) || "inferred";
|
|
1927
1836
|
const context = this.schemaUsageMap.get(name);
|
|
1928
1837
|
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
1929
1838
|
if (schema.enum) {
|
|
1930
|
-
const
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
});
|
|
1937
|
-
const enumSchemaCode = `${jsdoc}${schemaCode}
|
|
1938
|
-
${typeCode}`;
|
|
1939
|
-
this.schemas.set(name, enumSchemaCode);
|
|
1940
|
-
} else {
|
|
1941
|
-
const { enumCode, schemaCode, typeCode } = generateEnum(name, schema.enum, {
|
|
1942
|
-
enumType: "zod",
|
|
1943
|
-
prefix: this.options.prefix,
|
|
1944
|
-
suffix: this.options.suffix
|
|
1945
|
-
});
|
|
1946
|
-
if (enumCode) {
|
|
1947
|
-
this.enums.set(name, enumCode);
|
|
1948
|
-
}
|
|
1949
|
-
const enumSchemaCode = `${jsdoc}${schemaCode}
|
|
1839
|
+
const jsdoc2 = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
1840
|
+
const { schemaCode, typeCode } = generateEnum(name, schema.enum, {
|
|
1841
|
+
prefix: this.options.prefix,
|
|
1842
|
+
suffix: this.options.suffix
|
|
1843
|
+
});
|
|
1844
|
+
const enumSchemaCode = `${jsdoc2}${schemaCode}
|
|
1950
1845
|
${typeCode}`;
|
|
1951
|
-
|
|
1952
|
-
}
|
|
1846
|
+
this.schemas.set(name, enumSchemaCode);
|
|
1953
1847
|
return;
|
|
1954
1848
|
}
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
const
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1849
|
+
const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
|
|
1850
|
+
const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
1851
|
+
if (schema.allOf && schema.allOf.length === 1 && schema.allOf[0].$ref) {
|
|
1852
|
+
const refName = resolveRef(schema.allOf[0].$ref);
|
|
1853
|
+
(_a = this.schemaDependencies.get(name)) == null ? void 0 : _a.add(refName);
|
|
1854
|
+
}
|
|
1855
|
+
this.propertyGenerator = new PropertyGenerator({
|
|
1856
|
+
spec: this.spec,
|
|
1857
|
+
schemaDependencies: this.schemaDependencies,
|
|
1858
|
+
schemaType: this.options.schemaType || "all",
|
|
1859
|
+
mode: resolvedOptions.mode,
|
|
1860
|
+
includeDescriptions: resolvedOptions.includeDescriptions,
|
|
1861
|
+
useDescribe: resolvedOptions.useDescribe,
|
|
1862
|
+
namingOptions: {
|
|
1863
|
+
prefix: this.options.prefix,
|
|
1864
|
+
suffix: this.options.suffix
|
|
1967
1865
|
}
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
});
|
|
1982
|
-
const isAlias = !!(schema.$ref && !schema.properties && !schema.allOf && !schema.oneOf && !schema.anyOf);
|
|
1983
|
-
const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
|
|
1984
|
-
const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;
|
|
1985
|
-
if (zodSchema.includes("z.discriminatedUnion(")) {
|
|
1986
|
-
const match = zodSchema.match(/z\.discriminatedUnion\([^,]+,\s*\[([^\]]+)\]/);
|
|
1987
|
-
if (match) {
|
|
1988
|
-
const refs = match[1].split(",").map((ref) => ref.trim());
|
|
1989
|
-
for (const ref of refs) {
|
|
1990
|
-
const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
|
|
1991
|
-
if (depMatch) {
|
|
1992
|
-
const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
|
|
1993
|
-
(_b = this.schemaDependencies.get(name)) == null ? void 0 : _b.add(depName);
|
|
1994
|
-
}
|
|
1866
|
+
});
|
|
1867
|
+
const isAlias = !!(schema.$ref && !schema.properties && !schema.allOf && !schema.oneOf && !schema.anyOf);
|
|
1868
|
+
const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
|
|
1869
|
+
const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;
|
|
1870
|
+
if (zodSchema.includes("z.discriminatedUnion(")) {
|
|
1871
|
+
const match = zodSchema.match(/z\.discriminatedUnion\([^,]+,\s*\[([^\]]+)\]/);
|
|
1872
|
+
if (match) {
|
|
1873
|
+
const refs = match[1].split(",").map((ref) => ref.trim());
|
|
1874
|
+
for (const ref of refs) {
|
|
1875
|
+
const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
|
|
1876
|
+
if (depMatch) {
|
|
1877
|
+
const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
|
|
1878
|
+
(_b = this.schemaDependencies.get(name)) == null ? void 0 : _b.add(depName);
|
|
1995
1879
|
}
|
|
1996
1880
|
}
|
|
1997
1881
|
}
|
|
1998
|
-
this.schemas.set(name, zodSchemaCode);
|
|
1999
1882
|
}
|
|
1883
|
+
this.schemas.set(name, zodSchemaCode);
|
|
2000
1884
|
}
|
|
2001
1885
|
/**
|
|
2002
1886
|
* Generate query parameter schemas for each operation
|
|
@@ -2202,151 +2086,11 @@ ${propsCode}
|
|
|
2202
2086
|
}
|
|
2203
2087
|
return "z.unknown()";
|
|
2204
2088
|
}
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
const context = this.schemaUsageMap.get(name);
|
|
2211
|
-
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
2212
|
-
const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
2213
|
-
if (resolvedOptions.nativeEnumType === "enum") {
|
|
2214
|
-
const enumName = `${name}Enum`;
|
|
2215
|
-
const members = schema.enum.map((value) => {
|
|
2216
|
-
const key = typeof value === "string" ? this.toEnumKey(value) : `N${value}`;
|
|
2217
|
-
const val = typeof value === "string" ? `"${value}"` : value;
|
|
2218
|
-
return ` ${key} = ${val}`;
|
|
2219
|
-
}).join(",\n");
|
|
2220
|
-
const enumCode = `${jsdoc}export enum ${enumName} {
|
|
2221
|
-
${members}
|
|
2222
|
-
}`;
|
|
2223
|
-
this.nativeEnums.set(name, enumCode);
|
|
2224
|
-
const typeCode = `export type ${name} = ${enumName};`;
|
|
2225
|
-
this.types.set(name, typeCode);
|
|
2226
|
-
} else {
|
|
2227
|
-
const unionType = schema.enum.map((v) => typeof v === "string" ? `"${v}"` : v).join(" | ");
|
|
2228
|
-
const typeCode = `${jsdoc}export type ${name} = ${unionType};`;
|
|
2229
|
-
this.types.set(name, typeCode);
|
|
2230
|
-
}
|
|
2231
|
-
}
|
|
2232
|
-
/**
|
|
2233
|
-
* Convert string to valid enum key
|
|
2234
|
-
*/
|
|
2235
|
-
toEnumKey(value) {
|
|
2236
|
-
const cleaned = value.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2237
|
-
const pascalCase = cleaned.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
|
|
2238
|
-
return pascalCase || "Value";
|
|
2239
|
-
}
|
|
2240
|
-
/**
|
|
2241
|
-
* Add constraint annotations to JSDoc for native types
|
|
2242
|
-
*/
|
|
2243
|
-
addConstraintsToJSDoc(jsdoc, schema, includeDescriptions) {
|
|
2244
|
-
if (!includeDescriptions) return jsdoc;
|
|
2245
|
-
const constraints = [];
|
|
2246
|
-
if (schema.minLength !== void 0) constraints.push(`@minLength ${schema.minLength}`);
|
|
2247
|
-
if (schema.maxLength !== void 0) constraints.push(`@maxLength ${schema.maxLength}`);
|
|
2248
|
-
if (schema.pattern) constraints.push(`@pattern ${schema.pattern}`);
|
|
2249
|
-
if (schema.minimum !== void 0) constraints.push(`@minimum ${schema.minimum}`);
|
|
2250
|
-
if (schema.maximum !== void 0) constraints.push(`@maximum ${schema.maximum}`);
|
|
2251
|
-
if (schema.minItems !== void 0) constraints.push(`@minItems ${schema.minItems}`);
|
|
2252
|
-
if (schema.maxItems !== void 0) constraints.push(`@maxItems ${schema.maxItems}`);
|
|
2253
|
-
if (schema.minProperties !== void 0) constraints.push(`@minProperties ${schema.minProperties}`);
|
|
2254
|
-
if (schema.maxProperties !== void 0) constraints.push(`@maxProperties ${schema.maxProperties}`);
|
|
2255
|
-
if (schema.multipleOf !== void 0) constraints.push(`@multipleOf ${schema.multipleOf}`);
|
|
2256
|
-
if (schema.format) constraints.push(`@format ${schema.format}`);
|
|
2257
|
-
if (constraints.length === 0) return jsdoc;
|
|
2258
|
-
if (jsdoc) {
|
|
2259
|
-
const lines = jsdoc.trim().split("\n");
|
|
2260
|
-
if (lines[0] === "/**" && lines[lines.length - 1] === " */") {
|
|
2261
|
-
const newLines = [...lines.slice(0, -1), ...constraints.map((c) => ` * ${c}`), " */\n"];
|
|
2262
|
-
return newLines.join("\n");
|
|
2263
|
-
}
|
|
2264
|
-
const content = jsdoc.replace("/** ", "").replace(" */\n", "");
|
|
2265
|
-
return `/**
|
|
2266
|
-
* ${content}
|
|
2267
|
-
${constraints.map((c) => ` * ${c}`).join("\n")}
|
|
2268
|
-
*/
|
|
2269
|
-
`;
|
|
2270
|
-
}
|
|
2271
|
-
return `/**
|
|
2272
|
-
${constraints.map((c) => ` * ${c}`).join("\n")}
|
|
2273
|
-
*/
|
|
2274
|
-
`;
|
|
2275
|
-
}
|
|
2276
|
-
/**
|
|
2277
|
-
* Generate native TypeScript type definition from OpenAPI schema
|
|
2278
|
-
*/
|
|
2279
|
-
generateNativeTypeDefinition(schema, _schemaName) {
|
|
2280
|
-
if (schema.$ref) {
|
|
2281
|
-
return resolveRef(schema.$ref);
|
|
2282
|
-
}
|
|
2283
|
-
if (schema.const !== void 0) {
|
|
2284
|
-
return typeof schema.const === "string" ? `"${schema.const}"` : String(schema.const);
|
|
2285
|
-
}
|
|
2286
|
-
const isNullable2 = schema.nullable || Array.isArray(schema.type) && schema.type.includes("null");
|
|
2287
|
-
const wrapNullable2 = (type) => isNullable2 ? `(${type}) | null` : type;
|
|
2288
|
-
const primaryType = Array.isArray(schema.type) ? schema.type.find((t) => t !== "null") : schema.type;
|
|
2289
|
-
switch (primaryType) {
|
|
2290
|
-
case "string":
|
|
2291
|
-
return wrapNullable2("string");
|
|
2292
|
-
case "number":
|
|
2293
|
-
case "integer":
|
|
2294
|
-
return wrapNullable2("number");
|
|
2295
|
-
case "boolean":
|
|
2296
|
-
return wrapNullable2("boolean");
|
|
2297
|
-
case "array":
|
|
2298
|
-
if (schema.items) {
|
|
2299
|
-
const itemType = this.generateNativeTypeDefinition(schema.items);
|
|
2300
|
-
return wrapNullable2(`${itemType}[]`);
|
|
2301
|
-
}
|
|
2302
|
-
return wrapNullable2("unknown[]");
|
|
2303
|
-
case "object":
|
|
2304
|
-
return wrapNullable2(this.generateObjectType(schema));
|
|
2305
|
-
default:
|
|
2306
|
-
if (schema.allOf) {
|
|
2307
|
-
const types = schema.allOf.map((s) => this.generateNativeTypeDefinition(s));
|
|
2308
|
-
return wrapNullable2(types.join(" & "));
|
|
2309
|
-
}
|
|
2310
|
-
if (schema.oneOf || schema.anyOf) {
|
|
2311
|
-
const schemas = schema.oneOf || schema.anyOf || [];
|
|
2312
|
-
const types = schemas.map((s) => this.generateNativeTypeDefinition(s));
|
|
2313
|
-
return wrapNullable2(types.join(" | "));
|
|
2314
|
-
}
|
|
2315
|
-
return wrapNullable2("unknown");
|
|
2316
|
-
}
|
|
2317
|
-
}
|
|
2318
|
-
/**
|
|
2319
|
-
* Generate TypeScript object type definition
|
|
2320
|
-
*/
|
|
2321
|
-
generateObjectType(schema) {
|
|
2322
|
-
if (!schema.properties || Object.keys(schema.properties).length === 0) {
|
|
2323
|
-
return "Record<string, unknown>";
|
|
2324
|
-
}
|
|
2325
|
-
const context = this.schemaUsageMap.get(schema.$ref ? resolveRef(schema.$ref) : "");
|
|
2326
|
-
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
2327
|
-
const required = new Set(schema.required || []);
|
|
2328
|
-
const props = [];
|
|
2329
|
-
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
2330
|
-
const propType = this.generateNativeTypeDefinition(propSchema);
|
|
2331
|
-
const optional = !required.has(propName) ? "?" : "";
|
|
2332
|
-
let propJsdoc = generateJSDoc(propSchema, propName, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
2333
|
-
if (resolvedOptions.includeDescriptions && !propJsdoc) {
|
|
2334
|
-
propJsdoc = this.addConstraintsToJSDoc("", propSchema, resolvedOptions.includeDescriptions);
|
|
2335
|
-
} else if (propJsdoc && resolvedOptions.includeDescriptions) {
|
|
2336
|
-
propJsdoc = this.addConstraintsToJSDoc(propJsdoc, propSchema, resolvedOptions.includeDescriptions);
|
|
2337
|
-
}
|
|
2338
|
-
if (propJsdoc) {
|
|
2339
|
-
const cleanJsdoc = propJsdoc.trimEnd();
|
|
2340
|
-
props.push(` ${cleanJsdoc}
|
|
2341
|
-
${propName}${optional}: ${propType};`);
|
|
2342
|
-
} else {
|
|
2343
|
-
props.push(` ${propName}${optional}: ${propType};`);
|
|
2344
|
-
}
|
|
2345
|
-
}
|
|
2346
|
-
return `{
|
|
2347
|
-
${props.join("\n")}
|
|
2348
|
-
}`;
|
|
2349
|
-
}
|
|
2089
|
+
// REMOVED: generateNativeEnum method - no longer needed as we only generate Zod schemas
|
|
2090
|
+
// REMOVED: toEnumKey method - was only used by generateNativeEnum
|
|
2091
|
+
// REMOVED: addConstraintsToJSDoc method - was only used for native TypeScript types
|
|
2092
|
+
// REMOVED: generateNativeTypeDefinition method - was only used for native TypeScript types
|
|
2093
|
+
// REMOVED: generateObjectType method - was only used for native TypeScript types
|
|
2350
2094
|
/**
|
|
2351
2095
|
* Topological sort for schema dependencies
|
|
2352
2096
|
* Returns schemas in the order they should be declared
|
|
@@ -2358,9 +2102,6 @@ ${props.join("\n")}
|
|
|
2358
2102
|
const aliases = [];
|
|
2359
2103
|
const circularDeps = /* @__PURE__ */ new Set();
|
|
2360
2104
|
const codeCache = /* @__PURE__ */ new Map();
|
|
2361
|
-
for (const [name, code] of this.enums) {
|
|
2362
|
-
codeCache.set(name, code);
|
|
2363
|
-
}
|
|
2364
2105
|
for (const [name, code] of this.schemas) {
|
|
2365
2106
|
codeCache.set(name, code);
|
|
2366
2107
|
}
|
|
@@ -2385,7 +2126,7 @@ ${props.join("\n")}
|
|
|
2385
2126
|
const deps = this.schemaDependencies.get(name);
|
|
2386
2127
|
if (deps && deps.size > 0) {
|
|
2387
2128
|
for (const dep of deps) {
|
|
2388
|
-
if (this.
|
|
2129
|
+
if (this.schemas.has(dep) || this.types.has(dep)) {
|
|
2389
2130
|
visit(dep);
|
|
2390
2131
|
}
|
|
2391
2132
|
}
|
|
@@ -2396,7 +2137,7 @@ ${props.join("\n")}
|
|
|
2396
2137
|
sorted.push(name);
|
|
2397
2138
|
}
|
|
2398
2139
|
};
|
|
2399
|
-
const allNames = /* @__PURE__ */ new Set([...this.
|
|
2140
|
+
const allNames = /* @__PURE__ */ new Set([...this.schemas.keys(), ...this.types.keys()]);
|
|
2400
2141
|
for (const name of allNames) {
|
|
2401
2142
|
visit(name);
|
|
2402
2143
|
}
|
|
@@ -2414,7 +2155,6 @@ ${props.join("\n")}
|
|
|
2414
2155
|
generateStats() {
|
|
2415
2156
|
const stats = {
|
|
2416
2157
|
totalSchemas: this.schemas.size,
|
|
2417
|
-
enums: this.enums.size,
|
|
2418
2158
|
withCircularRefs: 0,
|
|
2419
2159
|
withDiscriminators: 0,
|
|
2420
2160
|
withConstraints: 0
|
|
@@ -2429,7 +2169,6 @@ ${props.join("\n")}
|
|
|
2429
2169
|
const output = [
|
|
2430
2170
|
"// Generation Statistics:",
|
|
2431
2171
|
`// Total schemas: ${stats.totalSchemas}`,
|
|
2432
|
-
`// Enums: ${stats.enums}`,
|
|
2433
2172
|
`// Circular references: ${stats.withCircularRefs}`,
|
|
2434
2173
|
`// Discriminated unions: ${stats.withDiscriminators}`,
|
|
2435
2174
|
`// With constraints: ${stats.withConstraints}`
|