@sap/cds-dk 8.9.14 → 8.9.16
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 +13 -0
- package/lib/import/odata/v4parser.js +114 -56
- package/npm-shrinkwrap.json +23 -23
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,19 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
9
9
|
|
|
10
|
+
## Version 8.9.16 - 2026-03-12
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- `cds import` now correctly imports views with parameters
|
|
15
|
+
- `cds import` now correctly handles OData referential constraints
|
|
16
|
+
|
|
17
|
+
## Version 8.9.15 - 2026-02-27
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- CVE-2026-26996: Update `minimatch` version to 3.1.5
|
|
22
|
+
|
|
10
23
|
## Version 8.9.14 - 2026-02-25
|
|
11
24
|
|
|
12
25
|
### Fixed
|
|
@@ -407,7 +407,7 @@ function _validateAnnotationNamespace(annotationTerm, vocabNamespaceToAlias) {
|
|
|
407
407
|
if (aliasOrNamespace === "cds") {
|
|
408
408
|
return
|
|
409
409
|
}
|
|
410
|
-
|
|
410
|
+
|
|
411
411
|
for (let alias of Object.values(known_vocabularies)) {
|
|
412
412
|
if (alias === aliasOrNamespace) {
|
|
413
413
|
return;
|
|
@@ -673,6 +673,19 @@ function _parseAssociationProperty(foreignReference, associationNode, parserCont
|
|
|
673
673
|
'=',
|
|
674
674
|
{ref: ['$self']}
|
|
675
675
|
]
|
|
676
|
+
} else if (associationNode.$ReferentialConstraint) {
|
|
677
|
+
associationProperty.on = []
|
|
678
|
+
for (const constraint in associationNode.$ReferentialConstraint) {
|
|
679
|
+
if (associationProperty.on.length) {
|
|
680
|
+
associationProperty.on.push('and')
|
|
681
|
+
}
|
|
682
|
+
associationProperty.on.push(
|
|
683
|
+
{ ref: [foreignReference, associationNode.$ReferentialConstraint[constraint]] },
|
|
684
|
+
'=',
|
|
685
|
+
{ ref: [constraint] }
|
|
686
|
+
)
|
|
687
|
+
}
|
|
688
|
+
|
|
676
689
|
} else if (common.checkForEmptyKeys(associationProperty, "V4")) {
|
|
677
690
|
associationProperty.keys = [];
|
|
678
691
|
}
|
|
@@ -719,52 +732,63 @@ function _parsePropertyContent(csnObj, elementObj, parserContext) {
|
|
|
719
732
|
const isPrimaryKey = true;
|
|
720
733
|
let dataType, isPrimitiveType, keySet = [];
|
|
721
734
|
|
|
722
|
-
Object.keys(elementObj)
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
);
|
|
742
|
-
} else {
|
|
743
|
-
throw new Error(messages.INVALID_DATATYPE + `'${dataType}' in element: '${objKey}'`)
|
|
735
|
+
const sortedElements = Object.keys(elementObj)
|
|
736
|
+
.sort((ele1, ele2) => {
|
|
737
|
+
if (elementObj[ele1]?.$Kind === elementObj[ele2]?.$Kind) {
|
|
738
|
+
return 0
|
|
739
|
+
} else if (elementObj[ele1]?.$Kind === 'NavigationProperty') {
|
|
740
|
+
return 1
|
|
741
|
+
} else if (elementObj[ele2]?.$Kind === 'NavigationProperty') {
|
|
742
|
+
return -1
|
|
743
|
+
}
|
|
744
|
+
return 0
|
|
745
|
+
})
|
|
746
|
+
sortedElements.forEach(objKey => {
|
|
747
|
+
const contentKind = elementObj[objKey].$Kind;
|
|
748
|
+
contentObj = elementObj[objKey];
|
|
749
|
+
|
|
750
|
+
if ((objKey.indexOf('@') === -1) && (objKey.indexOf('.') === -1)) {
|
|
751
|
+
if (contentObj instanceof Object) {
|
|
752
|
+
if (contentObj.$Type) {
|
|
753
|
+
dataType = contentObj.$Type;
|
|
754
|
+
isPrimitiveType = dataType.startsWith('Edm') ? true : false;
|
|
744
755
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
else if (!isPrimitiveType && !(contentKind === 'NavigationProperty')) {
|
|
748
|
-
const dataKind = _checkIsStructureTypeAndReturnDataKind(dataType, contentObj, 'property', parserContext);
|
|
749
|
-
|
|
750
|
-
if (['EnumType', 'TypeDefinition'].includes(dataKind)) {
|
|
751
|
-
csnObj.elements[objKey] = _generateStructuredDataTypeCsn(dataType, contentObj,
|
|
752
|
-
(keySet.includes(dataType) ? isPrimaryKey : !isPrimaryKey),
|
|
753
|
-
dataKind, 'property', parserContext
|
|
754
|
-
);
|
|
756
|
+
if (objKey === '$Key') {
|
|
757
|
+
keySet.push(...elementObj.$Key);
|
|
755
758
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
759
|
+
// primitive datatypes
|
|
760
|
+
else if (isPrimitiveType) {
|
|
761
|
+
if (edmPrimitiveTypes.includes(dataType)) {
|
|
762
|
+
csnObj.elements[objKey] = _generatePrimitiveDataTypeCsn(contentObj,
|
|
763
|
+
(keySet.includes(objKey) ? isPrimaryKey : !isPrimaryKey),
|
|
764
|
+
parserContext
|
|
765
|
+
);
|
|
766
|
+
} else {
|
|
767
|
+
throw new Error(messages.INVALID_DATATYPE + `'${dataType}' in element: '${objKey}'`)
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
// structured datatypes
|
|
771
|
+
else if (!isPrimitiveType && !(contentKind === 'NavigationProperty')) {
|
|
772
|
+
const dataKind = _checkIsStructureTypeAndReturnDataKind(dataType, contentObj, 'property', parserContext);
|
|
773
|
+
|
|
774
|
+
if (['EnumType', 'TypeDefinition'].includes(dataKind)) {
|
|
775
|
+
csnObj.elements[objKey] = _generateStructuredDataTypeCsn(dataType, contentObj,
|
|
776
|
+
(keySet.includes(objKey) ? isPrimaryKey : !isPrimaryKey),
|
|
777
|
+
dataKind, 'property', parserContext
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
csnObj.elements[objKey] = _generateStructuredDataTypeCsn(dataType, contentObj,
|
|
782
|
+
!isPrimaryKey, dataKind, 'property', parserContext
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
else if (contentKind === 'NavigationProperty') {
|
|
787
|
+
csnObj.elements[objKey] = _parseAssociationProperty(objKey, elementObj[objKey], parserContext);
|
|
760
788
|
}
|
|
761
|
-
}
|
|
762
|
-
else if (contentKind === 'NavigationProperty') {
|
|
763
|
-
csnObj.elements[objKey] = _parseAssociationProperty(objKey, elementObj[objKey], parserContext);
|
|
764
789
|
}
|
|
765
790
|
}
|
|
766
|
-
}
|
|
767
|
-
});
|
|
791
|
+
});
|
|
768
792
|
}
|
|
769
793
|
|
|
770
794
|
function _addBlobElement() {
|
|
@@ -1433,7 +1457,7 @@ function _collectBoundActionFunction(isAction, currNamespace, elementName, eleme
|
|
|
1433
1457
|
|
|
1434
1458
|
// binding parameter type should be within the available namespaces in the scope of a document.
|
|
1435
1459
|
if (entityTypeNamespace !== schemaName && entityTypeNamespace !== parserContext.schemaAliasToNamespace[schemaName]) {
|
|
1436
|
-
|
|
1460
|
+
|
|
1437
1461
|
// checking if the namespace is available in other schema of the document
|
|
1438
1462
|
if (parserContext.schemaToSchemaDataIndex.hasOwnProperty(schemaName)) {
|
|
1439
1463
|
entityTypeNamespace = schemaName;
|
|
@@ -1603,8 +1627,7 @@ function _preProcess(edmxAsJson, parserContext, importerContext) {
|
|
|
1603
1627
|
parserContext.entityToEntitySetMap._.size === 0 &&
|
|
1604
1628
|
parserContext.entityToSingletonMap._.size === 0 &&
|
|
1605
1629
|
parserContext.actionToActionImportMap._.size === 0 &&
|
|
1606
|
-
parserContext.functionToFunctionImportMap._.size === 0)
|
|
1607
|
-
{
|
|
1630
|
+
parserContext.functionToFunctionImportMap._.size === 0) {
|
|
1608
1631
|
parserContext.mockServerUc = false;
|
|
1609
1632
|
}
|
|
1610
1633
|
|
|
@@ -1666,22 +1689,57 @@ function _generateCSN(edmxAsJson, ignorePersistenceSkip, parserContext, importer
|
|
|
1666
1689
|
//
|
|
1667
1690
|
// This happens after Step 8 because that adjusts the names of entity container entities where
|
|
1668
1691
|
// entity type and entity set differ in naming
|
|
1669
|
-
for (const entity
|
|
1670
|
-
if (entity.
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
csn.definitions[entity].elements[e].on
|
|
1692
|
+
for (const [eName, entity] of Object.entries(csn.definitions)) {
|
|
1693
|
+
if (entity.kind !== 'entity') continue;
|
|
1694
|
+
const containingCompositions = Object.keys(entity.elements).filter(e =>
|
|
1695
|
+
entity.elements[e].type === 'cds.Composition' &&
|
|
1696
|
+
entity.elements[e].on
|
|
1675
1697
|
);
|
|
1676
1698
|
for (const comp of containingCompositions) {
|
|
1677
|
-
const compTarget = csn.definitions[
|
|
1678
|
-
const backLink = Object.keys(compTarget.elements).find(e =>
|
|
1679
|
-
compTarget.elements[e].type === 'cds.Association' &&
|
|
1680
|
-
compTarget.elements[e].target ===
|
|
1699
|
+
const compTarget = csn.definitions[entity.elements[comp].target];
|
|
1700
|
+
const backLink = Object.keys(compTarget.elements).find(e =>
|
|
1701
|
+
compTarget.elements[e].type === 'cds.Association' &&
|
|
1702
|
+
compTarget.elements[e].target === eName
|
|
1681
1703
|
)
|
|
1682
|
-
|
|
1704
|
+
const entityKeys = Object.keys(entity.elements).filter(ele => entity.elements[ele].key)
|
|
1705
|
+
if (compTarget.elements[backLink]?.keys && !entityKeys.some(key => compTarget.elements[backLink + '_' + key])) {
|
|
1683
1706
|
delete compTarget.elements[backLink].keys
|
|
1684
1707
|
}
|
|
1708
|
+
|
|
1709
|
+
// 3. View with parameters handling. In OData if the entity has a Composition Set with a backlink Parameters and every
|
|
1710
|
+
// other element is a key, its a View with Parameters. Import it as such to ensure proper outbound handling
|
|
1711
|
+
if (
|
|
1712
|
+
comp === 'Set' && backLink === 'Parameters' &&
|
|
1713
|
+
Object.keys(entity.elements).filter(e => entity.elements[e].key).length + 1 === Object.keys(entity.elements).length
|
|
1714
|
+
) {
|
|
1715
|
+
const actualEntity = csn.definitions[entity.elements[comp].target];
|
|
1716
|
+
const actualEntityName = entity.elements[comp].target
|
|
1717
|
+
// Adjust entity so that the current elements are parameters, remove Set, remove key flags
|
|
1718
|
+
delete entity.elements[comp];
|
|
1719
|
+
entity.params = {}
|
|
1720
|
+
for (const ele in entity.elements) {
|
|
1721
|
+
delete entity.elements[ele].key;
|
|
1722
|
+
entity.params[ele] = entity.elements[ele];
|
|
1723
|
+
}
|
|
1724
|
+
delete entity.elements
|
|
1725
|
+
// Move compTarget out of service
|
|
1726
|
+
// Get rid of service prefix
|
|
1727
|
+
let nameWithoutService = eName.split(parserContext.primarySchema).pop();
|
|
1728
|
+
// Get rid of leading dot
|
|
1729
|
+
nameWithoutService = nameWithoutService.substring(1, nameWithoutService.length)
|
|
1730
|
+
csn.definitions[nameWithoutService] = actualEntity;
|
|
1731
|
+
delete csn.definitions[actualEntityName];
|
|
1732
|
+
delete csn.definitions[nameWithoutService].elements['Parameters'];
|
|
1733
|
+
// Adjust entity to * query from compTarget
|
|
1734
|
+
entity.query = {
|
|
1735
|
+
SELECT: {
|
|
1736
|
+
from: {
|
|
1737
|
+
ref: [nameWithoutService]
|
|
1738
|
+
},
|
|
1739
|
+
columns: ["*"]
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1685
1743
|
}
|
|
1686
1744
|
}
|
|
1687
1745
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap/cds-dk",
|
|
3
|
-
"version": "8.9.
|
|
3
|
+
"version": "8.9.16",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@sap/cds-dk",
|
|
9
|
-
"version": "8.9.
|
|
9
|
+
"version": "8.9.16",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@cap-js/asyncapi": "^1.0.0",
|
|
@@ -109,12 +109,12 @@
|
|
|
109
109
|
}
|
|
110
110
|
},
|
|
111
111
|
"node_modules/@eslint/config-array": {
|
|
112
|
-
"version": "0.21.
|
|
112
|
+
"version": "0.21.2",
|
|
113
113
|
"license": "Apache-2.0",
|
|
114
114
|
"dependencies": {
|
|
115
115
|
"@eslint/object-schema": "^2.1.7",
|
|
116
116
|
"debug": "^4.3.1",
|
|
117
|
-
"minimatch": "^3.1.
|
|
117
|
+
"minimatch": "^3.1.5"
|
|
118
118
|
},
|
|
119
119
|
"engines": {
|
|
120
120
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
@@ -141,17 +141,17 @@
|
|
|
141
141
|
}
|
|
142
142
|
},
|
|
143
143
|
"node_modules/@eslint/eslintrc": {
|
|
144
|
-
"version": "3.3.
|
|
144
|
+
"version": "3.3.5",
|
|
145
145
|
"license": "MIT",
|
|
146
146
|
"dependencies": {
|
|
147
|
-
"ajv": "^6.
|
|
147
|
+
"ajv": "^6.14.0",
|
|
148
148
|
"debug": "^4.3.2",
|
|
149
149
|
"espree": "^10.0.1",
|
|
150
150
|
"globals": "^14.0.0",
|
|
151
151
|
"ignore": "^5.2.0",
|
|
152
152
|
"import-fresh": "^3.2.1",
|
|
153
153
|
"js-yaml": "^4.1.1",
|
|
154
|
-
"minimatch": "^3.1.
|
|
154
|
+
"minimatch": "^3.1.5",
|
|
155
155
|
"strip-json-comments": "^3.1.1"
|
|
156
156
|
},
|
|
157
157
|
"engines": {
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
}
|
|
163
163
|
},
|
|
164
164
|
"node_modules/@eslint/js": {
|
|
165
|
-
"version": "9.39.
|
|
165
|
+
"version": "9.39.4",
|
|
166
166
|
"license": "MIT",
|
|
167
167
|
"engines": {
|
|
168
168
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
}
|
|
231
231
|
},
|
|
232
232
|
"node_modules/@sap/cds": {
|
|
233
|
-
"version": "8.9.
|
|
233
|
+
"version": "8.9.9",
|
|
234
234
|
"license": "SEE LICENSE IN LICENSE",
|
|
235
235
|
"dependencies": {
|
|
236
236
|
"@sap/cds-compiler": "^5",
|
|
@@ -402,7 +402,7 @@
|
|
|
402
402
|
}
|
|
403
403
|
},
|
|
404
404
|
"node_modules/acorn": {
|
|
405
|
-
"version": "8.
|
|
405
|
+
"version": "8.16.0",
|
|
406
406
|
"license": "MIT",
|
|
407
407
|
"bin": {
|
|
408
408
|
"acorn": "bin/acorn"
|
|
@@ -419,7 +419,7 @@
|
|
|
419
419
|
}
|
|
420
420
|
},
|
|
421
421
|
"node_modules/ajv": {
|
|
422
|
-
"version": "6.
|
|
422
|
+
"version": "6.14.0",
|
|
423
423
|
"license": "MIT",
|
|
424
424
|
"dependencies": {
|
|
425
425
|
"fast-deep-equal": "^3.1.1",
|
|
@@ -476,7 +476,7 @@
|
|
|
476
476
|
"license": "MIT"
|
|
477
477
|
},
|
|
478
478
|
"node_modules/axios": {
|
|
479
|
-
"version": "1.13.
|
|
479
|
+
"version": "1.13.6",
|
|
480
480
|
"license": "MIT",
|
|
481
481
|
"dependencies": {
|
|
482
482
|
"follow-redirects": "^1.15.11",
|
|
@@ -921,22 +921,22 @@
|
|
|
921
921
|
}
|
|
922
922
|
},
|
|
923
923
|
"node_modules/eslint": {
|
|
924
|
-
"version": "9.39.
|
|
924
|
+
"version": "9.39.4",
|
|
925
925
|
"license": "MIT",
|
|
926
926
|
"dependencies": {
|
|
927
927
|
"@eslint-community/eslint-utils": "^4.8.0",
|
|
928
928
|
"@eslint-community/regexpp": "^4.12.1",
|
|
929
|
-
"@eslint/config-array": "^0.21.
|
|
929
|
+
"@eslint/config-array": "^0.21.2",
|
|
930
930
|
"@eslint/config-helpers": "^0.4.2",
|
|
931
931
|
"@eslint/core": "^0.17.0",
|
|
932
|
-
"@eslint/eslintrc": "^3.3.
|
|
933
|
-
"@eslint/js": "9.39.
|
|
932
|
+
"@eslint/eslintrc": "^3.3.5",
|
|
933
|
+
"@eslint/js": "9.39.4",
|
|
934
934
|
"@eslint/plugin-kit": "^0.4.1",
|
|
935
935
|
"@humanfs/node": "^0.16.6",
|
|
936
936
|
"@humanwhocodes/module-importer": "^1.0.1",
|
|
937
937
|
"@humanwhocodes/retry": "^0.4.2",
|
|
938
938
|
"@types/estree": "^1.0.6",
|
|
939
|
-
"ajv": "^6.
|
|
939
|
+
"ajv": "^6.14.0",
|
|
940
940
|
"chalk": "^4.0.0",
|
|
941
941
|
"cross-spawn": "^7.0.6",
|
|
942
942
|
"debug": "^4.3.2",
|
|
@@ -955,7 +955,7 @@
|
|
|
955
955
|
"is-glob": "^4.0.0",
|
|
956
956
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
|
957
957
|
"lodash.merge": "^4.6.2",
|
|
958
|
-
"minimatch": "^3.1.
|
|
958
|
+
"minimatch": "^3.1.5",
|
|
959
959
|
"natural-compare": "^1.4.0",
|
|
960
960
|
"optionator": "^0.9.3"
|
|
961
961
|
},
|
|
@@ -1217,7 +1217,7 @@
|
|
|
1217
1217
|
}
|
|
1218
1218
|
},
|
|
1219
1219
|
"node_modules/flatted": {
|
|
1220
|
-
"version": "3.
|
|
1220
|
+
"version": "3.4.1",
|
|
1221
1221
|
"license": "ISC"
|
|
1222
1222
|
},
|
|
1223
1223
|
"node_modules/follow-redirects": {
|
|
@@ -1702,7 +1702,7 @@
|
|
|
1702
1702
|
}
|
|
1703
1703
|
},
|
|
1704
1704
|
"node_modules/minimatch": {
|
|
1705
|
-
"version": "3.1.
|
|
1705
|
+
"version": "3.1.5",
|
|
1706
1706
|
"license": "ISC",
|
|
1707
1707
|
"dependencies": {
|
|
1708
1708
|
"brace-expansion": "^1.1.7"
|
|
@@ -1755,7 +1755,7 @@
|
|
|
1755
1755
|
"license": "MIT"
|
|
1756
1756
|
},
|
|
1757
1757
|
"node_modules/node-abi": {
|
|
1758
|
-
"version": "3.
|
|
1758
|
+
"version": "3.88.0",
|
|
1759
1759
|
"license": "MIT",
|
|
1760
1760
|
"optional": true,
|
|
1761
1761
|
"dependencies": {
|
|
@@ -1951,7 +1951,7 @@
|
|
|
1951
1951
|
"license": "MIT"
|
|
1952
1952
|
},
|
|
1953
1953
|
"node_modules/pump": {
|
|
1954
|
-
"version": "3.0.
|
|
1954
|
+
"version": "3.0.4",
|
|
1955
1955
|
"license": "MIT",
|
|
1956
1956
|
"optional": true,
|
|
1957
1957
|
"dependencies": {
|
|
@@ -2064,7 +2064,7 @@
|
|
|
2064
2064
|
"license": "MIT"
|
|
2065
2065
|
},
|
|
2066
2066
|
"node_modules/sax": {
|
|
2067
|
-
"version": "1.
|
|
2067
|
+
"version": "1.5.0",
|
|
2068
2068
|
"license": "BlueOak-1.0.0",
|
|
2069
2069
|
"engines": {
|
|
2070
2070
|
"node": ">=11.0.0"
|
package/package.json
CHANGED