@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.
@@ -240,29 +240,6 @@ var ApicodegenError = class ApicodegenError extends Error {
240
240
  }
241
241
  };
242
242
  /**
243
- * ANSI color codes for terminal output
244
- */
245
- const Colors = {
246
- reset: "\x1B[0m",
247
- bold: "\x1B[1m",
248
- red: "\x1B[31m",
249
- green: "\x1B[32m",
250
- yellow: "\x1B[33m",
251
- blue: "\x1B[34m",
252
- cyan: "\x1B[36m",
253
- gray: "\x1B[90m",
254
- brightRed: "\x1B[91m",
255
- brightGreen: "\x1B[92m"
256
- };
257
- /**
258
- * Format error for CLI output
259
- */
260
- function formatError(error, verbose = false) {
261
- if (error instanceof ApicodegenError) return error.toString(verbose);
262
- 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}` : ""}`;
263
- return `${Colors.red}${Colors.bold}Error${Colors.reset}: ${String(error)}`;
264
- }
265
- /**
266
243
  * Create error with common patterns
267
244
  */
268
245
  const createErrors = {
@@ -399,6 +376,68 @@ function isApicodegenError(error) {
399
376
  return error instanceof ApicodegenError;
400
377
  }
401
378
  //#endregion
379
+ //#region src/core/logger.ts
380
+ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
381
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
382
+ const red = (s) => `\x1b[31m${s}\x1b[0m`;
383
+ const blue = (s) => `\x1b[34m${s}\x1b[0m`;
384
+ const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
385
+ const magenta = (s) => `\x1b[35m${s}\x1b[0m`;
386
+ const gray = (s) => `\x1b[90m${s}\x1b[0m`;
387
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
388
+ const logger$1 = {
389
+ success(msg) {
390
+ console.log(`${green("✓")} ${msg}`);
391
+ },
392
+ error(err, verbose = false) {
393
+ if (isApicodegenError(err)) console.error(`${red("✗")} ${err.toString(verbose)}`);
394
+ else if (err instanceof Error) {
395
+ const msg = `Error: ${err.message}`;
396
+ console.error(`${red("✗")} ${msg}${verbose && err.stack ? `\n${gray(err.stack)}` : ""}`);
397
+ } else console.error(`${red("✗")} ${String(err)}`);
398
+ },
399
+ info(msg) {
400
+ console.log(`${blue("ℹ")} ${msg}`);
401
+ },
402
+ warn(msg) {
403
+ console.log(`${yellow("⚠")} ${msg}`);
404
+ },
405
+ loading(msg) {
406
+ console.log(`${yellow("🔄")} ${msg}`);
407
+ },
408
+ watching(msg) {
409
+ console.log(`${magenta("⟳")} ${msg}`);
410
+ },
411
+ fileChange(filePath) {
412
+ console.log(`${yellow("↓")} ${filePath}`);
413
+ },
414
+ fileAdd(filePath) {
415
+ console.log(`${green("+")} ${filePath}`);
416
+ },
417
+ shutdown() {
418
+ console.log(`\n${gray("👋 Shutting down...")}`);
419
+ },
420
+ divider(width = 50) {
421
+ console.log(`${bold(cyan("─".repeat(width)))}`);
422
+ },
423
+ heading(text, mode, width = 50) {
424
+ console.log(`${bold(cyan("─".repeat(width)))}`);
425
+ console.log(`${bold(cyan(text))}`);
426
+ console.log(`${gray("Mode:")} ${mode || "unknown"}`);
427
+ console.log(`${bold(cyan("─".repeat(width)))}`);
428
+ },
429
+ item(label, color = "green") {
430
+ const icon = color === "green" ? "✓" : color === "red" ? "✗" : "⚠";
431
+ console.log(`${color === "green" ? green(icon) : color === "red" ? red(icon) : yellow(icon)} ${label}`);
432
+ },
433
+ summary(stats) {
434
+ const { succeeded, failed, endpoints, schemas, duration } = stats;
435
+ const label = `API Code Gen - Complete (${succeeded} succeeded${failed > 0 ? `, ${failed} failed` : ""}, ${endpoints} endpoints, ${schemas} schemas, ${duration}ms)`;
436
+ if (failed === 0) console.log(`${green("✓")} ${label}`);
437
+ else console.log(`${yellow("⚠")} ${label}`);
438
+ }
439
+ };
440
+ //#endregion
402
441
  //#region src/core/base/Adaptor.ts
403
442
  /**
404
443
  * Base adapter for tool
@@ -764,10 +803,19 @@ var Generator = class Generator {
764
803
  return createPrinter().printFile(sourceFile);
765
804
  }
766
805
  static async write(code, filepath) {
806
+ const { mkdir } = await import("node:fs/promises");
807
+ const { dirname } = await import("node:path");
767
808
  try {
809
+ await mkdir(dirname(filepath), { recursive: true });
768
810
  await writeFile(filepath, code);
769
811
  } catch (error) {
770
- console.error(error);
812
+ throw new ApicodegenError({
813
+ code: ErrorCodes.OUTPUT_DIR_MISSING,
814
+ message: "Failed to write generated code to output file",
815
+ location: filepath,
816
+ cause: error instanceof Error ? error : new Error(String(error)),
817
+ suggestions: ["Verify the output directory path is writable", "Check that the parent directory exists or can be created"]
818
+ });
771
819
  }
772
820
  }
773
821
  /**
@@ -1104,12 +1152,12 @@ var FetchAdapter = class extends Adapter {
1104
1152
  }
1105
1153
  };
1106
1154
  //#endregion
1107
- //#region src/openapi/V2.ts
1108
- var V2 = class {
1109
- doc;
1110
- constructor(doc) {
1111
- this.doc = doc;
1112
- }
1155
+ //#region src/openapi/VersionedProvider.ts
1156
+ /**
1157
+ * Abstract base class. Subclasses implement the four container accessors
1158
+ * and a version tag. The shared logic lives here.
1159
+ */
1160
+ var VersionedProvider = class {
1113
1161
  /**
1114
1162
  * Resolves a path $ref to the actual path object.
1115
1163
  */
@@ -1121,281 +1169,37 @@ var V2 = class {
1121
1169
  * Is array schema.
1122
1170
  */
1123
1171
  isOpenAPIArraySchema(schema) {
1124
- return typeof schema === "object" && schema.type === "array";
1172
+ return typeof schema === "object" && schema !== null && schema.type === "array";
1125
1173
  }
1126
1174
  /**
1127
- * OpenAPI schema to base schema.
1175
+ * OpenAPI schema to base schema. Override for version-specific quirks
1176
+ * (V3_1 throws on missing ref; V3 returns `{ type: 'unknown' }`).
1128
1177
  */
1129
1178
  getSchemaByRef(schema, reserveRef = false, enums = [], upLevelSchemaKey = "") {
1130
1179
  let refName = "";
1131
1180
  if (Base.isRef(schema)) {
1132
- refName = Base.upperCamelCase(Base.ref2name(schema.$ref));
1181
+ refName = this.formatRefName(Base.ref2name(schema.$ref));
1133
1182
  if (reserveRef) return { type: upLevelSchemaKey + refName };
1134
- if (!this.doc.definitions) this.doc.definitions = {};
1135
- schema = this.doc.definitions[Base.ref2name(schema.$ref, this.doc)];
1183
+ const resolvedSchema = this.getSchemaContainer()?.[Base.ref2name(schema.$ref, this.doc)];
1184
+ if (!resolvedSchema) return { type: "unknown" };
1185
+ schema = resolvedSchema;
1136
1186
  }
1137
1187
  return this.toBaseSchema(schema, enums, "", upLevelSchemaKey + refName);
1138
1188
  }
1139
1189
  /**
1140
- * Transform all OpenAPI schema to Base Schema
1141
- */
1142
- toBaseSchema(schema, enums = [], schemaKey = "", upLevelSchemaKey = "") {
1143
- if (!schema) return { type: "unknown" };
1144
- if (Base.isRef(schema)) return this.getSchemaByRef(schema, true);
1145
- if (this.isOpenAPIArraySchema(schema)) {
1146
- const { type, description, items, required } = schema;
1147
- return {
1148
- type,
1149
- required: !!required,
1150
- description,
1151
- items: this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey)
1152
- };
1153
- } else {
1154
- const { required = [], allOf, anyOf, description, enum: enum_, format, oneOf, properties = {} } = schema;
1155
- let { type } = schema;
1156
- if (enum_ && type !== "boolean") {
1157
- const enumObject = {
1158
- name: Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(schemaKey)),
1159
- enum: [...new Set(enum_)]
1160
- };
1161
- const sameObject = Base.findSameSchema(enumObject, enums);
1162
- if (!sameObject && Base.isValidEnumType(schema)) enums.push(enumObject);
1163
- return {
1164
- type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
1165
- required,
1166
- description
1167
- };
1168
- }
1169
- if (type === void 0 && Object.keys(properties).length > 0) type = "object";
1170
- return {
1171
- type,
1172
- required,
1173
- description,
1174
- enum: enum_,
1175
- format,
1176
- allOf: allOf?.map((s) => Base.isRef(s) ? {
1177
- ...s,
1178
- ref: s.$ref,
1179
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1180
- } : this.toBaseSchema(s, enums)),
1181
- anyOf: anyOf?.map((s) => Base.isRef(s) ? {
1182
- ...s,
1183
- ref: s.$ref,
1184
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1185
- } : this.toBaseSchema(s, enums)),
1186
- oneOf: oneOf?.map((s) => Base.isRef(s) ? {
1187
- ...s,
1188
- ref: s.$ref,
1189
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1190
- } : this.toBaseSchema(s, enums)),
1191
- properties: Object.keys(properties).reduce((acc, p) => {
1192
- const propSchema = properties[p];
1193
- return {
1194
- ...acc,
1195
- [p]: Base.isRef(propSchema) ? { type: Base.capitalize(Base.ref2name(propSchema.$ref, this.doc)) } : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
1196
- };
1197
- }, {})
1198
- };
1199
- }
1200
- }
1201
- /**
1202
- * OpenAPI parameter to base parameter.
1203
- */
1204
- getParameterByRef(parameter, enums = [], upLevelSchemaKey = "") {
1205
- if (Base.isRef(parameter)) {
1206
- const refName = Base.ref2name(parameter.$ref, this.doc);
1207
- const resolved = this.doc.parameters?.[refName];
1208
- if (!resolved) throw new Error(`Parameter reference not found: ${parameter.$ref}`);
1209
- parameter = resolved;
1210
- }
1211
- const p = parameter;
1212
- const { name, required, description, type, items, enum: enum_, properties, schema } = p;
1213
- if (enum_) {
1214
- const type = Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(name));
1215
- const enumSchema = {
1216
- name: type,
1217
- enum: [...new Set(enum_)]
1218
- };
1219
- const sameEnum = Base.findSameSchema(enumSchema, enums);
1220
- if (!sameEnum && Base.isValidEnumType({
1221
- type,
1222
- enum: enum_
1223
- })) enums.push(enumSchema);
1224
- return {
1225
- name,
1226
- required,
1227
- description,
1228
- in: p.in,
1229
- schema: { type: sameEnum?.name ?? type }
1230
- };
1231
- }
1232
- if (items) return {
1233
- name,
1234
- required,
1235
- description,
1236
- in: p.in,
1237
- schema: {
1238
- type,
1239
- items
1240
- }
1241
- };
1242
- if (schema && Base.isRef(schema)) return {
1243
- name,
1244
- required,
1245
- description,
1246
- in: p.in,
1247
- schema: { type: Base.capitalize(Base.ref2name(schema.$ref)) }
1248
- };
1249
- return {
1250
- name,
1251
- required,
1252
- description,
1253
- in: p.in,
1254
- schema: {
1255
- type,
1256
- properties
1257
- }
1258
- };
1259
- }
1260
- /**
1261
- * OpenAPI schema to base response
1190
+ * Format a ref name for the schema's `type` field.
1191
+ * V3 uses `capitalize`; V3_1 uses `upperCamelCase` (preserved for compat).
1262
1192
  */
