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.
@@ -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.1";
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,72 @@ 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
+ extractComponentSchemaNameFromRef(ref) {
744
+ const [, rawPointer = ""] = ref.split("#");
745
+ if (!rawPointer) return null;
746
+ const pointerParts = (rawPointer.startsWith("/") ? rawPointer.slice(1) : rawPointer).split("/").filter(Boolean);
747
+ if (pointerParts.length < 2) return null;
748
+ const collection = pointerParts.at(-2);
749
+ if (collection !== "schemas" && collection !== "definitions") return null;
750
+ return this.normalizeTypeNameFromFile(pointerParts.at(-1) || "");
751
+ }
752
+ findExistingComponentBySchemaFragment(ref, typeName) {
753
+ const fragmentSchemaName = this.extractComponentSchemaNameFromRef(ref);
754
+ if (!fragmentSchemaName || fragmentSchemaName !== typeName) return null;
755
+ const localRef = this.createRef([
756
+ "components",
757
+ "schemas",
758
+ typeName
759
+ ]);
760
+ const byLocalRef = this._data.find((component) => component.$ref === localRef);
761
+ if (byLocalRef) return byLocalRef;
762
+ const matching = this._data.filter((component) => component.typeName === typeName);
763
+ return matching.length === 1 ? matching[0] : null;
764
+ }
765
+ preferExistingSchemaNameForExternalRef(typeName, refDetails) {
766
+ if (!this.config.preferExistingSchemaNamesForExternalRefs) return false;
767
+ if (pascalCase(refDetails.externalOpenapiFileName || "External") === typeName) return true;
768
+ return this.findExistingComponentBySchemaFragment(refDetails.ref, typeName) != null;
769
+ }
703
770
  createComponentDraft($ref, rawTypeData) {
704
771
  if (typeGuard.isObject(rawTypeData) && rawTypeData.typeName && rawTypeData.rawTypeData && rawTypeData.$ref) return rawTypeData;
705
772
  const parsed = this.parseRef($ref);
706
773
  const [, rawPointer = ""] = $ref.split("#");
707
774
  const pointerParts = (rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}`).split("/").filter(Boolean);
708
- const typeName = pointerParts.at(-1) || parsed.at(-1) || "Unknown";
775
+ const typeName = this.normalizeTypeNameFromFile(pointerParts.at(-1) || parsed.at(-1) || "Unknown");
709
776
  const rawComponentName = pointerParts.at(-2) || parsed[parsed.length - 2] || "schemas";
710
777
  return {
711
778
  $ref,
712
779
  typeName,
713
780
  rawTypeData,
714
- componentName: rawComponentName === "definitions" ? "schemas" : rawComponentName,
781
+ componentName: this.resolveComponentName(rawComponentName),
715
782
  /** result from schema parser */
716
783
  typeData: null
717
784
  };
@@ -731,6 +798,20 @@ var SchemaComponentsMap = class {
731
798
  filter(...componentNames) {
732
799
  return this._data.filter((it) => componentNames.some((componentName) => it.$ref.startsWith(`#/components/${componentName}`)));
733
800
  }
