swagger-typescript-api 13.6.11 → 13.7.1

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.
@@ -208,7 +208,7 @@ var ComponentTypeNameResolver = class extends NameResolver {
208
208
  //#endregion
209
209
  //#region package.json
210
210
  var name = "swagger-typescript-api";
211
- var version = "13.6.11";
211
+ var version = "13.7.1";
212
212
  var description = "Generate the API client for Fetch or Axios from an OpenAPI Specification";
213
213
  //#endregion
214
214
  //#region src/constants.ts
@@ -373,6 +373,7 @@ var CodeGenConfig = class {
373
373
  httpClientType = HTTP_CLIENT.FETCH;
374
374
  unwrapResponseData = false;
375
375
  disableThrowOnError = false;
376
+ disableFormatTypeNames = false;
376
377
  sortTypes = false;
377
378
  sortRoutes = false;
378
379
  templatePaths = {
@@ -405,6 +406,7 @@ var CodeGenConfig = class {
405
406
  silent = false;
406
407
  typePrefix = "";
407
408
  typeSuffix = "";
409
+ typeNameSeparator = "_";
408
410
  enumKeyPrefix = "";
409
411
  enumKeySuffix = "";
410
412
  patch = false;
@@ -2845,16 +2847,18 @@ var ResolvedSwaggerSchema = class ResolvedSwaggerSchema {
2845
2847
  }
2846
2848
  collectExternalRefCandidates(externalPath) {
2847
2849
  const candidates = /* @__PURE__ */ new Set();
2848
- if (/^https?:\/\//i.test(externalPath)) return [];
2850
+ const isRemote = /^https?:\/\//i.test(externalPath);
2851
+ const normalizedExternalPath = externalPath.startsWith("/") ? externalPath.replace(/^\/+/, "") : externalPath;
2852
+ if (isRemote) return [];
2849
2853
  if (node_path.default.isAbsolute(externalPath)) candidates.add(externalPath);
2850
2854
  const inputPath = this.config.input;
2851
- if (typeof inputPath === "string" && inputPath) candidates.add(node_path.default.resolve(node_path.default.dirname(inputPath), externalPath));
2855
+ if (typeof inputPath === "string" && inputPath) candidates.add(node_path.default.resolve(node_path.default.dirname(inputPath), normalizedExternalPath));
2852
2856
  for (const resolver of this.resolvers) try {
2853
2857
  const resolverPaths = typeof resolver.paths === "function" ? resolver.paths() : [];
2854
2858
  for (const resolverPath of resolverPaths) {
2855
2859
  if (typeof resolverPath !== "string") continue;
2856
2860
  if (/^https?:\/\//i.test(resolverPath)) continue;
2857
- candidates.add(node_path.default.resolve(node_path.default.dirname(resolverPath), externalPath));
2861
+ candidates.add(node_path.default.resolve(node_path.default.dirname(resolverPath), normalizedExternalPath));
2858
2862
  }
2859
2863
  } catch (e) {
2860
2864
  consola.default.debug(e);
@@ -3203,39 +3207,119 @@ var JavascriptTranslator = class extends Translator {
3203
3207
  //#region src/type-name-formatter.ts
3204
3208
  var TypeNameFormatter = class {
3205
3209
  formattedModelNamesMap = /* @__PURE__ */ new Map();
3210
+ usedFormattedTypeNames = /* @__PURE__ */ new Map();
3206
3211
  config;
3207
3212
  constructor(config) {
3208
3213
  this.config = config;
3209
3214
  }
3215
+ /**
3216
+ * Return the TypeScript identifier for a raw OpenAPI name. Fast path is a
3217
+ * cache hit on names resolved by `precommit`. The fallback (for names
3218
+ * discovered after precommit, e.g. enum keys inside schemas or types added
3219
+ * dynamically by `extractEnums`/`extractResponses`) computes the identifier
3220
+ * inline WITHOUT collision handling — collision resolution is the sole
3221
+ * responsibility of `precommit`. Callers expecting collision safety must
3222
+ * list every raw name in the precommit input.
3223
+ */
3210
3224
  format = (name, options = {}) => {
3211
3225
  const schemaType = options.type ?? "type-name";
3212
- const typePrefix = schemaType === "enum-key" ? this.config.enumKeyPrefix : this.config.typePrefix;
3213
- const typeSuffix = schemaType === "enum-key" ? this.config.enumKeySuffix : this.config.typeSuffix;
3226
+ const { typePrefix, typeSuffix } = this.getAffixes(schemaType);
3214
3227
  const hashKey = `${typePrefix}_${name}_${typeSuffix}`;
3228
+ const cached = this.formattedModelNamesMap.get(hashKey);
3229
+ if (cached !== void 0) return cached;
3215
3230
  if (typeof name !== "string") {
3216
3231
  consola.consola.warn("wrong model name", name);
3217
3232
  return name;
3218
3233
  }
3219
- if (/^(?!\d)([A-Z0-9_]{1,})$/g.test(name)) return (0, es_toolkit.compact)([
3220
- typePrefix,
3221
- name,
3222
- typeSuffix
3223
- ]).join("_");
3224
- if (this.formattedModelNamesMap.has(hashKey)) return this.formattedModelNamesMap.get(hashKey);
3225
- const formattedName = (0, es_toolkit_compat.startCase)(`${typePrefix}_${this.fixModelName(name, { type: schemaType })}_${typeSuffix}`).replace(/\s/g, "");
3226
- const formattedResultName = this.config.hooks.onFormatTypeName?.(formattedName, name, schemaType) || formattedName;
3227
- this.formattedModelNamesMap.set(hashKey, formattedResultName);
3228
- return formattedResultName;
3234
+ const result = this.computeFormattedName(name, schemaType, typePrefix, typeSuffix);
3235
+ this.formattedModelNamesMap.set(hashKey, result);
3236
+ return result;
3237
+ };
3238
+ /**
3239
+ * Resolve the TypeScript identifier for every raw schema name passed in,
3240
+ * populating `formattedModelNamesMap` and `usedFormattedTypeNames`. Must be
3241
+ * called once, before any `format()` call from the schema parser, so that
3242
+ * every subsequent `format()` for these names is a cache hit and returns
3243
+ * the collision-resolved identifier.
3244
+ *
3245
+ * Two passes:
3246
+ * 1. Claim every raw name whose formatted output equals the raw name
3247
+ * itself ("canonical"). User-declared identifiers like `FooBar` or
3248
+ * `FooBar1` are preserved regardless of the source order in which
3249
+ * the generator later visits them.
3250
+ * 2. For non-canonical names (e.g. `Foo_Bar` → `FooBar`), suffix with
3251
+ * the smallest integer not already claimed, so collisions produce
3252
+ * `FooBar`, `FooBar1`, `FooBar2`, … deterministically.
3253
+ *
3254
+ * Only type-names go through collision resolution here. Enum keys use the
3255
+ * fallback path in `format()` and are handled per-enum by the template.
3256
+ */
3257
+ precommit = (rawNames) => {
3258
+ const schemaType = "type-name";
3259
+ const { typePrefix, typeSuffix } = this.getAffixes(schemaType);
3260
+ const seen = /* @__PURE__ */ new Set();
3261
+ const names = [];
3262
+ for (const name of rawNames) {
3263
+ if (typeof name !== "string") continue;
3264
+ if (seen.has(name)) continue;
3265
+ seen.add(name);
3266
+ names.push(name);
3267
+ }
3268
+ for (const name of names) {
3269
+ const formatted = this.computeFormattedName(name, schemaType, typePrefix, typeSuffix);
3270
+ if (name !== formatted) continue;
3271
+ if (this.usedFormattedTypeNames.has(formatted)) continue;
3272
+ this.usedFormattedTypeNames.set(formatted, name);
3273
+ const hashKey = `${typePrefix}_${name}_${typeSuffix}`;
3274
+ this.formattedModelNamesMap.set(hashKey, formatted);
3275
+ }
3276
+ for (const name of names) {
3277
+ const hashKey = `${typePrefix}_${name}_${typeSuffix}`;
3278
+ if (this.formattedModelNamesMap.has(hashKey)) continue;
3279
+ const formatted = this.computeFormattedName(name, schemaType, typePrefix, typeSuffix);
3280
+ let final = formatted;
3281
+ if (this.usedFormattedTypeNames.has(final)) {
3282
+ let suffix = 1;
3283
+ while (this.usedFormattedTypeNames.has(`${formatted}${suffix}`)) suffix += 1;
3284
+ final = `${formatted}${suffix}`;
3285
+ }
3286
+ this.usedFormattedTypeNames.set(final, name);
3287
+ this.formattedModelNamesMap.set(hashKey, final);
3288
+ }
3229
3289
  };
3230
3290
  isValidName = (name) => /^([A-Za-z$_]{1,})$/g.test(name);
3231
3291
  fixModelName = (name, options) => {
3232
3292
  if (!this.isValidName(name)) {
3233
3293
  if (!/^[a-zA-Z_$]/g.test(name)) return `${options.type === "enum-key" ? this.config.fixInvalidEnumKeyPrefix : this.config.fixInvalidTypeNamePrefix} ${name}`;
3234
3294
  if (name.includes(".")) return name.replace(/Exclude_keyof[A-Za-z]+/g, () => "ExcludeKeys").replace(/%22~AND~%22/g, "And").replace(/%22~OR~%22/g, "Or").replace(/(\.?%22)|\./g, "_").replace(/__+$/, "");
3235
- if (name.includes("-")) return (0, es_toolkit_compat.startCase)(name).replace(/ /g, "");
3295
+ if (name.includes("-")) return this.config.disableFormatTypeNames ? name.replace(/-/g, "_") : (0, es_toolkit_compat.startCase)(name).replace(/ /g, "");
3236
3296
  }
3237
3297
  return name;
3238
3298
  };
3299
+ getAffixes = (schemaType) => ({
3300
+ typePrefix: schemaType === "enum-key" ? this.config.enumKeyPrefix : this.config.typePrefix,
3301
+ typeSuffix: schemaType === "enum-key" ? this.config.enumKeySuffix : this.config.typeSuffix
3302
+ });
3303
+ computeFormattedName = (name, schemaType, typePrefix, typeSuffix) => {
3304
+ const typeNameSeparator = this.config.typeNameSeparator;
3305
+ let resultName = name;
3306
+ if (this.config.disableFormatTypeNames) resultName = (0, es_toolkit.compact)([
3307
+ typePrefix,
3308
+ resultName,
3309
+ typeSuffix
3310
+ ]).join(typeNameSeparator);
3311
+ else if (/^(?!\d)([A-Z0-9_]{1,})$/g.test(resultName)) resultName = (0, es_toolkit.compact)([
3312
+ typePrefix,
3313
+ resultName,
3314
+ typeSuffix
3315
+ ]).join(typeNameSeparator);
3316
+ else resultName = (0, es_toolkit_compat.startCase)((0, es_toolkit.compact)([
3317
+ typePrefix,
3318
+ this.fixModelName(resultName, { type: schemaType }),
3319
+ typeSuffix
3320
+ ]).join(typeNameSeparator)).replace(/\s/g, "");
3321
+ return this.config.hooks.onFormatTypeName?.(resultName, name, schemaType) || resultName;
3322
+ };
3239
3323
  };
3240
3324
  //#endregion
3241
3325
  //#region src/util/file-system.ts
@@ -3354,7 +3438,9 @@ var CodeGenProcess = class {
3354
3438
  ]), rawTypeData);
3355
3439
  this.schemaComponentsMap.discriminatorsFirst();
3356
3440
  this.schemaComponentsMap.enumsFirst();
3357
- const parsedSchemas = this.schemaComponentsMap.filter((0, es_toolkit.compact)(["schemas", this.config.extractResponses && "responses"])).map((schemaComponent) => {
3441
+ const componentsToParse = this.schemaComponentsMap.filter((0, es_toolkit.compact)(["schemas", this.config.extractResponses && "responses"]));
3442
+ this.typeNameFormatter.precommit(componentsToParse.map((c) => c.typeName));
3443
+ const parsedSchemas = componentsToParse.map((schemaComponent) => {
3358
3444
  const parsed = this.schemaParserFabric.parseSchema(schemaComponent.rawTypeData, schemaComponent.typeName);
3359
3445
  schemaComponent.typeData = parsed;
3360
3446
  return parsed;
@@ -3817,4 +3903,4 @@ Object.defineProperty(exports, "version", {
3817
3903
  }
3818
3904
  });
3819
3905
 
3820
- //# sourceMappingURL=src-D7B_7nSd.cjs.map
3906
+ //# sourceMappingURL=src-pyGddI9m.cjs.map