@cap-js/ord 1.2.0 → 1.3.1

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 CHANGED
@@ -2,20 +2,29 @@ const cds = require("@sap/cds");
2
2
  const defaults = require("./defaults");
3
3
  const _ = require("lodash");
4
4
  const {
5
+ AUTHENTICATION_TYPE,
6
+ DATA_PRODUCT_ANNOTATION,
7
+ DATA_PRODUCT_TYPE,
5
8
  DESCRIPTION_PREFIX,
9
+ ENTITY_RELATIONSHIP_ANNOTATION,
10
+ LEVEL,
6
11
  ORD_EXTENSIONS_PREFIX,
12
+ ORD_ODM_ENTITY_NAME_ANNOTATION,
7
13
  ORD_RESOURCE_TYPE,
8
14
  RESOURCE_VISIBILITY,
9
- SHORT_DESCRIPTION_PREFIX
15
+ SEM_VERSION_REGEX,
16
+ SHORT_DESCRIPTION_PREFIX,
17
+ CONTENT_MERGE_KEY,
18
+ CDS_ELEMENT_KIND,
10
19
  } = require("./constants");
11
20
  const { Logger } = require("./logger");
12
21
 
13
22
  function unflatten(flattedObject) {
14
- let result = {}
23
+ let result = {};
15
24
  _.keys(flattedObject).forEach(function (key) {
16
- _.set(result, key, flattedObject[key])
17
- })
18
- return result
25
+ _.set(result, key, flattedObject[key]);
26
+ });
27
+ return result;
19
28
  }
20
29
 
