swagger-typescript-api 13.9.3 → 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.9.3";
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
@@ -263,6 +263,7 @@ const TsKeyword = {
263
263
  Date: "Date",
264
264
  Type: "type",
265
265
  Enum: "enum",
266
+ Const: "const",
266
267
  Interface: "interface",
267
268
  Array: "Array",
268
269
  Record: "Record",
@@ -282,7 +283,9 @@ var CodeGenConfig = class {
282
283
  generateRouteTypes = false;
283
284
  /** CLI flag */
284
285
  generateClient = true;
285
- /** CLI flag */
286
+ /** CLI flag. Controls enum output format: "enum" (default), "union" (T1 | T2 | TN), or "const" (as const object + type alias). */
287
+ enumStyle = "enum";
288
+ /** @deprecated Use enumStyle: "union" instead */
286
289
  generateUnionEnums = false;
287
290
  /** CLI flag */
288
291
  addReadonly = false;
@@ -372,6 +375,7 @@ var CodeGenConfig = class {
372
375
  enumKeyPrefix = "";
373
376
  enumKeySuffix = "";
374
377
  patch = false;
378
+ preferExistingSchemaNamesForExternalRefs = false;
375
379
  componentTypeNameResolver;
376
380
  /** name of the main exported class */
377
381
  apiClassName = "Api";
@@ -653,6 +657,10 @@ var CodeGenConfig = class {
653
657
  update = (update) => {
654
658
  objectAssign(this, update);
655
659
  if (this.enumNamesAsValues) this.extractEnums = true;
660
+ if (this.generateUnionEnums) {
661
+ consola$1.warn("`generateUnionEnums` is deprecated. Use `enumStyle: \"union\"` instead.");
662
+ if (this.enumStyle === "enum") this.enumStyle = "union";
663
+ }
656
664
  };
657
665
  };
658
666
  //#endregion
@@ -662,6 +670,18 @@ function pascalCase(value) {
662
670
  }
663
671
  //#endregion
664
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
+ ]);
665
685
  var SchemaComponentsMap = class {
666
686
  _data = [];
667
687
  constructor(config) {
@@ -693,18 +713,49 @@ var SchemaComponentsMap = class {
693
713
  });
694
714
  return matchingComponents.length === 1 ? matchingComponents[0] : null;
695
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
+ }
696
747
  createComponentDraft($ref, rawTypeData) {
697
748
  if (typeGuard.isObject(rawTypeData) && rawTypeData.typeName && rawTypeData.rawTypeData && rawTypeData.$ref) return rawTypeData;
698
749
  const parsed = this.parseRef($ref);
699
750
  const [, rawPointer = ""] = $ref.split("#");
700
751
  const pointerParts = (rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}`).split("/").filter(Boolean);
701
- const typeName = pointerParts.at(-1) || parsed.at(-1) || "Unknown";
752
+ const typeName = this.normalizeTypeNameFromFile(pointerParts.at(-1) || parsed.at(-1) || "Unknown");
702
753
  const rawComponentName = pointerParts.at(-2) || parsed[parsed.length - 2] || "schemas";
703
754
  return {
704
755
  $ref,
705
756
  typeName,
706
757
  rawTypeData,
707
- componentName: rawComponentName === "definitions" ? "schemas" : rawComponentName,
758
+ componentName: this.resolveComponentName(rawComponentName),
708
759
  /** result from schema parser */
709
760
  typeData: null
710
761
  };
@@ -724,6 +775,20 @@ var SchemaComponentsMap = class {
724
775
  filter(...componentNames) {
725
776
  return this._data.filter((it) => componentNames.some((componentName) => it.$ref.startsWith(`#/components/${componentName}`)));
726
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
+ }
727
792
  get = ($ref) => {
728
793
  const localFound = this._data.find((c) => c.$ref === $ref) || this.getByLocalFragmentRef($ref) || null;
729
794
  if (localFound != null) return localFound;
@@ -732,9 +797,24 @@ var SchemaComponentsMap = class {
732
797
  const foundByRef = resolvedSwaggerSchema.getRef($ref);
733
798
  const refDetails = resolvedSwaggerSchema.getRefDetails($ref);
734
799
  if (foundByRef != null) {
735
- 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);
736
808
  componentDraft.typeName = this.config.hooks.onFormatExternalTypeName?.(componentDraft.typeName, refDetails) || componentDraft.typeName;
737
- 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;
738
818
  return this.createComponent($ref, componentDraft);
739
819
  }
740
820
  return null;
@@ -767,7 +847,12 @@ var SchemaFormatters = class {
767
847
  }
768
848
  base = {
769
849
  [SCHEMA_TYPES$1.ENUM]: (parsedSchema) => {
770
- if (this.config.generateUnionEnums) return {
850
+ if (this.config.enumStyle === "const") return {
851
+ ...parsedSchema,
852
+ $content: parsedSchema.content,
853
+ content: parsedSchema.content.map(({ key, value }) => ` ${key}: ${value}`).join(",\n")
854
+ };
855
+ if (this.config.enumStyle === "union") return {
771
856
  ...parsedSchema,
772
857
  $content: parsedSchema.content,
773
858
  content: this.config.Ts.UnionType(parsedSchema.content.map(({ value }) => value))
@@ -1045,7 +1130,7 @@ var DiscriminatorSchemaParser = class extends MonoSchemaParser {
1045
1130
  const enumEntries = (parsedEnum.enum || []).map((key, index) => [key, index]);
1046
1131
  for (const [key, index] of enumEntries) {
1047
1132
  const enumContent = parsedEnum.content?.[index];
1048
- if (this.config.generateUnionEnums) {
1133
+ if (this.config.enumStyle === "union" || this.config.enumStyle === "const") {
1049
1134
  const literalValue = enumContent?.value ?? (key !== void 0 ? ts.StringValue(key) : void 0);
1050
1135
  if (literalValue !== void 0) mappingPropertySchemaEnumKeysMap[key] = literalValue;
1051
1136
  } else if (parsedEnum.typeName && enumContent?.key) mappingPropertySchemaEnumKeysMap[key] = ts.EnumUsageKey(parsedEnum.typeName, enumContent.key);
@@ -1206,7 +1291,7 @@ var EnumSchemaParser = class extends MonoSchemaParser {
1206
1291
  schemaType: SCHEMA_TYPES$1.ENUM,
1207
1292
  type: SCHEMA_TYPES$1.ENUM,
1208
1293
  keyType,
1209
- typeIdentifier: this.config.generateUnionEnums ? this.config.Ts.Keyword.Type : this.config.Ts.Keyword.Enum,
1294
+ typeIdentifier: this.config.enumStyle === "const" ? this.config.Ts.Keyword.Const : this.config.enumStyle === "union" ? this.config.Ts.Keyword.Type : this.config.Ts.Keyword.Enum,
1210
1295
  name: this.typeName,
1211
1296
  description: this.schemaFormatters.formatDescription(this.schema.description),
1212
1297
  content
@@ -2378,6 +2463,7 @@ var SchemaRoutes = class {
2378
2463
  security: hasSecurity,
2379
2464
  method,
2380
2465
  requestParams: requestParamsSchema,
2466
+ requestParamsOptional: requestParamsSchema?.typeData?.allFieldsAreOptional ?? false,
2381
2467
  payload: specificArgs.body,
2382
2468
  query: specificArgs.query,
2383
2469
  pathParams: specificArgs.pathParams,
@@ -3536,6 +3622,7 @@ var CodeGenProcess = class {
3536
3622
  ]), rawTypeData);
3537
3623
  this.schemaComponentsMap.discriminatorsFirst();
3538
3624
  this.schemaComponentsMap.enumsFirst();
3625
+ this.schemaComponentsMap.resolveRefOnlyComponents();
3539
3626
  const componentsToParse = this.schemaComponentsMap.filter(compact(["schemas", this.config.extractResponses && "responses"]));
3540
3627
  this.typeNameFormatter.precommit(componentsToParse.map((c) => c.typeName));
3541
3628
  const parsedSchemas = componentsToParse.map((schemaComponent) => {
@@ -3627,9 +3714,17 @@ var CodeGenProcess = class {
3627
3714
  while (processedCount < schemaComponentsCount) {
3628
3715
  modelTypes = [];
3629
3716
  processedCount = 0;
3717
+ const seenExportNames = /* @__PURE__ */ new Set();
3630
3718
  for (const component of components) if (modelTypeComponents.includes(component.componentName)) {
3631
3719
  const modelType = this.prepareModelType(component);
3632
- 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
+ }
3633
3728
  processedCount++;
3634
3729
  }
3635
3730
  schemaComponentsCount = getSchemaComponentsCount();
@@ -3930,4 +4025,4 @@ async function generateApi(config) {
3930
4025
  //#endregion
3931
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 };
3932
4027
 
3933
- //# sourceMappingURL=src-D2qG03ZJ.mjs.map
4028
+ //# sourceMappingURL=src-CxQXlsuV.mjs.map