@moccona/apicodegen 0.0.9 → 0.0.10

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/npm/index.mjs CHANGED
@@ -415,6 +415,250 @@ var Provider = class {
415
415
  }
416
416
  };
417
417
  //#endregion
418
+ //#region src/core/errors.ts
419
+ /**
420
+ * Error handling utilities for api-codegen
421
+ */
422
+ const ErrorCodes = {
423
+ SPEC_NOT_FOUND: "E_SPEC_NOT_FOUND",
424
+ SPEC_FETCH_FAILED: "E_SPEC_FETCH_FAILED",
425
+ SPEC_PARSE_FAILED: "E_SPEC_PARSE_FAILED",
426
+ OUTPUT_DIR_MISSING: "E_OUTPUT_DIR_MISSING",
427
+ CONFIG_INVALID: "E_CONFIG_INVALID",
428
+ VALIDATION_FAILED: "E_VALIDATION_FAILED",
429
+ GENERATION_FAILED: "E_GENERATION_FAILED",
430
+ TYPE_CHECK_FAILED: "E_TYPE_CHECK_FAILED"
431
+ };
432
+ /**
433
+ * Custom error class for api-codegen with rich context
434
+ */
435
+ var ApicodegenError = class ApicodegenError extends Error {
436
+ code;
437
+ location;
438
+ line;
439
+ column;
440
+ path;
441
+ suggestions;
442
+ cause;
443
+ constructor(context) {
444
+ super(context.message);
445
+ this.name = "ApicodegenError";
446
+ this.code = context.code;
447
+ this.location = context.location;
448
+ this.line = context.line;
449
+ this.column = context.column;
450
+ this.path = context.path;
451
+ this.suggestions = context.suggestions || [];
452
+ this.cause = context.cause;
453
+ if (Error.captureStackTrace) Error.captureStackTrace(this, ApicodegenError);
454
+ }
455
+ /**
456
+ * Convert error to formatted string for CLI output
457
+ */
458
+ toString(verbose = false) {
459
+ const lines = [];
460
+ lines.push(`\x1b[1;31mError [${this.code}]\x1b[0m ${this.message}`);
461
+ if (this.location) lines.push(` \x1b[36m→ Location:\x1b[0m ${this.location}`);
462
+ if (this.path) lines.push(` \x1b[36m→ Path:\x1b[0m ${this.path}`);
463
+ if (this.line !== void 0) {
464
+ let lineInfo = ` \x1b[36m→ Line:\x1b[0m ${this.line}`;
465
+ if (this.column !== void 0) lineInfo += `, Column: ${this.column}`;
466
+ lines.push(lineInfo);
467
+ }
468
+ if (this.suggestions.length > 0) for (const suggestion of this.suggestions) lines.push(` \x1b[32m→ Suggestion:\x1b[0m ${suggestion}`);
469
+ if (verbose && this.cause) {
470
+ lines.push(`\n \x1b[90mOriginal Error:\x1b[0m ${this.cause.message}`);
471
+ if (this.stack) {
472
+ const stackLines = this.stack.split("\n").slice(1).join("\n");
473
+ lines.push(`\x1b[90m${stackLines}\x1b[0m`);
474
+ }
475
+ }
476
+ return lines.join("\n");
477
+ }
478
+ /**
479
+ * Convert to JSON-serializable object
480
+ */
481
+ toJSON() {
482
+ return {
483
+ name: this.name,
484
+ code: this.code,
485
+ message: this.message,
486
+ location: this.location,
487
+ line: this.line,
488
+ column: this.column,
489
+ path: this.path,
490
+ suggestions: this.suggestions,
491
+ cause: this.cause?.message
492
+ };
493
+ }
494
+ };
495
+ /**
496
+ * ANSI color codes for terminal output
497
+ */
498
+ const Colors = {
499
+ reset: "\x1B[0m",
500
+ bold: "\x1B[1m",
501
+ red: "\x1B[31m",
502
+ green: "\x1B[32m",
503
+ yellow: "\x1B[33m",
504
+ blue: "\x1B[34m",
505
+ cyan: "\x1B[36m",
506
+ gray: "\x1B[90m",
507
+ brightRed: "\x1B[91m",
508
+ brightGreen: "\x1B[92m"
509
+ };
510
+ /**
511
+ * Format error for CLI output
512
+ */
513
+ function formatError(error, verbose = false) {
514
+ if (error instanceof ApicodegenError) return error.toString(verbose);
515
+ if (error instanceof Error) return `${Colors.red}${Colors.bold}Error${Colors.reset}: ${error.message}${verbose && error.stack ? `\n\n${Colors.gray}${error.stack}${Colors.reset}` : ""}`;
516
+ return `${Colors.red}${Colors.bold}Error${Colors.reset}: ${String(error)}`;
517
+ }
518
+ /**
519
+ * Print error to console with formatting
520
+ */
521
+ function printError(error, verbose = false, stream = process.stderr) {
522
+ stream.write(formatError(error, verbose));
523
+ stream.write("\n");
524
+ }
525
+ /**
526
+ * Create error with common patterns
527
+ */
528
+ const createErrors = {
529
+ specNotFound(path, cause) {
530
+ return new ApicodegenError({
531
+ code: ErrorCodes.SPEC_NOT_FOUND,
532
+ message: "OpenAPI spec file not found",
533
+ location: path,
534
+ suggestions: [
535
+ "Check if the file exists using 'ls -la'",
536
+ "Use --spec to provide the correct path",
537
+ "For remote specs, ensure the URL is accessible"
538
+ ],
539
+ cause
540
+ });
541
+ },
542
+ specFetchFailed(url, statusCode, cause) {
543
+ const message = statusCode ? `Failed to fetch OpenAPI spec (HTTP ${statusCode})` : "Failed to fetch OpenAPI spec from URL";
544
+ return new ApicodegenError({
545
+ code: ErrorCodes.SPEC_FETCH_FAILED,
546
+ message,
547
+ location: url,
548
+ suggestions: [
549
+ "Check if the URL is accessible in a browser",
550
+ "Download the spec file locally and use the local path",
551
+ "Verify CORS settings if fetching from a different origin"
552
+ ],
553
+ cause
554
+ });
555
+ },
556
+ specParseFailed(path, line, column, cause) {
557
+ return new ApicodegenError({
558
+ code: ErrorCodes.SPEC_PARSE_FAILED,
559
+ message: "Failed to parse OpenAPI spec (invalid JSON or YAML)",
560
+ location: path,
561
+ line,
562
+ column,
563
+ suggestions: [
564
+ "Validate JSON syntax using jsonlint.com",
565
+ "For YAML specs, ensure proper indentation",
566
+ "Check for trailing commas or unquoted special characters"
567
+ ],
568
+ cause
569
+ });
570
+ },
571
+ outputDirMissing(path, cause) {
572
+ return new ApicodegenError({
573
+ code: ErrorCodes.OUTPUT_DIR_MISSING,
574
+ message: "Output directory does not exist",
575
+ location: path,
576
+ suggestions: ["Create the directory: mkdir -p $(dirname <output>)", "Check if the path is correct"],
577
+ cause
578
+ });
579
+ },
580
+ configInvalid(path, cause) {
581
+ return new ApicodegenError({
582
+ code: ErrorCodes.CONFIG_INVALID,
583
+ message: "Invalid configuration file",
584
+ location: path,
585
+ suggestions: ["Validate JSON syntax in the config file", "Check for required fields (spec, output)"],
586
+ cause
587
+ });
588
+ },
589
+ validationFailed(path, details, cause) {
590
+ return new ApicodegenError({
591
+ code: ErrorCodes.VALIDATION_FAILED,
592
+ message: "OpenAPI spec validation failed",
593
+ location: path,
594
+ path: details,
595
+ suggestions: [
596
+ "Check OpenAPI spec structure at the specified path",
597
+ "Ensure all required fields are present",
598
+ "Validate using swagger.io editor"
599
+ ],
600
+ cause
601
+ });
602
+ },
603
+ generationFailed(cause) {
604
+ return new ApicodegenError({
605
+ code: ErrorCodes.GENERATION_FAILED,
606
+ message: "Code generation failed",
607
+ suggestions: [
608
+ "Check for unsupported OpenAPI features",
609
+ "Ensure spec follows OpenAPI 2.0, 3.0, or 3.1 specification",
610
+ "Use --verbose for more details"
611
+ ],
612
+ cause
613
+ });
614
+ },
615
+ typeCheckFailed(path, _errors, cause) {
616
+ return new ApicodegenError({
617
+ code: ErrorCodes.TYPE_CHECK_FAILED,
618
+ message: "TypeScript type check failed",
619
+ location: path,
620
+ suggestions: [
621
+ "Review type errors above",
622
+ "Check for schema inconsistencies",
623
+ "Update generated types or fix source schema"
624
+ ],
625
+ cause
626
+ });
627
+ },
628
+ missingRequiredField(field, context) {
629
+ return new ApicodegenError({
630
+ code: ErrorCodes.VALIDATION_FAILED,
631
+ message: `Missing required field: ${field}`,
632
+ path: context,
633
+ suggestions: [`Add the '${field}' field to your configuration`]
634
+ });
635
+ }
636
+ };
637
+ /**
638
+ * Wrap unknown error in ApicodegenError if needed
639
+ */
640
+ function wrapError(error, context) {
641
+ if (error instanceof ApicodegenError) return error;
642
+ if (error instanceof Error) return new ApicodegenError({
643
+ code: context?.code || ErrorCodes.GENERATION_FAILED,
644
+ message: context?.message || error.message,
645
+ location: context?.location,
646
+ suggestions: context?.suggestions,
647
+ cause: error
648
+ });
649
+ return new ApicodegenError({
650
+ code: context?.code || ErrorCodes.GENERATION_FAILED,
651
+ message: String(error),
652
+ suggestions: context?.suggestions
653
+ });
654
+ }
655
+ /**
656
+ * Check if error is an ApicodegenError
657
+ */
658
+ function isApicodegenError(error) {
659
+ return error instanceof ApicodegenError;
660
+ }
661
+ //#endregion
418
662
  //#region src/core/generator/index.ts
