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.
- package/dist/cli.cjs +14 -2
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +14 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +25 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +25 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-BeBS6icj.cjs → src-C6CxNImi.cjs} +106 -11
- package/dist/src-C6CxNImi.cjs.map +1 -0
- package/dist/{src-D2qG03ZJ.mjs → src-CxQXlsuV.mjs} +106 -11
- package/dist/src-CxQXlsuV.mjs.map +1 -0
- package/package.json +5 -5
- package/templates/base/content-type-accessors.ejs +18 -0
- package/templates/base/data-contracts.ejs +10 -0
- package/templates/base/enum-data-contract.ejs +6 -1
- package/templates/base/http-clients/axios-http-client.ejs +16 -2
- package/templates/base/http-clients/fetch-http-client.ejs +21 -7
- package/templates/default/procedure-call.ejs +3 -8
- package/templates/modular/api.ejs +4 -0
- package/templates/modular/procedure-call.ejs +3 -8
- package/dist/src-BeBS6icj.cjs.map +0 -1
- package/dist/src-D2qG03ZJ.mjs.map +0 -1
|
@@ -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.
|
|
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
|
|
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
|
-
|
|
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))
|
|
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.
|
|
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.
|
|
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.
|
|
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)
|
|
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-
|
|
4028
|
+
//# sourceMappingURL=src-CxQXlsuV.mjs.map
|