1263
- getResponseByRef(schema) {
1264
- if (Base.isRef(schema)) schema = this.doc.responses[Base.ref2name(schema.$ref, this.doc)];
1265
- const { schema: responseSchema } = schema;
1266
- return [{
1267
- type: "application/json",
1268
- schema: responseSchema && this.getSchemaByRef(responseSchema, true)
1269
- }];
1270
- }
1271
- init() {
1272
- const { definitions = {}, responses = {}, paths = {} } = this.doc;
1273
- const enums = [];
1274
- const definitions_ = Object.keys(definitions).reduce((acc, key) => {
1275
- const schema = definitions[key];
1276
- return {
1277
- ...acc,
1278
- [key]: this.getSchemaByRef(schema, false, enums, key)
1279
- };
1280
- }, {});
1281
- const responses_ = Object.keys(responses).reduce((acc, key) => {
1282
- const response = responses[key];
1283
- return {
1284
- ...acc,
1285
- [key]: this.getResponseByRef(response)
1286
- };
1287
- }, {});
1288
- const apis = Object.keys(paths).reduce((acc, path) => {
1289
- let pathObject = paths[path] ?? {};
1290
- if (pathObject.$ref) {
1291
- const resolved = this.resolvePathRef(pathObject.$ref);
1292
- if (resolved) pathObject = resolved;
1293
- }
1294
- const { parameters = [] } = pathObject;
1295
- const methodApis = [];
1296
- Object.values(HttpMethods).forEach((method) => {
1297
- const methodObject = pathObject[method];
1298
- if (methodObject) {
1299
- const { deprecated, operationId, summary: summary_, description: description_, responses = {} } = methodObject;
1300
- const { parameters: parameters_ = [] } = methodObject;
1301
- const baseParameters = [...parameters, ...parameters_].map((parameter) => this.getParameterByRef(parameter, enums));
1302
- const uniqueParameterName = [...new Set(baseParameters.map((p) => p.name))];
1303
- if (Object.keys(responses).length === 0) Object.assign(responses, { 200: { description: "Successful response" } });
1304
- const inBody = baseParameters.filter((p) => p.in === "body" || p.in === "formData");
1305
- const notInBody = baseParameters.filter((p) => p.in !== "body" && p.in !== "formData");
1306
- const httpCodes = Object.keys(responses);
1307
- for (const code of httpCodes) if (code in responses) {
1308
- const response = responses[code];
1309
- const responseSchema = this.getResponseByRef(response);
1310
- const inBodyOnlyHasBody = inBody && inBody.length === 1 && inBody[0].in === "body" && inBody[0].name === "body";
1311
- methodApis.push({
1312
- method,
1313
- operationId,
1314
- summary: summary_,
1315
- deprecated,
1316
- description: description_,
1317
- parameters: uniqueParameterName.map((name) => notInBody.find((p) => p.name === name)).filter(Boolean),
1318
- responses: responseSchema,
1319
- requestBody: inBody.length > 0 ? inBodyOnlyHasBody ? [{
1320
- type: "application/json",
1321
- schema: inBody[0].schema
1322
- }] : [{
1323
- type: "application/json",
1324
- schema: {
1325
- type: "object",
1326
- properties: inBody.reduce((a, p) => {
1327
- return {
1328
- ...a,
1329
- [p.name]: {
1330
- type: p.schema?.type ?? "unknown",
1331
- required: p.schema?.required,
1332
- items: p.schema?.items,
1333
- description: p.schema?.description
1334
- }
1335
- };
1336
- }, {})
1337
- }
1338
- }] : void 0
1339
- });
1340
- break;
1341
- }
1342
- }
1343
- });
1344
- return {
1345
- ...acc,
1346
- [path]: methodApis
1347
- };
1348
- }, {});
1349
- return {
1350
- enums: Base.uniqueEnums(enums),
1351
- schemas: definitions_,
1352
- responses: responses_,
1353
- parameters: {},
1354
- requestBodies: {},
1355
- apis
1356
- };
1357
- }
1358
- };
1359
- //#endregion
1360
- //#region src/openapi/V3.ts
1361
- var V3 = class {
1362
- doc;
1363
- constructor(doc) {
1364
- this.doc = doc;
1365
- }
1366
- /**
1367
- * Resolves a path $ref to the actual path object.
1368
- */
1369
- resolvePathRef($ref) {
1370
- const refName = Base.ref2name($ref, this.doc);
1371
- return this.doc.paths?.[refName];
1372
- }
1373
- /**
1374
- * Is array schema.
1375
- */
1376
- isOpenAPIArraySchema(schema) {
1377
- return typeof schema === "object" && schema.type === "array";
1378
- }
1379
- /**
1380
- * OpenAPI schema to base schema.
1381
- */
1382
- getSchemaByRef(schema, reserveRef = false, enums = [], upLevelSchemaKey = "") {
1383
- let refName = "";
1384
- if (Base.isRef(schema)) {
1385
- refName = Base.capitalize(Base.ref2name(schema.$ref));
1386
- if (reserveRef) return { type: upLevelSchemaKey + refName };
1387
- const resolvedSchema = this.doc.components?.schemas?.[Base.ref2name(schema.$ref, this.doc)];
1388
- if (!resolvedSchema) return { type: "unknown" };
1389
- schema = resolvedSchema;
1390
- }
1391
- return this.toBaseSchema(schema, enums, "", upLevelSchemaKey + refName);
1193
+ formatRefName(name) {
1194
+ return Base.capitalize(name);
1392
1195
  }
1393
1196
  /**
1394
- * OpenAPI parameter to base parameter.
1197
+ * OpenAPI parameter to base parameter. Override in V2 — its parameter
1198
+ * shape is structurally different (top-level `items`/`properties`/`enum`).
1395
1199
  */
1396
1200
  getParameterByRef(schema, enums = [], upLevelSchemaKey = "") {
1397
1201
  if (Base.isRef(schema)) {
1398
- const resolvedSchema = this.doc.components?.parameters?.[Base.ref2name(schema.$ref, this.doc)];
1202
+ const resolvedSchema = this.getParameterContainer()?.[Base.ref2name(schema.$ref, this.doc)];
1399
1203
  if (!resolvedSchema) return {
1400
1204
  name: "unknown",
1401
1205
  in: "query"
@@ -1426,37 +1230,38 @@ var V3 = class {
1426
1230
  description,
1427
1231
  deprecated,
1428
1232
  in: schema.in,
1429
- schema: schema.schema && this.getSchemaByRef(schema.schema, false, enums, upLevelSchemaKey + Base.capitalize(name))
1233
+ schema: schema.schema ? this.getSchemaByRef(schema.schema, false, enums, upLevelSchemaKey + Base.capitalize(name)) : void 0
1430
1234
  };
1431
1235
  }
1432
1236
  /**
1433
- * OpenAPI schema to base response
1237
+ * OpenAPI schema to base response. Override in V2 (its response shape
1238
+ * lacks the `content` wrapper).
1434
1239
  */
1435
1240
  getResponseByRef(schema) {
1436
1241
  if (Base.isRef(schema)) {
1437
- const resolvedSchema = this.doc.components?.responses?.[Base.ref2name(schema.$ref, this.doc)];
1242
+ const resolvedSchema = this.getResponseContainer()?.[Base.ref2name(schema.$ref, this.doc)];
1438
1243
  if (!resolvedSchema) return [];
1439
1244
  schema = resolvedSchema;
1440
1245
  }
1441
1246
  const { content = {} } = schema;
1442
1247
  return Object.keys(content).map((c) => ({
1443
1248
  type: c,
1444
- schema: content[c].schema && this.getSchemaByRef(content[c].schema, true)
1249
+ schema: content[c].schema ? this.getSchemaByRef(content[c].schema, true) : void 0
1445
1250
  }));
1446
1251
  }
1447
1252
  /**
1448
- * OpenAPI schema to requestBody.
1253
+ * OpenAPI schema to requestBody. V2 has no requestBody concept.
1449
1254
  */
1450
1255
  getRequestBodyByRef(schema, enums = []) {
1451
1256
  if (Base.isRef(schema)) {
1452
- const resolvedSchema = this.doc.components?.requestBodies?.[Base.ref2name(schema.$ref, this.doc)];
1257
+ const resolvedSchema = this.getRequestBodyContainer()?.[Base.ref2name(schema.$ref, this.doc)];
1453
1258
  if (!resolvedSchema) return [];
1454
1259
  schema = resolvedSchema;
1455
1260
  }
1456
1261
  const { content = {} } = schema;
1457
1262
  return Object.keys(content).map((c) => ({
1458
1263
  type: c,
1459
- schema: content[c].schema && this.getSchemaByRef(content[c].schema, false, enums)
1264
+ schema: content[c].schema ? this.getSchemaByRef(content[c].schema, false, enums) : void 0
1460
1265
  }));
1461
1266
  }
1462
1267
  /**
@@ -1467,92 +1272,98 @@ var V3 = class {
1467
1272
  if (Base.isRef(schema)) return this.getSchemaByRef(schema, true);
1468
1273
  if (this.isOpenAPIArraySchema(schema)) {
1469
1274
  const { type, description, items, required } = schema;
1275
+ const itemsSchema = items ? this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey) : { type: "unknown" };
1470
1276
  return {
1471
1277
  type,
1472
1278
  required: !!required,
1473
1279
  description,
1474
- items: this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey)
1280
+ items: itemsSchema
1475
1281
  };
1476
- } else {
1477
- const { required = [], allOf, anyOf, description, deprecated, enum: enum_, format, oneOf, properties = {} } = schema;
1478
- let { type } = schema;
1479
- if (enum_ && type !== "boolean") {
1480
- const enumObject = {
1481
- name: Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(schemaKey)),
1482
- enum: [...new Set(enum_)]
1483
- };
1484
- const sameObject = Base.findSameSchema(enumObject, enums);
1485
- if (!sameObject && Base.isValidEnumType(schema)) enums.push(enumObject);
1486
- return {
1487
- type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
1488
- required,
1489
- description,
1490
- deprecated
1491
- };
1492
- }
1493
- if (type === void 0 && Object.keys(properties).length > 0) type = "object";
1282
+ }
1283
+ const { required = [], allOf, anyOf, description, deprecated, enum: enum_, format, oneOf, properties = {} } = schema;
1284
+ let { type } = schema;
1285
+ if (enum_ && type !== "boolean") {
1286
+ const enumObject = {
1287
+ name: Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(schemaKey)),
1288
+ enum: [...new Set(enum_)]
1289
+ };
1290
+ const sameObject = Base.findSameSchema(enumObject, enums);
1291
+ if (!sameObject && Base.isValidEnumType(schema)) enums.push(enumObject);
1494
1292
  return {
1495
- type,
1293
+ type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
1496
1294
  required,
1497
1295
  description,
1498
- deprecated,
1499
- enum: enum_,
1500
- format,
1501
- allOf: allOf?.map((s) => Base.isRef(s) ? {
1502
- ...s,
1503
- ref: s.$ref,
1504
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1505
- } : this.toBaseSchema(s, enums)),
1506
- anyOf: anyOf?.map((s) => Base.isRef(s) ? {
1507
- ...s,
1508
- ref: s.$ref,
1509
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1510
- } : this.toBaseSchema(s, enums)),
1511
- oneOf: oneOf?.map((s) => Base.isRef(s) ? {
1512
- ...s,
1513
- ref: s.$ref,
1514
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1515
- } : this.toBaseSchema(s, enums)),
1516
- properties: Object.keys(properties).reduce((acc, p) => {
1517
- const propSchema = properties[p];
1518
- return {
1519
- ...acc,
1520
- [p]: Base.isRef(propSchema) ? {
1521
- type: Base.capitalize(Base.ref2name(propSchema.$ref, this.doc)),
1522
- isRef: true
1523
- } : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
1524
- };
1525
- }, {})
1296
+ deprecated
1526
1297
  };
1527
1298
  }
1299
+ if (type === void 0 && Object.keys(properties).length > 0) type = "object";
1300
+ return {
1301
+ type,
1302
+ required,
1303
+ description,
1304
+ deprecated,
1305
+ enum: enum_,
1306
+ format,
1307
+ allOf: allOf?.map((s) => Base.isRef(s) ? {
1308
+ ...s,
1309
+ ref: s.$ref,
1310
+ type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1311
+ } : this.toBaseSchema(s, enums)),
1312
+ anyOf: anyOf?.map((s) => Base.isRef(s) ? {
1313
+ ...s,
1314
+ ref: s.$ref,
1315
+ type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1316
+ } : this.toBaseSchema(s, enums)),
1317
+ oneOf: oneOf?.map((s) => Base.isRef(s) ? {
1318
+ ...s,
1319
+ ref: s.$ref,
1320
+ type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1321
+ } : this.toBaseSchema(s, enums)),
1322
+ properties: Object.keys(properties).reduce((acc, p) => {
1323
+ const propSchema = properties[p];
1324
+ return {
1325
+ ...acc,
1326
+ [p]: Base.isRef(propSchema) ? {
1327
+ type: Base.capitalize(Base.ref2name(propSchema.$ref, this.doc)),
1328
+ isRef: true
1329
+ } : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
1330
+ };
1331
+ }, {})
1332
+ };
1528
1333
  }
1334
+ /**
1335
+ * Run the parsing pipeline and return a ProviderInitResult.
1336
+ */
1529
1337
  init() {
1530
- const { components = {}, paths = {} } = this.doc;
1338
+ const { paths = {} } = this.doc;
1531
1339
  const enums = [];
1532
- const { requestBodies = {}, responses = {}, parameters = {}, schemas = {} } = components;
1533
- const schemas_ = Object.keys(schemas).reduce((acc, key) => {
1534
- const schema = schemas[key];
1340
+ const schemaContainer = this.getSchemaContainer() ?? {};
1341
+ const parameterContainer = this.getParameterContainer() ?? {};
1342
+ const responseContainer = this.getResponseContainer() ?? {};
1343
+ const requestBodyContainer = this.getRequestBodyContainer() ?? {};
1344
+ const schemas_ = Object.keys(schemaContainer).reduce((acc, key) => {
1345
+ const schema = schemaContainer[key];
1535
1346
  return {
1536
1347
  ...acc,
1537
1348
  [key]: this.getSchemaByRef(schema, false, enums, key)
1538
1349
  };
1539
1350
  }, {});
1540
- const parameters_ = Object.keys(parameters).reduce((acc, key) => {
1541
- const parameter = parameters[key];
1351
+ const parameters_ = Object.keys(parameterContainer).reduce((acc, key) => {
1352
+ const parameter = parameterContainer[key];
1542
1353
  return {
1543
1354
  ...acc,
1544
1355
  [key]: this.getParameterByRef(parameter, enums, key)
1545
1356
  };
1546
1357
  }, {});
1547
- const responses_ = Object.keys(responses).reduce((acc, key) => {
1548
- const response = responses[key];
1358
+ const responses_ = Object.keys(responseContainer).reduce((acc, key) => {
1359
+ const response = responseContainer[key];
1549
1360
  return {
1550
1361
  ...acc,
1551
1362
  [key]: this.getResponseByRef(response)
1552
1363
  };
1553
1364
  }, {});
1554
- const requestBodies_ = Object.keys(requestBodies).reduce((acc, key) => {
1555
- const requestBody = requestBodies[key];
1365
+ const requestBodies_ = Object.keys(requestBodyContainer).reduce((acc, key) => {
1366
+ const requestBody = requestBodyContainer[key];
1556
1367
  return {
1557
1368
  ...acc,
1558
1369
  [key]: this.getRequestBodyByRef(requestBody, enums)
@@ -1569,15 +1380,16 @@ var V3 = class {
1569
1380
  Object.values(HttpMethods).forEach((method) => {
1570
1381
  const methodObject = pathObject[method];
1571
1382
  if (methodObject) {
1572
- const { deprecated, operationId, responses = {}, summary: summary_, description: description_, requestBody = { content: {} } } = methodObject;
1383
+ const { deprecated, operationId, responses, summary: summary_, description: description_, requestBody = { content: {} } } = methodObject;
1384
+ const responsesClone = responses ? { ...responses } : {};
1573
1385
  const { parameters: parameters_ = [] } = methodObject;
1574
1386
  const baseParameters = [...parameters, ...parameters_].map((parameter) => this.getParameterByRef(parameter, enums));
1575
1387
  const baseRequestBody = this.getRequestBodyByRef(requestBody, enums);
1576
1388
  const uniqueParameterName = [...new Set(baseParameters.map((p) => p.name))];
1577
- if (Object.keys(responses).length === 0) Object.assign(responses, { 200: { description: "Successful response" } });
1578
- const httpCodes = Object.keys(responses);
1579
- for (const code of httpCodes) if (code in responses) {
1580
- const response = responses[code];
1389
+ if (Object.keys(responsesClone).length === 0) responsesClone[200] = { description: "Successful response" };
1390
+ const httpCodes = Object.keys(responsesClone);
1391
+ for (const code of httpCodes) if (code in responsesClone) {
1392
+ const response = responsesClone[code];
1581
1393
  const responseSchema = this.getResponseByRef(response);
1582
1394
  methodApis.push({
1583
1395
  method,
@@ -1609,246 +1421,248 @@ var V3 = class {
1609
1421
  }
1610
1422
  };
1611
1423
  //#endregion
1612
- //#region src/openapi/V3_1.ts
1613
- var V3_1 = class {
1424
+ //#region src/openapi/V2.ts
1425
+ var V2 = class extends VersionedProvider {
1614
1426
  doc;
1427
+ version = "v2";
1615
1428
  constructor(doc) {
1429
+ super();
1616
1430
  this.doc = doc;
1617
1431
  }
1618
- /**
1619
- * Resolves a path $ref to the actual path object.
1620
- */
1621
- resolvePathRef($ref) {
1622
- const refName = Base.ref2name($ref, this.doc);
1623
- return this.doc.paths?.[refName];
1432
+ getSchemaContainer() {
1433
+ return this.doc.definitions;
1624
1434
  }
1625
- /**
1626
- * Is array schema.
1627
- */
1628
- isOpenAPIArraySchema(schema) {
1629
- return typeof schema === "object" && schema.type === "array";
1435
+ getParameterContainer() {
1436
+ return this.doc.parameters;
1630
1437
  }
1631
- /**
1632
- * OpenAPI schema to base schema.
1633
- */
1634
- getSchemaByRef(schema, reserveRef = false, enums = [], upLevelSchemaKey = "") {
1635
- let refName = "";
1636
- if (Base.isRef(schema)) {
1637
- refName = Base.upperCamelCase(Base.ref2name(schema.$ref));
1638
- if (reserveRef) return { type: upLevelSchemaKey + refName };
1639
- if (!this.doc.components) this.doc.components = { schemas: {} };
1640
- const resolvedSchema = this.doc.components.schemas?.[Base.ref2name(schema.$ref, this.doc)];
1641
- if (!resolvedSchema) throw new Error(`Schema reference not found: ${refName}`);
1642
- schema = resolvedSchema;
1643
- }
1644
- return this.toBaseSchema(schema, enums, "", upLevelSchemaKey + refName);
1438
+ getResponseContainer() {
1439
+ return this.doc.responses;
1645
1440
  }
1441
+ getRequestBodyContainer() {}
1646
1442
  /**
1647
- * OpenAPI parameter to base parameter.
1443
+ * V2 parameter shape differs from V3: top-level `items`/`properties`/`enum`
1444
+ * rather than nested under `schema`. Override accordingly.
1648
1445
  */
1649
- getParameterByRef(schema, enums = [], upLevelSchemaKey = "") {
1650
- if (Base.isRef(schema)) schema = this.doc.components?.parameters?.[Base.ref2name(schema.$ref, this.doc)];
1651
- const { name, required, deprecated, description, schema: parameterSchema } = schema;
1652
- if (parameterSchema && !Base.isRef(parameterSchema) && parameterSchema.enum) {
1653
- const type = Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(name));
1446
+ getParameterByRef(parameter, enums = [], upLevelSchemaKey = "") {
1447
+ if (Base.isRef(parameter)) {
1448
+ const refName = Base.ref2name(parameter.$ref, this.doc);
1449
+ const resolved = this.doc.parameters?.[refName];
1450
+ if (!resolved) throw new Error(`Parameter reference not found: ${parameter.$ref}`);
1451
+ parameter = resolved;
1452
+ }
1453
+ const p = parameter;
1454
+ const { name, required, description, type, items, enum: enum_, properties, schema } = p;
1455
+ if (enum_) {
1456
+ const enumType = Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(name));
1654
1457
  const enumSchema = {
1655
- name: type,
1656
- enum: [...new Set(parameterSchema.enum)]
1458
+ name: enumType,
1459
+ enum: [...new Set(enum_)]
1657
1460
  };
1658
1461
  const sameEnum = Base.findSameSchema(enumSchema, enums);
1659
- if (!sameEnum && Base.isValidEnumType(parameterSchema)) enums.push(enumSchema);
1462
+ if (!sameEnum && Base.isValidEnumType({
1463
+ type: enumType,
1464
+ enum: enum_
1465
+ })) enums.push(enumSchema);
1660
1466
  return {
1661
1467
  name,
1662
1468
  required,
1663
1469
  description,
1664
- deprecated,
1665
- in: schema.in,
1666
- schema: { type: sameEnum?.name ?? type }
1470
+ in: p.in,
1471
+ schema: { type: sameEnum?.name ?? enumType }
1667
1472
  };
1668
1473
  }
1474
+ if (items) return {
1475
+ name,
1476
+ required,
1477
+ description,
1478
+ in: p.in,
1479
+ schema: {
1480
+ type,
1481
+ items
1482
+ }
1483
+ };
1484
+ if (schema && Base.isRef(schema)) return {
1485
+ name,
1486
+ required,
1487
+ description,
1488
+ in: p.in,
1489
+ schema: { type: Base.capitalize(Base.ref2name(schema.$ref)) }
1490
+ };
1669
1491
  return {
1670
1492
  name,
1671
1493
  required,
1672
1494
  description,
1673
- deprecated,
1674
- in: schema.in,
1675
- schema: schema.schema && this.getSchemaByRef(schema.schema, false, enums, upLevelSchemaKey + Base.capitalize(name))
1495
+ in: p.in,
1496
+ schema: {
1497
+ type,
1498
+ properties
1499
+ }
1676
1500
  };
1677
1501
  }
1678
1502
  /**
1679
- * OpenAPI schema to base response
1503
+ * V2 response shape: a `schema` field directly, not `content`. V2 always
1504
+ * emits JSON.
1680
1505
  */
1681
1506
  getResponseByRef(schema) {
1682
- if (Base.isRef(schema)) schema = this.doc.components?.responses?.[Base.ref2name(schema.$ref, this.doc)];
1683
- const { content = {} } = schema;
1684
- return Object.keys(content).map((c) => ({
1685
- type: c,
1686
- schema: content[c].schema && this.getSchemaByRef(content[c].schema, true)
1687
- }));
1688
- }
1689
- /**
1690
- * OpenAPI schema to requestBody.
1691
- */
1692
- getRequestBodyByRef(schema, enums = []) {
1693
- if (Base.isRef(schema)) schema = this.doc.components?.requestBodies?.[Base.ref2name(schema.$ref, this.doc)];
1694
- const { content = {} } = schema;
1695
- return Object.keys(content).map((c) => ({
1696
- type: c,
1697
- schema: content[c].schema && this.getSchemaByRef(content[c].schema, true, enums)
1698
- }));
1507
+ if (Base.isRef(schema)) schema = this.doc.responses[Base.ref2name(schema.$ref, this.doc)];
1508
+ const { schema: responseSchema } = schema;
1509
+ return [{
1510
+ type: "application/json",
1511
+ schema: responseSchema ? this.getSchemaByRef(responseSchema, true) : void 0
1512
+ }];
1699
1513
  }
1700
1514
  /**
1701
- * Transform all OpenAPI schema to Base Schema
1515
+ * V2 has no `requestBody` concept; parameters with `in: body` or
1516
+ * `in: formData` are split out and turned into a synthetic requestBody
1517
+ * here. A single body param named `body` is used directly; otherwise
1518
+ * the body / formData params are wrapped in a synthetic object.
1702
1519
  */
1703
- toBaseSchema(schema, enums = [], schemaKey = "", upLevelSchemaKey = "") {
1704
- if (!schema) return { type: "unknown" };
1705
- if (Base.isRef(schema)) return this.getSchemaByRef(schema, true);
1706
- if (this.isOpenAPIArraySchema(schema)) {
1707
- const { type, description, items, required } = schema;
1708
- return {
1709
- type,
1710
- required: !!required,
1711
- description,
1712
- items: this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey)
1713
- };
1714
- } else {
1715
- const { required = [], allOf, anyOf, description, deprecated, enum: enum_, format, oneOf, properties = {} } = schema;
1716
- let { type } = schema;
1717
- if (enum_ && type !== "boolean") {
1718
- const enumObject = {
1719
- name: Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(schemaKey)),
1720
- enum: [...new Set(enum_)]
1721
- };
1722
- const sameObject = Base.findSameSchema(enumObject, enums);
1723
- if (!sameObject && Base.isValidEnumType(schema)) enums.push(enumObject);
1724
- return {
1725
- type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
1726
- required,
1727
- description,
1728
- deprecated
1729
- };
1730
- }
1731
- if (type === void 0 && Object.keys(properties).length > 0) type = "object";
1732
- return {
1733
- type,
1734
- required,
1735
- description,
1736
- deprecated,
1737
- enum: enum_,
1738
- format,
1739
- allOf: allOf?.map((s) => Base.isRef(s) ? {
1740
- ...s,
1741
- ref: s.$ref,
1742
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1743
- } : this.toBaseSchema(s, enums)),
1744
- anyOf: anyOf?.map((s) => Base.isRef(s) ? {
1745
- ...s,
1746
- ref: s.$ref,
1747
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1748
- } : this.toBaseSchema(s, enums)),
1749
- oneOf: oneOf?.map((s) => Base.isRef(s) ? {
1750
- ...s,
1751
- ref: s.$ref,
1752
- type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
1753
- } : this.toBaseSchema(s, enums)),
1754
- properties: Object.keys(properties).reduce((acc, p) => {
1755
- const propSchema = properties[p];
1756
- return {
1757
- ...acc,
1758
- [p]: Base.isRef(propSchema) ? {
1759
- type: Base.capitalize(Base.ref2name(propSchema.$ref, this.doc)),
1760
- isRef: true
1761
- } : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
1762
- };
1763
- }, {})
1764
- };
1765
- }
1766
- }
1767
1520
  init() {
1768
- const { components = {}, paths = {} } = this.doc;
1521
+ const { paths = {} } = this.doc;
1769
1522
  const enums = [];
1770
- const { requestBodies = {}, responses = {}, parameters = {}, schemas = {} } = components;
1771
- const schemas_ = Object.keys(schemas).reduce((acc, key) => {
1772
- const schema = schemas[key];
1523
+ const schemaContainer = this.getSchemaContainer() ?? {};
1524
+ const parameterContainer = this.getParameterContainer() ?? {};
1525
+ const responseContainer = this.getResponseContainer() ?? {};
1526
+ const schemas_ = Object.keys(schemaContainer).reduce((acc, key) => {
1527
+ const schema = schemaContainer[key];
1773
1528
  return {
1774
1529
  ...acc,
1775
1530
  [key]: this.getSchemaByRef(schema, false, enums, key)
1776
1531
  };
1777
1532
  }, {});
1778
- const parameters_ = Object.keys(parameters).reduce((acc, key) => {
1779
- const parameter = parameters[key];
1533
+ const parameters_ = Object.keys(parameterContainer).reduce((acc, key) => {
1534
+ const parameter = parameterContainer[key];
1780
1535
  return {
1781
1536
  ...acc,
1782
1537
  [key]: this.getParameterByRef(parameter, enums, key)
1783
1538
  };
1784
1539
  }, {});
1785
- const responses_ = Object.keys(responses).reduce((acc, key) => {
1786
- const response = responses[key];
1540
+ const responses_ = Object.keys(responseContainer).reduce((acc, key) => {
1541
+ const response = responseContainer[key];
1787
1542
  return {
1788
1543
  ...acc,
1789
1544
  [key]: this.getResponseByRef(response)
1790
1545
  };
1791
1546
  }, {});
1792
- const requestBodies_ = Object.keys(requestBodies).reduce((acc, key) => {
1793
- const requestBody = requestBodies[key];
1794
- return {
1795
- ...acc,
1796
- [key]: this.getRequestBodyByRef(requestBody, enums)
1797
- };
1798
- }, {});
1799
- const apis = Object.keys(paths).reduce((acc, path) => {
1547
+ const apis = {};
1548
+ for (const path of Object.keys(paths)) {
1800
1549
  let pathObject = paths[path] ?? {};
1801
1550
  if (pathObject.$ref) {
1802
1551
  const resolved = this.resolvePathRef(pathObject.$ref);
1803
1552
  if (resolved) pathObject = resolved;
1804
1553
  }
1805
- const { parameters = [], description, summary } = pathObject;
1554
+ const { parameters = [] } = pathObject;
1806
1555
  const methodApis = [];
1807
1556
  Object.values(HttpMethods).forEach((method) => {
1808
1557
  const methodObject = pathObject[method];
1809
- if (methodObject) {
1810
- const { deprecated, operationId, summary: summary_, description: description_, responses = {}, requestBody = { content: {} } } = methodObject;
1811
- const { parameters: parameters_ = [] } = methodObject;
1812
- const baseParameters = [...parameters, ...parameters_].map((parameter) => this.getParameterByRef(parameter, enums));
1813
- const baseRequestBody = this.getRequestBodyByRef(requestBody, enums);
1814
- const uniqueParameterName = [...new Set(baseParameters.map((p) => p.name))];
1815
- if (Object.keys(responses).length === 0) Object.assign(responses, { 200: { description: "Successful response" } });
1816
- const httpCodes = Object.keys(responses);
1817
- for (const code of httpCodes) if (code in responses) {
1818
- const response = responses[code];
1819
- const responseSchema = this.getResponseByRef(response);
1820
- methodApis.push({
1821
- method,
1822
- operationId,
1823
- summary: summary_ ?? summary,
1824
- description: description_ ?? description,
1825
- deprecated,
1826
- parameters: uniqueParameterName.map((name) => baseParameters.find((p) => p.name === name)).filter((p) => p !== void 0),
1827
- responses: responseSchema,
1828
- requestBody: baseRequestBody
1829
- });
1830
- break;
1831
- }
1558
+ if (!methodObject) return;
1559
+ const { deprecated, operationId, summary: summary_, description: description_, responses } = methodObject;
1560
+ const { parameters: parameters_ = [] } = methodObject;
1561
+ const baseParameters = [...parameters, ...parameters_].map((p) => this.getParameterByRef(p, enums));
1562
+ const uniqueParameterName = [...new Set(baseParameters.map((p) => p.name))];
1563
+ const responsesClone = responses ? { ...responses } : {};
1564
+ if (Object.keys(responsesClone).length === 0) responsesClone[200] = { description: "Successful response" };
1565
+ const inBody = baseParameters.filter((p) => p.in === "body" || p.in === "formData");
1566
+ const notInBody = baseParameters.filter((p) => p.in !== "body" && p.in !== "formData");
1567
+ const httpCodes = Object.keys(responsesClone);
1568
+ for (const code of httpCodes) if (code in responsesClone) {
1569
+ const response = responsesClone[code];
1570
+ const responseSchema = this.getResponseByRef(response);
1571
+ const inBodyOnlyHasBody = inBody.length === 1 && inBody[0].in === "body" && inBody[0].name === "body";
1572
+ methodApis.push({
1573
+ method,
1574
+ operationId,
1575
+ summary: summary_,
1576
+ deprecated,
1577
+ description: description_,
1578
+ parameters: uniqueParameterName.map((name) => notInBody.find((p) => p.name === name)).filter((p) => p !== void 0),
1579
+ responses: responseSchema,
1580
+ requestBody: inBody.length > 0 ? inBodyOnlyHasBody ? [{
1581
+ type: "application/json",
1582
+ schema: inBody[0].schema
1583
+ }] : [{
1584
+ type: "application/json",
1585
+ schema: {
1586
+ type: "object",
1587
+ properties: inBody.reduce((a, p) => {
1588
+ return {
1589
+ ...a,
1590
+ [p.name]: {
1591
+ type: p.schema?.type ?? "unknown",
1592
+ required: p.schema?.required,
1593
+ items: p.schema?.items,
1594
+ description: p.schema?.description
1595
+ }
1596
+ };
1597
+ }, {})
1598
+ }
1599
+ }] : void 0
1600
+ });
1601
+ break;
1832
1602
  }
1833
1603
  });
1834
- return {
1835
- ...acc,
1836
- [path]: methodApis
1837
- };
1838
- }, {});
1604
+ apis[path] = methodApis;
1605
+ }
1839
1606
  return {
1840
1607
  enums: Base.uniqueEnums(enums),
1841
1608
  schemas: schemas_,
1842
1609
  responses: responses_,
1843
1610
  parameters: parameters_,
1844
- requestBodies: requestBodies_,
1611
+ requestBodies: {},
1845
1612
  apis
1846
1613
  };
1847
1614
  }
1848
1615
  };
1849
1616
  //#endregion
1617
+ //#region src/openapi/V3.ts
1618
+ var V3 = class extends VersionedProvider {
1619
+ doc;
1620
+ version = "v3";
1621
+ constructor(doc) {
1622
+ super();
1623
+ this.doc = doc;
1624
+ }
1625
+ getSchemaContainer() {
1626
+ return this.doc.components?.schemas;
1627
+ }
1628
+ getParameterContainer() {
1629
+ return this.doc.components?.parameters;
1630
+ }
1631
+ getResponseContainer() {
1632
+ return this.doc.components?.responses;
1633
+ }
1634
+ getRequestBodyContainer() {
1635
+ return this.doc.components?.requestBodies;
1636
+ }
1637
+ };
1638
+ //#endregion
1639
+ //#region src/openapi/V3_1.ts
1640
+ var V3_1 = class extends VersionedProvider {
1641
+ doc;
1642
+ version = "v3_1";
1643
+ constructor(doc) {
1644
+ super();
1645
+ this.doc = doc;
1646
+ }
1647
+ formatRefName(name) {
1648
+ return Base.upperCamelCase(name);
1649
+ }
1650
+ getSchemaContainer() {
1651
+ return this.doc.components?.schemas;
1652
+ }
1653
+ getParameterContainer() {
1654
+ return this.doc.components?.parameters;
1655
+ }
1656
+ getResponseContainer() {
1657
+ return this.doc.components?.responses;
1658
+ }
1659
+ getRequestBodyContainer() {
1660
+ return this.doc.components?.requestBodies;
1661
+ }
1662
+ };
1663
+ //#endregion
1850
1664
  //#region src/openapi/index.ts
1851
- const logger$1 = createScopedLogger("OpenAPI");
1665
+ const logger = createScopedLogger("OpenAPI");
1852
1666
  function getDocVersion(doc) {
1853
1667
  switch ((doc.openapi || doc.swagger).slice(0, 3)) {
1854
1668
  case "3.1": return "v3_1";
@@ -1860,7 +1674,7 @@ function getDocVersion(doc) {
1860
1674
  var OpenAPIProvider = class extends Provider {
1861
1675
  parse(doc) {
1862
1676
  const version = getDocVersion(doc);
1863
- logger$1.debug(`openapi version ${version}`);
1677
+ logger.debug(`openapi version ${version}`);
1864
1678
  switch (version) {
1865
1679
  case "v2": return new V2(doc).init();
1866
1680
  case "v3": return new V3(doc).init();
@@ -1878,9 +1692,9 @@ function getAdaptor(type) {
1878
1692
  async function codeGen(initOptions) {
1879
1693
  const startTime = Date.now();
1880
1694
  const { verbose } = initOptions;
1881
- if (verbose) logger$1.setLevel("debug");
1882
- else logger$1.setLevel("info");
1883
- logger$1.info(`Fetch document from ${initOptions.docURL}`);
1695
+ if (verbose) logger.setLevel("debug");
1696
+ else logger.setLevel("info");
1697
+ logger.info(`Fetch document from ${initOptions.docURL}`);
1884
1698
  const { enums, schemas, parameters, responses, requestBodies, apis } = new OpenAPIProvider(initOptions, await Base.fetchDoc(initOptions.docURL, initOptions.requestOptions));
1885
1699
  const adaptor = getAdaptor(initOptions.adaptor ?? "fetch");
1886
1700
  const code = await Generator.genCode({
@@ -1905,7 +1719,7 @@ async function codeGen(initOptions) {
1905
1719
  //#endregion
1906
1720
  //#region src/vite-plugin/index.ts
1907
1721
  const PLUGIN_NAME = "api-code-gen";
1908
- const logger = createScopedLogger("api-code-gen");
1722
+ const pluginLogger = createScopedLogger("api-code-gen");
1909
1723
  /**
1910
1724
  * Run TypeScript type checking on generated file
1911
1725
  */
@@ -1934,7 +1748,7 @@ async function validateSpecPath(specPath) {
1934
1748
  async function generateForOption(option) {
1935
1749
  const { name, typeCheck = true, verbose, ...restOptions } = option;
1936
1750
  try {
1937
- console.log(`\x1b[36m├─\x1b[0m ${name}`);
1751
+ logger$1.info(`Generating ${name}...`);
1938
1752
  const config = await loadConfig({
1939
1753
  name,
1940
1754
  cliOptions: {
@@ -1958,8 +1772,8 @@ async function generateForOption(option) {
1958
1772
  if (typeCheck && config.output) {
1959
1773
  const typeErrors = await runTypeCheck(config.output);
1960
1774
  if (typeErrors.length > 0) {
1961
- logger.warn(`Type check failed for ${config.output}`);
1962
- if (verbose) for (const error of typeErrors) logger.warn(` ${error}`);
1775
+ pluginLogger.warn(`Type check failed for ${config.output}`);
1776
+ if (verbose) for (const error of typeErrors) pluginLogger.warn(` ${error}`);
1963
1777
  }
1964
1778
  }
1965
1779
  return {
@@ -2000,45 +1814,47 @@ async function generateForOption(option) {
2000
1814
  */
2001
1815
  function apiCodeGenPlugin(options) {
2002
1816
  if (!Array.isArray(options) || options.length === 0) {
2003
- logger.warn("No API configurations provided to apiCodeGenPlugin");
1817
+ pluginLogger.warn("No API configurations provided to apiCodeGenPlugin");
2004
1818
  return { name: PLUGIN_NAME };
2005
1819
  }
2006
1820
  return {
2007
1821
  name: PLUGIN_NAME,
2008
1822
  async config(_config, env) {
2009
- console.log(`\x1b[1m\x1b[36m${"".repeat(50)}\x1b[0m`);
2010
- console.log(`\x1b[1m\x1b[36mAPI Code Gen\x1b[0m`);
2011
- console.log(`\x1b[90mMode:\x1b[0m ${env?.command || "unknown"}`);
2012
- console.log(`\x1b[1m\x1b[36m${"─".repeat(50)}\x1b[0m`);
1823
+ logger$1.heading("API Code Gen", env?.command);
2013
1824
  const results = await Promise.all(options.map(generateForOption));
2014
1825
  const successCount = results.filter((r) => r.success).length;
2015
1826
  const failCount = options.length - successCount;
2016
- console.log(`\x1b[1m\x1b[36m${"─".repeat(50)}\x1b[0m`);
1827
+ logger$1.divider();
2017
1828
  for (const result of results) if (result.success) {
2018
1829
  const { name, output, stats } = result;
2019
- if (stats) console.log(`\x1b[32m✓\x1b[0m ${name} → ${output} (${stats.endpoints} endpoints, ${stats.schemas} schemas) ${stats.duration}ms`);
2020
- else console.log(`\x1b[32m✓\x1b[0m ${name} → ${output || "N/A"}`);
1830
+ if (stats) logger$1.item(`${name} → ${output} (${stats.endpoints} endpoints, ${stats.schemas} schemas) ${stats.duration}ms`, "green");
1831
+ else logger$1.item(`${name} → ${output || "N/A"}`, "green");
2021
1832
  } else {
2022
1833
  const { name, error } = result;
2023
1834
  if (isApicodegenError(error)) {
2024
- console.log(`\x1b[31m✗\x1b[0m ${name}`);
2025
- console.log(`\x1b[90m${formatError(error, true)}\x1b[0m`);
1835
+ logger$1.item(name, "red");
1836
+ logger$1.error(error, true);
2026
1837
  } else {
2027
1838
  const wrapped = wrapError(error, {
2028
- code: "E_GENERATION_FAILED",
1839
+ code: ErrorCodes.GENERATION_FAILED,
2029
1840
  message: `Failed to generate API "${name}"`
2030
1841
  });
2031
- console.log(`\x1b[31m✗\x1b[0m ${name}`);
2032
- console.log(`\x1b[90m${formatError(wrapped, true)}\x1b[0m`);
1842
+ logger$1.item(name, "red");
1843
+ logger$1.error(wrapped, true);
2033
1844
  }
2034
1845
  }
2035
- console.log(`\x1b[1m\x1b[36m${"─".repeat(50)}\x1b[0m`);
1846
+ logger$1.divider();
2036
1847
  const totalDuration = results.reduce((sum, r) => sum + (r.stats?.duration || 0), 0);
2037
1848
  const totalEndpoints = results.reduce((sum, r) => sum + (r.stats?.endpoints || 0), 0);
2038
1849
  const totalSchemas = results.reduce((sum, r) => sum + (r.stats?.schemas || 0), 0);
2039
- 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)`);
2040
- 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)`);
2041
- console.log(`\x1b[1m\x1b[36m${"─".repeat(50)}\x1b[0m`);
1850
+ logger$1.summary({
1851
+ succeeded: successCount,
1852
+ failed: failCount,
1853
+ endpoints: totalEndpoints,
1854
+ schemas: totalSchemas,
1855
+ duration: totalDuration
1856
+ });
1857
+ logger$1.divider();
2042
1858
  return {};
2043
1859
  }
2044
1860
  };