@odata2ts/odata2ts 0.33.1 → 0.34.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/lib/FactoryFunctionModel.d.ts +3 -3
  3. package/lib/FactoryFunctionModel.js.map +1 -1
  4. package/lib/OptionModel.d.ts +9 -0
  5. package/lib/OptionModel.js.map +1 -1
  6. package/lib/app.js +18 -8
  7. package/lib/app.js.map +1 -1
  8. package/lib/data-model/DataModel.d.ts +12 -6
  9. package/lib/data-model/DataModel.js +10 -0
  10. package/lib/data-model/DataModel.js.map +1 -1
  11. package/lib/data-model/DataModelDigestion.js +37 -20
  12. package/lib/data-model/DataModelDigestion.js.map +1 -1
  13. package/lib/data-model/DataModelDigestionV2.js +1 -1
  14. package/lib/data-model/DataModelDigestionV2.js.map +1 -1
  15. package/lib/data-model/DataModelDigestionV4.js +1 -10
  16. package/lib/data-model/DataModelDigestionV4.js.map +1 -1
  17. package/lib/data-model/DataTypeModel.d.ts +17 -7
  18. package/lib/data-model/DataTypeModel.js.map +1 -1
  19. package/lib/data-model/NamingHelper.d.ts +1 -0
  20. package/lib/data-model/NamingHelper.js +4 -1
  21. package/lib/data-model/NamingHelper.js.map +1 -1
  22. package/lib/data-model/ServiceConfigHelper.js +2 -2
  23. package/lib/data-model/ServiceConfigHelper.js.map +1 -1
  24. package/lib/data-model/validation/NameClashValidator.d.ts +23 -0
  25. package/lib/data-model/validation/NameClashValidator.js +89 -0
  26. package/lib/data-model/validation/NameClashValidator.js.map +1 -0
  27. package/lib/data-model/validation/NameValidator.d.ts +6 -17
  28. package/lib/data-model/validation/NameValidator.js +0 -77
  29. package/lib/data-model/validation/NameValidator.js.map +1 -1
  30. package/lib/data-model/validation/NoopValidator.d.ts +12 -0
  31. package/lib/data-model/validation/NoopValidator.js +34 -0
  32. package/lib/data-model/validation/NoopValidator.js.map +1 -0
  33. package/lib/defaultConfig.js +1 -0
  34. package/lib/defaultConfig.js.map +1 -1
  35. package/lib/generator/ImportContainer.d.ts +44 -11
  36. package/lib/generator/ImportContainer.js +150 -47
  37. package/lib/generator/ImportContainer.js.map +1 -1
  38. package/lib/generator/ImportedNameValidator.d.ts +5 -0
  39. package/lib/generator/ImportedNameValidator.js +26 -0
  40. package/lib/generator/ImportedNameValidator.js.map +1 -0
  41. package/lib/generator/ModelGenerator.js +113 -72
  42. package/lib/generator/ModelGenerator.js.map +1 -1
  43. package/lib/generator/QueryObjectGenerator.js +134 -107
  44. package/lib/generator/QueryObjectGenerator.js.map +1 -1
  45. package/lib/generator/ServiceGenerator.d.ts +1 -1
  46. package/lib/generator/ServiceGenerator.js +160 -161
  47. package/lib/generator/ServiceGenerator.js.map +1 -1
  48. package/lib/generator/import/ImportObjects.d.ts +66 -0
  49. package/lib/generator/import/ImportObjects.js +83 -0
  50. package/lib/generator/import/ImportObjects.js.map +1 -0
  51. package/lib/project/FileHandler.d.ts +28 -0
  52. package/lib/project/FileHandler.js +66 -0
  53. package/lib/project/FileHandler.js.map +1 -0
  54. package/lib/project/ProjectManager.d.ts +44 -18
  55. package/lib/project/ProjectManager.js +156 -111
  56. package/lib/project/ProjectManager.js.map +1 -1
  57. package/lib/project/TsMorphHelper.d.ts +11 -0
  58. package/lib/project/TsMorphHelper.js +66 -0
  59. package/lib/project/TsMorphHelper.js.map +1 -0
  60. package/package.json +10 -8
