swagger-typescript-api 13.10.0 → 13.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -169,7 +169,7 @@ var ComponentTypeNameResolver = class extends NameResolver {
169
169
  //#endregion
170
170
  //#region package.json
171
171
  var name = "swagger-typescript-api";
172
- var version = "13.10.0";
172
+ var version = "13.11.0";
173
173
  var description = "Generate the API client for Fetch or Axios from an OpenAPI Specification";
174
174
  //#endregion
175
175
  //#region src/constants.ts
@@ -375,6 +375,7 @@ var CodeGenConfig = class {
375
375
  enumKeyPrefix = "";
376
376
  enumKeySuffix = "";
377
377
  patch = false;
378
+ preferExistingSchemaNamesForExternalRefs = false;
378
379
  componentTypeNameResolver;
379
380
  /** name of the main exported class */
380
381
  apiClassName = "Api";
@@ -669,6 +670,18 @@ function pascalCase(value) {
669
670
  }
670
671
  //#endregion
671
672
  //#region src/schema-components-map.ts
673
+ const OPENAPI_COMPONENT_NAMES = new Set([
674
+ "schemas",
675
+ "responses",
676
+ "requestBodies",
677
+ "parameters",
678
+ "headers",
679
+ "securitySchemes",
680
+ "links",
681
+ "callbacks",
682
+ "examples",
683
+ "pathItems"
684
+ ]);
672
685
  var SchemaComponentsMap = class {
673
686
  _data = [];
674
687
  constructor(config) {
@@ -700,18 +713,49 @@ var SchemaComponentsMap = class {
700
713
  });
701
714
  return matchingComponents.length === 1 ? matchingComponents[0] : null;
702
715
  }
716
+ normalizeTypeNameFromFile(typeName) {
717
+ return typeName.replace(/\.(yaml|yml|json)$/i, "");
718
+ }
719
+ resolveComponentName(rawComponentName) {
720
+ const normalizedComponentName = rawComponentName === "definitions" ? "schemas" : rawComponentName;
721
+ return OPENAPI_COMPONENT_NAMES.has(normalizedComponentName) ? normalizedComponentName : "schemas";
722
+ }
723
+ isFileOnlyRef(ref) {
724
+ const [, rawPointer = ""] = ref.split("#");
725
+ return !rawPointer.replace(/^\/+/, "");
726
+ }
727
+ unwrapExternalComponentsDocument(ref, resolved) {
728
+ if (!this.isFileOnlyRef(ref)) return null;
729
+ const schemas = resolved.components?.schemas;
730
+ if (!schemas || typeof schemas !== "object") return null;
731
+ const schemaEntries = Object.entries(schemas).filter(([, schemaData]) => schemaData != null && typeof schemaData === "object");
732
+ if (schemaEntries.length !== 1) return null;
733
+ const [schemaName, schemaData] = schemaEntries[0];
734
+ return {
735
+ ref: `${ref}#/components/schemas/${schemaName}`,
736
+ resolved: schemaData
737
+ };
738
+ }
739
+ isRefOnlyRawTypeData(rawTypeData) {
740
+ if (!rawTypeData || typeof rawTypeData !== "object") return false;
741
+ return Object.keys(rawTypeData).length === 1 && typeof rawTypeData.$ref === "string";
742
+ }
743
+ preferExistingSchemaNameForExternalRef(typeName, refDetails) {
744
+ if (!this.config.preferExistingSchemaNamesForExternalRefs) return false;
745
+ return pascalCase(refDetails.externalOpenapiFileName || "External") === typeName;
746
+ }
703
747
  createComponentDraft($ref, rawTypeData) {
704
748
  if (typeGuard.isObject(rawTypeData) && rawTypeData.typeName && rawTypeData.rawTypeData && rawTypeData.$ref) return rawTypeData;
705
749
  const parsed = this.parseRef($ref);
706
750
  const [, rawPointer = ""] = $ref.split("#");
707
751
  const pointerParts = (rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}`).split("/").filter(Boolean);
708
- const typeName = pointerParts.at(-1) || parsed.at(-1) || "Unknown";
752
+ const typeName = this.normalizeTypeNameFromFile(pointerParts.at(-1) || parsed.at(-1) || "Unknown");
709
753
  const rawComponentName = pointerParts.at(-2) || parsed[parsed.length - 2] || "schemas";
710
754
  return {
711
755
  $ref,
712
756
  typeName,
713
757
  rawTypeData,
714
- componentName: rawComponentName === "definitions" ? "schemas" : rawComponentName,
758
+ componentName: this.resolveComponentName(rawComponentName),
715
759
  /** result from schema parser */
716
760
  typeData: null
717
761
  };
@@ -731,6 +775,20 @@ var SchemaComponentsMap = class {
731
775
  filter(...componentNames) {
732
776
  return this._data.filter((it) => componentNames.some((componentName) => it.$ref.startsWith(`#/components/${componentName}`)));
733
777
  }
778
+ resolveRefOnlyComponents() {
779
+ if (!this.config.preferExistingSchemaNamesForExternalRefs) return;
780
+ const { resolvedSwaggerSchema } = this.config;
781
+ for (const component of this._data) {
782
+ if (!this.isRefOnlyRawTypeData(component.rawTypeData)) continue;
783
+ const ref = component.rawTypeData?.$ref;
784
+ if (typeof ref !== "string") continue;
785
+ const resolved = resolvedSwaggerSchema.getRef(ref);
786
+ if (resolved == null || typeof resolved !== "object") continue;
787
+ component.rawTypeData = resolved;
788
+ component.typeData = null;
789
+ delete component.$prepared;
790
+ }
791
+ }
734
792
  get = ($ref) => {
735
793
  const localFound = this._data.find((c) => c.$ref === $ref) || this.getByLocalFragmentRef($ref) || null;
736
794
  if (localFound != null) return localFound;
@@ -739,9 +797,24 @@ var SchemaComponentsMap = class {
739
797
  const foundByRef = resolvedSwaggerSchema.getRef($ref);
740
798
  const refDetails = resolvedSwaggerSchema.getRefDetails($ref);
741
799
  if (foundByRef != null) {
742
- const componentDraft = this.createComponentDraft($ref, foundByRef);
800
+ let resolvedRef = $ref;
801
+ let resolvedTypeData = foundByRef;
802
+ const unwrappedComponentsDocument = this.unwrapExternalComponentsDocument($ref, resolvedTypeData);
803
+ if (unwrappedComponentsDocument) {
804
+ resolvedRef = unwrappedComponentsDocument.ref;
805
+ resolvedTypeData = unwrappedComponentsDocument.resolved;
806
+ }
807
+ const componentDraft = this.createComponentDraft(resolvedRef, resolvedTypeData);
743
808
  componentDraft.typeName = this.config.hooks.onFormatExternalTypeName?.(componentDraft.typeName, refDetails) || componentDraft.typeName;
744
- if (this._data.some((component) => component.typeName === componentDraft.typeName)) componentDraft.typeName = this.config.hooks.onFixDuplicateExternalTypeName?.(componentDraft.typeName, refDetails, this._data.map((it) => it.typeName)) ?? `${pascalCase(refDetails.externalOpenapiFileName || "External")}${componentDraft.typeName}`;
809
+ if (this._data.some((component) => component.typeName === componentDraft.typeName)) {
810
+ if (this.preferExistingSchemaNameForExternalRef(componentDraft.typeName, refDetails)) {
811
+ const existingComponent = this._data.find((component) => component.typeName === componentDraft.typeName);
812
+ if (existingComponent) return existingComponent;
813
+ }
814
+ componentDraft.typeName = this.config.hooks.onFixDuplicateExternalTypeName?.(componentDraft.typeName, refDetails, this._data.map((it) => it.typeName)) ?? `${pascalCase(refDetails.externalOpenapiFileName || "External")}${componentDraft.typeName}`;
815
+ }
816
+ const existingComponent = this._data.find((component) => component.componentName === componentDraft.componentName && component.typeName === componentDraft.typeName);
817
+ if (existingComponent) return existingComponent;
745
818
  return this.createComponent($ref, componentDraft);
746
819
  }
747
820
  return null;
@@ -3549,6 +3622,7 @@ var CodeGenProcess = class {
3549
3622
  ]), rawTypeData);
3550
3623
  this.schemaComponentsMap.discriminatorsFirst();
3551
3624
  this.schemaComponentsMap.enumsFirst();
3625
+ this.schemaComponentsMap.resolveRefOnlyComponents();
3552
3626
  const componentsToParse = this.schemaComponentsMap.filter(compact(["schemas", this.config.extractResponses && "responses"]));
3553
3627
  this.typeNameFormatter.precommit(componentsToParse.map((c) => c.typeName));
3554
3628
  const parsedSchemas = componentsToParse.map((schemaComponent) => {
@@ -3640,9 +3714,17 @@ var CodeGenProcess = class {
3640
3714
  while (processedCount < schemaComponentsCount) {
3641
3715
  modelTypes = [];
3642
3716
  processedCount = 0;
3717
+ const seenExportNames = /* @__PURE__ */ new Set();
3643
3718
  for (const component of components) if (modelTypeComponents.includes(component.componentName)) {
3644
3719
  const modelType = this.prepareModelType(component);
3645
- if (modelType) modelTypes.push(modelType);
3720
+ if (modelType) {
3721
+ if (seenExportNames.has(modelType.name)) {
3722
+ processedCount++;
3723
+ continue;
3724
+ }
3725
+ seenExportNames.add(modelType.name);
3726
+ modelTypes.push(modelType);
3727
+ }
3646
3728
  processedCount++;
3647
3729
  }
3648
3730
  schemaComponentsCount = getSchemaComponentsCount();
@@ -3943,4 +4025,4 @@ async function generateApi(config) {
3943
4025
  //#endregion
3944
4026
  export { SCHEMA_TYPES as a, constants_exports as c, version as d, RequestContentKind as i, description as l, generateTemplates as n, CodeGenConfig as o, TemplatesGenConfig as r, HTTP_CLIENT as s, generateApi as t, name as u };
3945
4027
 
3946
- //# sourceMappingURL=src-djU9KRKm.mjs.map
4028
+ //# sourceMappingURL=src-CxQXlsuV.mjs.map