@ps-aux/api-client-gen 0.7.0-rc.6 → 0.7.0-rc.8

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.
@@ -1,12 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  var Path$1 = require('path');
4
- var fs$1 = require('fs');
4
+ var fs$2 = require('fs');
5
+ var fs$1 = require('node:fs');
5
6
  var Path = require('node:path');
7
+ require('c12');
8
+ var tsToZod = require('ts-to-zod');
9
+ var fs = require('node:fs/promises');
6
10
  var swaggerTypescriptApi = require('swagger-typescript-api');
7
11
  var node_url = require('node:url');
8
- var fs = require('node:fs/promises');
9
- var tsToZod = require('ts-to-zod');
10
12
 
11
13
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
12
14
  function _interopNamespaceDefault(e) {
@@ -26,7 +28,7 @@ function _interopNamespaceDefault(e) {
26
28
  return Object.freeze(n);
27
29
  }
28
30
 
29
- var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs$1);
31
+ var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs$2);
30
32
 
31
33
  /** A special constant with type `never` */
32
34
  function $constructor(name, initializer, params) {
@@ -4238,7 +4240,7 @@ const vNextOasGeneratorSchema = strictObject({
4238
4240
  }).prefault({}),
4239
4241
  codegen: strictObject({
4240
4242
  unwrap: boolean().default(true),
4241
- withRequestParams: boolean().default(false),
4243
+ withRequestParams: boolean().default(true),
4242
4244
  pathParamsStyle: _enum(["object", "positional"]).default("positional"),
4243
4245
  enumStyle: _enum(["enum", "union"]).default("enum"),
4244
4246
  comments: strictObject({
@@ -11283,9 +11285,82 @@ class CodeFormatter {
11283
11285
  }
11284
11286
  }
11285
11287
 
11286
- const splitIdentifierWords$1 = (str) => str.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter(Boolean);
11287
- const toPascalCaseIdentifier = (str) => splitIdentifierWords$1(str).map((word) => word[0].toUpperCase() + word.substring(1)).join("");
11288
- const toKebabCaseIdentifier = (str) => splitIdentifierWords$1(str).map((word) => word.toLowerCase()).join("-");
11288
+ const removeGenericTypes = (code) => {
11289
+ const declarations = [];
11290
+ const declarationStartRegex = /^export\s+(interface|enum|type)\s+[A-Za-z0-9_]+(?:<[^>\n]+>)?/gm;
11291
+ let match;
11292
+ while ((match = declarationStartRegex.exec(code)) !== null) {
11293
+ const declaration = extractDeclaration(code, match);
11294
+ if (!declaration) continue;
11295
+ declarations.push(declaration);
11296
+ declarationStartRegex.lastIndex = match.index + declaration.length;
11297
+ }
11298
+ return declarations.join("\n\n");
11299
+ };
11300
+ const extractDeclaration = (code, match) => {
11301
+ const header = match[0];
11302
+ if (header.includes("<")) return null;
11303
+ const kind = match[1];
11304
+ let cursor = match.index + header.length;
11305
+ if (kind === "type") {
11306
+ cursor = skipWhitespace(code, cursor);
11307
+ if (code[cursor] !== "=") return null;
11308
+ cursor = skipWhitespace(code, cursor + 1);
11309
+ if (code[cursor] !== "{") return null;
11310
+ } else {
11311
+ cursor = code.indexOf("{", cursor);
11312
+ if (cursor === -1) return null;
11313
+ }
11314
+ const end = findMatchingBrace(code, cursor);
11315
+ if (end === -1) return null;
11316
+ return code.slice(match.index, end + 1);
11317
+ };
11318
+ const skipWhitespace = (code, cursor) => {
11319
+ while (/\s/.test(code[cursor] ?? "")) {
11320
+ cursor += 1;
11321
+ }
11322
+ return cursor;
11323
+ };
11324
+ const findMatchingBrace = (code, openBraceIndex) => {
11325
+ let depth = 0;
11326
+ for (let i = openBraceIndex; i < code.length; i += 1) {
11327
+ if (code[i] === "{") depth += 1;
11328
+ if (code[i] === "}") {
11329
+ depth -= 1;
11330
+ if (depth === 0) return i;
11331
+ }
11332
+ }
11333
+ return -1;
11334
+ };
11335
+
11336
+ var __defProp$b = Object.defineProperty;
11337
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11338
+ var __publicField$b = (obj, key, value) => __defNormalProp$b(obj, key + "" , value);
11339
+ class ZodSchemaGenerator {
11340
+ constructor(codeFormatter) {
11341
+ this.codeFormatter = codeFormatter;
11342
+ __publicField$b(this, "generate", async ({
11343
+ sourceText,
11344
+ moduleImportPath,
11345
+ options = {}
11346
+ }) => {
11347
+ const { getZodSchemasFile } = tsToZod.generate({
11348
+ sourceText: removeGenericTypes(sourceText)
11349
+ });
11350
+ let generated = getZodSchemasFile(moduleImportPath);
11351
+ generated = generated.replaceAll(".optional()", ".nullable()");
11352
+ generated = generated.replaceAll(".int64()", ".int()");
11353
+ if (options.localDateTimes) {
11354
+ generated = generated.replaceAll(
11355
+ "z.string().datetime()",
11356
+ "z.string().datetime({local: true})"
11357
+ );
11358
+ }
11359
+ return this.codeFormatter.format(generated);
11360
+ });
11361
+ }
11362
+ }
11363
+
11289
11364
  const findRelativePath = (src, dst) => {
11290
11365
  const relativePath = Path$1.relative(Path$1.dirname(src), dst);
11291
11366
  const withoutExtension = relativePath.replace(/\.ts$/u, "");
@@ -11293,6 +11368,62 @@ const findRelativePath = (src, dst) => {
11293
11368
  return normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
11294
11369
  };
11295
11370
 
11371
+ const splitIdentifierWords$1 = (str) => str.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter(Boolean);
11372
+ const toPascalCaseIdentifier = (str) => splitIdentifierWords$1(str).map((word) => word[0].toUpperCase() + word.substring(1)).join("");
11373
+ const toKebabCaseIdentifier = (str) => splitIdentifierWords$1(str).map((word) => word.toLowerCase()).join("-");
11374
+
11375
+ var __defProp$a = Object.defineProperty;
11376
+ var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11377
+ var __publicField$a = (obj, key, value) => __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
11378
+ class FileWriter {
11379
+ constructor(outputDir, opts = {}) {
11380
+ this.outputDir = outputDir;
11381
+ this.opts = opts;
11382
+ __publicField$a(this, "resolveName", (req, opts) => {
11383
+ let name = opts?.preserveCase ? req.name : this.setNameCase(req.name);
11384
+ if (this.opts.suffix && opts?.noSuffix !== true) {
11385
+ name = name + "." + this.opts.suffix;
11386
+ }
11387
+ if (this.opts.mapFileName)
11388
+ name = this.opts.mapFileName({
11389
+ name,
11390
+ ext: req.ext
11391
+ });
11392
+ return name;
11393
+ });
11394
+ __publicField$a(this, "resolvePath", (req, opts) => this.getResolvedPath(req, opts));
11395
+ __publicField$a(this, "write", async ({ content, ...req }, opts) => {
11396
+ const resolvedPath = this.getResolvedPath(req, opts);
11397
+ await fs.mkdir(Path.dirname(resolvedPath), { recursive: true });
11398
+ await fs.writeFile(resolvedPath, content, "utf8");
11399
+ return resolvedPath;
11400
+ });
11401
+ __publicField$a(this, "getResolvedPath", ({ path, ext, ...req }, opts) => Path.resolve(
11402
+ this.outputDir,
11403
+ ...path ?? [],
11404
+ `${this.resolveName(
11405
+ {
11406
+ ext,
11407
+ ...req
11408
+ },
11409
+ opts
11410
+ )}.${ext}`
11411
+ ));
11412
+ __publicField$a(this, "setNameCase", (name) => {
11413
+ const [first, ...rest] = name.split(".");
11414
+ const converted = this.transformCase(first);
11415
+ return [converted, ...rest].join(".");
11416
+ });
11417
+ __publicField$a(this, "transformCase", (value) => {
11418
+ const nameCase = this.opts.case ?? "pascal";
11419
+ if (nameCase === "kebab") {
11420
+ return toKebabCaseIdentifier(value);
11421
+ }
11422
+ return toPascalCaseIdentifier(value);
11423
+ });
11424
+ }
11425
+ }
11426
+
11296
11427
  const generateOpenApiClient = async (inputFile, {
11297
11428
  name,
11298
11429
  outputDir,
@@ -11345,7 +11476,7 @@ const generateOpenApiClient = async (inputFile, {
11345
11476
  if (responseWrapper) {
11346
11477
  await modifyHttpClientAsyncWrapper([dstFile], responseWrapper, log);
11347
11478
  }
11348
- return { types: dstFile, promiseWrapper: [dstFile] };
11479
+ return dstFile;
11349
11480
  };
11350
11481
  const modifyHttpClientAsyncWrapper = async (filePaths, responseWrapper, log) => {
11351
11482
  log(
@@ -11377,12 +11508,21 @@ const modifyOutput = async (path, cmd) => {
11377
11508
  await fs.writeFile(path, content);
11378
11509
  };
11379
11510
  const getThisScriptDirname = () => {
11380
- return Path$1.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('generateApiClient.cjs', document.baseURI).href))));
11511
+ return Path$1.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('generate.cjs', document.baseURI).href))));
11381
11512
  };
11382
11513
  const getTemplatesDir = () => {
11383
11514
  const currentDir = getThisScriptDirname();
11384
- const templatesRelativePath = Path$1.basename(currentDir) === "dist" ? "../templates" : "../../../templates";
11385
- return Path$1.resolve(currentDir, templatesRelativePath);
11515
+ const templateDirCandidates = [
11516
+ Path$1.resolve(currentDir, "../../templates/legacy"),
11517
+ Path$1.resolve(currentDir, "../templates/legacy")
11518
+ ];
11519
+ const templateDir = templateDirCandidates.find(fs$1.existsSync);
11520
+ if (!templateDir) {
11521
+ throw new Error(
11522
+ `Legacy swagger-ts-api templates not found. Tried: ${templateDirCandidates.join(", ")}`
11523
+ );
11524
+ }
11525
+ return templateDir;
11386
11526
  };
11387
11527
 
11388
11528
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -11439,9 +11579,9 @@ const resolveLocalRef = (root, ref) => {
11439
11579
  return current;
11440
11580
  };
11441
11581
 
11442
- var __defProp$b = Object.defineProperty;
11443
- var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11444
- var __publicField$b = (obj, key, value) => __defNormalProp$b(obj, key + "" , value);
11582
+ var __defProp$9 = Object.defineProperty;
11583
+ var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11584
+ var __publicField$9 = (obj, key, value) => __defNormalProp$9(obj, key + "" , value);
11445
11585
  const PARAMETER_LOCATIONS = [
11446
11586
  "path",
11447
11587
  "query",
@@ -11467,7 +11607,7 @@ const mergeParameters = (base, override) => {
11467
11607
  class OpenApiNormalizer {
11468
11608
  constructor(doc) {
11469
11609
  this.doc = doc;
11470
- __publicField$b(this, "problems", []);
11610
+ __publicField$9(this, "problems", []);
11471
11611
  }
11472
11612
  load() {
11473
11613
  const info = readRecord(this.doc, "info");
@@ -11810,24 +11950,24 @@ const syntheticOperationId = (method, path) => {
11810
11950
  return `_${compact}`;
11811
11951
  };
11812
11952
 
11813
- var __defProp$a = Object.defineProperty;
11814
- var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11815
- var __publicField$a = (obj, key, value) => __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
11953
+ var __defProp$8 = Object.defineProperty;
11954
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11955
+ var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
11816
11956
  class TsCodegen {
11817
11957
  constructor(typeExprCodegen, docRenderer) {
11818
11958
  this.typeExprCodegen = typeExprCodegen;
11819
- __publicField$a(this, "usedTypeRefs", []);
11820
- __publicField$a(this, "usedTypeRefKeys", /* @__PURE__ */ new Set());
11821
- __publicField$a(this, "docRenderer");
11822
- __publicField$a(this, "typeExpr", (typeExpr) => {
11959
+ __publicField$8(this, "usedTypeRefs", []);
11960
+ __publicField$8(this, "usedTypeRefKeys", /* @__PURE__ */ new Set());
11961
+ __publicField$8(this, "docRenderer");
11962
+ __publicField$8(this, "typeExpr", (typeExpr) => {
11823
11963
  this.collectTypeRefsFromExpr(typeExpr);
11824
11964
  return this.typeExprCodegen.toCode(typeExpr).code;
11825
11965
  });
11826
- __publicField$a(this, "declaration", (name, declaration, options = {}) => {
11966
+ __publicField$8(this, "declaration", (name, declaration, options = {}) => {
11827
11967
  this.collectTypeRefsFromDeclaration(declaration);
11828
11968
  return this.toDeclarationCode(name, declaration, options);
11829
11969
  });
11830
- __publicField$a(this, "toChunk", (name, code, exports$1, imports = []) => {
11970
+ __publicField$8(this, "toChunk", (name, code, exports$1, imports = []) => {
11831
11971
  const exportedSymbols = new Set(exports$1);
11832
11972
  const refs = this.getTypeRefs().filter((ref) => {
11833
11973
  return ref.kind !== "internal" || !exportedSymbols.has(ref.name);
@@ -11840,17 +11980,17 @@ class TsCodegen {
11840
11980
  imports
11841
11981
  };
11842
11982
  });
11843
- __publicField$a(this, "getTypeRefs", () => {
11983
+ __publicField$8(this, "getTypeRefs", () => {
11844
11984
  return this.usedTypeRefs.map((ref) => ({ ...ref }));
11845
11985
  });
11846
- __publicField$a(this, "toDeclarationCode", (name, d, o) => {
11986
+ __publicField$8(this, "toDeclarationCode", (name, d, o) => {
11847
11987
  let code = this.toDeclarationBodyCode(name, d);
11848
11988
  if (o.exported) {
11849
11989
  code = `export ${code}`;
11850
11990
  }
11851
11991
  return this.addDoc(code, d.doc);
11852
11992
  });
11853
- __publicField$a(this, "toDeclarationBodyCode", (name, declaration) => {
11993
+ __publicField$8(this, "toDeclarationBodyCode", (name, declaration) => {
11854
11994
  switch (declaration.kind) {
11855
11995
  case "typeAlias":
11856
11996
  return `type ${name} = ${this.typeExprCodegen.toCode(declaration.typeExpr).code}`;
@@ -11871,7 +12011,7 @@ ${members}
11871
12011
  }
11872
12012
  }
11873
12013
  });
11874
- __publicField$a(this, "addDoc", (code, doc) => {
12014
+ __publicField$8(this, "addDoc", (code, doc) => {
11875
12015
  if (!doc) return code;
11876
12016
  const rendered = this.docRenderer.render(doc);
11877
12017
  return rendered ? `${rendered}
@@ -12003,13 +12143,13 @@ const toTsPropertyKey = (value) => {
12003
12143
  return isTsIdentifier(value) ? value : JSON.stringify(value);
12004
12144
  };
12005
12145
 
12006
- var __defProp$9 = Object.defineProperty;
12007
- var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12008
- var __publicField$9 = (obj, key, value) => __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
12146
+ var __defProp$7 = Object.defineProperty;
12147
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12148
+ var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
12009
12149
  class TypeExprCodegen {
12010
12150
  constructor(docRenderer) {
12011
- __publicField$9(this, "docRenderer");
12012
- __publicField$9(this, "toCode", (typeExpr) => {
12151
+ __publicField$7(this, "docRenderer");
12152
+ __publicField$7(this, "toCode", (typeExpr) => {
12013
12153
  switch (typeExpr.kind) {
12014
12154
  case "reference":
12015
12155
  return this.toReferenceCode(typeExpr);
@@ -12025,7 +12165,7 @@ class TypeExprCodegen {
12025
12165
  }
12026
12166
  }
12027
12167
  });
12028
- __publicField$9(this, "toReferenceCode", (typeExpr) => {
12168
+ __publicField$7(this, "toReferenceCode", (typeExpr) => {
12029
12169
  if (!typeExpr.typeArgs?.length) {
12030
12170
  return {
12031
12171
  code: typeExpr.ref.name,
@@ -12038,7 +12178,7 @@ class TypeExprCodegen {
12038
12178
  ref: typeExpr.ref
12039
12179
  };
12040
12180
  });
12041
- __publicField$9(this, "toInlineCode", (expr) => {
12181
+ __publicField$7(this, "toInlineCode", (expr) => {
12042
12182
  switch (expr.node) {
12043
12183
  case "scalar":
12044
12184
  return expr.name === "integer" ? "number" : expr.name;
@@ -12063,25 +12203,25 @@ class TypeExprCodegen {
12063
12203
  }
12064
12204
  }
12065
12205
  });
12066
- __publicField$9(this, "toIntersectionMemberCode", (typeExpr) => {
12206
+ __publicField$7(this, "toIntersectionMemberCode", (typeExpr) => {
12067
12207
  const rendered = this.toCode(typeExpr).code;
12068
12208
  return this.isUnion(typeExpr) ? `(${rendered})` : rendered;
12069
12209
  });
12070
- __publicField$9(this, "toArrayElementCode", (typeExpr) => {
12210
+ __publicField$7(this, "toArrayElementCode", (typeExpr) => {
12071
12211
  const rendered = this.toCode(typeExpr).code;
12072
12212
  return this.needsGroupingForArrayElement(typeExpr) ? `(${rendered})` : rendered;
12073
12213
  });
12074
- __publicField$9(this, "isUnion", (typeExpr) => {
12214
+ __publicField$7(this, "isUnion", (typeExpr) => {
12075
12215
  return typeExpr.kind === "inline" && typeExpr.expr.node === "union";
12076
12216
  });
12077
- __publicField$9(this, "needsGroupingForArrayElement", (typeExpr) => {
12217
+ __publicField$7(this, "needsGroupingForArrayElement", (typeExpr) => {
12078
12218
  return typeExpr.kind === "inline" && (typeExpr.expr.node === "union" || typeExpr.expr.node === "intersection");
12079
12219
  });
12080
- __publicField$9(this, "toLiteralCode", (value) => {
12220
+ __publicField$7(this, "toLiteralCode", (value) => {
12081
12221
  if (value === null) return "null";
12082
12222
  return JSON.stringify(value);
12083
12223
  });
12084
- __publicField$9(this, "toObjectCode", (properties, additionalProperties) => {
12224
+ __publicField$7(this, "toObjectCode", (properties, additionalProperties) => {
12085
12225
  const members = properties.map(
12086
12226
  (property) => this.toPropertyCode(property)
12087
12227
  );
@@ -12096,7 +12236,7 @@ class TypeExprCodegen {
12096
12236
  ${members.join("\n")}
12097
12237
  }`;
12098
12238
  });
12099
- __publicField$9(this, "toPropertyCode", (property) => {
12239
+ __publicField$7(this, "toPropertyCode", (property) => {
12100
12240
  const name = toTsPropertyKey(property.name);
12101
12241
  const optional = property.required ? "" : "?";
12102
12242
  const propertyCode = `${name}${optional}: ${this.toCode(property.typeExpr).code}`;
@@ -12111,14 +12251,14 @@ ${renderedProperty}` : renderedProperty;
12111
12251
  }
12112
12252
  }
12113
12253
 
12114
- var __defProp$8 = Object.defineProperty;
12115
- var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12116
- var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
12254
+ var __defProp$6 = Object.defineProperty;
12255
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12256
+ var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
12117
12257
  class TsCodegenFactory {
12118
12258
  constructor(docRenderer) {
12119
- __publicField$8(this, "typeExprCodegen");
12120
- __publicField$8(this, "docRenderer");
12121
- __publicField$8(this, "forNewChunk", () => {
12259
+ __publicField$6(this, "typeExprCodegen");
12260
+ __publicField$6(this, "docRenderer");
12261
+ __publicField$6(this, "forNewChunk", () => {
12122
12262
  return new TsCodegen(this.typeExprCodegen, this.docRenderer);
12123
12263
  });
12124
12264
  this.docRenderer = docRenderer;
@@ -12171,13 +12311,13 @@ const isReservedWord = (value) => {
12171
12311
  return RESERVED_WORDS.has(value);
12172
12312
  };
12173
12313
 
12174
- var __defProp$7 = Object.defineProperty;
12175
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12176
- var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
12314
+ var __defProp$5 = Object.defineProperty;
12315
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12316
+ var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
12177
12317
  class ParamsConstructor {
12178
12318
  constructor(options) {
12179
12319
  this.options = options;
12180
- __publicField$7(this, "process", (params, httpPath) => {
12320
+ __publicField$5(this, "process", (params, httpPath) => {
12181
12321
  const pathParamSpec = validatePathParams(params, httpPath);
12182
12322
  const pathParamBindings = pathParamSpec?.bindings;
12183
12323
  const funParams = params.flatMap(
@@ -12197,7 +12337,7 @@ class ParamsConstructor {
12197
12337
  hasQuery
12198
12338
  };
12199
12339
  });
12200
- __publicField$7(this, "renderOperationParams", (param, pathParamSpec) => {
12340
+ __publicField$5(this, "renderOperationParams", (param, pathParamSpec) => {
12201
12341
  if (param.kind !== "path" || !pathParamSpec) {
12202
12342
  return [
12203
12343
  {
@@ -12221,7 +12361,7 @@ class ParamsConstructor {
12221
12361
  }
12222
12362
  ];
12223
12363
  });
12224
- __publicField$7(this, "renderPathTemplateLiteral", (path, pathParamVarName, pathParamBindings) => {
12364
+ __publicField$5(this, "renderPathTemplateLiteral", (path, pathParamVarName, pathParamBindings) => {
12225
12365
  const escapedPath = path.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
12226
12366
  const pathWithParams = escapedPath.replace(
12227
12367
  /\{([^}]+)\}/g,
@@ -12235,7 +12375,7 @@ class ParamsConstructor {
12235
12375
  );
12236
12376
  return `\`${pathWithParams}\``;
12237
12377
  });
12238
- __publicField$7(this, "renderPathParamDestructuring", (pathParamBindings) => {
12378
+ __publicField$5(this, "renderPathParamDestructuring", (pathParamBindings) => {
12239
12379
  const members = Object.entries(pathParamBindings).map(
12240
12380
  ([paramName, binding]) => {
12241
12381
  const key = toTsPropertyKey(paramName);
@@ -12244,7 +12384,7 @@ class ParamsConstructor {
12244
12384
  );
12245
12385
  return `{ ${members.join(", ")} }`;
12246
12386
  });
12247
- __publicField$7(this, "paramName", (p) => {
12387
+ __publicField$5(this, "paramName", (p) => {
12248
12388
  switch (p.kind) {
12249
12389
  case "body":
12250
12390
  return this.options.paramNames.body;
@@ -12365,9 +12505,9 @@ const indentBlock = (value, indent) => {
12365
12505
 
12366
12506
  const consolidateObjectShorthandProperties = (code) => code.replace(/\b([A-Za-z_$][A-Za-z0-9_$]*)\s*:\s*\1\b/g, "$1");
12367
12507
 
12368
- var __defProp$6 = Object.defineProperty;
12369
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12370
- var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
12508
+ var __defProp$4 = Object.defineProperty;
12509
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12510
+ var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
12371
12511
  const REQUEST_PARAMS_TYPE = "RequestParams";
12372
12512
  const REQUEST_PARAMS_DEFAULT = "never";
12373
12513
  const REQUEST_PARAMS_ARG = "params";
@@ -12378,7 +12518,7 @@ class ApiClientCodegen {
12378
12518
  this.opts = opts;
12379
12519
  this.tsCodegenFactory = tsCodegenFactory;
12380
12520
  this.docRenderer = docRenderer;
12381
- __publicField$6(this, "generate", (apiName, operations, doc) => {
12521
+ __publicField$4(this, "generate", (apiName, operations, doc) => {
12382
12522
  const tsCodegen = this.tsCodegenFactory.forNewChunk();
12383
12523
  let httpClientType = tsCodegen.typeExpr({
12384
12524
  kind: "reference",
@@ -12403,7 +12543,7 @@ ${code}`;
12403
12543
  }
12404
12544
  return tsCodegen.toChunk("api", code, [apiName], methodsCode.imports);
12405
12545
  });
12406
- __publicField$6(this, "groupsOpsCode", (codegen, groupedOps) => combineRenderedCode(
12546
+ __publicField$4(this, "groupsOpsCode", (codegen, groupedOps) => combineRenderedCode(
12407
12547
  Object.entries(groupedOps).map(([groupName, ops]) => {
12408
12548
  const methodsCode = this.opsCode(codegen, ops, "object");
12409
12549
  return {
@@ -12417,7 +12557,7 @@ ${code}`;
12417
12557
  }),
12418
12558
  "\n\n"
12419
12559
  ));
12420
- __publicField$6(this, "opsCode", (codegen, operations, target = "class") => {
12560
+ __publicField$4(this, "opsCode", (codegen, operations, target = "class") => {
12421
12561
  const separator = target === "object" ? `,
12422
12562
  ${EMPTY_LINE_MARKER}
12423
12563
  ` : "\n\n";
@@ -12426,7 +12566,7 @@ ${EMPTY_LINE_MARKER}
12426
12566
  separator
12427
12567
  );
12428
12568
  });
12429
- __publicField$6(this, "renderOp", (op, tsCodegen, target) => {
12569
+ __publicField$4(this, "renderOp", (op, tsCodegen, target) => {
12430
12570
  const { signature: sig, http } = op;
12431
12571
  const paramNames = {
12432
12572
  path: "path",
@@ -12468,14 +12608,14 @@ ${EMPTY_LINE_MARKER}
12468
12608
  target
12469
12609
  });
12470
12610
  });
12471
- __publicField$6(this, "wrapInResponseWrapper", (typeExpr, tsCodegen) => {
12611
+ __publicField$4(this, "wrapInResponseWrapper", (typeExpr, tsCodegen) => {
12472
12612
  return tsCodegen.typeExpr({
12473
12613
  kind: "reference",
12474
12614
  ref: this.opts.httpClient.responseWrapper,
12475
12615
  typeArgs: [typeExpr]
12476
12616
  });
12477
12617
  });
12478
- __publicField$6(this, "renderFunctionCode", ({
12618
+ __publicField$4(this, "renderFunctionCode", ({
12479
12619
  doc,
12480
12620
  funName,
12481
12621
  responseType,
@@ -12524,11 +12664,11 @@ ${functionCode}` : functionCode,
12524
12664
  imports
12525
12665
  };
12526
12666
  });
12527
- __publicField$6(this, "renderOperationDoc", (doc, indent = "") => {
12667
+ __publicField$4(this, "renderOperationDoc", (doc, indent = "") => {
12528
12668
  if (!doc) return null;
12529
12669
  return indentBlock(this.docRenderer.render(this.toTsDoc(doc)), indent);
12530
12670
  });
12531
- __publicField$6(this, "renderApiClientDoc", (doc) => {
12671
+ __publicField$4(this, "renderApiClientDoc", (doc) => {
12532
12672
  if (!doc) return null;
12533
12673
  return this.docRenderer.render({
12534
12674
  nodes: [
@@ -12544,7 +12684,7 @@ ${functionCode}` : functionCode,
12544
12684
  ]
12545
12685
  });
12546
12686
  });
12547
- __publicField$6(this, "toTsDoc", (doc) => {
12687
+ __publicField$4(this, "toTsDoc", (doc) => {
12548
12688
  const nodes = [
12549
12689
  {
12550
12690
  key: "id",
@@ -12586,7 +12726,7 @@ const combineRenderedCode = (fragments, separator) => ({
12586
12726
  imports: fragments.flatMap((fragment) => fragment.imports)
12587
12727
  });
12588
12728
 
12589
- var httpClientPromiseTypesSource = "import type { HttpResponse, Request } from './common-types'\n\nexport type HttpClient<RequestParams = never> = {\n request: <Data>(\n req: Request,\n params?: RequestParams\n ) => Promise<HttpResponse<Data>>\n}\n";
12729
+ var httpClientPromiseTypesSource = "import type { HttpRequest, HttpResponse } from './common-types'\n\nexport type HttpClient<RequestParams = never> = {\n request: <Data>(\n req: HttpRequest,\n params?: RequestParams\n ) => Promise<HttpResponse<Data>>\n}\n";
12590
12730
 
12591
12731
  const promiseHttpClientRenderSpec = () => ({
12592
12732
  typeName: {
@@ -12628,7 +12768,7 @@ ${requestParamsVar}` : ""})${unwrap ? `.then(res => res.body)` : ""}
12628
12768
  }
12629
12769
  });
12630
12770
 
12631
- var httpClientObservableTypesSource = "import { Observable } from 'rxjs'\nimport type { HttpResponse, Request } from './common-types'\n\nexport type HttpClient<RequestParams = never> = {\n request: <Data>(\n req: Request,\n params?: RequestParams\n ) => Observable<HttpResponse<Data>>\n}\n";
12771
+ var httpClientObservableTypesSource = "import { Observable } from 'rxjs'\nimport type { HttpRequest, HttpResponse } from './common-types'\n\nexport type HttpClient<RequestParams = never> = {\n request: <Data>(\n req: HttpRequest,\n params?: RequestParams\n ) => Observable<HttpResponse<Data>>\n}\n";
12632
12772
 
12633
12773
  const rxJsHttpClientRenderSpec = () => ({
12634
12774
  typeName: {
@@ -12801,7 +12941,7 @@ const runtimeImportKey = (runtimeImport) => [
12801
12941
  runtimeImport.typeOnly === true ? "type" : "value"
12802
12942
  ].join("|");
12803
12943
 
12804
- var httpClientCommonTypesSource = "export type KnownRequestContentType =\n | 'application/json'\n | 'multipart/form-data'\n | 'application/x-www-form-urlencoded'\n\nexport type RequestContentType = KnownRequestContentType | string\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | QueryValue[]\n | Record<string, any>\n // Empty schema support\n | unknown\n\nexport type QueryParams = Record<string, QueryValue>\n\nexport type Request = {\n path: string\n method: 'GET' | 'POST' | 'PUT' | 'DELETE'\n responseFormat?: 'json' | 'document'\n headers?: Record<string, string>\n query?: QueryParams\n body?: any\n contentType?: RequestContentType\n}\n\nexport type HttpResponse<Data> = {\n body: Data\n headers: Record<string, string | string[]>\n status: number\n}\n\nexport type QuerySerializer = (params: QueryParams) => string\n";
12944
+ var httpClientCommonTypesSource = "export type KnownRequestContentType =\n | 'application/json'\n | 'multipart/form-data'\n | 'application/x-www-form-urlencoded'\n\nexport type RequestContentType = KnownRequestContentType | string\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | QueryValue[]\n | Record<string, any>\n // Empty schema support\n | unknown\n\nexport type QueryParams = Record<string, QueryValue>\n\nexport type HttpRequest = {\n path: string\n method: 'GET' | 'POST' | 'PUT' | 'DELETE'\n responseFormat?: 'json' | 'document'\n headers?: Record<string, string>\n query?: QueryParams\n body?: any\n contentType?: RequestContentType\n}\n\nexport type HttpResponse<Data> = {\n body: Data\n headers: Record<string, string | string[]>\n status: number\n}\n\nexport type QuerySerializer = (params: QueryParams) => string\n";
12805
12945
 
12806
12946
  const commonTypesCode = httpClientCommonTypesSource;
12807
12947
  const stripImports = (code) => code.replace(/^import[\s\S]*?from\s+['"][^'"]+['"]\s*;?\n?/gm, "").trim();
@@ -12823,13 +12963,13 @@ const provideHttpClientCode = (gen, opts) => {
12823
12963
  );
12824
12964
  };
12825
12965
 
12826
- var __defProp$5 = Object.defineProperty;
12827
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12828
- var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
12966
+ var __defProp$3 = Object.defineProperty;
12967
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12968
+ var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
12829
12969
  class TsDocRenderer {
12830
12970
  constructor(options) {
12831
12971
  this.options = options;
12832
- __publicField$5(this, "render", (doc, options = {}) => {
12972
+ __publicField$3(this, "render", (doc, options = {}) => {
12833
12973
  if (!this.options.enabled) return "";
12834
12974
  const lines = [];
12835
12975
  this.appendNodes(lines, doc.nodes, options);
@@ -12838,7 +12978,7 @@ class TsDocRenderer {
12838
12978
  }
12839
12979
  return this.renderComment(lines);
12840
12980
  });
12841
- __publicField$5(this, "renderComment", (lines) => {
12981
+ __publicField$3(this, "renderComment", (lines) => {
12842
12982
  if (!this.options.enabled) return "";
12843
12983
  if (!lines.length) return "";
12844
12984
  if (lines.length === 1) {
@@ -12849,7 +12989,7 @@ class TsDocRenderer {
12849
12989
  ${body}
12850
12990
  */`;
12851
12991
  });
12852
- __publicField$5(this, "appendDocText", (lines, value) => {
12992
+ __publicField$3(this, "appendDocText", (lines, value) => {
12853
12993
  const normalized = this.normalizeLines(value);
12854
12994
  if (!normalized.length) return;
12855
12995
  if (lines.length > 0) {
@@ -12857,19 +12997,19 @@ ${body}
12857
12997
  }
12858
12998
  lines.push(...normalized);
12859
12999
  });
12860
- __publicField$5(this, "appendField", (lines, key, value) => {
13000
+ __publicField$3(this, "appendField", (lines, key, value) => {
12861
13001
  const normalized = this.normalizeLines(value);
12862
13002
  if (!normalized.length) return;
12863
13003
  lines.push(`@${key} ${normalized[0]}`.trimEnd());
12864
13004
  lines.push(...normalized.slice(1));
12865
13005
  });
12866
- __publicField$5(this, "appendDeprecated", (lines, options) => {
13006
+ __publicField$3(this, "appendDeprecated", (lines, options) => {
12867
13007
  if (options.separate) {
12868
13008
  lines.push("");
12869
13009
  }
12870
13010
  lines.push("@deprecated");
12871
13011
  });
12872
- __publicField$5(this, "appendNodes", (lines, nodes = [], options = {}) => {
13012
+ __publicField$3(this, "appendNodes", (lines, nodes = [], options = {}) => {
12873
13013
  nodes.forEach((node) => {
12874
13014
  if (typeof node === "string") {
12875
13015
  if (options.compactText) {
@@ -12882,21 +13022,21 @@ ${body}
12882
13022
  this.appendField(lines, node.key, node.value);
12883
13023
  });
12884
13024
  });
12885
- __publicField$5(this, "normalizeLines", (value) => {
13025
+ __publicField$3(this, "normalizeLines", (value) => {
12886
13026
  const trimmed = value?.trim();
12887
13027
  if (!trimmed) return [];
12888
13028
  return trimmed.split(/\r?\n/u).map((line) => line.trimEnd().replaceAll("*/", "*\\/"));
12889
13029
  });
12890
- __publicField$5(this, "normalizeNonEmptyLines", (value) => this.normalizeLines(value).filter((line) => line.length > 0));
13030
+ __publicField$3(this, "normalizeNonEmptyLines", (value) => this.normalizeLines(value).filter((line) => line.length > 0));
12891
13031
  }
12892
13032
  }
12893
13033
 
12894
- const generateTsCode = (clientName, projectResult, opts) => {
13034
+ const generateOpenApiClientFiles = (clientName, input, opts) => {
12895
13035
  const docRenderer = new TsDocRenderer({
12896
13036
  enabled: opts.comments.enabled
12897
13037
  });
12898
13038
  const tsCodegenFac = new TsCodegenFactory(docRenderer);
12899
- const { schemaDefinitions } = projectResult;
13039
+ const { schemaDefinitions } = input;
12900
13040
  const types = [...schemaDefinitions].sort((a, b) => a.name.localeCompare(b.name)).map((def) => {
12901
13041
  const cg = tsCodegenFac.forNewChunk();
12902
13042
  const code = cg.declaration(def.name, def.declaration, {
@@ -12919,8 +13059,8 @@ const generateTsCode = (clientName, projectResult, opts) => {
12919
13059
  );
12920
13060
  const generated = clientCodegen.generate(
12921
13061
  clientName,
12922
- groupsOpsByTag(projectResult.operations),
12923
- projectResult.api
13062
+ input.operations,
13063
+ input.api
12924
13064
  );
12925
13065
  const clientModuleName = `${clientName}.client`;
12926
13066
  const typesModuleName = `${clientName}.types`;
@@ -12947,8 +13087,7 @@ const generateTsCode = (clientName, projectResult, opts) => {
12947
13087
  const all = [typesChunk, httpClientChunk, clientChunk, indexChunk];
12948
13088
  return {
12949
13089
  all,
12950
- typesName: typesChunk.name,
12951
- promiseWrappersNames: [httpClientChunk.name, clientChunk.name]
13090
+ typesName: typesChunk.name
12952
13091
  };
12953
13092
  };
12954
13093
  const createIndexFile = (moduleNames) => ({
@@ -12970,55 +13109,27 @@ const createIndexFile = (moduleNames) => ({
12970
13109
  }
12971
13110
  ]
12972
13111
  });
12973
- const groupsOpsByTag = (operations) => {
12974
- const groupedOps = {};
12975
- const rawTagsByNormalizedName = /* @__PURE__ */ new Map();
12976
- operations.forEach((operation) => {
12977
- const rawTag = operation.tags.find((tag) => tag.trim())?.trim() || "root";
12978
- let groupName;
12979
- try {
12980
- groupName = toTsCamelIdentifier(rawTag, {
12981
- leadingDigitPrefix: "tag"
12982
- });
12983
- } catch {
12984
- throw new Error(
12985
- `Invalid OpenAPI tag "${rawTag}": could not derive a client group name.`
12986
- );
12987
- }
12988
- const existingRawTag = rawTagsByNormalizedName.get(groupName);
12989
- if (existingRawTag && existingRawTag !== rawTag) {
12990
- throw new Error(
12991
- `Tag naming collision: "${existingRawTag}" and "${rawTag}" both normalize to "${groupName}". Rename one of these OpenAPI tags to continue.`
12992
- );
12993
- }
12994
- rawTagsByNormalizedName.set(groupName, rawTag);
12995
- const bucket = groupedOps[groupName] ?? [];
12996
- bucket.push(operation.op);
12997
- groupedOps[groupName] = bucket;
12998
- });
12999
- return groupedOps;
13000
- };
13001
13112
 
13002
- var __defProp$4 = Object.defineProperty;
13003
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13004
- var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
13113
+ var __defProp$2 = Object.defineProperty;
13114
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13115
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
13005
13116
  const TS_IDENTIFIER_PATTERN = /^[$A-Z_][0-9A-Z_$]*$/i;
13006
13117
  class ToTypeExprConverter {
13007
13118
  constructor(schemas = {}, options) {
13008
13119
  this.schemas = schemas;
13009
13120
  this.options = options;
13010
- __publicField$4(this, "schemaCache", /* @__PURE__ */ new WeakMap());
13011
- __publicField$4(this, "refCache", /* @__PURE__ */ new Map());
13012
- __publicField$4(this, "schemaDefinitions", []);
13013
- __publicField$4(this, "schemaDefinitionsById", /* @__PURE__ */ new Map());
13014
- __publicField$4(this, "schemaDefinitionsInProgress", /* @__PURE__ */ new Set());
13015
- __publicField$4(this, "getSchemaDefinitions", () => this.schemaDefinitions);
13016
- __publicField$4(this, "registerAllSchemaDefinitions", () => {
13121
+ __publicField$2(this, "schemaCache", /* @__PURE__ */ new WeakMap());
13122
+ __publicField$2(this, "refCache", /* @__PURE__ */ new Map());
13123
+ __publicField$2(this, "schemaDefinitions", []);
13124
+ __publicField$2(this, "schemaDefinitionsById", /* @__PURE__ */ new Map());
13125
+ __publicField$2(this, "schemaDefinitionsInProgress", /* @__PURE__ */ new Set());
13126
+ __publicField$2(this, "getSchemaDefinitions", () => this.schemaDefinitions);
13127
+ __publicField$2(this, "registerAllSchemaDefinitions", () => {
13017
13128
  Object.keys(this.schemas).forEach((schemaName) => {
13018
13129
  this.ensureSchemaDefinition(`#/components/schemas/${schemaName}`);
13019
13130
  });
13020
13131
  });
13021
- __publicField$4(this, "fromTypeExpr", (schema) => {
13132
+ __publicField$2(this, "fromTypeExpr", (schema) => {
13022
13133
  if (!schema) {
13023
13134
  return this.scalar("unknown");
13024
13135
  }
@@ -13041,14 +13152,14 @@ class ToTypeExprConverter {
13041
13152
  }
13042
13153
  return result;
13043
13154
  });
13044
- __publicField$4(this, "scalar", (name) => ({
13155
+ __publicField$2(this, "scalar", (name) => ({
13045
13156
  kind: "inline",
13046
13157
  expr: {
13047
13158
  node: "scalar",
13048
13159
  name
13049
13160
  }
13050
13161
  }));
13051
- __publicField$4(this, "union", (members) => {
13162
+ __publicField$2(this, "union", (members) => {
13052
13163
  const flatMembers = [];
13053
13164
  for (const member of members) {
13054
13165
  if (member.kind === "inline" && member.expr.node === "union") {
@@ -13068,14 +13179,14 @@ class ToTypeExprConverter {
13068
13179
  }
13069
13180
  };
13070
13181
  });
13071
- __publicField$4(this, "literal", (value) => ({
13182
+ __publicField$2(this, "literal", (value) => ({
13072
13183
  kind: "inline",
13073
13184
  expr: {
13074
13185
  node: "literal",
13075
13186
  value
13076
13187
  }
13077
13188
  }));
13078
- __publicField$4(this, "ref", (id) => {
13189
+ __publicField$2(this, "ref", (id) => {
13079
13190
  const name = this.refNameFromPath(id);
13080
13191
  return {
13081
13192
  kind: "reference",
@@ -13085,14 +13196,14 @@ class ToTypeExprConverter {
13085
13196
  }
13086
13197
  };
13087
13198
  });
13088
- __publicField$4(this, "builtinRef", (name) => ({
13199
+ __publicField$2(this, "builtinRef", (name) => ({
13089
13200
  kind: "reference",
13090
13201
  ref: {
13091
13202
  kind: "builtin",
13092
13203
  name
13093
13204
  }
13094
13205
  }));
13095
- __publicField$4(this, "refNameFromPath", (ref) => {
13206
+ __publicField$2(this, "refNameFromPath", (ref) => {
13096
13207
  const parts = ref.split("/");
13097
13208
  const name = parts[parts.length - 1];
13098
13209
  if (!name) {
@@ -13100,16 +13211,16 @@ class ToTypeExprConverter {
13100
13211
  }
13101
13212
  return name;
13102
13213
  });
13103
- __publicField$4(this, "refCacheKey", (schema) => {
13214
+ __publicField$2(this, "refCacheKey", (schema) => {
13104
13215
  return `${schema.$ref}|nullable:${schema.nullable === true}`;
13105
13216
  });
13106
- __publicField$4(this, "isUnconstrainedSchema", (schema) => {
13217
+ __publicField$2(this, "isUnconstrainedSchema", (schema) => {
13107
13218
  const meaningfulKeys = Object.keys(schema).filter(
13108
13219
  (key) => key !== "nullable"
13109
13220
  );
13110
13221
  return meaningfulKeys.length === 0;
13111
13222
  });
13112
- __publicField$4(this, "ensureSchemaDefinition", (refId) => {
13223
+ __publicField$2(this, "ensureSchemaDefinition", (refId) => {
13113
13224
  if (this.schemaDefinitionsById.has(refId) || this.schemaDefinitionsInProgress.has(refId)) {
13114
13225
  return;
13115
13226
  }
@@ -13130,18 +13241,18 @@ class ToTypeExprConverter {
13130
13241
  this.schemaDefinitionsInProgress.delete(refId);
13131
13242
  }
13132
13243
  });
13133
- __publicField$4(this, "isSchemaNode", (value) => {
13244
+ __publicField$2(this, "isSchemaNode", (value) => {
13134
13245
  return Boolean(
13135
13246
  value && typeof value === "object" && !Array.isArray(value)
13136
13247
  );
13137
13248
  });
13138
- __publicField$4(this, "toLiteralValue", (value) => {
13249
+ __publicField$2(this, "toLiteralValue", (value) => {
13139
13250
  if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
13140
13251
  return value;
13141
13252
  }
13142
13253
  throw new Error(`Unsupported literal value: ${String(value)}`);
13143
13254
  });
13144
- __publicField$4(this, "toDeclaration", (schema) => {
13255
+ __publicField$2(this, "toDeclaration", (schema) => {
13145
13256
  const enumDeclaration = this.toEnumDeclaration(schema);
13146
13257
  if (enumDeclaration) {
13147
13258
  return enumDeclaration;
@@ -13152,7 +13263,7 @@ class ToTypeExprConverter {
13152
13263
  typeExpr: this.fromTypeExpr(schema)
13153
13264
  };
13154
13265
  });
13155
- __publicField$4(this, "toEnumDeclaration", (schema) => {
13266
+ __publicField$2(this, "toEnumDeclaration", (schema) => {
13156
13267
  if (this.options.enumStyle !== "enum" || !Array.isArray(schema.enum)) {
13157
13268
  return void 0;
13158
13269
  }
@@ -13167,7 +13278,7 @@ class ToTypeExprConverter {
13167
13278
  members: this.toEnumMembers(schema.enum)
13168
13279
  };
13169
13280
  });
13170
- __publicField$4(this, "getEnumValueType", (values) => {
13281
+ __publicField$2(this, "getEnumValueType", (values) => {
13171
13282
  if (!values.length) {
13172
13283
  return void 0;
13173
13284
  }
@@ -13179,7 +13290,7 @@ class ToTypeExprConverter {
13179
13290
  }
13180
13291
  return void 0;
13181
13292
  });
13182
- __publicField$4(this, "toEnumMembers", (values) => {
13293
+ __publicField$2(this, "toEnumMembers", (values) => {
13183
13294
  const usedNames = /* @__PURE__ */ new Map();
13184
13295
  return values.map((value, index) => {
13185
13296
  const enumValue = value;
@@ -13192,7 +13303,7 @@ class ToTypeExprConverter {
13192
13303
  };
13193
13304
  });
13194
13305
  });
13195
- __publicField$4(this, "toEnumMemberBaseName", (value, index) => {
13306
+ __publicField$2(this, "toEnumMemberBaseName", (value, index) => {
13196
13307
  if (typeof value === "string" && this.options.uppercaseEnumKeys) {
13197
13308
  const compatName = this.toCompatEnumMemberName(value);
13198
13309
  if (compatName) {
@@ -13208,14 +13319,14 @@ class ToTypeExprConverter {
13208
13319
  const pascalName = toPascalCaseIdentifier(String(value));
13209
13320
  return pascalName === "Api" ? `Value${index + 1}` : pascalName;
13210
13321
  });
13211
- __publicField$4(this, "toCompatEnumMemberName", (value) => {
13322
+ __publicField$2(this, "toCompatEnumMemberName", (value) => {
13212
13323
  if (/^([A-Z_]{1,})$/g.test(value)) {
13213
13324
  return value;
13214
13325
  }
13215
13326
  const pascalName = toPascalCaseIdentifier(value);
13216
13327
  return pascalName === "Api" ? void 0 : pascalName;
13217
13328
  });
13218
- __publicField$4(this, "isScalarName", (value) => {
13329
+ __publicField$2(this, "isScalarName", (value) => {
13219
13330
  switch (value) {
13220
13331
  case "string":
13221
13332
  case "number":
@@ -13231,7 +13342,7 @@ class ToTypeExprConverter {
13231
13342
  return false;
13232
13343
  }
13233
13344
  });
13234
- __publicField$4(this, "hasNullMember", (expr) => {
13345
+ __publicField$2(this, "hasNullMember", (expr) => {
13235
13346
  if (expr.kind !== "inline") return false;
13236
13347
  if (expr.expr.node === "scalar") {
13237
13348
  return expr.expr.name === "null";
@@ -13241,13 +13352,13 @@ class ToTypeExprConverter {
13241
13352
  }
13242
13353
  return false;
13243
13354
  });
13244
- __publicField$4(this, "withNullable", (expr) => {
13355
+ __publicField$2(this, "withNullable", (expr) => {
13245
13356
  if (this.hasNullMember(expr)) {
13246
13357
  return expr;
13247
13358
  }
13248
13359
  return this.union([expr, this.scalar("null")]);
13249
13360
  });
13250
- __publicField$4(this, "projectObjectType", (schema) => {
13361
+ __publicField$2(this, "projectObjectType", (schema) => {
13251
13362
  const requiredRaw = schema.required;
13252
13363
  if (requiredRaw !== void 0 && !Array.isArray(requiredRaw)) {
13253
13364
  throw new Error(
@@ -13312,7 +13423,7 @@ class ToTypeExprConverter {
13312
13423
  }
13313
13424
  };
13314
13425
  });
13315
- __publicField$4(this, "isRequiredProperty", (name, required, propertySchema) => {
13426
+ __publicField$2(this, "isRequiredProperty", (name, required, propertySchema) => {
13316
13427
  if (required.has(name)) {
13317
13428
  return true;
13318
13429
  }
@@ -13321,7 +13432,7 @@ class ToTypeExprConverter {
13321
13432
  }
13322
13433
  return propertySchema.required === true;
13323
13434
  });
13324
- __publicField$4(this, "mapSchemaArrayMembers", (value, kind) => {
13435
+ __publicField$2(this, "mapSchemaArrayMembers", (value, kind) => {
13325
13436
  if (!Array.isArray(value) || !value.length) {
13326
13437
  throw new Error(
13327
13438
  `Unsupported schema: ${kind} must be a non-empty array`
@@ -13336,10 +13447,10 @@ class ToTypeExprConverter {
13336
13447
  return this.fromTypeExpr(entry);
13337
13448
  });
13338
13449
  });
13339
- __publicField$4(this, "isBinaryFileSchema", (schema) => {
13450
+ __publicField$2(this, "isBinaryFileSchema", (schema) => {
13340
13451
  return schema.type === "string" && schema.format === "binary";
13341
13452
  });
13342
- __publicField$4(this, "getSchemaDoc", (schema) => {
13453
+ __publicField$2(this, "getSchemaDoc", (schema) => {
13343
13454
  const summary = typeof schema.summary === "string" ? schema.summary : void 0;
13344
13455
  const description = typeof schema.description === "string" ? schema.description : void 0;
13345
13456
  const deprecated = typeof schema.deprecated === "boolean" ? schema.deprecated : void 0;
@@ -13360,7 +13471,7 @@ class ToTypeExprConverter {
13360
13471
  nodes
13361
13472
  };
13362
13473
  });
13363
- __publicField$4(this, "getSchemaAnnotations", (schema) => {
13474
+ __publicField$2(this, "getSchemaAnnotations", (schema) => {
13364
13475
  if (this.options.comments?.metadata === false) return [];
13365
13476
  return [
13366
13477
  this.annotationNode("format", schema.format),
@@ -13387,14 +13498,14 @@ class ToTypeExprConverter {
13387
13498
  (value) => value !== void 0
13388
13499
  );
13389
13500
  });
13390
- __publicField$4(this, "annotationNode", (name, value) => {
13501
+ __publicField$2(this, "annotationNode", (name, value) => {
13391
13502
  if (value === void 0) return void 0;
13392
13503
  return {
13393
13504
  key: name,
13394
13505
  value: String(value)
13395
13506
  };
13396
13507
  });
13397
- __publicField$4(this, "stringifyAnnotationValue", (value) => {
13508
+ __publicField$2(this, "stringifyAnnotationValue", (value) => {
13398
13509
  if (value === void 0) return void 0;
13399
13510
  if (value && typeof value === "object") {
13400
13511
  return JSON.stringify(value);
@@ -13404,7 +13515,7 @@ class ToTypeExprConverter {
13404
13515
  }
13405
13516
  return String(value);
13406
13517
  });
13407
- __publicField$4(this, "fromSchemaCore", (schema) => {
13518
+ __publicField$2(this, "fromSchemaCore", (schema) => {
13408
13519
  if (this.isUnconstrainedSchema(schema)) {
13409
13520
  return this.scalar("unknown");
13410
13521
  }
@@ -13484,9 +13595,9 @@ class ToTypeExprConverter {
13484
13595
  }
13485
13596
  }
13486
13597
 
13487
- var __defProp$3 = Object.defineProperty;
13488
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13489
- var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
13598
+ var __defProp$1 = Object.defineProperty;
13599
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13600
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
13490
13601
  const pickPreferredMediaType = (mediaTypes) => {
13491
13602
  if (!mediaTypes.length) return void 0;
13492
13603
  const exactJson = mediaTypes.find((media) => media === "application/json");
@@ -13566,10 +13677,10 @@ const toHttpMethodUpper = (method) => {
13566
13677
  class OperationProjector {
13567
13678
  constructor(options) {
13568
13679
  this.options = options;
13569
- __publicField$3(this, "seenOperationIds", /* @__PURE__ */ new Set());
13570
- __publicField$3(this, "typeExprConverter");
13571
- __publicField$3(this, "project", (openApi) => {
13572
- this.seenOperationIds.clear();
13680
+ __publicField$1(this, "rawOperationIdsByName", /* @__PURE__ */ new Map());
13681
+ __publicField$1(this, "typeExprConverter");
13682
+ __publicField$1(this, "project", (openApi) => {
13683
+ this.rawOperationIdsByName.clear();
13573
13684
  this.typeExprConverter = new ToTypeExprConverter(
13574
13685
  openApi.schemas,
13575
13686
  this.options.typeExtraction
@@ -13578,16 +13689,32 @@ class OperationProjector {
13578
13689
  this.typeExprConverter.registerAllSchemaDefinitions();
13579
13690
  }
13580
13691
  const operations = openApi.operations.map((operation) => {
13581
- const operationName = (operation.operationId ?? syntheticOperationId(operation.method, operation.path)).trim();
13582
- if (!operationName) {
13692
+ const operationId = (operation.operationId ?? syntheticOperationId(operation.method, operation.path)).trim();
13693
+ if (!operationId) {
13583
13694
  throw new Error(
13584
13695
  `Operation id is empty for ${operation.method.toUpperCase()} ${operation.path}`
13585
13696
  );
13586
13697
  }
13587
- if (this.seenOperationIds.has(operationName)) {
13588
- throw new Error(`Duplicate operation id: ${operationName}`);
13698
+ let operationName;
13699
+ try {
13700
+ operationName = toTsCamelIdentifier(operationId, {
13701
+ leadingDigitPrefix: "operation"
13702
+ });
13703
+ } catch {
13704
+ throw new Error(
13705
+ `Invalid operation id "${operationId}": could not derive a client method name.`
13706
+ );
13707
+ }
13708
+ const existingRawOperationId = this.rawOperationIdsByName.get(operationName);
13709
+ if (existingRawOperationId) {
13710
+ if (existingRawOperationId === operationId) {
13711
+ throw new Error(`Duplicate operation id: ${operationId}`);
13712
+ }
13713
+ throw new Error(
13714
+ `Operation naming collision: "${existingRawOperationId}" and "${operationId}" both normalize to "${operationName}". Rename one of these OpenAPI operation ids to continue.`
13715
+ );
13589
13716
  }
13590
- return this.projectOne(operationName, operation);
13717
+ return this.projectOne(operationId, operationName, operation);
13591
13718
  });
13592
13719
  return {
13593
13720
  api: {
@@ -13599,8 +13726,8 @@ class OperationProjector {
13599
13726
  schemaDefinitions: this.typeExprConverter.getSchemaDefinitions()
13600
13727
  };
13601
13728
  });
13602
- __publicField$3(this, "projectOne", (operationName, operation) => {
13603
- this.seenOperationIds.add(operationName);
13729
+ __publicField$1(this, "projectOne", (operationId, operationName, operation) => {
13730
+ this.rawOperationIdsByName.set(operationName, operationId);
13604
13731
  const parameters = [];
13605
13732
  const pathParameter = this.projectPathParameter(operation);
13606
13733
  const queryParameter = this.projectQueryParameter(operation);
@@ -13611,7 +13738,7 @@ class OperationProjector {
13611
13738
  return {
13612
13739
  op: {
13613
13740
  signature: {
13614
- doc: this.toOperationDoc(operationName, operation),
13741
+ doc: this.toOperationDoc(operationId, operation),
13615
13742
  name: operationName,
13616
13743
  parameters,
13617
13744
  returnType: this.projectReturnType(operation)
@@ -13628,7 +13755,7 @@ class OperationProjector {
13628
13755
  tags: [...operation.tags]
13629
13756
  };
13630
13757
  });
13631
- __publicField$3(this, "projectRequestContentType", (requestBody) => {
13758
+ __publicField$1(this, "projectRequestContentType", (requestBody) => {
13632
13759
  const { mediaType } = getPreferredMediaTypeEntry(
13633
13760
  requestBody?.content ?? {}
13634
13761
  );
@@ -13641,7 +13768,7 @@ class OperationProjector {
13641
13768
  return void 0;
13642
13769
  }
13643
13770
  });
13644
- __publicField$3(this, "projectResponseFormat", (operation) => {
13771
+ __publicField$1(this, "projectResponseFormat", (operation) => {
13645
13772
  const selectedResponses = selectReturnResponses(operation.responses);
13646
13773
  if (!selectedResponses.length) {
13647
13774
  return void 0;
@@ -13658,7 +13785,7 @@ class OperationProjector {
13658
13785
  }
13659
13786
  return void 0;
13660
13787
  });
13661
- __publicField$3(this, "projectParameterGroupTypeExpr", (params) => {
13788
+ __publicField$1(this, "projectParameterGroupTypeExpr", (params) => {
13662
13789
  const properties = Object.entries(params).map(([name, parameter]) => ({
13663
13790
  doc: this.toParameterDoc(parameter),
13664
13791
  name,
@@ -13675,7 +13802,7 @@ class OperationProjector {
13675
13802
  }
13676
13803
  };
13677
13804
  });
13678
- __publicField$3(this, "projectPathParameter", (operation) => {
13805
+ __publicField$1(this, "projectPathParameter", (operation) => {
13679
13806
  const params = operation.parameters.path;
13680
13807
  const entries = Object.values(params);
13681
13808
  if (!entries.length) return null;
@@ -13688,7 +13815,7 @@ class OperationProjector {
13688
13815
  typeExpr: this.projectParameterGroupTypeExpr(params)
13689
13816
  };
13690
13817
  });
13691
- __publicField$3(this, "projectQueryParameter", (operation) => {
13818
+ __publicField$1(this, "projectQueryParameter", (operation) => {
13692
13819
  const params = operation.parameters.query;
13693
13820
  const entries = Object.values(params);
13694
13821
  if (!entries.length) return null;
@@ -13698,7 +13825,7 @@ class OperationProjector {
13698
13825
  typeExpr: this.projectParameterGroupTypeExpr(params)
13699
13826
  };
13700
13827
  });
13701
- __publicField$3(this, "projectBodyParameter", (operation) => {
13828
+ __publicField$1(this, "projectBodyParameter", (operation) => {
13702
13829
  const requestBody = operation.requestBody;
13703
13830
  if (!requestBody) return null;
13704
13831
  return {
@@ -13709,7 +13836,7 @@ class OperationProjector {
13709
13836
  )
13710
13837
  };
13711
13838
  });
13712
- __publicField$3(this, "projectReturnType", (operation) => {
13839
+ __publicField$1(this, "projectReturnType", (operation) => {
13713
13840
  const selectedResponses = selectReturnResponses(operation.responses);
13714
13841
  if (!selectedResponses.length) {
13715
13842
  return this.typeExprConverter.scalar("void");
@@ -13723,17 +13850,17 @@ class OperationProjector {
13723
13850
  });
13724
13851
  return this.typeExprConverter.union(responseTypes);
13725
13852
  });
13726
- __publicField$3(this, "selectParameterSchema", (parameter) => {
13853
+ __publicField$1(this, "selectParameterSchema", (parameter) => {
13727
13854
  if (parameter.schema) return parameter.schema;
13728
13855
  return getPreferredMediaTypeEntry(parameter.content).media?.schema;
13729
13856
  });
13730
- __publicField$3(this, "selectRequestBodySchema", (requestBody) => {
13857
+ __publicField$1(this, "selectRequestBodySchema", (requestBody) => {
13731
13858
  return getPreferredMediaTypeEntry(requestBody.content).media?.schema;
13732
13859
  });
13733
- __publicField$3(this, "selectResponseSchema", (response) => {
13860
+ __publicField$1(this, "selectResponseSchema", (response) => {
13734
13861
  return getPreferredMediaTypeEntry(response.content).media?.schema;
13735
13862
  });
13736
- __publicField$3(this, "toParameterDoc", (parameter) => {
13863
+ __publicField$1(this, "toParameterDoc", (parameter) => {
13737
13864
  if (!parameter.description && !parameter.deprecated) {
13738
13865
  return void 0;
13739
13866
  }
@@ -13742,7 +13869,7 @@ class OperationProjector {
13742
13869
  nodes: parameter.description ? [parameter.description] : []
13743
13870
  };
13744
13871
  });
13745
- __publicField$3(this, "toOperationDoc", (operationName, operation) => {
13872
+ __publicField$1(this, "toOperationDoc", (operationName, operation) => {
13746
13873
  return {
13747
13874
  id: operationName,
13748
13875
  request: `${toHttpMethodUpper(operation.method)}:${operation.path}`,
@@ -13802,21 +13929,21 @@ const renderImportedSymbol = (importedSymbol, importKind) => [
13802
13929
  importedSymbol.alias ? `as ${importedSymbol.alias}` : void 0
13803
13930
  ].filter(Boolean).join(" ");
13804
13931
 
13805
- var __defProp$2 = Object.defineProperty;
13806
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13807
- var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
13932
+ var __defProp = Object.defineProperty;
13933
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13934
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
13808
13935
  class CodeWriter {
13809
13936
  constructor(formatter, fw) {
13810
13937
  this.formatter = formatter;
13811
13938
  this.fw = fw;
13812
- __publicField$2(this, "symbolChunkMap", /* @__PURE__ */ new Map());
13813
- __publicField$2(this, "resolveModuleName", (chunkName) => {
13939
+ __publicField(this, "symbolChunkMap", /* @__PURE__ */ new Map());
13940
+ __publicField(this, "resolveModuleName", (chunkName) => {
13814
13941
  return this.fw.resolveName({
13815
13942
  name: chunkName,
13816
13943
  ext: "ts"
13817
13944
  });
13818
13945
  });
13819
- __publicField$2(this, "write", async (files) => {
13946
+ __publicField(this, "write", async (files) => {
13820
13947
  this.symbolChunkMap = this.createSymbolChunkMap(files);
13821
13948
  const writtenPaths = {};
13822
13949
  for (const file of files) {
@@ -13834,7 +13961,7 @@ class CodeWriter {
13834
13961
  }
13835
13962
  return writtenPaths;
13836
13963
  });
13837
- __publicField$2(this, "createSymbolChunkMap", (files) => {
13964
+ __publicField(this, "createSymbolChunkMap", (files) => {
13838
13965
  const map = /* @__PURE__ */ new Map();
13839
13966
  for (const chunk of files) {
13840
13967
  if (isTsBarrelFile(chunk)) continue;
@@ -13849,7 +13976,7 @@ class CodeWriter {
13849
13976
  }
13850
13977
  return map;
13851
13978
  });
13852
- __publicField$2(this, "renderCodeChunk", (chunk) => {
13979
+ __publicField(this, "renderCodeChunk", (chunk) => {
13853
13980
  const imports = this.collectImports(chunk).map(
13854
13981
  this.toImportStatementSymbol
13855
13982
  );
@@ -13859,10 +13986,10 @@ class CodeWriter {
13859
13986
  ` : "";
13860
13987
  return importCode + chunk.code;
13861
13988
  });
13862
- __publicField$2(this, "renderBarrelFile", (file) => file.exports.map(
13989
+ __publicField(this, "renderBarrelFile", (file) => file.exports.map(
13863
13990
  (exportStatement) => this.renderBarrelExportStatement(exportStatement)
13864
13991
  ).join("\n"));
13865
- __publicField$2(this, "renderBarrelExportStatement", (exportStatement) => {
13992
+ __publicField(this, "renderBarrelExportStatement", (exportStatement) => {
13866
13993
  const from = `./${this.resolveModuleName(exportStatement.from)}`;
13867
13994
  if (exportStatement.kind === "all") {
13868
13995
  return exportStatement.typeOnly ? `export type * from '${from}'` : `export * from '${from}'`;
@@ -13873,7 +14000,7 @@ class CodeWriter {
13873
14000
  }).join(", ");
13874
14001
  return `export { ${names} } from '${from}'`;
13875
14002
  });
13876
- __publicField$2(this, "collectImports", (chunk) => {
14003
+ __publicField(this, "collectImports", (chunk) => {
13877
14004
  const imports = [];
13878
14005
  for (const ref of chunk.refs) {
13879
14006
  if (ref.kind === "builtin") continue;
@@ -13906,13 +14033,13 @@ class CodeWriter {
13906
14033
  }
13907
14034
  return imports;
13908
14035
  });
13909
- __publicField$2(this, "toImportStatementSymbol", (importedSymbol) => ({
14036
+ __publicField(this, "toImportStatementSymbol", (importedSymbol) => ({
13910
14037
  name: importedSymbol.name,
13911
14038
  alias: importedSymbol.alias,
13912
14039
  source: this.importSourceToString(importedSymbol.source),
13913
14040
  typeOnly: importedSymbol.typeOnly
13914
14041
  }));
13915
- __publicField$2(this, "importSourceToString", (src) => {
14042
+ __publicField(this, "importSourceToString", (src) => {
13916
14043
  return "module" in src ? src.module : (
13917
14044
  // TODO generalize later when we have different paths
13918
14045
  `./${this.resolveModuleName(src.name)}`
@@ -13927,7 +14054,7 @@ const getWriteOpts = (file) => ({
13927
14054
  noSuffix: isTsBarrelFile(file)
13928
14055
  });
13929
14056
 
13930
- class VNextOasClientGenerator {
14057
+ class OpenApiClientGenerator {
13931
14058
  constructor(options, log) {
13932
14059
  this.options = options;
13933
14060
  this.log = log;
@@ -13949,17 +14076,17 @@ class VNextOasClientGenerator {
13949
14076
  }).project(openApiIr);
13950
14077
  const writer = new CodeWriter(formatter, fw);
13951
14078
  const clientName = toPascalCaseIdentifier(apiName);
13952
- const chunks = generateTsCode(clientName, projectResult, {
14079
+ const input = {
14080
+ api: projectResult.api,
14081
+ operations: this.groupOpsByTag(projectResult.operations),
14082
+ schemaDefinitions: projectResult.schemaDefinitions
14083
+ };
14084
+ const chunks = generateOpenApiClientFiles(clientName, input, {
13953
14085
  ...this.options.codegen,
13954
14086
  httpClient: this.options.httpClient
13955
14087
  });
13956
14088
  const writtenPaths = await writer.write(chunks.all);
13957
- return {
13958
- promiseWrapper: chunks.promiseWrappersNames.map(
13959
- (name) => writtenPaths[name]
13960
- ),
13961
- types: writtenPaths[chunks.typesName]
13962
- };
14089
+ return writtenPaths[chunks.typesName];
13963
14090
  }
13964
14091
  filterOperations(openApiIr) {
13965
14092
  const ignoreTags = new Set(
@@ -13979,6 +14106,34 @@ class VNextOasClientGenerator {
13979
14106
  })
13980
14107
  };
13981
14108
  }
14109
+ groupOpsByTag(operations) {
14110
+ const groupedOps = {};
14111
+ const rawTagsByNormalizedName = /* @__PURE__ */ new Map();
14112
+ operations.forEach((operation) => {
14113
+ const rawTag = operation.tags.find((tag) => tag.trim())?.trim() || "root";
14114
+ let groupName;
14115
+ try {
14116
+ groupName = toTsCamelIdentifier(rawTag, {
14117
+ leadingDigitPrefix: "tag"
14118
+ });
14119
+ } catch {
14120
+ throw new Error(
14121
+ `Invalid OpenAPI tag "${rawTag}": could not derive a client group name.`
14122
+ );
14123
+ }
14124
+ const existingRawTag = rawTagsByNormalizedName.get(groupName);
14125
+ if (existingRawTag && existingRawTag !== rawTag) {
14126
+ throw new Error(
14127
+ `Tag naming collision: "${existingRawTag}" and "${rawTag}" both normalize to "${groupName}". Rename one of these OpenAPI tags to continue.`
14128
+ );
14129
+ }
14130
+ rawTagsByNormalizedName.set(groupName, rawTag);
14131
+ const bucket = groupedOps[groupName] ?? [];
14132
+ bucket.push(operation.op);
14133
+ groupedOps[groupName] = bucket;
14134
+ });
14135
+ return groupedOps;
14136
+ }
13982
14137
  normalizeSchema(rawSchema, inputFile) {
13983
14138
  const { result, problems } = new OpenApiNormalizer(rawSchema).load();
13984
14139
  problems.forEach((problem) => {
@@ -14021,11 +14176,11 @@ const toErrorMessage = (error) => {
14021
14176
  return error instanceof Error ? error.message : String(error);
14022
14177
  };
14023
14178
 
14024
- const generateOpenApiModel = async (spectPath, config, log, codeFormatter, fw) => {
14025
- let outFiles;
14179
+ const generateOasModel = async (spectPath, config, log, codeFormatter, fw) => {
14180
+ let typesFilePath;
14026
14181
  const { openApiGenerator } = config;
14027
14182
  if ("legacy" in openApiGenerator) {
14028
- outFiles = await generateOpenApiClient(
14183
+ typesFilePath = await generateOpenApiClient(
14029
14184
  spectPath,
14030
14185
  {
14031
14186
  ...openApiGenerator.legacy,
@@ -14035,7 +14190,7 @@ const generateOpenApiModel = async (spectPath, config, log, codeFormatter, fw) =
14035
14190
  log
14036
14191
  );
14037
14192
  } else {
14038
- outFiles = await new VNextOasClientGenerator(
14193
+ typesFilePath = await new OpenApiClientGenerator(
14039
14194
  openApiGenerator,
14040
14195
  log
14041
14196
  ).generate(
@@ -14048,136 +14203,8 @@ const generateOpenApiModel = async (spectPath, config, log, codeFormatter, fw) =
14048
14203
  fw
14049
14204
  );
14050
14205
  }
14051
- return { typesFilePath: outFiles.types };
14052
- };
14053
-
14054
- const removeGenericTypes = (code) => {
14055
- const declarations = [];
14056
- const declarationStartRegex = /^export\s+(interface|enum|type)\s+[A-Za-z0-9_]+(?:<[^>\n]+>)?/gm;
14057
- let match;
14058
- while ((match = declarationStartRegex.exec(code)) !== null) {
14059
- const declaration = extractDeclaration(code, match);
14060
- if (!declaration) continue;
14061
- declarations.push(declaration);
14062
- declarationStartRegex.lastIndex = match.index + declaration.length;
14063
- }
14064
- return declarations.join("\n\n");
14206
+ return { typesFilePath };
14065
14207
  };
14066
- const extractDeclaration = (code, match) => {
14067
- const header = match[0];
14068
- if (header.includes("<")) return null;
14069
- const kind = match[1];
14070
- let cursor = match.index + header.length;
14071
- if (kind === "type") {
14072
- cursor = skipWhitespace(code, cursor);
14073
- if (code[cursor] !== "=") return null;
14074
- cursor = skipWhitespace(code, cursor + 1);
14075
- if (code[cursor] !== "{") return null;
14076
- } else {
14077
- cursor = code.indexOf("{", cursor);
14078
- if (cursor === -1) return null;
14079
- }
14080
- const end = findMatchingBrace(code, cursor);
14081
- if (end === -1) return null;
14082
- return code.slice(match.index, end + 1);
14083
- };
14084
- const skipWhitespace = (code, cursor) => {
14085
- while (/\s/.test(code[cursor] ?? "")) {
14086
- cursor += 1;
14087
- }
14088
- return cursor;
14089
- };
14090
- const findMatchingBrace = (code, openBraceIndex) => {
14091
- let depth = 0;
14092
- for (let i = openBraceIndex; i < code.length; i += 1) {
14093
- if (code[i] === "{") depth += 1;
14094
- if (code[i] === "}") {
14095
- depth -= 1;
14096
- if (depth === 0) return i;
14097
- }
14098
- }
14099
- return -1;
14100
- };
14101
-
14102
- var __defProp$1 = Object.defineProperty;
14103
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14104
- var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, key + "" , value);
14105
- class ZodSchemaGenerator {
14106
- constructor(codeFormatter) {
14107
- this.codeFormatter = codeFormatter;
14108
- __publicField$1(this, "generate", async ({
14109
- sourceText,
14110
- moduleImportPath,
14111
- options = {}
14112
- }) => {
14113
- const { getZodSchemasFile } = tsToZod.generate({
14114
- sourceText: removeGenericTypes(sourceText)
14115
- });
14116
- let generated = getZodSchemasFile(moduleImportPath);
14117
- generated = generated.replaceAll(".optional()", ".nullable()");
14118
- generated = generated.replaceAll(".int64()", ".int()");
14119
- if (options.localDateTimes) {
14120
- generated = generated.replaceAll(
14121
- "z.string().datetime()",
14122
- "z.string().datetime({local: true})"
14123
- );
14124
- }
14125
- return this.codeFormatter.format(generated);
14126
- });
14127
- }
14128
- }
14129
-
14130
- var __defProp = Object.defineProperty;
14131
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14132
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
14133
- class FileWriter {
14134
- constructor(outputDir, opts = {}) {
14135
- this.outputDir = outputDir;
14136
- this.opts = opts;
14137
- __publicField(this, "resolveName", (req, opts) => {
14138
- let name = opts?.preserveCase ? req.name : this.setNameCase(req.name);
14139
- if (this.opts.suffix && opts?.noSuffix !== true) {
14140
- name = name + "." + this.opts.suffix;
14141
- }
14142
- if (this.opts.mapFileName)
14143
- name = this.opts.mapFileName({
14144
- name,
14145
- ext: req.ext
14146
- });
14147
- return name;
14148
- });
14149
- __publicField(this, "resolvePath", (req, opts) => this.getResolvedPath(req, opts));
14150
- __publicField(this, "write", async ({ content, ...req }, opts) => {
14151
- const resolvedPath = this.getResolvedPath(req, opts);
14152
- await fs.mkdir(Path.dirname(resolvedPath), { recursive: true });
14153
- await fs.writeFile(resolvedPath, content, "utf8");
14154
- return resolvedPath;
14155
- });
14156
- __publicField(this, "getResolvedPath", ({ path, ext, ...req }, opts) => Path.resolve(
14157
- this.outputDir,
14158
- ...path ?? [],
14159
- `${this.resolveName(
14160
- {
14161
- ext,
14162
- ...req
14163
- },
14164
- opts
14165
- )}.${ext}`
14166
- ));
14167
- __publicField(this, "setNameCase", (name) => {
14168
- const [first, ...rest] = name.split(".");
14169
- const converted = this.transformCase(first);
14170
- return [converted, ...rest].join(".");
14171
- });
14172
- __publicField(this, "transformCase", (value) => {
14173
- const nameCase = this.opts.case ?? "pascal";
14174
- if (nameCase === "kebab") {
14175
- return toKebabCaseIdentifier(value);
14176
- }
14177
- return toPascalCaseIdentifier(value);
14178
- });
14179
- }
14180
- }
14181
14208
 
14182
14209
  const generateApiClient = async (params, configFilePath, log = console.log) => {
14183
14210
  const config = parseProfileConfig(params, configFilePath);
@@ -14212,7 +14239,7 @@ const generateApiClientFromConfig = async (config, log = console.log) => {
14212
14239
  fs__namespace.mkdirSync(clientDir, {
14213
14240
  recursive: true
14214
14241
  });
14215
- const { typesFilePath } = await generateOpenApiModel(
14242
+ const { typesFilePath } = await generateOasModel(
14216
14243
  specPath,
14217
14244
  {
14218
14245
  ...config,