@sap/cds-compiler 2.13.8 → 3.0.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/CHANGELOG.md +155 -1594
- package/bin/cdsc.js +144 -66
- package/doc/CHANGELOG_ARCHIVE.md +1592 -0
- package/doc/CHANGELOG_BETA.md +3 -4
- package/doc/CHANGELOG_DEPRECATED.md +35 -1
- package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
- package/doc/Versioning.md +20 -1
- package/lib/api/.eslintrc.json +2 -2
- package/lib/api/main.js +237 -122
- package/lib/api/options.js +17 -88
- package/lib/api/validate.js +12 -16
- package/lib/base/keywords.js +216 -109
- package/lib/base/message-registry.js +152 -37
- package/lib/base/messages.js +145 -83
- package/lib/base/model.js +44 -2
- package/lib/base/optionProcessorHelper.js +19 -0
- package/lib/checks/actionsFunctions.js +7 -5
- package/lib/checks/annotationsOData.js +11 -32
- package/lib/checks/arrayOfs.js +1 -34
- package/lib/checks/cdsPersistence.js +1 -0
- package/lib/checks/elements.js +6 -6
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/nonexpandableStructured.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -1
- package/lib/checks/selectItems.js +5 -1
- package/lib/checks/types.js +4 -2
- package/lib/checks/utils.js +2 -2
- package/lib/checks/validator.js +4 -5
- package/lib/compiler/assert-consistency.js +16 -10
- package/lib/compiler/base.js +1 -0
- package/lib/compiler/builtins.js +98 -9
- package/lib/compiler/checks.js +22 -70
- package/lib/compiler/define.js +61 -13
- package/lib/compiler/extend.js +79 -14
- package/lib/compiler/finalize-parse-cdl.js +46 -29
- package/lib/compiler/index.js +100 -37
- package/lib/compiler/moduleLayers.js +7 -0
- package/lib/compiler/populate.js +19 -18
- package/lib/compiler/propagator.js +7 -4
- package/lib/compiler/resolve.js +297 -234
- package/lib/compiler/shared.js +107 -102
- package/lib/compiler/tweak-assocs.js +16 -11
- package/lib/compiler/utils.js +5 -0
- package/lib/edm/annotations/genericTranslation.js +93 -21
- package/lib/edm/csn2edm.js +230 -115
- package/lib/edm/edm.js +305 -226
- package/lib/edm/edmPreprocessor.js +509 -438
- package/lib/edm/edmUtils.js +31 -45
- package/lib/gen/Dictionary.json +98 -22
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +10 -30
- package/lib/gen/language.tokens +105 -114
- package/lib/gen/languageLexer.interp +1 -34
- package/lib/gen/languageLexer.js +889 -1007
- package/lib/gen/languageLexer.tokens +95 -106
- package/lib/gen/languageParser.js +20786 -22199
- package/lib/json/csnVersion.js +10 -11
- package/lib/json/from-csn.js +59 -51
- package/lib/json/to-csn.js +10 -10
- package/lib/language/antlrParser.js +2 -2
- package/lib/language/docCommentParser.js +62 -39
- package/lib/language/errorStrategy.js +52 -40
- package/lib/language/genericAntlrParser.js +348 -229
- package/lib/language/language.g4 +629 -653
- package/lib/language/multiLineStringParser.js +14 -42
- package/lib/language/textUtils.js +44 -0
- package/lib/main.d.ts +46 -43
- package/lib/main.js +108 -79
- package/lib/model/csnRefs.js +34 -7
- package/lib/model/csnUtils.js +337 -332
- package/lib/model/enrichCsn.js +1 -0
- package/lib/model/revealInternalProperties.js +30 -10
- package/lib/model/sortViews.js +32 -31
- package/lib/modelCompare/compare.js +6 -6
- package/lib/optionProcessor.js +73 -46
- package/lib/render/.eslintrc.json +1 -1
- package/lib/render/DuplicateChecker.js +4 -7
- package/lib/render/manageConstraints.js +70 -2
- package/lib/render/toCdl.js +1042 -882
- package/lib/render/toHdbcds.js +195 -245
- package/lib/render/toRename.js +44 -22
- package/lib/render/toSql.js +225 -241
- package/lib/render/utils/common.js +145 -15
- package/lib/render/utils/sql.js +20 -19
- package/lib/sql-identifier.js +6 -0
- package/lib/transform/db/.eslintrc.json +4 -3
- package/lib/transform/db/associations.js +2 -2
- package/lib/transform/db/cdsPersistence.js +5 -15
- package/lib/transform/db/constraints.js +4 -2
- package/lib/transform/db/expansion.js +22 -16
- package/lib/transform/db/flattening.js +109 -80
- package/lib/transform/db/transformExists.js +7 -7
- package/lib/transform/db/views.js +9 -6
- package/lib/transform/draft/.eslintrc.json +2 -2
- package/lib/transform/draft/db.js +6 -6
- package/lib/transform/draft/odata.js +6 -7
- package/lib/transform/forHanaNew.js +62 -48
- package/lib/transform/forOdataNew.js +49 -50
- package/lib/transform/localized.js +31 -20
- package/lib/transform/odata/toFinalBaseType.js +16 -14
- package/lib/transform/odata/typesExposure.js +146 -198
- package/lib/transform/odata/utils.js +1 -38
- package/lib/transform/transformUtilsNew.js +67 -84
- package/lib/transform/translateAssocsToJoins.js +7 -3
- package/lib/transform/universalCsn/.eslintrc.json +2 -2
- package/lib/transform/universalCsn/coreComputed.js +16 -9
- package/lib/transform/universalCsn/universalCsnEnricher.js +60 -10
- package/lib/utils/file.js +3 -3
- package/lib/utils/moduleResolve.js +13 -6
- package/lib/utils/timetrace.js +20 -21
- package/package.json +35 -4
- package/share/messages/message-explanations.json +2 -1
- package/share/messages/syntax-expected-integer.md +37 -0
- package/doc/ApiMigration.md +0 -237
- package/doc/CommandLineMigration.md +0 -58
- package/doc/ErrorMessages.md +0 -175
- package/doc/FioriAnnotations.md +0 -94
- package/doc/ODataTransformation.md +0 -273
- package/lib/backends.js +0 -529
- package/lib/fix_antlr4-8_warning.js +0 -56
- package/lib/transform/odata/attachPath.js +0 -96
- package/lib/transform/odata/expandStructKeysInAssociations.js +0 -59
- package/lib/transform/odata/generateForeignKeyElements.js +0 -261
- package/lib/transform/odata/referenceFlattener.js +0 -296
- package/lib/transform/odata/sortByAssociationDependency.js +0 -105
- package/lib/transform/odata/structuralPath.js +0 -72
- package/lib/transform/odata/structureFlattener.js +0 -171
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* In the OData transformer, managed associations produce foreign keys.
|
|
5
|
-
* If an association is also a primary key, the additionally created foreign keys become also primary keys in the parent artifact.
|
|
6
|
-
* Associations with partial foreign keys force other non-key elements and associations to become virtual primary keys.
|
|
7
|
-
* Proper FK generation requires specific order of performing that.
|
|
8
|
-
* This module provides functionality to sort managed associations according to their dependencies.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const {
|
|
12
|
-
forEachDefinition,
|
|
13
|
-
forEachMemberRecursively
|
|
14
|
-
} = require('../../model/csnUtils');
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
isAssociationOrComposition
|
|
18
|
-
} = require('./utils');
|
|
19
|
-
const { forEach } = require('../../utils/objectUtils.js');
|
|
20
|
-
|
|
21
|
-
function buildDependenciesFor(csn, referenceFlattener, isExternalServiceMember) {
|
|
22
|
-
|
|
23
|
-
let dependencies = {};
|
|
24
|
-
forEachDefinition(csn, (def, definitionName) => {
|
|
25
|
-
/** @type {CSN.Path} */
|
|
26
|
-
let root = ['definitions', definitionName];
|
|
27
|
-
forEachMemberRecursively(def, (element, elementName, structuralNodeName, subpath, parent) => {
|
|
28
|
-
let path = root.concat(subpath);
|
|
29
|
-
// go only through managed associations and compositions
|
|
30
|
-
if (isAssociationOrComposition(element) && element.keys && !element.on) { // check association FKs
|
|
31
|
-
let elementDependencies = []
|
|
32
|
-
element.keys.forEach(iForeignKey => {
|
|
33
|
-
let paths = iForeignKey.$paths;
|
|
34
|
-
if (!paths) return; // invalid references can not be resolved thus no $paths -> test/odataTransformation/negative/ForeignKeys.cds
|
|
35
|
-
let targetElementPath = paths[paths.length - 1];
|
|
36
|
-
if (!targetElementPath) return; // TODO check why
|
|
37
|
-
let targetElement = getElementForPath(csn, targetElementPath);
|
|
38
|
-
if (!targetElement) { // element was moved
|
|
39
|
-
targetElementPath = referenceFlattener.getElementTransition(targetElementPath);
|
|
40
|
-
if (!targetElementPath) return; // TODO check why
|
|
41
|
-
targetElement = getElementForPath(csn, targetElementPath);
|
|
42
|
-
}
|
|
43
|
-
if (targetElement && isAssociationOrComposition(targetElement)) {
|
|
44
|
-
elementDependencies.push(targetElementPath);
|
|
45
|
-
}
|
|
46
|
-
})
|
|
47
|
-
dependencies[path.join("/")] = { structuralNodeName, definitionName, elementName, element, path, parent, dependencies: elementDependencies };
|
|
48
|
-
}
|
|
49
|
-
}) // forEachMemberRecursively
|
|
50
|
-
}, { skipArtifact: isExternalServiceMember }) // forEachDefinition
|
|
51
|
-
|
|
52
|
-
let result = []; // final list of sorted association items
|
|
53
|
-
let inResult = {}; // paths of associations which were added in the result
|
|
54
|
-
let maxLoops = Object.keys(dependencies).length;
|
|
55
|
-
let loops = 0;
|
|
56
|
-
let done = false;
|
|
57
|
-
// walk over all dependencies and add to the result if all dependents are already in the result
|
|
58
|
-
while (!done) {
|
|
59
|
-
if (loops > maxLoops) {
|
|
60
|
-
throw Error('Failed to process the association dependencies - max loops reached');
|
|
61
|
-
}
|
|
62
|
-
done = true;
|
|
63
|
-
let toDelete = [];
|
|
64
|
-
forEach(dependencies, (name, item) => {
|
|
65
|
-
let countOfUnprocessedDependents = 0;
|
|
66
|
-
item.dependencies.forEach(path => {
|
|
67
|
-
let spath = path.join('/');
|
|
68
|
-
if (!inResult[spath]) countOfUnprocessedDependents++;
|
|
69
|
-
})
|
|
70
|
-
if (countOfUnprocessedDependents === 0) { // all dependents processed?
|
|
71
|
-
let spath = item.path.join('/');
|
|
72
|
-
if (!inResult[spath]) {
|
|
73
|
-
inResult[spath] = true;
|
|
74
|
-
result.push(item);
|
|
75
|
-
}
|
|
76
|
-
toDelete.push(name); // mark association to be removed from the processing list
|
|
77
|
-
} else {
|
|
78
|
-
done = false;
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
// delete already processed associations
|
|
82
|
-
toDelete.forEach(name => {
|
|
83
|
-
delete dependencies[name];
|
|
84
|
-
});
|
|
85
|
-
loops++;
|
|
86
|
-
} // while not done
|
|
87
|
-
|
|
88
|
-
// check if all dependencies were processed
|
|
89
|
-
if (Object.keys(dependencies).length !== 0) {
|
|
90
|
-
throw Error('Failed to process the association dependencies - there are more dependencies left');
|
|
91
|
-
}
|
|
92
|
-
return result;
|
|
93
|
-
|
|
94
|
-
function getElementForPath(node, path) {
|
|
95
|
-
path.forEach(name => {
|
|
96
|
-
if (!node) return;
|
|
97
|
-
node = node[name];
|
|
98
|
-
})
|
|
99
|
-
return node;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
module.exports = buildDependenciesFor
|
|
105
|
-
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
// The module traverses a given CSN using a specific path, collects structural node names and returns them.
|
|
2
|
-
|
|
3
|
-
const structuralNodeHandlers = {
|
|
4
|
-
definitions: traverseDict,
|
|
5
|
-
elements: traverseDict,
|
|
6
|
-
actions: traverseDict,
|
|
7
|
-
params: traverseDict,
|
|
8
|
-
items: traverseTyped,
|
|
9
|
-
enum: traverseDict,
|
|
10
|
-
returns: traverseTyped,
|
|
11
|
-
on: traverseArray,
|
|
12
|
-
keys: traverseArray,
|
|
13
|
-
ref: traverseArray,
|
|
14
|
-
query: traverseTyped,
|
|
15
|
-
SELECT: traverseTyped,
|
|
16
|
-
SET: traverseTyped,
|
|
17
|
-
args: traverseArray,
|
|
18
|
-
columns: traverseArray,
|
|
19
|
-
projection: traverseTyped,
|
|
20
|
-
from: traverseTyped,
|
|
21
|
-
mixin: traverseDict,
|
|
22
|
-
where: traverseArray,
|
|
23
|
-
orderBy: traverseArray,
|
|
24
|
-
groupBy: traverseArray,
|
|
25
|
-
having: traverseArray,
|
|
26
|
-
xpr: traverseArray,
|
|
27
|
-
expand: traverseArray,
|
|
28
|
-
inline: traverseArray,
|
|
29
|
-
cast: traverseTyped,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function structuralPath(csn, path) {
|
|
33
|
-
return traverseDict(csn.definitions, path, 1, ['definitions']);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function traverseArray(obj, path, index, typeStack) {
|
|
37
|
-
if(!Array.isArray(obj)) return typeStack;
|
|
38
|
-
const name = path[index];
|
|
39
|
-
const element = obj[name];
|
|
40
|
-
return traverseTyped(element, path, index+1, typeStack);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function traverseDict(obj, path, index, typeStack) {
|
|
44
|
-
if(typeof obj !== 'object') return typeStack;
|
|
45
|
-
const name = path[index];
|
|
46
|
-
if(name === undefined) return typeStack;
|
|
47
|
-
return traverseTyped(obj[name], path, index+1, typeStack);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function traverseDictArray(obj, path, index, typeStack) {
|
|
51
|
-
if(typeof obj !== 'object') return typeStack;
|
|
52
|
-
const name = path[index];
|
|
53
|
-
if(name === undefined) return typeStack;
|
|
54
|
-
return traverseArray(obj[name], path, index+1, typeStack);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function traverseTyped(obj, path, index, typeStack) {
|
|
58
|
-
if(!obj) return typeStack;
|
|
59
|
-
const name = path[index];
|
|
60
|
-
if(name === undefined) return typeStack;
|
|
61
|
-
if(name[0] === '@') return typeStack; // skip annotations
|
|
62
|
-
const func = structuralNodeHandlers[name];
|
|
63
|
-
if(func) return func(obj[name], path, index+1, typeStack.concat(name));
|
|
64
|
-
// not typed -> columns?
|
|
65
|
-
if(typeStack[typeStack.length-1] === 'columns')
|
|
66
|
-
return traverseDictArray(obj, path, index, typeStack);
|
|
67
|
-
return typeStack;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
module.exports = {
|
|
71
|
-
structuralPath
|
|
72
|
-
}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { copyAnnotations } = require('../../model/csnUtils');
|
|
4
|
-
const { cloneCsn, forEachDefinition } = require('../../model/csnUtils');
|
|
5
|
-
const { attachPathOnPartialCSN } = require('./attachPath');
|
|
6
|
-
|
|
7
|
-
// These functions are used for propagation of the annotations, virtual, key,
|
|
8
|
-
// notNull attributes collected along the path during flattening.
|
|
9
|
-
const { addPropsForPropagationFromElement, propagatePropsToElement, resetPropsForPropagation } = function () {
|
|
10
|
-
let toBePropagated = Object.create(null);
|
|
11
|
-
return {
|
|
12
|
-
addPropsForPropagationFromElement: function (element) {
|
|
13
|
-
copyAnnotations(element, toBePropagated);
|
|
14
|
-
if (element.virtual) toBePropagated.virtual = element.virtual;
|
|
15
|
-
if (element.key) toBePropagated.key = element.key;
|
|
16
|
-
},
|
|
17
|
-
propagatePropsToElement: function (element) {
|
|
18
|
-
copyAnnotations(toBePropagated, element);
|
|
19
|
-
if (toBePropagated.virtual) element.virtual = toBePropagated.virtual;
|
|
20
|
-
if (toBePropagated.key) element.key = toBePropagated.key;
|
|
21
|
-
},
|
|
22
|
-
resetPropsForPropagation: function () {
|
|
23
|
-
toBePropagated = Object.create(null);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}();
|
|
27
|
-
|
|
28
|
-
// keep here the state of the 'notNull' attribute
|
|
29
|
-
// this is needed because during flattening all the elements
|
|
30
|
-
// along the chain need to be assigned with not null so
|
|
31
|
-
// the resulting element to be not null as well
|
|
32
|
-
const { isNotNull, setNotNull, setUpNotNull } = function () {
|
|
33
|
-
let notNull = undefined;
|
|
34
|
-
return {
|
|
35
|
-
isNotNull: function () {
|
|
36
|
-
return notNull;
|
|
37
|
-
},
|
|
38
|
-
setNotNull: function (value) {
|
|
39
|
-
notNull = value;
|
|
40
|
-
},
|
|
41
|
-
setUpNotNull: function (element, isParentNotNull) {
|
|
42
|
-
if (isParentNotNull && element.notNull) setNotNull(element.notNull);
|
|
43
|
-
else if (isNotNull() && !element.notNull || (isNotNull() === false && element.notNull !== false)) setNotNull(undefined);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}();
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* During the OData transformations in flat-mode, all structured elements will be flattened.
|
|
50
|
-
* This module performs the complete flattening.
|
|
51
|
-
* It also provides information to the reference flattener: elements produced for specific path in the CSN structure.
|
|
52
|
-
* @param {CSN.Model} csn CSN-object to flatten
|
|
53
|
-
* @param {*} csnUtils instances of utility functions
|
|
54
|
-
* @param {*} options
|
|
55
|
-
* @param {*} referenceFlattener
|
|
56
|
-
* @param {Function} error
|
|
57
|
-
* @param {Function} isExternalServiceMember returns true for an artifact that is part of an external service
|
|
58
|
-
*/
|
|
59
|
-
function flattenCSN(csn, csnUtils, options, referenceFlattener, error, isExternalServiceMember) {
|
|
60
|
-
forEachDefinition(csn, (def, defName, propertyName, path) =>
|
|
61
|
-
flattenDefinition(def, path, csnUtils, options, referenceFlattener, error), { skipArtifact: isExternalServiceMember });
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Flattens one single definition and all structures in it. Modifies the definition in place.
|
|
66
|
-
* @param {CSN.Definition} definition definition object to flatten
|
|
67
|
-
* @param {CSN.Path} definitionPath path in CSN object
|
|
68
|
-
* @param {*} csnUtils utility functions
|
|
69
|
-
* @param {*} options
|
|
70
|
-
* @param {*} referenceFlattener
|
|
71
|
-
* @param {Function} error
|
|
72
|
-
*/
|
|
73
|
-
function flattenDefinition(definition, definitionPath, csnUtils, options, referenceFlattener, error) {
|
|
74
|
-
if (definition.kind !== 'entity')
|
|
75
|
-
return;
|
|
76
|
-
|
|
77
|
-
let { newFlatElements } = flattenStructure(definition.elements, definitionPath, csnUtils, options, error, referenceFlattener);
|
|
78
|
-
|
|
79
|
-
attachPathOnPartialCSN(newFlatElements, definitionPath.concat('elements'));
|
|
80
|
-
definition.elements = newFlatElements;
|
|
81
|
-
|
|
82
|
-
if (definition.params) {
|
|
83
|
-
let { newFlatElements } = flattenStructure(definition.params, definitionPath, csnUtils, options, error, referenceFlattener);
|
|
84
|
-
attachPathOnPartialCSN(newFlatElements, definitionPath.concat('params'));
|
|
85
|
-
definition.params = newFlatElements;
|
|
86
|
-
}
|
|
87
|
-
} // flattenDefinition
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Flattens structured element by calling element flattener for each structured child.
|
|
91
|
-
* Returns a dictionary containing all the new elements for the given structure.
|
|
92
|
-
* @param {*} dictionary to flatten
|
|
93
|
-
* @param {CSN.Path} path the path of the structure in the CSN tree
|
|
94
|
-
* @param {*} csnUtils
|
|
95
|
-
* @param {Function} error Error message function
|
|
96
|
-
* @param {*} [referenceFlattener]
|
|
97
|
-
* @param {string[]} [elementPathInStructure] list of parent element names
|
|
98
|
-
* @param {*} [newFlatElements]
|
|
99
|
-
* @param {boolean} [isTopLevelElement] states if this is a top level element
|
|
100
|
-
*/
|
|
101
|
-
function flattenStructure(dictionary, path, csnUtils, options, error, referenceFlattener = undefined, elementPathInStructure = [],
|
|
102
|
-
newFlatElements = Object.create(null), isTopLevelElement = true, isParentNotNull = false) {
|
|
103
|
-
|
|
104
|
-
if (!isTopLevelElement) addPropsForPropagationFromElement(dictionary);
|
|
105
|
-
|
|
106
|
-
let generatedNewFlatElementsNames = []; // holds the names of all new child elements of the structure
|
|
107
|
-
|
|
108
|
-
dictionary && Object.entries(dictionary).forEach(([elementName, element]) => {
|
|
109
|
-
let currPath = path.concat('elements', elementName);
|
|
110
|
-
|
|
111
|
-
if (isTopLevelElement) {
|
|
112
|
-
resetPropsForPropagation();
|
|
113
|
-
setNotNull(element.notNull)
|
|
114
|
-
} else {
|
|
115
|
-
setUpNotNull(element, isParentNotNull);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// flat elements when structured and NOT empty (allow incomplete structures - cds-compiler#4337)
|
|
119
|
-
if (csnUtils.isStructured(element) && !(element.elements && Object.keys(element.elements).length === 0)) {
|
|
120
|
-
|
|
121
|
-
if (referenceFlattener) referenceFlattener.registerFlattenedElement(currPath, element.$path);
|
|
122
|
-
|
|
123
|
-
addPropsForPropagationFromElement(element);
|
|
124
|
-
|
|
125
|
-
// if the child element is structured itself -> needs to be flattened
|
|
126
|
-
const elements = element.elements || csnUtils.getFinalBaseType(element.type).elements;
|
|
127
|
-
let result = flattenStructure(elements, currPath, csnUtils, options, error, referenceFlattener, elementPathInStructure.concat(elementName), newFlatElements, false, isNotNull());
|
|
128
|
-
generatedNewFlatElementsNames.push(...result.generatedNewFlatElementsNames); // accomulate names of produced elements
|
|
129
|
-
|
|
130
|
-
} else { // when we do not need to flat, this is scalar or empty (cds-compiler#4337) -> needs to be registered in referenceFlattener
|
|
131
|
-
let newElementName = elementPathInStructure.concat(elementName).join('_');
|
|
132
|
-
let elementNameWithDots = elementPathInStructure.concat(elementName).join('.');
|
|
133
|
-
addNewElementToResult(element, newElementName, elementNameWithDots, currPath);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
if (referenceFlattener) {
|
|
138
|
-
referenceFlattener.registerGeneratedElementsForPath(path, generatedNewFlatElementsNames);
|
|
139
|
-
}
|
|
140
|
-
return { newFlatElements, generatedNewFlatElementsNames };
|
|
141
|
-
|
|
142
|
-
// adds newly created element into the final dictionary of elements
|
|
143
|
-
function addNewElementToResult(element, elementName, elementNameWithDots, path) {
|
|
144
|
-
if (newFlatElements[elementName]) {
|
|
145
|
-
error(null, path, `Generated element ${elementName} conflicts with other generated element`);
|
|
146
|
-
} else {
|
|
147
|
-
let newPath = path.slice(0, 2).concat('elements', elementName);
|
|
148
|
-
let newElement = createNewElement(element, elementNameWithDots, newPath);
|
|
149
|
-
newFlatElements[elementName] = newElement;
|
|
150
|
-
generatedNewFlatElementsNames.push(elementName);
|
|
151
|
-
|
|
152
|
-
if (referenceFlattener) {
|
|
153
|
-
referenceFlattener.registerElementTransition(path, newPath);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
} // addNewElementToResult
|
|
157
|
-
|
|
158
|
-
// creates new element by copying the properties of the originating element
|
|
159
|
-
function createNewElement(element, elementNameWithDots, path) {
|
|
160
|
-
let newElement = cloneCsn(element, options);
|
|
161
|
-
if (!isTopLevelElement) propagatePropsToElement(newElement);
|
|
162
|
-
if (isNotNull() === undefined) delete newElement.notNull;
|
|
163
|
-
if (!isTopLevelElement && referenceFlattener) {
|
|
164
|
-
referenceFlattener.setElementNameWithDots(path, elementNameWithDots);
|
|
165
|
-
}
|
|
166
|
-
return newElement;
|
|
167
|
-
} // createNewElement
|
|
168
|
-
|
|
169
|
-
} // flattenStructure
|
|
170
|
-
|
|
171
|
-
module.exports = { flattenCSN, flattenStructure };
|