21
30
  function readORDExtensions(model) {
@@ -36,7 +45,6 @@ function readORDExtensions(model) {
36
45
  * @param {Object} srvDefinition The service definition object.
37
46
  * @returns {Array} An array containing paths and it's kind.
38
47
  */
39
-
40
48
  const _generatePaths = (srv, srvDefinition) => {
41
49
  const srvObj = { name: srv, definition: srvDefinition };
42
50
  const protocols = cds.service.protocols;
@@ -47,7 +55,7 @@ const _generatePaths = (srv, srvDefinition) => {
47
55
  //removing instances of graphql protocol from paths
48
56
  for (var index = paths.length - 1; index >= 0; index--) {
49
57
  if (paths[index].kind === "graphql") {
50
- Logger.warn('Graphql protocol is not supported.');
58
+ Logger.warn("Graphql protocol is not supported.");
51
59
  paths.splice(index, 1);
52
60
  }
53
61
  }
@@ -62,20 +70,32 @@ const _generatePaths = (srv, srvDefinition) => {
62
70
  };
63
71
 
64
72
  /**
65
- * This is a template function to create Entity Type object for Entity Type Array.
73
+ * This is a template function to create item of entityTypeMappings array.
66
74
  *
67
- * @param {string} entity The name of the entity.
68
- * @returns {Object} An object for the entity type.
75
+ * @param {string} entity The entity definition.
76
+ * @returns {Object} An entry of the entityTypeMappings array.
69
77
  */
70
- const createEntityTypeTemplate = (entity) => ({
71
- ordId: `sap.odm:entityType:${entity["@ODM.entityName"]}:v1`,
72
- });
73
-
74
- function _getGroupID(
75
- fullyQualifiedName,
76
- groupTypeId = defaults.groupTypeId,
77
- appConfig,
78
- ) {
78
+ const createEntityTypeMappingsItemTemplate = (entity) => {
79
+ if (entity[ORD_ODM_ENTITY_NAME_ANNOTATION]) {
80
+ return {
81
+ ordId: `sap.odm:entityType:${entity[ORD_ODM_ENTITY_NAME_ANNOTATION]}:v1`,
82
+ entityName: entity[ORD_ODM_ENTITY_NAME_ANNOTATION],
83
+ ...entity,
84
+ };
85
+ } else if (entity[ENTITY_RELATIONSHIP_ANNOTATION]) {
86
+ const ordIdParts = entity[ENTITY_RELATIONSHIP_ANNOTATION].split(":");
87
+ const namespace = ordIdParts[0];
88
+ const entityName = ordIdParts[1];
89
+ const version = ordIdParts[2] || "v1";
90
+ return {
91
+ ordId: `${namespace}:entityType:${entityName}:${version}`,
92
+ entityName,
93
+ ...entity,
94
+ };
95
+ }
96
+ };
97
+
98
+ function _getGroupID(fullyQualifiedName, groupTypeId = defaults.groupTypeId, appConfig) {
79
99
  return `${groupTypeId}:${appConfig.ordNamespace}:${fullyQualifiedName}`;
80
100
  }
81
101
 
@@ -95,6 +115,49 @@ function _getTitleFromServiceName(srv) {
95
115
  }
96
116
  }
97
117
 
118
+ /**
119
+ * This is a function to get the version of the entity,
120
+ * validate it and log if it is not a valid semantical version.
121
+ *
122
+ * @param {object} entity An entity object.
123
+ * @returns Version of the entity with '1.0.0' as fallback value.
124
+ */
125
+ function _getEntityVersion(entity) {
126
+ const entityVersion = entity.ordId.split(":").pop();
127
+ const version = entityVersion.replace("v", "") + ".0.0"; // TODO: version can be stated/overwritten by annotation
128
+ if (!SEM_VERSION_REGEX.test(version)) {
129
+ Logger.warn(`Entity version "${version}" is not a valid semantic version.`);
130
+ }
131
+ return version;
132
+ }
133
+
134
+ /**
135
+ * This is a function to create a resource definition object.
136
+ * @param {string} resourceType The type of the resource.
137
+ * @param {string} mediaType The media type of the resource.
138
+ * @param {string} ordId The ordId of the resource.
139
+ * @param {string} serviceName The name of the service.
140
+ * @param {string} fileExtension The file extension of the resource.
141
+ * @param {Array} accessStrategies The array of accessStrategies objects
142
+ * @returns {Object} A resource definition object.
143
+ * @private
144
+ */
145
+ function _getResourceDefinition(
146
+ resourceType,
147
+ mediaType,
148
+ ordId,
149
+ serviceName,
150
+ fileExtension,
151
+ accessStrategies = [{ type: AUTHENTICATION_TYPE.Open }],
152
+ ) {
153
+ return {
154
+ type: resourceType,
155
+ mediaType: `application/${mediaType}`,
156
+ url: `/ord/v1/${ordId}/${serviceName}.${fileExtension}`,
157
+ accessStrategies,
158
+ };
159
+ }
160
+
98
161
  /**
99
162
  * This is a template function to create group object of a service for groups array in ORD doc.
100
163
  *
@@ -107,79 +170,144 @@ const createGroupsTemplateForService = (serviceName, serviceDefinition, appConfi
107
170
  const ordExtensions = readORDExtensions(serviceDefinition);
108
171
 
109
172
  if (!serviceDefinition) {
110
- Logger.warn('Unable to find service definition:', serviceName)
111
- return undefined
173
+ Logger.warn("Unable to find service definition:", serviceName);
174
+ return undefined;
112
175
  }
113
176
 
114
177
  const groupId = _getGroupID(serviceName, defaults.groupTypeId, appConfig);
115
178
  return {
116
179
  groupId: groupId,
117
180
  groupTypeId: defaults.groupTypeId,
118
- title: ordExtensions.title ?? _getTitleFromServiceName(serviceName)
181
+ title: ordExtensions.title ?? _getTitleFromServiceName(serviceName),
182
+ };
183
+ };
184
+
185
+ /**
186
+ * This is a template function to create EntityType object for EntityTypes Array.
187
+ * Ensures correct visibility assignment based on referenced resources.
188
+ *
189
+ * @param { object } appConfig The configuration object.
190
+ * @param { Array } packageIds The available package identifiers.
191
+ * @param { object } entity The entity definition.
192
+ * @returns { object } An object for the EntityType.
193
+ */
194
+ const createEntityTypeTemplate = (appConfig, packageIds, entity) => {
195
+ const ordExtensions = readORDExtensions(entity);
196
+ const visibility = ordExtensions.visibility || RESOURCE_VISIBILITY.public;
197
+
198
+ if (visibility === RESOURCE_VISIBILITY.private) {
199
+ return null;
200
+ }
201
+
202
+ const packageId = _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.entityType, visibility);
203
+
204
+ return {
205
+ ordId: entity.ordId,
206
+ localId: entity.entityName,
207
+ title: entity["@title"] ?? entity["@Common.Label"] ?? entity.entityName,
208
+ shortDescription: SHORT_DESCRIPTION_PREFIX + entity.entityName,
209
+ description: DESCRIPTION_PREFIX + entity.entityName,
210
+ version: _getEntityVersion(entity),
211
+ lastUpdate: appConfig.lastUpdate,
212
+ visibility,
213
+ partOfPackage: packageId,
214
+ releaseStatus: "active",
215
+ level: entity["@ObjectModel.compositionRoot"] || entity["@ODM.root"] ? LEVEL.rootEntity : LEVEL.subEntity,
216
+ extensible: { supported: "no" },
217
+ ...ordExtensions,
119
218
  };
219
+ };
220
+
221
+ function _handleVisibility(ordExtensions, definition) {
222
+ let visibility;
223
+ if (ordExtensions.visibility) {
224
+ visibility = ordExtensions.visibility;
225
+ } else if (definition[ORD_EXTENSIONS_PREFIX + "visibility"]) {
226
+ visibility = definition[ORD_EXTENSIONS_PREFIX + "visibility"];
227
+ } else {
228
+ visibility = RESOURCE_VISIBILITY.public;
229
+ }
230
+ return visibility;
120
231
  }
121
232
 
122
233
  /**
123
234
  * This is a template function to create API Resource object for API Resource Array.
124
235
  * Properties of an API resource can be overwritten by the ORD extensions. Example: visibility.
125
-
236
+ * Ensures proper visibility compliance by checking associated EntityTypes.
126
237
  * @param {string} serviceName The name of the service.
127
238
  * @param {object} serviceDefinition The definition of the service
239
+ * @param {object} appConfig - The application configuration.
240
+ * @param {Array} packageIds - The available package identifiers.
241
+ * @param {Array} accessStrategies The array of accessStrategies objects
128
242
  * @returns {Array} An array of objects for the API Resources.
129
243
  */
130
- const createAPIResourceTemplate = (serviceName, serviceDefinition, appConfig, packageIds) => {
244
+ const createAPIResourceTemplate = (serviceName, serviceDefinition, appConfig, packageIds, accessStrategies) => {
131
245
  const ordExtensions = readORDExtensions(serviceDefinition);
246
+ const visibility = _handleVisibility(ordExtensions, serviceDefinition);
247
+ const packageId = _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.api, visibility);
248
+
132
249
  const paths = _generatePaths(serviceName, serviceDefinition);
133
250
  const apiResources = [];
251
+ const ordId = `${appConfig.ordNamespace}:apiResource:${serviceName}:v1`;
134
252
 
135
253
  paths.forEach((generatedPath) => {
136
254
  let resourceDefinitions = [
137
- {
138
- type: "openapi-v3",
139
- mediaType: "application/json",
140
- url: `/.well-known/open-resource-discovery/v1/api-metadata/${serviceName}.oas3.json`,
141
- accessStrategies: [{ type: "open" }],
142
- },
255
+ _getResourceDefinition("openapi-v3", "json", ordId, serviceName, "oas3.json", accessStrategies),
143
256
  ];
144
257
 
145
258
  if (generatedPath.kind !== "rest") {
146
259
  //edmx resource definition is not generated in case of 'rest' protocol
147
- resourceDefinitions.push({
148
- type: "edmx",
149
- mediaType: "application/xml",
150
- url: `/.well-known/open-resource-discovery/v1/api-metadata/${serviceName}.edmx`,
151
- accessStrategies: [{ type: "open" }],
152
- });
260
+ resourceDefinitions.push(
261
+ _getResourceDefinition("edmx", "xml", ordId, serviceName, "edmx", accessStrategies),
262
+ );
153
263
  }
154
264
 
265
+ const entityTypeMappings = _getEntityTypeMappings(serviceDefinition);
266
+
155
267
  let obj = {
156
- ordId: `${appConfig.ordNamespace}:apiResource:${serviceName}:v1`,
157
- title:
158
- serviceDefinition["@title"] ??
159
- serviceDefinition["@Common.Label"] ??
160
- serviceName,
268
+ ordId,
269
+ title: serviceDefinition["@title"] ?? serviceDefinition["@Common.Label"] ?? serviceName,
161
270
  shortDescription: SHORT_DESCRIPTION_PREFIX + serviceName,
162
- description:
163
- serviceDefinition["@Core.Description"] ??
164
- DESCRIPTION_PREFIX + serviceName,
271
+ description: serviceDefinition["@Core.Description"] ?? DESCRIPTION_PREFIX + serviceName,
165
272
  version: "1.0.0",
166
273
  lastUpdate: appConfig.lastUpdate,
167
- visibility: RESOURCE_VISIBILITY.public,
168
- partOfPackage: _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.api),
274
+ visibility,
275
+ partOfPackage: packageId,
169
276
  partOfGroups: [_getGroupID(serviceName, defaults.groupTypeId, appConfig)],
170
277
  releaseStatus: "active",
171
- apiProtocol:
172
- generatedPath.kind === "odata" ? "odata-v4" : generatedPath.kind,
278
+ apiProtocol: generatedPath.kind === "odata" ? "odata-v4" : generatedPath.kind,
173
279
  resourceDefinitions: resourceDefinitions,
174
280
  entryPoints: [generatedPath.path],
175
281
  extensible: {
176
282
  supported: "no",
177
283
  },
178
- entityTypeMappings: [{ entityTypeTargets: appConfig.odmEntity }],
284
+ ...(entityTypeMappings ? { entityTypeMappings } : {}),
179
285
  ...ordExtensions,
180
286
  };
181
287
 
182
- if (obj.visibility === RESOURCE_VISIBILITY.public) apiResources.push(obj);
288
+ if (serviceDefinition[DATA_PRODUCT_ANNOTATION] === DATA_PRODUCT_TYPE.primary) {
289
+ obj.apiProtocol = "rest";
290
+ obj.visibility = RESOURCE_VISIBILITY.internal;
291
+ obj.direction = "outbound";
292
+ obj.implementationStandard = "sap.dp:data-subscription-api:v1";
293
+ obj.entryPoints = [];
294
+ obj.resourceDefinitions = [
295
+ _getResourceDefinition(
296
+ "sap-csn-interop-effective-v1",
297
+ "json",
298
+ ordId,
299
+ serviceName,
300
+ "csn.json",
301
+ accessStrategies,
302
+ ),
303
+ ];
304
+
305
+ apiResources.push(obj);
306
+ }
307
+
308
+ if (obj.visibility !== RESOURCE_VISIBILITY.private) {
309
+ apiResources.push(obj);
310
+ }
183
311
  });
184
312
 
185
313
  return apiResources;
@@ -189,57 +317,136 @@ const createAPIResourceTemplate = (serviceName, serviceDefinition, appConfig, pa
189
317
  * This is a template function to create Event Resource object for Event Resource Array.
190
318
  * There can be only one event resource per service because all events are using the same protocol, they are always Cloud Events.
191
319
  * Properties of an event resource can be overwritten by the ORD extensions. Example: visibility.
320
+ * Ensures proper visibility compliance by checking associated EntityTypes.
192
321
  *
193
322
  * @param {string} serviceName The name of the service.
194
323
  * @param {object} serviceDefinition The definition of the service
324
+ * @param {object} appConfig - The application configuration.
325
+ * @param {Array} packageIds - The available package identifiers.
326
+ * @param {Array} accessStrategies The array of accessStrategies objects
195
327
  * @returns {Array} An single-item array of objects for the Event Resources.
196
328
  */
197
- const createEventResourceTemplate = (serviceName, serviceDefinition, appConfig, packageIds) => {
329
+ const createEventResourceTemplate = (serviceName, serviceDefinition, appConfig, packageIds, accessStrategies) => {
198
330
  const ordExtensions = readORDExtensions(serviceDefinition);
199
- if (!!ordExtensions.visibility && ordExtensions.visibility !== RESOURCE_VISIBILITY.public) return [];
200
- return [{
201
- ordId: `${appConfig.ordNamespace}:eventResource:${serviceName}:v1`,
331
+ const visibility = _handleVisibility(ordExtensions, serviceDefinition);
332
+ const packageId = _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.event, visibility);
333
+ const ordId = `${appConfig.ordNamespace}:eventResource:${serviceName}:v1`;
334
+ const entityTypeMappings = _getEntityTypeMappings(serviceDefinition);
335
+
336
+ let obj = {
337
+ ordId,
202
338
  title:
203
339
  serviceDefinition["@title"] ??
204
340
  serviceDefinition["@Common.Label"] ??
205
341
  `ODM ${appConfig.appName.replace(/[^a-zA-Z0-9]/g, "")} Events`,
206
342
  shortDescription: `${serviceName} event resource`,
207
343
  description:
208
- serviceDefinition['@description'] ?? serviceDefinition['@Core.Description'] ??
344
+ serviceDefinition["@description"] ??
345
+ serviceDefinition["@Core.Description"] ??
209
346
  "CAP Event resource describing events / messages.",
210
347
  version: "1.0.0",
211
348
  lastUpdate: appConfig.lastUpdate,
212
349
  releaseStatus: "active",
213
- partOfPackage: _getPackageID(appConfig.ordNamespace, packageIds, ORD_RESOURCE_TYPE.event),
350
+ partOfPackage: packageId,
214
351
  partOfGroups: [_getGroupID(serviceName, defaults.groupTypeId, appConfig)],
215
- visibility: RESOURCE_VISIBILITY.public,
352
+ visibility,
216
353
  resourceDefinitions: [
217
- {
218
- type: "asyncapi-v2",
219
- mediaType: "application/json",
220
- url: `/.well-known/open-resource-discovery/v1/api-metadata/${serviceName}.asyncapi2.json`,
221
- accessStrategies: [
222
- {
223
- type: "open",
224
- },
225
- ],
226
- },
354
+ _getResourceDefinition("asyncapi-v2", "json", ordId, serviceName, "asyncapi2.json", accessStrategies),
227
355
  ],
228
356
  extensible: { supported: "no" },
357
+ ...(entityTypeMappings ? { entityTypeMappings } : {}),
358
+ ...ordExtensions,
359
+ };
229
360
 
230
- ...ordExtensions
231
- }]
361
+ return obj.visibility === RESOURCE_VISIBILITY.public || obj.visibility === RESOURCE_VISIBILITY.internal
362
+ ? [obj]
363
+ : [];
232
364
  };
233
365
 
234
- function _getPackageID(namespace, packageIds, resourceType) {
366
+ function _getEntityTypeMappings(definitionObj) {
367
+ if (!definitionObj.entities) {
368
+ return;
369
+ }
370
+ const entities = Object.values(definitionObj.entities)
371
+ .flatMap((entity) => _flattenEntityGraph(entity))
372
+ .map(createEntityTypeMappingsItemTemplate);
373
+ const entityTypeTargets = _.uniqBy(entities, CONTENT_MERGE_KEY)
374
+ .filter((entity) => entity !== undefined)
375
+ .map(({ ordId }) => ({
376
+ ordId,
377
+ }));
378
+ if (entityTypeTargets.length > 0) {
379
+ return [{ entityTypeTargets }];
380
+ } else {
381
+ return;
382
+ }
383
+ }
384
+
385
+ function _flattenEntityGraph(currentEntity, processedEntities = []) {
386
+ if (!currentEntity.associations) {
387
+ return [currentEntity];
388
+ }
389
+ const entityAssociationTargets = Object.values(currentEntity.associations).map((association) => ({
390
+ target: association.target,
391
+ entity: association._target,
392
+ }));
393
+
394
+ const assertionsTodo = [];
395
+ entityAssociationTargets.forEach(({ target, entity }) => {
396
+ if (processedEntities.includes(target)) {
397
+ return;
398
+ }
399
+ processedEntities = [...processedEntities, target];
400
+ assertionsTodo.push(entity);
401
+ });
402
+
403
+ return [currentEntity, ...assertionsTodo.flatMap((entity) => _flattenEntityGraph(entity, processedEntities))];
404
+ }
405
+
406
+ function _getPackageID(namespace, packageIds, resourceType, visibility = RESOURCE_VISIBILITY.public) {
235
407
  if (!packageIds) return;
236
408
 
237
- return packageIds.find((id) => id.includes("-" + resourceType)) || packageIds.find((id) => id.includes(namespace));
409
+ if (resourceType) {
410
+ return (
411
+ packageIds.find((id) => {
412
+ if (visibility === RESOURCE_VISIBILITY.public) {
413
+ return id.includes(resourceType) && !id.includes("-internal") && !id.includes("-private");
414
+ } else {
415
+ return id.includes(`${resourceType}-${visibility}`);
416
+ }
417
+ }) || packageIds.find((id) => id.includes(namespace))
418
+ );
419
+ }
420
+
421
+ return packageIds.find((id) => id.includes(`-${resourceType}-`)) || packageIds.find((id) => id.includes(namespace));
422
+ }
423
+
424
+ function _propagateORDVisibility(model) {
425
+ for (const [name, def] of Object.entries(model.definitions)) {
426
+ if (def.kind === CDS_ELEMENT_KIND.service && def[ORD_EXTENSIONS_PREFIX + "visibility"]) {
427
+ const serviceName = name;
428
+ const serviceVisibility = def[ORD_EXTENSIONS_PREFIX + "visibility"];
429
+ for (const serviceChildrenDef of model.definitions) {
430
+ if (
431
+ serviceChildrenDef.name.startsWith(serviceName + ".") &&
432
+ !serviceChildrenDef[ORD_EXTENSIONS_PREFIX + "visibility"]
433
+ ) {
434
+ serviceChildrenDef[ORD_EXTENSIONS_PREFIX + "visibility"] = serviceVisibility;
435
+ }
436
+ }
437
+ }
438
+ }
439
+
440
+ return model;
238
441
  }
239
442
 
240
443
  module.exports = {
241
444
  createEntityTypeTemplate,
445
+ createEntityTypeMappingsItemTemplate,
242
446
  createGroupsTemplateForService,
243
447
  createAPIResourceTemplate,
244
448
  createEventResourceTemplate,
449
+ _getPackageID,
450
+ _getEntityTypeMappings,
451
+ _propagateORDVisibility,
245
452
  };
package/package.json CHANGED
@@ -1,13 +1,17 @@
1
1
  {
2
2
  "name": "@cap-js/ord",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "CAP Plugin for generating ORD document.",
5
5
  "repository": "cap-js/ord",
6
6
  "author": "SAP SE (https://www.sap.com)",
7
7
  "homepage": "https://cap.cloud.sap/",
8
- "license": "SEE LICENSE IN LICENSE",
8
+ "license": "Apache-2.0",
9
+ "workspaces": [
10
+ "xmpl"
11
+ ],
9
12
  "main": "cds-plugin.js",
10
13
  "files": [
14
+ "cds-plugin.js",
11
15
  "lib",
12
16
  "data",
13
17
  "LICENSES"
@@ -20,15 +24,24 @@
20
24
  },
21
25
  "devDependencies": {
22
26
  "eslint": "^8",
23
- "jest": "^29.7.0"
27
+ "jest": "^29.7.0",
28
+ "prettier": "3.5.3"
24
29
  },
25
30
  "peerDependencies": {
26
- "@cap-js/asyncapi": "^1.0.0",
27
- "@cap-js/openapi": "^1.0.2",
28
- "@sap/cds": "^8.1.1",
29
- "@sap/cds-compiler": "5.0.6"
31
+ "@sap/cds": ">=9",
32
+ "@sap/cds-dk": ">=9"
30
33
  },
31
34
  "dependencies": {
35
+ "@cap-js/asyncapi": "^1.0.3",
36
+ "@cap-js/openapi": "^1.2.1",
37
+ "bcrypt": "^5.1.1",
32
38
  "lodash": "^4.17.21"
39
+ },
40
+ "cds": {
41
+ "requires": {
42
+ "SAP ORD Service": {
43
+ "model": "@cap-js/ord/lib/ord-service"
44
+ }
45
+ }
33
46
  }
34
- }
47
+ }
package/lib/plugin.js DELETED
@@ -1,33 +0,0 @@
1
- const cds = require("@sap/cds");
2
- const { Logger } = require("./logger");
3
- const { ord, getMetadata, defaults } = require("./");
4
-
5
-
6
- cds.on("bootstrap", (app) => {
7
- app.use("/.well-known/open-resource-discovery", async (req, res) => {
8
- if (req.url === "/") {
9
- res.status(200).send(defaults.baseTemplate);
10
- } else {
11
- try {
12
- const { contentType, response } = await getMetadata(req.url);
13
- res.status(200).contentType(contentType).send(response);
14
- } catch (error) {
15
- Logger.error(error, 'Error while generating metadata');
16
- res.status(500).send(error.message);
17
- }
18
- }
19
- });
20
-
21
- app.get("/open-resource-discovery/v1/documents/1", async (req, res) => {
22
- try {
23
- const csn = await cds.load(cds.env.folders.srv);
24
- const data = ord(csn);
25
- return res.status(200).send(data);
26
- } catch (error) {
27
- Logger.error(error, 'Error while creating ORD document');
28
- return res.status(500).send(error.message);
29
- }
30
- });
31
- });
32
-
33
- module.exports = cds.server;