@cerios/openapi-to-zod 0.3.0 → 0.4.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 +2 -2
- package/dist/cli.js +129 -23
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +134 -28
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +36 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -6291,13 +6291,13 @@ var init_property_generator = __esm({
|
|
|
6291
6291
|
}
|
|
6292
6292
|
});
|
|
6293
6293
|
|
|
6294
|
-
// src/generator.ts
|
|
6294
|
+
// src/openapi-generator.ts
|
|
6295
6295
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
6296
6296
|
import { dirname, normalize } from "path";
|
|
6297
6297
|
import { parse } from "yaml";
|
|
6298
|
-
var
|
|
6299
|
-
var
|
|
6300
|
-
"src/generator.ts"() {
|
|
6298
|
+
var OpenApiGenerator;
|
|
6299
|
+
var init_openapi_generator = __esm({
|
|
6300
|
+
"src/openapi-generator.ts"() {
|
|
6301
6301
|
"use strict";
|
|
6302
6302
|
init_esm_shims();
|
|
6303
6303
|
init_errors();
|
|
@@ -6305,7 +6305,7 @@ var init_generator = __esm({
|
|
|
6305
6305
|
init_jsdoc_generator();
|
|
6306
6306
|
init_property_generator();
|
|
6307
6307
|
init_name_utils();
|
|
6308
|
-
|
|
6308
|
+
OpenApiGenerator = class {
|
|
6309
6309
|
constructor(options) {
|
|
6310
6310
|
this.schemas = /* @__PURE__ */ new Map();
|
|
6311
6311
|
this.types = /* @__PURE__ */ new Map();
|
|
@@ -6345,19 +6345,41 @@ var init_generator = __esm({
|
|
|
6345
6345
|
}
|
|
6346
6346
|
}
|
|
6347
6347
|
try {
|
|
6348
|
-
const
|
|
6349
|
-
|
|
6348
|
+
const content = readFileSync(this.options.input, "utf-8");
|
|
6349
|
+
try {
|
|
6350
|
+
this.spec = parse(content);
|
|
6351
|
+
} catch (yamlError) {
|
|
6352
|
+
try {
|
|
6353
|
+
this.spec = JSON.parse(content);
|
|
6354
|
+
} catch {
|
|
6355
|
+
if (yamlError instanceof Error) {
|
|
6356
|
+
const errorMessage = [
|
|
6357
|
+
`Failed to parse OpenAPI specification from: ${this.options.input}`,
|
|
6358
|
+
"",
|
|
6359
|
+
`Error: ${yamlError.message}`,
|
|
6360
|
+
"",
|
|
6361
|
+
"Please ensure:",
|
|
6362
|
+
" - The file exists and is readable",
|
|
6363
|
+
" - The file contains valid YAML or JSON syntax",
|
|
6364
|
+
" - The file is a valid OpenAPI 3.x specification"
|
|
6365
|
+
].join("\n");
|
|
6366
|
+
throw new SpecValidationError(errorMessage, {
|
|
6367
|
+
filePath: this.options.input,
|
|
6368
|
+
originalError: yamlError.message
|
|
6369
|
+
});
|
|
6370
|
+
}
|
|
6371
|
+
throw yamlError;
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6350
6374
|
} catch (error) {
|
|
6375
|
+
if (error instanceof SpecValidationError) {
|
|
6376
|
+
throw error;
|
|
6377
|
+
}
|
|
6351
6378
|
if (error instanceof Error) {
|
|
6352
6379
|
const errorMessage = [
|
|
6353
|
-
`Failed to
|
|
6354
|
-
"",
|
|
6355
|
-
`Error: ${error.message}`,
|
|
6380
|
+
`Failed to read OpenAPI specification from: ${this.options.input}`,
|
|
6356
6381
|
"",
|
|
6357
|
-
|
|
6358
|
-
" - The file exists and is readable",
|
|
6359
|
-
" - The file contains valid YAML syntax",
|
|
6360
|
-
" - The file is a valid OpenAPI 3.x specification"
|
|
6382
|
+
`Error: ${error.message}`
|
|
6361
6383
|
].join("\n");
|
|
6362
6384
|
throw new SpecValidationError(errorMessage, { filePath: this.options.input, originalError: error.message });
|
|
6363
6385
|
}
|
|
@@ -7221,7 +7243,7 @@ ${props.join("\n")}
|
|
|
7221
7243
|
async function processSpec(spec, index, total) {
|
|
7222
7244
|
console.log(`Processing [${index + 1}/${total}] ${spec.input}...`);
|
|
7223
7245
|
try {
|
|
7224
|
-
const generator = new
|
|
7246
|
+
const generator = new OpenApiGenerator(spec);
|
|
7225
7247
|
generator.generate();
|
|
7226
7248
|
console.log(`\u2713 Successfully generated ${spec.output}`);
|
|
7227
7249
|
return {
|
|
@@ -7322,7 +7344,7 @@ var init_batch_executor = __esm({
|
|
|
7322
7344
|
"use strict";
|
|
7323
7345
|
init_esm_shims();
|
|
7324
7346
|
init_errors();
|
|
7325
|
-
|
|
7347
|
+
init_openapi_generator();
|
|
7326
7348
|
}
|
|
7327
7349
|
});
|
|
7328
7350
|
|
|
@@ -7397,7 +7419,7 @@ function mergeConfigWithDefaults(config) {
|
|
|
7397
7419
|
return merged;
|
|
7398
7420
|
});
|
|
7399
7421
|
}
|
|
7400
|
-
var TypeModeSchema, NativeEnumTypeSchema, RequestResponseOptionsSchema,
|
|
7422
|
+
var TypeModeSchema, NativeEnumTypeSchema, RequestResponseOptionsSchema, OpenApiGeneratorOptionsSchema, ConfigFileSchema, createTypeScriptLoader;
|
|
7401
7423
|
var init_config_loader = __esm({
|
|
7402
7424
|
"src/utils/config-loader.ts"() {
|
|
7403
7425
|
"use strict";
|
|
@@ -7412,7 +7434,7 @@ var init_config_loader = __esm({
|
|
|
7412
7434
|
typeMode: TypeModeSchema.optional(),
|
|
7413
7435
|
nativeEnumType: NativeEnumTypeSchema.optional()
|
|
7414
7436
|
});
|
|
7415
|
-
|
|
7437
|
+
OpenApiGeneratorOptionsSchema = z.strictObject({
|
|
7416
7438
|
mode: z.enum(["strict", "normal", "loose"]).optional(),
|
|
7417
7439
|
input: z.string(),
|
|
7418
7440
|
output: z.string(),
|
|
@@ -7442,7 +7464,7 @@ var init_config_loader = __esm({
|
|
|
7442
7464
|
request: RequestResponseOptionsSchema.optional(),
|
|
7443
7465
|
response: RequestResponseOptionsSchema.optional()
|
|
7444
7466
|
}).optional(),
|
|
7445
|
-
specs: z.array(
|
|
7467
|
+
specs: z.array(OpenApiGeneratorOptionsSchema).min(1, "At least one spec is required"),
|
|
7446
7468
|
executionMode: z.enum(["parallel", "sequential"]).optional()
|
|
7447
7469
|
});
|
|
7448
7470
|
createTypeScriptLoader = () => {
|
|
@@ -7481,7 +7503,8 @@ var init_config_loader = __esm({
|
|
|
7481
7503
|
});
|
|
7482
7504
|
|
|
7483
7505
|
// src/cli.ts
|
|
7484
|
-
import { existsSync as existsSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
7506
|
+
import { existsSync as existsSync2, readdirSync, statSync, writeFileSync as writeFileSync2 } from "fs";
|
|
7507
|
+
import { join } from "path";
|
|
7485
7508
|
import { Command } from "commander";
|
|
7486
7509
|
var require_cli = __commonJS({
|
|
7487
7510
|
"src/cli.ts"() {
|
|
@@ -7532,6 +7555,36 @@ Breaking Changes (v2.0):
|
|
|
7532
7555
|
}
|
|
7533
7556
|
});
|
|
7534
7557
|
program.parse();
|
|
7558
|
+
function findSpecFiles() {
|
|
7559
|
+
const specFolders = ["spec", "specs"];
|
|
7560
|
+
const validExtensions = [".yaml", ".yml", ".json"];
|
|
7561
|
+
const excludePatterns = ["node_modules", ".git", "dist", "build", "coverage"];
|
|
7562
|
+
const allFiles = [];
|
|
7563
|
+
for (const folder of specFolders) {
|
|
7564
|
+
if (!existsSync2(folder)) continue;
|
|
7565
|
+
try {
|
|
7566
|
+
const entries = readdirSync(folder, { recursive: true, encoding: "utf-8" });
|
|
7567
|
+
for (const entry of entries) {
|
|
7568
|
+
const fullPath = join(folder, entry);
|
|
7569
|
+
if (excludePatterns.some((pattern) => fullPath.includes(pattern))) continue;
|
|
7570
|
+
try {
|
|
7571
|
+
const stats = statSync(fullPath);
|
|
7572
|
+
if (!stats.isFile()) continue;
|
|
7573
|
+
const hasValidExt = validExtensions.some((ext) => fullPath.endsWith(ext));
|
|
7574
|
+
if (!hasValidExt) continue;
|
|
7575
|
+
const sizeKB = (stats.size / 1024).toFixed(2);
|
|
7576
|
+
allFiles.push({ path: fullPath.replace(/\\/g, "/"), size: `${sizeKB} KB` });
|
|
7577
|
+
} catch {
|
|
7578
|
+
}
|
|
7579
|
+
}
|
|
7580
|
+
} catch {
|
|
7581
|
+
}
|
|
7582
|
+
}
|
|
7583
|
+
allFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
7584
|
+
const totalCount = allFiles.length;
|
|
7585
|
+
const files = allFiles.slice(0, 20);
|
|
7586
|
+
return { files, totalCount };
|
|
7587
|
+
}
|
|
7535
7588
|
async function executeConfigMode(options) {
|
|
7536
7589
|
let config;
|
|
7537
7590
|
try {
|
|
@@ -7565,14 +7618,66 @@ Breaking Changes (v2.0):
|
|
|
7565
7618
|
return;
|
|
7566
7619
|
}
|
|
7567
7620
|
}
|
|
7568
|
-
const
|
|
7569
|
-
|
|
7621
|
+
const { files, totalCount } = findSpecFiles();
|
|
7622
|
+
if (totalCount > 20) {
|
|
7623
|
+
console.log(`Showing first 20 of ${totalCount} files found. Use manual entry to specify others.
|
|
7624
|
+
`);
|
|
7625
|
+
}
|
|
7626
|
+
let inputPath;
|
|
7627
|
+
if (files.length > 0) {
|
|
7628
|
+
const choices = [
|
|
7629
|
+
...files.map((f) => ({ title: `${f.path} (${f.size})`, value: f.path })),
|
|
7630
|
+
{ title: "\u2192 Enter manually...", value: "__MANUAL__" }
|
|
7631
|
+
];
|
|
7632
|
+
const inputResponse = await (0, import_prompts.default)({
|
|
7633
|
+
type: "select",
|
|
7634
|
+
name: "input",
|
|
7635
|
+
message: "Select OpenAPI spec file (YAML or JSON):",
|
|
7636
|
+
choices
|
|
7637
|
+
});
|
|
7638
|
+
if (!inputResponse.input) {
|
|
7639
|
+
console.log("\nInitialization cancelled.");
|
|
7640
|
+
return;
|
|
7641
|
+
}
|
|
7642
|
+
if (inputResponse.input === "__MANUAL__") {
|
|
7643
|
+
const manualResponse = await (0, import_prompts.default)({
|
|
7644
|
+
type: "text",
|
|
7645
|
+
name: "input",
|
|
7646
|
+
message: "Input OpenAPI file path (YAML or JSON):",
|
|
7647
|
+
initial: "openapi.{yaml,yml,json}",
|
|
7648
|
+
validate: (value) => {
|
|
7649
|
+
if (value.length === 0) return "Input path is required";
|
|
7650
|
+
if (!existsSync2(value)) return "\u26A0\uFE0F File does not exist. Continue anyway?";
|
|
7651
|
+
return true;
|
|
7652
|
+
}
|
|
7653
|
+
});
|
|
7654
|
+
if (!manualResponse.input) {
|
|
7655
|
+
console.log("\nInitialization cancelled.");
|
|
7656
|
+
return;
|
|
7657
|
+
}
|
|
7658
|
+
inputPath = manualResponse.input;
|
|
7659
|
+
} else {
|
|
7660
|
+
inputPath = inputResponse.input;
|
|
7661
|
+
}
|
|
7662
|
+
} else {
|
|
7663
|
+
const manualResponse = await (0, import_prompts.default)({
|
|
7570
7664
|
type: "text",
|
|
7571
7665
|
name: "input",
|
|
7572
|
-
message: "Input OpenAPI file path:",
|
|
7573
|
-
initial: "openapi.yaml",
|
|
7574
|
-
validate: (value) =>
|
|
7575
|
-
|
|
7666
|
+
message: "Input OpenAPI file path (YAML or JSON):",
|
|
7667
|
+
initial: "openapi.{yaml,yml,json}",
|
|
7668
|
+
validate: (value) => {
|
|
7669
|
+
if (value.length === 0) return "Input path is required";
|
|
7670
|
+
if (!existsSync2(value)) return "\u26A0\uFE0F File does not exist. Continue anyway?";
|
|
7671
|
+
return true;
|
|
7672
|
+
}
|
|
7673
|
+
});
|
|
7674
|
+
if (!manualResponse.input) {
|
|
7675
|
+
console.log("\nInitialization cancelled.");
|
|
7676
|
+
return;
|
|
7677
|
+
}
|
|
7678
|
+
inputPath = manualResponse.input;
|
|
7679
|
+
}
|
|
7680
|
+
const response = await (0, import_prompts.default)([
|
|
7576
7681
|
{
|
|
7577
7682
|
type: "text",
|
|
7578
7683
|
name: "output",
|
|
@@ -7597,11 +7702,12 @@ Breaking Changes (v2.0):
|
|
|
7597
7702
|
initial: true
|
|
7598
7703
|
}
|
|
7599
7704
|
]);
|
|
7600
|
-
if (!response.
|
|
7705
|
+
if (!response.output || !response.format) {
|
|
7601
7706
|
console.log("\nInitialization cancelled.");
|
|
7602
7707
|
return;
|
|
7603
7708
|
}
|
|
7604
|
-
const {
|
|
7709
|
+
const { output, format, includeDefaults } = response;
|
|
7710
|
+
const input = inputPath;
|
|
7605
7711
|
let configContent;
|
|
7606
7712
|
let configFilename;
|
|
7607
7713
|
if (format === "ts") {
|