@cap-js/ord 1.7.0 → 1.9.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/lib/templates.js DELETED
@@ -1,613 +0,0 @@
1
- const defaults = require("./defaults");
2
- const _ = require("lodash");
3
- const {
4
- DATA_PRODUCT_ANNOTATION,
5
- DATA_PRODUCT_SIMPLE_ANNOTATION,
6
- DATA_PRODUCT_TYPE,
7
- DESCRIPTION_PREFIX,
8
- ENTITY_RELATIONSHIP_ANNOTATION,
9
- LEVEL,
10
- ORD_EXTENSIONS_PREFIX,
11
- ORD_ODM_ENTITY_NAME_ANNOTATION,
12
- ORD_RESOURCE_TYPE,
13
- RESOURCE_VISIBILITY,
14
- ALLOWED_VISIBILITY,
15
- SUPPORTED_IMPLEMENTATIONSTANDARD_VERSIONS,
16
- SEM_VERSION_REGEX,
17
- SHORT_DESCRIPTION_PREFIX,
18
- CONTENT_MERGE_KEY,
19
- CDS_ELEMENT_KIND,
20
- ORD_API_PROTOCOL,
21
- MCP_RESOURCE_DEFINITION_TYPE,
22
- } = require("./constants");
23
- const Logger = require("./logger");
24
- const { ensureAccessStrategies } = require("./access-strategies");
25
- const { resolveApiResourceProtocol } = require("./protocol-resolver");
26
-
27
- function unflatten(flattedObject) {
28
- let result = {};
29
- _.keys(flattedObject).forEach(function (key) {
30
- _.set(result, key, flattedObject[key]);
31
- });
32
- return result;
33
- }
34
-
35
- function readORDExtensions(model) {
36
- const ordExtensions = {};
37
- for (const key in model) {
38
- if (key.startsWith(ORD_EXTENSIONS_PREFIX)) {
39
- const ordKey = key.replace(ORD_EXTENSIONS_PREFIX, "");
40
- ordExtensions[ordKey] = model[key];
41
- }
42
- }
43
- return unflatten(ordExtensions);
44
- }
45
-
46
- /**
47
- * This is a template function to create item of entityTypeMappings array.
48
- *
49
- * @param {string} entity The entity definition.
50
- * @returns {Object} An entry of the entityTypeMappings array.
51
- */
52
- const createEntityTypeMappingsItemTemplate = (entity) => {
53
- const results = [];
54
- if (entity[ORD_ODM_ENTITY_NAME_ANNOTATION]) {
55
- results.push({
56
- ordId: `sap.odm:entityType:${entity[ORD_ODM_ENTITY_NAME_ANNOTATION]}:v1`,
57
- entityName: entity[ORD_ODM_ENTITY_NAME_ANNOTATION],
58
- isODMMapping: true,
59
- ...entity,
60
- });
61
- }
62
- if (entity[ENTITY_RELATIONSHIP_ANNOTATION]) {
63
- const ordIdParts = entity[ENTITY_RELATIONSHIP_ANNOTATION].split(":");
64
- const namespace = ordIdParts[0];
65
- const entityName = ordIdParts[1];
66
- const version = ordIdParts[2] || "v1";
67
- results.push({
68
- ordId: `${namespace}:entityType:${entityName}:${version}`,
69
- entityName,
70
- ...entity,
71
- });
72
- }
73
- if (results.length === 0) return;
74
- return results;
75
- };
76
-
77
- function _getGroupID(serviceDefinition, groupTypeId = defaults.groupTypeId, appConfig) {
78
- return `${groupTypeId}:${appConfig.ordNamespace}:${_getCleanServiceName(serviceDefinition, appConfig)}`;
79
- }
80
-
81
- function _startsWithNamespace(name, namespace) {
82
- if (!name.startsWith(namespace)) return false;
83
- const rest = name.substring(namespace.length);
84
- return rest === "" || rest.startsWith(".");
85
- }
86
-
87
- function _getCleanServiceName({ name }, appConfig) {
88
- let sortedName = name;
89
- if (appConfig.internalNamespace && _startsWithNamespace(name, appConfig.internalNamespace)) {
90
- sortedName = name.substring(appConfig.internalNamespace.length);
91
- } else if (_startsWithNamespace(name, appConfig.ordNamespace)) {
92
- sortedName = name.substring(appConfig.ordNamespace.length);
93
- }
94
- if (sortedName.startsWith(".")) {
95
- sortedName = sortedName.substring(1);
96
- }
97
- return sortedName;
98
- }
99
-
100
- /**
101
- * This is a function to resolve the title of the service group.
102
- *
103
- * @param {string} srv The name of the service.
104
- * @returns {string} The title of the service group.
105
- */
106
- function _getTitleFromServiceName(srv) {
107
- let serviceName = srv.substring(srv.lastIndexOf(".") + 1);
108
- let index = serviceName.indexOf("Service");
109
- if (index >= 0) {
110
- return `${serviceName.substring(0, index)} Service`;
111
- } else {
112
- return `${serviceName} Service`;
113
- }
114
- }
115
-
116
- /**
117
- * This is a function to get the version of the entity,
118
- * validate it and log if it is not a valid semantical version.
119
- *
120
- * @param {object} entity An entity object.
121
- * @returns Version of the entity with '1.0.0' as fallback value.
122
- */
123
- function _getEntityVersion(entity) {
124
- const entityVersion = entity.ordId.split(":").pop();
125
- const version = entityVersion.replace("v", "") + ".0.0"; // TODO: version can be stated/overwritten by annotation
126
- if (!SEM_VERSION_REGEX.test(version)) {
127
- Logger.warn("Entity version", version, "is not a valid semantic version.");
128
- }
129
- return version;
130
- }
131
-
132
- /**
133
- * Pure template function for creating ORD resource definitions.
134
- * This function does not make assumptions about access strategies - they must be provided explicitly.
135
- * Access strategies are validated and will fallback to 'open' in non-strict mode if missing.
136
- *
137
- * @param {string} resourceType The type of the resource.
138
- * @param {string} mediaType The media type of the resource.
139
- * @param {string} ordId The ordId of the resource.
140
- * @param {string} serviceName The name of the service.
141
- * @param {string} fileExtension The file extension of the resource.
142
- * @param {Array} accessStrategies The array of accessStrategies objects (required, no default)
143
- * @returns {Object} A resource definition object.
144
- * @private
145
- */
146
- function _getResourceDefinition(resourceType, mediaType, ordId, serviceName, fileExtension, accessStrategies) {
147
- // Validate and ensure access strategies are present
148
- // In non-strict mode, this will log error and fallback to 'open'
149
- // In strict mode (cds.env.ord.strictAccessStrategies = true), this will throw
150
- const validatedStrategies = ensureAccessStrategies(accessStrategies, {
151
- resourceName: `${serviceName} (${resourceType})`,
152
- });
153
-
154
- return {
155
- type: resourceType,
156
- mediaType: `application/${mediaType}`,
157
- url: `/ord/v1/${ordId}/${serviceName}.${fileExtension}`,
158
- accessStrategies: validatedStrategies,
159
- };
160
- }
161
-
162
- /**
163
- * This is a template function to create group object of a service for groups array in ORD doc.
164
- *
165
- * @param {string} serviceName The name of the service.
166
- * @param {object} serviceDefinition The definition of the service
167
- * @param {object} appConfig - The application configuration.
168
- * @returns {Object} A group object.
169
- */
170
- const createGroupsTemplateForService = (serviceName, serviceDefinition, appConfig) => {
171
- const ordExtensions = readORDExtensions(serviceDefinition);
172
-
173
- if (!serviceDefinition) {
174
- Logger.warn("Unable to find service definition:", serviceName);
175
- return undefined;
176
- }
177
-
178
- const visibility = _handleVisibility(ordExtensions, serviceDefinition, appConfig.env?.defaultVisibility);
179
- if (visibility === RESOURCE_VISIBILITY.private) {
180
- // If the visibility of the service is private, do not create a group
181
- Logger.info("Skipping group creation for private service:", serviceName);
182
- return undefined;
183
- }
184
-
185
- const groupId = _getGroupID(serviceDefinition, defaults.groupTypeId, appConfig);
186
- return {
187
- groupId: groupId,
188
- groupTypeId: defaults.groupTypeId,
189
- title: ordExtensions.title ?? _getTitleFromServiceName(serviceName),
190
- };
191
- };
192
-
193
- /**
194
- * This is a template function to create EntityType object for EntityTypes Array.
195
- * Ensures correct visibility assignment based on referenced resources.
196
- *
197
- * @param { object } appConfig The configuration object.
198
- * @param { Array } packageIds The available package identifiers.
199
- * @param { object } entity The entity definition.
200
- * @returns { object } An object for the EntityType.
201
- */
202
- const createEntityTypeTemplate = (appConfig, packageIds, entity) => {
203
- if (entity.isODMMapping) {
204
- // ODM mappings are not created as entity types, they are only used in entityTypeMappings
205
- return [];
206
- }
207
- if (appConfig.hasSAPPolicyLevel) {
208
- // If SAP policy level is present, don't create entity type, they must be in the central repository
209
- return [];
210
- }
211
-
212
- const ordExtensions = readORDExtensions(entity);
213
- const visibility = ordExtensions.visibility || RESOURCE_VISIBILITY.public;
214
-
215
- if (visibility === RESOURCE_VISIBILITY.private) {
216
- return [];
217
- }
218
-
219
- const packageId = _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.entityType, visibility);
220
-
221
- return {
222
- ordId: entity.ordId,
223
- localId: entity.entityName,
224
- title: entity["@title"] ?? entity["@Common.Label"] ?? entity.entityName,
225
- shortDescription: SHORT_DESCRIPTION_PREFIX + entity.entityName,
226
- description: DESCRIPTION_PREFIX + entity.entityName,
227
- version: _getEntityVersion(entity),
228
- lastUpdate: appConfig.lastUpdate,
229
- visibility,
230
- partOfPackage: packageId,
231
- releaseStatus: "active",
232
- level: entity["@ObjectModel.compositionRoot"] || entity["@ODM.root"] ? LEVEL.rootEntity : LEVEL.subEntity,
233
- extensible: { supported: "no" },
234
- ...ordExtensions,
235
- };
236
- };
237
-
238
- /**
239
- * Determines the visibility of a resource based on provided extensions, definition, and default visibility.
240
- *
241
- * The function checks for custom visibility values, validates the default visibility,
242
- * and applies specific rules based on the resource's definition and extensions.
243
- *
244
- * @param {Object} ordExtensions - Extensions object containing resource metadata.
245
- * @param {Object} definition - The resource definition object.
246
- * @param {string} [defaultVisibility=RESOURCE_VISIBILITY.public] - The default visibility value.
247
- * @returns {string} The resolved visibility value for the resource.
248
- */
249
- function _handleVisibility(ordExtensions, definition, defaultVisibility = RESOURCE_VISIBILITY.public) {
250
- let visibility;
251
- //check for supported custom visibility value in defaultVisibility variable
252
- if (!ALLOWED_VISIBILITY.includes(defaultVisibility)) {
253
- Logger.warn(
254
- "Default visibility",
255
- defaultVisibility,
256
- "is not supported. Using",
257
- RESOURCE_VISIBILITY.public,
258
- "as fallback.",
259
- );
260
- defaultVisibility = RESOURCE_VISIBILITY.public;
261
- }
262
- // Determine visibility
263
- if (isPrimaryDataProductService(definition)) {
264
- visibility = RESOURCE_VISIBILITY.internal;
265
- } else if (ordExtensions.visibility) {
266
- visibility = ordExtensions.visibility;
267
- } else if (definition[ORD_EXTENSIONS_PREFIX + "visibility"]) {
268
- visibility = definition[ORD_EXTENSIONS_PREFIX + "visibility"];
269
- } else if (SUPPORTED_IMPLEMENTATIONSTANDARD_VERSIONS.includes(ordExtensions.implementationStandard)) {
270
- // if the implementationStandard is for example sap:ord-document-api:v1, it should be public by default
271
- visibility = RESOURCE_VISIBILITY.public;
272
- } else if (ALLOWED_VISIBILITY.includes(defaultVisibility)) {
273
- // Default visibility from config file
274
- visibility = defaultVisibility;
275
- }
276
- return visibility;
277
- }
278
-
279
- /**
280
- * This is a template function to create API Resource object for API Resource Array.
281
- * Properties of an API resource can be overwritten by the ORD extensions. Example: visibility.
282
- * Ensures proper visibility compliance by checking associated EntityTypes.
283
- * @param {string} serviceName The name of the service.
284
- * @param {object} serviceDefinition The definition of the service
285
- * @param {object} appConfig - The application configuration.
286
- * @param {Array} packageIds - The available package identifiers.
287
- * @param {Array} accessStrategies The array of accessStrategies objects
288
- * @returns {Array} An array of objects for the API Resources.
289
- */
290
- const createAPIResourceTemplate = (serviceName, serviceDefinition, appConfig, packageIds, accessStrategies) => {
291
- const ordExtensions = readORDExtensions(serviceDefinition);
292
- const visibility = _handleVisibility(ordExtensions, serviceDefinition, appConfig.env?.defaultVisibility);
293
- const packageId = _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.api, visibility);
294
-
295
- const protocolResults = resolveApiResourceProtocol(serviceName, serviceDefinition, {
296
- isPrimaryDataProduct: isPrimaryDataProductService,
297
- });
298
- const apiResources = [];
299
-
300
- // If no protocols were generated, skip this service
301
- if (protocolResults.length === 0) {
302
- Logger.info(`No supported protocols for service '${serviceName}', skipping API resource generation.`);
303
- return apiResources;
304
- }
305
-
306
- // Handle version suffix extraction for primary data product services
307
- let cleanServiceName,
308
- version,
309
- semanticVersion,
310
- extracted = null;
311
- if (isPrimaryDataProductService(serviceDefinition)) {
312
- extracted = _extractVersionFromServiceName(serviceDefinition.name);
313
- if (extracted) {
314
- // Create a temporary service definition with the clean name for namespace processing
315
- const versionExtractedServiceDefinition = { ...serviceDefinition, name: extracted.cleanName };
316
- cleanServiceName = _getCleanServiceName(versionExtractedServiceDefinition, appConfig);
317
- version = extracted.version;
318
- semanticVersion = extracted.semanticVersion;
319
- } else {
320
- // Invalid pattern - use current behavior
321
- cleanServiceName = _getCleanServiceName(serviceDefinition, appConfig);
322
- version = "v1";
323
- semanticVersion = "1.0.0";
324
- }
325
- } else {
326
- // Non-data product - use current behavior
327
- cleanServiceName = _getCleanServiceName(serviceDefinition, appConfig);
328
- version = "v1";
329
- semanticVersion = "1.0.0";
330
- }
331
-
332
- const ordId = `${appConfig.ordNamespace}:apiResource:${cleanServiceName}:${version}`;
333
-
334
- protocolResults.forEach((protocolResult) => {
335
- const { apiProtocol, entryPoints, hasResourceDefinitions } = protocolResult;
336
-
337
- // Build resource definitions based on protocol
338
- let resourceDefinitions = [];
339
- if (hasResourceDefinitions) {
340
- if (apiProtocol === ORD_API_PROTOCOL.SAP_DATA_SUBSCRIPTION) {
341
- // Data product services use CSN
342
- resourceDefinitions = [
343
- _getResourceDefinition(
344
- "sap-csn-interop-effective-v1",
345
- "json",
346
- ordId,
347
- serviceName,
348
- "csn.json",
349
- accessStrategies,
350
- ),
351
- ];
352
- } else if (apiProtocol === ORD_API_PROTOCOL.REST) {
353
- // REST only has OpenAPI, no EDMX
354
- resourceDefinitions = [
355
- _getResourceDefinition("openapi-v3", "json", ordId, serviceName, "oas3.json", accessStrategies),
356
- ];
357
- } else if (apiProtocol === ORD_API_PROTOCOL.MCP) {
358
- resourceDefinitions = [
359
- _getResourceDefinition(
360
- MCP_RESOURCE_DEFINITION_TYPE,
361
- "json",
362
- ordId,
363
- serviceName,
364
- "mcp.json",
365
- accessStrategies,
366
- ),
367
- ];
368
- } else if (apiProtocol === ORD_API_PROTOCOL.GRAPHQL) {
369
- // GraphQL only has GraphQL SDL
370
- resourceDefinitions = [
371
- {
372
- type: "graphql-sdl",
373
- mediaType: "text/plain",
374
- url: `/ord/v1/${ordId}/${serviceName}.graphql`,
375
- accessStrategies: ensureAccessStrategies(accessStrategies, {
376
- resourceName: `${serviceName} (graphql-sdl)`,
377
- }),
378
- },
379
- ];
380
- } else if (apiProtocol === ORD_API_PROTOCOL.ODATA_V2) {
381
- // openapi-v3 is not supported for OData V2, only EDMX
382
- resourceDefinitions = [
383
- _getResourceDefinition("edmx", "xml", ordId, serviceName, "edmx", accessStrategies),
384
- ];
385
- } else {
386
- // odata-v4 and others have both OpenAPI and EDMX
387
- resourceDefinitions = [
388
- _getResourceDefinition("openapi-v3", "json", ordId, serviceName, "oas3.json", accessStrategies),
389
- _getResourceDefinition("edmx", "xml", ordId, serviceName, "edmx", accessStrategies),
390
- ];
391
- }
392
- }
393
-
394
- const exposedEntityTypes = _getExposedEntityTypes(serviceDefinition);
395
-
396
- let obj = {
397
- ordId,
398
- title: serviceDefinition["@title"] ?? serviceDefinition["@Common.Label"] ?? serviceName,
399
- shortDescription: SHORT_DESCRIPTION_PREFIX + serviceName,
400
- description: serviceDefinition["@Core.Description"] ?? DESCRIPTION_PREFIX + serviceName,
401
- version: semanticVersion,
402
- lastUpdate: appConfig.lastUpdate,
403
- visibility,
404
- partOfPackage: packageId,
405
- partOfGroups: [_getGroupID(serviceDefinition, defaults.groupTypeId, appConfig)],
406
- releaseStatus: "active",
407
- apiProtocol,
408
- resourceDefinitions,
409
- entryPoints,
410
- extensible: {
411
- supported: "no",
412
- },
413
- ...(exposedEntityTypes ? { exposedEntityTypes } : []),
414
- ...ordExtensions,
415
- };
416
-
417
- // Special handling for data product services
418
- if (isPrimaryDataProductService(serviceDefinition)) {
419
- obj.direction = "outbound";
420
- if (extracted) {
421
- // Overwrite partOfGroups
422
- obj.partOfGroups = [`${defaults.groupTypeId}:${appConfig.ordNamespace}:${cleanServiceName}`];
423
- }
424
- }
425
-
426
- if (obj.visibility !== RESOURCE_VISIBILITY.private) {
427
- apiResources.push(obj);
428
- }
429
- });
430
-
431
- return apiResources;
432
- };
433
-
434
- /**
435
- * This is a template function to create Event Resource object for Event Resource Array.
436
- * There can be only one event resource per service because all events are using the same protocol, they are always Cloud Events.
437
- * Properties of an event resource can be overwritten by the ORD extensions. Example: visibility.
438
- * Ensures proper visibility compliance by checking associated EntityTypes.
439
- *
440
- * @param {string} serviceName The name of the service.
441
- * @param {object} serviceDefinition The definition of the service
442
- * @param {object} appConfig - The application configuration.
443
- * @param {Array} packageIds - The available package identifiers.
444
- * @param {Array} accessStrategies The array of accessStrategies objects
445
- * @returns {Array} An single-item array of objects for the Event Resources.
446
- */
447
- const createEventResourceTemplate = (serviceName, serviceDefinition, appConfig, packageIds, accessStrategies) => {
448
- const ordExtensions = readORDExtensions(serviceDefinition);
449
- const visibility = _handleVisibility(ordExtensions, serviceDefinition, appConfig.env?.defaultVisibility);
450
- const packageId = _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.event, visibility);
451
- const ordId = `${appConfig.ordNamespace}:eventResource:${_getCleanServiceName(serviceDefinition, appConfig)}:v1`;
452
- const exposedEntityTypes = _getExposedEntityTypes(serviceDefinition);
453
-
454
- let obj = {
455
- ordId,
456
- title:
457
- serviceDefinition["@title"] ??
458
- serviceDefinition["@Common.Label"] ??
459
- `ODM ${appConfig.appName.replace(/[^a-zA-Z0-9]/g, "")} Events`,
460
- shortDescription: `${serviceName} event resource`,
461
- description:
462
- serviceDefinition["@description"] ??
463
- serviceDefinition["@Core.Description"] ??
464
- "CAP Event resource describing events / messages.",
465
- version: "1.0.0",
466
- lastUpdate: appConfig.lastUpdate,
467
- releaseStatus: "active",
468
- partOfPackage: packageId,
469
- partOfGroups: [_getGroupID(serviceDefinition, defaults.groupTypeId, appConfig)],
470
- visibility,
471
- resourceDefinitions: [
472
- _getResourceDefinition("asyncapi-v2", "json", ordId, serviceName, "asyncapi2.json", accessStrategies),
473
- ],
474
- extensible: { supported: "no" },
475
- ...(exposedEntityTypes ? { exposedEntityTypes } : []),
476
- ...ordExtensions,
477
- };
478
-
479
- return obj.visibility === RESOURCE_VISIBILITY.public || obj.visibility === RESOURCE_VISIBILITY.internal
480
- ? [obj]
481
- : [];
482
- };
483
-
484
- function isPrimaryDataProductService(serviceDefinition) {
485
- return (
486
- serviceDefinition[DATA_PRODUCT_ANNOTATION] === DATA_PRODUCT_TYPE.primary ||
487
- !!serviceDefinition[DATA_PRODUCT_SIMPLE_ANNOTATION]
488
- );
489
- }
490
-
491
- function _getExposedEntityTypes(definitionObj) {
492
- if (!definitionObj.entities) {
493
- return;
494
- }
495
- const entities = Object.values(definitionObj.entities).flatMap((entity) => {
496
- const entityData = _flattenEntityGraph(entity).flatMap(createEntityTypeMappingsItemTemplate).filter(Boolean);
497
- return _.uniqBy(entityData, CONTENT_MERGE_KEY);
498
- });
499
- const exposedEntityTypes = _.uniqBy(entities, CONTENT_MERGE_KEY)
500
- .filter((entity) => entity !== undefined)
501
- .map(({ ordId }) => ({
502
- ordId,
503
- }));
504
-
505
- if (exposedEntityTypes.length > 0) {
506
- return exposedEntityTypes;
507
- }
508
- }
509
-
510
- function _flattenEntityGraph(currentEntity, processedEntities = []) {
511
- if (!currentEntity.associations) {
512
- return [currentEntity];
513
- }
514
- const entityAssociationTargets = Object.values(currentEntity.associations).map((association) => ({
515
- target: association.target,
516
- entity: association._target,
517
- }));
518
-
519
- const assertionsTodo = [];
520
- entityAssociationTargets.forEach(({ target, entity }) => {
521
- if (processedEntities.includes(target)) {
522
- return;
523
- }
524
- assertionsTodo.push(entity);
525
-
526
- /*
527
- the next line operates on heap memory so that the same entity is not processed again
528
- heap memory is used so that the check is the same in:
529
- a > b > c > b scenario (runs first)
530
- a > d > c > ... scenario (runs later and does not process c again)
531
- */
532
- processedEntities.push(target);
533
- });
534
-
535
- return [currentEntity, ...assertionsTodo.flatMap((entity) => _flattenEntityGraph(entity, processedEntities))];
536
- }
537
-
538
- /**
539
- * Extracts version suffix from service name for data product services.
540
- * Only accepts pattern: .v<number> (e.g., .v0, .v1, .v2, .v10)
541
- * Rejects patterns like: .v1.1, .v1.0, .version1, .beta
542
- *
543
- * @param {string} serviceName The full service name
544
- * @returns {Object|null} Object with cleanName, version, and semanticVersion, or null if invalid pattern
545
- */
546
- function _extractVersionFromServiceName(serviceName) {
547
- // Only match pattern: .v<number> (where number is 1 or more digits)
548
- const versionPattern = /\.v(\d+)$/;
549
- const match = serviceName.match(versionPattern);
550
-
551
- if (!match) {
552
- return null; // No valid version suffix found
553
- }
554
-
555
- const versionNumber = parseInt(match[1], 10);
556
-
557
- return {
558
- cleanName: serviceName.replace(versionPattern, ""),
559
- version: `v${versionNumber}`,
560
- semanticVersion: `${versionNumber}.0.0`,
561
- };
562
- }
563
-
564
- function _getPackageID(namespace, packageIds, resourceType, visibility = RESOURCE_VISIBILITY.public) {
565
- if (!packageIds) return;
566
-
567
- if (resourceType) {
568
- return (
569
- packageIds.find((id) => {
570
- if (visibility === RESOURCE_VISIBILITY.public) {
571
- return id.includes(resourceType) && !id.includes("-internal") && !id.includes("-private");
572
- } else {
573
- return id.includes(`${resourceType}-${visibility}`);
574
- }
575
- }) || packageIds.find((id) => id.includes(namespace))
576
- );
577
- }
578
-
579
- return packageIds.find((id) => id.includes(`-${resourceType}-`)) || packageIds.find((id) => id.includes(namespace));
580
- }
581
-
582
- function _propagateORDVisibility(model) {
583
- for (const [name, def] of Object.entries(model.definitions)) {
584
- if (def.kind === CDS_ELEMENT_KIND.service && def[ORD_EXTENSIONS_PREFIX + "visibility"]) {
585
- const serviceName = name;
586
- const serviceVisibility = def[ORD_EXTENSIONS_PREFIX + "visibility"];
587
- for (const serviceChildrenDef of model.definitions) {
588
- if (
589
- serviceChildrenDef.name.startsWith(serviceName + ".") &&
590
- !serviceChildrenDef[ORD_EXTENSIONS_PREFIX + "visibility"]
591
- ) {
592
- serviceChildrenDef[ORD_EXTENSIONS_PREFIX + "visibility"] = serviceVisibility;
593
- }
594
- }
595
- }
596
- }
597
-
598
- return model;
599
- }
600
-
601
- module.exports = {
602
- createEntityTypeTemplate,
603
- createEntityTypeMappingsItemTemplate,
604
- createGroupsTemplateForService,
605
- createAPIResourceTemplate,
606
- createEventResourceTemplate,
607
- readORDExtensions,
608
- _getPackageID,
609
- _getExposedEntityTypes,
610
- _propagateORDVisibility,
611
- _handleVisibility,
612
- isPrimaryDataProductService,
613
- };