419
663
  var Generator = class Generator {
420
664
  /**
@@ -430,10 +674,19 @@ var Generator = class Generator {
430
674
  return createPrinter().printFile(sourceFile);
431
675
  }
432
676
  static async write(code, filepath) {
677
+ const { mkdir } = await import("node:fs/promises");
678
+ const { dirname } = await import("node:path");
433
679
  try {
680
+ await mkdir(dirname(filepath), { recursive: true });
434
681
  await writeFile(filepath, code);
435
682
  } catch (error) {
436
- console.error(error);
683
+ throw new ApicodegenError({
684
+ code: ErrorCodes.OUTPUT_DIR_MISSING,
685
+ message: "Failed to write generated code to output file",
686
+ location: filepath,
687
+ cause: error instanceof Error ? error : new Error(String(error)),
688
+ suggestions: ["Verify the output directory path is writable", "Check that the parent directory exists or can be created"]
689
+ });
437
690
  }
438
691
  }
439
692
  /**
@@ -913,20 +1166,6 @@ async function loadConfig(options = {}) {
913
1166
  };
914
1167
  }
915
1168
  /**
916
- * Create CLI options from config for commander
917
- */
918
- function configToCLIOptions(config) {
919
- const options = {};
920
- if (config.spec) options.spec = config.spec;
921
- if (config.output) options.output = config.output;
922
- if (config.adaptor) options.adaptor = config.adaptor;
923
- if (config.baseURL) options.baseURL = config.baseURL;
924
- if (config.verbose) options.verbose = config.verbose;
925
- if (config.watch) options.watch = config.watch;
926
- if (config.importClientSource) options.importClientSource = config.importClientSource;
927
- return options;
928
- }
929
- /**
930
1169
  * Convert resolved config to provider options format
931
1170
  */
932
1171
  function toProviderOptions(config) {
@@ -941,509 +1180,74 @@ function toProviderOptions(config) {
941
1180
  };
942
1181
  }
943
1182
  //#endregion
944
- //#region src/core/errors.ts
945
- /**
946
- * Error handling utilities for api-codegen
947
- */
948
- const ErrorCodes = {
949
- SPEC_NOT_FOUND: "E_SPEC_NOT_FOUND",
950
- SPEC_FETCH_FAILED: "E_SPEC_FETCH_FAILED",
951
- SPEC_PARSE_FAILED: "E_SPEC_PARSE_FAILED",
952
- OUTPUT_DIR_MISSING: "E_OUTPUT_DIR_MISSING",
953
- CONFIG_INVALID: "E_CONFIG_INVALID",
954
- VALIDATION_FAILED: "E_VALIDATION_FAILED",
955
- GENERATION_FAILED: "E_GENERATION_FAILED",
956
- TYPE_CHECK_FAILED: "E_TYPE_CHECK_FAILED"
957
- };
958
- /**
959
- * Custom error class for api-codegen with rich context
960
- */
961
- var ApicodegenError = class ApicodegenError extends Error {
962
- code;
963
- location;
964
- line;
965
- column;
966
- path;
967
- suggestions;
968
- cause;
969
- constructor(context) {
970
- super(context.message);
971
- this.name = "ApicodegenError";
972
- this.code = context.code;
973
- this.location = context.location;
974
- this.line = context.line;
975
- this.column = context.column;
976
- this.path = context.path;
977
- this.suggestions = context.suggestions || [];
978
- this.cause = context.cause;
979
- if (Error.captureStackTrace) Error.captureStackTrace(this, ApicodegenError);
980
- }
981
- /**
982
- * Convert error to formatted string for CLI output
983
- */
984
- toString(verbose = false) {
985
- const lines = [];
986
- lines.push(`\x1b[1;31mError [${this.code}]\x1b[0m ${this.message}`);
987
- if (this.location) lines.push(` \x1b[36m→ Location:\x1b[0m ${this.location}`);
988
- if (this.path) lines.push(` \x1b[36m→ Path:\x1b[0m ${this.path}`);
989
- if (this.line !== void 0) {
990
- let lineInfo = ` \x1b[36m→ Line:\x1b[0m ${this.line}`;
991
- if (this.column !== void 0) lineInfo += `, Column: ${this.column}`;
992
- lines.push(lineInfo);
993
- }
994
- if (this.suggestions.length > 0) for (const suggestion of this.suggestions) lines.push(` \x1b[32m→ Suggestion:\x1b[0m ${suggestion}`);
995
- if (verbose && this.cause) {
996
- lines.push(`\n \x1b[90mOriginal Error:\x1b[0m ${this.cause.message}`);
997
- if (this.stack) {
998
- const stackLines = this.stack.split("\n").slice(1).join("\n");
999
- lines.push(`\x1b[90m${stackLines}\x1b[0m`);
1000
- }
1001
- }
1002
- return lines.join("\n");
1003
- }
1004
- /**
1005
- * Convert to JSON-serializable object
1006
- */
1007
- toJSON() {
1008
- return {
1009
- name: this.name,
1010
- code: this.code,
1011
- message: this.message,
1012
- location: this.location,
1013
- line: this.line,
1014
- column: this.column,
1015
- path: this.path,
1016
- suggestions: this.suggestions,
1017
- cause: this.cause?.message
1018
- };
1019
- }
1020
- };
1021
- /**
1022
- * ANSI color codes for terminal output
1023
- */
1024
- const Colors = {
1025
- reset: "\x1B[0m",
1026
- bold: "\x1B[1m",
1027
- red: "\x1B[31m",
1028
- green: "\x1B[32m",
1029
- yellow: "\x1B[33m",
1030
- blue: "\x1B[34m",
1031
- cyan: "\x1B[36m",
1032
- gray: "\x1B[90m",
1033
- brightRed: "\x1B[91m",
1034
- brightGreen: "\x1B[92m"
1035
- };
1036
- /**
1037
- * Format error for CLI output
1038
- */
1039
- function formatError(error, verbose = false) {
1040
- if (error instanceof ApicodegenError) return error.toString(verbose);
1041
- if (error instanceof Error) return `${Colors.red}${Colors.bold}Error${Colors.reset}: ${error.message}${verbose && error.stack ? `\n\n${Colors.gray}${error.stack}${Colors.reset}` : ""}`;
1042
- return `${Colors.red}${Colors.bold}Error${Colors.reset}: ${String(error)}`;
1043
- }
1044
- /**
1045
- * Print error to console with formatting
1046
- */
1047
- function printError(error, verbose = false, stream = process.stderr) {
1048
- stream.write(formatError(error, verbose));
1049
- stream.write("\n");
1050
- }
1051
- /**
1052
- * Create error with common patterns
1053
- */
1054
- const createErrors = {
1055
- specNotFound(path, cause) {
1056
- return new ApicodegenError({
1057
- code: ErrorCodes.SPEC_NOT_FOUND,
1058
- message: "OpenAPI spec file not found",
1059
- location: path,
1060
- suggestions: [
1061
- "Check if the file exists using 'ls -la'",
1062
- "Use --spec to provide the correct path",
1063
- "For remote specs, ensure the URL is accessible"
1064
- ],
1065
- cause
1066
- });
1067
- },
1068
- specFetchFailed(url, statusCode, cause) {
1069
- const message = statusCode ? `Failed to fetch OpenAPI spec (HTTP ${statusCode})` : "Failed to fetch OpenAPI spec from URL";
1070
- return new ApicodegenError({
1071
- code: ErrorCodes.SPEC_FETCH_FAILED,
1072
- message,
1073
- location: url,
1074
- suggestions: [
1075
- "Check if the URL is accessible in a browser",
1076
- "Download the spec file locally and use the local path",
1077
- "Verify CORS settings if fetching from a different origin"
1078
- ],
1079
- cause
1080
- });
1081
- },
1082
- specParseFailed(path, line, column, cause) {
1083
- return new ApicodegenError({
1084
- code: ErrorCodes.SPEC_PARSE_FAILED,
1085
- message: "Failed to parse OpenAPI spec (invalid JSON or YAML)",
1086
- location: path,
1087
- line,
1088
- column,
1089
- suggestions: [
1090
- "Validate JSON syntax using jsonlint.com",
1091
- "For YAML specs, ensure proper indentation",
1092
- "Check for trailing commas or unquoted special characters"
1093
- ],
1094
- cause
1095
- });
1096
- },
1097
- outputDirMissing(path, cause) {
1098
- return new ApicodegenError({
1099
- code: ErrorCodes.OUTPUT_DIR_MISSING,
1100
- message: "Output directory does not exist",
1101
- location: path,
1102
- suggestions: ["Create the directory: mkdir -p $(dirname <output>)", "Check if the path is correct"],
1103
- cause
1104
- });
1105
- },
1106
- configInvalid(path, cause) {
1107
- return new ApicodegenError({
1108
- code: ErrorCodes.CONFIG_INVALID,
1109
- message: "Invalid configuration file",
1110
- location: path,
1111
- suggestions: ["Validate JSON syntax in the config file", "Check for required fields (spec, output)"],
1112
- cause
1113
- });
1114
- },
1115
- validationFailed(path, details, cause) {
1116
- return new ApicodegenError({
1117
- code: ErrorCodes.VALIDATION_FAILED,
1118
- message: "OpenAPI spec validation failed",
1119
- location: path,
1120
- path: details,
1121
- suggestions: [
1122
- "Check OpenAPI spec structure at the specified path",
1123
- "Ensure all required fields are present",
1124
- "Validate using swagger.io editor"
1125
- ],
1126
- cause
1127
- });
1128
- },
1129
- generationFailed(cause) {
1130
- return new ApicodegenError({
1131
- code: ErrorCodes.GENERATION_FAILED,
1132
- message: "Code generation failed",
1133
- suggestions: [
1134
- "Check for unsupported OpenAPI features",
1135
- "Ensure spec follows OpenAPI 2.0, 3.0, or 3.1 specification",
1136
- "Use --verbose for more details"
1137
- ],
1138
- cause
1139
- });
1140
- },
1141
- typeCheckFailed(path, _errors, cause) {
1142
- return new ApicodegenError({
1143
- code: ErrorCodes.TYPE_CHECK_FAILED,
1144
- message: "TypeScript type check failed",
1145
- location: path,
1146
- suggestions: [
1147
- "Review type errors above",
1148
- "Check for schema inconsistencies",
1149
- "Update generated types or fix source schema"
1150
- ],
1151
- cause
1152
- });
1153
- },
1154
- missingRequiredField(field, context) {
1155
- return new ApicodegenError({
1156
- code: ErrorCodes.VALIDATION_FAILED,
1157
- message: `Missing required field: ${field}`,
1158
- path: context,
1159
- suggestions: [`Add the '${field}' field to your configuration`]
1160
- });
1161
- }
1162
- };
1163
- /**
1164
- * Wrap unknown error in ApicodegenError if needed
1165
- */
1166
- function wrapError(error, context) {
1167
- if (error instanceof ApicodegenError) return error;
1168
- if (error instanceof Error) return new ApicodegenError({
1169
- code: context?.code || ErrorCodes.GENERATION_FAILED,
1170
- message: context?.message || error.message,
1171
- location: context?.location,
1172
- suggestions: context?.suggestions,
1173
- cause: error
1174
- });
1175
- return new ApicodegenError({
1176
- code: context?.code || ErrorCodes.GENERATION_FAILED,
1177
- message: String(error),
1178
- suggestions: context?.suggestions
1179
- });
1180
- }
1181
- /**
1182
- * Check if error is an ApicodegenError
1183
- */
1184
- function isApicodegenError(error) {
1185
- return error instanceof ApicodegenError;
1186
- }
1187
- //#endregion
1188
- //#region src/openapi/V2.ts
1189
- var V2 = class {
1190
- doc;
1191
- constructor(doc) {
1192
- this.doc = doc;
1193
- }
1194
- /**
1195
- * Resolves a path $ref to the actual path object.
1196
- */
1197
- resolvePathRef($ref) {
1198
- const refName = Base.ref2name($ref, this.doc);
1199
- return this.doc.paths?.[refName];
1200
- }
1201
- /**
1202
- * Is array schema.
1203
- */
1204
- isOpenAPIArraySchema(schema) {
1205
- return typeof schema === "object" && schema.type === "array";
1206
- }
1207
- /**
1208
- * OpenAPI schema to base schema.
1209
- */
1210
- getSchemaByRef(schema, reserveRef = false, enums = [], upLevelSchemaKey = "") {
1211
- let refName = "";
1212
- if (Base.isRef(schema)) {
1213
- refName = Base.upperCamelCase(Base.ref2name(schema.$ref));
1214
- if (reserveRef) return { type: upLevelSchemaKey + refName };
1215
- if (!this.doc.definitions) this.doc.definitions = {};
1216
- schema = this.doc.definitions[Base.ref2name(schema.$ref, this.doc)];
1217
- }
1218
- return this.toBaseSchema(schema, enums, "", upLevelSchemaKey + refName);
1219
- }
1220
- /**
1221
- * Transform all OpenAPI schema to Base Schema
1222
- */
1223
- toBaseSchema(schema, enums = [], schemaKey = "", upLevelSchemaKey = "") {
1224
- if (!schema) return { type: "unknown" };
1225
- if (Base.isRef(schema)) return this.getSchemaByRef(schema, true);
1226
- if (this.isOpenAPIArraySchema(schema)) {
1227
- const { type, description, items, required } = schema;
1228
- return {
1229
- type,
1230
- required: !!required,
1231
- description,
1232
- items: this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey)
1233
- };
1234
- } else {
1235
- const { required = [], allOf, anyOf, description, enum: enum_, format, oneOf, properties = {} } = schema;
1236
- let { type } = schema;
1237
- if (enum_ && type !== "boolean") {
1238
- const enumObject = {
1239
- name: Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(schemaKey)),
1240
- enum: [...new Set(enum_)]
1241
- };
1242
- const sameObject = Base.findSameSchema(enumObject, enums);
1243
- if (!sameObject && Base.isValidEnumType(schema)) enums.push(enumObject);
1244
- return {
1245
- type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
1246
- required,
1247
- description
1248
- };
1249
- }
1250
- if (type === void 0 && Object.keys(properties).length > 0) type = "object";
1251
- return {
1252
- type,
1253
- required,
1254
- description,
1255
- enum: enum_,
1256
- format,
1257
- allOf: allOf?.map((s) => Base.isRef(s) ? {
1258
- ...s,
1259
- ref: s.$ref,
1260
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1261
- } : this.toBaseSchema(s, enums)),
1262
- anyOf: anyOf?.map((s) => Base.isRef(s) ? {
1263
- ...s,
1264
- ref: s.$ref,
1265
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1266
- } : this.toBaseSchema(s, enums)),
1267
- oneOf: oneOf?.map((s) => Base.isRef(s) ? {
1268
- ...s,
1269
- ref: s.$ref,
1270
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1271
- } : this.toBaseSchema(s, enums)),
1272
- properties: Object.keys(properties).reduce((acc, p) => {
1273
- const propSchema = properties[p];
1274
- return {
1275
- ...acc,
1276
- [p]: Base.isRef(propSchema) ? { type: Base.capitalize(Base.ref2name(propSchema.$ref, this.doc)) } : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
1277
- };
1278
- }, {})
1279
- };
1280
- }
1281
- }
1282
- /**
1283
- * OpenAPI parameter to base parameter.
1284
- */
1285
- getParameterByRef(parameter, enums = [], upLevelSchemaKey = "") {
1286
- if (Base.isRef(parameter)) {
1287
- const refName = Base.ref2name(parameter.$ref, this.doc);
1288
- const resolved = this.doc.parameters?.[refName];
1289
- if (!resolved) throw new Error(`Parameter reference not found: ${parameter.$ref}`);
1290
- parameter = resolved;
1291
- }
1292
- const p = parameter;
1293
- const { name, required, description, type, items, enum: enum_, properties, schema } = p;
1294
- if (enum_) {
1295
- const type = Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(name));
1296
- const enumSchema = {
1297
- name: type,
1298
- enum: [...new Set(enum_)]
1299
- };
1300
- const sameEnum = Base.findSameSchema(enumSchema, enums);
1301
- if (!sameEnum && Base.isValidEnumType({
1302
- type,
1303
- enum: enum_
1304
- })) enums.push(enumSchema);
1305
- return {
1306
- name,
1307
- required,
1308
- description,
1309
- in: p.in,
1310
- schema: { type: sameEnum?.name ?? type }
1311
- };
1312
- }
1313
- if (items) return {
1314
- name,
1315
- required,
1316
- description,
1317
- in: p.in,
1318
- schema: {
1319
- type,
1320
- items
1321
- }
1322
- };
1323
- if (schema && Base.isRef(schema)) return {
1324
- name,
1325
- required,
1326
- description,
1327
- in: p.in,
1328
- schema: { type: Base.capitalize(Base.ref2name(schema.$ref)) }
1329
- };
1330
- return {
1331
- name,
1332
- required,
1333
- description,
1334
- in: p.in,
1335
- schema: {
1336
- type,
1337
- properties
1338
- }
1339
- };
1340
- }
1341
- /**
1342
- * OpenAPI schema to base response
1343
- */
1344
- getResponseByRef(schema) {
1345
- if (Base.isRef(schema)) schema = this.doc.responses[Base.ref2name(schema.$ref, this.doc)];
1346
- const { schema: responseSchema } = schema;
1347
- return [{
1348
- type: "application/json",
1349
- schema: responseSchema && this.getSchemaByRef(responseSchema, true)
1350
- }];
1351
- }
1352
- init() {
1353
- const { definitions = {}, responses = {}, paths = {} } = this.doc;
1354
- const enums = [];
1355
- const definitions_ = Object.keys(definitions).reduce((acc, key) => {
1356
- const schema = definitions[key];
1357
- return {
1358
- ...acc,
1359
- [key]: this.getSchemaByRef(schema, false, enums, key)
1360
- };
1361
- }, {});
1362
- const responses_ = Object.keys(responses).reduce((acc, key) => {
1363
- const response = responses[key];
1364
- return {
1365
- ...acc,
1366
- [key]: this.getResponseByRef(response)
1367
- };
1368
- }, {});
1369
- const apis = Object.keys(paths).reduce((acc, path) => {
1370
- let pathObject = paths[path] ?? {};
1371
- if (pathObject.$ref) {
1372
- const resolved = this.resolvePathRef(pathObject.$ref);
1373
- if (resolved) pathObject = resolved;
1374
- }
1375
- const { parameters = [] } = pathObject;
1376
- const methodApis = [];
1377
- Object.values(HttpMethods).forEach((method) => {
1378
- const methodObject = pathObject[method];
1379
- if (methodObject) {
1380
- const { deprecated, operationId, summary: summary_, description: description_, responses = {} } = methodObject;
1381
- const { parameters: parameters_ = [] } = methodObject;
1382
- const baseParameters = [...parameters, ...parameters_].map((parameter) => this.getParameterByRef(parameter, enums));
1383
- const uniqueParameterName = [...new Set(baseParameters.map((p) => p.name))];
1384
- if (Object.keys(responses).length === 0) Object.assign(responses, { 200: { description: "Successful response" } });
1385
- const inBody = baseParameters.filter((p) => p.in === "body" || p.in === "formData");
1386
- const notInBody = baseParameters.filter((p) => p.in !== "body" && p.in !== "formData");
1387
- const httpCodes = Object.keys(responses);
1388
- for (const code of httpCodes) if (code in responses) {
1389
- const response = responses[code];
1390
- const responseSchema = this.getResponseByRef(response);
1391
- const inBodyOnlyHasBody = inBody && inBody.length === 1 && inBody[0].in === "body" && inBody[0].name === "body";
1392
- methodApis.push({
1393
- method,
1394
- operationId,
1395
- summary: summary_,
1396
- deprecated,
1397
- description: description_,
1398
- parameters: uniqueParameterName.map((name) => notInBody.find((p) => p.name === name)).filter(Boolean),
1399
- responses: responseSchema,
1400
- requestBody: inBody.length > 0 ? inBodyOnlyHasBody ? [{
1401
- type: "application/json",
1402
- schema: inBody[0].schema
1403
- }] : [{
1404
- type: "application/json",
1405
- schema: {
1406
- type: "object",
1407
- properties: inBody.reduce((a, p) => {
1408
- return {
1409
- ...a,
1410
- [p.name]: {
1411
- type: p.schema?.type ?? "unknown",
1412
- required: p.schema?.required,
1413
- items: p.schema?.items,
1414
- description: p.schema?.description
1415
- }
1416
- };
1417
- }, {})
1418
- }
1419
- }] : void 0
1420
- });
1421
- break;
1422
- }
1423
- }
1424
- });
1425
- return {
1426
- ...acc,
1427
- [path]: methodApis
1428
- };
1429
- }, {});
1430
- return {
1431
- enums: Base.uniqueEnums(enums),
1432
- schemas: definitions_,
1433
- responses: responses_,
1434
- parameters: {},
1435
- requestBodies: {},
1436
- apis
1437
- };
1183
+ //#region src/core/logger.ts
1184
+ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
1185
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
1186
+ const red = (s) => `\x1b[31m${s}\x1b[0m`;
1187
+ const blue = (s) => `\x1b[34m${s}\x1b[0m`;
1188
+ const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
1189
+ const magenta = (s) => `\x1b[35m${s}\x1b[0m`;
1190
+ const gray = (s) => `\x1b[90m${s}\x1b[0m`;
1191
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
1192
+ const logger = {
1193
+ success(msg) {
1194
+ console.log(`${green("")} ${msg}`);
1195
+ },
1196
+ error(err, verbose = false) {
1197
+ if (isApicodegenError(err)) console.error(`${red("✗")} ${err.toString(verbose)}`);
1198
+ else if (err instanceof Error) {
1199
+ const msg = `Error: ${err.message}`;
1200
+ console.error(`${red("✗")} ${msg}${verbose && err.stack ? `\n${gray(err.stack)}` : ""}`);
1201
+ } else console.error(`${red("✗")} ${String(err)}`);
1202
+ },
1203
+ info(msg) {
1204
+ console.log(`${blue("ℹ")} ${msg}`);
1205
+ },
1206
+ warn(msg) {
1207
+ console.log(`${yellow("⚠")} ${msg}`);
1208
+ },
1209
+ loading(msg) {
1210
+ console.log(`${yellow("🔄")} ${msg}`);
1211
+ },
1212
+ watching(msg) {
1213
+ console.log(`${magenta("⟳")} ${msg}`);
1214
+ },
1215
+ fileChange(filePath) {
1216
+ console.log(`${yellow("↓")} ${filePath}`);
1217
+ },
1218
+ fileAdd(filePath) {
1219
+ console.log(`${green("+")} ${filePath}`);
1220
+ },
1221
+ shutdown() {
1222
+ console.log(`\n${gray("👋 Shutting down...")}`);
1223
+ },
1224
+ divider(width = 50) {
1225
+ console.log(`${bold(cyan("─".repeat(width)))}`);
1226
+ },
1227
+ heading(text, mode, width = 50) {
1228
+ console.log(`${bold(cyan("─".repeat(width)))}`);
1229
+ console.log(`${bold(cyan(text))}`);
1230
+ console.log(`${gray("Mode:")} ${mode || "unknown"}`);
1231
+ console.log(`${bold(cyan("─".repeat(width)))}`);
1232
+ },
1233
+ item(label, color = "green") {
1234
+ const icon = color === "green" ? "✓" : color === "red" ? "✗" : "⚠";
1235
+ console.log(`${color === "green" ? green(icon) : color === "red" ? red(icon) : yellow(icon)} ${label}`);
1236
+ },
1237
+ summary(stats) {
1238
+ const { succeeded, failed, endpoints, schemas, duration } = stats;
1239
+ const label = `API Code Gen - Complete (${succeeded} succeeded${failed > 0 ? `, ${failed} failed` : ""}, ${endpoints} endpoints, ${schemas} schemas, ${duration}ms)`;
1240
+ if (failed === 0) console.log(`${green("✓")} ${label}`);
1241
+ else console.log(`${yellow("")} ${label}`);
1438
1242
  }
1439
1243
  };
1440
1244
  //#endregion
1441
- //#region src/openapi/V3.ts
1442
- var V3 = class {
1443
- doc;
1444
- constructor(doc) {
1445
- this.doc = doc;
1446
- }
1245
+ //#region src/openapi/VersionedProvider.ts
1246
+ /**
1247
+ * Abstract base class. Subclasses implement the four container accessors
1248
+ * and a version tag. The shared logic lives here.
1249
+ */
1250
+ var VersionedProvider = class {
1447
1251
  /**
1448
1252
  * Resolves a path $ref to the actual path object.
1449
1253
  */
@@ -1455,28 +1259,37 @@ var V3 = class {
1455
1259
  * Is array schema.
1456
1260
  */
1457
1261
  isOpenAPIArraySchema(schema) {
1458
- return typeof schema === "object" && schema.type === "array";
1262
+ return typeof schema === "object" && schema !== null && schema.type === "array";
1459
1263
  }
1460
1264
  /**
1461
- * OpenAPI schema to base schema.
1265
+ * OpenAPI schema to base schema. Override for version-specific quirks
1266
+ * (V3_1 throws on missing ref; V3 returns `{ type: 'unknown' }`).
1462
1267
  */
1463
1268
  getSchemaByRef(schema, reserveRef = false, enums = [], upLevelSchemaKey = "") {
1464
1269
  let refName = "";
1465
1270
  if (Base.isRef(schema)) {
1466
- refName = Base.capitalize(Base.ref2name(schema.$ref));
1271
+ refName = this.formatRefName(Base.ref2name(schema.$ref));
1467
1272
  if (reserveRef) return { type: upLevelSchemaKey + refName };
1468
- const resolvedSchema = this.doc.components?.schemas?.[Base.ref2name(schema.$ref, this.doc)];
1273
+ const resolvedSchema = this.getSchemaContainer()?.[Base.ref2name(schema.$ref, this.doc)];
1469
1274
  if (!resolvedSchema) return { type: "unknown" };
1470
1275
  schema = resolvedSchema;
1471
1276
  }
1472
1277
  return this.toBaseSchema(schema, enums, "", upLevelSchemaKey + refName);
1473
1278
  }
1474
1279
  /**
1475
- * OpenAPI parameter to base parameter.
1280
+ * Format a ref name for the schema's `type` field.
1281
+ * V3 uses `capitalize`; V3_1 uses `upperCamelCase` (preserved for compat).
1282
+ */
1283
+ formatRefName(name) {
1284
+ return Base.capitalize(name);
1285
+ }
1286
+ /**
1287
+ * OpenAPI parameter to base parameter. Override in V2 — its parameter
1288
+ * shape is structurally different (top-level `items`/`properties`/`enum`).
1476
1289
  */
1477
1290
  getParameterByRef(schema, enums = [], upLevelSchemaKey = "") {
1478
1291
  if (Base.isRef(schema)) {
1479
- const resolvedSchema = this.doc.components?.parameters?.[Base.ref2name(schema.$ref, this.doc)];
1292
+ const resolvedSchema = this.getParameterContainer()?.[Base.ref2name(schema.$ref, this.doc)];
1480
1293
  if (!resolvedSchema) return {
1481
1294
  name: "unknown",
1482
1295
  in: "query"
@@ -1507,37 +1320,38 @@ var V3 = class {
1507
1320
  description,
1508
1321
  deprecated,
1509
1322
  in: schema.in,
1510
- schema: schema.schema && this.getSchemaByRef(schema.schema, false, enums, upLevelSchemaKey + Base.capitalize(name))
1323
+ schema: schema.schema ? this.getSchemaByRef(schema.schema, false, enums, upLevelSchemaKey + Base.capitalize(name)) : void 0
1511
1324
  };
1512
1325
  }
1513
1326
  /**
1514
- * OpenAPI schema to base response
1327
+ * OpenAPI schema to base response. Override in V2 (its response shape
1328
+ * lacks the `content` wrapper).
1515
1329
  */
1516
1330
  getResponseByRef(schema) {
1517
1331
  if (Base.isRef(schema)) {
1518
- const resolvedSchema = this.doc.components?.responses?.[Base.ref2name(schema.$ref, this.doc)];
1332
+ const resolvedSchema = this.getResponseContainer()?.[Base.ref2name(schema.$ref, this.doc)];
1519
1333
  if (!resolvedSchema) return [];
1520
1334
  schema = resolvedSchema;
1521
1335
  }
1522
1336
  const { content = {} } = schema;
1523
1337
  return Object.keys(content).map((c) => ({
1524
1338
  type: c,
1525
- schema: content[c].schema && this.getSchemaByRef(content[c].schema, true)
1339
+ schema: content[c].schema ? this.getSchemaByRef(content[c].schema, true) : void 0
1526
1340
  }));
1527
1341
  }
1528
1342
  /**
1529
- * OpenAPI schema to requestBody.
1343
+ * OpenAPI schema to requestBody. V2 has no requestBody concept.
1530
1344
  */
1531
1345
  getRequestBodyByRef(schema, enums = []) {
1532
1346
  if (Base.isRef(schema)) {
1533
- const resolvedSchema = this.doc.components?.requestBodies?.[Base.ref2name(schema.$ref, this.doc)];
1347
+ const resolvedSchema = this.getRequestBodyContainer()?.[Base.ref2name(schema.$ref, this.doc)];
1534
1348
  if (!resolvedSchema) return [];
1535
1349
  schema = resolvedSchema;
1536
1350
  }
1537
1351
  const { content = {} } = schema;
1538
1352
  return Object.keys(content).map((c) => ({
1539
1353
  type: c,
1540
- schema: content[c].schema && this.getSchemaByRef(content[c].schema, false, enums)
1354
+ schema: content[c].schema ? this.getSchemaByRef(content[c].schema, false, enums) : void 0
1541
1355
  }));
1542
1356
  }
1543
1357
  /**
@@ -1548,92 +1362,98 @@ var V3 = class {
1548
1362
  if (Base.isRef(schema)) return this.getSchemaByRef(schema, true);
1549
1363
  if (this.isOpenAPIArraySchema(schema)) {
1550
1364
  const { type, description, items, required } = schema;
1365
+ const itemsSchema = items ? this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey) : { type: "unknown" };
1551
1366
  return {
1552
1367
  type,
1553
1368
  required: !!required,
1554
1369
  description,
1555
- items: this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey)
1370
+ items: itemsSchema
1556
1371
  };
1557
- } else {
1558
- const { required = [], allOf, anyOf, description, deprecated, enum: enum_, format, oneOf, properties = {} } = schema;
1559
- let { type } = schema;
1560
- if (enum_ && type !== "boolean") {
1561
- const enumObject = {
1562
- name: Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(schemaKey)),
1563
- enum: [...new Set(enum_)]
1564
- };
1565
- const sameObject = Base.findSameSchema(enumObject, enums);
1566
- if (!sameObject && Base.isValidEnumType(schema)) enums.push(enumObject);
1567
- return {
1568
- type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
1569
- required,
1570
- description,
1571
- deprecated
1572
- };
1573
- }
1574
- if (type === void 0 && Object.keys(properties).length > 0) type = "object";
1372
+ }
1373
+ const { required = [], allOf, anyOf, description, deprecated, enum: enum_, format, oneOf, properties = {} } = schema;
1374
+ let { type } = schema;
1375
+ if (enum_ && type !== "boolean") {
1376
+ const enumObject = {
1377
+ name: Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(schemaKey)),
1378
+ enum: [...new Set(enum_)]
1379
+ };
1380
+ const sameObject = Base.findSameSchema(enumObject, enums);
1381
+ if (!sameObject && Base.isValidEnumType(schema)) enums.push(enumObject);
1575
1382
  return {
1576
- type,
1383
+ type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
1577
1384
  required,
1578
1385
  description,
1579
- deprecated,
1580
- enum: enum_,
1581
- format,
1582
- allOf: allOf?.map((s) => Base.isRef(s) ? {
1583
- ...s,
1584
- ref: s.$ref,
1585
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1586
- } : this.toBaseSchema(s, enums)),
1587
- anyOf: anyOf?.map((s) => Base.isRef(s) ? {
1588
- ...s,
1589
- ref: s.$ref,
1590
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1591
- } : this.toBaseSchema(s, enums)),
1592
- oneOf: oneOf?.map((s) => Base.isRef(s) ? {
1593
- ...s,
1594
- ref: s.$ref,
1595
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1596
- } : this.toBaseSchema(s, enums)),
1597
- properties: Object.keys(properties).reduce((acc, p) => {
1598
- const propSchema = properties[p];
1599
- return {
1600
- ...acc,
1601
- [p]: Base.isRef(propSchema) ? {
1602
- type: Base.capitalize(Base.ref2name(propSchema.$ref, this.doc)),
1603
- isRef: true
1604
- } : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
1605
- };
1606
- }, {})
1386
+ deprecated
1607
1387
  };
1608
1388
  }
1389
+ if (type === void 0 && Object.keys(properties).length > 0) type = "object";
1390
+ return {
1391
+ type,
1392
+ required,
1393
+ description,
1394
+ deprecated,
1395
+ enum: enum_,
1396
+ format,
1397
+ allOf: allOf?.map((s) => Base.isRef(s) ? {
1398
+ ...s,
1399
+ ref: s.$ref,
1400
+ type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1401
+ } : this.toBaseSchema(s, enums)),
1402
+ anyOf: anyOf?.map((s) => Base.isRef(s) ? {
1403
+ ...s,
1404
+ ref: s.$ref,
1405
+ type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1406
+ } : this.toBaseSchema(s, enums)),
1407
+ oneOf: oneOf?.map((s) => Base.isRef(s) ? {
1408
+ ...s,
1409
+ ref: s.$ref,
1410
+ type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1411
+ } : this.toBaseSchema(s, enums)),
1412
+ properties: Object.keys(properties).reduce((acc, p) => {
1413
+ const propSchema = properties[p];
1414
+ return {
1415
+ ...acc,
1416
+ [p]: Base.isRef(propSchema) ? {
1417
+ type: Base.capitalize(Base.ref2name(propSchema.$ref, this.doc)),
1418
+ isRef: true
1419
+ } : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
1420
+ };
1421
+ }, {})
1422
+ };
1609
1423
  }
1424
+ /**
1425
+ * Run the parsing pipeline and return a ProviderInitResult.
1426
+ */
1610
1427
  init() {
1611
- const { components = {}, paths = {} } = this.doc;
1428
+ const { paths = {} } = this.doc;
1612
1429
  const enums = [];
1613
- const { requestBodies = {}, responses = {}, parameters = {}, schemas = {} } = components;
1614
- const schemas_ = Object.keys(schemas).reduce((acc, key) => {
1615
- const schema = schemas[key];
1430
+ const schemaContainer = this.getSchemaContainer() ?? {};
1431
+ const parameterContainer = this.getParameterContainer() ?? {};
1432
+ const responseContainer = this.getResponseContainer() ?? {};
1433
+ const requestBodyContainer = this.getRequestBodyContainer() ?? {};
1434
+ const schemas_ = Object.keys(schemaContainer).reduce((acc, key) => {
1435
+ const schema = schemaContainer[key];
1616
1436
  return {
1617
1437
  ...acc,
1618
1438
  [key]: this.getSchemaByRef(schema, false, enums, key)
1619
1439
  };
1620
1440
  }, {});
1621
- const parameters_ = Object.keys(parameters).reduce((acc, key) => {
1622
- const parameter = parameters[key];
1441
+ const parameters_ = Object.keys(parameterContainer).reduce((acc, key) => {
1442
+ const parameter = parameterContainer[key];
1623
1443
  return {
1624
1444
  ...acc,
1625
1445
  [key]: this.getParameterByRef(parameter, enums, key)
1626
1446
  };
1627
1447
  }, {});
1628
- const responses_ = Object.keys(responses).reduce((acc, key) => {
1629
- const response = responses[key];
1448
+ const responses_ = Object.keys(responseContainer).reduce((acc, key) => {
1449
+ const response = responseContainer[key];
1630
1450
  return {
1631
1451
  ...acc,
1632
1452
  [key]: this.getResponseByRef(response)
1633
1453
  };
1634
1454
  }, {});
1635
- const requestBodies_ = Object.keys(requestBodies).reduce((acc, key) => {
1636
- const requestBody = requestBodies[key];
1455
+ const requestBodies_ = Object.keys(requestBodyContainer).reduce((acc, key) => {
1456
+ const requestBody = requestBodyContainer[key];
1637
1457
  return {
1638
1458
  ...acc,
1639
1459
  [key]: this.getRequestBodyByRef(requestBody, enums)
@@ -1650,15 +1470,16 @@ var V3 = class {
1650
1470
  Object.values(HttpMethods).forEach((method) => {
1651
1471
  const methodObject = pathObject[method];
1652
1472
  if (methodObject) {
1653
- const { deprecated, operationId, responses = {}, summary: summary_, description: description_, requestBody = { content: {} } } = methodObject;
1473
+ const { deprecated, operationId, responses, summary: summary_, description: description_, requestBody = { content: {} } } = methodObject;
1474
+ const responsesClone = responses ? { ...responses } : {};
1654
1475
  const { parameters: parameters_ = [] } = methodObject;
1655
1476
  const baseParameters = [...parameters, ...parameters_].map((parameter) => this.getParameterByRef(parameter, enums));
1656
1477
  const baseRequestBody = this.getRequestBodyByRef(requestBody, enums);
1657
1478
  const uniqueParameterName = [...new Set(baseParameters.map((p) => p.name))];
1658
- if (Object.keys(responses).length === 0) Object.assign(responses, { 200: { description: "Successful response" } });
1659
- const httpCodes = Object.keys(responses);
1660
- for (const code of httpCodes) if (code in responses) {
1661
- const response = responses[code];
1479
+ if (Object.keys(responsesClone).length === 0) responsesClone[200] = { description: "Successful response" };
1480
+ const httpCodes = Object.keys(responsesClone);
1481
+ for (const code of httpCodes) if (code in responsesClone) {
1482
+ const response = responsesClone[code];
1662
1483
  const responseSchema = this.getResponseByRef(response);
1663
1484
  methodApis.push({
1664
1485
  method,
@@ -1690,244 +1511,246 @@ var V3 = class {
1690
1511
  }
1691
1512
  };
1692
1513
  //#endregion
1693
- //#region src/openapi/V3_1.ts
1694
- var V3_1 = class {
1514
+ //#region src/openapi/V2.ts
1515
+ var V2 = class extends VersionedProvider {
1695
1516
  doc;
1517
+ version = "v2";
1696
1518
  constructor(doc) {
1519
+ super();
1697
1520
  this.doc = doc;
1698
1521
  }
1699
- /**
1700
- * Resolves a path $ref to the actual path object.
1701
- */
1702
- resolvePathRef($ref) {
1703
- const refName = Base.ref2name($ref, this.doc);
1704
- return this.doc.paths?.[refName];
1522
+ getSchemaContainer() {
1523
+ return this.doc.definitions;
1705
1524
  }
1706
- /**
1707
- * Is array schema.
1708
- */
1709
- isOpenAPIArraySchema(schema) {
1710
- return typeof schema === "object" && schema.type === "array";
1525
+ getParameterContainer() {
1526
+ return this.doc.parameters;
1711
1527
  }
1712
- /**
1713
- * OpenAPI schema to base schema.
1714
- */
1715
- getSchemaByRef(schema, reserveRef = false, enums = [], upLevelSchemaKey = "") {
1716
- let refName = "";
1717
- if (Base.isRef(schema)) {
1718
- refName = Base.upperCamelCase(Base.ref2name(schema.$ref));
1719
- if (reserveRef) return { type: upLevelSchemaKey + refName };
1720
- if (!this.doc.components) this.doc.components = { schemas: {} };
1721
- const resolvedSchema = this.doc.components.schemas?.[Base.ref2name(schema.$ref, this.doc)];
1722
- if (!resolvedSchema) throw new Error(`Schema reference not found: ${refName}`);
1723
- schema = resolvedSchema;
1724
- }
1725
- return this.toBaseSchema(schema, enums, "", upLevelSchemaKey + refName);
1528
+ getResponseContainer() {
1529
+ return this.doc.responses;
1726
1530
  }
1531
+ getRequestBodyContainer() {}
1727
1532
  /**
1728
- * OpenAPI parameter to base parameter.
1533
+ * V2 parameter shape differs from V3: top-level `items`/`properties`/`enum`
1534
+ * rather than nested under `schema`. Override accordingly.
1729
1535
  */
1730
- getParameterByRef(schema, enums = [], upLevelSchemaKey = "") {
1731
- if (Base.isRef(schema)) schema = this.doc.components?.parameters?.[Base.ref2name(schema.$ref, this.doc)];
1732
- const { name, required, deprecated, description, schema: parameterSchema } = schema;
1733
- if (parameterSchema && !Base.isRef(parameterSchema) && parameterSchema.enum) {
1734
- const type = Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(name));
1536
+ getParameterByRef(parameter, enums = [], upLevelSchemaKey = "") {
1537
+ if (Base.isRef(parameter)) {
1538
+ const refName = Base.ref2name(parameter.$ref, this.doc);
1539
+ const resolved = this.doc.parameters?.[refName];
1540
+ if (!resolved) throw new Error(`Parameter reference not found: ${parameter.$ref}`);
1541
+ parameter = resolved;
1542
+ }
1543
+ const p = parameter;
1544
+ const { name, required, description, type, items, enum: enum_, properties, schema } = p;
1545
+ if (enum_) {
1546
+ const enumType = Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(name));
1735
1547
  const enumSchema = {
1736
- name: type,
1737
- enum: [...new Set(parameterSchema.enum)]
1548
+ name: enumType,
1549
+ enum: [...new Set(enum_)]
1738
1550
  };
1739
1551
  const sameEnum = Base.findSameSchema(enumSchema, enums);
1740
- if (!sameEnum && Base.isValidEnumType(parameterSchema)) enums.push(enumSchema);
1552
+ if (!sameEnum && Base.isValidEnumType({
1553
+ type: enumType,
1554
+ enum: enum_
1555
+ })) enums.push(enumSchema);
1741
1556
  return {
1742
1557
  name,
1743
1558
  required,
1744
1559
  description,
1745
- deprecated,
1746
- in: schema.in,
1747
- schema: { type: sameEnum?.name ?? type }
1560
+ in: p.in,
1561
+ schema: { type: sameEnum?.name ?? enumType }
1748
1562
  };
1749
1563
  }
1564
+ if (items) return {
1565
+ name,
1566
+ required,
1567
+ description,
1568
+ in: p.in,
1569
+ schema: {
1570
+ type,
1571
+ items
1572
+ }
1573
+ };
1574
+ if (schema && Base.isRef(schema)) return {
1575
+ name,
1576
+ required,
1577
+ description,
1578
+ in: p.in,
1579
+ schema: { type: Base.capitalize(Base.ref2name(schema.$ref)) }
1580
+ };
1750
1581
  return {
1751
1582
  name,
1752
1583
  required,
1753
1584
  description,
1754
- deprecated,
1755
- in: schema.in,
1756
- schema: schema.schema && this.getSchemaByRef(schema.schema, false, enums, upLevelSchemaKey + Base.capitalize(name))
1585
+ in: p.in,
1586
+ schema: {
1587
+ type,
1588
+ properties
1589
+ }
1757
1590
  };
1758
1591
  }
1759
1592
  /**
1760
- * OpenAPI schema to base response
1593
+ * V2 response shape: a `schema` field directly, not `content`. V2 always
1594
+ * emits JSON.
1761
1595
  */
1762
1596
  getResponseByRef(schema) {
1763
- if (Base.isRef(schema)) schema = this.doc.components?.responses?.[Base.ref2name(schema.$ref, this.doc)];
1764
- const { content = {} } = schema;
1765
- return Object.keys(content).map((c) => ({
1766
- type: c,
1767
- schema: content[c].schema && this.getSchemaByRef(content[c].schema, true)
1768
- }));
1769
- }
1770
- /**
1771
- * OpenAPI schema to requestBody.
1772
- */
1773
- getRequestBodyByRef(schema, enums = []) {
1774
- if (Base.isRef(schema)) schema = this.doc.components?.requestBodies?.[Base.ref2name(schema.$ref, this.doc)];
1775
- const { content = {} } = schema;
1776
- return Object.keys(content).map((c) => ({
1777
- type: c,
1778
- schema: content[c].schema && this.getSchemaByRef(content[c].schema, true, enums)
1779
- }));
1597
+ if (Base.isRef(schema)) schema = this.doc.responses[Base.ref2name(schema.$ref, this.doc)];
1598
+ const { schema: responseSchema } = schema;
1599
+ return [{
1600
+ type: "application/json",
1601
+ schema: responseSchema ? this.getSchemaByRef(responseSchema, true) : void 0
1602
+ }];
1780
1603
  }
1781
1604
  /**
1782
- * Transform all OpenAPI schema to Base Schema
1605
+ * V2 has no `requestBody` concept; parameters with `in: body` or
1606
+ * `in: formData` are split out and turned into a synthetic requestBody
1607
+ * here. A single body param named `body` is used directly; otherwise
1608
+ * the body / formData params are wrapped in a synthetic object.
1783
1609
  */
1784
- toBaseSchema(schema, enums = [], schemaKey = "", upLevelSchemaKey = "") {
1785
- if (!schema) return { type: "unknown" };
1786
- if (Base.isRef(schema)) return this.getSchemaByRef(schema, true);
1787
- if (this.isOpenAPIArraySchema(schema)) {
1788
- const { type, description, items, required } = schema;
1789
- return {
1790
- type,
1791
- required: !!required,
1792
- description,
1793
- items: this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey)
1794
- };
1795
- } else {
1796
- const { required = [], allOf, anyOf, description, deprecated, enum: enum_, format, oneOf, properties = {} } = schema;
1797
- let { type } = schema;
1798
- if (enum_ && type !== "boolean") {
1799
- const enumObject = {
1800
- name: Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(schemaKey)),
1801
- enum: [...new Set(enum_)]
1802
- };
1803
- const sameObject = Base.findSameSchema(enumObject, enums);
1804
- if (!sameObject && Base.isValidEnumType(schema)) enums.push(enumObject);
1805
- return {
1806
- type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
1807
- required,
1808
- description,
1809
- deprecated
1810
- };
1811
- }
1812
- if (type === void 0 && Object.keys(properties).length > 0) type = "object";
1813
- return {
1814
- type,
1815
- required,
1816
- description,
1817
- deprecated,
1818
- enum: enum_,
1819
- format,
1820
- allOf: allOf?.map((s) => Base.isRef(s) ? {
1821
- ...s,
1822
- ref: s.$ref,
1823
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1824
- } : this.toBaseSchema(s, enums)),
1825
- anyOf: anyOf?.map((s) => Base.isRef(s) ? {
1826
- ...s,
1827
- ref: s.$ref,
1828
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1829
- } : this.toBaseSchema(s, enums)),
1830
- oneOf: oneOf?.map((s) => Base.isRef(s) ? {
1831
- ...s,
1832
- ref: s.$ref,
1833
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1834
- } : this.toBaseSchema(s, enums)),
1835
- properties: Object.keys(properties).reduce((acc, p) => {
1836
- const propSchema = properties[p];
1837
- return {
1838
- ...acc,
1839
- [p]: Base.isRef(propSchema) ? {
1840
- type: Base.capitalize(Base.ref2name(propSchema.$ref, this.doc)),
1841
- isRef: true
1842
- } : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
1843
- };
1844
- }, {})
1845
- };
1846
- }
1847
- }
1848
1610
  init() {
1849
- const { components = {}, paths = {} } = this.doc;
1611
+ const { paths = {} } = this.doc;
1850
1612
  const enums = [];
1851
- const { requestBodies = {}, responses = {}, parameters = {}, schemas = {} } = components;
1852
- const schemas_ = Object.keys(schemas).reduce((acc, key) => {
1853
- const schema = schemas[key];
1613
+ const schemaContainer = this.getSchemaContainer() ?? {};
1614
+ const parameterContainer = this.getParameterContainer() ?? {};
1615
+ const responseContainer = this.getResponseContainer() ?? {};
1616
+ const schemas_ = Object.keys(schemaContainer).reduce((acc, key) => {
1617
+ const schema = schemaContainer[key];
1854
1618
  return {
1855
1619
  ...acc,
1856
1620
  [key]: this.getSchemaByRef(schema, false, enums, key)
1857
1621
  };
1858
1622
  }, {});
1859
- const parameters_ = Object.keys(parameters).reduce((acc, key) => {
1860
- const parameter = parameters[key];
1623
+ const parameters_ = Object.keys(parameterContainer).reduce((acc, key) => {
1624
+ const parameter = parameterContainer[key];
1861
1625
  return {
1862
1626
  ...acc,
1863
1627
  [key]: this.getParameterByRef(parameter, enums, key)
1864
1628
  };
1865
1629
  }, {});
1866
- const responses_ = Object.keys(responses).reduce((acc, key) => {
1867
- const response = responses[key];
1630
+ const responses_ = Object.keys(responseContainer).reduce((acc, key) => {
1631
+ const response = responseContainer[key];
1868
1632
  return {
1869
1633
  ...acc,
1870
1634
  [key]: this.getResponseByRef(response)
1871
1635
  };
1872
1636
  }, {});
1873
- const requestBodies_ = Object.keys(requestBodies).reduce((acc, key) => {
1874
- const requestBody = requestBodies[key];
1875
- return {
1876
- ...acc,
1877
- [key]: this.getRequestBodyByRef(requestBody, enums)
1878
- };
1879
- }, {});
1880
- const apis = Object.keys(paths).reduce((acc, path) => {
1637
+ const apis = {};
1638
+ for (const path of Object.keys(paths)) {
1881
1639
  let pathObject = paths[path] ?? {};
1882
1640
  if (pathObject.$ref) {
1883
1641
  const resolved = this.resolvePathRef(pathObject.$ref);
1884
1642
  if (resolved) pathObject = resolved;
1885
1643
  }
1886
- const { parameters = [], description, summary } = pathObject;
1644
+ const { parameters = [] } = pathObject;
1887
1645
  const methodApis = [];
1888
1646
  Object.values(HttpMethods).forEach((method) => {
1889
1647
  const methodObject = pathObject[method];
1890
- if (methodObject) {
1891
- const { deprecated, operationId, summary: summary_, description: description_, responses = {}, requestBody = { content: {} } } = methodObject;
1892
- const { parameters: parameters_ = [] } = methodObject;
1893
- const baseParameters = [...parameters, ...parameters_].map((parameter) => this.getParameterByRef(parameter, enums));
1894
- const baseRequestBody = this.getRequestBodyByRef(requestBody, enums);
1895
- const uniqueParameterName = [...new Set(baseParameters.map((p) => p.name))];
1896
- if (Object.keys(responses).length === 0) Object.assign(responses, { 200: { description: "Successful response" } });
1897
- const httpCodes = Object.keys(responses);
1898
- for (const code of httpCodes) if (code in responses) {
1899
- const response = responses[code];
1900
- const responseSchema = this.getResponseByRef(response);
1901
- methodApis.push({
1902
- method,
1903
- operationId,
1904
- summary: summary_ ?? summary,
1905
- description: description_ ?? description,
1906
- deprecated,
1907
- parameters: uniqueParameterName.map((name) => baseParameters.find((p) => p.name === name)).filter((p) => p !== void 0),
1908
- responses: responseSchema,
1909
- requestBody: baseRequestBody
1910
- });
1911
- break;
1912
- }
1648
+ if (!methodObject) return;
1649
+ const { deprecated, operationId, summary: summary_, description: description_, responses } = methodObject;
1650
+ const { parameters: parameters_ = [] } = methodObject;
1651
+ const baseParameters = [...parameters, ...parameters_].map((p) => this.getParameterByRef(p, enums));
1652
+ const uniqueParameterName = [...new Set(baseParameters.map((p) => p.name))];
1653
+ const responsesClone = responses ? { ...responses } : {};
1654
+ if (Object.keys(responsesClone).length === 0) responsesClone[200] = { description: "Successful response" };
1655
+ const inBody = baseParameters.filter((p) => p.in === "body" || p.in === "formData");
1656
+ const notInBody = baseParameters.filter((p) => p.in !== "body" && p.in !== "formData");
1657
+ const httpCodes = Object.keys(responsesClone);
1658
+ for (const code of httpCodes) if (code in responsesClone) {
1659
+ const response = responsesClone[code];
1660
+ const responseSchema = this.getResponseByRef(response);
1661
+ const inBodyOnlyHasBody = inBody.length === 1 && inBody[0].in === "body" && inBody[0].name === "body";
1662
+ methodApis.push({
1663
+ method,
1664
+ operationId,
1665
+ summary: summary_,
1666
+ deprecated,
1667
+ description: description_,
1668
+ parameters: uniqueParameterName.map((name) => notInBody.find((p) => p.name === name)).filter((p) => p !== void 0),
1669
+ responses: responseSchema,
1670
+ requestBody: inBody.length > 0 ? inBodyOnlyHasBody ? [{
1671
+ type: "application/json",
1672
+ schema: inBody[0].schema
1673
+ }] : [{
1674
+ type: "application/json",
1675
+ schema: {
1676
+ type: "object",
1677
+ properties: inBody.reduce((a, p) => {
1678
+ return {
1679
+ ...a,
1680
+ [p.name]: {
1681
+ type: p.schema?.type ?? "unknown",
1682
+ required: p.schema?.required,
1683
+ items: p.schema?.items,
1684
+ description: p.schema?.description
1685
+ }
1686
+ };
1687
+ }, {})
1688
+ }
1689
+ }] : void 0
1690
+ });
1691
+ break;
1913
1692
  }
1914
1693
  });
1915
- return {
1916
- ...acc,
1917
- [path]: methodApis
1918
- };
1919
- }, {});
1694
+ apis[path] = methodApis;
1695
+ }
1920
1696
  return {
1921
1697
  enums: Base.uniqueEnums(enums),
1922
1698
  schemas: schemas_,
1923
1699
  responses: responses_,
1924
1700
  parameters: parameters_,
1925
- requestBodies: requestBodies_,
1701
+ requestBodies: {},
1926
1702
  apis
1927
1703
  };
1928
1704
  }
1929
1705
  };
1930
1706
  //#endregion
1707
+ //#region src/openapi/V3.ts
1708
+ var V3 = class extends VersionedProvider {
1709
+ doc;
1710
+ version = "v3";
1711
+ constructor(doc) {
1712
+ super();
1713
+ this.doc = doc;
1714
+ }
1715
+ getSchemaContainer() {
1716
+ return this.doc.components?.schemas;
1717
+ }
1718
+ getParameterContainer() {
1719
+ return this.doc.components?.parameters;
1720
+ }
1721
+ getResponseContainer() {
1722
+ return this.doc.components?.responses;
1723
+ }
1724
+ getRequestBodyContainer() {
1725
+ return this.doc.components?.requestBodies;
1726
+ }
1727
+ };
1728
+ //#endregion
1729
+ //#region src/openapi/V3_1.ts
1730
+ var V3_1 = class extends VersionedProvider {
1731
+ doc;
1732
+ version = "v3_1";
1733
+ constructor(doc) {
1734
+ super();
1735
+ this.doc = doc;
1736
+ }
1737
+ formatRefName(name) {
1738
+ return Base.upperCamelCase(name);
1739
+ }
1740
+ getSchemaContainer() {
1741
+ return this.doc.components?.schemas;
1742
+ }
1743
+ getParameterContainer() {
1744
+ return this.doc.components?.parameters;
1745
+ }
1746
+ getResponseContainer() {
1747
+ return this.doc.components?.responses;
1748
+ }
1749
+ getRequestBodyContainer() {
1750
+ return this.doc.components?.requestBodies;
1751
+ }
1752
+ };
1753
+ //#endregion
1931
1754
  //#region src/openapi/index.ts
1932
1755
  const logger$1 = createScopedLogger("OpenAPI");
1933
1756
  let OpenAPIVersion = /* @__PURE__ */ function(OpenAPIVersion) {
@@ -1993,7 +1816,7 @@ async function codeGen(initOptions) {
1993
1816
  //#endregion
1994
1817
  //#region src/vite-plugin/index.ts
1995
1818
  const PLUGIN_NAME = "api-code-gen";
1996
- const logger = createScopedLogger("api-code-gen");
1819
+ const pluginLogger = createScopedLogger("api-code-gen");
1997
1820
  /**
1998
1821
  * Run TypeScript type checking on generated file
1999
1822
  */
@@ -2022,7 +1845,7 @@ async function validateSpecPath(specPath) {
2022
1845
  async function generateForOption(option) {
2023
1846
  const { name, typeCheck = true, verbose, ...restOptions } = option;
2024
1847
  try {
2025
- console.log(`\x1b[36m├─\x1b[0m ${name}`);
1848
+ logger.info(`Generating ${name}...`);
2026
1849
  const config = await loadConfig({
2027
1850
  name,
2028
1851
  cliOptions: {
@@ -2046,8 +1869,8 @@ async function generateForOption(option) {
2046
1869
  if (typeCheck && config.output) {
2047
1870
  const typeErrors = await runTypeCheck(config.output);
2048
1871
  if (typeErrors.length > 0) {
2049
- logger.warn(`Type check failed for ${config.output}`);
2050
- if (verbose) for (const error of typeErrors) logger.warn(` ${error}`);
1872
+ pluginLogger.warn(`Type check failed for ${config.output}`);
1873
+ if (verbose) for (const error of typeErrors) pluginLogger.warn(` ${error}`);
2051
1874
  }
2052
1875
  }
2053
1876
  return {
@@ -2088,50 +1911,52 @@ async function generateForOption(option) {
2088
1911
  */
2089
1912
  function apiCodeGenPlugin(options) {
2090
1913
  if (!Array.isArray(options) || options.length === 0) {
2091
- logger.warn("No API configurations provided to apiCodeGenPlugin");
1914
+ pluginLogger.warn("No API configurations provided to apiCodeGenPlugin");
2092
1915
  return { name: PLUGIN_NAME };
2093
1916
  }
2094
1917
  return {
2095
1918
  name: PLUGIN_NAME,
2096
1919
  async config(_config, env) {
2097
- console.log(`\x1b[1m\x1b[36m${"".repeat(50)}\x1b[0m`);
2098
- console.log(`\x1b[1m\x1b[36mAPI Code Gen\x1b[0m`);
2099
- console.log(`\x1b[90mMode:\x1b[0m ${env?.command || "unknown"}`);
2100
- console.log(`\x1b[1m\x1b[36m${"─".repeat(50)}\x1b[0m`);
1920
+ logger.heading("API Code Gen", env?.command);
2101
1921
  const results = await Promise.all(options.map(generateForOption));
2102
1922
  const successCount = results.filter((r) => r.success).length;
2103
1923
  const failCount = options.length - successCount;
2104
- console.log(`\x1b[1m\x1b[36m${"─".repeat(50)}\x1b[0m`);
1924
+ logger.divider();
2105
1925
  for (const result of results) if (result.success) {
2106
1926
  const { name, output, stats } = result;
2107
- if (stats) console.log(`\x1b[32m✓\x1b[0m ${name} → ${output} (${stats.endpoints} endpoints, ${stats.schemas} schemas) ${stats.duration}ms`);
2108
- else console.log(`\x1b[32m✓\x1b[0m ${name} → ${output || "N/A"}`);
1927
+ if (stats) logger.item(`${name} → ${output} (${stats.endpoints} endpoints, ${stats.schemas} schemas) ${stats.duration}ms`, "green");
1928
+ else logger.item(`${name} → ${output || "N/A"}`, "green");
2109
1929
  } else {
2110
1930
  const { name, error } = result;
2111
1931
  if (isApicodegenError(error)) {
2112
- console.log(`\x1b[31m✗\x1b[0m ${name}`);
2113
- console.log(`\x1b[90m${formatError(error, true)}\x1b[0m`);
1932
+ logger.item(name, "red");
1933
+ logger.error(error, true);
2114
1934
  } else {
2115
1935
  const wrapped = wrapError(error, {
2116
- code: "E_GENERATION_FAILED",
1936
+ code: ErrorCodes.GENERATION_FAILED,
2117
1937
  message: `Failed to generate API "${name}"`
2118
1938
  });
2119
- console.log(`\x1b[31m✗\x1b[0m ${name}`);
2120
- console.log(`\x1b[90m${formatError(wrapped, true)}\x1b[0m`);
1939
+ logger.item(name, "red");
1940
+ logger.error(wrapped, true);
2121
1941
  }
2122
1942
  }
2123
- console.log(`\x1b[1m\x1b[36m${"─".repeat(50)}\x1b[0m`);
1943
+ logger.divider();
2124
1944
  const totalDuration = results.reduce((sum, r) => sum + (r.stats?.duration || 0), 0);
2125
1945
  const totalEndpoints = results.reduce((sum, r) => sum + (r.stats?.endpoints || 0), 0);
2126
1946
  const totalSchemas = results.reduce((sum, r) => sum + (r.stats?.schemas || 0), 0);
2127
- if (failCount === 0) console.log(`\x1b[32m✓\x1b[0m API Code Gen - Complete (\x1b[90m${successCount}/${options.length} succeeded\x1b[0m, ${totalEndpoints} endpoints, ${totalSchemas} schemas, ${totalDuration}ms\x1b[0m)`);
2128
- else console.log(`\x1b[33m⚠\x1b[0m API Code Gen - Complete (\x1b[90m${successCount} succeeded, ${failCount} failed\x1b[0m, ${totalEndpoints} endpoints, ${totalSchemas} schemas, ${totalDuration}ms\x1b[0m)`);
2129
- console.log(`\x1b[1m\x1b[36m${"─".repeat(50)}\x1b[0m`);
1947
+ logger.summary({
1948
+ succeeded: successCount,
1949
+ failed: failCount,
1950
+ endpoints: totalEndpoints,
1951
+ schemas: totalSchemas,
1952
+ duration: totalDuration
1953
+ });
1954
+ logger.divider();
2130
1955
  return {};
2131
1956
  }
2132
1957
  };
2133
1958
  }
2134
1959
  //#endregion
2135
- export { Adapter, Adaptors, ApicodegenError, ArraySchemaType, AxiosAdapter, Base, Colors, ErrorCodes, FetchAdapter, Generator, HttpMethods, MediaTypes, NonArraySchemaType, OpenAPIProvider, OpenAPIVersion, ParameterIn, Provider, SchemaFormatType, SchemaType, SuccessHttpStatusCode, apiCodeGenPlugin, codeGen, configToCLIOptions, createErrors, formatError, isApicodegenError, loadConfig, printError, toProviderOptions, wrapError };
1960
+ export { Adapter, Adaptors, ApicodegenError, ArraySchemaType, AxiosAdapter, Base, Colors, ErrorCodes, FetchAdapter, Generator, HttpMethods, MediaTypes, NonArraySchemaType, OpenAPIProvider, OpenAPIVersion, ParameterIn, Provider, SchemaFormatType, SchemaType, SuccessHttpStatusCode, apiCodeGenPlugin, codeGen, createErrors, formatError, isApicodegenError, loadConfig, logger, printError, toProviderOptions, wrapError };
2136
1961
 
2137
1962
  //# sourceMappingURL=index.mjs.map