swagger-typescript-api 13.10.0 → 13.11.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.10.0";
211
+ var version = "13.11.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
@@ -414,6 +414,7 @@ var CodeGenConfig = class {
414
414
  enumKeyPrefix = "";
415
415
  enumKeySuffix = "";
416
416
  patch = false;
417
+ preferExistingSchemaNamesForExternalRefs = false;
417
418
  componentTypeNameResolver;
418
419
  /** name of the main exported class */
419
420
  apiClassName = "Api";
@@ -708,6 +709,18 @@ function pascalCase(value) {
708
709
  }
709
710
  //#endregion
710
711
  //#region src/schema-components-map.ts
712
+ const OPENAPI_COMPONENT_NAMES = new Set([
713
+ "schemas",
714
+ "responses",
715
+ "requestBodies",
716
+ "parameters",
717
+ "headers",
718
+ "securitySchemes",
719
+ "links",
720
+ "callbacks",
721
+ "examples",
722
+ "pathItems"
723
+ ]);
711
724
  var SchemaComponentsMap = class {
712
725
  _data = [];
713
726
  constructor(config) {
@@ -739,18 +752,72 @@ var SchemaComponentsMap = class {
739
752
  });
740
753
  return matchingComponents.length === 1 ? matchingComponents[0] : null;
741
754
  }
755
+ normalizeTypeNameFromFile(typeName) {
756
+ return typeName.replace(/\.(yaml|yml|json)$/i, "");
757
+ }
758
+ resolveComponentName(rawComponentName) {
759
+ const normalizedComponentName = rawComponentName === "definitions" ? "schemas" : rawComponentName;
760
+ return OPENAPI_COMPONENT_NAMES.has(normalizedComponentName) ? normalizedComponentName : "schemas";
761
+ }
762
+ isFileOnlyRef(ref) {
763
+ const [, rawPointer = ""] = ref.split("#");
764
+ return !rawPointer.replace(/^\/+/, "");
765
+ }
766
+ unwrapExternalComponentsDocument(ref, resolved) {
767
+ if (!this.isFileOnlyRef(ref)) return null;
768
+ const schemas = resolved.components?.schemas;
769
+ if (!schemas || typeof schemas !== "object") return null;
770
+ const schemaEntries = Object.entries(schemas).filter(([, schemaData]) => schemaData != null && typeof schemaData === "object");
771
+ if (schemaEntries.length !== 1) return null;
772
+ const [schemaName, schemaData] = schemaEntries[0];
773
+ return {
774
+ ref: `${ref}#/components/schemas/${schemaName}`,
775
+ resolved: schemaData
776
+ };
777
+ }
778
+ isRefOnlyRawTypeData(rawTypeData) {
779
+ if (!rawTypeData || typeof rawTypeData !== "object") return false;
780
+ return Object.keys(rawTypeData).length === 1 && typeof rawTypeData.$ref === "string";
781
+ }
782
+ extractComponentSchemaNameFromRef(ref) {
783
+ const [, rawPointer = ""] = ref.split("#");
784
+ if (!rawPointer) return null;
785
+ const pointerParts = (rawPointer.startsWith("/") ? rawPointer.slice(1) : rawPointer).split("/").filter(Boolean);
786
+ if (pointerParts.length < 2) return null;
787
+ const collection = pointerParts.at(-2);
788
+ if (collection !== "schemas" && collection !== "definitions") return null;
789
+ return this.normalizeTypeNameFromFile(pointerParts.at(-1) || "");
790
+ }
791
+ findExistingComponentBySchemaFragment(ref, typeName) {
792
+ const fragmentSchemaName = this.extractComponentSchemaNameFromRef(ref);
793
+ if (!fragmentSchemaName || fragmentSchemaName !== typeName) return null;
794
+ const localRef = this.createRef([
795
+ "components",
796
+ "schemas",
797
+ typeName
798
+ ]);
799
+ const byLocalRef = this._data.find((component) => component.$ref === localRef);
800
+ if (byLocalRef) return byLocalRef;
801
+ const matching = this._data.filter((component) => component.typeName === typeName);
802
+ return matching.length === 1 ? matching[0] : null;
803
+ }
804
+ preferExistingSchemaNameForExternalRef(typeName, refDetails) {
805
+ if (!this.config.preferExistingSchemaNamesForExternalRefs) return false;
806
+ if (pascalCase(refDetails.externalOpenapiFileName || "External") === typeName) return true;
807
+ return this.findExistingComponentBySchemaFragment(refDetails.ref, typeName) != null;
808
+ }
742
809
  createComponentDraft($ref, rawTypeData) {
743
810
  if (yummies_type_guard.typeGuard.isObject(rawTypeData) && rawTypeData.typeName && rawTypeData.rawTypeData && rawTypeData.$ref) return rawTypeData;
744
811
  const parsed = this.parseRef($ref);
745
812
  const [, rawPointer = ""] = $ref.split("#");
746
813
  const pointerParts = (rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}`).split("/").filter(Boolean);
747
- const typeName = pointerParts.at(-1) || parsed.at(-1) || "Unknown";
814
+ const typeName = this.normalizeTypeNameFromFile(pointerParts.at(-1) || parsed.at(-1) || "Unknown");
748
815
  const rawComponentName = pointerParts.at(-2) || parsed[parsed.length - 2] || "schemas";
749
816
  return {
750
817
  $ref,
751
818
  typeName,
752
819
  rawTypeData,
753
- componentName: rawComponentName === "definitions" ? "schemas" : rawComponentName,
820
+ componentName: this.resolveComponentName(rawComponentName),
754
821
  /** result from schema parser */
755
822
  typeData: null
756
823
  };
@@ -770,6 +837,20 @@ var SchemaComponentsMap = class {
770
837
  filter(...componentNames) {
771
838
  return this._data.filter((it) => componentNames.some((componentName) => it.$ref.startsWith(`#/components/${componentName}`)));
772
839
  }
840
+ resolveRefOnlyComponents() {
841
+ if (!this.config.preferExistingSchemaNamesForExternalRefs) return;
842
+ const { resolvedSwaggerSchema } = this.config;
843
+ for (const component of this._data) {
844
+ if (!this.isRefOnlyRawTypeData(component.rawTypeData)) continue;
845
+ const ref = component.rawTypeData?.$ref;
846
+ if (typeof ref !== "string") continue;
847
+ const resolved = resolvedSwaggerSchema.getRef(ref);
848
+ if (resolved == null || typeof resolved !== "object") continue;
849
+ component.rawTypeData = resolved;
850
+ component.typeData = null;
851
+ delete component.$prepared;
852
+ }
853
+ }
773
854
  get = ($ref) => {
774
855
  const localFound = this._data.find((c) => c.$ref === $ref) || this.getByLocalFragmentRef($ref) || null;
775
856
  if (localFound != null) return localFound;
@@ -778,9 +859,28 @@ var SchemaComponentsMap = class {
778
859
  const foundByRef = resolvedSwaggerSchema.getRef($ref);
779
860
  const refDetails = resolvedSwaggerSchema.getRefDetails($ref);
780
861
  if (foundByRef != null) {
781
- const componentDraft = this.createComponentDraft($ref, foundByRef);
862
+ let resolvedRef = $ref;
863
+ let resolvedTypeData = foundByRef;
864
+ const unwrappedComponentsDocument = this.unwrapExternalComponentsDocument($ref, resolvedTypeData);
865
+ if (unwrappedComponentsDocument) {
866
+ resolvedRef = unwrappedComponentsDocument.ref;
867
+ resolvedTypeData = unwrappedComponentsDocument.resolved;
868
+ }
869
+ const componentDraft = this.createComponentDraft(resolvedRef, resolvedTypeData);
782
870
  componentDraft.typeName = this.config.hooks.onFormatExternalTypeName?.(componentDraft.typeName, refDetails) || componentDraft.typeName;
783
- 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}`;
871
+ if (this.config.preferExistingSchemaNamesForExternalRefs) {
872
+ const existingByFragment = this.findExistingComponentBySchemaFragment(refDetails.ref, componentDraft.typeName);
873
+ if (existingByFragment) return existingByFragment;
874
+ }
875
+ if (this._data.some((component) => component.typeName === componentDraft.typeName)) {
876
+ if (this.preferExistingSchemaNameForExternalRef(componentDraft.typeName, refDetails)) {
877
+ const existingComponent = this.findExistingComponentBySchemaFragment(refDetails.ref, componentDraft.typeName) ?? this._data.find((component) => component.typeName === componentDraft.typeName);
878
+ if (existingComponent) return existingComponent;
879
+ }
880
+ componentDraft.typeName = this.config.hooks.onFixDuplicateExternalTypeName?.(componentDraft.typeName, refDetails, this._data.map((it) => it.typeName)) ?? `${pascalCase(refDetails.externalOpenapiFileName || "External")}${componentDraft.typeName}`;
881
+ }
882
+ const existingComponent = this._data.find((component) => component.componentName === componentDraft.componentName && component.typeName === componentDraft.typeName);
883
+ if (existingComponent) return existingComponent;
784
884
  return this.createComponent($ref, componentDraft);
785
885
  }
786
886
  return null;
@@ -3588,6 +3688,7 @@ var CodeGenProcess = class {
3588
3688
  ]), rawTypeData);
3589
3689
  this.schemaComponentsMap.discriminatorsFirst();
3590
3690
  this.schemaComponentsMap.enumsFirst();
3691
+ this.schemaComponentsMap.resolveRefOnlyComponents();
3591
3692
  const componentsToParse = this.schemaComponentsMap.filter((0, es_toolkit.compact)(["schemas", this.config.extractResponses && "responses"]));
3592
3693
  this.typeNameFormatter.precommit(componentsToParse.map((c) => c.typeName));
3593
3694
  const parsedSchemas = componentsToParse.map((schemaComponent) => {
@@ -3679,9 +3780,17 @@ var CodeGenProcess = class {
3679
3780
  while (processedCount < schemaComponentsCount) {
3680
3781
  modelTypes = [];
3681
3782
  processedCount = 0;
3783
+ const seenExportNames = /* @__PURE__ */ new Set();
3682
3784
  for (const component of components) if (modelTypeComponents.includes(component.componentName)) {
3683
3785
  const modelType = this.prepareModelType(component);
3684
- if (modelType) modelTypes.push(modelType);
3786
+ if (modelType) {
3787
+ if (seenExportNames.has(modelType.name)) {
3788
+ processedCount++;
3789
+ continue;
3790
+ }
3791
+ seenExportNames.add(modelType.name);
3792
+ modelTypes.push(modelType);
3793
+ }
3685
3794
  processedCount++;
3686
3795
  }
3687
3796
  schemaComponentsCount = getSchemaComponentsCount();
@@ -4053,4 +4162,4 @@ Object.defineProperty(exports, "version", {
4053
4162
  }
4054
4163
  });
4055
4164
 
4056
- //# sourceMappingURL=src-B2z6JCvN.cjs.map
4165
+ //# sourceMappingURL=src-dL4yFLYT.cjs.map