@@ -2,76 +2,179 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ImportContainer = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const path_1 = tslib_1.__importDefault(require("path"));
6
+ const odata_core_1 = require("@odata2ts/odata-core");
7
+ const ImportObjects_1 = require("./import/ImportObjects");
8
+ const ImportedNameValidator_1 = require("./ImportedNameValidator");
9
+ /**
10
+ * Handles all the import statements for a given file.
11
+ *
12
+ * Features a renaming mechanism, so that when the import name conflicts with an existing import a new
13
+ * name is generated and returned.
14
+ *
15
+ * Map<string,string>
16
+ */
5
17
  class ImportContainer {
6
- constructor(fileNames) {
7
- this.mapping = {
8
- core: { moduleName: "@odata2ts/odata-core", isRelative: false },
9
- qobjects: { moduleName: "@odata2ts/odata-query-objects", isRelative: false },
10
- clientApi: { moduleName: "@odata2ts/http-client-api", isRelative: false },
11
- service: { moduleName: "@odata2ts/odata-service", isRelative: false },
12
- genModel: { moduleName: "", isRelative: true },
13
- genQObjects: { moduleName: "", isRelative: true },
18
+ constructor(path, fileName, dataModel, mainFileNames, bundledFileGeneration, reservedNames) {
19
+ this.path = path;
20
+ this.fileName = fileName;
21
+ this.dataModel = dataModel;
22
+ this.mainFileNames = mainFileNames;
23
+ this.bundledFileGeneration = bundledFileGeneration;
24
+ this.reservedNames = reservedNames;
25
+ // mapping of a custom defined type to a primitive type
26
+ this.customTypes = new Map();
27
+ // imports to generated artefacts
28
+ this.internalImports = new Map();
29
+ this.libs = {
30
+ core: new Map(),
31
+ qObject: new Map(),
32
+ clientApi: new Map(),
33
+ service: new Map(),
14
34
  };
15
- this.container = {
16
- core: new Set(),
17
- qobjects: new Set(),
18
- clientApi: new Set(),
19
- service: new Set(),
20
- genModel: new Set(),
21
- genQObjects: new Set(),
22
- customTypes: new Map(),
23
- };
24
- this.mapping.genModel.moduleName = fileNames.model;
25
- this.mapping.genQObjects.moduleName = fileNames.qObject;
35
+ this.importedNameValidator = new ImportedNameValidator_1.ImportedNameValidator(reservedNames);
26
36
  }
27
- addFromCore(...names) {
28
- names.forEach((n) => this.container.core.add(n));
37
+ addCoreLib(odataVersion, ...coreLibs) {
38
+ return coreLibs.map((coreLib) => {
39
+ const name = ImportObjects_1.CoreImports[coreLib] + (ImportObjects_1.VERSIONED_CORE_IMPORTS.includes(coreLib) ? odata_core_1.ODataVersions[odataVersion] : "");
40
+ const importName = this.importedNameValidator.validateName(ImportObjects_1.LIB_MODULES.core, name);
41
+ this.libs.core.set(name, importName);
42
+ return importName;
43
+ });
29
44
  }
30
45
  addFromQObject(...names) {
31
- names.forEach((n) => this.container.qobjects.add(n));
32
- }
33
- addFromClientApi(...names) {
34
- names.forEach((n) => this.container.clientApi.add(n));
46
+ return names.map((n) => {
47
+ const importName = this.importedNameValidator.validateName(ImportObjects_1.LIB_MODULES.qObject, n);
48
+ this.libs.qObject.set(n, importName);
49
+ return importName;
50
+ });
35
51
  }
36
- addFromService(...names) {
37
- names.forEach((n) => this.container.service.add(n));
52
+ addQObject(...qObjects) {
53
+ return this.addFromQObject(...qObjects.map((qObject) => ImportObjects_1.QueryObjectImports[qObject]));
38
54
  }
39
- addGeneratedModel(...names) {
40
- names.forEach((n) => this.container.genModel.add(n));
55
+ addClientApi(...clientApis) {
56
+ return clientApis.map((clientApi) => {
57
+ const name = ImportObjects_1.ClientApiImports[clientApi];
58
+ const importName = this.importedNameValidator.validateName(ImportObjects_1.LIB_MODULES.clientApi, name);
59
+ this.libs.clientApi.set(name, importName);
60
+ return importName;
61
+ });
41
62
  }
42
- addGeneratedQObject(...names) {
43
- names.forEach((n) => this.container.genQObjects.add(n));
63
+ addServiceObject(odataVersion, ...serviceObjects) {
64
+ return serviceObjects
65
+ .map((so) => {
66
+ return ImportObjects_1.ServiceImports[so] + (ImportObjects_1.VERSIONED_SERVICE_IMPORTS.includes(so) ? odata_core_1.ODataVersions[odataVersion] : "");
67
+ })
68
+ .map((so) => {
69
+ const importName = this.importedNameValidator.validateName(ImportObjects_1.LIB_MODULES.service, so);
70
+ this.libs.service.set(so, importName);
71
+ return importName;
72
+ });
44
73
  }
45
74
  addCustomType(moduleName, typeName) {
46
- let importList = this.container.customTypes.get(moduleName);
75
+ let importList = this.customTypes.get(moduleName);
47
76
  if (!importList) {
48
- importList = new Set();
49
- this.container.customTypes.set(moduleName, importList);
77
+ importList = new Map();
78
+ this.customTypes.set(moduleName, importList);
79
+ }
80
+ const importName = this.importedNameValidator.validateName(moduleName, typeName);
81
+ importList.set(typeName, importName);
82
+ return importName;
83
+ }
84
+ pathAndFile(filePath, fileName) {
85
+ return filePath ? `${filePath}/${fileName}` : fileName;
86
+ }
87
+ isDifferentFile(filePath, fileName) {
88
+ return this.pathAndFile(this.path, this.fileName) !== this.pathAndFile(filePath, fileName);
89
+ }
90
+ addGeneratedImport(folderPath, fileName, name) {
91
+ // imports are only relevant for different files
92
+ if (!this.isDifferentFile(folderPath, fileName)) {
93
+ return name;
94
+ }
95
+ const moduleName = this.pathAndFile(folderPath, fileName);
96
+ const importName = this.importedNameValidator.validateName(moduleName, name);
97
+ const imports = this.internalImports.get(moduleName) || new Map();
98
+ imports.set(name, importName);
99
+ this.internalImports.set(moduleName, imports);
100
+ return importName;
101
+ }
102
+ addGeneratedModel(fqName, name) {
103
+ if (this.bundledFileGeneration) {
104
+ return this.addGeneratedImport("", this.mainFileNames.model, name);
105
+ }
106
+ else {
107
+ const model = this.dataModel.getModel(fqName);
108
+ if (!model && fqName !== "") {
109
+ throw new Error(`Cannot find model by its fully qualified name: ${fqName}!`);
110
+ }
111
+ const folderPath = model ? model.folderPath : "";
112
+ const modelName = model ? model.modelName : this.mainFileNames.model;
113
+ return this.addGeneratedImport(folderPath, modelName, name);
114
+ }
115
+ }
116
+ addGeneratedQObject(fqName, name) {
117
+ if (this.bundledFileGeneration) {
118
+ return this.addGeneratedImport("", this.mainFileNames.qObject, name);
119
+ }
120
+ else {
121
+ const model = this.dataModel.getModel(fqName);
122
+ if (!model && fqName !== "") {
123
+ throw new Error(`Cannot find q-object by its fully qualified name: ${fqName}!`);
124
+ }
125
+ const folderPath = model ? model.folderPath : "";
126
+ const qName = model ? model.qName : this.mainFileNames.qObject;
127
+ return this.addGeneratedImport(folderPath, qName, name);
128
+ }
129
+ }
130
+ addGeneratedService(fqName, name) {
131
+ if (this.bundledFileGeneration) {
132
+ return this.addGeneratedImport("", this.mainFileNames.service, name);
133
+ }
134
+ else {
135
+ const model = this.dataModel.getModel(fqName);
136
+ return this.addGeneratedImport(model.folderPath, model.serviceName, name);
50
137
  }
51
- importList.add(typeName);
52
138
  }
53
139
  getImportDeclarations(fromSubPath = false) {
54
- const _a = this.container, { customTypes } = _a, standardImports = tslib_1.__rest(_a, ["customTypes"]);
55
140
  return [
56
- ...[...customTypes.keys()]
57
- .filter((key) => { var _a; return !!((_a = customTypes.get(key)) === null || _a === void 0 ? void 0 : _a.size); })
58
- .map((key) => {
141
+ ...Object.entries(this.libs)
142
+ .filter(([_, values]) => !!values.size)
143
+ .map(([moduleName, toImport]) => {
59
144
  return {
60
- namedImports: [...customTypes.get(key)],
61
- moduleSpecifier: key,
145
+ namedImports: this.getNamedImports(toImport),
146
+ moduleSpecifier: ImportObjects_1.LIB_MODULES[moduleName],
62
147
  };
63
148
  }),
64
- ...Object.entries(standardImports)
65
- .filter(([_, values]) => !!values.size)
66
- .map(([key, values]) => {
67
- const mapping = this.mapping[key];
149
+ ...[...this.customTypes.keys()]
150
+ .filter((moduleName) => { var _a; return !!((_a = this.customTypes.get(moduleName)) === null || _a === void 0 ? void 0 : _a.size); })
151
+ .map((moduleName) => {
152
+ const toImport = this.customTypes.get(moduleName);
68
153
  return {
69
- namedImports: [...values],
70
- moduleSpecifier: `${mapping.isRelative ? `${fromSubPath ? ".." : "."}/` : ""}${mapping.moduleName}`,
154
+ namedImports: this.getNamedImports(toImport),
155
+ moduleSpecifier: moduleName,
156
+ };
157
+ }),
158
+ ...[...this.internalImports.entries()]
159
+ .filter(([_, toImport]) => toImport.size > 0)
160
+ .map(([key, toImport]) => {
161
+ return {
162
+ namedImports: this.getNamedImports(toImport),
163
+ moduleSpecifier: this.getModuleSpecifier(key),
71
164
  };
72
165
  }),
73
166
  ];
74
167
  }
168
+ getNamedImports(toImport) {
169
+ return [...toImport.entries()].map(([name, alias]) => ({
170
+ name,
171
+ alias: alias !== name ? alias : undefined,
172
+ }));
173
+ }
174
+ getModuleSpecifier(filePath) {
175
+ const relativePath = path_1.default.relative(this.path, filePath).replaceAll(path_1.default.sep, "/");
176
+ return !relativePath.startsWith(".") ? "./" + relativePath : relativePath;
177
+ }
75
178
  }
76
179
  exports.ImportContainer = ImportContainer;
77
180
  //# sourceMappingURL=ImportContainer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImportContainer.js","sourceRoot":"","sources":["../../src/generator/ImportContainer.ts"],"names":[],"mappings":"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","sourcesContent":["import { ImportDeclarationStructure } from \"ts-morph\";\r\n\r\nimport { ProjectFiles } from \"../data-model/DataModel\";\r\n\r\ntype ImportContainerType = {\r\n core: Set<string>;\r\n qobjects: Set<string>;\r\n clientApi: Set<string>;\r\n service: Set<string>;\r\n genModel: Set<string>;\r\n genQObjects: Set<string>;\r\n customTypes: Map<string, Set<string>>;\r\n};\r\n\r\nexport class ImportContainer {\r\n private mapping: {\r\n [K in keyof ImportContainerType as string]: { moduleName: string; isRelative: boolean; addName?: boolean };\r\n } = {\r\n core: { moduleName: \"@odata2ts/odata-core\", isRelative: false },\r\n qobjects: { moduleName: \"@odata2ts/odata-query-objects\", isRelative: false },\r\n clientApi: { moduleName: \"@odata2ts/http-client-api\", isRelative: false },\r\n service: { moduleName: \"@odata2ts/odata-service\", isRelative: false },\r\n genModel: { moduleName: \"\", isRelative: true },\r\n genQObjects: { moduleName: \"\", isRelative: true },\r\n };\r\n\r\n private container: ImportContainerType = {\r\n core: new Set(),\r\n qobjects: new Set(),\r\n clientApi: new Set(),\r\n service: new Set(),\r\n genModel: new Set(),\r\n genQObjects: new Set(),\r\n customTypes: new Map(),\r\n };\r\n\r\n constructor(fileNames: ProjectFiles) {\r\n this.mapping.genModel.moduleName = fileNames.model;\r\n this.mapping.genQObjects.moduleName = fileNames.qObject;\r\n }\r\n\r\n public addFromCore(...names: Array<string>) {\r\n names.forEach((n) => this.container.core.add(n));\r\n }\r\n\r\n public addFromQObject(...names: Array<string>) {\r\n names.forEach((n) => this.container.qobjects.add(n));\r\n }\r\n\r\n public addFromClientApi(...names: Array<string>) {\r\n names.forEach((n) => this.container.clientApi.add(n));\r\n }\r\n\r\n public addFromService(...names: Array<string>) {\r\n names.forEach((n) => this.container.service.add(n));\r\n }\r\n\r\n public addGeneratedModel(...names: Array<string>) {\r\n names.forEach((n) => this.container.genModel.add(n));\r\n }\r\n\r\n public addGeneratedQObject(...names: Array<string>) {\r\n names.forEach((n) => this.container.genQObjects.add(n));\r\n }\r\n\r\n public addCustomType(moduleName: string, typeName: string) {\r\n let importList = this.container.customTypes.get(moduleName);\r\n if (!importList) {\r\n importList = new Set();\r\n this.container.customTypes.set(moduleName, importList);\r\n }\r\n importList.add(typeName);\r\n }\r\n\r\n public getImportDeclarations(fromSubPath: boolean = false): Array<ImportDeclarationStructure> {\r\n const { customTypes, ...standardImports } = this.container;\r\n\r\n return [\r\n ...[...customTypes.keys()]\r\n .filter((key) => !!customTypes.get(key)?.size)\r\n .map((key) => {\r\n return {\r\n namedImports: [...customTypes.get(key)!],\r\n moduleSpecifier: key,\r\n } as ImportDeclarationStructure;\r\n }),\r\n ...Object.entries(standardImports)\r\n .filter(([_, values]) => !!values.size)\r\n .map(([key, values]) => {\r\n const mapping = this.mapping[key];\r\n return {\r\n namedImports: [...values],\r\n moduleSpecifier: `${mapping.isRelative ? `${fromSubPath ? \"..\" : \".\"}/` : \"\"}${mapping.moduleName}`,\r\n } as ImportDeclarationStructure;\r\n }),\r\n ];\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ImportContainer.js","sourceRoot":"","sources":["../../src/generator/ImportContainer.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"path\";\r\n\r\nimport { ODataVersions } from \"@odata2ts/odata-core\";\r\nimport { ImportDeclarationStructure } from \"ts-morph\";\r\n\r\nimport { DataModel } from \"../data-model/DataModel\";\r\nimport { ComplexType, OperationType } from \"../data-model/DataTypeModel\";\r\nimport {\r\n ClientApiImports,\r\n CoreImports,\r\n LIB_MODULES,\r\n QueryObjectImports,\r\n ServiceImports,\r\n VERSIONED_CORE_IMPORTS,\r\n VERSIONED_SERVICE_IMPORTS,\r\n} from \"./import/ImportObjects\";\r\nimport { ImportedNameValidator } from \"./ImportedNameValidator\";\r\n\r\ntype ImportContainerType = Record<keyof typeof LIB_MODULES, Map<string, string>>;\r\n\r\n/**\r\n * Handles all the import statements for a given file.\r\n *\r\n * Features a renaming mechanism, so that when the import name conflicts with an existing import a new\r\n * name is generated and returned.\r\n *\r\n * Map<string,string>\r\n */\r\nexport class ImportContainer {\r\n private readonly importedNameValidator: ImportedNameValidator;\r\n // mapping of a custom defined type to a primitive type\r\n private customTypes = new Map<string, Map<string, string>>();\r\n // imports to generated artefacts\r\n private internalImports = new Map<string, Map<string, string>>();\r\n\r\n private libs: ImportContainerType = {\r\n core: new Map(),\r\n qObject: new Map(),\r\n clientApi: new Map(),\r\n service: new Map(),\r\n };\r\n\r\n constructor(\r\n protected path: string,\r\n protected fileName: string,\r\n protected dataModel: DataModel,\r\n protected mainFileNames: { model: string; qObject: string; service: string },\r\n protected readonly bundledFileGeneration: boolean,\r\n protected reservedNames: Array<string> | undefined\r\n ) {\r\n this.importedNameValidator = new ImportedNameValidator(reservedNames);\r\n }\r\n\r\n public addCoreLib(odataVersion: ODataVersions, ...coreLibs: Array<CoreImports>) {\r\n return coreLibs.map((coreLib) => {\r\n const name = CoreImports[coreLib] + (VERSIONED_CORE_IMPORTS.includes(coreLib) ? ODataVersions[odataVersion] : \"\");\r\n const importName = this.importedNameValidator.validateName(LIB_MODULES.core, name);\r\n this.libs.core.set(name, importName);\r\n return importName;\r\n });\r\n }\r\n\r\n public addFromQObject(...names: Array<string>) {\r\n return names.map((n) => {\r\n const importName = this.importedNameValidator.validateName(LIB_MODULES.qObject, n);\r\n this.libs.qObject.set(n, importName);\r\n return importName;\r\n });\r\n }\r\n\r\n public addQObject(...qObjects: Array<QueryObjectImports>) {\r\n return this.addFromQObject(...qObjects.map((qObject) => QueryObjectImports[qObject]));\r\n }\r\n\r\n public addClientApi(...clientApis: Array<ClientApiImports>) {\r\n return clientApis.map((clientApi) => {\r\n const name = ClientApiImports[clientApi];\r\n const importName = this.importedNameValidator.validateName(LIB_MODULES.clientApi, name);\r\n this.libs.clientApi.set(name, importName);\r\n return importName;\r\n });\r\n }\r\n\r\n public addServiceObject(odataVersion: ODataVersions, ...serviceObjects: Array<ServiceImports>) {\r\n return serviceObjects\r\n .map((so) => {\r\n return ServiceImports[so] + (VERSIONED_SERVICE_IMPORTS.includes(so) ? ODataVersions[odataVersion] : \"\");\r\n })\r\n .map((so) => {\r\n const importName = this.importedNameValidator.validateName(LIB_MODULES.service, so);\r\n this.libs.service.set(so, importName);\r\n return importName;\r\n });\r\n }\r\n\r\n public addCustomType(moduleName: string, typeName: string) {\r\n let importList = this.customTypes.get(moduleName);\r\n if (!importList) {\r\n importList = new Map();\r\n this.customTypes.set(moduleName, importList);\r\n }\r\n\r\n const importName = this.importedNameValidator.validateName(moduleName, typeName);\r\n importList.set(typeName, importName);\r\n return importName;\r\n }\r\n\r\n private pathAndFile(filePath: string, fileName: string) {\r\n return filePath ? `${filePath}/${fileName}` : fileName;\r\n }\r\n\r\n private isDifferentFile(filePath: string, fileName: string) {\r\n return this.pathAndFile(this.path, this.fileName) !== this.pathAndFile(filePath, fileName);\r\n }\r\n\r\n private addGeneratedImport(folderPath: string, fileName: string, name: string): string {\r\n // imports are only relevant for different files\r\n if (!this.isDifferentFile(folderPath, fileName)) {\r\n return name;\r\n }\r\n\r\n const moduleName = this.pathAndFile(folderPath, fileName);\r\n const importName = this.importedNameValidator.validateName(moduleName, name);\r\n\r\n const imports = this.internalImports.get(moduleName) || new Map<string, string>();\r\n imports.set(name, importName);\r\n this.internalImports.set(moduleName, imports);\r\n\r\n return importName;\r\n }\r\n\r\n public addGeneratedModel(fqName: string, name: string): string {\r\n if (this.bundledFileGeneration) {\r\n return this.addGeneratedImport(\"\", this.mainFileNames.model, name);\r\n } else {\r\n const model = this.dataModel.getModel(fqName) as ComplexType | undefined;\r\n if (!model && fqName !== \"\") {\r\n throw new Error(`Cannot find model by its fully qualified name: ${fqName}!`);\r\n }\r\n\r\n const folderPath = model ? model.folderPath : \"\";\r\n const modelName = model ? model.modelName : this.mainFileNames.model;\r\n return this.addGeneratedImport(folderPath, modelName, name);\r\n }\r\n }\r\n\r\n public addGeneratedQObject(fqName: string, name: string) {\r\n if (this.bundledFileGeneration) {\r\n return this.addGeneratedImport(\"\", this.mainFileNames.qObject, name);\r\n } else {\r\n const model = this.dataModel.getModel(fqName) as ComplexType | undefined;\r\n if (!model && fqName !== \"\") {\r\n throw new Error(`Cannot find q-object by its fully qualified name: ${fqName}!`);\r\n }\r\n\r\n const folderPath = model ? model.folderPath : \"\";\r\n const qName = model ? model.qName : this.mainFileNames!.qObject;\r\n return this.addGeneratedImport(folderPath, qName, name);\r\n }\r\n }\r\n\r\n public addGeneratedService(fqName: string, name: string) {\r\n if (this.bundledFileGeneration) {\r\n return this.addGeneratedImport(\"\", this.mainFileNames.service, name);\r\n } else {\r\n const model = this.dataModel.getModel(fqName) as ComplexType;\r\n return this.addGeneratedImport(model.folderPath, model.serviceName, name);\r\n }\r\n }\r\n\r\n public getImportDeclarations(fromSubPath: boolean = false): Array<ImportDeclarationStructure> {\r\n return [\r\n ...Object.entries(this.libs)\r\n .filter(([_, values]) => !!values.size)\r\n .map(([moduleName, toImport]) => {\r\n return {\r\n namedImports: this.getNamedImports(toImport),\r\n moduleSpecifier: LIB_MODULES[moduleName as keyof typeof LIB_MODULES],\r\n } as ImportDeclarationStructure;\r\n }),\r\n ...[...this.customTypes.keys()]\r\n .filter((moduleName) => !!this.customTypes.get(moduleName)?.size)\r\n .map((moduleName) => {\r\n const toImport = this.customTypes.get(moduleName)!;\r\n return {\r\n namedImports: this.getNamedImports(toImport),\r\n moduleSpecifier: moduleName,\r\n } as ImportDeclarationStructure;\r\n }),\r\n ...[...this.internalImports.entries()]\r\n .filter(([_, toImport]) => toImport.size > 0)\r\n .map(([key, toImport]) => {\r\n return {\r\n namedImports: this.getNamedImports(toImport),\r\n moduleSpecifier: this.getModuleSpecifier(key),\r\n } as ImportDeclarationStructure;\r\n }),\r\n ];\r\n }\r\n\r\n private getNamedImports(toImport: Map<string, string>): Array<{ name: string; alias: string | undefined }> {\r\n return [...toImport.entries()].map(([name, alias]) => ({\r\n name,\r\n alias: alias !== name ? alias : undefined,\r\n }));\r\n }\r\n\r\n private getModuleSpecifier(filePath: string): string {\r\n const relativePath = path.relative(this.path, filePath).replaceAll(path.sep, \"/\");\r\n return !relativePath.startsWith(\".\") ? \"./\" + relativePath : relativePath;\r\n }\r\n}\r\n"]}
@@ -0,0 +1,5 @@
1
+ export declare class ImportedNameValidator {
2
+ private importedNames;
3
+ constructor(reservedNames?: Array<string> | undefined);
4
+ validateName(qualifier: string, name: string): string;
5
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImportedNameValidator = void 0;
4
+ class ImportedNameValidator {
5
+ constructor(reservedNames) {
6
+ this.importedNames = new Map();
7
+ reservedNames === null || reservedNames === void 0 ? void 0 : reservedNames.forEach((rn) => {
8
+ this.importedNames.set(rn, { ["_"]: rn });
9
+ });
10
+ }
11
+ validateName(qualifier, name) {
12
+ var _a;
13
+ const qualifiers = (_a = this.importedNames.get(name)) !== null && _a !== void 0 ? _a : {};
14
+ const hitName = qualifiers[qualifier];
15
+ if (hitName) {
16
+ return hitName;
17
+ }
18
+ const qualifiersSize = Object.keys(qualifiers).length;
19
+ const result = qualifiersSize ? `${name}_${qualifiersSize}` : name;
20
+ qualifiers[qualifier] = result;
21
+ this.importedNames.set(name, qualifiers);
22
+ return result;
23
+ }
24
+ }
25
+ exports.ImportedNameValidator = ImportedNameValidator;
26
+ //# sourceMappingURL=ImportedNameValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImportedNameValidator.js","sourceRoot":"","sources":["../../src/generator/ImportedNameValidator.ts"],"names":[],"mappings":";;;AAAA,MAAa,qBAAqB;IAGhC,YAAmB,aAAyC;QAFpD,kBAAa,GAAG,IAAI,GAAG,EAAkC,CAAC;QAGhE,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;YAC5B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,YAAY,CAAC,SAAiB,EAAE,IAAY;;QACjD,MAAM,UAAU,GAAG,MAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAI,EAAE,CAAC;QACtD,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QAEtC,IAAI,OAAO,EAAE;YACX,OAAO,OAAO,CAAC;SAChB;QAED,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC;QACtD,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAEnE,UAAU,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC;QAC/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAEzC,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAzBD,sDAyBC","sourcesContent":["export class ImportedNameValidator {\n private importedNames = new Map<string, Record<string, string>>();\n\n public constructor(reservedNames?: Array<string> | undefined) {\n reservedNames?.forEach((rn) => {\n this.importedNames.set(rn, { [\"_\"]: rn });\n });\n }\n\n public validateName(qualifier: string, name: string): string {\n const qualifiers = this.importedNames.get(name) ?? {};\n const hitName = qualifiers[qualifier];\n\n if (hitName) {\n return hitName;\n }\n\n const qualifiersSize = Object.keys(qualifiers).length;\n const result = qualifiersSize ? `${name}_${qualifiersSize}` : name;\n\n qualifiers[qualifier] = result;\n this.importedNames.set(name, qualifiers);\n\n return result;\n }\n}\n"]}
@@ -1,75 +1,113 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateModels = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const ts_morph_1 = require("ts-morph");
5
- const ImportContainer_1 = require("./ImportContainer");
6
- const generateModels = (dataModel, sourceFile, version, options, namingHelper) => {
7
- const generator = new ModelGenerator(dataModel, sourceFile, version, options, namingHelper);
6
+ const ImportObjects_1 = require("./import/ImportObjects");
7
+ const generateModels = (project, dataModel, version, options, namingHelper) => {
8
+ const generator = new ModelGenerator(project, dataModel, version, options, namingHelper);
8
9
  return generator.generate();
9
10
  };
10
11
  exports.generateModels = generateModels;
11
- const DEFERRED_CONTENT = "DeferredContent";
12
12
  class ModelGenerator {
13
- constructor(dataModel, sourceFile, version, options, namingHelper) {
13
+ constructor(project, dataModel, version, options, namingHelper) {
14
+ this.project = project;
14
15
  this.dataModel = dataModel;
15
- this.sourceFile = sourceFile;
16
16
  this.version = version;
17
17
  this.options = options;
18
18
  this.namingHelper = namingHelper;
19
19
  }
20
20
  generate() {
21
- this.importContainer = new ImportContainer_1.ImportContainer(this.namingHelper.getFileNames());
22
- this.generateEnums();
23
- this.generateModels();
24
- if (!this.options.skipOperations) {
25
- this.generateUnboundOperationParams();
26
- }
21
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
22
+ this.project.initModels();
23
+ const promises = [
24
+ ...this.generateEnums(),
25
+ ...this.generateEntityTypeModels(),
26
+ ...this.generateComplexTypeModels(),
27
+ ];
28
+ if (!this.options.skipOperations) {
29
+ promises.push(this.generateUnboundOperationParams());
30
+ }
31
+ yield Promise.all(promises);
32
+ return this.project.finalizeModels();
33
+ });
27
34
  }
28
35
  generateEnums() {
29
- this.dataModel.getEnums().forEach((et) => {
30
- this.sourceFile.addEnum({
31
- name: et.name,
36
+ return this.dataModel.getEnums().map((et) => {
37
+ const file = this.project.createOrGetModelFile(et.folderPath, et.modelName);
38
+ file.getFile().addEnum({
39
+ name: et.modelName,
32
40
  isExported: true,
33
41
  members: et.members.map((mem) => ({ name: mem, initializer: `"${mem}"` })),
34
42
  });
43
+ return this.project.finalizeFile(file);
35
44
  });
36
45
  }
37
- generateModels() {
38
- this.dataModel.getEntityTypes().forEach((model) => {
39
- this.generateModel(model);
46
+ generateEntityTypeModels() {
47
+ return this.dataModel.getEntityTypes().map((model) => {
48
+ const file = this.project.createOrGetModelFile(model.folderPath, model.modelName, [
49
+ model.modelName,
50
+ model.id.modelName,
51
+ model.editableName,
52
+ ]);
53
+ // query model
54
+ this.generateModel(file, model);
55
+ // key model
40
56
  if (!this.options.skipIdModels && model.generateId) {
41
- this.generateIdModel(model);
57
+ this.generateIdModel(file, model);
42
58
  }
43
- if (!this.options.skipEditableModels && !model.abstract) {
44
- this.generateEditableModel(model);
59
+ // editable model
60
+ if (!this.options.skipEditableModels) {
61
+ this.generateEditableModel(file, model);
45
62
  }
63
+ // param models for bound operations
46
64
  if (!this.options.skipOperations) {
47
- this.generateBoundOperationParams(model.fqName);
65
+ [
66
+ ...this.dataModel.getEntityTypeOperations(model.fqName),
67
+ ...this.dataModel.getEntitySetOperations(model.fqName),
68
+ ].forEach((operation) => {
69
+ this.generateOperationParams(file, operation);
70
+ });
48
71
  }
72
+ return this.project.finalizeFile(file);
49
73
  });
50
- this.dataModel.getComplexTypes().forEach((model) => {
51
- this.generateModel(model);
52
- if (!this.options.skipEditableModels && !model.abstract) {
53
- this.generateEditableModel(model);
74
+ }
75
+ generateComplexTypeModels() {
76
+ return this.dataModel.getComplexTypes().map((model) => {
77
+ const file = this.project.createOrGetModelFile(model.folderPath, model.modelName, [
78
+ model.modelName,
79
+ model.editableName,
80
+ ]);
81
+ // query model
82
+ this.generateModel(file, model);
83
+ // editable model
84
+ if (!this.options.skipEditableModels) {
85
+ this.generateEditableModel(file, model);
54
86
  }
87
+ return this.project.finalizeFile(file);
55
88
  });
56
- this.sourceFile.addImportDeclarations(this.importContainer.getImportDeclarations());
57
89
  }
58
- generateModel(model) {
59
- this.sourceFile.addInterface({
60
- name: model.name,
90
+ generateModel(file, model) {
91
+ const imports = file.getImports();
92
+ let extendsClause = undefined;
93
+ if (model.finalBaseClass) {
94
+ const modelName = imports.addGeneratedModel(model.baseClasses[0], this.namingHelper.getModelName(model.finalBaseClass));
95
+ extendsClause = [modelName];
96
+ }
97
+ file.getFile().addInterface({
98
+ name: model.modelName,
61
99
  isExported: true,
62
100
  properties: model.props.map((p) => {
63
101
  const isEntity = p.dataType == "ModelType" /* DataTypes.ModelType */;
64
102
  return {
65
103
  name: p.name,
66
- type: this.getPropType(p),
104
+ type: this.getPropType(file.getImports(), p),
67
105
  // props for entities or entity collections are not added in V4 if not explicitly expanded
68
106
  hasQuestionToken: this.dataModel.isV4() && isEntity,
69
107
  docs: this.options.skipComments ? undefined : [this.generatePropDoc(p, model)],
70
108
  };
71
109
  }),
72
- extends: model.finalBaseClass ? [this.namingHelper.getModelName(model.finalBaseClass)] : undefined,
110
+ extends: extendsClause,
73
111
  });
74
112
  }
75
113
  generatePropDoc(prop, model) {
@@ -98,21 +136,24 @@ class ModelGenerator {
98
136
  attributeTable.map((row) => `| ${row[0]} | \`${row[1]}\` |`).join("\n");
99
137
  return { kind: ts_morph_1.StructureKind.JSDoc, description };
100
138
  }
101
- getPropType(prop) {
102
- const isEntity = prop.dataType == "ModelType" /* DataTypes.ModelType */;
139
+ getPropType(imports, prop) {
103
140
  // V2 entity special: deferred content
104
141
  let suffix = "";
105
- if (isEntity && this.dataModel.isV2()) {
106
- this.importContainer.addFromCore(DEFERRED_CONTENT);
107
- suffix = ` | ${DEFERRED_CONTENT}`;
142
+ if (this.dataModel.isV2() && prop.dataType == "ModelType" /* DataTypes.ModelType */) {
143
+ const [defContent] = imports.addCoreLib(this.version, ImportObjects_1.CoreImports.DeferredContent);
144
+ suffix = ` | ${defContent}`;
145
+ }
146
+ let typeName;
147
+ if (prop.dataType === "PrimitiveType" /* DataTypes.PrimitiveType */) {
148
+ // custom types which require type imports => possible via converters
149
+ typeName = prop.typeModule ? imports.addCustomType(prop.typeModule, prop.type) : prop.type;
108
150
  }
109
- // custom types which require type imports => possible via converters
110
- else if (prop.typeModule) {
111
- this.importContainer.addCustomType(prop.typeModule, prop.type);
151
+ else {
152
+ typeName = imports.addGeneratedModel(prop.fqType, prop.type);
112
153
  }
113
154
  // Collections
114
155
  if (prop.isCollection) {
115
- const type = `Array<${prop.type}>`;
156
+ const type = `Array<${typeName}>`;
116
157
  if (this.dataModel.isV2() && this.options.v2ModelsWithExtraResultsWrapping) {
117
158
  return `{ results: ${type} }` + suffix;
118
159
  }
@@ -121,19 +162,21 @@ class ModelGenerator {
121
162
  }
122
163
  }
123
164
  // primitive, enum & complex types
124
- return prop.type + (prop.required ? "" : " | null") + suffix;
165
+ return typeName + (prop.required ? "" : " | null") + suffix;
125
166
  }
126
- generateIdModel(model) {
167
+ generateIdModel(file, model) {
127
168
  const singleType = model.keys.length === 1 ? `${model.keys[0].type} | ` : "";
128
- const keyTypes = model.keys.map((keyProp) => `${keyProp.name}: ${this.getPropType(keyProp)}`).join(",");
169
+ const keyTypes = model.keys
170
+ .map((keyProp) => `${keyProp.name}: ${this.getPropType(file.getImports(), keyProp)}`)
171
+ .join(",");
129
172
  const type = `${singleType}{${keyTypes}}`;
130
- this.sourceFile.addTypeAlias({
131
- name: model.idModelName,
173
+ file.getFile().addTypeAlias({
174
+ name: model.id.modelName,
132
175
  isExported: true,
133
176
  type,
134
177
  });
135
178
  }
136
- generateEditableModel(model) {
179
+ generateEditableModel(file, model) {
137
180
  const entityTypes = ["ModelType" /* DataTypes.ModelType */, "ComplexType" /* DataTypes.ComplexType */];
138
181
  const allProps = [...model.baseProps, ...model.props].filter((p) => !p.managed);
139
182
  const requiredProps = allProps
@@ -146,10 +189,10 @@ class ModelGenerator {
146
189
  .join(" | ");
147
190
  const complexProps = allProps.filter((p) => p.dataType === "ComplexType" /* DataTypes.ComplexType */);
148
191
  const extendsClause = [
149
- requiredProps ? `Pick<${model.name}, ${requiredProps}>` : null,
150
- optionalProps ? `Partial<Pick<${model.name}, ${optionalProps}>>` : null,
192
+ requiredProps ? `Pick<${model.modelName}, ${requiredProps}>` : null,
193
+ optionalProps ? `Partial<Pick<${model.modelName}, ${optionalProps}>>` : null,
151
194
  ].filter((e) => !!e);
152
- this.sourceFile.addInterface({
195
+ file.getFile().addInterface({
153
196
  name: model.editableName,
154
197
  isExported: true,
155
198
  extends: extendsClause,
@@ -158,7 +201,7 @@ class ModelGenerator {
158
201
  : complexProps.map((p) => {
159
202
  return {
160
203
  name: p.name,
161
- type: this.getEditablePropType(p),
204
+ type: this.getEditablePropType(file.getImports(), p),
162
205
  // optional props don't need to be specified in editable model
163
206
  // also, entities would require deep insert func => we make it optional for now
164
207
  hasQuestionToken: !p.required || p.dataType === "ModelType" /* DataTypes.ModelType */,
@@ -166,43 +209,41 @@ class ModelGenerator {
166
209
  }),
167
210
  });
168
211
  }
169
- getEditablePropType(prop) {
170
- const type = prop.dataType === "ModelType" /* DataTypes.ModelType */
171
- ? this.dataModel.getEntityType(prop.fqType).editableName
172
- : prop.dataType === "ComplexType" /* DataTypes.ComplexType */
173
- ? this.dataModel.getComplexType(prop.fqType).editableName
174
- : prop.type;
212
+ getEditablePropType(imports, prop) {
213
+ const isModelType = ["ModelType" /* DataTypes.ModelType */, "ComplexType" /* DataTypes.ComplexType */].includes(prop.dataType);
214
+ let editableType = prop.type;
215
+ if (isModelType) {
216
+ const editName = this.dataModel.getComplexType(prop.fqType).editableName;
217
+ editableType = imports.addGeneratedModel(prop.fqType, editName);
218
+ }
175
219
  // Collections
176
220
  if (prop.isCollection) {
177
- return `Array<${type}>`;
221
+ return `Array<${editableType}>`;
178
222
  }
179
223
  // primitive, enum & complex types
180
- return type + (prop.required ? "" : " | null");
224
+ return editableType + (prop.required ? "" : " | null");
181
225
  }
182
226
  generateUnboundOperationParams() {
183
- this.dataModel.getUnboundOperationTypes().forEach((operation) => {
184
- this.generateOperationParams(operation);
185
- });
186
- }
187
- generateBoundOperationParams(entityName) {
188
- [
189
- ...this.dataModel.getEntityTypeOperations(entityName),
190
- ...this.dataModel.getEntitySetOperations(entityName),
191
- ].forEach((operation) => {
192
- this.generateOperationParams(operation);
227
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
228
+ const unboundOps = this.dataModel.getUnboundOperationTypes();
229
+ const reservedNames = unboundOps.map((op) => op.paramsModelName);
230
+ const file = this.project.createOrGetMainModelFile(reservedNames);
231
+ unboundOps.forEach((operation) => {
232
+ this.generateOperationParams(file, operation);
233
+ });
193
234
  });
194
235
  }
195
- generateOperationParams(operation) {
236
+ generateOperationParams(file, operation) {
196
237
  if (!operation.parameters.length) {
197
238
  return;
198
239
  }
199
- this.sourceFile.addInterface({
240
+ file.getFile().addInterface({
200
241
  name: operation.paramsModelName,
201
242
  isExported: true,
202
243
  properties: operation.parameters.map((p) => {
203
244
  return {
204
245
  name: p.name,
205
- type: this.getPropType(p),
246
+ type: this.getPropType(file.getImports(), p),
206
247
  hasQuestionToken: !p.required,
207
248
  };
208
249
  }),