@cap-js/ord 1.3.3 → 1.3.4
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/lib/defaults.js +4 -12
- package/lib/ord.js +6 -5
- package/lib/templates.js +50 -15
- package/lib/utils.js +12 -0
- package/package.json +1 -1
package/lib/defaults.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { OPEN_RESOURCE_DISCOVERY_VERSION, SHORT_DESCRIPTION_PREFIX, RESOURCE_VISIBILITY } = require("./constants");
|
|
2
|
+
const { hasSAPPolicyLevel } = require("./utils");
|
|
2
3
|
const { getAuthConfig } = require("./authentication");
|
|
3
4
|
const _ = require("lodash");
|
|
4
5
|
|
|
@@ -35,15 +36,6 @@ const generateUniquePackageOrdId = (ordNamespace, name, tag, visibility) => {
|
|
|
35
36
|
return `${ordNamespace}:package:${regexWithRemoval(name)}${tag}${visibilitySuffix}:v1`;
|
|
36
37
|
};
|
|
37
38
|
|
|
38
|
-
/**
|
|
39
|
-
* Checks if at least one policy level in the array is SAP.
|
|
40
|
-
*
|
|
41
|
-
* @param {string[]} policyLevels - Array of policy levels.
|
|
42
|
-
*/
|
|
43
|
-
function hasSAPPolicyLevel(policyLevels) {
|
|
44
|
-
return policyLevels.some((policyLevel) => policyLevel.split(":")[0].toLowerCase() === "sap");
|
|
45
|
-
}
|
|
46
|
-
|
|
47
39
|
/**
|
|
48
40
|
* Module containing default configuration for ORD Document.
|
|
49
41
|
* @module defaults
|
|
@@ -58,16 +50,16 @@ module.exports = {
|
|
|
58
50
|
ordId: defaultProductOrdId(name),
|
|
59
51
|
title: nameWithSpaces(name),
|
|
60
52
|
shortDescription: SHORT_DESCRIPTION_PREFIX + nameWithSpaces(name),
|
|
61
|
-
vendor: "customer:vendor:
|
|
53
|
+
vendor: "customer:vendor:Customer:",
|
|
62
54
|
},
|
|
63
55
|
],
|
|
64
56
|
groupTypeId: "sap.cds:service",
|
|
65
|
-
packages: function getPackageData(appConfig
|
|
57
|
+
packages: function getPackageData(appConfig) {
|
|
66
58
|
const name = appConfig.appName;
|
|
67
59
|
const ordNamespace = appConfig.ordNamespace;
|
|
68
60
|
const productsOrdId = appConfig.existingProductORDId || appConfig.products?.[0]?.ordId;
|
|
69
61
|
const vendor = appConfig.env?.packages?.[0]?.vendor;
|
|
70
|
-
if (hasSAPPolicyLevel(policyLevels)) {
|
|
62
|
+
if (hasSAPPolicyLevel(appConfig.policyLevels)) {
|
|
71
63
|
return _.uniqBy(
|
|
72
64
|
packageTypes.flatMap(({ tag, type }) =>
|
|
73
65
|
Object.values(RESOURCE_VISIBILITY).map((visibility) => ({
|
package/lib/ord.js
CHANGED
|
@@ -185,14 +185,14 @@ const _getGroups = (csn, appConfig) => {
|
|
|
185
185
|
.filter((resource) => !!resource);
|
|
186
186
|
};
|
|
187
187
|
|
|
188
|
-
const _getPackages = (
|
|
189
|
-
return defaults.packages(appConfig
|
|
188
|
+
const _getPackages = (appConfig) => {
|
|
189
|
+
return defaults.packages(appConfig);
|
|
190
190
|
};
|
|
191
191
|
|
|
192
192
|
const _getEntityTypes = (appConfig, packageIds) => {
|
|
193
193
|
if (!appConfig.entityTypeTargets?.length) return [];
|
|
194
194
|
|
|
195
|
-
return appConfig.entityTypeTargets.
|
|
195
|
+
return appConfig.entityTypeTargets.flatMap((entity) => createEntityTypeTemplate(appConfig, packageIds, entity));
|
|
196
196
|
};
|
|
197
197
|
|
|
198
198
|
const _getAPIResources = (csn, appConfig, packageIds, accessStrategies) => {
|
|
@@ -238,10 +238,11 @@ const _getProducts = (appConfig) => {
|
|
|
238
238
|
};
|
|
239
239
|
|
|
240
240
|
function createDefaultORDDocument(linkedCsn, appConfig) {
|
|
241
|
+
appConfig.policyLevels = _getPolicyLevels(appConfig);
|
|
241
242
|
let ordDocument = {
|
|
242
243
|
$schema: "https://open-resource-discovery.github.io/specification/spec-v1/interfaces/Document.schema.json",
|
|
243
244
|
openResourceDiscovery: _getOpenResourceDiscovery(appConfig),
|
|
244
|
-
policyLevels:
|
|
245
|
+
policyLevels: appConfig.policyLevels,
|
|
245
246
|
description: _getDescription(appConfig),
|
|
246
247
|
consumptionBundles: _getConsumptionBundles(appConfig),
|
|
247
248
|
};
|
|
@@ -256,7 +257,7 @@ function createDefaultORDDocument(linkedCsn, appConfig) {
|
|
|
256
257
|
ordDocument.products = [_getProducts(appConfig)[0]];
|
|
257
258
|
}
|
|
258
259
|
|
|
259
|
-
ordDocument.packages = _getPackages(
|
|
260
|
+
ordDocument.packages = _getPackages(appConfig);
|
|
260
261
|
|
|
261
262
|
return ordDocument;
|
|
262
263
|
}
|
package/lib/templates.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const cds = require("@sap/cds");
|
|
2
|
+
const { hasSAPPolicyLevel } = require("./utils");
|
|
2
3
|
const defaults = require("./defaults");
|
|
3
4
|
const _ = require("lodash");
|
|
4
5
|
const {
|
|
@@ -80,6 +81,7 @@ const createEntityTypeMappingsItemTemplate = (entity) => {
|
|
|
80
81
|
return {
|
|
81
82
|
ordId: `sap.odm:entityType:${entity[ORD_ODM_ENTITY_NAME_ANNOTATION]}:v1`,
|
|
82
83
|
entityName: entity[ORD_ODM_ENTITY_NAME_ANNOTATION],
|
|
84
|
+
isODMMapping: true,
|
|
83
85
|
...entity,
|
|
84
86
|
};
|
|
85
87
|
} else if (entity[ENTITY_RELATIONSHIP_ANNOTATION]) {
|
|
@@ -95,8 +97,19 @@ const createEntityTypeMappingsItemTemplate = (entity) => {
|
|
|
95
97
|
}
|
|
96
98
|
};
|
|
97
99
|
|
|
98
|
-
function _getGroupID(
|
|
99
|
-
return `${groupTypeId}:${appConfig.ordNamespace}:${
|
|
100
|
+
function _getGroupID(serviceDefinition, groupTypeId = defaults.groupTypeId, appConfig) {
|
|
101
|
+
return `${groupTypeId}:${appConfig.ordNamespace}:${_getGroupNameWithNestedNamespace(serviceDefinition, appConfig)}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function _getGroupNameWithNestedNamespace({ name }, appConfig) {
|
|
105
|
+
if (!name.startsWith(appConfig.ordNamespace)) {
|
|
106
|
+
return name;
|
|
107
|
+
}
|
|
108
|
+
let sortedName = name.substring(appConfig.ordNamespace.length);
|
|
109
|
+
if (sortedName.startsWith(".")) {
|
|
110
|
+
sortedName = sortedName.substring(1);
|
|
111
|
+
}
|
|
112
|
+
return sortedName;
|
|
100
113
|
}
|
|
101
114
|
|
|
102
115
|
/**
|
|
@@ -174,7 +187,7 @@ const createGroupsTemplateForService = (serviceName, serviceDefinition, appConfi
|
|
|
174
187
|
return undefined;
|
|
175
188
|
}
|
|
176
189
|
|
|
177
|
-
const groupId = _getGroupID(
|
|
190
|
+
const groupId = _getGroupID(serviceDefinition, defaults.groupTypeId, appConfig);
|
|
178
191
|
return {
|
|
179
192
|
groupId: groupId,
|
|
180
193
|
groupTypeId: defaults.groupTypeId,
|
|
@@ -192,11 +205,20 @@ const createGroupsTemplateForService = (serviceName, serviceDefinition, appConfi
|
|
|
192
205
|
* @returns { object } An object for the EntityType.
|
|
193
206
|
*/
|
|
194
207
|
const createEntityTypeTemplate = (appConfig, packageIds, entity) => {
|
|
208
|
+
if (entity.isODMMapping) {
|
|
209
|
+
// ODM mappings are not created as entity types, they are only used in entityTypeMappings
|
|
210
|
+
return [];
|
|
211
|
+
}
|
|
212
|
+
if (hasSAPPolicyLevel(appConfig.policyLevels)) {
|
|
213
|
+
// If SAP policy level is present, don't create entity type, they must be in the central repository
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
|
|
195
217
|
const ordExtensions = readORDExtensions(entity);
|
|
196
218
|
const visibility = ordExtensions.visibility || RESOURCE_VISIBILITY.public;
|
|
197
219
|
|
|
198
220
|
if (visibility === RESOURCE_VISIBILITY.private) {
|
|
199
|
-
return
|
|
221
|
+
return [];
|
|
200
222
|
}
|
|
201
223
|
|
|
202
224
|
const packageId = _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.entityType, visibility);
|
|
@@ -220,7 +242,9 @@ const createEntityTypeTemplate = (appConfig, packageIds, entity) => {
|
|
|
220
242
|
|
|
221
243
|
function _handleVisibility(ordExtensions, definition) {
|
|
222
244
|
let visibility;
|
|
223
|
-
if (
|
|
245
|
+
if (isPrimaryDataProductService(definition)) {
|
|
246
|
+
visibility = RESOURCE_VISIBILITY.internal;
|
|
247
|
+
} else if (ordExtensions.visibility) {
|
|
224
248
|
visibility = ordExtensions.visibility;
|
|
225
249
|
} else if (definition[ORD_EXTENSIONS_PREFIX + "visibility"]) {
|
|
226
250
|
visibility = definition[ORD_EXTENSIONS_PREFIX + "visibility"];
|
|
@@ -248,7 +272,7 @@ const createAPIResourceTemplate = (serviceName, serviceDefinition, appConfig, pa
|
|
|
248
272
|
|
|
249
273
|
const paths = _generatePaths(serviceName, serviceDefinition);
|
|
250
274
|
const apiResources = [];
|
|
251
|
-
const ordId = `${appConfig.ordNamespace}:apiResource:${
|
|
275
|
+
const ordId = `${appConfig.ordNamespace}:apiResource:${_getGroupNameWithNestedNamespace(serviceDefinition, appConfig)}:v1`;
|
|
252
276
|
|
|
253
277
|
paths.forEach((generatedPath) => {
|
|
254
278
|
let resourceDefinitions = [
|
|
@@ -273,7 +297,7 @@ const createAPIResourceTemplate = (serviceName, serviceDefinition, appConfig, pa
|
|
|
273
297
|
lastUpdate: appConfig.lastUpdate,
|
|
274
298
|
visibility,
|
|
275
299
|
partOfPackage: packageId,
|
|
276
|
-
partOfGroups: [_getGroupID(
|
|
300
|
+
partOfGroups: [_getGroupID(serviceDefinition, defaults.groupTypeId, appConfig)],
|
|
277
301
|
releaseStatus: "active",
|
|
278
302
|
apiProtocol: generatedPath.kind === "odata" ? "odata-v4" : generatedPath.kind,
|
|
279
303
|
resourceDefinitions: resourceDefinitions,
|
|
@@ -285,9 +309,8 @@ const createAPIResourceTemplate = (serviceName, serviceDefinition, appConfig, pa
|
|
|
285
309
|
...ordExtensions,
|
|
286
310
|
};
|
|
287
311
|
|
|
288
|
-
if (serviceDefinition
|
|
312
|
+
if (isPrimaryDataProductService(serviceDefinition)) {
|
|
289
313
|
obj.apiProtocol = "rest";
|
|
290
|
-
obj.visibility = RESOURCE_VISIBILITY.internal;
|
|
291
314
|
obj.direction = "outbound";
|
|
292
315
|
obj.implementationStandard = "sap.dp:data-subscription-api:v1";
|
|
293
316
|
obj.entryPoints = [];
|
|
@@ -328,7 +351,7 @@ const createEventResourceTemplate = (serviceName, serviceDefinition, appConfig,
|
|
|
328
351
|
const ordExtensions = readORDExtensions(serviceDefinition);
|
|
329
352
|
const visibility = _handleVisibility(ordExtensions, serviceDefinition);
|
|
330
353
|
const packageId = _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.event, visibility);
|
|
331
|
-
const ordId = `${appConfig.ordNamespace}:eventResource:${
|
|
354
|
+
const ordId = `${appConfig.ordNamespace}:eventResource:${_getGroupNameWithNestedNamespace(serviceDefinition, appConfig)}:v1`;
|
|
332
355
|
const entityTypeMappings = _getEntityTypeMappings(serviceDefinition);
|
|
333
356
|
|
|
334
357
|
let obj = {
|
|
@@ -346,7 +369,7 @@ const createEventResourceTemplate = (serviceName, serviceDefinition, appConfig,
|
|
|
346
369
|
lastUpdate: appConfig.lastUpdate,
|
|
347
370
|
releaseStatus: "active",
|
|
348
371
|
partOfPackage: packageId,
|
|
349
|
-
partOfGroups: [_getGroupID(
|
|
372
|
+
partOfGroups: [_getGroupID(serviceDefinition, defaults.groupTypeId, appConfig)],
|
|
350
373
|
visibility,
|
|
351
374
|
resourceDefinitions: [
|
|
352
375
|
_getResourceDefinition("asyncapi-v2", "json", ordId, serviceName, "asyncapi2.json", accessStrategies),
|
|
@@ -361,13 +384,18 @@ const createEventResourceTemplate = (serviceName, serviceDefinition, appConfig,
|
|
|
361
384
|
: [];
|
|
362
385
|
};
|
|
363
386
|
|
|
387
|
+
function isPrimaryDataProductService(serviceDefinition) {
|
|
388
|
+
return serviceDefinition[DATA_PRODUCT_ANNOTATION] === DATA_PRODUCT_TYPE.primary;
|
|
389
|
+
}
|
|
390
|
+
|
|
364
391
|
function _getEntityTypeMappings(definitionObj) {
|
|
365
392
|
if (!definitionObj.entities) {
|
|
366
393
|
return;
|
|
367
394
|
}
|
|
368
|
-
const entities = Object.values(definitionObj.entities)
|
|
369
|
-
|
|
370
|
-
.
|
|
395
|
+
const entities = Object.values(definitionObj.entities).flatMap((entity) => {
|
|
396
|
+
const entityData = _flattenEntityGraph(entity).map(createEntityTypeMappingsItemTemplate);
|
|
397
|
+
return _.uniqBy(entityData, CONTENT_MERGE_KEY);
|
|
398
|
+
});
|
|
371
399
|
const entityTypeTargets = _.uniqBy(entities, CONTENT_MERGE_KEY)
|
|
372
400
|
.filter((entity) => entity !== undefined)
|
|
373
401
|
.map(({ ordId }) => ({
|
|
@@ -394,8 +422,15 @@ function _flattenEntityGraph(currentEntity, processedEntities = []) {
|
|
|
394
422
|
if (processedEntities.includes(target)) {
|
|
395
423
|
return;
|
|
396
424
|
}
|
|
397
|
-
processedEntities = [...processedEntities, target];
|
|
398
425
|
assertionsTodo.push(entity);
|
|
426
|
+
|
|
427
|
+
/*
|
|
428
|
+
the next line operates on heap memory so that the same entity is not processed again
|
|
429
|
+
heap memory is used so that the check is the same in:
|
|
430
|
+
a > b > c > b scenario (runs first)
|
|
431
|
+
a > d > c > ... scenario (runs later and does not process c again)
|
|
432
|
+
*/
|
|
433
|
+
processedEntities.push(target);
|
|
399
434
|
});
|
|
400
435
|
|
|
401
436
|
return [currentEntity, ...assertionsTodo.flatMap((entity) => _flattenEntityGraph(entity, processedEntities))];
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if at least one policy level in the array is SAP.
|
|
3
|
+
*
|
|
4
|
+
* @param {string[]} policyLevels - Array of policy levels.
|
|
5
|
+
*/
|
|
6
|
+
function hasSAPPolicyLevel(policyLevels) {
|
|
7
|
+
return policyLevels.some((policyLevel) => policyLevel.split(":")[0].toLowerCase() === "sap");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
hasSAPPolicyLevel,
|
|
12
|
+
};
|