@sap/cds-compiler 2.12.0 → 2.15.2
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 +221 -15
- package/bin/cdsc.js +125 -50
- package/bin/cdsse.js +2 -2
- package/doc/CHANGELOG_BETA.md +13 -6
- package/doc/CHANGELOG_DEPRECATED.md +22 -6
- package/doc/NameResolution.md +21 -16
- package/lib/api/main.js +47 -84
- package/lib/api/options.js +5 -6
- package/lib/api/validate.js +6 -11
- package/lib/backends.js +15 -23
- package/lib/base/dictionaries.js +0 -8
- package/lib/base/error.js +26 -0
- package/lib/base/keywords.js +7 -17
- package/lib/base/location.js +9 -4
- package/lib/base/message-registry.js +114 -18
- package/lib/base/messages.js +101 -90
- package/lib/base/model.js +2 -63
- package/lib/base/optionProcessorHelper.js +177 -123
- package/lib/checks/annotationsOData.js +12 -33
- package/lib/checks/arrayOfs.js +1 -34
- package/lib/checks/cdsPersistence.js +2 -1
- package/lib/checks/enricher.js +17 -1
- package/lib/checks/invalidTarget.js +3 -1
- package/lib/checks/managedWithoutKeys.js +3 -1
- package/lib/checks/selectItems.js +4 -4
- package/lib/checks/sql-snippets.js +27 -26
- package/lib/checks/types.js +1 -1
- package/lib/checks/validator.js +6 -11
- package/lib/compiler/assert-consistency.js +6 -3
- package/lib/compiler/base.js +1 -0
- package/lib/compiler/builtins.js +19 -6
- package/lib/compiler/checks.js +23 -60
- package/lib/compiler/cycle-detector.js +1 -1
- package/lib/compiler/define.js +1151 -0
- package/lib/compiler/extend.js +1000 -0
- package/lib/compiler/finalize-parse-cdl.js +237 -0
- package/lib/compiler/index.js +107 -39
- package/lib/compiler/kick-start.js +190 -0
- package/lib/compiler/moduleLayers.js +4 -4
- package/lib/compiler/populate.js +1227 -0
- package/lib/compiler/propagator.js +114 -46
- package/lib/compiler/resolve.js +1521 -0
- package/lib/compiler/shared.js +126 -65
- package/lib/compiler/tweak-assocs.js +535 -0
- package/lib/compiler/utils.js +197 -33
- package/lib/edm/.eslintrc.json +5 -0
- package/lib/edm/annotations/genericTranslation.js +38 -24
- package/lib/edm/annotations/preprocessAnnotations.js +2 -2
- package/lib/edm/csn2edm.js +219 -100
- package/lib/edm/edm.js +302 -230
- package/lib/edm/edmPreprocessor.js +554 -419
- package/lib/edm/edmUtils.js +138 -44
- package/lib/gen/Dictionary.json +100 -19
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +11 -1
- package/lib/gen/language.tokens +86 -83
- package/lib/gen/languageLexer.interp +10 -1
- package/lib/gen/languageLexer.js +860 -833
- package/lib/gen/languageLexer.tokens +78 -75
- package/lib/gen/languageParser.js +5765 -4480
- package/lib/json/csnVersion.js +10 -11
- package/lib/json/from-csn.js +15 -3
- package/lib/json/to-csn.js +126 -68
- package/lib/language/docCommentParser.js +4 -4
- package/lib/language/genericAntlrParser.js +123 -5
- package/lib/language/language.g4 +355 -156
- package/lib/language/multiLineStringParser.js +5 -5
- package/lib/main.d.ts +486 -59
- package/lib/main.js +41 -9
- package/lib/model/api.js +3 -1
- package/lib/model/csnRefs.js +252 -156
- package/lib/model/csnUtils.js +384 -297
- package/lib/model/enrichCsn.js +71 -29
- package/lib/model/revealInternalProperties.js +29 -8
- package/lib/model/sortViews.js +2 -1
- package/lib/modelCompare/compare.js +23 -18
- package/lib/optionProcessor.js +63 -26
- package/lib/render/manageConstraints.js +35 -32
- package/lib/render/toCdl.js +897 -947
- package/lib/render/toHdbcds.js +205 -257
- package/lib/render/toSql.js +264 -225
- package/lib/render/utils/common.js +136 -25
- package/lib/render/utils/sql.js +4 -3
- package/lib/render/utils/stringEscapes.js +111 -0
- package/lib/sql-identifier.js +1 -1
- package/lib/transform/.eslintrc.json +5 -0
- package/lib/transform/db/.eslintrc.json +3 -1
- package/lib/transform/db/applyTransformations.js +35 -12
- package/lib/transform/db/assertUnique.js +1 -1
- package/lib/transform/db/associations.js +104 -306
- package/lib/transform/db/cdsPersistence.js +2 -2
- package/lib/transform/db/constraints.js +58 -53
- package/lib/transform/db/expansion.js +60 -33
- package/lib/transform/db/flattening.js +582 -104
- package/lib/transform/db/groupByOrderBy.js +3 -1
- package/lib/transform/db/transformExists.js +66 -13
- package/lib/transform/db/views.js +11 -7
- package/lib/transform/draft/.eslintrc.json +38 -0
- package/lib/transform/{db/draft.js → draft/db.js} +6 -5
- package/lib/transform/draft/odata.js +227 -0
- package/lib/transform/forHanaNew.js +109 -208
- package/lib/transform/forOdataNew.js +59 -212
- package/lib/transform/localized.js +46 -26
- package/lib/transform/odata/toFinalBaseType.js +85 -11
- package/lib/transform/odata/typesExposure.js +147 -199
- package/lib/transform/odata/utils.js +2 -2
- package/lib/transform/transformUtilsNew.js +44 -33
- package/lib/transform/translateAssocsToJoins.js +3 -20
- package/lib/transform/universalCsn/.eslintrc.json +36 -0
- package/lib/transform/universalCsn/coreComputed.js +172 -0
- package/lib/transform/universalCsn/universalCsnEnricher.js +737 -0
- package/lib/transform/universalCsn/utils.js +63 -0
- package/lib/utils/moduleResolve.js +13 -6
- package/lib/utils/objectUtils.js +30 -0
- package/package.json +1 -1
- package/share/messages/README.md +26 -0
- package/share/messages/message-explanations.json +2 -1
- package/share/messages/syntax-expected-integer.md +37 -0
- package/lib/compiler/definer.js +0 -2361
- package/lib/compiler/resolver.js +0 -3079
- 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 -290
- package/lib/transform/odata/sortByAssociationDependency.js +0 -105
- package/lib/transform/odata/structuralPath.js +0 -72
- package/lib/transform/odata/structureFlattener.js +0 -171
- package/lib/transform/universalCsnEnricher.js +0 -237
package/lib/edm/edm.js
CHANGED
|
@@ -1,23 +1,91 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
'use strict'
|
|
4
2
|
|
|
5
3
|
const edmUtils = require('./edmUtils.js');
|
|
6
4
|
const { isBuiltinType } = require('../model/csnUtils.js');
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const { forEach } = require("../utils/objectUtils");
|
|
6
|
+
|
|
7
|
+
// facet definitions, optional could either be true or array of edm types
|
|
8
|
+
// remove indicates wether or not the canonic facet shall be removed when applying @odata.Type
|
|
9
|
+
const EdmTypeFacetMap = {
|
|
10
|
+
'MaxLength': { v2: true, v4: true, remove: true, optional: true },
|
|
11
|
+
'Precision': { v2: true, v4: true, remove: true, optional: true },
|
|
12
|
+
'Scale': { v2: true, v4: true, remove: true, optional: true },
|
|
13
|
+
'SRID': { v4: true, remove: true, optional: true },
|
|
14
|
+
//'FixedLength': { v2: true },
|
|
15
|
+
//'Collation': { v2: true },
|
|
16
|
+
//'Unicode': { v2: true, v4: true },
|
|
17
|
+
};
|
|
18
|
+
const EdmTypeFacetNames = Object.keys(EdmTypeFacetMap);
|
|
19
|
+
|
|
20
|
+
// Merged primitive type map with descriptions taken from V4 spec and filled up with V2 spec
|
|
21
|
+
const EdmPrimitiveTypeMap = {
|
|
22
|
+
'Edm.Binary': { v2: true, v4: true, MaxLength: true, FixedLength: true, desc: 'Binary data' },
|
|
23
|
+
'Edm.Boolean': { v2: true, v4: true, desc: 'Binary-valued logic' },
|
|
24
|
+
'Edm.Byte': { v2: true, v4: true, desc: 'Unsigned 8-bit integer' },
|
|
25
|
+
'Edm.Date': { v4: true, desc: 'Date without a time-zone offset' },
|
|
26
|
+
'Edm.DateTime': { v2: true, Precision: true, desc: 'Date and time with values ranging from 12:00:00 midnight, January 1, 1753 A.D. through 11:59:59 P.M, December 31, 9999 A.D.' },
|
|
27
|
+
'Edm.DateTimeOffset': { v2: true, v4: true, Precision: true, desc: 'Date and time with a time-zone offset, no leap seconds' },
|
|
28
|
+
'Edm.Decimal': { v2: true, v4: true, Precision: true, Scale: true, desc: 'Numeric values with decimal representation' },
|
|
29
|
+
'Edm.Double': { v2: true, v4: true, desc: 'IEEE 754 binary64 floating-point number (15-17 decimal digits)' },
|
|
30
|
+
'Edm.Duration': { v4: true, Precision: true, desc: 'Signed duration in days, hours, minutes, and (sub)seconds' },
|
|
31
|
+
'Edm.Guid': { v2: true, v4: true, desc: '16-byte (128-bit) unique identifier' },
|
|
32
|
+
'Edm.Int16': { v2: true, v4: true, desc: 'Signed 16-bit integer' },
|
|
33
|
+
'Edm.Int32': { v2: true, v4: true, desc: 'Signed 32-bit integer' },
|
|
34
|
+
'Edm.Int64': { v2: true, v4: true, desc: 'Signed 64-bit integer' },
|
|
35
|
+
'Edm.SByte': { v2: true, v4: true, desc: 'Signed 8-bit integer' },
|
|
36
|
+
'Edm.Single': { v2: true, v4: true, desc: 'IEEE 754 binary32 floating-point number (6-9 decimal digits)' },
|
|
37
|
+
'Edm.Stream': { v4: true, MaxLength: true, desc: 'Binary data stream' },
|
|
38
|
+
'Edm.String': { v2: true, v4: true, MaxLength: true, FixedLength: true, Collation: true, Unicode: true, desc: 'Sequence of characters' },
|
|
39
|
+
'Edm.Time': { v2: true, Precision: true, desc: 'time of day with values ranging from 0:00:00.x to 23:59:59.y, where x and y depend upon the precision' },
|
|
40
|
+
'Edm.TimeOfDay': { v4: true, Precision: true, desc: 'Clock time 00:00-23:59:59.999999999999' },
|
|
41
|
+
'Edm.Geography': { v4: true, SRID: true, desc: 'Abstract base type for all Geography types' },
|
|
42
|
+
'Edm.GeographyPoint': { v4: true, SRID: true, desc: 'A point in a round-earth coordinate system' },
|
|
43
|
+
'Edm.GeographyLineString': { v4: true, SRID: true, desc: 'Line string in a round-earth coordinate system' },
|
|
44
|
+
'Edm.GeographyPolygon': { v4: true, SRID: true, desc: 'Polygon in a round-earth coordinate system' },
|
|
45
|
+
'Edm.GeographyMultiPoint': { v4: true, SRID: true, desc: 'Collection of points in a round-earth coordinate system' },
|
|
46
|
+
'Edm.GeographyMultiLineString': { v4: true, SRID: true, desc: 'Collection of line strings in a round-earth coordinate system' },
|
|
47
|
+
'Edm.GeographyMultiPolygon': { v4: true, SRID: true, desc: 'Collection of polygons in a round-earth coordinate system' },
|
|
48
|
+
'Edm.GeographyCollection': { v4: true, SRID: true, desc: 'Collection of arbitrary Geography values' },
|
|
49
|
+
'Edm.Geometry': { v4: true, SRID: true, desc: 'Abstract base type for all Geometry types' },
|
|
50
|
+
'Edm.GeometryPoint': { v4: true, SRID: true, desc: 'Point in a flat-earth coordinate system' },
|
|
51
|
+
'Edm.GeometryLineString': { v4: true, SRID: true, desc: 'Line string in a flat-earth coordinate system' },
|
|
52
|
+
'Edm.GeometryPolygon': { v4: true, SRID: true, descr: 'Polygon in a flat-earth coordinate system' },
|
|
53
|
+
'Edm.GeometryMultiPoint': { v4: true, SRID: true, desc: 'Collection of points in a flat-earth coordinate system' },
|
|
54
|
+
'Edm.GeometryMultiLineString': { v4: true, SRID: true, desc: 'Collection of line strings in a flat-earth coordinate system' },
|
|
55
|
+
'Edm.GeometryMultiPolygon': { v4: true, SRID: true, desc: 'Collection of polygons in a flat-earth coordinate system' },
|
|
56
|
+
'Edm.GeometryCollection': { v4: true, SRID: true, desc: 'Collection of arbitrary Geometry values' },
|
|
57
|
+
//'Edm.PrimitiveType': { v4: true, desc: 'Abstract meta type' },
|
|
58
|
+
//'Edm.Untyped': { v4: true, desc: 'Abstract void type' },
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
function getEdm(options, messageFunctions) {
|
|
62
|
+
const { error } = messageFunctions || { error: ()=>true, warning: ()=>true };
|
|
9
63
|
class Node
|
|
10
64
|
{
|
|
11
|
-
|
|
65
|
+
/**
|
|
66
|
+
* @param {boolean[]} v Versions in the form of [<v2>, <v4>].
|
|
67
|
+
* @param {object} attributes
|
|
68
|
+
* @param {CSN.Model} csn
|
|
69
|
+
*/
|
|
70
|
+
constructor(v, attributes = Object.create(null), csn=undefined)
|
|
12
71
|
{
|
|
13
72
|
if(!attributes || typeof attributes !== 'object')
|
|
14
73
|
error(null, 'Please debug me: attributes must be a dictionary');
|
|
15
74
|
if(!Array.isArray(v))
|
|
16
75
|
error(null, 'Please debug me: v is either undefined or not an array: ' + v);
|
|
17
|
-
if(v.filter(v=>v).length
|
|
76
|
+
if(v.filter(v => v).length !== 1)
|
|
18
77
|
error(null, 'Please debug me: exactly one version must be set');
|
|
19
|
-
|
|
20
|
-
|
|
78
|
+
|
|
79
|
+
// Common attributes of JSON and XML.
|
|
80
|
+
// Note: Can't assign attributes directly, due to the input object being modified.
|
|
81
|
+
// The caller re-uses the object for other nodes.
|
|
82
|
+
this._edmAttributes = Object.assign(Object.create(null), attributes);
|
|
83
|
+
this._xmlOnlyAttributes = Object.create(null);
|
|
84
|
+
this._jsonOnlyAttributes = Object.create(null);
|
|
85
|
+
|
|
86
|
+
this._children = [];
|
|
87
|
+
this._ignoreChildren = false;
|
|
88
|
+
this._v = v;
|
|
21
89
|
|
|
22
90
|
if(this.v2)
|
|
23
91
|
this.setSapVocabularyAsAttributes(csn);
|
|
@@ -30,44 +98,53 @@ module.exports = function (options, error) {
|
|
|
30
98
|
return this.constructor.name
|
|
31
99
|
}
|
|
32
100
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Set the EDM(X) attribute on the Node.
|
|
103
|
+
* @param {string} key
|
|
104
|
+
* @param {any} value
|
|
105
|
+
*/
|
|
106
|
+
setEdmAttribute(key, value) {
|
|
107
|
+
if(key !== undefined && key !== null && value !== undefined && value !== null)
|
|
108
|
+
this._edmAttributes[key] = value;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Remove the EDM(X) attribute on the Node.
|
|
113
|
+
* @param {string} name
|
|
114
|
+
*/
|
|
115
|
+
removeEdmAttribute(name) {
|
|
116
|
+
if (name in this._edmAttributes)
|
|
117
|
+
delete this._edmAttributes[name];
|
|
48
118
|
}
|
|
49
119
|
|
|
50
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Set properties that should only appear in the XML representation
|
|
122
|
+
* @param {object} attributes
|
|
123
|
+
* @return {any}
|
|
124
|
+
*/
|
|
51
125
|
setXml(attributes)
|
|
52
126
|
{
|
|
53
|
-
if(!attributes || typeof attributes !== 'object')
|
|
54
|
-
error(null, 'Please debug me: attributes must be a dictionary');
|
|
55
127
|
return Object.assign(this._xmlOnlyAttributes, attributes);
|
|
56
128
|
}
|
|
57
129
|
|
|
58
|
-
|
|
59
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Set properties that should only appear in the JSON representation.
|
|
132
|
+
* Today JSON attributes are not rendered in toJSONattributes()
|
|
133
|
+
*
|
|
134
|
+
* @param {object} attributes
|
|
135
|
+
* @return {any}
|
|
136
|
+
*/
|
|
60
137
|
setJSON(attributes)
|
|
61
138
|
{
|
|
62
|
-
if(!attributes || typeof attributes !== 'object')
|
|
63
|
-
error(null, 'Please debug me: attributes must be a dictionary');
|
|
64
139
|
return Object.assign(this._jsonOnlyAttributes, attributes);
|
|
65
140
|
}
|
|
66
141
|
|
|
67
142
|
prepend(...children)
|
|
68
143
|
{
|
|
69
144
|
this._children.splice(0, 0, ...children.filter(c => c));
|
|
145
|
+
return this;
|
|
70
146
|
}
|
|
147
|
+
|
|
71
148
|
append(...children)
|
|
72
149
|
{
|
|
73
150
|
// remove undefined entries
|
|
@@ -78,9 +155,9 @@ module.exports = function (options, error) {
|
|
|
78
155
|
// virtual
|
|
79
156
|
toJSON()
|
|
80
157
|
{
|
|
81
|
-
|
|
158
|
+
const json = Object.create(null);
|
|
82
159
|
// $kind Property MAY be omitted in JSON for performance reasons
|
|
83
|
-
if(!
|
|
160
|
+
if(!(this.kind in Node.noJsonKinds))
|
|
84
161
|
json['$Kind'] = this.kind;
|
|
85
162
|
|
|
86
163
|
this.toJSONattributes(json);
|
|
@@ -91,7 +168,7 @@ module.exports = function (options, error) {
|
|
|
91
168
|
// virtual
|
|
92
169
|
toJSONattributes(json)
|
|
93
170
|
{
|
|
94
|
-
|
|
171
|
+
forEach(this._edmAttributes, (p, v) => {
|
|
95
172
|
if (p !== 'Name')
|
|
96
173
|
json[p[0] === '@' ? p : '$' + p] = v;
|
|
97
174
|
});
|
|
@@ -101,9 +178,9 @@ module.exports = function (options, error) {
|
|
|
101
178
|
// virtual
|
|
102
179
|
toJSONchildren(json)
|
|
103
180
|
{
|
|
104
|
-
// any child with a Name should be added by
|
|
181
|
+
// any child with a Name should be added by its name into the JSON object
|
|
105
182
|
// all others must overload toJSONchildren()
|
|
106
|
-
this._children.filter(c => c.Name).forEach(c => json[c.Name] = c.toJSON());
|
|
183
|
+
this._children.filter(c => c._edmAttributes.Name).forEach(c => json[c._edmAttributes.Name] = c.toJSON());
|
|
107
184
|
}
|
|
108
185
|
|
|
109
186
|
// virtual
|
|
@@ -112,9 +189,9 @@ module.exports = function (options, error) {
|
|
|
112
189
|
let kind = this.kind;
|
|
113
190
|
let head = indent + '<' + kind;
|
|
114
191
|
|
|
115
|
-
if(kind
|
|
116
|
-
delete this.Collection;
|
|
117
|
-
this.Type=`Collection(${this.Type})`;
|
|
192
|
+
if(kind==='Parameter' && this._edmAttributes.Collection) {
|
|
193
|
+
delete this._edmAttributes.Collection;
|
|
194
|
+
this._edmAttributes.Type=`Collection(${this._edmAttributes.Type})`;
|
|
118
195
|
}
|
|
119
196
|
|
|
120
197
|
head += this.toXMLattributes();
|
|
@@ -135,13 +212,13 @@ module.exports = function (options, error) {
|
|
|
135
212
|
toXMLattributes()
|
|
136
213
|
{
|
|
137
214
|
let tmpStr = '';
|
|
138
|
-
|
|
139
|
-
if (typeof
|
|
140
|
-
tmpStr += ' ' + p + '="' + edmUtils.
|
|
215
|
+
forEach(this._edmAttributes, (p, v) => {
|
|
216
|
+
if (v !== undefined && typeof v !== 'object')
|
|
217
|
+
tmpStr += ' ' + p + '="' + edmUtils.escapeStringForAttributeValue(v) + '"'
|
|
141
218
|
});
|
|
142
|
-
|
|
143
|
-
if (typeof v !== 'object')
|
|
144
|
-
tmpStr += ' ' + p + '="' + edmUtils.
|
|
219
|
+
forEach(this._xmlOnlyAttributes, (p, v) => {
|
|
220
|
+
if (v !== undefined && typeof v !== 'object')
|
|
221
|
+
tmpStr += ' ' + p + '="' + edmUtils.escapeStringForAttributeValue(v) + '"'
|
|
145
222
|
});
|
|
146
223
|
return tmpStr;
|
|
147
224
|
}
|
|
@@ -170,13 +247,16 @@ module.exports = function (options, error) {
|
|
|
170
247
|
}
|
|
171
248
|
}
|
|
172
249
|
|
|
250
|
+
// $kind Property MAY be omitted in JSON for performance reasons
|
|
251
|
+
Node.noJsonKinds = {'Property':1, 'EntitySet':1, 'ActionImport':1, 'FunctionImport':1, 'Singleton':1, 'Schema':1};
|
|
252
|
+
|
|
173
253
|
class Reference extends Node
|
|
174
254
|
{
|
|
175
255
|
constructor(v, details)
|
|
176
256
|
{
|
|
177
257
|
super(v, details);
|
|
178
258
|
if(this.v2)
|
|
179
|
-
this['xmlns:edmx'] = 'http://docs.oasis-open.org/odata/ns/edmx';
|
|
259
|
+
this._edmAttributes['xmlns:edmx'] = 'http://docs.oasis-open.org/odata/ns/edmx';
|
|
180
260
|
}
|
|
181
261
|
|
|
182
262
|
get kind() { return 'edmx:Reference' }
|
|
@@ -207,12 +287,12 @@ module.exports = function (options, error) {
|
|
|
207
287
|
{
|
|
208
288
|
constructor(v, ns, alias=undefined, serviceCsn=null, annotations=[], withEntityContainer=true)
|
|
209
289
|
{
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if(alias != undefined)
|
|
290
|
+
const props = { Namespace: ns };
|
|
291
|
+
if(alias !== undefined)
|
|
213
292
|
props.Alias = alias;
|
|
214
293
|
super(v, props);
|
|
215
|
-
this.
|
|
294
|
+
this._annotations = annotations;
|
|
295
|
+
this._actions = Object.create(null);
|
|
216
296
|
this.setXml( { xmlns: (this.v2) ? 'http://schemas.microsoft.com/ado/2008/09/edm' : 'http://docs.oasis-open.org/odata/ns/edm' } );
|
|
217
297
|
|
|
218
298
|
if(this.v2 && serviceCsn)
|
|
@@ -227,17 +307,17 @@ module.exports = function (options, error) {
|
|
|
227
307
|
// append for rendering, ok ec has Name
|
|
228
308
|
this.append(ec);
|
|
229
309
|
// set as attribute for later access...
|
|
230
|
-
this.
|
|
310
|
+
this._ec = ec;
|
|
231
311
|
}
|
|
232
312
|
}
|
|
233
313
|
|
|
234
314
|
// hold actions and functions in V4
|
|
235
315
|
addAction(action)
|
|
236
316
|
{
|
|
237
|
-
if(this._actions[action.Name])
|
|
238
|
-
this._actions[action.Name].push(action);
|
|
317
|
+
if(this._actions[action._edmAttributes.Name])
|
|
318
|
+
this._actions[action._edmAttributes.Name].push(action);
|
|
239
319
|
else
|
|
240
|
-
this._actions[action.Name] = [action];
|
|
320
|
+
this._actions[action._edmAttributes.Name] = [action];
|
|
241
321
|
}
|
|
242
322
|
|
|
243
323
|
setAnnotations(annotations)
|
|
@@ -249,7 +329,7 @@ module.exports = function (options, error) {
|
|
|
249
329
|
innerXML(indent, what)
|
|
250
330
|
{
|
|
251
331
|
let xml = '';
|
|
252
|
-
if(what
|
|
332
|
+
if(what==='metadata' || what==='all')
|
|
253
333
|
{
|
|
254
334
|
xml += super.innerXML(indent);
|
|
255
335
|
edmUtils.forAll(this._actions, actionArray => {
|
|
@@ -257,11 +337,11 @@ module.exports = function (options, error) {
|
|
|
257
337
|
xml += action.toXML(indent, what) + '\n'; });
|
|
258
338
|
});
|
|
259
339
|
}
|
|
260
|
-
if(what
|
|
340
|
+
if(what==='annotations' || what==='all')
|
|
261
341
|
{
|
|
262
342
|
if(this._annotations.length > 0) {
|
|
263
|
-
this._annotations.filter(a => a.Term).forEach(a => xml += a.toXML(indent) + '\n');
|
|
264
|
-
this._annotations.filter(a => a.Target).forEach(a => xml += a.toXML(indent) + '\n');
|
|
343
|
+
this._annotations.filter(a => a._edmAttributes.Term).forEach(a => xml += a.toXML(indent) + '\n');
|
|
344
|
+
this._annotations.filter(a => a._edmAttributes.Target).forEach(a => xml += a.toXML(indent) + '\n');
|
|
265
345
|
}
|
|
266
346
|
}
|
|
267
347
|
return xml;
|
|
@@ -270,7 +350,7 @@ module.exports = function (options, error) {
|
|
|
270
350
|
// no $Namespace
|
|
271
351
|
toJSONattributes(json)
|
|
272
352
|
{
|
|
273
|
-
edmUtils.forAll(this, (v,p) => {
|
|
353
|
+
edmUtils.forAll(this._edmAttributes, (v,p) => {
|
|
274
354
|
if (p !== 'Name' && p !== 'Namespace')
|
|
275
355
|
json[p[0] === '@' ? p : '$' + p] = v;
|
|
276
356
|
});
|
|
@@ -281,13 +361,13 @@ module.exports = function (options, error) {
|
|
|
281
361
|
// 'edmx:DataServices' should not appear in JSON
|
|
282
362
|
super.toJSONchildren(json);
|
|
283
363
|
if(this._annotations.length > 0) {
|
|
284
|
-
this._annotations.filter(a => a.Term).forEach(a => {
|
|
364
|
+
this._annotations.filter(a => a._edmAttributes.Term).forEach(a => {
|
|
285
365
|
Object.entries(a.toJSON()).forEach(([n, v]) => {
|
|
286
366
|
json[n] = v;
|
|
287
367
|
});
|
|
288
368
|
});
|
|
289
369
|
let json_Annotations = Object.create(null);
|
|
290
|
-
this._annotations.filter(a => a.Target).forEach(a => json_Annotations[a.Target] = a.toJSON());
|
|
370
|
+
this._annotations.filter(a => a._edmAttributes.Target).forEach(a => json_Annotations[a._edmAttributes.Target] = a.toJSON());
|
|
291
371
|
if(Object.keys(json_Annotations).length)
|
|
292
372
|
json['$Annotations'] = json_Annotations;
|
|
293
373
|
}
|
|
@@ -308,7 +388,7 @@ module.exports = function (options, error) {
|
|
|
308
388
|
constructor(v)
|
|
309
389
|
{
|
|
310
390
|
super(v);
|
|
311
|
-
this.
|
|
391
|
+
this._schemas = Object.create(null);
|
|
312
392
|
|
|
313
393
|
if(this.v2)
|
|
314
394
|
this.setXml( { 'm:DataServiceVersion': '2.0' } )
|
|
@@ -327,7 +407,7 @@ module.exports = function (options, error) {
|
|
|
327
407
|
toJSONchildren(json)
|
|
328
408
|
{
|
|
329
409
|
// 'edmx:DataServices' should not appear in JSON
|
|
330
|
-
this._children.forEach(s => json[s.Namespace] = s.toJSON());
|
|
410
|
+
this._children.forEach(s => json[s._edmAttributes.Namespace] = s.toJSON());
|
|
331
411
|
return json;
|
|
332
412
|
}
|
|
333
413
|
}
|
|
@@ -347,12 +427,15 @@ module.exports = function (options, error) {
|
|
|
347
427
|
constructor(v, service)
|
|
348
428
|
{
|
|
349
429
|
super(v, { Version : (v[1]) ? '4.0' : '1.0' });
|
|
350
|
-
this.
|
|
430
|
+
this._service = service;
|
|
431
|
+
this._defaultRefs = [];
|
|
351
432
|
|
|
352
|
-
|
|
433
|
+
const xmlProps = Object.create(null);
|
|
353
434
|
if(this.v4)
|
|
354
435
|
{
|
|
355
|
-
xmlProps['xmlns:edmx']
|
|
436
|
+
xmlProps['xmlns:edmx'] = 'http://docs.oasis-open.org/odata/ns/edmx';
|
|
437
|
+
xmlProps['xmlns:m'] = undefined;
|
|
438
|
+
xmlProps['xmlns:sap'] = undefined;
|
|
356
439
|
}
|
|
357
440
|
else
|
|
358
441
|
{
|
|
@@ -365,19 +448,6 @@ module.exports = function (options, error) {
|
|
|
365
448
|
|
|
366
449
|
get kind() { return 'edmx:Edmx' }
|
|
367
450
|
|
|
368
|
-
hasAnnotations()
|
|
369
|
-
{
|
|
370
|
-
let rc = false;
|
|
371
|
-
this._service._children.forEach(c =>
|
|
372
|
-
{ if(c._annotations.length > 0) rc = true; } )
|
|
373
|
-
return rc;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
getSchemaCount()
|
|
377
|
-
{
|
|
378
|
-
return this._service._children.length;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
451
|
getAnnotations(schemaIndex=0)
|
|
382
452
|
{
|
|
383
453
|
if(this._service && this._service._children[schemaIndex])
|
|
@@ -397,12 +467,12 @@ module.exports = function (options, error) {
|
|
|
397
467
|
let schema = this._service._children[0];
|
|
398
468
|
|
|
399
469
|
let json = Object.create(null);
|
|
400
|
-
json['$Version'] = this.Version;
|
|
401
|
-
json['$EntityContainer'] = schema.Namespace + '.' + schema._ec.Name;
|
|
470
|
+
json['$Version'] = this._edmAttributes.Version;
|
|
471
|
+
json['$EntityContainer'] = schema._edmAttributes.Namespace + '.' + schema._ec._edmAttributes.Name;
|
|
402
472
|
|
|
403
473
|
let reference_json = Object.create(null);
|
|
404
|
-
this._defaultRefs.forEach(r => reference_json[r.Uri] = r.toJSON());
|
|
405
|
-
this._children.forEach(r => reference_json[r.Uri] = r.toJSON());
|
|
474
|
+
this._defaultRefs.forEach(r => reference_json[r._edmAttributes.Uri] = r.toJSON());
|
|
475
|
+
this._children.forEach(r => reference_json[r._edmAttributes.Uri] = r.toJSON());
|
|
406
476
|
|
|
407
477
|
if(Object.keys(reference_json).length)
|
|
408
478
|
json['$Reference'] = reference_json;
|
|
@@ -415,9 +485,7 @@ module.exports = function (options, error) {
|
|
|
415
485
|
// all(default), metadata, annotations
|
|
416
486
|
toXML(what='all')
|
|
417
487
|
{
|
|
418
|
-
|
|
419
|
-
rc += `${super.toXML('', what)}`;
|
|
420
|
-
return rc;
|
|
488
|
+
return '<?xml version="1.0" encoding="utf-8"?>\n' + super.toXML('', what);
|
|
421
489
|
}
|
|
422
490
|
|
|
423
491
|
innerXML(indent, what)
|
|
@@ -434,33 +502,32 @@ module.exports = function (options, error) {
|
|
|
434
502
|
|
|
435
503
|
class EntityContainer extends Node
|
|
436
504
|
{
|
|
437
|
-
constructor() {
|
|
438
|
-
super(
|
|
439
|
-
this.
|
|
505
|
+
constructor(v, attributes, csn) {
|
|
506
|
+
super(v, attributes, csn);
|
|
507
|
+
this._registry = Object.create(null);
|
|
440
508
|
}
|
|
441
509
|
// use the _SetAttributes
|
|
442
510
|
setSapVocabularyAsAttributes(csn)
|
|
443
511
|
{
|
|
444
512
|
super.setSapVocabularyAsAttributes(csn, true);
|
|
445
513
|
}
|
|
514
|
+
|
|
446
515
|
register(entry) {
|
|
447
|
-
if(!this._registry[entry.Name])
|
|
448
|
-
this._registry[entry.Name] = [entry];
|
|
516
|
+
if(!this._registry[entry._edmAttributes.Name])
|
|
517
|
+
this._registry[entry._edmAttributes.Name] = [entry];
|
|
449
518
|
else
|
|
450
|
-
this._registry[entry.Name].push(entry);
|
|
451
|
-
|
|
519
|
+
this._registry[entry._edmAttributes.Name].push(entry);
|
|
520
|
+
this.append(entry);
|
|
452
521
|
}
|
|
453
522
|
}
|
|
454
523
|
|
|
455
524
|
|
|
456
|
-
|
|
457
525
|
class Singleton extends Node
|
|
458
526
|
{
|
|
459
527
|
toJSONattributes(json)
|
|
460
528
|
{
|
|
461
|
-
|
|
462
|
-
if (p !== 'Name')
|
|
463
|
-
{
|
|
529
|
+
forEach(this._edmAttributes, (p, v) => {
|
|
530
|
+
if (p !== 'Name') {
|
|
464
531
|
if(p === 'EntityType') // it's $Type in json
|
|
465
532
|
json['$Type'] = v;
|
|
466
533
|
else
|
|
@@ -473,7 +540,7 @@ module.exports = function (options, error) {
|
|
|
473
540
|
toJSONchildren(json)
|
|
474
541
|
{
|
|
475
542
|
let json_navPropBinding = Object.create(null);
|
|
476
|
-
this._children.forEach(npb => json_navPropBinding[npb.Path] = npb.Target);
|
|
543
|
+
this._children.forEach(npb => json_navPropBinding[npb._edmAttributes.Path] = npb._edmAttributes.Target);
|
|
477
544
|
if(Object.keys(json_navPropBinding).length > 0)
|
|
478
545
|
json['$NavigationPropertyBinding'] = json_navPropBinding;
|
|
479
546
|
|
|
@@ -481,7 +548,7 @@ module.exports = function (options, error) {
|
|
|
481
548
|
}
|
|
482
549
|
|
|
483
550
|
getDuplicateMessage() {
|
|
484
|
-
return `EntityType "${this.EntityType}"`
|
|
551
|
+
return `EntityType "${this._edmAttributes.EntityType}"`
|
|
485
552
|
}
|
|
486
553
|
}
|
|
487
554
|
|
|
@@ -534,13 +601,13 @@ module.exports = function (options, error) {
|
|
|
534
601
|
constructor(v, details)
|
|
535
602
|
{
|
|
536
603
|
super(v, details);
|
|
537
|
-
this.
|
|
604
|
+
this._returnType = undefined;
|
|
538
605
|
}
|
|
539
606
|
|
|
540
607
|
innerXML(indent)
|
|
541
608
|
{
|
|
542
609
|
let xml = super.innerXML(indent);
|
|
543
|
-
if(this._returnType
|
|
610
|
+
if(this._returnType !== undefined)
|
|
544
611
|
xml += this._returnType.toXML(indent) + '\n';
|
|
545
612
|
return xml
|
|
546
613
|
}
|
|
@@ -573,12 +640,12 @@ module.exports = function (options, error) {
|
|
|
573
640
|
*/
|
|
574
641
|
class FunctionImport extends Node {
|
|
575
642
|
getDuplicateMessage() {
|
|
576
|
-
return `Function "${this.Name}"`
|
|
643
|
+
return `Function "${this._edmAttributes.Name}"`
|
|
577
644
|
}
|
|
578
645
|
} //ActionFunctionBase {}
|
|
579
646
|
class ActionImport extends Node {
|
|
580
647
|
getDuplicateMessage() {
|
|
581
|
-
return `Action "${this.Name}"`
|
|
648
|
+
return `Action "${this._edmAttributes.Name}"`
|
|
582
649
|
}
|
|
583
650
|
}
|
|
584
651
|
|
|
@@ -586,75 +653,81 @@ module.exports = function (options, error) {
|
|
|
586
653
|
{
|
|
587
654
|
constructor(v, attributes, csn, typeName='Type')
|
|
588
655
|
{
|
|
589
|
-
if(!(csn instanceof Object || (typeof csn === 'object' && csn !== null)))
|
|
590
|
-
error(null, 'Please debug me: csn must be an object');
|
|
591
|
-
|
|
592
656
|
// ??? Is CSN still required? NavProp?
|
|
593
657
|
super(v, attributes, csn);
|
|
594
|
-
this.
|
|
595
|
-
|
|
596
|
-
if(this[typeName]
|
|
658
|
+
this._typeName = typeName;
|
|
659
|
+
this._scalarType = undefined;
|
|
660
|
+
if(this._edmAttributes[typeName] === undefined)
|
|
597
661
|
{
|
|
598
662
|
let typecsn = csn.type ? csn : (csn.items && csn.items.type ? csn.items : csn);
|
|
599
663
|
// Complex/EntityType are derived from TypeBase
|
|
600
664
|
// but have no type attribute in their CSN
|
|
601
665
|
if(typecsn.type) { // this thing has a type
|
|
602
|
-
// check
|
|
603
|
-
let scalarType = undefined;
|
|
666
|
+
// check whether this is a scalar type (or array of scalar type) or a named type
|
|
604
667
|
if(typecsn.items && typecsn.items.type &&
|
|
605
668
|
isBuiltinType(typecsn.items.type)) {
|
|
606
|
-
|
|
669
|
+
this._scalarType = typecsn.items;
|
|
607
670
|
}
|
|
608
671
|
else if(isBuiltinType(typecsn.type)) {
|
|
609
|
-
|
|
672
|
+
this._scalarType = typecsn;
|
|
610
673
|
}
|
|
611
|
-
if(
|
|
612
|
-
this[typeName] = csn._edmType;
|
|
674
|
+
if(this._scalarType) {
|
|
675
|
+
this._edmAttributes[typeName] = csn._edmType;
|
|
613
676
|
// CDXCORE-CDXCORE-173 ignore type facets for Edm.Stream
|
|
614
677
|
// cds-compiler/issues/7835: Only set length for Binary as long as it is
|
|
615
678
|
// unclear how many bytes a string character represents.
|
|
616
679
|
// We can't calculate an unambiguous byte stream length for DB dependent
|
|
617
680
|
// multi-byte characters.
|
|
618
|
-
if(!(this[typeName] === 'Edm.Stream' &&
|
|
619
|
-
!
|
|
620
|
-
edmUtils.addTypeFacets(this,
|
|
681
|
+
if(!(this._edmAttributes[typeName] === 'Edm.Stream' &&
|
|
682
|
+
!( /*scalarType.type === 'cds.String' ||*/ this._scalarType.type === 'cds.Binary')))
|
|
683
|
+
edmUtils.addTypeFacets(this, this._scalarType);
|
|
684
|
+
// CDXCORE-245:
|
|
685
|
+
// map type to @odata.Type
|
|
686
|
+
// optionally add @odata { MaxLength, Precision, Scale, SRID } but only in combination with @odata.Type
|
|
687
|
+
const odataType = csn['@odata.Type'];
|
|
688
|
+
if(odataType)
|
|
689
|
+
{
|
|
690
|
+
const td = EdmPrimitiveTypeMap[odataType];
|
|
691
|
+
// If type is known, it must be available in the current version
|
|
692
|
+
// Reason: EDMX Importer may set `@odata.Type: 'Edm.DateTime'` on imported V2 services
|
|
693
|
+
// Not filtering out this incompatible type here in case of a V4 rendering would
|
|
694
|
+
// produce an unrecoverable error.
|
|
695
|
+
if(td && (td.v2 === this.v2 || td.v4 === this.v4)) {
|
|
696
|
+
this.setEdmAttribute(typeName, odataType);
|
|
697
|
+
EdmTypeFacetNames.forEach(facet => {
|
|
698
|
+
if(EdmTypeFacetMap[facet].remove)
|
|
699
|
+
this.removeEdmAttribute(facet);
|
|
700
|
+
if(td[facet] !== undefined &&
|
|
701
|
+
(EdmTypeFacetMap[facet].v2 === this.v2 ||
|
|
702
|
+
EdmTypeFacetMap[facet].v4 === this.v4)
|
|
703
|
+
) {
|
|
704
|
+
this.setEdmAttribute(facet, csn['@odata.'+facet]);
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
}
|
|
621
709
|
}
|
|
622
710
|
else {
|
|
623
|
-
this[typeName] = typecsn.type;
|
|
624
|
-
}
|
|
625
|
-
// CDXCORE-245:
|
|
626
|
-
// map type to @odata.Type
|
|
627
|
-
// optionally add @odata.MaxLength but only in combination with @odata.Type
|
|
628
|
-
// In absence of checks restrict @odata.Type to 'Edm.String' and 'Edm.Int[16,32,64]'
|
|
629
|
-
let odataType = csn['@odata.Type'];
|
|
630
|
-
if(odataType === 'Edm.String')
|
|
631
|
-
{
|
|
632
|
-
this[typeName] = odataType;
|
|
633
|
-
if(csn['@odata.MaxLength']) {
|
|
634
|
-
this['MaxLength'] = csn['@odata.MaxLength'];
|
|
635
|
-
}
|
|
636
|
-
} else if(['Edm.Int16', 'Edm.Int32', 'Edm.Int64'].includes(odataType)) {
|
|
637
|
-
this[typeName] = odataType;
|
|
711
|
+
this._edmAttributes[typeName] = typecsn.type;
|
|
638
712
|
}
|
|
639
713
|
}
|
|
640
714
|
}
|
|
715
|
+
|
|
641
716
|
// Set the collection property if this is either an element or a parameter
|
|
642
|
-
|
|
643
|
-
this.set({ _isCollection: csn._isCollection });
|
|
644
|
-
}
|
|
717
|
+
this._isCollection = (csn.kind === undefined) ? csn._isCollection : false;
|
|
645
718
|
|
|
646
|
-
if(options.whatsMySchemaName && this[typeName]) {
|
|
647
|
-
let schemaName = options.whatsMySchemaName(this[typeName]);
|
|
719
|
+
if(options.whatsMySchemaName && this._edmAttributes[typeName]) {
|
|
720
|
+
let schemaName = options.whatsMySchemaName(this._edmAttributes[typeName]);
|
|
648
721
|
if(schemaName && schemaName !== options.serviceName) {
|
|
649
|
-
this[typeName] = this[typeName].replace(options.serviceName + '.', '');
|
|
722
|
+
this._edmAttributes[typeName] = this._edmAttributes[typeName].replace(options.serviceName + '.', '');
|
|
650
723
|
}
|
|
651
724
|
}
|
|
652
725
|
|
|
653
726
|
// store undecorated type for JSON
|
|
654
|
-
this.
|
|
727
|
+
this._type = this._edmAttributes[typeName];
|
|
655
728
|
// decorate for XML (not for Complex/EntityType)
|
|
656
729
|
if(this._isCollection)
|
|
657
|
-
this[typeName] = `Collection(${this[typeName]})`
|
|
730
|
+
this._edmAttributes[typeName] = `Collection(${this._edmAttributes[typeName]})`
|
|
658
731
|
}
|
|
659
732
|
|
|
660
733
|
toJSONattributes(json)
|
|
@@ -664,7 +737,7 @@ module.exports = function (options, error) {
|
|
|
664
737
|
if(this._type !== 'Edm.String' && this._type) // Edm.String is default)
|
|
665
738
|
json['$'+this._typeName] = this._type;
|
|
666
739
|
|
|
667
|
-
edmUtils.forAll(this, (v,p) => {
|
|
740
|
+
edmUtils.forAll(this._edmAttributes, (v,p) => {
|
|
668
741
|
if (p !== 'Name' && p !== this._typeName
|
|
669
742
|
// remove this line if Nullable=true becomes default
|
|
670
743
|
&& !(p === 'Nullable' && v == false))
|
|
@@ -721,7 +794,9 @@ module.exports = function (options, error) {
|
|
|
721
794
|
});
|
|
722
795
|
|
|
723
796
|
if(csn.$edmKeyPaths && csn.$edmKeyPaths.length)
|
|
724
|
-
this.
|
|
797
|
+
this._keys = new Key(v, csn.$edmKeyPaths);
|
|
798
|
+
else
|
|
799
|
+
this._keys = undefined;
|
|
725
800
|
}
|
|
726
801
|
|
|
727
802
|
innerXML(indent)
|
|
@@ -788,7 +863,7 @@ module.exports = function (options, error) {
|
|
|
788
863
|
{
|
|
789
864
|
toJSONattributes(json)
|
|
790
865
|
{
|
|
791
|
-
json[this.Name] = this.Value;
|
|
866
|
+
json[this._edmAttributes.Name] = this._edmAttributes.Value;
|
|
792
867
|
return json;
|
|
793
868
|
}
|
|
794
869
|
}
|
|
@@ -798,7 +873,7 @@ module.exports = function (options, error) {
|
|
|
798
873
|
constructor(v, attributes, csn)
|
|
799
874
|
{
|
|
800
875
|
super(v, attributes, csn);
|
|
801
|
-
this.
|
|
876
|
+
this._csn = csn;
|
|
802
877
|
if(this.v2)
|
|
803
878
|
{
|
|
804
879
|
let typecsn = csn.items || csn;
|
|
@@ -806,7 +881,7 @@ module.exports = function (options, error) {
|
|
|
806
881
|
// see edmUtils.mapsCdsToEdmType => add sap:display-format annotation
|
|
807
882
|
// only if Edm.DateTime is the result of a cast from Edm.Date
|
|
808
883
|
// but not if Edm.DateTime is the result of a regular cds type mapping
|
|
809
|
-
if(this.Type === 'Edm.DateTime'
|
|
884
|
+
if(this._edmAttributes.Type === 'Edm.DateTime'
|
|
810
885
|
&& (typecsn.type !== 'cds.DateTime' && typecsn.type !== 'cds.Timestamp'))
|
|
811
886
|
this.setXml( { 'sap:display-format' : 'Date' } );
|
|
812
887
|
|
|
@@ -818,14 +893,14 @@ module.exports = function (options, error) {
|
|
|
818
893
|
{
|
|
819
894
|
// From the Spec: In OData 4.01 responses a collection-valued property MUST specify a value for the Nullable attribute.
|
|
820
895
|
if(this._isCollection) {
|
|
821
|
-
this.Nullable = !this.isNotNullable();
|
|
896
|
+
this._edmAttributes.Nullable = !this.isNotNullable();
|
|
822
897
|
}
|
|
823
898
|
// Nullable=true is default, mention Nullable=false only in XML
|
|
824
899
|
// Nullable=false is default for EDM JSON representation 4.01
|
|
825
900
|
// When a key explicitly (!) has 'notNull = false', it stays nullable
|
|
826
901
|
else if(this.isNotNullable())
|
|
827
902
|
{
|
|
828
|
-
this.Nullable = false;
|
|
903
|
+
this._edmAttributes.Nullable = false;
|
|
829
904
|
}
|
|
830
905
|
}
|
|
831
906
|
|
|
@@ -842,7 +917,7 @@ module.exports = function (options, error) {
|
|
|
842
917
|
{
|
|
843
918
|
super.toJSONattributes(json);
|
|
844
919
|
// mention all nullable elements explicitly, remove if Nullable=true becomes default
|
|
845
|
-
if(this.Nullable === undefined || this.Nullable === true)
|
|
920
|
+
if(this._edmAttributes.Nullable === undefined || this._edmAttributes.Nullable === true)
|
|
846
921
|
{
|
|
847
922
|
json['$Nullable'] = true;
|
|
848
923
|
}
|
|
@@ -864,9 +939,6 @@ module.exports = function (options, error) {
|
|
|
864
939
|
{
|
|
865
940
|
let json = Object.create(null);
|
|
866
941
|
this.toJSONattributes(json);
|
|
867
|
-
// !this._nullable if Nullable=true become default
|
|
868
|
-
if(this._nullable)
|
|
869
|
-
json['$Nullable'] = this._nullable;
|
|
870
942
|
return json;
|
|
871
943
|
}
|
|
872
944
|
}
|
|
@@ -875,28 +947,16 @@ module.exports = function (options, error) {
|
|
|
875
947
|
{
|
|
876
948
|
constructor(v, attributes, csn)
|
|
877
949
|
{
|
|
878
|
-
// the annotations in this array shall become exposed as Property attributes in
|
|
879
|
-
// the V2 metadata.xml
|
|
880
|
-
// @ts-ignore
|
|
881
|
-
Property.SAP_Annotation_Attribute_WhiteList = [
|
|
882
|
-
'@sap.hierarchy.node.for', //-> sap:hierarchy-node-for
|
|
883
|
-
'@sap.hierarchy.parent.node.for', // -> sap:hierarchy-parent-node-for
|
|
884
|
-
'@sap.hierarchy.level.for', // -> sap:hierarchy-level-for
|
|
885
|
-
'@sap.hierarchy.drill.state.for', // -> sap:hierarchy-drill-state-for
|
|
886
|
-
'@sap.hierarchy.node.descendant.count.for' // -> sap:hierarchy-node-descendant-count-for
|
|
887
|
-
];
|
|
888
|
-
|
|
889
950
|
super(v, attributes, csn);
|
|
890
951
|
// TIPHANACDS-4180
|
|
891
952
|
if(this.v2)
|
|
892
953
|
{
|
|
893
954
|
if(csn['@odata.etag'] == true || csn['@cds.etag'] == true)
|
|
894
|
-
this.ConcurrencyMode='Fixed'
|
|
955
|
+
this._edmAttributes.ConcurrencyMode='Fixed'
|
|
895
956
|
|
|
896
957
|
// translate the following @sap annos as xml attributes to the Property
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
if (Property.SAP_Annotation_Attribute_WhiteList.includes(p))
|
|
958
|
+
forEach(csn, (p, v) => {
|
|
959
|
+
if (p in Property.SAP_Annotation_Attributes)
|
|
900
960
|
this.setXml( { ['sap:' + p.slice(5).replace(/\./g, '-')] : v });
|
|
901
961
|
});
|
|
902
962
|
}
|
|
@@ -906,7 +966,7 @@ module.exports = function (options, error) {
|
|
|
906
966
|
// added a @Core.ComputedDefaultValue for complex defaults
|
|
907
967
|
if (csn.default && !csn['@Core.ComputedDefaultValue']) {
|
|
908
968
|
|
|
909
|
-
|
|
969
|
+
const def = csn.default;
|
|
910
970
|
// if def has a value, it's a simple value
|
|
911
971
|
let defVal = def.val;
|
|
912
972
|
// if it's a simple value with signs, produce a string representation
|
|
@@ -927,9 +987,7 @@ module.exports = function (options, error) {
|
|
|
927
987
|
Additionally: The attribute is named 'Default' in V2 and 'DefaultValue' in V4
|
|
928
988
|
*/
|
|
929
989
|
if(this.v4)
|
|
930
|
-
this[`Default${this.v4 ? 'Value' : ''}`] =
|
|
931
|
-
? defVal
|
|
932
|
-
: edmUtils.escapeString(defVal);
|
|
990
|
+
this._edmAttributes[`Default${this.v4 ? 'Value' : ''}`] = defVal;
|
|
933
991
|
}
|
|
934
992
|
}
|
|
935
993
|
}
|
|
@@ -938,6 +996,17 @@ module.exports = function (options, error) {
|
|
|
938
996
|
// static get isProperty() { return true }
|
|
939
997
|
}
|
|
940
998
|
|
|
999
|
+
// the annotations in this array shall become exposed as Property attributes in
|
|
1000
|
+
// the V2 metadata.xml
|
|
1001
|
+
Property.SAP_Annotation_Attributes = {
|
|
1002
|
+
'@sap.hierarchy.node.for':1, // -> sap:hierarchy-node-for
|
|
1003
|
+
'@sap.hierarchy.parent.node.for':1, // -> sap:hierarchy-parent-node-for
|
|
1004
|
+
'@sap.hierarchy.level.for':1, // -> sap:hierarchy-level-for
|
|
1005
|
+
'@sap.hierarchy.drill.state.for':1, // -> sap:hierarchy-drill-state-for
|
|
1006
|
+
'@sap.hierarchy.node.descendant.count.for':1, // -> sap:hierarchy-node-descendant-count-for
|
|
1007
|
+
'@sap.parameter':1
|
|
1008
|
+
};
|
|
1009
|
+
|
|
941
1010
|
class PropertyRef extends Node
|
|
942
1011
|
{
|
|
943
1012
|
constructor(v, Name, Alias) {
|
|
@@ -945,7 +1014,7 @@ module.exports = function (options, error) {
|
|
|
945
1014
|
}
|
|
946
1015
|
|
|
947
1016
|
toJSON() {
|
|
948
|
-
return this.Alias ? { [this.Alias]:this.Name } : this.Name;
|
|
1017
|
+
return this._edmAttributes.Alias ? { [this._edmAttributes.Alias]:this._edmAttributes.Name } : this._edmAttributes.Name;
|
|
949
1018
|
}
|
|
950
1019
|
}
|
|
951
1020
|
|
|
@@ -956,12 +1025,12 @@ module.exports = function (options, error) {
|
|
|
956
1025
|
super(v, attributes, csn);
|
|
957
1026
|
|
|
958
1027
|
if(mode != null)
|
|
959
|
-
this.Mode = mode;
|
|
1028
|
+
this._edmAttributes.Mode = mode;
|
|
960
1029
|
|
|
961
1030
|
// V2 XML: Parameters that are not explicitly marked as Nullable or NotNullable in the CSN must become Nullable=true
|
|
962
1031
|
// V2 XML Spec does only mention default Nullable=true for Properties not for Parameters so omitting Nullable=true let
|
|
963
1032
|
// the client assume that Nullable is false.... Correct Nullable Handling is done inside Parameter constructor
|
|
964
|
-
if(this.v2 && this.Nullable === undefined)
|
|
1033
|
+
if(this.v2 && this._edmAttributes.Nullable === undefined)
|
|
965
1034
|
this.setXml({Nullable: true});
|
|
966
1035
|
}
|
|
967
1036
|
|
|
@@ -969,7 +1038,7 @@ module.exports = function (options, error) {
|
|
|
969
1038
|
{
|
|
970
1039
|
// we need Name but NO $kind, can't use standard to JSON()
|
|
971
1040
|
let json = Object.create(null);
|
|
972
|
-
json['$Name'] = this.Name;
|
|
1041
|
+
json['$Name'] = this._edmAttributes.Name;
|
|
973
1042
|
return this.toJSONattributes(json);
|
|
974
1043
|
}
|
|
975
1044
|
}
|
|
@@ -985,28 +1054,34 @@ module.exports = function (options, error) {
|
|
|
985
1054
|
let [src, tgt] = edmUtils.determineMultiplicity(csn._constraints._partnerCsn || csn);
|
|
986
1055
|
csn._constraints._multiplicity = csn._constraints._partnerCsn ? [tgt, src] : [src, tgt];
|
|
987
1056
|
|
|
988
|
-
this.
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
_targetCsn: csn._target
|
|
992
|
-
} );
|
|
1057
|
+
this._type = attributes.Type;
|
|
1058
|
+
this._isCollection = this.isToMany();
|
|
1059
|
+
this._targetCsn = csn._target;
|
|
993
1060
|
|
|
994
1061
|
if (this.v4)
|
|
995
1062
|
{
|
|
1063
|
+
if(options.isStructFormat && this._csn.key)
|
|
1064
|
+
this._edmAttributes.Nullable = false;
|
|
1065
|
+
|
|
996
1066
|
// either csn has multiplicity or we have to use the multiplicity of the backlink
|
|
997
1067
|
if(this._isCollection) {
|
|
998
|
-
this.Type = `Collection(${attributes.Type})`
|
|
1068
|
+
this._edmAttributes.Type = `Collection(${attributes.Type})`
|
|
999
1069
|
// attribute Nullable is not allowed in combination with Collection (see Spec)
|
|
1000
1070
|
// Even if min cardinality is > 0, remove Nullable, because the implicit OData contract
|
|
1001
1071
|
// is that a navigation property must either return an empty collection or all collection
|
|
1002
1072
|
// values are !null (with other words: a collection must never return [1,2,null,3])
|
|
1003
|
-
delete this.Nullable;
|
|
1073
|
+
delete this._edmAttributes.Nullable;
|
|
1004
1074
|
}
|
|
1005
1075
|
// we have exactly one selfReference or the default partner
|
|
1006
|
-
let partner =
|
|
1076
|
+
let partner =
|
|
1077
|
+
!csn.$noPartner ?
|
|
1078
|
+
csn._selfReferences.length === 1
|
|
1079
|
+
? csn._selfReferences[0]
|
|
1080
|
+
: csn._constraints._partnerCsn
|
|
1081
|
+
: undefined;
|
|
1007
1082
|
if(partner && partner['@odata.navigable'] !== false) {
|
|
1008
1083
|
// $abspath[0] is main entity
|
|
1009
|
-
this.Partner = partner.$abspath.slice(1).join(options.pathDelimiter);
|
|
1084
|
+
this._edmAttributes.Partner = partner.$abspath.slice(1).join(options.pathDelimiter);
|
|
1010
1085
|
}
|
|
1011
1086
|
|
|
1012
1087
|
/*
|
|
@@ -1019,9 +1094,9 @@ module.exports = function (options, error) {
|
|
|
1019
1094
|
2) ContainsTarget stems from the @odata.contained annotation
|
|
1020
1095
|
*/
|
|
1021
1096
|
if(csn['@odata.contained'] == true || csn.containsTarget) {
|
|
1022
|
-
this.ContainsTarget = true;
|
|
1097
|
+
this._edmAttributes.ContainsTarget = true;
|
|
1023
1098
|
}
|
|
1024
|
-
if(this.ContainsTarget === undefined && csn.type === 'cds.Composition') {
|
|
1099
|
+
if(this._edmAttributes.ContainsTarget === undefined && csn.type === 'cds.Composition') {
|
|
1025
1100
|
// Delete is redundant in containment
|
|
1026
1101
|
// TODO: to be specified via @sap.on.delete
|
|
1027
1102
|
this.append(new OnDelete(v, { Action: 'Cascade' } ) );
|
|
@@ -1032,7 +1107,7 @@ module.exports = function (options, error) {
|
|
|
1032
1107
|
if (this.v2 && this.isNotNullable()) {
|
|
1033
1108
|
// in V2 not null must be expressed with target cardinality of 1 or more,
|
|
1034
1109
|
// store Nullable=false and evaluate in determineMultiplicity()
|
|
1035
|
-
delete this.Nullable;
|
|
1110
|
+
delete this._edmAttributes.Nullable;
|
|
1036
1111
|
}
|
|
1037
1112
|
|
|
1038
1113
|
// store NavProp reference in the model for bidirectional $Partner tagging (done in getReferentialConstraints())
|
|
@@ -1076,10 +1151,10 @@ module.exports = function (options, error) {
|
|
|
1076
1151
|
switch(c.kind) {
|
|
1077
1152
|
case 'ReferentialConstraint':
|
|
1078
1153
|
// collect ref constraints in dictionary
|
|
1079
|
-
json_constraints[c.Property] = c.ReferencedProperty;
|
|
1154
|
+
json_constraints[c._edmAttributes.Property] = c._edmAttributes.ReferencedProperty;
|
|
1080
1155
|
break;
|
|
1081
1156
|
case 'OnDelete':
|
|
1082
|
-
json['$OnDelete'] = c.Action;
|
|
1157
|
+
json['$OnDelete'] = c._edmAttributes.Action;
|
|
1083
1158
|
break;
|
|
1084
1159
|
default:
|
|
1085
1160
|
error(null, 'Please debug me: Unhandled NavProp child: ' + c.kind);
|
|
@@ -1110,6 +1185,12 @@ module.exports = function (options, error) {
|
|
|
1110
1185
|
|
|
1111
1186
|
class ReferentialConstraint extends Node
|
|
1112
1187
|
{
|
|
1188
|
+
constructor(v, attributes, csn) {
|
|
1189
|
+
super(v, attributes, csn);
|
|
1190
|
+
this._d = null;
|
|
1191
|
+
this._p = null;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1113
1194
|
innerXML(indent)
|
|
1114
1195
|
{
|
|
1115
1196
|
if(this._d && this._p)
|
|
@@ -1141,12 +1222,12 @@ module.exports = function (options, error) {
|
|
|
1141
1222
|
{
|
|
1142
1223
|
// short form: key: value
|
|
1143
1224
|
const inlineConstExpr =
|
|
1144
|
-
[ 'Edm.Binary', 'Edm.Boolean', 'Edm.Byte', 'Edm.Date', 'Edm.DateTimeOffset',
|
|
1225
|
+
[ 'Edm.Binary', 'Edm.Boolean', 'Edm.Byte', 'Edm.Date', 'Edm.DateTimeOffset', 'Edm.Decimal', 'Edm.Double', 'Edm.Duration', 'Edm.Guid',
|
|
1145
1226
|
'Edm.Int16', 'Edm.Int32', 'Edm.Int64', 'Edm.SByte','Edm.Single', /*'Edm.Stream',*/ 'Edm.String', 'Edm.TimeOfDay',
|
|
1146
1227
|
/* UI.xml: defines Annotations with generic type 'Edm.PrimitiveType' */
|
|
1147
|
-
'Edm.PrimitiveType', 'Bool'
|
|
1148
|
-
// Official JSON V4.01 Spec defines these paths as constant inline expression
|
|
1149
|
-
|
|
1228
|
+
'Edm.PrimitiveType', 'Bool',
|
|
1229
|
+
// Official JSON V4.01 Spec defines these paths as constant inline expression:
|
|
1230
|
+
'AnnotationPath', 'ModelElementPath', 'NavigationPropertyPath', 'PropertyPath',
|
|
1150
1231
|
];
|
|
1151
1232
|
|
|
1152
1233
|
const dict = this._jsonOnlyAttributes;
|
|
@@ -1157,20 +1238,13 @@ module.exports = function (options, error) {
|
|
|
1157
1238
|
switch(inline[0])
|
|
1158
1239
|
{
|
|
1159
1240
|
/* short notation for Edm.Boolean, Edm.String and Edm.Float, see internal project:
|
|
1160
|
-
|
|
1161
|
-
|
|
1241
|
+
edmx2csn-npm/edm-converters/blob/835d92a1aa6b0be25c56cef85e260c9188187429/lib/edmxV40ToJsonV40/README.md
|
|
1242
|
+
*/
|
|
1162
1243
|
case 'Edm.Boolean':
|
|
1163
1244
|
v = (v=='true'?true:(v=='false'?false:v));
|
|
1164
1245
|
// eslint-no-fallthrough
|
|
1165
|
-
case 'Edm.String':
|
|
1166
|
-
// eslint-no-fallthrough
|
|
1167
|
-
case 'Edm.Float':
|
|
1168
|
-
// eslint-no-fallthrough
|
|
1169
|
-
return v;
|
|
1170
1246
|
default:
|
|
1171
|
-
|
|
1172
|
-
// because they didn't want to lookup the type in the vocabulary
|
|
1173
|
-
return { '$Cast': v, '$Type': inline[0] };
|
|
1247
|
+
return v;
|
|
1174
1248
|
}
|
|
1175
1249
|
}
|
|
1176
1250
|
else
|
|
@@ -1200,13 +1274,12 @@ module.exports = function (options, error) {
|
|
|
1200
1274
|
constructor(v, target)
|
|
1201
1275
|
{
|
|
1202
1276
|
super(v, { Target: target });
|
|
1203
|
-
|
|
1204
|
-
this.setXml( { xmlns : 'http://docs.oasis-open.org/odata/ns/edm' } );
|
|
1277
|
+
this.setXml( { xmlns : this.v2 ? 'http://docs.oasis-open.org/odata/ns/edm' : undefined } );
|
|
1205
1278
|
}
|
|
1206
1279
|
|
|
1207
1280
|
toJSONattributes(json)
|
|
1208
1281
|
{
|
|
1209
|
-
|
|
1282
|
+
forEach(this._edmAttributes, (p, v) => {
|
|
1210
1283
|
if (p !== 'Target')
|
|
1211
1284
|
json[p[0] === '@' ? p : '$' + p] = v;
|
|
1212
1285
|
});
|
|
@@ -1255,7 +1328,7 @@ module.exports = function (options, error) {
|
|
|
1255
1328
|
}
|
|
1256
1329
|
|
|
1257
1330
|
getJsonFQTermName() {
|
|
1258
|
-
return '@' + this.Term + (this.Qualifier ? '#' + this.Qualifier : '');
|
|
1331
|
+
return '@' + this._edmAttributes.Term + (this._edmAttributes.Qualifier ? '#' + this._edmAttributes.Qualifier : '');
|
|
1259
1332
|
}
|
|
1260
1333
|
}
|
|
1261
1334
|
|
|
@@ -1272,11 +1345,11 @@ module.exports = function (options, error) {
|
|
|
1272
1345
|
{
|
|
1273
1346
|
toJSONattributes(json)
|
|
1274
1347
|
{
|
|
1275
|
-
if(this.Type)
|
|
1276
|
-
json['@type'] = this.Type;
|
|
1277
|
-
let keys = Object.keys(this).filter(k => k !== 'Type');
|
|
1348
|
+
if(this._edmAttributes.Type)
|
|
1349
|
+
json['@type'] = this._edmAttributes.Type;
|
|
1350
|
+
let keys = Object.keys(this._edmAttributes).filter(k => k !== 'Type');
|
|
1278
1351
|
for(const key of keys)
|
|
1279
|
-
json['$'+key] = this[key];
|
|
1352
|
+
json['$'+key] = this._edmAttributes[key];
|
|
1280
1353
|
}
|
|
1281
1354
|
|
|
1282
1355
|
toJSONchildren(json)
|
|
@@ -1296,7 +1369,7 @@ module.exports = function (options, error) {
|
|
|
1296
1369
|
json[n] = a;
|
|
1297
1370
|
});
|
|
1298
1371
|
// render property as const expr (or subnode)
|
|
1299
|
-
json[c.Property] = c.toJSON();
|
|
1372
|
+
json[c._edmAttributes.Property] = c.toJSON();
|
|
1300
1373
|
break;
|
|
1301
1374
|
}
|
|
1302
1375
|
default:
|
|
@@ -1311,7 +1384,7 @@ module.exports = function (options, error) {
|
|
|
1311
1384
|
constructor(v, property)
|
|
1312
1385
|
{
|
|
1313
1386
|
super(v);
|
|
1314
|
-
this.Property = property;
|
|
1387
|
+
this._edmAttributes.Property = property;
|
|
1315
1388
|
}
|
|
1316
1389
|
|
|
1317
1390
|
toJSON()
|
|
@@ -1325,7 +1398,7 @@ module.exports = function (options, error) {
|
|
|
1325
1398
|
}
|
|
1326
1399
|
}
|
|
1327
1400
|
mergeJSONannotations() {
|
|
1328
|
-
return super.mergeJSONAnnotations(this.Property);
|
|
1401
|
+
return super.mergeJSONAnnotations(this._edmAttributes.Property);
|
|
1329
1402
|
}
|
|
1330
1403
|
}
|
|
1331
1404
|
|
|
@@ -1334,14 +1407,10 @@ module.exports = function (options, error) {
|
|
|
1334
1407
|
constructor(v, kind, details)
|
|
1335
1408
|
{
|
|
1336
1409
|
super(v, details);
|
|
1337
|
-
this.
|
|
1410
|
+
this._kind = kind;
|
|
1338
1411
|
}
|
|
1339
1412
|
|
|
1340
|
-
|
|
1341
|
-
{
|
|
1342
|
-
Object.defineProperty(this, 'kind',
|
|
1343
|
-
{ get: function() { return kind; }});
|
|
1344
|
-
}
|
|
1413
|
+
get kind() { return this._kind; }
|
|
1345
1414
|
}
|
|
1346
1415
|
|
|
1347
1416
|
class ValueThing extends Thing
|
|
@@ -1349,14 +1418,14 @@ module.exports = function (options, error) {
|
|
|
1349
1418
|
constructor(v, kind, value)
|
|
1350
1419
|
{
|
|
1351
1420
|
super(v, kind, undefined);
|
|
1352
|
-
this.
|
|
1421
|
+
this._value = value;
|
|
1353
1422
|
}
|
|
1354
1423
|
|
|
1355
1424
|
toXML(indent='')
|
|
1356
1425
|
{
|
|
1357
1426
|
let kind = this.kind;
|
|
1358
1427
|
let xml = indent + '<' + kind + this.toXMLattributes();
|
|
1359
|
-
xml += (this._value !== undefined ? '>' + edmUtils.
|
|
1428
|
+
xml += (this._value !== undefined ? '>' + edmUtils.escapeStringForText(this._value) + '</' + kind + '>' : '/>');
|
|
1360
1429
|
return xml;
|
|
1361
1430
|
}
|
|
1362
1431
|
|
|
@@ -1411,10 +1480,11 @@ module.exports = function (options, error) {
|
|
|
1411
1480
|
}
|
|
1412
1481
|
class Cast extends AnnotationBase {
|
|
1413
1482
|
toXMLattributes() {
|
|
1483
|
+
// TODO: Why json?
|
|
1414
1484
|
if(this._jsonOnlyAttributes['Collection'])
|
|
1415
|
-
return ` Type="Collection(${this.Type})"`
|
|
1485
|
+
return ` Type="Collection(${this._edmAttributes.Type})"`
|
|
1416
1486
|
else
|
|
1417
|
-
return ` Type="${this.Type}"`
|
|
1487
|
+
return ` Type="${this._edmAttributes.Type}"`
|
|
1418
1488
|
}
|
|
1419
1489
|
toJSON() {
|
|
1420
1490
|
const json = this.mergeJSONAnnotations();
|
|
@@ -1453,7 +1523,7 @@ module.exports = function (options, error) {
|
|
|
1453
1523
|
|
|
1454
1524
|
toJSONattributes(json) // including Name
|
|
1455
1525
|
{
|
|
1456
|
-
|
|
1526
|
+
forEach(this._edmAttributes, (p, v) => {
|
|
1457
1527
|
json[p[0] === '@' ? p : '$' + p] = v;
|
|
1458
1528
|
});
|
|
1459
1529
|
return json;
|
|
@@ -1482,10 +1552,10 @@ module.exports = function (options, error) {
|
|
|
1482
1552
|
constructor(v, details, navProp, fromRole, toRole, multiplicity)
|
|
1483
1553
|
{
|
|
1484
1554
|
super(v, details);
|
|
1485
|
-
this.
|
|
1486
|
-
this._end.push(
|
|
1555
|
+
this._end = [
|
|
1487
1556
|
new End(v, { Role: fromRole[0], Type: fromRole[1], Multiplicity: multiplicity[0] } ),
|
|
1488
|
-
new End(v, { Role: toRole[0], Type: toRole[1], Multiplicity: multiplicity[1] } )
|
|
1557
|
+
new End(v, { Role: toRole[0], Type: toRole[1], Multiplicity: multiplicity[1] } )
|
|
1558
|
+
];
|
|
1489
1559
|
|
|
1490
1560
|
// set Delete:Cascade on composition end
|
|
1491
1561
|
if(navProp._csn.type === 'cds.Composition')
|
|
@@ -1516,7 +1586,7 @@ module.exports = function (options, error) {
|
|
|
1516
1586
|
);
|
|
1517
1587
|
}
|
|
1518
1588
|
getDuplicateMessage() {
|
|
1519
|
-
return `Association "${this.Association}"`
|
|
1589
|
+
return `Association "${this._edmAttributes.Association}"`
|
|
1520
1590
|
}
|
|
1521
1591
|
}
|
|
1522
1592
|
|
|
@@ -1527,8 +1597,8 @@ module.exports = function (options, error) {
|
|
|
1527
1597
|
function(v, from, to, c)
|
|
1528
1598
|
{
|
|
1529
1599
|
let node = new ReferentialConstraint(v, {});
|
|
1530
|
-
node.
|
|
1531
|
-
node.
|
|
1600
|
+
node._d = new Dependent(v, { Role: from } );
|
|
1601
|
+
node._p = new Principal(v, { Role: to } );
|
|
1532
1602
|
|
|
1533
1603
|
edmUtils.forAll(c, cv => {
|
|
1534
1604
|
node._d.append(new PropertyRef(v, cv[0].join(options.pathDelimiter)));
|
|
@@ -1592,3 +1662,5 @@ module.exports = function (options, error) {
|
|
|
1592
1662
|
}
|
|
1593
1663
|
|
|
1594
1664
|
} // instance function
|
|
1665
|
+
|
|
1666
|
+
module.exports = { EdmTypeFacetMap, EdmTypeFacetNames, EdmPrimitiveTypeMap, getEdm };
|