ng-openapi 0.1.9 → 0.1.11-beta.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/cli.cjs +268 -240
- package/index.d.ts +9 -19
- package/index.js +276 -243
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -112,16 +112,15 @@ var import_ts_morph = require("ts-morph");
|
|
|
112
112
|
|
|
113
113
|
// ../shared/src/utils/string.utils.ts
|
|
114
114
|
function camelCase(str) {
|
|
115
|
-
|
|
116
|
-
return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
|
|
115
|
+
return str.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^./, (char) => char.toLowerCase());
|
|
117
116
|
}
|
|
118
117
|
__name(camelCase, "camelCase");
|
|
119
118
|
function kebabCase(str) {
|
|
120
|
-
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
119
|
+
return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[-_\s]+/g, "-").toLowerCase();
|
|
121
120
|
}
|
|
122
121
|
__name(kebabCase, "kebabCase");
|
|
123
122
|
function pascalCase(str) {
|
|
124
|
-
return str.replace(/
|
|
123
|
+
return str.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^./, (char) => char.toUpperCase());
|
|
125
124
|
}
|
|
126
125
|
__name(pascalCase, "pascalCase");
|
|
127
126
|
|
|
@@ -447,6 +446,12 @@ function inferResponseTypeFromContentType(contentType) {
|
|
|
447
446
|
__name(inferResponseTypeFromContentType, "inferResponseTypeFromContentType");
|
|
448
447
|
function getResponseType(response, config) {
|
|
449
448
|
const responseType = getResponseTypeFromResponse(response);
|
|
449
|
+
const content = response.content || {};
|
|
450
|
+
for (const [contentType, mediaType] of Object.entries(content)) {
|
|
451
|
+
if (mediaType == null ? void 0 : mediaType.schema) {
|
|
452
|
+
return getTypeScriptType(mediaType.schema, config, mediaType.schema.nullable);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
450
455
|
switch (responseType) {
|
|
451
456
|
case "blob":
|
|
452
457
|
return "Blob";
|
|
@@ -454,15 +459,6 @@ function getResponseType(response, config) {
|
|
|
454
459
|
return "ArrayBuffer";
|
|
455
460
|
case "text":
|
|
456
461
|
return "string";
|
|
457
|
-
case "json": {
|
|
458
|
-
const content = response.content || {};
|
|
459
|
-
for (const [contentType, mediaType] of Object.entries(content)) {
|
|
460
|
-
if (inferResponseTypeFromContentType(contentType) === "json" && (mediaType == null ? void 0 : mediaType.schema)) {
|
|
461
|
-
return getTypeScriptType(mediaType.schema, config, mediaType.schema.nullable);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
return "any";
|
|
465
|
-
}
|
|
466
462
|
default:
|
|
467
463
|
return "any";
|
|
468
464
|
}
|
|
@@ -724,82 +720,76 @@ var SwaggerParser = _SwaggerParser;
|
|
|
724
720
|
|
|
725
721
|
// src/lib/generators/type/type.generator.ts
|
|
726
722
|
var _TypeGenerator = class _TypeGenerator {
|
|
727
|
-
constructor(parser,
|
|
723
|
+
constructor(parser, project, config, outputRoot) {
|
|
728
724
|
__publicField(this, "project");
|
|
729
725
|
__publicField(this, "parser");
|
|
730
726
|
__publicField(this, "sourceFile");
|
|
731
727
|
__publicField(this, "generatedTypes", /* @__PURE__ */ new Set());
|
|
732
728
|
__publicField(this, "config");
|
|
729
|
+
// Performance caches
|
|
730
|
+
__publicField(this, "pascalCaseCache", /* @__PURE__ */ new Map());
|
|
731
|
+
__publicField(this, "sanitizedNameCache", /* @__PURE__ */ new Map());
|
|
732
|
+
__publicField(this, "typeResolutionCache", /* @__PURE__ */ new Map());
|
|
733
|
+
// Batch collection for AST operations
|
|
734
|
+
__publicField(this, "statements", []);
|
|
735
|
+
__publicField(this, "deferredTypes", /* @__PURE__ */ new Map());
|
|
733
736
|
this.config = config;
|
|
734
|
-
|
|
735
|
-
this.project = new import_ts_morph.Project({
|
|
736
|
-
compilerOptions: __spreadValues({
|
|
737
|
-
declaration: true,
|
|
738
|
-
target: import_ts_morph.ScriptTarget.ES2022,
|
|
739
|
-
module: import_ts_morph.ModuleKind.Preserve,
|
|
740
|
-
strict: true
|
|
741
|
-
}, this.config.compilerOptions)
|
|
742
|
-
});
|
|
737
|
+
this.project = project;
|
|
743
738
|
this.parser = parser;
|
|
739
|
+
const outputPath = outputRoot + "/models/index.ts";
|
|
744
740
|
this.sourceFile = this.project.createSourceFile(outputPath, "", {
|
|
745
741
|
overwrite: true
|
|
746
742
|
});
|
|
747
743
|
}
|
|
748
|
-
|
|
744
|
+
generate() {
|
|
749
745
|
return __async(this, null, function* () {
|
|
750
|
-
|
|
751
|
-
|
|
746
|
+
try {
|
|
747
|
+
const definitions = this.parser.getDefinitions();
|
|
748
|
+
if (!definitions || Object.keys(definitions).length === 0) {
|
|
749
|
+
console.warn("No definitions found in swagger file");
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
this.collectAllTypeStructures(definitions);
|
|
753
|
+
this.collectSdkTypes();
|
|
754
|
+
this.applyBatchUpdates();
|
|
755
|
+
yield this.finalize();
|
|
756
|
+
} catch (error) {
|
|
757
|
+
console.error("Error in generate():", error);
|
|
758
|
+
throw new Error(`Failed to generate types: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
759
|
+
}
|
|
752
760
|
});
|
|
753
761
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
this.generateSdkTypes();
|
|
766
|
-
this.sourceFile.formatText();
|
|
767
|
-
this.sourceFile.saveSync();
|
|
768
|
-
} catch (error) {
|
|
769
|
-
console.error("Error in generate():", error);
|
|
770
|
-
throw new Error(`Failed to generate types: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
771
|
-
}
|
|
762
|
+
collectAllTypeStructures(definitions) {
|
|
763
|
+
Object.keys(definitions).forEach((name) => {
|
|
764
|
+
const interfaceName = this.getCachedPascalCase(name);
|
|
765
|
+
this.generatedTypes.add(interfaceName);
|
|
766
|
+
});
|
|
767
|
+
Object.entries(definitions).forEach(([name, definition]) => {
|
|
768
|
+
this.collectTypeStructure(name, definition);
|
|
769
|
+
});
|
|
770
|
+
this.deferredTypes.forEach((definition, name) => {
|
|
771
|
+
this.collectTypeStructure(name, definition);
|
|
772
|
+
});
|
|
772
773
|
}
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
return;
|
|
777
|
-
}
|
|
778
|
-
this.generatedTypes.add(interfaceName);
|
|
774
|
+
collectTypeStructure(name, definition) {
|
|
775
|
+
var _a;
|
|
776
|
+
const interfaceName = (_a = this.getCachedPascalCase(name)) != null ? _a : "";
|
|
779
777
|
if (definition.enum) {
|
|
780
|
-
this.
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
this.
|
|
785
|
-
return;
|
|
778
|
+
this.collectEnumStructure(interfaceName, definition);
|
|
779
|
+
} else if (definition.allOf) {
|
|
780
|
+
this.collectCompositeTypeStructure(interfaceName, definition);
|
|
781
|
+
} else {
|
|
782
|
+
this.collectInterfaceStructure(interfaceName, definition);
|
|
786
783
|
}
|
|
787
|
-
const interfaceDeclaration = this.sourceFile.addInterface({
|
|
788
|
-
name: interfaceName,
|
|
789
|
-
isExported: true,
|
|
790
|
-
docs: definition.description ? [
|
|
791
|
-
definition.description
|
|
792
|
-
] : void 0
|
|
793
|
-
});
|
|
794
|
-
this.addInterfaceProperties(interfaceDeclaration, definition);
|
|
795
784
|
}
|
|
796
|
-
|
|
785
|
+
collectEnumStructure(name, definition) {
|
|
797
786
|
var _a;
|
|
798
787
|
if (!((_a = definition.enum) == null ? void 0 : _a.length)) return;
|
|
799
788
|
const isStringEnum = definition.enum.some((value) => typeof value === "string");
|
|
800
789
|
if (isStringEnum) {
|
|
801
790
|
const unionType = definition.enum.map((value) => typeof value === "string" ? `'${this.escapeString(value)}'` : String(value)).join(" | ");
|
|
802
|
-
this.
|
|
791
|
+
this.statements.push({
|
|
792
|
+
kind: import_ts_morph.StructureKind.TypeAlias,
|
|
803
793
|
name,
|
|
804
794
|
type: unionType,
|
|
805
795
|
isExported: true,
|
|
@@ -807,53 +797,44 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
807
797
|
definition.description
|
|
808
798
|
] : void 0
|
|
809
799
|
});
|
|
810
|
-
} else if (definition.description && this.config.options.generateEnumBasedOnDescription) {
|
|
811
|
-
const enumDeclaration = this.sourceFile.addEnum({
|
|
812
|
-
name,
|
|
813
|
-
isExported: true
|
|
814
|
-
});
|
|
815
|
-
try {
|
|
816
|
-
const enumValueObjects = JSON.parse(definition.description);
|
|
817
|
-
enumValueObjects.forEach((enumValueObject) => {
|
|
818
|
-
enumDeclaration.addMember({
|
|
819
|
-
name: enumValueObject.Name,
|
|
820
|
-
value: enumValueObject.Value
|
|
821
|
-
});
|
|
822
|
-
});
|
|
823
|
-
} catch (e) {
|
|
824
|
-
console.error(`Failed to parse enum description for ${name}`);
|
|
825
|
-
definition.enum.forEach((value) => {
|
|
826
|
-
const enumKey = this.toEnumKey(value);
|
|
827
|
-
enumDeclaration.addMember({
|
|
828
|
-
name: enumKey,
|
|
829
|
-
value
|
|
830
|
-
});
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
800
|
} else {
|
|
834
|
-
const
|
|
801
|
+
const members = this.buildEnumMembers(definition);
|
|
802
|
+
this.statements.push({
|
|
803
|
+
kind: import_ts_morph.StructureKind.Enum,
|
|
835
804
|
name,
|
|
836
805
|
isExported: true,
|
|
837
806
|
docs: definition.description ? [
|
|
838
807
|
definition.description
|
|
839
|
-
] : void 0
|
|
840
|
-
|
|
841
|
-
definition.enum.forEach((value) => {
|
|
842
|
-
const enumKey = this.toEnumKey(value);
|
|
843
|
-
enumDeclaration.addMember({
|
|
844
|
-
name: enumKey,
|
|
845
|
-
value
|
|
846
|
-
});
|
|
808
|
+
] : void 0,
|
|
809
|
+
members
|
|
847
810
|
});
|
|
848
811
|
}
|
|
849
812
|
}
|
|
850
|
-
|
|
813
|
+
buildEnumMembers(definition) {
|
|
814
|
+
var _a;
|
|
815
|
+
if (definition.description && this.config.options.generateEnumBasedOnDescription) {
|
|
816
|
+
try {
|
|
817
|
+
const enumValueObjects = JSON.parse(definition.description);
|
|
818
|
+
return enumValueObjects.map((obj) => ({
|
|
819
|
+
name: obj.Name,
|
|
820
|
+
value: obj.Value
|
|
821
|
+
}));
|
|
822
|
+
} catch (e) {
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
return (_a = definition.enum) == null ? void 0 : _a.map((value) => ({
|
|
826
|
+
name: this.toEnumKey(value),
|
|
827
|
+
value
|
|
828
|
+
}));
|
|
829
|
+
}
|
|
830
|
+
collectCompositeTypeStructure(name, definition) {
|
|
851
831
|
let typeExpression = "";
|
|
852
832
|
if (definition.allOf) {
|
|
853
|
-
const types = definition.allOf.map((def) => this.
|
|
833
|
+
const types = definition.allOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown");
|
|
854
834
|
typeExpression = types.length > 0 ? types.join(" & ") : "Record<string, unknown>";
|
|
855
835
|
}
|
|
856
|
-
this.
|
|
836
|
+
this.statements.push({
|
|
837
|
+
kind: import_ts_morph.StructureKind.TypeAlias,
|
|
857
838
|
name,
|
|
858
839
|
type: typeExpression,
|
|
859
840
|
isExported: true,
|
|
@@ -862,34 +843,30 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
862
843
|
] : void 0
|
|
863
844
|
});
|
|
864
845
|
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
});
|
|
880
|
-
return;
|
|
881
|
-
}
|
|
846
|
+
collectInterfaceStructure(name, definition) {
|
|
847
|
+
const properties = this.buildInterfaceProperties(definition);
|
|
848
|
+
this.statements.push({
|
|
849
|
+
kind: import_ts_morph.StructureKind.Interface,
|
|
850
|
+
name,
|
|
851
|
+
isExported: true,
|
|
852
|
+
docs: definition.description ? [
|
|
853
|
+
definition.description
|
|
854
|
+
] : void 0,
|
|
855
|
+
properties,
|
|
856
|
+
indexSignatures: this.buildIndexSignatures(definition)
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
buildInterfaceProperties(definition) {
|
|
882
860
|
if (!definition.properties) {
|
|
883
|
-
|
|
884
|
-
return;
|
|
861
|
+
return [];
|
|
885
862
|
}
|
|
886
|
-
Object.entries(definition.properties).
|
|
863
|
+
return Object.entries(definition.properties).map(([propertyName, property]) => {
|
|
887
864
|
var _a, _b;
|
|
888
865
|
const isRequired = (_b = (_a = definition.required) == null ? void 0 : _a.includes(propertyName)) != null ? _b : false;
|
|
889
866
|
const isReadOnly = property.readOnly;
|
|
890
|
-
const propertyType = this.
|
|
891
|
-
const sanitizedName = this.
|
|
892
|
-
|
|
867
|
+
const propertyType = this.resolveSwaggerTypeCached(property);
|
|
868
|
+
const sanitizedName = this.getCachedSanitizedName(propertyName);
|
|
869
|
+
return {
|
|
893
870
|
name: sanitizedName,
|
|
894
871
|
type: propertyType,
|
|
895
872
|
isReadonly: isReadOnly,
|
|
@@ -897,9 +874,48 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
897
874
|
docs: property.description ? [
|
|
898
875
|
property.description
|
|
899
876
|
] : void 0
|
|
900
|
-
}
|
|
877
|
+
};
|
|
901
878
|
});
|
|
902
879
|
}
|
|
880
|
+
buildIndexSignatures(definition) {
|
|
881
|
+
if (!definition.properties && definition.additionalProperties === false) {
|
|
882
|
+
return [
|
|
883
|
+
{
|
|
884
|
+
keyName: "key",
|
|
885
|
+
keyType: "string",
|
|
886
|
+
returnType: "never"
|
|
887
|
+
}
|
|
888
|
+
];
|
|
889
|
+
}
|
|
890
|
+
if (!definition.properties && definition.additionalProperties === true) {
|
|
891
|
+
return [
|
|
892
|
+
{
|
|
893
|
+
keyName: "key",
|
|
894
|
+
keyType: "string",
|
|
895
|
+
returnType: "any"
|
|
896
|
+
}
|
|
897
|
+
];
|
|
898
|
+
}
|
|
899
|
+
if (!definition.properties) {
|
|
900
|
+
return [
|
|
901
|
+
{
|
|
902
|
+
keyName: "key",
|
|
903
|
+
keyType: "string",
|
|
904
|
+
returnType: "unknown"
|
|
905
|
+
}
|
|
906
|
+
];
|
|
907
|
+
}
|
|
908
|
+
return [];
|
|
909
|
+
}
|
|
910
|
+
resolveSwaggerTypeCached(schema) {
|
|
911
|
+
const cacheKey = JSON.stringify(schema);
|
|
912
|
+
if (this.typeResolutionCache.has(cacheKey)) {
|
|
913
|
+
return this.typeResolutionCache.get(cacheKey);
|
|
914
|
+
}
|
|
915
|
+
const result = this.resolveSwaggerType(schema);
|
|
916
|
+
this.typeResolutionCache.set(cacheKey, result);
|
|
917
|
+
return result;
|
|
918
|
+
}
|
|
903
919
|
resolveSwaggerType(schema) {
|
|
904
920
|
if (schema.$ref) {
|
|
905
921
|
return this.resolveReference(schema.$ref);
|
|
@@ -908,13 +924,13 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
908
924
|
return schema.enum.map((value) => typeof value === "string" ? `'${this.escapeString(value)}'` : String(value)).join(" | ");
|
|
909
925
|
}
|
|
910
926
|
if (schema.allOf) {
|
|
911
|
-
return schema.allOf.map((def) => this.
|
|
927
|
+
return schema.allOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown").join(" & ") || "Record<string, unknown>";
|
|
912
928
|
}
|
|
913
929
|
if (schema.oneOf) {
|
|
914
|
-
return schema.oneOf.map((def) => this.
|
|
930
|
+
return schema.oneOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown").join(" | ") || "unknown";
|
|
915
931
|
}
|
|
916
932
|
if (schema.anyOf) {
|
|
917
|
-
return schema.anyOf.map((def) => this.
|
|
933
|
+
return schema.anyOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown").join(" | ") || "unknown";
|
|
918
934
|
}
|
|
919
935
|
if (schema.type === "array") {
|
|
920
936
|
const itemType = schema.items ? this.getArrayItemType(schema.items) : "unknown";
|
|
@@ -925,7 +941,7 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
925
941
|
return this.generateInlineObjectType(schema);
|
|
926
942
|
}
|
|
927
943
|
if (schema.additionalProperties) {
|
|
928
|
-
const valueType = typeof schema.additionalProperties === "object" ? this.
|
|
944
|
+
const valueType = typeof schema.additionalProperties === "object" ? this.resolveSwaggerTypeCached(schema.additionalProperties) : "unknown";
|
|
929
945
|
return `Record<string, ${valueType}>`;
|
|
930
946
|
}
|
|
931
947
|
return "Record<string, unknown>";
|
|
@@ -935,7 +951,7 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
935
951
|
generateInlineObjectType(definition) {
|
|
936
952
|
if (!definition.properties) {
|
|
937
953
|
if (definition.additionalProperties) {
|
|
938
|
-
const additionalType = typeof definition.additionalProperties === "object" ? this.
|
|
954
|
+
const additionalType = typeof definition.additionalProperties === "object" ? this.resolveSwaggerTypeCached(definition.additionalProperties) : "unknown";
|
|
939
955
|
return `Record<string, ${additionalType}>`;
|
|
940
956
|
}
|
|
941
957
|
return "Record<string, unknown>";
|
|
@@ -944,29 +960,104 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
944
960
|
var _a, _b;
|
|
945
961
|
const isRequired = (_b = (_a = definition.required) == null ? void 0 : _a.includes(key)) != null ? _b : false;
|
|
946
962
|
const questionMark = isRequired ? "" : "?";
|
|
947
|
-
const sanitizedKey = this.
|
|
948
|
-
return `${sanitizedKey}${questionMark}: ${this.
|
|
963
|
+
const sanitizedKey = this.getCachedSanitizedName(key);
|
|
964
|
+
return `${sanitizedKey}${questionMark}: ${this.resolveSwaggerTypeCached(prop)}`;
|
|
949
965
|
}).join("; ");
|
|
950
966
|
return `{ ${properties} }`;
|
|
951
967
|
}
|
|
952
968
|
resolveReference(ref) {
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
969
|
+
const refName = ref.split("/").pop();
|
|
970
|
+
if (!refName) {
|
|
971
|
+
console.warn(`Invalid reference format: ${ref}`);
|
|
972
|
+
return "unknown";
|
|
973
|
+
}
|
|
974
|
+
return this.getCachedPascalCase(refName);
|
|
975
|
+
}
|
|
976
|
+
collectSdkTypes() {
|
|
977
|
+
var _a;
|
|
978
|
+
const { response } = (_a = this.config.options.validation) != null ? _a : {};
|
|
979
|
+
const typeParameters = [
|
|
980
|
+
"TResponseType extends 'arraybuffer' | 'blob' | 'json' | 'text'"
|
|
981
|
+
];
|
|
982
|
+
const properties = [
|
|
983
|
+
{
|
|
984
|
+
name: "headers",
|
|
985
|
+
type: "HttpHeaders",
|
|
986
|
+
hasQuestionToken: true
|
|
987
|
+
},
|
|
988
|
+
{
|
|
989
|
+
name: "reportProgress",
|
|
990
|
+
type: "boolean",
|
|
991
|
+
hasQuestionToken: true
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
name: "responseType",
|
|
995
|
+
type: "TResponseType",
|
|
996
|
+
hasQuestionToken: true
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
name: "withCredentials",
|
|
1000
|
+
type: "boolean",
|
|
1001
|
+
hasQuestionToken: true
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
name: "context",
|
|
1005
|
+
type: "HttpContext",
|
|
1006
|
+
hasQuestionToken: true
|
|
959
1007
|
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1008
|
+
];
|
|
1009
|
+
if (response) {
|
|
1010
|
+
properties.push({
|
|
1011
|
+
name: "parse",
|
|
1012
|
+
type: "(response: unknown) => TReturnType",
|
|
1013
|
+
hasQuestionToken: true
|
|
1014
|
+
});
|
|
1015
|
+
typeParameters.push("TReturnType");
|
|
1016
|
+
}
|
|
1017
|
+
this.statements.push({
|
|
1018
|
+
kind: import_ts_morph.StructureKind.Interface,
|
|
1019
|
+
name: "RequestOptions",
|
|
1020
|
+
isExported: true,
|
|
1021
|
+
typeParameters,
|
|
1022
|
+
properties,
|
|
1023
|
+
docs: [
|
|
1024
|
+
"Request Options for Angular HttpClient requests"
|
|
1025
|
+
]
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
applyBatchUpdates() {
|
|
1029
|
+
this.sourceFile.insertText(0, TYPE_GENERATOR_HEADER_COMMENT);
|
|
1030
|
+
this.sourceFile.addImportDeclarations([
|
|
1031
|
+
{
|
|
1032
|
+
namedImports: [
|
|
1033
|
+
"HttpContext",
|
|
1034
|
+
"HttpHeaders"
|
|
1035
|
+
],
|
|
1036
|
+
moduleSpecifier: "@angular/common/http"
|
|
963
1037
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
1038
|
+
]);
|
|
1039
|
+
this.sourceFile.addStatements(this.statements);
|
|
1040
|
+
}
|
|
1041
|
+
finalize() {
|
|
1042
|
+
return __async(this, null, function* () {
|
|
1043
|
+
this.sourceFile.formatText();
|
|
1044
|
+
yield this.sourceFile.save();
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
// Cached helper methods
|
|
1048
|
+
getCachedPascalCase(str) {
|
|
1049
|
+
if (!this.pascalCaseCache.has(str)) {
|
|
1050
|
+
this.pascalCaseCache.set(str, this.pascalCaseForEnums(str));
|
|
968
1051
|
}
|
|
1052
|
+
return this.pascalCaseCache.get(str);
|
|
969
1053
|
}
|
|
1054
|
+
getCachedSanitizedName(name) {
|
|
1055
|
+
if (!this.sanitizedNameCache.has(name)) {
|
|
1056
|
+
this.sanitizedNameCache.set(name, this.sanitizePropertyName(name));
|
|
1057
|
+
}
|
|
1058
|
+
return this.sanitizedNameCache.get(name);
|
|
1059
|
+
}
|
|
1060
|
+
// Original helper methods
|
|
970
1061
|
mapSwaggerTypeToTypeScript(type, format, isNullable) {
|
|
971
1062
|
if (!type) return "unknown";
|
|
972
1063
|
switch (type) {
|
|
@@ -1013,75 +1104,15 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
1013
1104
|
}
|
|
1014
1105
|
getArrayItemType(items) {
|
|
1015
1106
|
if (Array.isArray(items)) {
|
|
1016
|
-
const types = items.map((item) => this.
|
|
1107
|
+
const types = items.map((item) => this.resolveSwaggerTypeCached(item));
|
|
1017
1108
|
return `[${types.join(", ")}]`;
|
|
1018
1109
|
} else {
|
|
1019
|
-
return this.
|
|
1110
|
+
return this.resolveSwaggerTypeCached(items);
|
|
1020
1111
|
}
|
|
1021
1112
|
}
|
|
1022
1113
|
escapeString(str) {
|
|
1023
1114
|
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
1024
1115
|
}
|
|
1025
|
-
generateSdkTypes() {
|
|
1026
|
-
var _a;
|
|
1027
|
-
this.sourceFile.addImportDeclarations([
|
|
1028
|
-
{
|
|
1029
|
-
namedImports: [
|
|
1030
|
-
"HttpContext",
|
|
1031
|
-
"HttpHeaders"
|
|
1032
|
-
],
|
|
1033
|
-
moduleSpecifier: "@angular/common/http"
|
|
1034
|
-
}
|
|
1035
|
-
]);
|
|
1036
|
-
const { response } = (_a = this.config.options.validation) != null ? _a : {};
|
|
1037
|
-
const typeParameters = [
|
|
1038
|
-
"TResponseType extends 'arraybuffer' | 'blob' | 'json' | 'text'"
|
|
1039
|
-
];
|
|
1040
|
-
const properties = [
|
|
1041
|
-
{
|
|
1042
|
-
name: "headers",
|
|
1043
|
-
type: "HttpHeaders",
|
|
1044
|
-
hasQuestionToken: true
|
|
1045
|
-
},
|
|
1046
|
-
{
|
|
1047
|
-
name: "reportProgress",
|
|
1048
|
-
type: "boolean",
|
|
1049
|
-
hasQuestionToken: true
|
|
1050
|
-
},
|
|
1051
|
-
{
|
|
1052
|
-
name: "responseType",
|
|
1053
|
-
type: "TResponseType",
|
|
1054
|
-
hasQuestionToken: true
|
|
1055
|
-
},
|
|
1056
|
-
{
|
|
1057
|
-
name: "withCredentials",
|
|
1058
|
-
type: "boolean",
|
|
1059
|
-
hasQuestionToken: true
|
|
1060
|
-
},
|
|
1061
|
-
{
|
|
1062
|
-
name: "context",
|
|
1063
|
-
type: "HttpContext",
|
|
1064
|
-
hasQuestionToken: true
|
|
1065
|
-
}
|
|
1066
|
-
];
|
|
1067
|
-
if (response) {
|
|
1068
|
-
properties.push({
|
|
1069
|
-
name: "parse",
|
|
1070
|
-
type: "(response: unknown) => TReturnType",
|
|
1071
|
-
hasQuestionToken: true
|
|
1072
|
-
});
|
|
1073
|
-
typeParameters.push("TReturnType");
|
|
1074
|
-
}
|
|
1075
|
-
this.sourceFile.addInterface({
|
|
1076
|
-
name: "RequestOptions",
|
|
1077
|
-
isExported: true,
|
|
1078
|
-
typeParameters,
|
|
1079
|
-
properties,
|
|
1080
|
-
docs: [
|
|
1081
|
-
"Request Options for Angular HttpClient requests"
|
|
1082
|
-
]
|
|
1083
|
-
});
|
|
1084
|
-
}
|
|
1085
1116
|
};
|
|
1086
1117
|
__name(_TypeGenerator, "TypeGenerator");
|
|
1087
1118
|
var TypeGenerator = _TypeGenerator;
|
|
@@ -2299,7 +2330,10 @@ var _ServiceMethodGenerator = class _ServiceMethodGenerator {
|
|
|
2299
2330
|
parameters,
|
|
2300
2331
|
returnType,
|
|
2301
2332
|
statements: methodBody,
|
|
2302
|
-
overloads: methodOverLoads
|
|
2333
|
+
overloads: methodOverLoads,
|
|
2334
|
+
docs: operation.description ? [
|
|
2335
|
+
operation.description
|
|
2336
|
+
] : void 0
|
|
2303
2337
|
});
|
|
2304
2338
|
}
|
|
2305
2339
|
generateMethodName(operation) {
|
|
@@ -2319,10 +2353,12 @@ var _ServiceMethodGenerator = class _ServiceMethodGenerator {
|
|
|
2319
2353
|
if (operation.operationId) {
|
|
2320
2354
|
return camelCase(operation.operationId);
|
|
2321
2355
|
}
|
|
2322
|
-
const method = operation.method.toLowerCase();
|
|
2323
|
-
const pathParts = operation.path.split("/").
|
|
2324
|
-
|
|
2325
|
-
|
|
2356
|
+
const method = pascalCase(operation.method.toLowerCase());
|
|
2357
|
+
const pathParts = operation.path.split("/").map((str) => {
|
|
2358
|
+
return pascalCase(pascalCase(str).replace(/[^a-zA-Z0-9]/g, ""));
|
|
2359
|
+
});
|
|
2360
|
+
const resource = pathParts.join("") || "resource";
|
|
2361
|
+
return `${camelCase(resource)}${method}`;
|
|
2326
2362
|
}
|
|
2327
2363
|
};
|
|
2328
2364
|
__name(_ServiceMethodGenerator, "ServiceMethodGenerator");
|
|
@@ -2346,22 +2382,16 @@ var _ServiceGenerator = class _ServiceGenerator {
|
|
|
2346
2382
|
}
|
|
2347
2383
|
this.methodGenerator = new ServiceMethodGenerator(config);
|
|
2348
2384
|
}
|
|
2349
|
-
static create(swaggerPathOrUrl, project, config) {
|
|
2350
|
-
return __async(this, null, function* () {
|
|
2351
|
-
const parser = yield SwaggerParser.create(swaggerPathOrUrl, config);
|
|
2352
|
-
return new _ServiceGenerator(parser, project, config);
|
|
2353
|
-
});
|
|
2354
|
-
}
|
|
2355
2385
|
generate(outputRoot) {
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
this.generateServiceFile(controllerName, operations, outputDir);
|
|
2386
|
+
return __async(this, null, function* () {
|
|
2387
|
+
const outputDir = path8.join(outputRoot, "services");
|
|
2388
|
+
const paths = extractPaths(this.spec.paths);
|
|
2389
|
+
if (paths.length === 0) {
|
|
2390
|
+
console.warn("No API paths found in the specification");
|
|
2391
|
+
return;
|
|
2392
|
+
}
|
|
2393
|
+
const controllerGroups = this.groupPathsByController(paths);
|
|
2394
|
+
yield Promise.all(Object.entries(controllerGroups).map(([controllerName, operations]) => this.generateServiceFile(controllerName, operations, outputDir)));
|
|
2365
2395
|
});
|
|
2366
2396
|
}
|
|
2367
2397
|
groupPathsByController(paths) {
|
|
@@ -2385,16 +2415,18 @@ var _ServiceGenerator = class _ServiceGenerator {
|
|
|
2385
2415
|
return groups;
|
|
2386
2416
|
}
|
|
2387
2417
|
generateServiceFile(controllerName, operations, outputDir) {
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2418
|
+
return __async(this, null, function* () {
|
|
2419
|
+
const fileName = `${camelCase(controllerName)}.service.ts`;
|
|
2420
|
+
const filePath = path8.join(outputDir, fileName);
|
|
2421
|
+
const sourceFile = this.project.createSourceFile(filePath, "", {
|
|
2422
|
+
overwrite: true
|
|
2423
|
+
});
|
|
2424
|
+
const usedTypes = collectUsedTypes(operations);
|
|
2425
|
+
this.addImports(sourceFile, usedTypes);
|
|
2426
|
+
this.addServiceClass(sourceFile, controllerName, operations);
|
|
2427
|
+
sourceFile.formatText();
|
|
2428
|
+
sourceFile.saveSync();
|
|
2392
2429
|
});
|
|
2393
|
-
const usedTypes = collectUsedTypes(operations);
|
|
2394
|
-
this.addImports(sourceFile, usedTypes);
|
|
2395
|
-
this.addServiceClass(sourceFile, controllerName, operations);
|
|
2396
|
-
sourceFile.formatText();
|
|
2397
|
-
sourceFile.saveSync();
|
|
2398
2430
|
}
|
|
2399
2431
|
addImports(sourceFile, usedTypes) {
|
|
2400
2432
|
const basePathTokenName = getBasePathTokenName(this.config.clientName);
|
|
@@ -2578,8 +2610,9 @@ function generateFromConfig(config) {
|
|
|
2578
2610
|
}, config.compilerOptions)
|
|
2579
2611
|
});
|
|
2580
2612
|
console.log(`\u{1F4E1} Processing OpenAPI specification from ${inputType}: ${config.input}`);
|
|
2581
|
-
const
|
|
2582
|
-
typeGenerator
|
|
2613
|
+
const swaggerParser = yield SwaggerParser.create(config.input, config);
|
|
2614
|
+
const typeGenerator = new TypeGenerator(swaggerParser, project, config, outputPath);
|
|
2615
|
+
yield typeGenerator.generate();
|
|
2583
2616
|
console.log(`\u2705 TypeScript interfaces generated`);
|
|
2584
2617
|
if (generateServices) {
|
|
2585
2618
|
const tokenGenerator = new TokenGenerator(project, config.clientName);
|
|
@@ -2590,8 +2623,8 @@ function generateFromConfig(config) {
|
|
|
2590
2623
|
}
|
|
2591
2624
|
const fileDownloadHelper = new FileDownloadGenerator(project);
|
|
2592
2625
|
fileDownloadHelper.generate(outputPath);
|
|
2593
|
-
const serviceGenerator =
|
|
2594
|
-
serviceGenerator.generate(outputPath);
|
|
2626
|
+
const serviceGenerator = new ServiceGenerator(swaggerParser, project, config);
|
|
2627
|
+
yield serviceGenerator.generate(outputPath);
|
|
2595
2628
|
const indexGenerator = new ServiceIndexGenerator(project);
|
|
2596
2629
|
indexGenerator.generateIndex(outputPath);
|
|
2597
2630
|
console.log(`\u2705 Angular services generated`);
|
|
@@ -2602,9 +2635,9 @@ function generateFromConfig(config) {
|
|
|
2602
2635
|
}
|
|
2603
2636
|
if ((_b = config.plugins) == null ? void 0 : _b.length) {
|
|
2604
2637
|
for (const plugin of config.plugins) {
|
|
2605
|
-
const
|
|
2606
|
-
const pluginGenerator =
|
|
2607
|
-
pluginGenerator.generate(outputPath);
|
|
2638
|
+
const generatorClass = plugin;
|
|
2639
|
+
const pluginGenerator = new generatorClass(swaggerParser, project, config);
|
|
2640
|
+
yield pluginGenerator.generate(outputPath);
|
|
2608
2641
|
}
|
|
2609
2642
|
console.log(`\u2705 Plugins are generated`);
|
|
2610
2643
|
}
|