@sap/cds-dk 6.0.4 → 6.1.3
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 +60 -1
- package/bin/add.js +29 -16
- package/bin/compile/index.js +7 -2
- package/bin/fix-redirects.js +4 -2
- package/bin/init.js +5 -0
- package/bin/login.js +20 -4
- package/bin/pull.js +58 -0
- package/bin/push.js +52 -0
- package/bin/subscribe.js +45 -0
- package/lib/bind/bindingUtil.js +1 -2
- package/lib/cds.js +2 -3
- package/lib/client/activate.js +17 -16
- package/lib/client/auth_manager.js +10 -5
- package/lib/client/base_command.js +4 -6
- package/lib/client/extend.js +3 -2
- package/lib/client/helper/cf_helper.js +1 -0
- package/lib/client/helper/errors.js +11 -0
- package/lib/client/helper/logging.js +3 -10
- package/lib/client/helper/url_helper.js +7 -3
- package/lib/client/index.js +1 -1
- package/lib/client/params.js +9 -6
- package/lib/client/pull.js +48 -0
- package/lib/client/push.js +45 -0
- package/lib/client/settings_manager.js +81 -27
- package/lib/compile/openapi/csdl2openapi.js +135 -163
- package/lib/compile/openapi/index.js +0 -1
- package/lib/import/common.js +9 -1
- package/lib/import/odata/metadataconverter/MetadataConverter.js +17 -4
- package/lib/import/odata/v2parser.js +50 -26
- package/lib/import/odata/v4parser.js +110 -29
- package/lib/import/openapi/importOpenAPI.js +3 -3
- package/lib/init/constants.js +9 -3
- package/lib/init/template/_merging/registry-mta.js +284 -0
- package/lib/init/template/approuter/files/xs-app.json.hbs +7 -7
- package/lib/init/template/approuter/index.js +22 -32
- package/lib/init/template/auditlog/index.js +7 -9
- package/lib/init/template/data/index.js +2 -4
- package/lib/init/template/extensibility/files/cds.package.json +7 -0
- package/lib/init/template/extensibility/files/cds.package.json.hbs +9 -0
- package/lib/init/template/extensibility/files/xs-security.json.hbs +26 -0
- package/lib/init/template/extensibility/index.js +48 -0
- package/lib/init/template/hana/files/java/cdsrc.json.hbs +1 -1
- package/lib/init/template/hana/files/java/profile.cdsrc.json.hbs +2 -2
- package/lib/init/template/hana/files/mta.yaml.hbs +10 -0
- package/lib/init/template/hana/files/nodejs/cds.package.json.hbs +1 -1
- package/lib/init/template/hana/files/nodejs/cds.profile.package.json.hbs +2 -2
- package/lib/init/template/hana/index.js +74 -61
- package/lib/init/template/kibana-logging/index.js +31 -37
- package/lib/init/template/lint/files/.eslint/rules/no-entity-moo.js +14 -14
- package/lib/init/template/mta/files/mta.yaml.hbs +1 -1
- package/lib/init/template/mta/index.js +13 -7
- package/lib/init/template/mtx/index.js +2 -142
- package/lib/init/template/multitenancy/files/cds.package.json +7 -0
- package/lib/init/template/multitenancy/files/cds.package.json.hbs +9 -0
- package/lib/init/template/{mtx → multitenancy}/files/dependencies.package.json +1 -1
- package/lib/init/template/multitenancy/files/java/.cdsrc.json +19 -0
- package/lib/init/template/multitenancy/files/java/package.json +31 -0
- package/lib/init/template/{mtx → multitenancy}/files/mta.yaml.hbs +13 -6
- package/lib/init/template/multitenancy/files/xs-security.json.hbs +18 -0
- package/lib/init/template/multitenancy/index.js +109 -0
- package/lib/init/template/nodejs/files/package.json.hbs +4 -1
- package/lib/init/template/templateBase.js +2 -1
- package/lib/init/template/toggles/files/cds.package.json +7 -0
- package/lib/init/template/toggles/files/cds.package.json.hbs +9 -0
- package/lib/init/template/toggles/index.js +24 -0
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +10 -0
- package/lib/init/template/xsuaa/index.js +44 -33
- package/lib/init/util/projectReader.js +12 -7
- package/lib/init/util/templateUtil.js +113 -111
- package/lib/k8s/ChartAdder.js +13 -3
- package/lib/k8s/ChartBuilder.js +6 -0
- package/lib/k8s/buildModel.js +1 -3
- package/lib/k8s/connectivity/index.js +5 -5
- package/lib/k8s/deployment/index.js +2 -4
- package/lib/k8s/deployment/subchart/Chart.yaml +1 -1
- package/lib/k8s/deployment/subchart/templates/_helpers.tpl +22 -11
- package/lib/k8s/deployment/subchart/templates/deployment.yaml +12 -5
- package/lib/k8s/deployment/subchart/templates/network-policy.yaml +3 -1
- package/lib/k8s/deployment/subchart/templates/pod-disruption-budget.yaml +1 -1
- package/lib/k8s/deployment/subchart/values.md +812 -0
- package/lib/k8s/deployment/subchart/values.schema.json +125 -30
- package/lib/k8s/deployment/subchart/values.yaml +7 -3
- package/lib/k8s/hana-deployer/index.js +10 -0
- package/lib/k8s/hana-deployer/templates/hana-deployer-job.yaml +8 -0
- package/lib/k8s/html5-apps-deployer/index.js +10 -0
- package/lib/k8s/html5-apps-deployer/templates/html5-apps-deployer-job.yaml +8 -0
- package/lib/k8s/index.js +2 -2
- package/lib/k8s/resources/helm/chart/schemas/values.root.schema.json +11 -0
- package/lib/k8s/resources/helm/chart/schemas/values.schema.json +479 -0
- package/lib/k8s/resources/helm/chart/templates/_deployment_helpers.tpl +1 -159
- package/lib/k8s/resources/helm/chart/templates/_helpers.tpl +0 -33
- package/lib/k8s/resources/helm/chart/templates/_sapcp_helpers.tpl +1 -1
- package/lib/lint/Linter.js +155 -158
- package/lib/lint/io.js +12 -5
- package/npm-shrinkwrap.json +214 -74
- package/package.json +5 -4
- package/lib/init/template/_merging/existences.js +0 -297
- package/lib/init/template/mtx/files/cds.package.json +0 -12
- package/lib/init/template/mtx/files/cds.package.json.hbs +0 -14
- package/lib/init/template/mtx/files/java/.cdsrc.json +0 -17
- package/lib/init/template/mtx/files/java/package.json +0 -43
- package/lib/init/template/mtx/files/java/server.js +0 -30
- package/lib/init/template/mtx/files/xs-security.json.hbs +0 -48
- package/lib/lint/.eslintrc.js +0 -3
|
@@ -7,10 +7,9 @@ var pluralize = require('pluralize')
|
|
|
7
7
|
//TODO
|
|
8
8
|
// - Core.Example for complex types
|
|
9
9
|
// - reduce number of loops over schemas
|
|
10
|
-
// - inject
|
|
10
|
+
// - inject $$name into each model element to make parameter passing easier?
|
|
11
11
|
// - allow passing additional files for referenced documents
|
|
12
12
|
// - delta: headers Prefer and Preference-Applied
|
|
13
|
-
// - response codes and descriptions - https://issues.oasis-open.org/browse/ODATA-884
|
|
14
13
|
// - inline definitions for Edm.* to make OpenAPI documents self-contained
|
|
15
14
|
// - both "clickable" and freestyle $expand, $select, $orderby - does not work yet, open issue for OpenAPI UI
|
|
16
15
|
// - system query options for actions/functions/imports depending on $Collection
|
|
@@ -21,6 +20,18 @@ var pluralize = require('pluralize')
|
|
|
21
20
|
// - InsertRestrictions/NonInsertableNavigationProperties
|
|
22
21
|
// - see //TODO comments below
|
|
23
22
|
|
|
23
|
+
const SUFFIX = {
|
|
24
|
+
read: "",
|
|
25
|
+
create: "-create",
|
|
26
|
+
update: "-update",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const TITLE_SUFFIX = {
|
|
30
|
+
"": "",
|
|
31
|
+
"-create": " (for create)",
|
|
32
|
+
"-update": " (for update)",
|
|
33
|
+
};
|
|
34
|
+
|
|
24
35
|
/**
|
|
25
36
|
* Construct an OpenAPI description from a CSDL document
|
|
26
37
|
* @param {object} csdl CSDL document
|
|
@@ -31,6 +42,7 @@ module.exports.csdl2openapi = function (
|
|
|
31
42
|
csdl,
|
|
32
43
|
{
|
|
33
44
|
url: serviceRoot,
|
|
45
|
+
servers: serversObject,
|
|
34
46
|
scheme: scheme = 'https',
|
|
35
47
|
host: host = 'localhost',
|
|
36
48
|
basePath: basePath = '/service-root',
|
|
@@ -47,6 +59,8 @@ module.exports.csdl2openapi = function (
|
|
|
47
59
|
const namespace = { 'Edm': 'Edm' };
|
|
48
60
|
const namespaceUrl = {};
|
|
49
61
|
const voc = {};
|
|
62
|
+
const requiredSchemas = { list: [], used: {} };
|
|
63
|
+
|
|
50
64
|
preProcess(csdl, boundOverloads, derivedTypes, alias, namespace, namespaceUrl, voc);
|
|
51
65
|
|
|
52
66
|
const entityContainer = csdl.$EntityContainer ? modelElement(csdl.$EntityContainer) : {};
|
|
@@ -59,7 +73,7 @@ module.exports.csdl2openapi = function (
|
|
|
59
73
|
'x-sap-api-type': 'ODATAV4',
|
|
60
74
|
'x-odata-version': '4.0',
|
|
61
75
|
'x-sap-shortText': getShortText(csdl, entityContainer),
|
|
62
|
-
servers: getServers(serviceRoot),
|
|
76
|
+
servers: getServers(serviceRoot, serversObject),
|
|
63
77
|
tags: entityContainer ? getTags(entityContainer) : {},
|
|
64
78
|
paths: entityContainer ? getPaths(entityContainer) : {},
|
|
65
79
|
components: getComponents(csdl, entityContainer)
|
|
@@ -152,7 +166,7 @@ module.exports.csdl2openapi = function (
|
|
|
152
166
|
);
|
|
153
167
|
}
|
|
154
168
|
if (!element) {
|
|
155
|
-
|
|
169
|
+
console.warn(`Invalid annotation target '${target}'`);
|
|
156
170
|
} else if (Array.isArray(element)) {
|
|
157
171
|
//TODO: action or function:
|
|
158
172
|
//- loop over all overloads
|
|
@@ -165,7 +179,8 @@ module.exports.csdl2openapi = function (
|
|
|
165
179
|
case 2:
|
|
166
180
|
if (['Action', 'Function'].includes(element.$Kind)) {
|
|
167
181
|
if (segments[1] == '$ReturnType') {
|
|
168
|
-
|
|
182
|
+
if (element.$ReturnType)
|
|
183
|
+
Object.assign(element.$ReturnType, annotations);
|
|
169
184
|
} else {
|
|
170
185
|
const parameter = element.$Parameter.find(p => p.$Name == segments[1]);
|
|
171
186
|
Object.assign(parameter, annotations);
|
|
@@ -407,12 +422,27 @@ module.exports.csdl2openapi = function (
|
|
|
407
422
|
|
|
408
423
|
/**
|
|
409
424
|
* Construct an array of Server Objects
|
|
410
|
-
* @param {object}
|
|
411
|
-
* @param {object}
|
|
425
|
+
* @param {object} serviceRoot The service root
|
|
426
|
+
* @param {object} serversObject Input servers object
|
|
412
427
|
* @return {Array} The list of servers
|
|
413
428
|
*/
|
|
414
|
-
function getServers(serviceRoot) {
|
|
415
|
-
|
|
429
|
+
function getServers(serviceRoot, serversObject) {
|
|
430
|
+
let servers;
|
|
431
|
+
|
|
432
|
+
if (serversObject) {
|
|
433
|
+
try {
|
|
434
|
+
servers = JSON.parse(serversObject);
|
|
435
|
+
} catch (err) {
|
|
436
|
+
throw new Error(`The input server object is invalid.`);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if(!servers.length){
|
|
440
|
+
throw new Error(`The input server object should be an array.`);
|
|
441
|
+
}
|
|
442
|
+
} else {
|
|
443
|
+
servers = [{ url: serviceRoot }];
|
|
444
|
+
}
|
|
445
|
+
return servers;
|
|
416
446
|
}
|
|
417
447
|
|
|
418
448
|
/**
|
|
@@ -484,7 +514,7 @@ module.exports.csdl2openapi = function (
|
|
|
484
514
|
const nonExpandable = nonExpandableProperties(root, navigationPath);
|
|
485
515
|
|
|
486
516
|
paths[prefix] = pathItem;
|
|
487
|
-
if (prefixParameters.length > 0)
|
|
517
|
+
if (prefixParameters.length > 0) pathItem.parameters = prefixParameters;
|
|
488
518
|
|
|
489
519
|
operationRead(pathItem, element, name, sourceName, targetName, target, level, restrictions, false, nonExpandable);
|
|
490
520
|
if (element.$Collection && (element.$ContainsTarget || level < 2 && target)) {
|
|
@@ -505,6 +535,9 @@ module.exports.csdl2openapi = function (
|
|
|
505
535
|
pathItemsWithNavigation(paths, prefix, prefixParameters, type, root, sourceName, level, navigationPath);
|
|
506
536
|
}
|
|
507
537
|
}
|
|
538
|
+
|
|
539
|
+
if (Object.keys(pathItem).filter((i) => i !== "parameters").length === 0)
|
|
540
|
+
delete paths[prefix];
|
|
508
541
|
}
|
|
509
542
|
|
|
510
543
|
/**
|
|
@@ -568,6 +601,8 @@ module.exports.csdl2openapi = function (
|
|
|
568
601
|
operationRead(pathItem, element, name, sourceName, targetName, target, level, restrictions, true, nonExpandable);
|
|
569
602
|
operationUpdate(pathItem, element, name, sourceName, target, level, restrictions, true);
|
|
570
603
|
operationDelete(pathItem, element, name, sourceName, target, level, restrictions, true);
|
|
604
|
+
if (Object.keys(pathItem).filter((i) => i !== "parameters").length === 0)
|
|
605
|
+
delete paths[path];
|
|
571
606
|
|
|
572
607
|
pathItemsForBoundOperations(paths, path, parameters, element, sourceName, true);
|
|
573
608
|
pathItemsWithNavigation(paths, path, parameters, type, root, sourceName, level, navigationPath);
|
|
@@ -600,11 +635,11 @@ module.exports.csdl2openapi = function (
|
|
|
600
635
|
required: true,
|
|
601
636
|
content: {
|
|
602
637
|
'application/json': {
|
|
603
|
-
schema: ref(element.$Type,
|
|
638
|
+
schema: ref(element.$Type, SUFFIX.create),
|
|
604
639
|
}
|
|
605
640
|
}
|
|
606
641
|
},
|
|
607
|
-
responses: response(201, 'Created ' + lname, { $Type: element.$Type })
|
|
642
|
+
responses: response(201, 'Created ' + lname, { $Type: element.$Type }, insertRestrictions.ErrorResponses),
|
|
608
643
|
};
|
|
609
644
|
if (insertRestrictions.LongDescription) pathItem.post.description = insertRestrictions.LongDescription;
|
|
610
645
|
if (targetName && sourceName != targetName) pathItem.post.tags.push(targetName);
|
|
@@ -657,7 +692,7 @@ module.exports.csdl2openapi = function (
|
|
|
657
692
|
* @param {array} nonExpandable Non-expandable navigation properties
|
|
658
693
|
*/
|
|
659
694
|
function operationRead(pathItem, element, name, sourceName, targetName, target, level, restrictions, byKey, nonExpandable) {
|
|
660
|
-
const targetRestrictions = target
|
|
695
|
+
const targetRestrictions = target?.[voc.Capabilities.ReadRestrictions];
|
|
661
696
|
const readRestrictions = restrictions.ReadRestrictions || targetRestrictions || {};
|
|
662
697
|
const readByKeyRestrictions = readRestrictions.ReadByKeyRestrictions;
|
|
663
698
|
let readable = true;
|
|
@@ -675,7 +710,8 @@ module.exports.csdl2openapi = function (
|
|
|
675
710
|
summary: descriptions.Description || operationSummary('Retrieve', name, sourceName, level, element.$Collection, byKey),
|
|
676
711
|
tags: [sourceName],
|
|
677
712
|
parameters: [],
|
|
678
|
-
responses: response(200, 'Retrieved ' + (byKey ? pluralize.singular(lname) : lname), { $Type: element.$Type, $Collection: collection }
|
|
713
|
+
responses: response(200, 'Retrieved ' + (byKey ? pluralize.singular(lname) : lname), { $Type: element.$Type, $Collection: collection },
|
|
714
|
+
byKey ? readByKeyRestrictions?.ErrorResponses : readRestrictions?.ErrorResponses)
|
|
679
715
|
};
|
|
680
716
|
const deltaSupported = element[voc.Capabilities.ChangeTracking] && element[voc.Capabilities.ChangeTracking].Supported;
|
|
681
717
|
if (!byKey && deltaSupported) {
|
|
@@ -1125,11 +1161,11 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
1125
1161
|
required: true,
|
|
1126
1162
|
content: {
|
|
1127
1163
|
'application/json': {
|
|
1128
|
-
schema: ref(element.$Type,
|
|
1164
|
+
schema: ref(element.$Type, SUFFIX.update),
|
|
1129
1165
|
}
|
|
1130
1166
|
}
|
|
1131
1167
|
},
|
|
1132
|
-
responses: response(204,
|
|
1168
|
+
responses: response(204, "Success", undefined, updateRestrictions.ErrorResponses),
|
|
1133
1169
|
};
|
|
1134
1170
|
if (updateRestrictions.LongDescription) operation.description = updateRestrictions.LongDescription;
|
|
1135
1171
|
customParameters(operation, updateRestrictions);
|
|
@@ -1156,7 +1192,7 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
1156
1192
|
pathItem.delete = {
|
|
1157
1193
|
summary: deleteRestrictions.Description || operationSummary('Delete', name, sourceName, level, element.$Collection, byKey),
|
|
1158
1194
|
tags: [sourceName],
|
|
1159
|
-
responses: response(204,
|
|
1195
|
+
responses: response(204, "Success", undefined, deleteRestrictions.ErrorResponses),
|
|
1160
1196
|
};
|
|
1161
1197
|
if (deleteRestrictions.LongDescription) pathItem.delete.description = deleteRestrictions.LongDescription;
|
|
1162
1198
|
customParameters(pathItem.delete, deleteRestrictions);
|
|
@@ -1374,9 +1410,8 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
1374
1410
|
post: {
|
|
1375
1411
|
summary: actionImport[voc.Core.Description] || overload[voc.Core.Description] || 'Invoke action ' + name,
|
|
1376
1412
|
tags: [overload[voc.Common.Label] || sourceName || 'Service Operations'],
|
|
1377
|
-
responses: overload.$ReturnType
|
|
1378
|
-
|
|
1379
|
-
: response(204, 'Success')
|
|
1413
|
+
responses: overload.$ReturnType ? response(200, "Success", overload.$ReturnType, overload[voc.Capabilities.OperationRestrictions]?.ErrorResponses)
|
|
1414
|
+
: response(204, "Success", undefined, overload[voc.Capabilities.OperationRestrictions]?.ErrorResponses),
|
|
1380
1415
|
}
|
|
1381
1416
|
};
|
|
1382
1417
|
const description = actionImport[voc.Core.LongDescription] || overload[voc.Core.LongDescription];
|
|
@@ -1487,7 +1522,7 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
1487
1522
|
summary: functionImport[voc.Core.Description] || overload[voc.Core.Description] || 'Invoke function ' + name,
|
|
1488
1523
|
tags: [overload[voc.Common.Label] || sourceName || 'Service Operations'],
|
|
1489
1524
|
parameters: prefixParameters.concat(params),
|
|
1490
|
-
responses: response(200,
|
|
1525
|
+
responses: response(200, "Success", overload.$ReturnType, overload[voc.Capabilities.OperationRestrictions]?.ErrorResponses),
|
|
1491
1526
|
}
|
|
1492
1527
|
};
|
|
1493
1528
|
const iDescription = functionImport[voc.Core.LongDescription] || overload[voc.Core.LongDescription];
|
|
@@ -1561,8 +1596,9 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
1561
1596
|
* @param {string} code HTTP response code
|
|
1562
1597
|
* @param {string} description Description
|
|
1563
1598
|
* @param {object} type Response type object
|
|
1599
|
+
* @param {array} errors Array of operation-specific status codes with descriptions
|
|
1564
1600
|
*/
|
|
1565
|
-
|
|
1601
|
+
function response(code, description, type, errors) {
|
|
1566
1602
|
const r = {};
|
|
1567
1603
|
r[code] = {
|
|
1568
1604
|
description: description
|
|
@@ -1584,8 +1620,21 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
1584
1620
|
}
|
|
1585
1621
|
};
|
|
1586
1622
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1623
|
+
if (errors) {
|
|
1624
|
+
for (const e of errors) {
|
|
1625
|
+
r[e.StatusCode] = {
|
|
1626
|
+
description: e.Description,
|
|
1627
|
+
content: {
|
|
1628
|
+
"application/json": {
|
|
1629
|
+
schema: { $ref: "#/components/schemas/error" },
|
|
1630
|
+
},
|
|
1631
|
+
},
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
} else {
|
|
1635
|
+
r["4XX"] = {
|
|
1636
|
+
$ref: "#/components/responses/error",
|
|
1637
|
+
};
|
|
1589
1638
|
}
|
|
1590
1639
|
return r;
|
|
1591
1640
|
}
|
|
@@ -1626,34 +1675,37 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
1626
1675
|
* @return {object} Map of Schema Objects
|
|
1627
1676
|
*/
|
|
1628
1677
|
function getSchemas(csdl) {
|
|
1629
|
-
const
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
}
|
|
1678
|
+
const unordered = {};
|
|
1679
|
+
|
|
1680
|
+
for (const r of requiredSchemas.list) {
|
|
1681
|
+
const type = modelElement(`${r.namespace}.${r.name}`);
|
|
1682
|
+
if (!type) continue;
|
|
1683
|
+
switch (type.$Kind) {
|
|
1684
|
+
case "ComplexType":
|
|
1685
|
+
case "EntityType":
|
|
1686
|
+
schemasForStructuredType(unordered, r.namespace, r.name, type, r.suffix);
|
|
1687
|
+
break;
|
|
1688
|
+
case "EnumType":
|
|
1689
|
+
schemaForEnumerationType(unordered, r.namespace, r.name, type);
|
|
1690
|
+
break;
|
|
1691
|
+
case "TypeDefinition":
|
|
1692
|
+
schemaForTypeDefinition(unordered, r.namespace, r.name, type);
|
|
1693
|
+
break;
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
const ordered = {};
|
|
1697
|
+
for (const name of Object.keys(unordered).sort()) {
|
|
1698
|
+
ordered[name] = unordered[name];
|
|
1699
|
+
}
|
|
1648
1700
|
|
|
1649
|
-
inlineTypes(
|
|
1701
|
+
inlineTypes(ordered);
|
|
1650
1702
|
|
|
1651
1703
|
if (csdl.$EntityContainer) {
|
|
1652
|
-
|
|
1653
|
-
|
|
1704
|
+
ordered.count = count();
|
|
1705
|
+
ordered.error = error();
|
|
1654
1706
|
}
|
|
1655
1707
|
|
|
1656
|
-
return
|
|
1708
|
+
return ordered;
|
|
1657
1709
|
}
|
|
1658
1710
|
|
|
1659
1711
|
/**
|
|
@@ -1729,87 +1781,66 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
1729
1781
|
* @param {object} schemas Map of Schema Objects to augment
|
|
1730
1782
|
* @param {string} qualifier Qualifier for structured type
|
|
1731
1783
|
* @param {string} name Simple name of structured type
|
|
1784
|
+
* @param {string} suffix Suffix for read/create/update
|
|
1732
1785
|
* @param {object} type Structured type
|
|
1733
1786
|
* @return {object} Map of Schemas Objects
|
|
1734
1787
|
*/
|
|
1735
|
-
|
|
1736
|
-
const
|
|
1737
|
-
const
|
|
1738
|
-
const updName = allName + '-update';
|
|
1788
|
+
function schemasForStructuredType(schemas, qualifier, name, type, suffix) {
|
|
1789
|
+
const schemaName = qualifier + "." + name + suffix;
|
|
1790
|
+
const baseName = qualifier + "." + name;
|
|
1739
1791
|
const isKey = keyMap(type);
|
|
1740
1792
|
const required = Object.keys(isKey);
|
|
1741
|
-
const
|
|
1742
|
-
const creProperties = {};
|
|
1743
|
-
const updProperties = {};
|
|
1793
|
+
const schemaProperties = {};
|
|
1744
1794
|
|
|
1745
1795
|
const properties = propertiesOfStructuredType(type);
|
|
1746
1796
|
Object.keys(properties).forEach(iName => {
|
|
1747
1797
|
const property = properties[iName];
|
|
1748
|
-
|
|
1749
|
-
if
|
|
1750
|
-
required.push(iName)
|
|
1751
|
-
}
|
|
1798
|
+
if (suffix === SUFFIX.read) schemaProperties[iName] = getSchema(property);
|
|
1799
|
+
if((Object.prototype.hasOwnProperty.call(property, '@Common.FieldControl')) && property['@Common.FieldControl'] === 'Mandatory')
|
|
1800
|
+
{ required.push(iName) }
|
|
1752
1801
|
if (property.$Kind == 'NavigationProperty') {
|
|
1753
|
-
if (property.$Collection) {
|
|
1754
|
-
|
|
1802
|
+
if (property.$Collection && suffix === "") {
|
|
1803
|
+
schemaProperties[`${iName}@${csdl.$Version === '4.0' ? 'odata.' : ''}count`] = ref('count');
|
|
1755
1804
|
}
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1805
|
+
if (suffix === SUFFIX.create)
|
|
1806
|
+
schemaProperties[iName] = getSchema(property, SUFFIX.create);
|
|
1807
|
+
if (suffix === SUFFIX.update && deepUpdate)
|
|
1808
|
+
schemaProperties[iName] = getSchema(property, SUFFIX.create);
|
|
1759
1809
|
} else {
|
|
1760
|
-
if (property[voc.Core.Permissions]
|
|
1810
|
+
if (property[voc.Core.Permissions] != "Read" && !property[voc.Core.Computed] && property.$ContainsTarget) {
|
|
1761
1811
|
let index = required.indexOf(iName);
|
|
1762
1812
|
if (index != -1) required.splice(index, 1);
|
|
1763
1813
|
} else {
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1814
|
+
if (suffix === SUFFIX.create)
|
|
1815
|
+
schemaProperties[iName] = getSchema(property, SUFFIX.create);
|
|
1816
|
+
if (suffix === SUFFIX.update && !isKey[iName] && !property[voc.Core.Immutable])
|
|
1817
|
+
schemaProperties[iName] = getSchema(property, SUFFIX.update);
|
|
1767
1818
|
}
|
|
1768
1819
|
}
|
|
1769
1820
|
});
|
|
1770
1821
|
|
|
1771
|
-
const title = name;
|
|
1772
1822
|
|
|
1773
|
-
schemas[
|
|
1774
|
-
title:
|
|
1823
|
+
schemas[schemaName] = {
|
|
1824
|
+
title: (type[voc.Core.Description] || name) + TITLE_SUFFIX[suffix],
|
|
1775
1825
|
type: 'object'
|
|
1776
1826
|
};
|
|
1777
|
-
if (Object.keys(
|
|
1827
|
+
if (Object.keys(schemaProperties).length > 0)
|
|
1828
|
+
schemas[schemaName].properties = schemaProperties;
|
|
1778
1829
|
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
type: 'object',
|
|
1782
|
-
};
|
|
1783
|
-
if (Object.keys(creProperties).length > 0) schemas[creName].properties = creProperties;
|
|
1784
|
-
if (required.length > 0) schemas[creName].required = required;
|
|
1785
|
-
|
|
1786
|
-
schemas[updName] = {
|
|
1787
|
-
title: title + ' (for update)',
|
|
1788
|
-
type: 'object'
|
|
1789
|
-
};
|
|
1790
|
-
if (Object.keys(updProperties).length > 0) schemas[updName].properties = updProperties;
|
|
1830
|
+
if (suffix === SUFFIX.create && required.length > 0)
|
|
1831
|
+
schemas[schemaName].required = required;
|
|
1791
1832
|
|
|
1792
1833
|
const description = type[voc.Core.Description];
|
|
1793
1834
|
if (description) {
|
|
1794
|
-
schemas[
|
|
1795
|
-
schemas[creName].description = description;
|
|
1796
|
-
schemas[updName].description = description;
|
|
1835
|
+
schemas[schemaName].description = description;
|
|
1797
1836
|
}
|
|
1798
1837
|
|
|
1799
|
-
if (derivedTypes[
|
|
1800
|
-
schemas[
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
derivedTypes[allName].forEach(derivedType => {
|
|
1804
|
-
schemas[allName].anyOf.push(ref(derivedType));
|
|
1805
|
-
schemas[creName].anyOf.push(ref(derivedType, '-create'));
|
|
1806
|
-
schemas[updName].anyOf.push(ref(derivedType, '-update'));
|
|
1838
|
+
if (derivedTypes[baseName]) {
|
|
1839
|
+
schemas[schemaName].anyOf = [];
|
|
1840
|
+
derivedTypes[baseName].forEach((derivedType) => {
|
|
1841
|
+
schemas[schemaName].anyOf.push(ref(derivedType, suffix));
|
|
1807
1842
|
});
|
|
1808
|
-
if (!type.$Abstract) {
|
|
1809
|
-
schemas[allName].anyOf.push({});
|
|
1810
|
-
schemas[creName].anyOf.push({});
|
|
1811
|
-
schemas[updName].anyOf.push({});
|
|
1812
|
-
}
|
|
1843
|
+
if (!type.$Abstract) schemas[schemaName].anyOf.push({});
|
|
1813
1844
|
}
|
|
1814
1845
|
}
|
|
1815
1846
|
|
|
@@ -2215,6 +2246,10 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
2215
2246
|
nsp = namespace[parts.qualifier];
|
|
2216
2247
|
name = nsp + '.' + parts.name;
|
|
2217
2248
|
url = namespaceUrl[nsp] || '';
|
|
2249
|
+
if (url === "" && !requiredSchemas.used[name + suffix]) {
|
|
2250
|
+
requiredSchemas.used[name + suffix] = true;
|
|
2251
|
+
requiredSchemas.list.push({ namespace: nsp, name: parts.name, suffix });
|
|
2252
|
+
}
|
|
2218
2253
|
//TODO: introduce better way than guessing
|
|
2219
2254
|
if (url.endsWith('.xml')) url = url.substring(0, url.length - 3) + "openapi3.json";
|
|
2220
2255
|
}
|
|
@@ -2347,67 +2382,4 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
|
|
|
2347
2382
|
return !name.startsWith('$') && !name.includes('@');
|
|
2348
2383
|
}
|
|
2349
2384
|
|
|
2350
|
-
}
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
/**
|
|
2354
|
-
* Delete referenced Schema and Parameter Objects from an OpenAPI description
|
|
2355
|
-
* @param {object} openapi OpenAPI description
|
|
2356
|
-
*/
|
|
2357
|
-
module.exports.deleteUnreferencedSchemas = function (openapi) {
|
|
2358
|
-
var gReferenced;
|
|
2359
|
-
var gDeleted;
|
|
2360
|
-
|
|
2361
|
-
do {
|
|
2362
|
-
gReferenced = {};
|
|
2363
|
-
getReferencedSchemas(openapi, gReferenced);
|
|
2364
|
-
gDeleted = deleteUnreferenced(openapi.components.schemas, gReferenced, '#/components/schemas/');
|
|
2365
|
-
} while (gDeleted)
|
|
2366
|
-
|
|
2367
|
-
deleteUnreferenced(openapi.components.parameters, gReferenced, '#/components/parameters/');
|
|
2368
|
-
if (Object.keys(openapi.components.parameters || {}).length == 0) {
|
|
2369
|
-
delete openapi.components.parameters;
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
return;
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
/**
|
|
2376
|
-
* Get unreferenced Schema and Parameter Objects recursively
|
|
2377
|
-
* @param {object} openapi OpenAPI description
|
|
2378
|
-
* @param {object} referenced Map of referenced objects
|
|
2379
|
-
*/
|
|
2380
|
-
function getReferencedSchemas(document, referenced) {
|
|
2381
|
-
Object.keys(document).forEach(key => {
|
|
2382
|
-
let value = document[key];
|
|
2383
|
-
if (key == '$ref') {
|
|
2384
|
-
referenced[value] = true;
|
|
2385
|
-
} else {
|
|
2386
|
-
if (Array.isArray(value)) {
|
|
2387
|
-
value.forEach(item => getReferencedSchemas(item, referenced))
|
|
2388
|
-
} else if (typeof value == 'object' && value != null) {
|
|
2389
|
-
getReferencedSchemas(value, referenced);
|
|
2390
|
-
}
|
|
2391
|
-
}
|
|
2392
|
-
});
|
|
2393
|
-
}
|
|
2394
|
-
|
|
2395
|
-
/**
|
|
2396
|
-
* Delete unreferenced Schema and Parameter Objects recursively
|
|
2397
|
-
* @param {object} schemas Map of Schema and Parameter Objects
|
|
2398
|
-
* @param {object} referenced Map of referenced objects
|
|
2399
|
-
* @param {string} prefix Prefix used within referenced
|
|
2400
|
-
*/
|
|
2401
|
-
function deleteUnreferenced(schemas, referenced, prefix) {
|
|
2402
|
-
var deleted = false;
|
|
2403
|
-
|
|
2404
|
-
Object.keys(schemas || {}).forEach(key => {
|
|
2405
|
-
if (!referenced[prefix + key]) {
|
|
2406
|
-
delete schemas[key];
|
|
2407
|
-
deleted = true;
|
|
2408
|
-
}
|
|
2409
|
-
});
|
|
2410
|
-
|
|
2411
|
-
return deleted;
|
|
2412
|
-
}
|
|
2413
|
-
}
|
|
2385
|
+
};
|
package/lib/import/common.js
CHANGED
|
@@ -373,7 +373,8 @@ async function _updatePackageJson(dest, service, version, cwd) {
|
|
|
373
373
|
version = (version === "V2") ? 'odata-v2' : 'odata';
|
|
374
374
|
}
|
|
375
375
|
if (!requires[service]) {
|
|
376
|
-
const
|
|
376
|
+
const initial_model = path.relative(cwd, dest);
|
|
377
|
+
const model = isLinux() ? initial_model.replace(/\\/g, '/') : initial_model;
|
|
377
378
|
cds.env.requires[service] = requires[service] = { kind: version, model };
|
|
378
379
|
await write(package_json, JSON.stringify(conf, null, ' '));
|
|
379
380
|
console.log(`[cds] - updated ./package.json`);
|
|
@@ -409,6 +410,13 @@ async function identifyFile(filepath) {
|
|
|
409
410
|
return extension;
|
|
410
411
|
}
|
|
411
412
|
|
|
413
|
+
function isLinux(){
|
|
414
|
+
let platform = process.platform
|
|
415
|
+
if (platform === 'linux' || platform === 'win32'){
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
412
420
|
function readEnvVariables(options, cliCheck) {
|
|
413
421
|
if (cds.env.import) {
|
|
414
422
|
if (cliCheck) {
|
|
@@ -579,18 +579,28 @@ class Expression {
|
|
|
579
579
|
const nonStdAttributes = this.getNonStdAttributes(element.attributes);
|
|
580
580
|
for (let i = 0; i < nonStdAttributes.length; i++) {
|
|
581
581
|
let attr = nonStdAttributes[i];
|
|
582
|
+
let check = 0;
|
|
582
583
|
let [prefix, attrName] = attr.split(':');
|
|
583
|
-
if(attrName)
|
|
584
|
+
if (attrName)
|
|
584
585
|
attrName = attrName.replace(/-/g,'.');
|
|
585
586
|
let attribute;
|
|
586
587
|
if ((MetadataConverter.custom_namespace.includes(prefix) || MetadataConverter.custom_namespace.includes(true)) && attrName !== undefined)
|
|
587
588
|
attribute = "@" + prefix + "." + attrName;
|
|
588
589
|
else if (attrName === undefined)
|
|
589
590
|
attribute = "$" + prefix;
|
|
590
|
-
if (attribute !== undefined)
|
|
591
|
-
target
|
|
591
|
+
if (attribute !== undefined && attribute.startsWith('$') === false) {
|
|
592
|
+
Object.entries(target).forEach(a => {
|
|
593
|
+
if (Object.keys(a[1]).length === 0 && typeof(a[1]) != 'boolean' ) {
|
|
594
|
+
a[1][attribute] = element.attributes[attr];
|
|
595
|
+
check = 1;
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
if (check == 0 )
|
|
599
|
+
target[attribute] = element.attributes[attr];
|
|
600
|
+
}
|
|
592
601
|
}
|
|
593
602
|
}
|
|
603
|
+
|
|
594
604
|
getNonStdAttributes(attributes) {
|
|
595
605
|
const attributeList = [];
|
|
596
606
|
const standardArrtibutes = ['MaxLength', 'Precision', 'Scale', 'Nullable', 'DefaultValue',
|
|
@@ -1667,7 +1677,10 @@ class PropertyValueExpression extends Expression {
|
|
|
1667
1677
|
this.setTarget(target);
|
|
1668
1678
|
this.buildTypeCollectionAndFacets('$Type');
|
|
1669
1679
|
|
|
1670
|
-
if (element.attributes.Path) target[name]
|
|
1680
|
+
if (element.attributes.Path) target[name] = {"=": element.attributes.Path};
|
|
1681
|
+
if (element.attributes.PropertyPath) target[name] = {"=": element.attributes.PropertyPath};
|
|
1682
|
+
if (element.attributes.EnumMember) target[name] = {"#": element.attributes.EnumMember.substring(element.attributes.EnumMember.lastIndexOf('/')+1)};
|
|
1683
|
+
if (element.attributes.NavigationPropertyPath) target[name] = {"=": element.attributes.NavigationPropertyPath};
|
|
1671
1684
|
if (element.attributes.String) target[name] = element.attributes.String;
|
|
1672
1685
|
if (element.attributes.Bool) target[name] = element.attributes.Bool === 'true';
|
|
1673
1686
|
|