ng-openapi 0.1.10 → 0.1.11-pr-20-type-generator-performance-dcd6bb3.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 +235 -192
- package/index.js +239 -194
- package/package.json +1 -1
package/cli.cjs
CHANGED
|
@@ -44,10 +44,13 @@ var fs4 = __toESM(require("fs"));
|
|
|
44
44
|
var path11 = __toESM(require("path"));
|
|
45
45
|
|
|
46
46
|
// package.json
|
|
47
|
-
var version = "0.1.
|
|
47
|
+
var version = "0.1.10";
|
|
48
48
|
|
|
49
49
|
// src/lib/core/generator.ts
|
|
50
|
-
var
|
|
50
|
+
var import_ts_morph6 = require("ts-morph");
|
|
51
|
+
|
|
52
|
+
// src/lib/generators/type/type.generator.ts
|
|
53
|
+
var import_ts_morph = require("ts-morph");
|
|
51
54
|
|
|
52
55
|
// ../shared/src/utils/string.utils.ts
|
|
53
56
|
function camelCase(str) {
|
|
@@ -620,6 +623,13 @@ var TypeGenerator = class {
|
|
|
620
623
|
sourceFile;
|
|
621
624
|
generatedTypes = /* @__PURE__ */ new Set();
|
|
622
625
|
config;
|
|
626
|
+
// Performance caches
|
|
627
|
+
pascalCaseCache = /* @__PURE__ */ new Map();
|
|
628
|
+
sanitizedNameCache = /* @__PURE__ */ new Map();
|
|
629
|
+
typeResolutionCache = /* @__PURE__ */ new Map();
|
|
630
|
+
// Batch collection for AST operations
|
|
631
|
+
statements = [];
|
|
632
|
+
deferredTypes = /* @__PURE__ */ new Map();
|
|
623
633
|
constructor(parser, project, config, outputRoot) {
|
|
624
634
|
this.config = config;
|
|
625
635
|
this.project = project;
|
|
@@ -636,45 +646,44 @@ var TypeGenerator = class {
|
|
|
636
646
|
console.warn("No definitions found in swagger file");
|
|
637
647
|
return;
|
|
638
648
|
}
|
|
639
|
-
this.
|
|
640
|
-
|
|
641
|
-
this.
|
|
642
|
-
this.
|
|
643
|
-
this.sourceFile.saveSync();
|
|
649
|
+
this.collectAllTypeStructures(definitions);
|
|
650
|
+
this.collectSdkTypes();
|
|
651
|
+
this.applyBatchUpdates();
|
|
652
|
+
await this.finalize();
|
|
644
653
|
} catch (error) {
|
|
645
654
|
console.error("Error in generate():", error);
|
|
646
655
|
throw new Error(`Failed to generate types: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
647
656
|
}
|
|
648
657
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
|
|
658
|
+
collectAllTypeStructures(definitions) {
|
|
659
|
+
Object.keys(definitions).forEach((name) => {
|
|
660
|
+
const interfaceName = this.getCachedPascalCase(name);
|
|
661
|
+
this.generatedTypes.add(interfaceName);
|
|
662
|
+
});
|
|
663
|
+
Object.entries(definitions).forEach(([name, definition]) => {
|
|
664
|
+
this.collectTypeStructure(name, definition);
|
|
665
|
+
});
|
|
666
|
+
this.deferredTypes.forEach((definition, name) => {
|
|
667
|
+
this.collectTypeStructure(name, definition);
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
collectTypeStructure(name, definition) {
|
|
671
|
+
const interfaceName = this.getCachedPascalCase(name) ?? "";
|
|
655
672
|
if (definition.enum) {
|
|
656
|
-
this.
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
this.
|
|
661
|
-
return;
|
|
673
|
+
this.collectEnumStructure(interfaceName, definition);
|
|
674
|
+
} else if (definition.allOf) {
|
|
675
|
+
this.collectCompositeTypeStructure(interfaceName, definition);
|
|
676
|
+
} else {
|
|
677
|
+
this.collectInterfaceStructure(interfaceName, definition);
|
|
662
678
|
}
|
|
663
|
-
const interfaceDeclaration = this.sourceFile.addInterface({
|
|
664
|
-
name: interfaceName,
|
|
665
|
-
isExported: true,
|
|
666
|
-
docs: definition.description ? [
|
|
667
|
-
definition.description
|
|
668
|
-
] : void 0
|
|
669
|
-
});
|
|
670
|
-
this.addInterfaceProperties(interfaceDeclaration, definition);
|
|
671
679
|
}
|
|
672
|
-
|
|
680
|
+
collectEnumStructure(name, definition) {
|
|
673
681
|
if (!definition.enum?.length) return;
|
|
674
682
|
const isStringEnum = definition.enum.some((value) => typeof value === "string");
|
|
675
683
|
if (isStringEnum) {
|
|
676
684
|
const unionType = definition.enum.map((value) => typeof value === "string" ? `'${this.escapeString(value)}'` : String(value)).join(" | ");
|
|
677
|
-
this.
|
|
685
|
+
this.statements.push({
|
|
686
|
+
kind: import_ts_morph.StructureKind.TypeAlias,
|
|
678
687
|
name,
|
|
679
688
|
type: unionType,
|
|
680
689
|
isExported: true,
|
|
@@ -682,53 +691,43 @@ var TypeGenerator = class {
|
|
|
682
691
|
definition.description
|
|
683
692
|
] : void 0
|
|
684
693
|
});
|
|
685
|
-
} else if (definition.description && this.config.options.generateEnumBasedOnDescription) {
|
|
686
|
-
const enumDeclaration = this.sourceFile.addEnum({
|
|
687
|
-
name,
|
|
688
|
-
isExported: true
|
|
689
|
-
});
|
|
690
|
-
try {
|
|
691
|
-
const enumValueObjects = JSON.parse(definition.description);
|
|
692
|
-
enumValueObjects.forEach((enumValueObject) => {
|
|
693
|
-
enumDeclaration.addMember({
|
|
694
|
-
name: enumValueObject.Name,
|
|
695
|
-
value: enumValueObject.Value
|
|
696
|
-
});
|
|
697
|
-
});
|
|
698
|
-
} catch (e) {
|
|
699
|
-
console.error(`Failed to parse enum description for ${name}`);
|
|
700
|
-
definition.enum.forEach((value) => {
|
|
701
|
-
const enumKey = this.toEnumKey(value);
|
|
702
|
-
enumDeclaration.addMember({
|
|
703
|
-
name: enumKey,
|
|
704
|
-
value
|
|
705
|
-
});
|
|
706
|
-
});
|
|
707
|
-
}
|
|
708
694
|
} else {
|
|
709
|
-
const
|
|
695
|
+
const members = this.buildEnumMembers(definition);
|
|
696
|
+
this.statements.push({
|
|
697
|
+
kind: import_ts_morph.StructureKind.Enum,
|
|
710
698
|
name,
|
|
711
699
|
isExported: true,
|
|
712
700
|
docs: definition.description ? [
|
|
713
701
|
definition.description
|
|
714
|
-
] : void 0
|
|
715
|
-
|
|
716
|
-
definition.enum.forEach((value) => {
|
|
717
|
-
const enumKey = this.toEnumKey(value);
|
|
718
|
-
enumDeclaration.addMember({
|
|
719
|
-
name: enumKey,
|
|
720
|
-
value
|
|
721
|
-
});
|
|
702
|
+
] : void 0,
|
|
703
|
+
members
|
|
722
704
|
});
|
|
723
705
|
}
|
|
724
706
|
}
|
|
725
|
-
|
|
707
|
+
buildEnumMembers(definition) {
|
|
708
|
+
if (definition.description && this.config.options.generateEnumBasedOnDescription) {
|
|
709
|
+
try {
|
|
710
|
+
const enumValueObjects = JSON.parse(definition.description);
|
|
711
|
+
return enumValueObjects.map((obj) => ({
|
|
712
|
+
name: obj.Name,
|
|
713
|
+
value: obj.Value
|
|
714
|
+
}));
|
|
715
|
+
} catch {
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return definition.enum?.map((value) => ({
|
|
719
|
+
name: this.toEnumKey(value),
|
|
720
|
+
value
|
|
721
|
+
}));
|
|
722
|
+
}
|
|
723
|
+
collectCompositeTypeStructure(name, definition) {
|
|
726
724
|
let typeExpression = "";
|
|
727
725
|
if (definition.allOf) {
|
|
728
|
-
const types = definition.allOf.map((def) => this.
|
|
726
|
+
const types = definition.allOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown");
|
|
729
727
|
typeExpression = types.length > 0 ? types.join(" & ") : "Record<string, unknown>";
|
|
730
728
|
}
|
|
731
|
-
this.
|
|
729
|
+
this.statements.push({
|
|
730
|
+
kind: import_ts_morph.StructureKind.TypeAlias,
|
|
732
731
|
name,
|
|
733
732
|
type: typeExpression,
|
|
734
733
|
isExported: true,
|
|
@@ -737,37 +736,29 @@ var TypeGenerator = class {
|
|
|
737
736
|
] : void 0
|
|
738
737
|
});
|
|
739
738
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
});
|
|
755
|
-
return;
|
|
756
|
-
}
|
|
739
|
+
collectInterfaceStructure(name, definition) {
|
|
740
|
+
const properties = this.buildInterfaceProperties(definition);
|
|
741
|
+
this.statements.push({
|
|
742
|
+
kind: import_ts_morph.StructureKind.Interface,
|
|
743
|
+
name,
|
|
744
|
+
isExported: true,
|
|
745
|
+
docs: definition.description ? [
|
|
746
|
+
definition.description
|
|
747
|
+
] : void 0,
|
|
748
|
+
properties,
|
|
749
|
+
indexSignatures: this.buildIndexSignatures(definition)
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
buildInterfaceProperties(definition) {
|
|
757
753
|
if (!definition.properties) {
|
|
758
|
-
|
|
759
|
-
keyName: "key",
|
|
760
|
-
keyType: "string",
|
|
761
|
-
returnType: "unknown"
|
|
762
|
-
});
|
|
763
|
-
return;
|
|
754
|
+
return [];
|
|
764
755
|
}
|
|
765
|
-
Object.entries(definition.properties).
|
|
756
|
+
return Object.entries(definition.properties).map(([propertyName, property]) => {
|
|
766
757
|
const isRequired = definition.required?.includes(propertyName) ?? false;
|
|
767
758
|
const isReadOnly = property.readOnly;
|
|
768
|
-
const propertyType = this.
|
|
769
|
-
const sanitizedName = this.
|
|
770
|
-
|
|
759
|
+
const propertyType = this.resolveSwaggerTypeCached(property);
|
|
760
|
+
const sanitizedName = this.getCachedSanitizedName(propertyName);
|
|
761
|
+
return {
|
|
771
762
|
name: sanitizedName,
|
|
772
763
|
type: propertyType,
|
|
773
764
|
isReadonly: isReadOnly,
|
|
@@ -775,9 +766,48 @@ var TypeGenerator = class {
|
|
|
775
766
|
docs: property.description ? [
|
|
776
767
|
property.description
|
|
777
768
|
] : void 0
|
|
778
|
-
}
|
|
769
|
+
};
|
|
779
770
|
});
|
|
780
771
|
}
|
|
772
|
+
buildIndexSignatures(definition) {
|
|
773
|
+
if (!definition.properties && definition.additionalProperties === false) {
|
|
774
|
+
return [
|
|
775
|
+
{
|
|
776
|
+
keyName: "key",
|
|
777
|
+
keyType: "string",
|
|
778
|
+
returnType: "never"
|
|
779
|
+
}
|
|
780
|
+
];
|
|
781
|
+
}
|
|
782
|
+
if (!definition.properties && definition.additionalProperties === true) {
|
|
783
|
+
return [
|
|
784
|
+
{
|
|
785
|
+
keyName: "key",
|
|
786
|
+
keyType: "string",
|
|
787
|
+
returnType: "any"
|
|
788
|
+
}
|
|
789
|
+
];
|
|
790
|
+
}
|
|
791
|
+
if (!definition.properties) {
|
|
792
|
+
return [
|
|
793
|
+
{
|
|
794
|
+
keyName: "key",
|
|
795
|
+
keyType: "string",
|
|
796
|
+
returnType: "unknown"
|
|
797
|
+
}
|
|
798
|
+
];
|
|
799
|
+
}
|
|
800
|
+
return [];
|
|
801
|
+
}
|
|
802
|
+
resolveSwaggerTypeCached(schema) {
|
|
803
|
+
const cacheKey = JSON.stringify(schema);
|
|
804
|
+
if (this.typeResolutionCache.has(cacheKey)) {
|
|
805
|
+
return this.typeResolutionCache.get(cacheKey);
|
|
806
|
+
}
|
|
807
|
+
const result = this.resolveSwaggerType(schema);
|
|
808
|
+
this.typeResolutionCache.set(cacheKey, result);
|
|
809
|
+
return result;
|
|
810
|
+
}
|
|
781
811
|
resolveSwaggerType(schema) {
|
|
782
812
|
if (schema.$ref) {
|
|
783
813
|
return this.resolveReference(schema.$ref);
|
|
@@ -786,13 +816,13 @@ var TypeGenerator = class {
|
|
|
786
816
|
return schema.enum.map((value) => typeof value === "string" ? `'${this.escapeString(value)}'` : String(value)).join(" | ");
|
|
787
817
|
}
|
|
788
818
|
if (schema.allOf) {
|
|
789
|
-
return schema.allOf.map((def) => this.
|
|
819
|
+
return schema.allOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown").join(" & ") || "Record<string, unknown>";
|
|
790
820
|
}
|
|
791
821
|
if (schema.oneOf) {
|
|
792
|
-
return schema.oneOf.map((def) => this.
|
|
822
|
+
return schema.oneOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown").join(" | ") || "unknown";
|
|
793
823
|
}
|
|
794
824
|
if (schema.anyOf) {
|
|
795
|
-
return schema.anyOf.map((def) => this.
|
|
825
|
+
return schema.anyOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown").join(" | ") || "unknown";
|
|
796
826
|
}
|
|
797
827
|
if (schema.type === "array") {
|
|
798
828
|
const itemType = schema.items ? this.getArrayItemType(schema.items) : "unknown";
|
|
@@ -803,7 +833,7 @@ var TypeGenerator = class {
|
|
|
803
833
|
return this.generateInlineObjectType(schema);
|
|
804
834
|
}
|
|
805
835
|
if (schema.additionalProperties) {
|
|
806
|
-
const valueType = typeof schema.additionalProperties === "object" ? this.
|
|
836
|
+
const valueType = typeof schema.additionalProperties === "object" ? this.resolveSwaggerTypeCached(schema.additionalProperties) : "unknown";
|
|
807
837
|
return `Record<string, ${valueType}>`;
|
|
808
838
|
}
|
|
809
839
|
return "Record<string, unknown>";
|
|
@@ -813,7 +843,7 @@ var TypeGenerator = class {
|
|
|
813
843
|
generateInlineObjectType(definition) {
|
|
814
844
|
if (!definition.properties) {
|
|
815
845
|
if (definition.additionalProperties) {
|
|
816
|
-
const additionalType = typeof definition.additionalProperties === "object" ? this.
|
|
846
|
+
const additionalType = typeof definition.additionalProperties === "object" ? this.resolveSwaggerTypeCached(definition.additionalProperties) : "unknown";
|
|
817
847
|
return `Record<string, ${additionalType}>`;
|
|
818
848
|
}
|
|
819
849
|
return "Record<string, unknown>";
|
|
@@ -821,29 +851,101 @@ var TypeGenerator = class {
|
|
|
821
851
|
const properties = Object.entries(definition.properties).map(([key, prop]) => {
|
|
822
852
|
const isRequired = definition.required?.includes(key) ?? false;
|
|
823
853
|
const questionMark = isRequired ? "" : "?";
|
|
824
|
-
const sanitizedKey = this.
|
|
825
|
-
return `${sanitizedKey}${questionMark}: ${this.
|
|
854
|
+
const sanitizedKey = this.getCachedSanitizedName(key);
|
|
855
|
+
return `${sanitizedKey}${questionMark}: ${this.resolveSwaggerTypeCached(prop)}`;
|
|
826
856
|
}).join("; ");
|
|
827
857
|
return `{ ${properties} }`;
|
|
828
858
|
}
|
|
829
859
|
resolveReference(ref) {
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
860
|
+
const refName = ref.split("/").pop();
|
|
861
|
+
if (!refName) {
|
|
862
|
+
console.warn(`Invalid reference format: ${ref}`);
|
|
863
|
+
return "unknown";
|
|
864
|
+
}
|
|
865
|
+
return this.getCachedPascalCase(refName);
|
|
866
|
+
}
|
|
867
|
+
collectSdkTypes() {
|
|
868
|
+
const { response } = this.config.options.validation ?? {};
|
|
869
|
+
const typeParameters = [
|
|
870
|
+
"TResponseType extends 'arraybuffer' | 'blob' | 'json' | 'text'"
|
|
871
|
+
];
|
|
872
|
+
const properties = [
|
|
873
|
+
{
|
|
874
|
+
name: "headers",
|
|
875
|
+
type: "HttpHeaders",
|
|
876
|
+
hasQuestionToken: true
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
name: "reportProgress",
|
|
880
|
+
type: "boolean",
|
|
881
|
+
hasQuestionToken: true
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
name: "responseType",
|
|
885
|
+
type: "TResponseType",
|
|
886
|
+
hasQuestionToken: true
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
name: "withCredentials",
|
|
890
|
+
type: "boolean",
|
|
891
|
+
hasQuestionToken: true
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
name: "context",
|
|
895
|
+
type: "HttpContext",
|
|
896
|
+
hasQuestionToken: true
|
|
836
897
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
898
|
+
];
|
|
899
|
+
if (response) {
|
|
900
|
+
properties.push({
|
|
901
|
+
name: "parse",
|
|
902
|
+
type: "(response: unknown) => TReturnType",
|
|
903
|
+
hasQuestionToken: true
|
|
904
|
+
});
|
|
905
|
+
typeParameters.push("TReturnType");
|
|
906
|
+
}
|
|
907
|
+
this.statements.push({
|
|
908
|
+
kind: import_ts_morph.StructureKind.Interface,
|
|
909
|
+
name: "RequestOptions",
|
|
910
|
+
isExported: true,
|
|
911
|
+
typeParameters,
|
|
912
|
+
properties,
|
|
913
|
+
docs: [
|
|
914
|
+
"Request Options for Angular HttpClient requests"
|
|
915
|
+
]
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
applyBatchUpdates() {
|
|
919
|
+
this.sourceFile.insertText(0, TYPE_GENERATOR_HEADER_COMMENT);
|
|
920
|
+
this.sourceFile.addImportDeclarations([
|
|
921
|
+
{
|
|
922
|
+
namedImports: [
|
|
923
|
+
"HttpContext",
|
|
924
|
+
"HttpHeaders"
|
|
925
|
+
],
|
|
926
|
+
moduleSpecifier: "@angular/common/http"
|
|
840
927
|
}
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
928
|
+
]);
|
|
929
|
+
this.sourceFile.addStatements(this.statements);
|
|
930
|
+
}
|
|
931
|
+
async finalize() {
|
|
932
|
+
this.sourceFile.formatText();
|
|
933
|
+
await this.sourceFile.save();
|
|
934
|
+
}
|
|
935
|
+
// Cached helper methods
|
|
936
|
+
getCachedPascalCase(str) {
|
|
937
|
+
if (!this.pascalCaseCache.has(str)) {
|
|
938
|
+
this.pascalCaseCache.set(str, this.pascalCaseForEnums(str));
|
|
939
|
+
}
|
|
940
|
+
return this.pascalCaseCache.get(str);
|
|
941
|
+
}
|
|
942
|
+
getCachedSanitizedName(name) {
|
|
943
|
+
if (!this.sanitizedNameCache.has(name)) {
|
|
944
|
+
this.sanitizedNameCache.set(name, this.sanitizePropertyName(name));
|
|
845
945
|
}
|
|
946
|
+
return this.sanitizedNameCache.get(name);
|
|
846
947
|
}
|
|
948
|
+
// Original helper methods
|
|
847
949
|
mapSwaggerTypeToTypeScript(type, format, isNullable) {
|
|
848
950
|
if (!type) return "unknown";
|
|
849
951
|
switch (type) {
|
|
@@ -890,78 +992,19 @@ var TypeGenerator = class {
|
|
|
890
992
|
}
|
|
891
993
|
getArrayItemType(items) {
|
|
892
994
|
if (Array.isArray(items)) {
|
|
893
|
-
const types = items.map((item) => this.
|
|
995
|
+
const types = items.map((item) => this.resolveSwaggerTypeCached(item));
|
|
894
996
|
return `[${types.join(", ")}]`;
|
|
895
997
|
} else {
|
|
896
|
-
return this.
|
|
998
|
+
return this.resolveSwaggerTypeCached(items);
|
|
897
999
|
}
|
|
898
1000
|
}
|
|
899
1001
|
escapeString(str) {
|
|
900
1002
|
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
901
1003
|
}
|
|
902
|
-
generateSdkTypes() {
|
|
903
|
-
this.sourceFile.addImportDeclarations([
|
|
904
|
-
{
|
|
905
|
-
namedImports: [
|
|
906
|
-
"HttpContext",
|
|
907
|
-
"HttpHeaders"
|
|
908
|
-
],
|
|
909
|
-
moduleSpecifier: "@angular/common/http"
|
|
910
|
-
}
|
|
911
|
-
]);
|
|
912
|
-
const { response } = this.config.options.validation ?? {};
|
|
913
|
-
const typeParameters = [
|
|
914
|
-
"TResponseType extends 'arraybuffer' | 'blob' | 'json' | 'text'"
|
|
915
|
-
];
|
|
916
|
-
const properties = [
|
|
917
|
-
{
|
|
918
|
-
name: "headers",
|
|
919
|
-
type: "HttpHeaders",
|
|
920
|
-
hasQuestionToken: true
|
|
921
|
-
},
|
|
922
|
-
{
|
|
923
|
-
name: "reportProgress",
|
|
924
|
-
type: "boolean",
|
|
925
|
-
hasQuestionToken: true
|
|
926
|
-
},
|
|
927
|
-
{
|
|
928
|
-
name: "responseType",
|
|
929
|
-
type: "TResponseType",
|
|
930
|
-
hasQuestionToken: true
|
|
931
|
-
},
|
|
932
|
-
{
|
|
933
|
-
name: "withCredentials",
|
|
934
|
-
type: "boolean",
|
|
935
|
-
hasQuestionToken: true
|
|
936
|
-
},
|
|
937
|
-
{
|
|
938
|
-
name: "context",
|
|
939
|
-
type: "HttpContext",
|
|
940
|
-
hasQuestionToken: true
|
|
941
|
-
}
|
|
942
|
-
];
|
|
943
|
-
if (response) {
|
|
944
|
-
properties.push({
|
|
945
|
-
name: "parse",
|
|
946
|
-
type: "(response: unknown) => TReturnType",
|
|
947
|
-
hasQuestionToken: true
|
|
948
|
-
});
|
|
949
|
-
typeParameters.push("TReturnType");
|
|
950
|
-
}
|
|
951
|
-
this.sourceFile.addInterface({
|
|
952
|
-
name: "RequestOptions",
|
|
953
|
-
isExported: true,
|
|
954
|
-
typeParameters,
|
|
955
|
-
properties,
|
|
956
|
-
docs: [
|
|
957
|
-
"Request Options for Angular HttpClient requests"
|
|
958
|
-
]
|
|
959
|
-
});
|
|
960
|
-
}
|
|
961
1004
|
};
|
|
962
1005
|
|
|
963
1006
|
// src/lib/generators/utility/token.generator.ts
|
|
964
|
-
var
|
|
1007
|
+
var import_ts_morph2 = require("ts-morph");
|
|
965
1008
|
var path2 = __toESM(require("path"));
|
|
966
1009
|
var TokenGenerator = class {
|
|
967
1010
|
static {
|
|
@@ -997,7 +1040,7 @@ var TokenGenerator = class {
|
|
|
997
1040
|
const clientContextTokenName = this.getClientContextTokenName();
|
|
998
1041
|
sourceFile.addVariableStatement({
|
|
999
1042
|
isExported: true,
|
|
1000
|
-
declarationKind:
|
|
1043
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1001
1044
|
declarations: [
|
|
1002
1045
|
{
|
|
1003
1046
|
name: basePathTokenName,
|
|
@@ -1014,7 +1057,7 @@ var TokenGenerator = class {
|
|
|
1014
1057
|
});
|
|
1015
1058
|
sourceFile.addVariableStatement({
|
|
1016
1059
|
isExported: true,
|
|
1017
|
-
declarationKind:
|
|
1060
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1018
1061
|
declarations: [
|
|
1019
1062
|
{
|
|
1020
1063
|
name: interceptorsTokenName,
|
|
@@ -1031,7 +1074,7 @@ var TokenGenerator = class {
|
|
|
1031
1074
|
});
|
|
1032
1075
|
sourceFile.addVariableStatement({
|
|
1033
1076
|
isExported: true,
|
|
1034
|
-
declarationKind:
|
|
1077
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1035
1078
|
declarations: [
|
|
1036
1079
|
{
|
|
1037
1080
|
name: clientContextTokenName,
|
|
@@ -1046,7 +1089,7 @@ var TokenGenerator = class {
|
|
|
1046
1089
|
if (this.clientName === "default") {
|
|
1047
1090
|
sourceFile.addVariableStatement({
|
|
1048
1091
|
isExported: true,
|
|
1049
|
-
declarationKind:
|
|
1092
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1050
1093
|
declarations: [
|
|
1051
1094
|
{
|
|
1052
1095
|
name: "BASE_PATH",
|
|
@@ -1060,7 +1103,7 @@ var TokenGenerator = class {
|
|
|
1060
1103
|
});
|
|
1061
1104
|
sourceFile.addVariableStatement({
|
|
1062
1105
|
isExported: true,
|
|
1063
|
-
declarationKind:
|
|
1106
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1064
1107
|
declarations: [
|
|
1065
1108
|
{
|
|
1066
1109
|
name: "CLIENT_CONTEXT_TOKEN",
|
|
@@ -1233,7 +1276,7 @@ var FileDownloadGenerator = class {
|
|
|
1233
1276
|
};
|
|
1234
1277
|
|
|
1235
1278
|
// src/lib/generators/utility/date-transformer.generator.ts
|
|
1236
|
-
var
|
|
1279
|
+
var import_ts_morph3 = require("ts-morph");
|
|
1237
1280
|
var path4 = __toESM(require("path"));
|
|
1238
1281
|
var DateTransformerGenerator = class {
|
|
1239
1282
|
static {
|
|
@@ -1279,7 +1322,7 @@ var DateTransformerGenerator = class {
|
|
|
1279
1322
|
});
|
|
1280
1323
|
sourceFile.addVariableStatement({
|
|
1281
1324
|
isExported: true,
|
|
1282
|
-
declarationKind:
|
|
1325
|
+
declarationKind: import_ts_morph3.VariableDeclarationKind.Const,
|
|
1283
1326
|
declarations: [
|
|
1284
1327
|
{
|
|
1285
1328
|
name: "ISO_DATE_REGEX",
|
|
@@ -1621,7 +1664,7 @@ return makeEnvironmentProviders(providers);`;
|
|
|
1621
1664
|
};
|
|
1622
1665
|
|
|
1623
1666
|
// src/lib/generators/utility/base-interceptor.generator.ts
|
|
1624
|
-
var
|
|
1667
|
+
var import_ts_morph4 = require("ts-morph");
|
|
1625
1668
|
var path7 = __toESM(require("path"));
|
|
1626
1669
|
var BaseInterceptorGenerator = class {
|
|
1627
1670
|
static {
|
|
@@ -1690,14 +1733,14 @@ var BaseInterceptorGenerator = class {
|
|
|
1690
1733
|
{
|
|
1691
1734
|
name: "httpInterceptors",
|
|
1692
1735
|
type: "HttpInterceptor[]",
|
|
1693
|
-
scope:
|
|
1736
|
+
scope: import_ts_morph4.Scope.Private,
|
|
1694
1737
|
isReadonly: true,
|
|
1695
1738
|
initializer: `inject(${interceptorsTokenName})`
|
|
1696
1739
|
},
|
|
1697
1740
|
{
|
|
1698
1741
|
name: "clientContextToken",
|
|
1699
1742
|
type: "HttpContextToken<string>",
|
|
1700
|
-
scope:
|
|
1743
|
+
scope: import_ts_morph4.Scope.Private,
|
|
1701
1744
|
isReadonly: true,
|
|
1702
1745
|
initializer: clientContextTokenName
|
|
1703
1746
|
}
|
|
@@ -1754,7 +1797,7 @@ var BaseInterceptorGenerator = class {
|
|
|
1754
1797
|
};
|
|
1755
1798
|
|
|
1756
1799
|
// src/lib/generators/service/service.generator.ts
|
|
1757
|
-
var
|
|
1800
|
+
var import_ts_morph5 = require("ts-morph");
|
|
1758
1801
|
var path8 = __toESM(require("path"));
|
|
1759
1802
|
|
|
1760
1803
|
// src/lib/generators/service/service-method/service-method-body.generator.ts
|
|
@@ -2331,27 +2374,27 @@ var ServiceGenerator = class {
|
|
|
2331
2374
|
serviceClass.addProperty({
|
|
2332
2375
|
name: "httpClient",
|
|
2333
2376
|
type: "HttpClient",
|
|
2334
|
-
scope:
|
|
2377
|
+
scope: import_ts_morph5.Scope.Private,
|
|
2335
2378
|
isReadonly: true,
|
|
2336
2379
|
initializer: "inject(HttpClient)"
|
|
2337
2380
|
});
|
|
2338
2381
|
serviceClass.addProperty({
|
|
2339
2382
|
name: "basePath",
|
|
2340
2383
|
type: "string",
|
|
2341
|
-
scope:
|
|
2384
|
+
scope: import_ts_morph5.Scope.Private,
|
|
2342
2385
|
isReadonly: true,
|
|
2343
2386
|
initializer: `inject(${basePathTokenName})`
|
|
2344
2387
|
});
|
|
2345
2388
|
serviceClass.addProperty({
|
|
2346
2389
|
name: "clientContextToken",
|
|
2347
2390
|
type: "HttpContextToken<string>",
|
|
2348
|
-
scope:
|
|
2391
|
+
scope: import_ts_morph5.Scope.Private,
|
|
2349
2392
|
isReadonly: true,
|
|
2350
2393
|
initializer: clientContextTokenName
|
|
2351
2394
|
});
|
|
2352
2395
|
serviceClass.addMethod({
|
|
2353
2396
|
name: "createContextWithClientId",
|
|
2354
|
-
scope:
|
|
2397
|
+
scope: import_ts_morph5.Scope.Private,
|
|
2355
2398
|
parameters: [
|
|
2356
2399
|
{
|
|
2357
2400
|
name: "existingContext",
|
|
@@ -2436,11 +2479,11 @@ async function generateFromConfig(config) {
|
|
|
2436
2479
|
});
|
|
2437
2480
|
}
|
|
2438
2481
|
try {
|
|
2439
|
-
const project = new
|
|
2482
|
+
const project = new import_ts_morph6.Project({
|
|
2440
2483
|
compilerOptions: {
|
|
2441
2484
|
declaration: true,
|
|
2442
|
-
target:
|
|
2443
|
-
module:
|
|
2485
|
+
target: import_ts_morph6.ScriptTarget.ES2022,
|
|
2486
|
+
module: import_ts_morph6.ModuleKind.Preserve,
|
|
2444
2487
|
strict: true,
|
|
2445
2488
|
...config.compilerOptions
|
|
2446
2489
|
}
|
package/index.js
CHANGED
|
@@ -105,7 +105,10 @@ __export(index_exports, {
|
|
|
105
105
|
module.exports = __toCommonJS(index_exports);
|
|
106
106
|
|
|
107
107
|
// src/lib/core/generator.ts
|
|
108
|
-
var
|
|
108
|
+
var import_ts_morph6 = require("ts-morph");
|
|
109
|
+
|
|
110
|
+
// src/lib/generators/type/type.generator.ts
|
|
111
|
+
var import_ts_morph = require("ts-morph");
|
|
109
112
|
|
|
110
113
|
// ../shared/src/utils/string.utils.ts
|
|
111
114
|
function camelCase(str) {
|
|
@@ -723,6 +726,13 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
723
726
|
__publicField(this, "sourceFile");
|
|
724
727
|
__publicField(this, "generatedTypes", /* @__PURE__ */ new Set());
|
|
725
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());
|
|
726
736
|
this.config = config;
|
|
727
737
|
this.project = project;
|
|
728
738
|
this.parser = parser;
|
|
@@ -739,49 +749,47 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
739
749
|
console.warn("No definitions found in swagger file");
|
|
740
750
|
return;
|
|
741
751
|
}
|
|
742
|
-
this.
|
|
743
|
-
|
|
744
|
-
this.
|
|
745
|
-
this.
|
|
746
|
-
this.sourceFile.saveSync();
|
|
752
|
+
this.collectAllTypeStructures(definitions);
|
|
753
|
+
this.collectSdkTypes();
|
|
754
|
+
this.applyBatchUpdates();
|
|
755
|
+
yield this.finalize();
|
|
747
756
|
} catch (error) {
|
|
748
757
|
console.error("Error in generate():", error);
|
|
749
758
|
throw new Error(`Failed to generate types: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
750
759
|
}
|
|
751
760
|
});
|
|
752
761
|
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
const interfaceName = this.
|
|
756
|
-
if (this.generatedTypes.has(interfaceName)) {
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
762
|
+
collectAllTypeStructures(definitions) {
|
|
763
|
+
Object.keys(definitions).forEach((name) => {
|
|
764
|
+
const interfaceName = this.getCachedPascalCase(name);
|
|
759
765
|
this.generatedTypes.add(interfaceName);
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
return;
|
|
767
|
-
}
|
|
768
|
-
const interfaceDeclaration = this.sourceFile.addInterface({
|
|
769
|
-
name: interfaceName,
|
|
770
|
-
isExported: true,
|
|
771
|
-
docs: definition.description ? [
|
|
772
|
-
definition.description
|
|
773
|
-
] : void 0
|
|
774
|
-
});
|
|
775
|
-
this.addInterfaceProperties(interfaceDeclaration, definition);
|
|
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);
|
|
776
772
|
});
|
|
777
773
|
}
|
|
778
|
-
|
|
774
|
+
collectTypeStructure(name, definition) {
|
|
775
|
+
var _a;
|
|
776
|
+
const interfaceName = (_a = this.getCachedPascalCase(name)) != null ? _a : "";
|
|
777
|
+
if (definition.enum) {
|
|
778
|
+
this.collectEnumStructure(interfaceName, definition);
|
|
779
|
+
} else if (definition.allOf) {
|
|
780
|
+
this.collectCompositeTypeStructure(interfaceName, definition);
|
|
781
|
+
} else {
|
|
782
|
+
this.collectInterfaceStructure(interfaceName, definition);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
collectEnumStructure(name, definition) {
|
|
779
786
|
var _a;
|
|
780
787
|
if (!((_a = definition.enum) == null ? void 0 : _a.length)) return;
|
|
781
788
|
const isStringEnum = definition.enum.some((value) => typeof value === "string");
|
|
782
789
|
if (isStringEnum) {
|
|
783
790
|
const unionType = definition.enum.map((value) => typeof value === "string" ? `'${this.escapeString(value)}'` : String(value)).join(" | ");
|
|
784
|
-
this.
|
|
791
|
+
this.statements.push({
|
|
792
|
+
kind: import_ts_morph.StructureKind.TypeAlias,
|
|
785
793
|
name,
|
|
786
794
|
type: unionType,
|
|
787
795
|
isExported: true,
|
|
@@ -789,53 +797,44 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
789
797
|
definition.description
|
|
790
798
|
] : void 0
|
|
791
799
|
});
|
|
792
|
-
} else if (definition.description && this.config.options.generateEnumBasedOnDescription) {
|
|
793
|
-
const enumDeclaration = this.sourceFile.addEnum({
|
|
794
|
-
name,
|
|
795
|
-
isExported: true
|
|
796
|
-
});
|
|
797
|
-
try {
|
|
798
|
-
const enumValueObjects = JSON.parse(definition.description);
|
|
799
|
-
enumValueObjects.forEach((enumValueObject) => {
|
|
800
|
-
enumDeclaration.addMember({
|
|
801
|
-
name: enumValueObject.Name,
|
|
802
|
-
value: enumValueObject.Value
|
|
803
|
-
});
|
|
804
|
-
});
|
|
805
|
-
} catch (e) {
|
|
806
|
-
console.error(`Failed to parse enum description for ${name}`);
|
|
807
|
-
definition.enum.forEach((value) => {
|
|
808
|
-
const enumKey = this.toEnumKey(value);
|
|
809
|
-
enumDeclaration.addMember({
|
|
810
|
-
name: enumKey,
|
|
811
|
-
value
|
|
812
|
-
});
|
|
813
|
-
});
|
|
814
|
-
}
|
|
815
800
|
} else {
|
|
816
|
-
const
|
|
801
|
+
const members = this.buildEnumMembers(definition);
|
|
802
|
+
this.statements.push({
|
|
803
|
+
kind: import_ts_morph.StructureKind.Enum,
|
|
817
804
|
name,
|
|
818
805
|
isExported: true,
|
|
819
806
|
docs: definition.description ? [
|
|
820
807
|
definition.description
|
|
821
|
-
] : void 0
|
|
822
|
-
|
|
823
|
-
definition.enum.forEach((value) => {
|
|
824
|
-
const enumKey = this.toEnumKey(value);
|
|
825
|
-
enumDeclaration.addMember({
|
|
826
|
-
name: enumKey,
|
|
827
|
-
value
|
|
828
|
-
});
|
|
808
|
+
] : void 0,
|
|
809
|
+
members
|
|
829
810
|
});
|
|
830
811
|
}
|
|
831
812
|
}
|
|
832
|
-
|
|
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) {
|
|
833
831
|
let typeExpression = "";
|
|
834
832
|
if (definition.allOf) {
|
|
835
|
-
const types = definition.allOf.map((def) => this.
|
|
833
|
+
const types = definition.allOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown");
|
|
836
834
|
typeExpression = types.length > 0 ? types.join(" & ") : "Record<string, unknown>";
|
|
837
835
|
}
|
|
838
|
-
this.
|
|
836
|
+
this.statements.push({
|
|
837
|
+
kind: import_ts_morph.StructureKind.TypeAlias,
|
|
839
838
|
name,
|
|
840
839
|
type: typeExpression,
|
|
841
840
|
isExported: true,
|
|
@@ -844,38 +843,30 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
844
843
|
] : void 0
|
|
845
844
|
});
|
|
846
845
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
});
|
|
862
|
-
return;
|
|
863
|
-
}
|
|
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) {
|
|
864
860
|
if (!definition.properties) {
|
|
865
|
-
|
|
866
|
-
keyName: "key",
|
|
867
|
-
keyType: "string",
|
|
868
|
-
returnType: "unknown"
|
|
869
|
-
});
|
|
870
|
-
return;
|
|
861
|
+
return [];
|
|
871
862
|
}
|
|
872
|
-
Object.entries(definition.properties).
|
|
863
|
+
return Object.entries(definition.properties).map(([propertyName, property]) => {
|
|
873
864
|
var _a, _b;
|
|
874
865
|
const isRequired = (_b = (_a = definition.required) == null ? void 0 : _a.includes(propertyName)) != null ? _b : false;
|
|
875
866
|
const isReadOnly = property.readOnly;
|
|
876
|
-
const propertyType = this.
|
|
877
|
-
const sanitizedName = this.
|
|
878
|
-
|
|
867
|
+
const propertyType = this.resolveSwaggerTypeCached(property);
|
|
868
|
+
const sanitizedName = this.getCachedSanitizedName(propertyName);
|
|
869
|
+
return {
|
|
879
870
|
name: sanitizedName,
|
|
880
871
|
type: propertyType,
|
|
881
872
|
isReadonly: isReadOnly,
|
|
@@ -883,9 +874,48 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
883
874
|
docs: property.description ? [
|
|
884
875
|
property.description
|
|
885
876
|
] : void 0
|
|
886
|
-
}
|
|
877
|
+
};
|
|
887
878
|
});
|
|
888
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
|
+
}
|
|
889
919
|
resolveSwaggerType(schema) {
|
|
890
920
|
if (schema.$ref) {
|
|
891
921
|
return this.resolveReference(schema.$ref);
|
|
@@ -894,13 +924,13 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
894
924
|
return schema.enum.map((value) => typeof value === "string" ? `'${this.escapeString(value)}'` : String(value)).join(" | ");
|
|
895
925
|
}
|
|
896
926
|
if (schema.allOf) {
|
|
897
|
-
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>";
|
|
898
928
|
}
|
|
899
929
|
if (schema.oneOf) {
|
|
900
|
-
return schema.oneOf.map((def) => this.
|
|
930
|
+
return schema.oneOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown").join(" | ") || "unknown";
|
|
901
931
|
}
|
|
902
932
|
if (schema.anyOf) {
|
|
903
|
-
return schema.anyOf.map((def) => this.
|
|
933
|
+
return schema.anyOf.map((def) => this.resolveSwaggerTypeCached(def)).filter((type) => type !== "any" && type !== "unknown").join(" | ") || "unknown";
|
|
904
934
|
}
|
|
905
935
|
if (schema.type === "array") {
|
|
906
936
|
const itemType = schema.items ? this.getArrayItemType(schema.items) : "unknown";
|
|
@@ -911,7 +941,7 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
911
941
|
return this.generateInlineObjectType(schema);
|
|
912
942
|
}
|
|
913
943
|
if (schema.additionalProperties) {
|
|
914
|
-
const valueType = typeof schema.additionalProperties === "object" ? this.
|
|
944
|
+
const valueType = typeof schema.additionalProperties === "object" ? this.resolveSwaggerTypeCached(schema.additionalProperties) : "unknown";
|
|
915
945
|
return `Record<string, ${valueType}>`;
|
|
916
946
|
}
|
|
917
947
|
return "Record<string, unknown>";
|
|
@@ -921,7 +951,7 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
921
951
|
generateInlineObjectType(definition) {
|
|
922
952
|
if (!definition.properties) {
|
|
923
953
|
if (definition.additionalProperties) {
|
|
924
|
-
const additionalType = typeof definition.additionalProperties === "object" ? this.
|
|
954
|
+
const additionalType = typeof definition.additionalProperties === "object" ? this.resolveSwaggerTypeCached(definition.additionalProperties) : "unknown";
|
|
925
955
|
return `Record<string, ${additionalType}>`;
|
|
926
956
|
}
|
|
927
957
|
return "Record<string, unknown>";
|
|
@@ -930,29 +960,104 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
930
960
|
var _a, _b;
|
|
931
961
|
const isRequired = (_b = (_a = definition.required) == null ? void 0 : _a.includes(key)) != null ? _b : false;
|
|
932
962
|
const questionMark = isRequired ? "" : "?";
|
|
933
|
-
const sanitizedKey = this.
|
|
934
|
-
return `${sanitizedKey}${questionMark}: ${this.
|
|
963
|
+
const sanitizedKey = this.getCachedSanitizedName(key);
|
|
964
|
+
return `${sanitizedKey}${questionMark}: ${this.resolveSwaggerTypeCached(prop)}`;
|
|
935
965
|
}).join("; ");
|
|
936
966
|
return `{ ${properties} }`;
|
|
937
967
|
}
|
|
938
968
|
resolveReference(ref) {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
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
|
|
945
1007
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
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"
|
|
949
1037
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
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));
|
|
954
1051
|
}
|
|
1052
|
+
return this.pascalCaseCache.get(str);
|
|
955
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
|
|
956
1061
|
mapSwaggerTypeToTypeScript(type, format, isNullable) {
|
|
957
1062
|
if (!type) return "unknown";
|
|
958
1063
|
switch (type) {
|
|
@@ -999,81 +1104,21 @@ var _TypeGenerator = class _TypeGenerator {
|
|
|
999
1104
|
}
|
|
1000
1105
|
getArrayItemType(items) {
|
|
1001
1106
|
if (Array.isArray(items)) {
|
|
1002
|
-
const types = items.map((item) => this.
|
|
1107
|
+
const types = items.map((item) => this.resolveSwaggerTypeCached(item));
|
|
1003
1108
|
return `[${types.join(", ")}]`;
|
|
1004
1109
|
} else {
|
|
1005
|
-
return this.
|
|
1110
|
+
return this.resolveSwaggerTypeCached(items);
|
|
1006
1111
|
}
|
|
1007
1112
|
}
|
|
1008
1113
|
escapeString(str) {
|
|
1009
1114
|
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
1010
1115
|
}
|
|
1011
|
-
generateSdkTypes() {
|
|
1012
|
-
var _a;
|
|
1013
|
-
this.sourceFile.addImportDeclarations([
|
|
1014
|
-
{
|
|
1015
|
-
namedImports: [
|
|
1016
|
-
"HttpContext",
|
|
1017
|
-
"HttpHeaders"
|
|
1018
|
-
],
|
|
1019
|
-
moduleSpecifier: "@angular/common/http"
|
|
1020
|
-
}
|
|
1021
|
-
]);
|
|
1022
|
-
const { response } = (_a = this.config.options.validation) != null ? _a : {};
|
|
1023
|
-
const typeParameters = [
|
|
1024
|
-
"TResponseType extends 'arraybuffer' | 'blob' | 'json' | 'text'"
|
|
1025
|
-
];
|
|
1026
|
-
const properties = [
|
|
1027
|
-
{
|
|
1028
|
-
name: "headers",
|
|
1029
|
-
type: "HttpHeaders",
|
|
1030
|
-
hasQuestionToken: true
|
|
1031
|
-
},
|
|
1032
|
-
{
|
|
1033
|
-
name: "reportProgress",
|
|
1034
|
-
type: "boolean",
|
|
1035
|
-
hasQuestionToken: true
|
|
1036
|
-
},
|
|
1037
|
-
{
|
|
1038
|
-
name: "responseType",
|
|
1039
|
-
type: "TResponseType",
|
|
1040
|
-
hasQuestionToken: true
|
|
1041
|
-
},
|
|
1042
|
-
{
|
|
1043
|
-
name: "withCredentials",
|
|
1044
|
-
type: "boolean",
|
|
1045
|
-
hasQuestionToken: true
|
|
1046
|
-
},
|
|
1047
|
-
{
|
|
1048
|
-
name: "context",
|
|
1049
|
-
type: "HttpContext",
|
|
1050
|
-
hasQuestionToken: true
|
|
1051
|
-
}
|
|
1052
|
-
];
|
|
1053
|
-
if (response) {
|
|
1054
|
-
properties.push({
|
|
1055
|
-
name: "parse",
|
|
1056
|
-
type: "(response: unknown) => TReturnType",
|
|
1057
|
-
hasQuestionToken: true
|
|
1058
|
-
});
|
|
1059
|
-
typeParameters.push("TReturnType");
|
|
1060
|
-
}
|
|
1061
|
-
this.sourceFile.addInterface({
|
|
1062
|
-
name: "RequestOptions",
|
|
1063
|
-
isExported: true,
|
|
1064
|
-
typeParameters,
|
|
1065
|
-
properties,
|
|
1066
|
-
docs: [
|
|
1067
|
-
"Request Options for Angular HttpClient requests"
|
|
1068
|
-
]
|
|
1069
|
-
});
|
|
1070
|
-
}
|
|
1071
1116
|
};
|
|
1072
1117
|
__name(_TypeGenerator, "TypeGenerator");
|
|
1073
1118
|
var TypeGenerator = _TypeGenerator;
|
|
1074
1119
|
|
|
1075
1120
|
// src/lib/generators/utility/token.generator.ts
|
|
1076
|
-
var
|
|
1121
|
+
var import_ts_morph2 = require("ts-morph");
|
|
1077
1122
|
var path2 = __toESM(require("path"));
|
|
1078
1123
|
var _TokenGenerator = class _TokenGenerator {
|
|
1079
1124
|
constructor(project, clientName = "default") {
|
|
@@ -1106,7 +1151,7 @@ var _TokenGenerator = class _TokenGenerator {
|
|
|
1106
1151
|
const clientContextTokenName = this.getClientContextTokenName();
|
|
1107
1152
|
sourceFile.addVariableStatement({
|
|
1108
1153
|
isExported: true,
|
|
1109
|
-
declarationKind:
|
|
1154
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1110
1155
|
declarations: [
|
|
1111
1156
|
{
|
|
1112
1157
|
name: basePathTokenName,
|
|
@@ -1123,7 +1168,7 @@ var _TokenGenerator = class _TokenGenerator {
|
|
|
1123
1168
|
});
|
|
1124
1169
|
sourceFile.addVariableStatement({
|
|
1125
1170
|
isExported: true,
|
|
1126
|
-
declarationKind:
|
|
1171
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1127
1172
|
declarations: [
|
|
1128
1173
|
{
|
|
1129
1174
|
name: interceptorsTokenName,
|
|
@@ -1140,7 +1185,7 @@ var _TokenGenerator = class _TokenGenerator {
|
|
|
1140
1185
|
});
|
|
1141
1186
|
sourceFile.addVariableStatement({
|
|
1142
1187
|
isExported: true,
|
|
1143
|
-
declarationKind:
|
|
1188
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1144
1189
|
declarations: [
|
|
1145
1190
|
{
|
|
1146
1191
|
name: clientContextTokenName,
|
|
@@ -1155,7 +1200,7 @@ var _TokenGenerator = class _TokenGenerator {
|
|
|
1155
1200
|
if (this.clientName === "default") {
|
|
1156
1201
|
sourceFile.addVariableStatement({
|
|
1157
1202
|
isExported: true,
|
|
1158
|
-
declarationKind:
|
|
1203
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1159
1204
|
declarations: [
|
|
1160
1205
|
{
|
|
1161
1206
|
name: "BASE_PATH",
|
|
@@ -1169,7 +1214,7 @@ var _TokenGenerator = class _TokenGenerator {
|
|
|
1169
1214
|
});
|
|
1170
1215
|
sourceFile.addVariableStatement({
|
|
1171
1216
|
isExported: true,
|
|
1172
|
-
declarationKind:
|
|
1217
|
+
declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
|
|
1173
1218
|
declarations: [
|
|
1174
1219
|
{
|
|
1175
1220
|
name: "CLIENT_CONTEXT_TOKEN",
|
|
@@ -1343,7 +1388,7 @@ __name(_FileDownloadGenerator, "FileDownloadGenerator");
|
|
|
1343
1388
|
var FileDownloadGenerator = _FileDownloadGenerator;
|
|
1344
1389
|
|
|
1345
1390
|
// src/lib/generators/utility/date-transformer.generator.ts
|
|
1346
|
-
var
|
|
1391
|
+
var import_ts_morph3 = require("ts-morph");
|
|
1347
1392
|
var path4 = __toESM(require("path"));
|
|
1348
1393
|
var _DateTransformerGenerator = class _DateTransformerGenerator {
|
|
1349
1394
|
constructor(project) {
|
|
@@ -1386,7 +1431,7 @@ var _DateTransformerGenerator = class _DateTransformerGenerator {
|
|
|
1386
1431
|
});
|
|
1387
1432
|
sourceFile.addVariableStatement({
|
|
1388
1433
|
isExported: true,
|
|
1389
|
-
declarationKind:
|
|
1434
|
+
declarationKind: import_ts_morph3.VariableDeclarationKind.Const,
|
|
1390
1435
|
declarations: [
|
|
1391
1436
|
{
|
|
1392
1437
|
name: "ISO_DATE_REGEX",
|
|
@@ -1728,7 +1773,7 @@ __name(_ProviderGenerator, "ProviderGenerator");
|
|
|
1728
1773
|
var ProviderGenerator = _ProviderGenerator;
|
|
1729
1774
|
|
|
1730
1775
|
// src/lib/generators/utility/base-interceptor.generator.ts
|
|
1731
|
-
var
|
|
1776
|
+
var import_ts_morph4 = require("ts-morph");
|
|
1732
1777
|
var path7 = __toESM(require("path"));
|
|
1733
1778
|
var _project, _clientName;
|
|
1734
1779
|
var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
|
|
@@ -1795,14 +1840,14 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
|
|
|
1795
1840
|
{
|
|
1796
1841
|
name: "httpInterceptors",
|
|
1797
1842
|
type: "HttpInterceptor[]",
|
|
1798
|
-
scope:
|
|
1843
|
+
scope: import_ts_morph4.Scope.Private,
|
|
1799
1844
|
isReadonly: true,
|
|
1800
1845
|
initializer: `inject(${interceptorsTokenName})`
|
|
1801
1846
|
},
|
|
1802
1847
|
{
|
|
1803
1848
|
name: "clientContextToken",
|
|
1804
1849
|
type: "HttpContextToken<string>",
|
|
1805
|
-
scope:
|
|
1850
|
+
scope: import_ts_morph4.Scope.Private,
|
|
1806
1851
|
isReadonly: true,
|
|
1807
1852
|
initializer: clientContextTokenName
|
|
1808
1853
|
}
|
|
@@ -1863,7 +1908,7 @@ __name(_BaseInterceptorGenerator, "BaseInterceptorGenerator");
|
|
|
1863
1908
|
var BaseInterceptorGenerator = _BaseInterceptorGenerator;
|
|
1864
1909
|
|
|
1865
1910
|
// src/lib/generators/service/service.generator.ts
|
|
1866
|
-
var
|
|
1911
|
+
var import_ts_morph5 = require("ts-morph");
|
|
1867
1912
|
var path8 = __toESM(require("path"));
|
|
1868
1913
|
|
|
1869
1914
|
// src/lib/generators/service/service-method/service-method-body.generator.ts
|
|
@@ -2448,27 +2493,27 @@ var _ServiceGenerator = class _ServiceGenerator {
|
|
|
2448
2493
|
serviceClass.addProperty({
|
|
2449
2494
|
name: "httpClient",
|
|
2450
2495
|
type: "HttpClient",
|
|
2451
|
-
scope:
|
|
2496
|
+
scope: import_ts_morph5.Scope.Private,
|
|
2452
2497
|
isReadonly: true,
|
|
2453
2498
|
initializer: "inject(HttpClient)"
|
|
2454
2499
|
});
|
|
2455
2500
|
serviceClass.addProperty({
|
|
2456
2501
|
name: "basePath",
|
|
2457
2502
|
type: "string",
|
|
2458
|
-
scope:
|
|
2503
|
+
scope: import_ts_morph5.Scope.Private,
|
|
2459
2504
|
isReadonly: true,
|
|
2460
2505
|
initializer: `inject(${basePathTokenName})`
|
|
2461
2506
|
});
|
|
2462
2507
|
serviceClass.addProperty({
|
|
2463
2508
|
name: "clientContextToken",
|
|
2464
2509
|
type: "HttpContextToken<string>",
|
|
2465
|
-
scope:
|
|
2510
|
+
scope: import_ts_morph5.Scope.Private,
|
|
2466
2511
|
isReadonly: true,
|
|
2467
2512
|
initializer: clientContextTokenName
|
|
2468
2513
|
});
|
|
2469
2514
|
serviceClass.addMethod({
|
|
2470
2515
|
name: "createContextWithClientId",
|
|
2471
|
-
scope:
|
|
2516
|
+
scope: import_ts_morph5.Scope.Private,
|
|
2472
2517
|
parameters: [
|
|
2473
2518
|
{
|
|
2474
2519
|
name: "existingContext",
|
|
@@ -2556,11 +2601,11 @@ function generateFromConfig(config) {
|
|
|
2556
2601
|
});
|
|
2557
2602
|
}
|
|
2558
2603
|
try {
|
|
2559
|
-
const project = new
|
|
2604
|
+
const project = new import_ts_morph6.Project({
|
|
2560
2605
|
compilerOptions: __spreadValues({
|
|
2561
2606
|
declaration: true,
|
|
2562
|
-
target:
|
|
2563
|
-
module:
|
|
2607
|
+
target: import_ts_morph6.ScriptTarget.ES2022,
|
|
2608
|
+
module: import_ts_morph6.ModuleKind.Preserve,
|
|
2564
2609
|
strict: true
|
|
2565
2610
|
}, config.compilerOptions)
|
|
2566
2611
|
});
|
package/package.json
CHANGED