@cerios/openapi-to-zod 1.0.0 → 1.1.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 +178 -0
- package/dist/cli.js +122 -23
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +129 -23
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +117 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +117 -14
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.mts +59 -2
- package/dist/internal.d.ts +59 -2
- package/dist/internal.js +130 -2
- package/dist/internal.js.map +1 -1
- package/dist/internal.mjs +127 -2
- package/dist/internal.mjs.map +1 -1
- package/dist/{types-BjoP91vk.d.mts → types-B7ePTDjr.d.mts} +31 -0
- package/dist/{types-BjoP91vk.d.ts → types-B7ePTDjr.d.ts} +31 -0
- package/package.json +102 -89
package/dist/index.mjs
CHANGED
|
@@ -71,8 +71,20 @@ import { minimatch as minimatch2 } from "minimatch";
|
|
|
71
71
|
import { parse } from "yaml";
|
|
72
72
|
|
|
73
73
|
// src/utils/name-utils.ts
|
|
74
|
+
function sanitizeIdentifier(str) {
|
|
75
|
+
return str.replace(/[^a-zA-Z0-9._\-\s]+/g, "_");
|
|
76
|
+
}
|
|
74
77
|
function toCamelCase(str, options) {
|
|
75
|
-
|
|
78
|
+
const sanitized = sanitizeIdentifier(str);
|
|
79
|
+
const words = sanitized.split(/[.\-_\s]+/).filter((word) => word.length > 0);
|
|
80
|
+
let name;
|
|
81
|
+
if (words.length === 0) {
|
|
82
|
+
name = str.charAt(0).toLowerCase() + str.slice(1);
|
|
83
|
+
} else if (words.length === 1) {
|
|
84
|
+
name = words[0].charAt(0).toLowerCase() + words[0].slice(1);
|
|
85
|
+
} else {
|
|
86
|
+
name = words[0].charAt(0).toLowerCase() + words[0].slice(1) + words.slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
87
|
+
}
|
|
76
88
|
if (options == null ? void 0 : options.prefix) {
|
|
77
89
|
const prefix = options.prefix.toLowerCase();
|
|
78
90
|
name = prefix + name.charAt(0).toUpperCase() + name.slice(1);
|
|
@@ -85,12 +97,23 @@ function toCamelCase(str, options) {
|
|
|
85
97
|
}
|
|
86
98
|
function toPascalCase(str) {
|
|
87
99
|
const stringValue = String(str);
|
|
88
|
-
|
|
100
|
+
const isAlreadyValidCase = /^[a-zA-Z][a-zA-Z0-9]*$/.test(stringValue);
|
|
101
|
+
if (isAlreadyValidCase) {
|
|
102
|
+
return stringValue.charAt(0).toUpperCase() + stringValue.slice(1);
|
|
103
|
+
}
|
|
104
|
+
const sanitized = sanitizeIdentifier(stringValue);
|
|
105
|
+
const words = sanitized.split(/[.\-_\s]+/).filter((word) => word.length > 0);
|
|
106
|
+
let result;
|
|
107
|
+
if (words.length === 0) {
|
|
108
|
+
result = "Value";
|
|
109
|
+
} else {
|
|
110
|
+
result = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
111
|
+
}
|
|
89
112
|
if (/^\d/.test(result)) {
|
|
90
113
|
result = `N${result}`;
|
|
91
114
|
}
|
|
92
115
|
if (!result || /^_+$/.test(result)) {
|
|
93
|
-
|
|
116
|
+
return "Value";
|
|
94
117
|
}
|
|
95
118
|
return result;
|
|
96
119
|
}
|
|
@@ -102,9 +125,10 @@ function resolveRef(ref) {
|
|
|
102
125
|
// src/generators/enum-generator.ts
|
|
103
126
|
function generateEnum(name, values, options) {
|
|
104
127
|
const schemaName = `${toCamelCase(name, options)}Schema`;
|
|
128
|
+
const typeName = toPascalCase(name);
|
|
105
129
|
const enumValues = values.map((v) => `"${v}"`).join(", ");
|
|
106
130
|
const schemaCode = `export const ${schemaName} = z.enum([${enumValues}]);`;
|
|
107
|
-
const typeCode = `export type ${
|
|
131
|
+
const typeCode = `export type ${typeName} = z.infer<typeof ${schemaName}>;`;
|
|
108
132
|
return { schemaCode, typeCode };
|
|
109
133
|
}
|
|
110
134
|
|
|
@@ -237,6 +261,76 @@ var LRUCache = class {
|
|
|
237
261
|
}
|
|
238
262
|
};
|
|
239
263
|
|
|
264
|
+
// src/utils/pattern-utils.ts
|
|
265
|
+
function isRegexPattern(pattern) {
|
|
266
|
+
if (pattern.startsWith("^") || pattern.endsWith("$")) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
if (/\\[dDwWsS]/.test(pattern)) {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
if (/\.\*|\.\+/.test(pattern)) {
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
if (/[[\]()]/.test(pattern)) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
if (/[^/][+?*]\{/.test(pattern)) {
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
function patternToRegex(pattern) {
|
|
284
|
+
if (pattern instanceof RegExp) {
|
|
285
|
+
return pattern;
|
|
286
|
+
}
|
|
287
|
+
if (isRegexPattern(pattern)) {
|
|
288
|
+
try {
|
|
289
|
+
return new RegExp(pattern);
|
|
290
|
+
} catch (error) {
|
|
291
|
+
console.warn(`\u26A0\uFE0F Invalid regex pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`);
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
function stripPrefix(input, pattern, ensureLeadingChar) {
|
|
298
|
+
if (!pattern) {
|
|
299
|
+
return input;
|
|
300
|
+
}
|
|
301
|
+
const regex = patternToRegex(pattern);
|
|
302
|
+
if (regex) {
|
|
303
|
+
const match = input.match(regex);
|
|
304
|
+
if (match && match.index === 0) {
|
|
305
|
+
const stripped = input.substring(match[0].length);
|
|
306
|
+
if (ensureLeadingChar) {
|
|
307
|
+
if (stripped === "") {
|
|
308
|
+
return ensureLeadingChar;
|
|
309
|
+
}
|
|
310
|
+
if (!stripped.startsWith(ensureLeadingChar)) {
|
|
311
|
+
return `${ensureLeadingChar}${stripped}`;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return stripped;
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
const stringPattern = pattern;
|
|
318
|
+
if (input.startsWith(stringPattern)) {
|
|
319
|
+
const stripped = input.substring(stringPattern.length);
|
|
320
|
+
if (ensureLeadingChar) {
|
|
321
|
+
if (stripped === "") {
|
|
322
|
+
return ensureLeadingChar;
|
|
323
|
+
}
|
|
324
|
+
if (!stripped.startsWith(ensureLeadingChar)) {
|
|
325
|
+
return `${ensureLeadingChar}${stripped}`;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return stripped;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return input;
|
|
332
|
+
}
|
|
333
|
+
|
|
240
334
|
// src/validators/array-validator.ts
|
|
241
335
|
function generateArrayValidation(schema, context) {
|
|
242
336
|
var _a;
|
|
@@ -1093,8 +1187,9 @@ var _PropertyGenerator = class _PropertyGenerator {
|
|
|
1093
1187
|
}
|
|
1094
1188
|
(_a = this.context.schemaDependencies.get(currentSchema)) == null ? void 0 : _a.add(refName);
|
|
1095
1189
|
}
|
|
1096
|
-
const
|
|
1097
|
-
|
|
1190
|
+
const strippedRefName = stripPrefix(resolvedRefName, this.context.stripSchemaPrefix);
|
|
1191
|
+
const schemaName = `${toCamelCase(strippedRefName, this.context.namingOptions)}Schema`;
|
|
1192
|
+
if (currentSchema && (refName === currentSchema || this.isCircularThroughAlias(currentSchema, refName))) {
|
|
1098
1193
|
const lazySchema = `z.lazy((): z.ZodTypeAny => ${schemaName})`;
|
|
1099
1194
|
return wrapNullable(lazySchema, nullable);
|
|
1100
1195
|
}
|
|
@@ -1394,6 +1489,7 @@ var OpenApiGenerator = class {
|
|
|
1394
1489
|
schemaType: options.schemaType || "all",
|
|
1395
1490
|
prefix: options.prefix,
|
|
1396
1491
|
suffix: options.suffix,
|
|
1492
|
+
stripSchemaPrefix: options.stripSchemaPrefix,
|
|
1397
1493
|
showStats: (_c = options.showStats) != null ? _c : true,
|
|
1398
1494
|
request: options.request,
|
|
1399
1495
|
response: options.response,
|
|
@@ -1470,7 +1566,8 @@ var OpenApiGenerator = class {
|
|
|
1470
1566
|
namingOptions: {
|
|
1471
1567
|
prefix: this.options.prefix,
|
|
1472
1568
|
suffix: this.options.suffix
|
|
1473
|
-
}
|
|
1569
|
+
},
|
|
1570
|
+
stripSchemaPrefix: this.options.stripSchemaPrefix
|
|
1474
1571
|
});
|
|
1475
1572
|
}
|
|
1476
1573
|
/**
|
|
@@ -1504,9 +1601,11 @@ var OpenApiGenerator = class {
|
|
|
1504
1601
|
const typeCode = this.types.get(name);
|
|
1505
1602
|
if (schemaCode) {
|
|
1506
1603
|
output.push(schemaCode);
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1604
|
+
const strippedName = stripPrefix(name, this.options.stripSchemaPrefix);
|
|
1605
|
+
const typeName = toPascalCase(strippedName);
|
|
1606
|
+
if (!schemaCode.includes(`export type ${typeName}`)) {
|
|
1607
|
+
const schemaName = `${toCamelCase(strippedName, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
|
|
1608
|
+
output.push(`export type ${typeName} = z.infer<typeof ${schemaName}>;`);
|
|
1510
1609
|
}
|
|
1511
1610
|
output.push("");
|
|
1512
1611
|
} else if (typeCode) {
|
|
@@ -1822,7 +1921,8 @@ var OpenApiGenerator = class {
|
|
|
1822
1921
|
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
1823
1922
|
if (schema.enum) {
|
|
1824
1923
|
const jsdoc2 = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
1825
|
-
const
|
|
1924
|
+
const strippedName2 = stripPrefix(name, this.options.stripSchemaPrefix);
|
|
1925
|
+
const { schemaCode, typeCode } = generateEnum(strippedName2, schema.enum, {
|
|
1826
1926
|
prefix: this.options.prefix,
|
|
1827
1927
|
suffix: this.options.suffix
|
|
1828
1928
|
});
|
|
@@ -1831,7 +1931,8 @@ ${typeCode}`;
|
|
|
1831
1931
|
this.schemas.set(name, enumSchemaCode);
|
|
1832
1932
|
return;
|
|
1833
1933
|
}
|
|
1834
|
-
const
|
|
1934
|
+
const strippedName = stripPrefix(name, this.options.stripSchemaPrefix);
|
|
1935
|
+
const schemaName = `${toCamelCase(strippedName, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
|
|
1835
1936
|
const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
1836
1937
|
if (schema.allOf && schema.allOf.length === 1 && schema.allOf[0].$ref) {
|
|
1837
1938
|
const refName = resolveRef(schema.allOf[0].$ref);
|
|
@@ -1847,7 +1948,8 @@ ${typeCode}`;
|
|
|
1847
1948
|
namingOptions: {
|
|
1848
1949
|
prefix: this.options.prefix,
|
|
1849
1950
|
suffix: this.options.suffix
|
|
1850
|
-
}
|
|
1951
|
+
},
|
|
1952
|
+
stripSchemaPrefix: this.options.stripSchemaPrefix
|
|
1851
1953
|
});
|
|
1852
1954
|
const isAlias = !!(schema.$ref && !schema.properties && !schema.allOf && !schema.oneOf && !schema.anyOf);
|
|
1853
1955
|
const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
|
|
@@ -2049,7 +2151,8 @@ ${propsCode}
|
|
|
2049
2151
|
generateQueryParamType(schema, param) {
|
|
2050
2152
|
if (schema.$ref) {
|
|
2051
2153
|
const refName = resolveRef(schema.$ref);
|
|
2052
|
-
const
|
|
2154
|
+
const strippedRefName = stripPrefix(refName, this.options.stripSchemaPrefix);
|
|
2155
|
+
const schemaName = toCamelCase(strippedRefName, { prefix: this.options.prefix, suffix: this.options.suffix });
|
|
2053
2156
|
return `${schemaName}Schema`;
|
|
2054
2157
|
}
|
|
2055
2158
|
if (schema.enum) {
|