@odata2ts/odata2ts 0.18.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 (97) hide show
  1. package/CHANGELOG.md +601 -0
  2. package/LICENSE +21 -0
  3. package/README.md +129 -0
  4. package/lib/FactoryFunctionModel.d.ts +13 -0
  5. package/lib/FactoryFunctionModel.js +3 -0
  6. package/lib/FactoryFunctionModel.js.map +1 -0
  7. package/lib/NamingModel.d.ts +191 -0
  8. package/lib/NamingModel.js +12 -0
  9. package/lib/NamingModel.js.map +1 -0
  10. package/lib/OptionModel.d.ts +208 -0
  11. package/lib/OptionModel.js +24 -0
  12. package/lib/OptionModel.js.map +1 -0
  13. package/lib/app.d.ts +8 -0
  14. package/lib/app.js +61 -0
  15. package/lib/app.js.map +1 -0
  16. package/lib/cli.d.ts +3 -0
  17. package/lib/cli.js +154 -0
  18. package/lib/cli.js.map +1 -0
  19. package/lib/data-model/DataModel.d.ts +68 -0
  20. package/lib/data-model/DataModel.js +114 -0
  21. package/lib/data-model/DataModel.js.map +1 -0
  22. package/lib/data-model/DataModelDigestion.d.ts +43 -0
  23. package/lib/data-model/DataModelDigestion.js +224 -0
  24. package/lib/data-model/DataModelDigestion.js.map +1 -0
  25. package/lib/data-model/DataModelDigestionV2.d.ts +10 -0
  26. package/lib/data-model/DataModelDigestionV2.js +201 -0
  27. package/lib/data-model/DataModelDigestionV2.js.map +1 -0
  28. package/lib/data-model/DataModelDigestionV4.d.ts +3 -0
  29. package/lib/data-model/DataModelDigestionV4.js +196 -0
  30. package/lib/data-model/DataModelDigestionV4.js.map +1 -0
  31. package/lib/data-model/DataTypeModel.d.ts +102 -0
  32. package/lib/data-model/DataTypeModel.js +9 -0
  33. package/lib/data-model/DataTypeModel.js.map +1 -0
  34. package/lib/data-model/NamingHelper.d.ts +57 -0
  35. package/lib/data-model/NamingHelper.js +225 -0
  36. package/lib/data-model/NamingHelper.js.map +1 -0
  37. package/lib/data-model/ServiceConfigHelper.d.ts +13 -0
  38. package/lib/data-model/ServiceConfigHelper.js +63 -0
  39. package/lib/data-model/ServiceConfigHelper.js.map +1 -0
  40. package/lib/data-model/edmx/ODataEdmxModelBase.d.ts +79 -0
  41. package/lib/data-model/edmx/ODataEdmxModelBase.js +3 -0
  42. package/lib/data-model/edmx/ODataEdmxModelBase.js.map +1 -0
  43. package/lib/data-model/edmx/ODataEdmxModelV3.d.ts +63 -0
  44. package/lib/data-model/edmx/ODataEdmxModelV3.js +3 -0
  45. package/lib/data-model/edmx/ODataEdmxModelV3.js.map +1 -0
  46. package/lib/data-model/edmx/ODataEdmxModelV4.d.ts +67 -0
  47. package/lib/data-model/edmx/ODataEdmxModelV4.js +3 -0
  48. package/lib/data-model/edmx/ODataEdmxModelV4.js.map +1 -0
  49. package/lib/defaultConfig.d.ts +9 -0
  50. package/lib/defaultConfig.js +176 -0
  51. package/lib/defaultConfig.js.map +1 -0
  52. package/lib/evaluateConfig.d.ts +25 -0
  53. package/lib/evaluateConfig.js +78 -0
  54. package/lib/evaluateConfig.js.map +1 -0
  55. package/lib/generator/ImportContainer.d.ts +16 -0
  56. package/lib/generator/ImportContainer.js +92 -0
  57. package/lib/generator/ImportContainer.js.map +1 -0
  58. package/lib/generator/ModelGenerator.d.ts +2 -0
  59. package/lib/generator/ModelGenerator.js +178 -0
  60. package/lib/generator/ModelGenerator.js.map +1 -0
  61. package/lib/generator/QueryObjectGenerator.d.ts +2 -0
  62. package/lib/generator/QueryObjectGenerator.js +234 -0
  63. package/lib/generator/QueryObjectGenerator.js.map +1 -0
  64. package/lib/generator/ServiceGenerator.d.ts +5 -0
  65. package/lib/generator/ServiceGenerator.js +412 -0
  66. package/lib/generator/ServiceGenerator.js.map +1 -0
  67. package/lib/generator/index.d.ts +3 -0
  68. package/lib/generator/index.js +10 -0
  69. package/lib/generator/index.js.map +1 -0
  70. package/lib/index.d.ts +3 -0
  71. package/lib/index.js +7 -0
  72. package/lib/index.js.map +1 -0
  73. package/lib/project/ProjectManager.d.ts +30 -0
  74. package/lib/project/ProjectManager.js +177 -0
  75. package/lib/project/ProjectManager.js.map +1 -0
  76. package/lib/project/formatter/BaseFormatter.d.ts +49 -0
  77. package/lib/project/formatter/BaseFormatter.js +31 -0
  78. package/lib/project/formatter/BaseFormatter.js.map +1 -0
  79. package/lib/project/formatter/FileFormatter.d.ts +16 -0
  80. package/lib/project/formatter/FileFormatter.js +3 -0
  81. package/lib/project/formatter/FileFormatter.js.map +1 -0
  82. package/lib/project/formatter/NoopFormatter.d.ts +29 -0
  83. package/lib/project/formatter/NoopFormatter.js +43 -0
  84. package/lib/project/formatter/NoopFormatter.js.map +1 -0
  85. package/lib/project/formatter/PrettierFormatter.d.ts +46 -0
  86. package/lib/project/formatter/PrettierFormatter.js +93 -0
  87. package/lib/project/formatter/PrettierFormatter.js.map +1 -0
  88. package/lib/project/formatter/index.d.ts +2 -0
  89. package/lib/project/formatter/index.js +15 -0
  90. package/lib/project/formatter/index.js.map +1 -0
  91. package/lib/project/logger/logFilePath.d.ts +1 -0
  92. package/lib/project/logger/logFilePath.js +13 -0
  93. package/lib/project/logger/logFilePath.js.map +1 -0
  94. package/lib/run-cli.d.ts +2 -0
  95. package/lib/run-cli.js +7 -0
  96. package/lib/run-cli.js.map +1 -0
  97. package/package.json +91 -0
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateQueryObjects = void 0;
4
+ const odata_core_1 = require("@odata2ts/odata-core");
5
+ const ts_morph_1 = require("ts-morph");
6
+ const processors_1 = require("xml2js/lib/processors");
7
+ const ImportContainer_1 = require("./ImportContainer");
8
+ const generateQueryObjects = (dataModel, sourceFile, version, options, namingHelper) => {
9
+ const generator = new QueryObjectGenerator(dataModel, sourceFile, version, options, namingHelper);
10
+ return generator.generate();
11
+ };
12
+ exports.generateQueryObjects = generateQueryObjects;
13
+ class QueryObjectGenerator {
14
+ constructor(dataModel, sourceFile, version, options, namingHelper) {
15
+ this.dataModel = dataModel;
16
+ this.sourceFile = sourceFile;
17
+ this.version = version;
18
+ this.options = options;
19
+ this.namingHelper = namingHelper;
20
+ }
21
+ generate() {
22
+ const importContainer = new ImportContainer_1.ImportContainer(this.namingHelper.getFileNames());
23
+ this.generateModels(importContainer);
24
+ if (!this.options.skipOperations) {
25
+ this.generateUnboundOperations(importContainer);
26
+ }
27
+ this.sourceFile.addImportDeclarations(importContainer.getImportDeclarations(false));
28
+ }
29
+ generateModels(importContainer) {
30
+ this.dataModel.getModels().forEach((model) => {
31
+ this.generateModel(model, importContainer);
32
+ if (!this.options.skipIdModels) {
33
+ this.generateIdFunction(model, importContainer);
34
+ }
35
+ if (!this.options.skipOperations) {
36
+ this.generateBoundOperations(model.name, importContainer);
37
+ }
38
+ });
39
+ this.dataModel.getComplexTypes().forEach((model) => {
40
+ this.generateModel(model, importContainer);
41
+ });
42
+ if (this.dataModel.getModels().length || this.dataModel.getComplexTypes().length) {
43
+ importContainer.addFromQObject("QueryObject");
44
+ }
45
+ }
46
+ generateModel(model, importContainer) {
47
+ let extendsClause = "QueryObject";
48
+ if (model.baseClasses.length) {
49
+ const baseClass = model.baseClasses[0];
50
+ const baseModel = this.dataModel.getModel(baseClass) || this.dataModel.getComplexType(baseClass);
51
+ extendsClause = baseModel.qName;
52
+ }
53
+ this.sourceFile.addClass({
54
+ name: model.qName,
55
+ isExported: true,
56
+ extends: extendsClause,
57
+ properties: this.generateQueryObjectProps(model.props, importContainer),
58
+ });
59
+ this.sourceFile.addVariableStatement({
60
+ declarationKind: ts_morph_1.VariableDeclarationKind.Const,
61
+ isExported: true,
62
+ declarations: [
63
+ {
64
+ name: (0, processors_1.firstCharLowerCase)(model.qName),
65
+ initializer: `new ${model.qName}()`,
66
+ },
67
+ ],
68
+ });
69
+ }
70
+ generateQueryObjectProps(props, importContainer) {
71
+ return props.map((prop) => {
72
+ const { odataName } = prop;
73
+ const name = this.namingHelper.getQPropName(prop.name);
74
+ const isModelType = prop.dataType === "ModelType" /* ModelType */ || prop.dataType === "ComplexType" /* ComplexType */;
75
+ let qPathInit;
76
+ // factor in collections
77
+ if (prop.isCollection) {
78
+ const cType = `Q${isModelType ? "Entity" : ""}CollectionPath`;
79
+ const qObject = prop.qObject;
80
+ if (!qObject) {
81
+ throw new Error("QObject for collection is missing!");
82
+ }
83
+ qPathInit = `new ${cType}(this.withPrefix("${odataName}"), () => ${qObject})`;
84
+ importContainer.addFromQObject(cType);
85
+ if (!isModelType) {
86
+ importContainer.addFromQObject(qObject);
87
+ }
88
+ }
89
+ else {
90
+ if (isModelType) {
91
+ qPathInit = `new ${prop.qPath}(this.withPrefix("${odataName}"), () => ${prop.qObject})`;
92
+ }
93
+ else {
94
+ let converterStmt = this.generateConverterStmt(prop.converters, importContainer);
95
+ qPathInit = `new ${prop.qPath}(this.withPrefix("${odataName}")${converterStmt ? `, ${converterStmt}` : ""})`;
96
+ }
97
+ // add import for data type
98
+ importContainer.addFromQObject(prop.qPath);
99
+ }
100
+ return {
101
+ name,
102
+ scope: ts_morph_1.Scope.Public,
103
+ isReadonly: true,
104
+ initializer: qPathInit,
105
+ };
106
+ });
107
+ }
108
+ generateConverterStmt(converters, importContainer) {
109
+ if (!(converters === null || converters === void 0 ? void 0 : converters.length)) {
110
+ return;
111
+ }
112
+ converters.forEach((converter) => {
113
+ importContainer.addCustomType(converter.package, converter.converterId);
114
+ });
115
+ if (converters.length === 1) {
116
+ return converters[0].converterId;
117
+ }
118
+ else {
119
+ importContainer.addCustomType("@odata2ts/converter-runtime", "createChain");
120
+ const [first, second, ...moreConverters] = converters;
121
+ return moreConverters.reduce((stmt, conv) => `${stmt}.chain(${conv.converterId})`, `createChain(${first.converterId}, ${second.converterId})`);
122
+ }
123
+ }
124
+ generateIdFunction(model, importContainer) {
125
+ if (!model.generateId) {
126
+ return;
127
+ }
128
+ const qFunc = "QId";
129
+ importContainer.addFromQObject(qFunc);
130
+ importContainer.addGeneratedModel(model.idModelName);
131
+ this.sourceFile.addClass({
132
+ name: model.qIdFunctionName,
133
+ isExported: true,
134
+ extends: `${qFunc}<${model.idModelName}>`,
135
+ properties: [
136
+ {
137
+ name: "params",
138
+ scope: ts_morph_1.Scope.Private,
139
+ isReadonly: true,
140
+ initializer: this.getParamInitString(model.keys, importContainer),
141
+ },
142
+ ],
143
+ methods: [
144
+ {
145
+ name: "getParams",
146
+ statements: ["return this.params"],
147
+ },
148
+ ],
149
+ });
150
+ }
151
+ getParamInitString(props, importContainer) {
152
+ return `[${props
153
+ .map((prop) => {
154
+ var _a;
155
+ if (prop.qParam) {
156
+ importContainer.addFromQObject(prop.qParam);
157
+ }
158
+ const isMappedNameNecessary = prop.odataName !== prop.name;
159
+ const mappedName = isMappedNameNecessary ? `"${prop.name}"` : ((_a = prop.converters) === null || _a === void 0 ? void 0 : _a.length) ? "undefined" : undefined;
160
+ const converterStmt = this.generateConverterStmt(prop.converters, importContainer);
161
+ return `new ${prop.qParam}("${prop.odataName}"${mappedName ? `, ${mappedName}` : ""}${converterStmt ? `, ${converterStmt}` : ""})`;
162
+ })
163
+ .join(",")}]`;
164
+ }
165
+ generateUnboundOperations(importContainer) {
166
+ this.dataModel.getUnboundOperationTypes().forEach((operation) => {
167
+ this.generateOperation(operation, importContainer);
168
+ });
169
+ }
170
+ generateBoundOperations(bindingName, importContainer) {
171
+ this.dataModel.getOperationTypeByBinding(bindingName).forEach((operation) => {
172
+ this.generateOperation(operation, importContainer);
173
+ });
174
+ }
175
+ generateOperation(operation, importContainer) {
176
+ const isV2 = this.version === odata_core_1.ODataVersions.V2;
177
+ const qOperation = operation.type === "Action" /* Action */ ? "QAction" : "QFunction";
178
+ const returnType = operation.returnType;
179
+ let returnTypeOpStmt = "";
180
+ const hasParams = operation.parameters.length > 0;
181
+ importContainer.addFromQObject(qOperation);
182
+ if (hasParams) {
183
+ importContainer.addGeneratedModel(operation.paramsModelName);
184
+ }
185
+ if (returnType) {
186
+ if (returnType.dataType === "ComplexType" /* ComplexType */ || returnType.dataType === "ModelType" /* ModelType */) {
187
+ if (returnType.qObject) {
188
+ importContainer.addFromQObject("OperationReturnType", "ReturnTypes", "QComplexParam");
189
+ returnTypeOpStmt = `new OperationReturnType(ReturnTypes.COMPLEX${returnType.isCollection ? "_COLLECTION" : ""}, new QComplexParam("NONE", new ${returnType.qObject}))`;
190
+ }
191
+ }
192
+ else if (returnType.converters && returnType.qParam) {
193
+ importContainer.addFromQObject("OperationReturnType", "ReturnTypes", returnType.qParam);
194
+ returnTypeOpStmt = `new OperationReturnType(ReturnTypes.VALUE${returnType.isCollection ? "_COLLECTION" : ""}, new ${returnType.qParam}("NONE", undefined, ${this.generateConverterStmt(returnType.converters, importContainer)}))`;
195
+ }
196
+ }
197
+ this.sourceFile.addClass({
198
+ name: operation.qName,
199
+ isExported: true,
200
+ extends: qOperation + (hasParams ? `<${operation.paramsModelName}>` : ""),
201
+ properties: [
202
+ {
203
+ name: "params",
204
+ scope: ts_morph_1.Scope.Private,
205
+ isReadonly: true,
206
+ initializer: this.getParamInitString(operation.parameters, importContainer),
207
+ },
208
+ ],
209
+ ctors: [
210
+ {
211
+ statements: [
212
+ `super("${operation.odataName}"${returnTypeOpStmt ? ", " + returnTypeOpStmt : isV2 ? ", undefined" : ""}${isV2 ? ", { v2Mode: true }" : ""})`,
213
+ ],
214
+ },
215
+ ],
216
+ methods: [
217
+ {
218
+ name: "getParams",
219
+ statements: ["return this.params"],
220
+ },
221
+ // functions without params: add an overriding buildUrl() to not force users to have to pass undefined as param
222
+ ...(operation.type === "Function" /* Function */ && !hasParams
223
+ ? [
224
+ {
225
+ name: "buildUrl",
226
+ statements: ["return super.buildUrl(undefined)"],
227
+ },
228
+ ]
229
+ : []),
230
+ ],
231
+ });
232
+ }
233
+ }
234
+ //# sourceMappingURL=QueryObjectGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryObjectGenerator.js","sourceRoot":"","sources":["../../src/generator/QueryObjectGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { ODataVersions } from "@odata2ts/odata-core";
2
+ import { DataModel } from "../data-model/DataModel";
3
+ import { NamingHelper } from "../data-model/NamingHelper";
4
+ import { ProjectManager } from "../project/ProjectManager";
5
+ export declare function generateServices(dataModel: DataModel, project: ProjectManager, version: ODataVersions, namingHelper: NamingHelper): Promise<void>;
@@ -0,0 +1,412 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateServices = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const odata_core_1 = require("@odata2ts/odata-core");
6
+ const ts_morph_1 = require("ts-morph");
7
+ const upper_case_first_1 = require("upper-case-first");
8
+ const processors_1 = require("xml2js/lib/processors");
9
+ const ImportContainer_1 = require("./ImportContainer");
10
+ const ROOT_SERVICE = "ODataService";
11
+ const RESPONSE_TYPES = {
12
+ collection: "ODataCollectionResponse",
13
+ model: "ODataModelResponse",
14
+ value: "ODataValueResponse",
15
+ };
16
+ function generateServices(dataModel, project, version, namingHelper) {
17
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
18
+ const generator = new ServiceGenerator(dataModel, project, version, namingHelper);
19
+ return generator.generate();
20
+ });
21
+ }
22
+ exports.generateServices = generateServices;
23
+ class ServiceGenerator {
24
+ constructor(dataModel, project, version, namingHelper) {
25
+ this.dataModel = dataModel;
26
+ this.project = project;
27
+ this.version = version;
28
+ this.namingHelper = namingHelper;
29
+ this.generateQOperationProps = (operation) => {
30
+ return {
31
+ scope: ts_morph_1.Scope.Private,
32
+ name: this.namingHelper.getPrivatePropName(operation.qName),
33
+ type: operation.qName,
34
+ hasQuestionToken: true,
35
+ };
36
+ };
37
+ }
38
+ generate() {
39
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
40
+ const sourceFile = yield this.project.createMainServiceFile();
41
+ const serviceName = this.namingHelper.getMainServiceName();
42
+ const container = this.dataModel.getEntityContainer();
43
+ const unboundOperations = [...Object.values(container.functions), ...Object.values(container.actions)];
44
+ yield this.generateModelServices();
45
+ const importContainer = new ImportContainer_1.ImportContainer(this.namingHelper.getFileNames());
46
+ importContainer.addFromClientApi("ODataClient");
47
+ importContainer.addFromService(ROOT_SERVICE);
48
+ sourceFile.addClass({
49
+ isExported: true,
50
+ name: serviceName,
51
+ typeParameters: ["ClientType extends ODataClient"],
52
+ extends: `${ROOT_SERVICE}<ClientType>`,
53
+ properties: [
54
+ {
55
+ scope: ts_morph_1.Scope.Private,
56
+ name: this.namingHelper.getPrivatePropName("name"),
57
+ type: "string",
58
+ initializer: `"${this.namingHelper.getODataServiceName()}"`,
59
+ },
60
+ ...this.generateEntityServiceResolverProp(container.entitySets, importContainer),
61
+ ...this.generateServiceGettersByAssignment(container.entitySets),
62
+ ...this.generateServiceTypeProps(container.singletons, this.namingHelper.getServiceName, importContainer),
63
+ ...Object.values(unboundOperations).map(({ operation }) => this.generateQOperationProps(operation)),
64
+ ],
65
+ methods: [
66
+ ...this.generateServiceTypeGetters(container.singletons, this.namingHelper.getServiceName),
67
+ ...this.generateUnboundOperations(unboundOperations, importContainer),
68
+ ],
69
+ });
70
+ sourceFile.addImportDeclarations(importContainer.getImportDeclarations(false));
71
+ });
72
+ }
73
+ generateEntityServiceResolverProp(services, importContainer) {
74
+ return Object.values(services).map(({ name, entityType }) => {
75
+ const resolverName = this.namingHelper.getServiceResolverName(entityType.name);
76
+ importContainer.addGeneratedService(this.namingHelper.getServiceName(entityType.name), resolverName);
77
+ return {
78
+ name: this.namingHelper.getPublicPropNameForService(name),
79
+ scope: ts_morph_1.Scope.Public,
80
+ initializer: `${resolverName}(this.client, this.getPath(), "${name}")`,
81
+ };
82
+ });
83
+ }
84
+ generateServiceGettersByAssignment(services) {
85
+ return Object.values(services).map(({ name, odataName, entityType }) => {
86
+ const propName = this.namingHelper.getPublicPropNameForService(name);
87
+ return {
88
+ scope: ts_morph_1.Scope.Public,
89
+ name: this.namingHelper.getRelatedServiceGetter(name),
90
+ initializer: `this.${propName}.get.bind(this.${propName})`,
91
+ };
92
+ });
93
+ }
94
+ generateServiceTypeProps(services, typeRetriever, importContainer) {
95
+ return Object.values(services).map(({ name, entityType }) => {
96
+ const type = typeRetriever(entityType.name);
97
+ importContainer.addGeneratedService(this.namingHelper.getServiceName(entityType.name), type);
98
+ return {
99
+ scope: ts_morph_1.Scope.Private,
100
+ name: this.namingHelper.getPrivatePropName(name),
101
+ type: `${type}<ClientType>`,
102
+ hasQuestionToken: true,
103
+ };
104
+ });
105
+ }
106
+ generateServiceTypeGetters(services, typeRetriever) {
107
+ return Object.values(services).map(({ name, odataName, entityType }) => {
108
+ const propName = "this." + this.namingHelper.getPrivatePropName(name);
109
+ const serviceType = typeRetriever(entityType.name);
110
+ return {
111
+ scope: ts_morph_1.Scope.Public,
112
+ name: this.namingHelper.getRelatedServiceGetter(name),
113
+ statements: [
114
+ `if(!${propName}) {`,
115
+ // prettier-ignore
116
+ ` ${propName} = new ${serviceType}(this.client, this.getPath(), "${odataName}")`,
117
+ "}",
118
+ `return ${propName}`,
119
+ ],
120
+ };
121
+ });
122
+ }
123
+ getVersionSuffix() {
124
+ return this.version === odata_core_1.ODataVersions.V2 ? "V2" : "V4";
125
+ }
126
+ generateModelService(model, serviceName, serviceFile, importContainer) {
127
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
128
+ const entityServiceType = "EntityTypeService" + this.getVersionSuffix();
129
+ const collectionServiceType = "CollectionService" + this.getVersionSuffix();
130
+ const editableModelName = model.editableName;
131
+ const operations = this.dataModel.getOperationTypeByBinding(model.name);
132
+ const props = [...model.baseProps, ...model.props];
133
+ const modelProps = props.filter((prop) => prop.dataType === "ModelType" /* ModelType */ || prop.dataType === "ComplexType" /* ComplexType */);
134
+ const primColProps = props.filter((prop) => prop.isCollection && prop.dataType !== "ModelType" /* ModelType */ && prop.dataType !== "ComplexType" /* ComplexType */);
135
+ importContainer.addFromService(entityServiceType);
136
+ importContainer.addFromClientApi("ODataClient");
137
+ importContainer.addGeneratedModel(model.name, editableModelName);
138
+ importContainer.addGeneratedQObject(model.qName, (0, processors_1.firstCharLowerCase)(model.qName));
139
+ // generate EntityTypeService
140
+ serviceFile.addClass({
141
+ isExported: true,
142
+ name: serviceName,
143
+ typeParameters: ["ClientType extends ODataClient"],
144
+ extends: entityServiceType + `<ClientType, ${model.name}, ${editableModelName}, ${model.qName}>`,
145
+ ctors: [
146
+ {
147
+ parameters: [
148
+ { name: "client", type: "ClientType" },
149
+ { name: "basePath", type: "string" },
150
+ { name: "name", type: "string" },
151
+ ],
152
+ statements: [`super(client, basePath, name, ${(0, processors_1.firstCharLowerCase)(model.qName)});`],
153
+ },
154
+ ],
155
+ properties: [
156
+ ...this.generateModelProps(modelProps, collectionServiceType, serviceName, importContainer),
157
+ ...this.generatePrimitiveCollectionProps(primColProps, collectionServiceType, importContainer),
158
+ ...operations.map(this.generateQOperationProps),
159
+ ],
160
+ methods: [
161
+ ...this.generateModelPropGetters(modelProps, collectionServiceType),
162
+ ...this.generatePrimitiveCollectionGetters(primColProps, collectionServiceType),
163
+ ...this.generateBoundOperations(operations, importContainer),
164
+ ],
165
+ });
166
+ });
167
+ }
168
+ generateModelProps(modelProps, collectionServiceType, serviceName, importContainer) {
169
+ return modelProps.map((prop) => {
170
+ const complexType = this.dataModel.getComplexType(prop.type);
171
+ const key = this.namingHelper.getServiceName(prop.type);
172
+ let propModelType = prop.isCollection ? this.namingHelper.getCollectionServiceName(prop.type) : key;
173
+ if (prop.isCollection && complexType) {
174
+ const editableName = complexType.editableName;
175
+ importContainer.addFromService(collectionServiceType);
176
+ importContainer.addGeneratedModel(complexType.name, editableName);
177
+ importContainer.addGeneratedQObject(complexType.qName, (0, processors_1.firstCharLowerCase)(complexType.qName));
178
+ propModelType = `${collectionServiceType}<ClientType, ${complexType.name}, ${complexType.qName}, ${editableName}>`;
179
+ }
180
+ else {
181
+ // don't include imports for this type
182
+ if (serviceName !== key) {
183
+ importContainer.addGeneratedService(key, propModelType);
184
+ }
185
+ propModelType = `${propModelType}<ClientType>`;
186
+ }
187
+ return {
188
+ scope: ts_morph_1.Scope.Private,
189
+ name: this.namingHelper.getPrivatePropName(prop.name),
190
+ type: propModelType,
191
+ hasQuestionToken: true,
192
+ };
193
+ });
194
+ }
195
+ generatePrimitiveCollectionProps(primColProps, collectionServiceType, importContainer) {
196
+ return primColProps.map((prop) => {
197
+ const isEnum = prop.dataType === "EnumType" /* EnumType */;
198
+ const type = isEnum ? `EnumCollection<${prop.type}>` : `${(0, upper_case_first_1.upperCaseFirst)(prop.type)}Collection`;
199
+ const qType = isEnum ? "QEnumCollection" : `Q${type}`;
200
+ const collectionType = `${collectionServiceType}<ClientType, ${type}, ${qType}>`;
201
+ if (!prop.qObject) {
202
+ throw new Error("Illegal State: [qObject] must be provided for Collection types!");
203
+ }
204
+ importContainer.addFromService(collectionServiceType);
205
+ importContainer.addFromQObject(prop.qObject, (0, processors_1.firstCharLowerCase)(prop.qObject));
206
+ if (isEnum) {
207
+ importContainer.addGeneratedModel(prop.type);
208
+ importContainer.addFromQObject("EnumCollection");
209
+ }
210
+ else {
211
+ importContainer.addFromQObject(type);
212
+ }
213
+ return {
214
+ scope: ts_morph_1.Scope.Private,
215
+ name: this.namingHelper.getPrivatePropName(prop.name),
216
+ type: `${collectionType}`,
217
+ hasQuestionToken: true,
218
+ };
219
+ });
220
+ }
221
+ generateModelPropGetters(modelProps, collectionServiceType) {
222
+ return modelProps.map((prop) => {
223
+ const complexType = this.dataModel.getComplexType(prop.type);
224
+ const isComplexCollection = prop.isCollection && complexType;
225
+ const type = isComplexCollection
226
+ ? collectionServiceType
227
+ : prop.isCollection
228
+ ? this.namingHelper.getCollectionServiceName(prop.type)
229
+ : this.namingHelper.getServiceName(prop.type);
230
+ const typeWithGenerics = isComplexCollection
231
+ ? `${collectionServiceType}<ClientType, ${complexType.name}, ${complexType.qName}, ${complexType.editableName}>`
232
+ : `${type}<ClientType>`;
233
+ const privateSrvProp = "this." + this.namingHelper.getPrivatePropName(prop.name);
234
+ return {
235
+ scope: ts_morph_1.Scope.Public,
236
+ name: this.namingHelper.getRelatedServiceGetter(prop.name),
237
+ returnType: typeWithGenerics,
238
+ statements: [
239
+ `if(!${privateSrvProp}) {`,
240
+ // prettier-ignore
241
+ ` ${privateSrvProp} = new ${type}(this.client, this.getPath(), "${prop.odataName}"${isComplexCollection ? `, ${(0, processors_1.firstCharLowerCase)(complexType.qName)}` : ""})`,
242
+ "}",
243
+ `return ${privateSrvProp}`,
244
+ ],
245
+ };
246
+ });
247
+ }
248
+ generatePrimitiveCollectionGetters(primColProps, collectionServiceType) {
249
+ return primColProps.map((prop) => {
250
+ const propName = "this." + this.namingHelper.getPrivatePropName(prop.name);
251
+ return {
252
+ scope: ts_morph_1.Scope.Public,
253
+ name: this.namingHelper.getRelatedServiceGetter(prop.name),
254
+ statements: [
255
+ `if(!${propName}) {`,
256
+ // prettier-ignore
257
+ ` ${propName} = new ${collectionServiceType}(this.client, this.getPath(), "${prop.odataName}", ${(0, processors_1.firstCharLowerCase)(prop.qObject)})`,
258
+ "}",
259
+ `return ${propName}`,
260
+ ],
261
+ };
262
+ });
263
+ }
264
+ generateEntityCollectionService(model, serviceName, serviceFile, importContainer) {
265
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
266
+ const entitySetServiceType = "EntitySetService" + this.getVersionSuffix();
267
+ const editableModelName = model.editableName;
268
+ const qObjectName = (0, processors_1.firstCharLowerCase)(model.qName);
269
+ importContainer.addFromService(entitySetServiceType);
270
+ importContainer.addGeneratedModel(model.idModelName);
271
+ importContainer.addGeneratedQObject(model.qIdFunctionName);
272
+ const collectionOperations = this.dataModel.getOperationTypeByBinding(`Collection(${model.name})`);
273
+ serviceFile.addClass({
274
+ isExported: true,
275
+ name: this.namingHelper.getCollectionServiceName(model.name),
276
+ typeParameters: ["ClientType extends ODataClient"],
277
+ extends: entitySetServiceType +
278
+ `<ClientType, ${model.name}, ${editableModelName}, ${model.qName}, ${model.idModelName}, ${serviceName}<ClientType>>`,
279
+ ctors: [
280
+ {
281
+ parameters: [
282
+ { name: "client", type: "ClientType" },
283
+ { name: "basePath", type: "string" },
284
+ { name: "name", type: "string" },
285
+ ],
286
+ statements: [
287
+ `super(client, basePath, name, ${qObjectName}, ${serviceName}, new ${model.qIdFunctionName}(name));`,
288
+ ],
289
+ },
290
+ ],
291
+ properties: [...collectionOperations.map(this.generateQOperationProps)],
292
+ methods: [...this.generateBoundOperations(collectionOperations, importContainer)],
293
+ });
294
+ });
295
+ }
296
+ generateEntityServiceResolver(model, serviceName, serviceFile, importContainer) {
297
+ const idFunctionName = this.namingHelper.getQIdFunctionName(model.odataName);
298
+ const collectionName = this.namingHelper.getCollectionServiceName(model.name);
299
+ importContainer.addFromClientApi("ODataClient");
300
+ importContainer.addFromService("EntityServiceResolver");
301
+ importContainer.addGeneratedQObject(idFunctionName);
302
+ serviceFile.addFunction({
303
+ name: this.namingHelper.getServiceResolverName(model.name),
304
+ isExported: true,
305
+ parameters: [
306
+ {
307
+ name: "client",
308
+ type: "ODataClient",
309
+ },
310
+ {
311
+ name: "basePath",
312
+ type: "string",
313
+ },
314
+ {
315
+ name: "entityName",
316
+ type: "string",
317
+ },
318
+ ],
319
+ statements: [
320
+ `return new EntityServiceResolver(client, basePath, entityName, ${idFunctionName}, ${serviceName}, ${collectionName});`,
321
+ ],
322
+ });
323
+ }
324
+ generateModelServices() {
325
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
326
+ // build service file for each entity, consisting of EntityTypeService & EntityCollectionService
327
+ for (const model of this.dataModel.getModels()) {
328
+ const serviceName = this.namingHelper.getServiceName(model.name);
329
+ const serviceFile = yield this.project.createServiceFile(serviceName);
330
+ const importContainer = new ImportContainer_1.ImportContainer(this.namingHelper.getFileNames());
331
+ // entity type service
332
+ yield this.generateModelService(model, serviceName, serviceFile, importContainer);
333
+ // entity collection service
334
+ yield this.generateEntityCollectionService(model, serviceName, serviceFile, importContainer);
335
+ // the resolver function
336
+ yield this.generateEntityServiceResolver(model, serviceName, serviceFile, importContainer);
337
+ serviceFile.addImportDeclarations(importContainer.getImportDeclarations(true));
338
+ }
339
+ // build service file for complex types
340
+ for (const model of this.dataModel.getComplexTypes()) {
341
+ const serviceName = this.namingHelper.getServiceName(model.name);
342
+ const serviceFile = yield this.project.createServiceFile(serviceName);
343
+ const importContainer = new ImportContainer_1.ImportContainer(this.namingHelper.getFileNames());
344
+ // entity type service
345
+ yield this.generateModelService(model, serviceName, serviceFile, importContainer);
346
+ serviceFile.addImportDeclarations(importContainer.getImportDeclarations(true));
347
+ }
348
+ });
349
+ }
350
+ generateBoundOperations(operations, importContainer) {
351
+ return operations.reduce((collector, operation) => {
352
+ collector.push(this.generateMethod(operation.name, operation, importContainer));
353
+ return collector;
354
+ }, []);
355
+ }
356
+ generateUnboundOperations(operations, importContainer) {
357
+ return Object.values(operations).reduce((collector, { name, operation }) => {
358
+ collector.push(this.generateMethod(name, operation, importContainer));
359
+ return collector;
360
+ }, []);
361
+ }
362
+ generateMethod(name, operation, importContainer) {
363
+ var _a, _b;
364
+ const isFunc = operation.type === "Function" /* Function */;
365
+ const odataType = ((_a = operation.returnType) === null || _a === void 0 ? void 0 : _a.isCollection)
366
+ ? RESPONSE_TYPES.collection + this.getVersionSuffix()
367
+ : ((_b = operation.returnType) === null || _b === void 0 ? void 0 : _b.dataType) === "PrimitiveType" /* PrimitiveType */
368
+ ? RESPONSE_TYPES.value + this.getVersionSuffix()
369
+ : RESPONSE_TYPES.model + this.getVersionSuffix();
370
+ const returnType = operation.returnType;
371
+ const requestConfigParam = { name: "requestConfig", hasQuestionToken: true, type: "ODataClientConfig<ClientType>" };
372
+ const hasParams = operation.parameters.length > 0;
373
+ // importing dependencies
374
+ importContainer.addFromClientApi("ODataClientConfig", "ODataResponse");
375
+ importContainer.addFromCore(odataType);
376
+ if (returnType === null || returnType === void 0 ? void 0 : returnType.type) {
377
+ if (["EnumType" /* EnumType */, "ModelType" /* ModelType */, "ComplexType" /* ComplexType */].includes(returnType.dataType)) {
378
+ importContainer.addGeneratedModel(returnType.type);
379
+ }
380
+ }
381
+ importContainer.addGeneratedQObject(operation.qName);
382
+ if (hasParams) {
383
+ importContainer.addGeneratedModel(operation.paramsModelName);
384
+ }
385
+ const qOpProp = "this." + this.namingHelper.getPrivatePropName(operation.qName);
386
+ return {
387
+ scope: ts_morph_1.Scope.Public,
388
+ isAsync: true,
389
+ name,
390
+ parameters: hasParams
391
+ ? [{ name: "params", type: operation.paramsModelName }, requestConfigParam]
392
+ : [requestConfigParam],
393
+ returnType: `ODataResponse<${odataType}<${(returnType === null || returnType === void 0 ? void 0 : returnType.type) || "void"}>>`,
394
+ statements: [
395
+ `if(!${qOpProp}) {`,
396
+ ` ${qOpProp} = new ${operation.qName}()`,
397
+ "}",
398
+ `const url = this.addFullPath(${qOpProp}.buildUrl(${isFunc && hasParams ? "params" : ""}));`,
399
+ `${returnType ? "const response = await " : "return"} this.client.${!isFunc
400
+ ? // actions: since V4
401
+ `post(url, ${hasParams ? `${qOpProp}.convertUserParams(params)` : "{}"}, ${requestConfigParam.name})`
402
+ : operation.usePost
403
+ ? // V2 POST => BUT values are still query params, they are not part of the request body
404
+ `post(url, undefined, ${requestConfigParam.name})`
405
+ : // functions: since V2
406
+ `get(url, ${requestConfigParam.name})`};`,
407
+ returnType ? `return ${qOpProp}.convertResponse(response);` : "",
408
+ ],
409
+ };
410
+ }
411
+ }
412
+ //# sourceMappingURL=ServiceGenerator.js.map