@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.
- package/CHANGELOG.md +28 -0
- package/lib/FactoryFunctionModel.d.ts +3 -3
- package/lib/FactoryFunctionModel.js.map +1 -1
- package/lib/OptionModel.d.ts +9 -0
- package/lib/OptionModel.js.map +1 -1
- package/lib/app.js +18 -8
- package/lib/app.js.map +1 -1
- package/lib/data-model/DataModel.d.ts +12 -6
- package/lib/data-model/DataModel.js +10 -0
- package/lib/data-model/DataModel.js.map +1 -1
- package/lib/data-model/DataModelDigestion.js +37 -20
- package/lib/data-model/DataModelDigestion.js.map +1 -1
- package/lib/data-model/DataModelDigestionV2.js +1 -1
- package/lib/data-model/DataModelDigestionV2.js.map +1 -1
- package/lib/data-model/DataModelDigestionV4.js +1 -10
- package/lib/data-model/DataModelDigestionV4.js.map +1 -1
- package/lib/data-model/DataTypeModel.d.ts +17 -7
- package/lib/data-model/DataTypeModel.js.map +1 -1
- package/lib/data-model/NamingHelper.d.ts +1 -0
- package/lib/data-model/NamingHelper.js +4 -1
- package/lib/data-model/NamingHelper.js.map +1 -1
- package/lib/data-model/ServiceConfigHelper.js +2 -2
- package/lib/data-model/ServiceConfigHelper.js.map +1 -1
- package/lib/data-model/validation/NameClashValidator.d.ts +23 -0
- package/lib/data-model/validation/NameClashValidator.js +89 -0
- package/lib/data-model/validation/NameClashValidator.js.map +1 -0
- package/lib/data-model/validation/NameValidator.d.ts +6 -17
- package/lib/data-model/validation/NameValidator.js +0 -77
- package/lib/data-model/validation/NameValidator.js.map +1 -1
- package/lib/data-model/validation/NoopValidator.d.ts +12 -0
- package/lib/data-model/validation/NoopValidator.js +34 -0
- package/lib/data-model/validation/NoopValidator.js.map +1 -0
- package/lib/defaultConfig.js +1 -0
- package/lib/defaultConfig.js.map +1 -1
- package/lib/generator/ImportContainer.d.ts +44 -11
- package/lib/generator/ImportContainer.js +150 -47
- package/lib/generator/ImportContainer.js.map +1 -1
- package/lib/generator/ImportedNameValidator.d.ts +5 -0
- package/lib/generator/ImportedNameValidator.js +26 -0
- package/lib/generator/ImportedNameValidator.js.map +1 -0
- package/lib/generator/ModelGenerator.js +113 -72
- package/lib/generator/ModelGenerator.js.map +1 -1
- package/lib/generator/QueryObjectGenerator.js +134 -107
- package/lib/generator/QueryObjectGenerator.js.map +1 -1
- package/lib/generator/ServiceGenerator.d.ts +1 -1
- package/lib/generator/ServiceGenerator.js +160 -161
- package/lib/generator/ServiceGenerator.js.map +1 -1
- package/lib/generator/import/ImportObjects.d.ts +66 -0
- package/lib/generator/import/ImportObjects.js +83 -0
- package/lib/generator/import/ImportObjects.js.map +1 -0
- package/lib/project/FileHandler.d.ts +28 -0
- package/lib/project/FileHandler.js +66 -0
- package/lib/project/FileHandler.js.map +1 -0
- package/lib/project/ProjectManager.d.ts +44 -18
- package/lib/project/ProjectManager.js +156 -111
- package/lib/project/ProjectManager.js.map +1 -1
- package/lib/project/TsMorphHelper.d.ts +11 -0
- package/lib/project/TsMorphHelper.js +66 -0
- package/lib/project/TsMorphHelper.js.map +1 -0
- package/package.json +10 -8
|
@@ -7,24 +7,18 @@ const deepmerge_1 = tslib_1.__importDefault(require("deepmerge"));
|
|
|
7
7
|
const ts_morph_1 = require("ts-morph");
|
|
8
8
|
const upper_case_first_1 = require("upper-case-first");
|
|
9
9
|
const processors_1 = require("xml2js/lib/processors");
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const RESPONSE_TYPES = {
|
|
13
|
-
collection: "ODataCollectionResponse",
|
|
14
|
-
model: "ODataModelResponse",
|
|
15
|
-
value: "ODataValueResponse",
|
|
16
|
-
};
|
|
17
|
-
function generateServices(dataModel, project, version, namingHelper, options) {
|
|
10
|
+
const ImportObjects_1 = require("./import/ImportObjects");
|
|
11
|
+
function generateServices(project, dataModel, version, namingHelper, options) {
|
|
18
12
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
19
|
-
const generator = new ServiceGenerator(
|
|
13
|
+
const generator = new ServiceGenerator(project, dataModel, version, namingHelper, options);
|
|
20
14
|
return generator.generate();
|
|
21
15
|
});
|
|
22
16
|
}
|
|
23
17
|
exports.generateServices = generateServices;
|
|
24
18
|
class ServiceGenerator {
|
|
25
|
-
constructor(
|
|
26
|
-
this.dataModel = dataModel;
|
|
19
|
+
constructor(project, dataModel, version, namingHelper, options = {}) {
|
|
27
20
|
this.project = project;
|
|
21
|
+
this.dataModel = dataModel;
|
|
28
22
|
this.version = version;
|
|
29
23
|
this.namingHelper = namingHelper;
|
|
30
24
|
this.options = options;
|
|
@@ -42,19 +36,30 @@ class ServiceGenerator {
|
|
|
42
36
|
}
|
|
43
37
|
generate() {
|
|
44
38
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
const
|
|
46
|
-
|
|
39
|
+
const mainServiceName = this.namingHelper.getMainServiceName();
|
|
40
|
+
this.project.initServices();
|
|
41
|
+
yield Promise.all([
|
|
42
|
+
this.generateMainService(mainServiceName),
|
|
43
|
+
...this.generateEntityTypeServices(),
|
|
44
|
+
...this.generateComplexTypeServices(),
|
|
45
|
+
]);
|
|
46
|
+
return this.project.finalizeServices();
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
generateMainService(mainServiceName) {
|
|
50
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
const mainServiceFile = this.project.getMainServiceFile();
|
|
52
|
+
const importContainer = mainServiceFile.getImports();
|
|
47
53
|
const container = this.dataModel.getEntityContainer();
|
|
48
54
|
const unboundOperations = [...Object.values(container.functions), ...Object.values(container.actions)];
|
|
49
|
-
const
|
|
50
|
-
importContainer.
|
|
51
|
-
importContainer.addFromService(ROOT_SERVICE);
|
|
55
|
+
const [httpClient] = importContainer.addClientApi(ImportObjects_1.ClientApiImports.ODataHttpClient);
|
|
56
|
+
const [rootService] = importContainer.addServiceObject(this.version, ImportObjects_1.ServiceImports.ODataService);
|
|
52
57
|
const { properties, methods } = (0, deepmerge_1.default)(this.generateMainServiceProperties(container, importContainer), this.generateMainServiceOperations(unboundOperations, importContainer));
|
|
53
|
-
|
|
58
|
+
mainServiceFile.getFile().addClass({
|
|
54
59
|
isExported: true,
|
|
55
|
-
name:
|
|
56
|
-
typeParameters: [
|
|
57
|
-
extends: `${
|
|
60
|
+
name: mainServiceName,
|
|
61
|
+
typeParameters: [`ClientType extends ${httpClient}`],
|
|
62
|
+
extends: `${rootService}<ClientType>`,
|
|
58
63
|
ctors: this.isV4BigNumber()
|
|
59
64
|
? [
|
|
60
65
|
{
|
|
@@ -69,8 +74,6 @@ class ServiceGenerator {
|
|
|
69
74
|
properties,
|
|
70
75
|
methods,
|
|
71
76
|
});
|
|
72
|
-
yield this.generateModelServices(sourceFile, importContainer);
|
|
73
|
-
sourceFile.addImportDeclarations(importContainer.getImportDeclarations(false));
|
|
74
77
|
});
|
|
75
78
|
}
|
|
76
79
|
generateMainServiceProperties(container, importContainer) {
|
|
@@ -79,7 +82,7 @@ class ServiceGenerator {
|
|
|
79
82
|
result.methods.push(this.generateRelatedServiceGetter(name, odataName, entityType, importContainer));
|
|
80
83
|
});
|
|
81
84
|
Object.values(container.singletons).forEach((singleton) => {
|
|
82
|
-
result.properties.push(this.generateSingletonProp(
|
|
85
|
+
result.properties.push(this.generateSingletonProp(importContainer, singleton));
|
|
83
86
|
result.methods.push(this.generateSingletonGetter(singleton));
|
|
84
87
|
});
|
|
85
88
|
return result;
|
|
@@ -92,18 +95,15 @@ class ServiceGenerator {
|
|
|
92
95
|
throw new Error(`Operation "${operation}" not found!`);
|
|
93
96
|
}
|
|
94
97
|
result.properties.push(this.generateQOperationProp(op));
|
|
95
|
-
result.methods.push(this.generateMethod(name, op, importContainer));
|
|
98
|
+
result.methods.push(this.generateMethod(name, op, importContainer, ""));
|
|
96
99
|
});
|
|
97
100
|
return result;
|
|
98
101
|
}
|
|
99
|
-
generateRelatedServiceGetter(propName, odataPropName, entityType,
|
|
100
|
-
const idName = entityType.
|
|
101
|
-
const idFunctionName = entityType.
|
|
102
|
-
const serviceName =
|
|
103
|
-
const collectionName =
|
|
104
|
-
importContainer.addFromClientApi("ODataHttpClient");
|
|
105
|
-
importContainer.addGeneratedModel(idName);
|
|
106
|
-
importContainer.addGeneratedQObject(idFunctionName);
|
|
102
|
+
generateRelatedServiceGetter(propName, odataPropName, entityType, imports) {
|
|
103
|
+
const idName = imports.addGeneratedModel(entityType.id.fqName, entityType.id.modelName);
|
|
104
|
+
const idFunctionName = imports.addGeneratedQObject(entityType.id.fqName, entityType.id.qName);
|
|
105
|
+
const serviceName = imports.addGeneratedService(entityType.fqName, entityType.serviceName);
|
|
106
|
+
const collectionName = imports.addGeneratedService(entityType.fqName, entityType.serviceCollectionName);
|
|
107
107
|
return {
|
|
108
108
|
scope: ts_morph_1.Scope.Public,
|
|
109
109
|
name: this.namingHelper.getRelatedServiceGetter(propName),
|
|
@@ -138,9 +138,9 @@ class ServiceGenerator {
|
|
|
138
138
|
],
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
|
-
generateSingletonProp(
|
|
141
|
+
generateSingletonProp(importContainer, singleton) {
|
|
142
142
|
const { name, entityType } = singleton;
|
|
143
|
-
const type =
|
|
143
|
+
const type = entityType.serviceName;
|
|
144
144
|
return {
|
|
145
145
|
scope: ts_morph_1.Scope.Private,
|
|
146
146
|
name: this.namingHelper.getPrivatePropName(name),
|
|
@@ -151,7 +151,7 @@ class ServiceGenerator {
|
|
|
151
151
|
generateSingletonGetter(singleton) {
|
|
152
152
|
const { name, odataName, entityType } = singleton;
|
|
153
153
|
const propName = "this." + this.namingHelper.getPrivatePropName(name);
|
|
154
|
-
const serviceType =
|
|
154
|
+
const serviceType = entityType.serviceName;
|
|
155
155
|
return {
|
|
156
156
|
scope: ts_morph_1.Scope.Public,
|
|
157
157
|
name: this.namingHelper.getRelatedServiceGetter(name),
|
|
@@ -165,26 +165,24 @@ class ServiceGenerator {
|
|
|
165
165
|
],
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
generateEntityTypeService(model, serviceName, serviceFile, importContainer) {
|
|
172
|
-
const entityServiceType = "EntityTypeService" + this.getVersionSuffix();
|
|
173
|
-
const editableModelName = model.editableName;
|
|
174
|
-
const qObjectName = (0, processors_1.firstCharLowerCase)(model.qName);
|
|
168
|
+
generateEntityTypeService(file, model) {
|
|
169
|
+
const importContainer = file.getImports();
|
|
175
170
|
const operations = this.dataModel.getEntityTypeOperations(model.fqName);
|
|
176
171
|
const props = [...model.baseProps, ...model.props];
|
|
177
|
-
importContainer.
|
|
178
|
-
importContainer.
|
|
179
|
-
|
|
180
|
-
importContainer.
|
|
181
|
-
const
|
|
172
|
+
const [entityServiceType] = importContainer.addServiceObject(this.version, ImportObjects_1.ServiceImports.EntityTypeService);
|
|
173
|
+
const [httpClient] = importContainer.addClientApi(ImportObjects_1.ClientApiImports.ODataHttpClient);
|
|
174
|
+
// note: predictable first imports => no need to take renaming into account
|
|
175
|
+
const modelName = importContainer.addGeneratedModel(model.fqName, model.modelName);
|
|
176
|
+
const editableModelName = importContainer.addGeneratedModel(model.fqName, model.editableName);
|
|
177
|
+
const qName = importContainer.addGeneratedQObject(model.fqName, model.qName);
|
|
178
|
+
const qObjectName = importContainer.addGeneratedQObject(model.fqName, (0, processors_1.firstCharLowerCase)(model.qName));
|
|
179
|
+
const { properties, methods } = (0, deepmerge_1.default)(this.generateServiceProperties(importContainer, model.serviceName, props), this.generateServiceOperations(importContainer, model, operations));
|
|
182
180
|
// generate EntityTypeService
|
|
183
|
-
|
|
181
|
+
file.getFile().addClass({
|
|
184
182
|
isExported: true,
|
|
185
|
-
name: serviceName,
|
|
186
|
-
typeParameters: [
|
|
187
|
-
extends: entityServiceType + `<ClientType, ${
|
|
183
|
+
name: model.serviceName,
|
|
184
|
+
typeParameters: [`ClientType extends ${httpClient}`],
|
|
185
|
+
extends: entityServiceType + `<ClientType, ${modelName}, ${editableModelName}, ${qName}>`,
|
|
188
186
|
ctors: [
|
|
189
187
|
{
|
|
190
188
|
parameters: [
|
|
@@ -199,16 +197,13 @@ class ServiceGenerator {
|
|
|
199
197
|
methods,
|
|
200
198
|
});
|
|
201
199
|
}
|
|
202
|
-
|
|
203
|
-
return "PrimitiveTypeService" + this.getVersionSuffix();
|
|
204
|
-
}
|
|
205
|
-
generateServiceProperties(serviceName, props, importContainer) {
|
|
206
|
-
const collectionServiceType = "CollectionService" + this.getVersionSuffix();
|
|
200
|
+
generateServiceProperties(importContainer, serviceName, props) {
|
|
207
201
|
const result = { properties: [], methods: [] };
|
|
208
202
|
props.forEach((prop) => {
|
|
203
|
+
// complex types, collection of complex types or entityTypes
|
|
209
204
|
if ((prop.dataType === "ModelType" /* DataTypes.ModelType */ && !prop.isCollection) || prop.dataType === "ComplexType" /* DataTypes.ComplexType */) {
|
|
210
|
-
result.properties.push(this.generateModelProp(
|
|
211
|
-
result.methods.push(this.generateModelPropGetter(
|
|
205
|
+
result.properties.push(this.generateModelProp(importContainer, prop));
|
|
206
|
+
result.methods.push(this.generateModelPropGetter(importContainer, prop));
|
|
212
207
|
}
|
|
213
208
|
else if (prop.isCollection) {
|
|
214
209
|
// collection of entity types
|
|
@@ -219,40 +214,41 @@ class ServiceGenerator {
|
|
|
219
214
|
}
|
|
220
215
|
result.methods.push(this.generateRelatedServiceGetter(prop.name, prop.odataName, entityType, importContainer));
|
|
221
216
|
}
|
|
222
|
-
// collection of primitive or
|
|
217
|
+
// collection of primitive or enum types
|
|
223
218
|
else {
|
|
224
|
-
result.properties.push(this.generatePrimitiveCollectionProp(
|
|
225
|
-
result.methods.push(this.generatePrimitiveCollectionGetter(
|
|
219
|
+
result.properties.push(this.generatePrimitiveCollectionProp(importContainer, prop));
|
|
220
|
+
result.methods.push(this.generatePrimitiveCollectionGetter(importContainer, prop));
|
|
226
221
|
}
|
|
227
222
|
}
|
|
223
|
+
// generation of services for each primitive property: turned off by default
|
|
228
224
|
else if (this.options.enablePrimitivePropertyServices && prop.dataType === "PrimitiveType" /* DataTypes.PrimitiveType */) {
|
|
229
|
-
result.properties.push(this.generatePrimitiveTypeProp(
|
|
230
|
-
result.methods.push(this.generatePrimitiveTypeGetter(prop));
|
|
225
|
+
result.properties.push(this.generatePrimitiveTypeProp(importContainer, prop));
|
|
226
|
+
result.methods.push(this.generatePrimitiveTypeGetter(importContainer, prop));
|
|
231
227
|
}
|
|
232
228
|
});
|
|
233
229
|
return result;
|
|
234
230
|
}
|
|
235
|
-
generateServiceOperations(
|
|
231
|
+
generateServiceOperations(importContainer, model, operations) {
|
|
236
232
|
const result = { properties: [], methods: [] };
|
|
237
233
|
operations.forEach((operation) => {
|
|
238
234
|
result.properties.push(this.generateQOperationProp(operation));
|
|
239
|
-
result.methods.push(this.generateMethod(operation.name, operation, importContainer));
|
|
235
|
+
result.methods.push(this.generateMethod(operation.name, operation, importContainer, model.fqName));
|
|
240
236
|
});
|
|
241
237
|
return result;
|
|
242
238
|
}
|
|
243
|
-
generateModelProp(
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
propModelType = `${collectionServiceType}<ClientType, ${complexType.name}, ${complexType.qName}, ${editableName}>`;
|
|
239
|
+
generateModelProp(imports, prop) {
|
|
240
|
+
const propModel = this.dataModel.getModel(prop.fqType);
|
|
241
|
+
let propModelType;
|
|
242
|
+
if (prop.isCollection) {
|
|
243
|
+
const modelName = imports.addGeneratedModel(propModel.fqName, propModel.modelName);
|
|
244
|
+
const editableModelName = imports.addGeneratedModel(propModel.fqName, propModel.editableName);
|
|
245
|
+
const qModelName = imports.addGeneratedQObject(propModel.fqName, propModel.qName);
|
|
246
|
+
const [collectionServiceType] = imports.addServiceObject(this.version, ImportObjects_1.ServiceImports.CollectionService);
|
|
247
|
+
propModelType = `${collectionServiceType}<ClientType, ${modelName}, ${qModelName}, ${editableModelName}>`;
|
|
253
248
|
}
|
|
254
249
|
else {
|
|
255
|
-
|
|
250
|
+
const serviceName = imports.addGeneratedService(propModel.fqName, propModel.serviceName);
|
|
251
|
+
propModelType = `${serviceName}<ClientType>`;
|
|
256
252
|
}
|
|
257
253
|
return {
|
|
258
254
|
scope: ts_morph_1.Scope.Private,
|
|
@@ -261,23 +257,25 @@ class ServiceGenerator {
|
|
|
261
257
|
hasQuestionToken: true,
|
|
262
258
|
};
|
|
263
259
|
}
|
|
264
|
-
generatePrimitiveCollectionProp(
|
|
265
|
-
const isEnum = prop.dataType === "EnumType" /* DataTypes.EnumType */;
|
|
266
|
-
const type = isEnum ? `EnumCollection<${prop.type}>` : `${(0, upper_case_first_1.upperCaseFirst)(prop.type)}Collection`;
|
|
267
|
-
const qType = isEnum ? "QEnumCollection" : prop.qObject;
|
|
268
|
-
const collectionType = `${collectionServiceType}<ClientType, ${type}, ${qType}>`;
|
|
260
|
+
generatePrimitiveCollectionProp(imports, prop) {
|
|
269
261
|
if (!prop.qObject) {
|
|
270
262
|
throw new Error("Illegal State: [qObject] must be provided for Collection types!");
|
|
271
263
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
264
|
+
const [collectionServiceType] = imports.addServiceObject(this.version, ImportObjects_1.ServiceImports.CollectionService);
|
|
265
|
+
const isEnum = prop.dataType === "EnumType" /* DataTypes.EnumType */;
|
|
266
|
+
let qType;
|
|
267
|
+
let type;
|
|
268
|
+
if (!isEnum) {
|
|
269
|
+
// TODO move string concat (StringCollection, GuidCollection...) to better place
|
|
270
|
+
[type, qType] = imports.addFromQObject(`${(0, upper_case_first_1.upperCaseFirst)(prop.type)}Collection`, prop.qObject);
|
|
277
271
|
}
|
|
278
272
|
else {
|
|
279
|
-
|
|
273
|
+
const propEnum = this.dataModel.getModel(prop.fqType);
|
|
274
|
+
const propTypeModel = imports.addGeneratedModel(propEnum.fqName, propEnum.modelName);
|
|
275
|
+
[type, qType] = imports.addQObject(ImportObjects_1.QueryObjectImports.EnumCollection, ImportObjects_1.QueryObjectImports.QEnumCollection);
|
|
276
|
+
type = `${type}<${propTypeModel}>`;
|
|
280
277
|
}
|
|
278
|
+
const collectionType = `${collectionServiceType}<ClientType, ${type}, ${qType}>`;
|
|
281
279
|
return {
|
|
282
280
|
scope: ts_morph_1.Scope.Private,
|
|
283
281
|
name: this.namingHelper.getPrivatePropName(prop.name),
|
|
@@ -285,29 +283,26 @@ class ServiceGenerator {
|
|
|
285
283
|
hasQuestionToken: true,
|
|
286
284
|
};
|
|
287
285
|
}
|
|
288
|
-
generatePrimitiveTypeProp(
|
|
289
|
-
const serviceType = this.
|
|
290
|
-
|
|
291
|
-
if (prop.typeModule) {
|
|
292
|
-
importContainer.addCustomType(prop.typeModule, prop.type);
|
|
293
|
-
}
|
|
286
|
+
generatePrimitiveTypeProp(imports, prop) {
|
|
287
|
+
const [serviceType] = imports.addServiceObject(this.version, ImportObjects_1.ServiceImports.PrimitiveTypeService);
|
|
288
|
+
const type = prop.typeModule ? imports.addCustomType(prop.typeModule, prop.type) : prop.type;
|
|
294
289
|
return {
|
|
295
290
|
scope: ts_morph_1.Scope.Private,
|
|
296
291
|
name: this.namingHelper.getPrivatePropName(prop.name),
|
|
297
|
-
type: `${serviceType}<ClientType, ${
|
|
292
|
+
type: `${serviceType}<ClientType, ${type}>`,
|
|
298
293
|
hasQuestionToken: true,
|
|
299
294
|
};
|
|
300
295
|
}
|
|
301
|
-
generateModelPropGetter(
|
|
302
|
-
const
|
|
303
|
-
const isComplexCollection = prop.isCollection &&
|
|
296
|
+
generateModelPropGetter(imports, prop) {
|
|
297
|
+
const model = this.dataModel.getModel(prop.fqType);
|
|
298
|
+
const isComplexCollection = prop.isCollection && model.dataType === "ComplexType" /* DataTypes.ComplexType */;
|
|
304
299
|
const type = isComplexCollection
|
|
305
|
-
?
|
|
300
|
+
? imports.addServiceObject(this.version, ImportObjects_1.ServiceImports.CollectionService)[0]
|
|
306
301
|
: prop.isCollection
|
|
307
|
-
?
|
|
308
|
-
:
|
|
302
|
+
? model.serviceCollectionName
|
|
303
|
+
: model.serviceName;
|
|
309
304
|
const typeWithGenerics = isComplexCollection
|
|
310
|
-
? `${
|
|
305
|
+
? `${type}<ClientType, ${imports.addGeneratedModel(model.fqName, model.modelName)}, ${imports.addGeneratedQObject(model.fqName, model.qName)}, ${imports.addGeneratedModel(model.fqName, model.editableName)}>`
|
|
311
306
|
: `${type}<ClientType>`;
|
|
312
307
|
const privateSrvProp = "this." + this.namingHelper.getPrivatePropName(prop.name);
|
|
313
308
|
return {
|
|
@@ -318,13 +313,16 @@ class ServiceGenerator {
|
|
|
318
313
|
`if(!${privateSrvProp}) {`,
|
|
319
314
|
` const { client, path } = this.__base;`,
|
|
320
315
|
// prettier-ignore
|
|
321
|
-
` ${privateSrvProp} = new ${type}(client, path, "${prop.odataName}"${isComplexCollection ? `, ${(0, processors_1.firstCharLowerCase)(
|
|
316
|
+
` ${privateSrvProp} = new ${type}(client, path, "${prop.odataName}"${isComplexCollection ? `, ${imports.addGeneratedQObject(model.fqName, (0, processors_1.firstCharLowerCase)(model.qName))}` : ""})`,
|
|
322
317
|
"}",
|
|
323
318
|
`return ${privateSrvProp}`,
|
|
324
319
|
],
|
|
325
320
|
};
|
|
326
321
|
}
|
|
327
|
-
generatePrimitiveCollectionGetter(
|
|
322
|
+
generatePrimitiveCollectionGetter(imports, prop) {
|
|
323
|
+
const [collectionServiceType] = imports.addServiceObject(this.version, ImportObjects_1.ServiceImports.CollectionService);
|
|
324
|
+
const instanceName = (0, processors_1.firstCharLowerCase)(prop.qObject);
|
|
325
|
+
const [qInstanceName] = imports.addFromQObject(instanceName);
|
|
328
326
|
const propName = "this." + this.namingHelper.getPrivatePropName(prop.name);
|
|
329
327
|
return {
|
|
330
328
|
scope: ts_morph_1.Scope.Public,
|
|
@@ -333,14 +331,14 @@ class ServiceGenerator {
|
|
|
333
331
|
`if(!${propName}) {`,
|
|
334
332
|
` const { client, path } = this.__base;`,
|
|
335
333
|
// prettier-ignore
|
|
336
|
-
` ${propName} = new ${collectionServiceType}(client, path, "${prop.odataName}", ${
|
|
334
|
+
` ${propName} = new ${collectionServiceType}(client, path, "${prop.odataName}", ${qInstanceName}${this.isV4BigNumber() ? ", true" : ""})`,
|
|
337
335
|
"}",
|
|
338
336
|
`return ${propName}`,
|
|
339
337
|
],
|
|
340
338
|
};
|
|
341
339
|
}
|
|
342
|
-
generatePrimitiveTypeGetter(prop) {
|
|
343
|
-
const serviceType = this.
|
|
340
|
+
generatePrimitiveTypeGetter(imports, prop) {
|
|
341
|
+
const [serviceType] = imports.addServiceObject(this.version, ImportObjects_1.ServiceImports.PrimitiveTypeService);
|
|
344
342
|
const propName = "this." + this.namingHelper.getPrivatePropName(prop.name);
|
|
345
343
|
// for V2: mapped name must be specified
|
|
346
344
|
const useMappedName = this.version === odata_core_1.ODataVersions.V2 && prop.name !== prop.odataName;
|
|
@@ -359,21 +357,21 @@ class ServiceGenerator {
|
|
|
359
357
|
],
|
|
360
358
|
};
|
|
361
359
|
}
|
|
362
|
-
generateEntityCollectionService(
|
|
363
|
-
const
|
|
360
|
+
generateEntityCollectionService(file, model) {
|
|
361
|
+
const importContainer = file.getImports();
|
|
364
362
|
const editableModelName = model.editableName;
|
|
365
363
|
const qObjectName = (0, processors_1.firstCharLowerCase)(model.qName);
|
|
366
|
-
importContainer.
|
|
367
|
-
importContainer.addGeneratedModel(model.
|
|
368
|
-
importContainer.addGeneratedQObject(model.
|
|
364
|
+
const [entitySetServiceType] = importContainer.addServiceObject(this.version, ImportObjects_1.ServiceImports.EntitySetService);
|
|
365
|
+
const paramsModelName = importContainer.addGeneratedModel(model.id.fqName, model.id.modelName);
|
|
366
|
+
const qIdFunctionName = importContainer.addGeneratedQObject(model.id.fqName, model.id.qName);
|
|
369
367
|
const collectionOperations = this.dataModel.getEntitySetOperations(model.fqName);
|
|
370
|
-
const { properties, methods } = this.generateServiceOperations(
|
|
371
|
-
|
|
368
|
+
const { properties, methods } = this.generateServiceOperations(importContainer, model, collectionOperations);
|
|
369
|
+
file.getFile().addClass({
|
|
372
370
|
isExported: true,
|
|
373
|
-
name:
|
|
371
|
+
name: model.serviceCollectionName,
|
|
374
372
|
typeParameters: ["ClientType extends ODataHttpClient"],
|
|
375
373
|
extends: entitySetServiceType +
|
|
376
|
-
`<ClientType, ${model.
|
|
374
|
+
`<ClientType, ${model.modelName}, ${editableModelName}, ${model.qName}, ${paramsModelName}>`,
|
|
377
375
|
ctors: [
|
|
378
376
|
{
|
|
379
377
|
parameters: [
|
|
@@ -382,7 +380,7 @@ class ServiceGenerator {
|
|
|
382
380
|
{ name: "name", type: "string" },
|
|
383
381
|
],
|
|
384
382
|
statements: [
|
|
385
|
-
`super(client, basePath, name, ${qObjectName}, new ${
|
|
383
|
+
`super(client, basePath, name, ${qObjectName}, new ${qIdFunctionName}(name)${this.isV4BigNumber() ? ", true" : ""});`,
|
|
386
384
|
],
|
|
387
385
|
},
|
|
388
386
|
],
|
|
@@ -390,67 +388,60 @@ class ServiceGenerator {
|
|
|
390
388
|
methods,
|
|
391
389
|
});
|
|
392
390
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
// build service file for complex types
|
|
407
|
-
const complexTypes = this.dataModel.getComplexTypes().filter((ct) => !ct.abstract);
|
|
408
|
-
for (const model of complexTypes) {
|
|
409
|
-
const serviceName = this.namingHelper.getServiceName(model.name);
|
|
410
|
-
// entity type service
|
|
411
|
-
this.generateEntityTypeService(model, serviceName, serviceFile, importContainer);
|
|
391
|
+
generateEntityTypeServices() {
|
|
392
|
+
// build service file for each entity, consisting of EntityTypeService & EntityCollectionService
|
|
393
|
+
return this.dataModel.getEntityTypes().map((model) => {
|
|
394
|
+
const file = this.project.createOrGetServiceFile(model.folderPath, model.serviceName, [
|
|
395
|
+
model.serviceName,
|
|
396
|
+
model.serviceCollectionName,
|
|
397
|
+
]);
|
|
398
|
+
// entity type service
|
|
399
|
+
this.generateEntityTypeService(file, model);
|
|
400
|
+
// entity collection service if this entity specified keys at all
|
|
401
|
+
if (model.keyNames.length) {
|
|
402
|
+
this.generateEntityCollectionService(file, model);
|
|
412
403
|
}
|
|
404
|
+
return this.project.finalizeFile(file);
|
|
413
405
|
});
|
|
414
406
|
}
|
|
415
|
-
|
|
416
|
-
|
|
407
|
+
generateComplexTypeServices() {
|
|
408
|
+
// build service file for complex types
|
|
409
|
+
return this.dataModel.getComplexTypes().map((model) => {
|
|
410
|
+
const file = this.project.createOrGetServiceFile(model.folderPath, model.serviceName, [model.serviceName]);
|
|
411
|
+
// entity type service
|
|
412
|
+
this.generateEntityTypeService(file, model);
|
|
413
|
+
return this.project.finalizeFile(file);
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
generateMethod(name, operation, importContainer, baseFqName) {
|
|
417
417
|
const isFunc = operation.type === "Function" /* OperationTypes.Function */;
|
|
418
|
-
const odataType = ((_a = operation.returnType) === null || _a === void 0 ? void 0 : _a.isCollection)
|
|
419
|
-
? RESPONSE_TYPES.collection + this.getVersionSuffix()
|
|
420
|
-
: ((_b = operation.returnType) === null || _b === void 0 ? void 0 : _b.dataType) === "PrimitiveType" /* DataTypes.PrimitiveType */
|
|
421
|
-
? RESPONSE_TYPES.value + this.getVersionSuffix()
|
|
422
|
-
: RESPONSE_TYPES.model + this.getVersionSuffix();
|
|
423
418
|
const returnType = operation.returnType;
|
|
419
|
+
const hasParams = operation.parameters.length > 0;
|
|
420
|
+
// importing dependencies
|
|
421
|
+
const [httpClientConfigModel, odataResponse] = importContainer.addClientApi(ImportObjects_1.ClientApiImports.ODataHttpClientConfig, ImportObjects_1.ClientApiImports.HttpResponseModel);
|
|
422
|
+
const responseStructure = this.importReturnType(importContainer, returnType);
|
|
423
|
+
const qOperationName = importContainer.addGeneratedQObject(baseFqName, operation.qName);
|
|
424
|
+
const rtType = (returnType === null || returnType === void 0 ? void 0 : returnType.type) && returnType.dataType !== "PrimitiveType" /* DataTypes.PrimitiveType */
|
|
425
|
+
? importContainer.addGeneratedModel(returnType.fqType, returnType.type)
|
|
426
|
+
: returnType === null || returnType === void 0 ? void 0 : returnType.type;
|
|
427
|
+
const paramsModelName = hasParams
|
|
428
|
+
? importContainer.addGeneratedModel(baseFqName, operation.paramsModelName)
|
|
429
|
+
: undefined;
|
|
424
430
|
const requestConfigParam = {
|
|
425
431
|
name: "requestConfig",
|
|
426
432
|
hasQuestionToken: true,
|
|
427
|
-
type:
|
|
433
|
+
type: `${httpClientConfigModel}<ClientType>`,
|
|
428
434
|
};
|
|
429
|
-
const hasParams = operation.parameters.length > 0;
|
|
430
|
-
// importing dependencies
|
|
431
|
-
importContainer.addFromClientApi("ODataHttpClientConfig", "ODataResponse");
|
|
432
|
-
importContainer.addFromCore(odataType);
|
|
433
|
-
if (returnType === null || returnType === void 0 ? void 0 : returnType.type) {
|
|
434
|
-
if (["EnumType" /* DataTypes.EnumType */, "ModelType" /* DataTypes.ModelType */, "ComplexType" /* DataTypes.ComplexType */].includes(returnType.dataType)) {
|
|
435
|
-
importContainer.addGeneratedModel(returnType.type);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
importContainer.addGeneratedQObject(operation.qName);
|
|
439
|
-
if (hasParams) {
|
|
440
|
-
importContainer.addGeneratedModel(operation.paramsModelName);
|
|
441
|
-
}
|
|
442
435
|
const qOpProp = "this." + this.namingHelper.getPrivatePropName(operation.qName);
|
|
443
436
|
return {
|
|
444
437
|
scope: ts_morph_1.Scope.Public,
|
|
445
438
|
isAsync: true,
|
|
446
439
|
name,
|
|
447
|
-
parameters: hasParams
|
|
448
|
-
|
|
449
|
-
: [requestConfigParam],
|
|
450
|
-
returnType: `ODataResponse<${odataType}<${(returnType === null || returnType === void 0 ? void 0 : returnType.type) || "void"}>>`,
|
|
440
|
+
parameters: hasParams ? [{ name: "params", type: paramsModelName }, requestConfigParam] : [requestConfigParam],
|
|
441
|
+
returnType: `Promise<${odataResponse}<${responseStructure}<${rtType || "void"}>>>`,
|
|
451
442
|
statements: [
|
|
452
443
|
`if(!${qOpProp}) {`,
|
|
453
|
-
` ${qOpProp} = new ${
|
|
444
|
+
` ${qOpProp} = new ${qOperationName}()`,
|
|
454
445
|
"}",
|
|
455
446
|
`const { addFullPath, client, getDefaultHeaders } = this.__base;`,
|
|
456
447
|
`const url = addFullPath(${qOpProp}.buildUrl(${isFunc && hasParams ? "params" : ""}));`,
|
|
@@ -466,5 +457,13 @@ class ServiceGenerator {
|
|
|
466
457
|
],
|
|
467
458
|
};
|
|
468
459
|
}
|
|
460
|
+
importReturnType(imports, returnType) {
|
|
461
|
+
const typeToImport = (returnType === null || returnType === void 0 ? void 0 : returnType.isCollection)
|
|
462
|
+
? ImportObjects_1.CoreImports.ODataCollectionResponse
|
|
463
|
+
: (returnType === null || returnType === void 0 ? void 0 : returnType.dataType) === "PrimitiveType" /* DataTypes.PrimitiveType */
|
|
464
|
+
? ImportObjects_1.CoreImports.ODataValueResponse
|
|
465
|
+
: ImportObjects_1.CoreImports.ODataModelResponse;
|
|
466
|
+
return imports.addCoreLib(this.version, typeToImport)[0];
|
|
467
|
+
}
|
|
469
468
|
}
|
|
470
469
|
//# sourceMappingURL=ServiceGenerator.js.map
|