801
+ resolveRefOnlyComponents() {
802
+ if (!this.config.preferExistingSchemaNamesForExternalRefs) return;
803
+ const { resolvedSwaggerSchema } = this.config;
804
+ for (const component of this._data) {
805
+ if (!this.isRefOnlyRawTypeData(component.rawTypeData)) continue;
806
+ const ref = component.rawTypeData?.$ref;
807
+ if (typeof ref !== "string") continue;
808
+ const resolved = resolvedSwaggerSchema.getRef(ref);
809
+ if (resolved == null || typeof resolved !== "object") continue;
810
+ component.rawTypeData = resolved;
811
+ component.typeData = null;
812
+ delete component.$prepared;
813
+ }
814
+ }
734
815
  get = ($ref) => {
735
816
  const localFound = this._data.find((c) => c.$ref === $ref) || this.getByLocalFragmentRef($ref) || null;
736
817
  if (localFound != null) return localFound;
@@ -739,9 +820,28 @@ var SchemaComponentsMap = class {
739
820
  const foundByRef = resolvedSwaggerSchema.getRef($ref);
740
821
  const refDetails = resolvedSwaggerSchema.getRefDetails($ref);
741
822
  if (foundByRef != null) {
742
- const componentDraft = this.createComponentDraft($ref, foundByRef);
823
+ let resolvedRef = $ref;
824
+ let resolvedTypeData = foundByRef;
825
+ const unwrappedComponentsDocument = this.unwrapExternalComponentsDocument($ref, resolvedTypeData);
826
+ if (unwrappedComponentsDocument) {
827
+ resolvedRef = unwrappedComponentsDocument.ref;
828
+ resolvedTypeData = unwrappedComponentsDocument.resolved;
829
+ }
830
+ const componentDraft = this.createComponentDraft(resolvedRef, resolvedTypeData);
743
831
  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}`;
832
+ if (this.config.preferExistingSchemaNamesForExternalRefs) {
833
+ const existingByFragment = this.findExistingComponentBySchemaFragment(refDetails.ref, componentDraft.typeName);
834
+ if (existingByFragment) return existingByFragment;
835
+ }
836
+ if (this._data.some((component) => component.typeName === componentDraft.typeName)) {
837
+ if (this.preferExistingSchemaNameForExternalRef(componentDraft.typeName, refDetails)) {
838
+ const existingComponent = this.findExistingComponentBySchemaFragment(refDetails.ref, componentDraft.typeName) ?? this._data.find((component) => component.typeName === componentDraft.typeName);
839
+ if (existingComponent) return existingComponent;
840
+ }
841
+ componentDraft.typeName = this.config.hooks.onFixDuplicateExternalTypeName?.(componentDraft.typeName, refDetails, this._data.map((it) => it.typeName)) ?? `${pascalCase(refDetails.externalOpenapiFileName || "External")}${componentDraft.typeName}`;
842
+ }
843
+ const existingComponent = this._data.find((component) => component.componentName === componentDraft.componentName && component.typeName === componentDraft.typeName);
844
+ if (existingComponent) return existingComponent;
745
845
  return this.createComponent($ref, componentDraft);
746
846
  }
747
847
  return null;
@@ -3549,6 +3649,7 @@ var CodeGenProcess = class {
3549
3649
  ]), rawTypeData);
3550
3650
  this.schemaComponentsMap.discriminatorsFirst();
3551
3651
  this.schemaComponentsMap.enumsFirst();
3652
+ this.schemaComponentsMap.resolveRefOnlyComponents();
3552
3653
  const componentsToParse = this.schemaComponentsMap.filter(compact(["schemas", this.config.extractResponses && "responses"]));
3553
3654
  this.typeNameFormatter.precommit(componentsToParse.map((c) => c.typeName));
3554
3655
  const parsedSchemas = componentsToParse.map((schemaComponent) => {
@@ -3640,9 +3741,17 @@ var CodeGenProcess = class {
3640
3741
  while (processedCount < schemaComponentsCount) {
3641
3742
  modelTypes = [];
3642
3743
  processedCount = 0;
3744
+ const seenExportNames = /* @__PURE__ */ new Set();
3643
3745
  for (const component of components) if (modelTypeComponents.includes(component.componentName)) {
3644
3746
  const modelType = this.prepareModelType(component);
3645
- if (modelType) modelTypes.push(modelType);
3747
+ if (modelType) {
3748
+ if (seenExportNames.has(modelType.name)) {
3749
+ processedCount++;
3750
+ continue;
3751
+ }
3752
+ seenExportNames.add(modelType.name);
3753
+ modelTypes.push(modelType);
3754
+ }
3646
3755
  processedCount++;
3647
3756
  }
3648
3757
  schemaComponentsCount = getSchemaComponentsCount();
@@ -3943,4 +4052,4 @@ async function generateApi(config) {
3943
4052
  //#endregion
3944
4053
  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
4054
 
3946
- //# sourceMappingURL=src-djU9KRKm.mjs.map
4055
+ //# sourceMappingURL=src-CdwLmxYh.mjs.map