@sap/cds-compiler 4.3.0 → 4.4.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 +36 -0
- package/lib/api/main.js +14 -24
- package/lib/api/options.js +1 -0
- package/lib/api/trace.js +38 -0
- package/lib/base/location.js +46 -1
- package/lib/base/message-registry.js +68 -16
- package/lib/base/messages.js +8 -3
- package/lib/checks/.eslintrc.json +1 -0
- package/lib/checks/actionsFunctions.js +1 -1
- package/lib/checks/annotationsOData.js +2 -2
- package/lib/checks/selectItems.js +4 -1
- package/lib/compiler/assert-consistency.js +3 -2
- package/lib/compiler/base.js +1 -1
- package/lib/compiler/builtins.js +25 -1
- package/lib/compiler/checks.js +6 -5
- package/lib/compiler/define.js +12 -10
- package/lib/compiler/extend.js +22 -22
- package/lib/compiler/finalize-parse-cdl.js +1 -1
- package/lib/compiler/generate.js +70 -53
- package/lib/compiler/kick-start.js +9 -5
- package/lib/compiler/populate.js +31 -22
- package/lib/compiler/propagator.js +6 -2
- package/lib/compiler/resolve.js +52 -17
- package/lib/compiler/shared.js +74 -38
- package/lib/compiler/tweak-assocs.js +64 -23
- package/lib/compiler/utils.js +40 -23
- package/lib/edm/.eslintrc.json +2 -0
- package/lib/edm/EdmPrimitiveTypeDefinitions.js +252 -0
- package/lib/edm/annotations/edmJson.js +994 -0
- package/lib/edm/annotations/genericTranslation.js +75 -421
- package/lib/edm/annotations/vocabularyDefinitions.js +160 -0
- package/lib/edm/csn2edm.js +12 -5
- package/lib/edm/edm.js +14 -73
- package/lib/edm/edmPreprocessor.js +6 -0
- package/lib/gen/Dictionary.json +187 -16
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +1 -1
- package/lib/gen/languageLexer.interp +1 -1
- package/lib/gen/languageLexer.js +1129 -671
- package/lib/gen/languageParser.js +4285 -4283
- package/lib/json/from-csn.js +13 -18
- package/lib/json/to-csn.js +11 -6
- package/lib/language/antlrParser.js +0 -1
- package/lib/language/docCommentParser.js +1 -1
- package/lib/language/errorStrategy.js +95 -30
- package/lib/language/genericAntlrParser.js +21 -1
- package/lib/main.js +13 -3
- package/lib/model/csnRefs.js +42 -8
- package/lib/model/csnUtils.js +14 -2
- package/lib/model/enrichCsn.js +33 -5
- package/lib/model/revealInternalProperties.js +5 -0
- package/lib/modelCompare/compare.js +76 -14
- package/lib/modelCompare/utils/filter.js +19 -12
- package/lib/optionProcessor.js +2 -0
- package/lib/render/.eslintrc.json +1 -1
- package/lib/render/manageConstraints.js +1 -0
- package/lib/render/toHdbcds.js +3 -0
- package/lib/render/toRename.js +3 -1
- package/lib/render/toSql.js +46 -92
- package/lib/render/utils/common.js +76 -0
- package/lib/render/utils/delta.js +17 -3
- package/lib/sql-identifier.js +1 -1
- package/lib/transform/db/.eslintrc.json +1 -0
- package/lib/transform/db/applyTransformations.js +30 -4
- package/lib/transform/db/associations.js +22 -10
- package/lib/transform/db/backlinks.js +6 -2
- package/lib/transform/db/expansion.js +2 -2
- package/lib/transform/db/transformExists.js +13 -39
- package/lib/transform/draft/db.js +14 -3
- package/lib/transform/draft/odata.js +5 -18
- package/lib/transform/effective/associations.js +46 -15
- package/lib/transform/effective/main.js +7 -2
- package/lib/transform/effective/misc.js +43 -24
- package/lib/transform/effective/queries.js +20 -22
- package/lib/transform/effective/types.js +6 -2
- package/lib/transform/forOdata.js +5 -2
- package/lib/transform/localized.js +1 -1
- package/lib/transform/parseExpr.js +73 -21
- package/lib/transform/translateAssocsToJoins.js +24 -16
- package/lib/utils/term.js +2 -2
- package/package.json +2 -1
|
@@ -6,7 +6,7 @@ const {
|
|
|
6
6
|
forEachGeneric,
|
|
7
7
|
forEachInOrder,
|
|
8
8
|
} = require('../base/model');
|
|
9
|
-
const { dictLocation, weakLocation } = require('../base/location');
|
|
9
|
+
const { dictLocation, weakLocation, weakRefLocation } = require('../base/location');
|
|
10
10
|
|
|
11
11
|
const {
|
|
12
12
|
setLink,
|
|
@@ -42,7 +42,7 @@ function tweakAssocs( model ) {
|
|
|
42
42
|
// Phase 5: rewrite associations
|
|
43
43
|
model._entities.forEach( rewriteArtifact );
|
|
44
44
|
// Think hard whether an on condition rewrite can lead to a new cyclic
|
|
45
|
-
// dependency. If so, we need other messages anyway. TODO: probably
|
|
45
|
+
// dependency. If so, we need other messages anyway. TODO: probably dox
|
|
46
46
|
// another cyclic check with testMode.js
|
|
47
47
|
forEachUserArtifact( model, 'definitions', function check( art ) {
|
|
48
48
|
checkOnCondition( art.on, (art.kind !== 'mixin' ? 'on' : 'mixin-on'), art );
|
|
@@ -73,7 +73,7 @@ function tweakAssocs( model ) {
|
|
|
73
73
|
} );
|
|
74
74
|
}
|
|
75
75
|
if (art._service)
|
|
76
|
-
forEachGeneric( art, 'elements',
|
|
76
|
+
forEachGeneric( art, 'elements', complainAboutTargetOutsideService );
|
|
77
77
|
|
|
78
78
|
traverseQueryPost( art.query, false, ( query ) => {
|
|
79
79
|
forEachGeneric( query, 'elements', rewriteAssociationCheck );
|
|
@@ -95,12 +95,14 @@ function tweakAssocs( model ) {
|
|
|
95
95
|
// } );
|
|
96
96
|
// }
|
|
97
97
|
|
|
98
|
-
function
|
|
98
|
+
function complainAboutTargetOutsideService( elem ) {
|
|
99
99
|
const target = elem.target && elem.target._artifact;
|
|
100
100
|
if (!target || target._service) // assoc to other service is OK
|
|
101
101
|
return;
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
const loc = [ elem.target.location, elem ];
|
|
103
|
+
const main = elem._main || elem;
|
|
104
|
+
if (!elem.$inferred && !main.$inferred) {
|
|
105
|
+
info( 'assoc-target-not-in-service', loc,
|
|
104
106
|
{ target, '#': (elem._main.query ? 'select' : 'define') }, {
|
|
105
107
|
std: 'Target $(TARGET) of association is outside any service', // not used
|
|
106
108
|
// eslint-disable-next-line max-len
|
|
@@ -110,10 +112,13 @@ function tweakAssocs( model ) {
|
|
|
110
112
|
} );
|
|
111
113
|
}
|
|
112
114
|
else {
|
|
115
|
+
const text = main.$inferred === 'autoexposed' ? 'exposed' : 'std';
|
|
113
116
|
// ID published! Used in stakeholder project; if renamed, add to oldMessageIds
|
|
114
|
-
info( 'assoc-outside-service',
|
|
115
|
-
|
|
116
|
-
|
|
117
|
+
info( 'assoc-outside-service', loc, { '#': text, target, service: main._service }, {
|
|
118
|
+
std: 'Association target $(TARGET) is outside any service',
|
|
119
|
+
// eslint-disable-next-line max-len
|
|
120
|
+
exposed: 'If association is published in service $(SERVICE), its target $(TARGET) is outside any service',
|
|
121
|
+
} );
|
|
117
122
|
}
|
|
118
123
|
}
|
|
119
124
|
|
|
@@ -257,10 +262,36 @@ function tweakAssocs( model ) {
|
|
|
257
262
|
rewriteCondition( art, elem );
|
|
258
263
|
else if (elem.foreignKeys)
|
|
259
264
|
rewriteKeys( art, elem );
|
|
265
|
+
|
|
266
|
+
if (art.on)
|
|
267
|
+
removeManagedPropsFromUnmanaged( art );
|
|
268
|
+
|
|
260
269
|
elem = art;
|
|
261
270
|
}
|
|
262
271
|
}
|
|
263
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Remove properties from unmanaged association `elem` that are only valid
|
|
275
|
+
* on managed associations. Only set to `NULL` (special value for propagator),
|
|
276
|
+
* if necessary, i.e. the value is set on the `_origin`-chain.
|
|
277
|
+
*/
|
|
278
|
+
function removeManagedPropsFromUnmanaged( elem ) {
|
|
279
|
+
removeProp( 'notNull' );
|
|
280
|
+
removeProp( 'default' );
|
|
281
|
+
|
|
282
|
+
function removeProp( prop ) {
|
|
283
|
+
let origin = elem;
|
|
284
|
+
while (origin) {
|
|
285
|
+
if (origin[prop]) { // regardless of the value, reset the property
|
|
286
|
+
const location = weakLocation( elem.name.location );
|
|
287
|
+
elem[prop] = { $inferred: 'NULL', val: undefined, location };
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
origin = origin._origin;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
264
295
|
function originTarget( elem ) {
|
|
265
296
|
const assoc = !elem.expand && getOrigin( elem );
|
|
266
297
|
const ftype = assoc && effectiveType( assoc );
|
|
@@ -276,13 +307,13 @@ function tweakAssocs( model ) {
|
|
|
276
307
|
// already in Phase 2: redirectImplicitly()
|
|
277
308
|
// console.log(message( null, elem.location, elem, {art:assoc,target:assoc.target},
|
|
278
309
|
// 'Info','FK').toString())
|
|
310
|
+
elem.foreignKeys = Object.create(null); // set already here (also for zero foreign keys)
|
|
279
311
|
forEachInOrder( assoc, 'foreignKeys', ( orig, name ) => {
|
|
280
|
-
const
|
|
312
|
+
const location = weakRefLocation( elem.target );
|
|
313
|
+
const fk = linkToOrigin( orig, name, elem, 'foreignKeys', location );
|
|
281
314
|
fk.$inferred = 'rewrite'; // Override existing value; TODO: other $inferred value?
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
setLink( fk, '_effectiveType', orig._effectiveType );
|
|
285
|
-
const te = copyExpr( orig.targetElement, elem.location );
|
|
315
|
+
setLink( fk, '_effectiveType', fk );
|
|
316
|
+
const te = copyExpr( orig.targetElement, location );
|
|
286
317
|
if (elem._redirected) {
|
|
287
318
|
const i = te.path[0]; // TODO: or also follow path like for ON?
|
|
288
319
|
const state = rewriteItem( elem, i, i.id, elem, true );
|
|
@@ -325,12 +356,9 @@ function tweakAssocs( model ) {
|
|
|
325
356
|
// `cond` still points to the original condition; does not include possible assoc filter
|
|
326
357
|
elem.on.$inferred = 'copy';
|
|
327
358
|
|
|
328
|
-
// console.log(message( null, elem.location, elem, {art:assoc,target:assoc.target},
|
|
329
|
-
// 'Info','ON').toString(), nav)
|
|
330
359
|
const { navigation } = nav;
|
|
331
360
|
if (!navigation) // TODO: what about $projection.assoc as myAssoc ?
|
|
332
361
|
return; // should not happen: $projection, $magic, or ref to const
|
|
333
|
-
// console.log(message( null, elem.location, elem, {art:assoc}, 'Info','D').toString())
|
|
334
362
|
// Currently, having an unmanaged association inside a struct is not
|
|
335
363
|
// supported by this function:
|
|
336
364
|
if (navigation !== assoc && navigation._origin !== assoc) { // TODO: re-check
|
|
@@ -428,8 +456,13 @@ function tweakAssocs( model ) {
|
|
|
428
456
|
setLink( expr.path[0], '_artifact', elem );
|
|
429
457
|
// _navigation link not necessary because this condition is not rewritten
|
|
430
458
|
// inside the same view (would otherwise be needed for mixins).
|
|
459
|
+
|
|
460
|
+
if (elem.name.id.charAt(0) === '$')
|
|
461
|
+
prependSelfToPath( expr.path, elem );
|
|
431
462
|
}
|
|
432
463
|
} );
|
|
464
|
+
|
|
465
|
+
checkOnCondition( cond, 'on', elem );
|
|
433
466
|
return cond;
|
|
434
467
|
}
|
|
435
468
|
|
|
@@ -465,6 +498,9 @@ function tweakAssocs( model ) {
|
|
|
465
498
|
setLink( lhs.path[0], '_artifact', elem ); // different to rhs!
|
|
466
499
|
setLink( lhs, '_artifact', lhs.path[lhs.path.length - 1] );
|
|
467
500
|
|
|
501
|
+
if (elem.name.id.charAt(0) === '$')
|
|
502
|
+
prependSelfToPath( lhs.path, elem );
|
|
503
|
+
|
|
468
504
|
const rhs = {
|
|
469
505
|
path: [
|
|
470
506
|
// use origin's name; elem could have alias
|
|
@@ -587,11 +623,12 @@ function tweakAssocs( model ) {
|
|
|
587
623
|
|
|
588
624
|
function rewritePath( ref, item, assoc, elem, location ) {
|
|
589
625
|
const { path } = ref;
|
|
590
|
-
|
|
626
|
+
const root = path[0];
|
|
591
627
|
if (!elem) {
|
|
592
628
|
if (location) {
|
|
629
|
+
const elemref = root._navigation?.kind === '$self' ? path.slice(1) : path;
|
|
593
630
|
error( 'rewrite-not-projected', [ location, assoc ], {
|
|
594
|
-
name: assoc.name.id, art: item._artifact, elemref: { ref:
|
|
631
|
+
name: assoc.name.id, art: item._artifact, elemref: { ref: elemref },
|
|
595
632
|
}, {
|
|
596
633
|
std: 'Projected association $(NAME) uses non-projected element $(ELEMREF)',
|
|
597
634
|
element: 'Projected association $(NAME) uses non-projected element $(ELEMREF) of $(ART)',
|
|
@@ -614,10 +651,7 @@ function tweakAssocs( model ) {
|
|
|
614
651
|
}
|
|
615
652
|
}
|
|
616
653
|
else if (elem.name.id.charAt(0) === '$') {
|
|
617
|
-
|
|
618
|
-
path.unshift( root );
|
|
619
|
-
setLink( root, '_navigation', assoc._parent.$tableAliases.$self );
|
|
620
|
-
setArtifactLink( root, assoc._parent );
|
|
654
|
+
prependSelfToPath( path, assoc );
|
|
621
655
|
}
|
|
622
656
|
else {
|
|
623
657
|
setLink( root, '_navigation', elem );
|
|
@@ -644,6 +678,13 @@ function tweakAssocs( model ) {
|
|
|
644
678
|
setArtifactLink( ref, state );
|
|
645
679
|
}
|
|
646
680
|
|
|
681
|
+
function prependSelfToPath( path, elem ) {
|
|
682
|
+
const root = { id: '$self', location: path[0].location };
|
|
683
|
+
path.unshift( root );
|
|
684
|
+
setLink( root, '_navigation', elem._parent.$tableAliases.$self );
|
|
685
|
+
setArtifactLink( root, elem._parent );
|
|
686
|
+
}
|
|
687
|
+
|
|
647
688
|
function rewriteItem( elem, item, name, assoc, forKeys ) {
|
|
648
689
|
if (!elem._redirected)
|
|
649
690
|
return true;
|
package/lib/compiler/utils.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
const { dictAdd, pushToDict, dictFirst } = require('../base/dictionaries');
|
|
14
|
+
const { weakLocation } = require('../base/location');
|
|
14
15
|
const { XsnName, XsnArtifact, CsnLocation } = require('./classes');
|
|
15
16
|
|
|
16
17
|
const $inferred = Symbol.for( 'cds.$inferred' );
|
|
@@ -89,10 +90,11 @@ function setArtifactLink( obj, value ) {
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
function linkToOrigin( origin, name, parent, prop, location, silentDep ) {
|
|
93
|
+
location ||= weakLocation( origin.name.location ); // not ??=
|
|
92
94
|
const elem = {
|
|
93
|
-
name: { location:
|
|
95
|
+
name: { location, id: origin.name.id },
|
|
94
96
|
kind: origin.kind,
|
|
95
|
-
location
|
|
97
|
+
location,
|
|
96
98
|
};
|
|
97
99
|
if (origin.name.$inferred)
|
|
98
100
|
elem.name.$inferred = origin.name.$inferred;
|
|
@@ -101,6 +103,7 @@ function linkToOrigin( origin, name, parent, prop, location, silentDep ) {
|
|
|
101
103
|
setLink( elem, '_origin', origin );
|
|
102
104
|
// TODO: should we use silent dependencies also for other things, like
|
|
103
105
|
// included elements? (Currently for $inferred: 'expanded' only)
|
|
106
|
+
// TODO: shouldn't we always use silent dependencies in this function?
|
|
104
107
|
if (silentDep)
|
|
105
108
|
dependsOnSilent( elem, origin );
|
|
106
109
|
else
|
|
@@ -241,11 +244,11 @@ function augmentPath( location, ...args ) {
|
|
|
241
244
|
return { path: args.map( id => ({ id, location }) ), location };
|
|
242
245
|
}
|
|
243
246
|
|
|
244
|
-
function copyExpr( expr, location
|
|
247
|
+
function copyExpr( expr, location ) {
|
|
245
248
|
if (!expr || typeof expr !== 'object')
|
|
246
249
|
return expr;
|
|
247
250
|
else if (Array.isArray( expr ))
|
|
248
|
-
return expr.map( e => copyExpr( e, location
|
|
251
|
+
return expr.map( e => copyExpr( e, location ) );
|
|
249
252
|
|
|
250
253
|
const proto = Object.getPrototypeOf( expr );
|
|
251
254
|
if (proto && proto !== Object.prototype && proto !== XsnName.prototype &&
|
|
@@ -255,23 +258,17 @@ function copyExpr( expr, location, skipUnderscored, rewritePath ) {
|
|
|
255
258
|
const r = Object.create( proto );
|
|
256
259
|
for (const prop of Object.getOwnPropertyNames( expr )) {
|
|
257
260
|
const pd = Object.getOwnPropertyDescriptor( expr, prop );
|
|
258
|
-
if (!
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
else if (!proto) {
|
|
264
|
-
r[prop] = copyExpr( pd.value, location, skipUnderscored, rewritePath );
|
|
265
|
-
}
|
|
266
|
-
else if (prop === 'location') {
|
|
267
|
-
r[prop] = location || pd.value;
|
|
268
|
-
}
|
|
269
|
-
else if (prop.charAt(0) !== '$' || prop === '$inferred') {
|
|
270
|
-
r[prop] = copyExpr( pd.value, location, skipUnderscored, rewritePath );
|
|
271
|
-
}
|
|
272
|
-
else if (!skipUnderscored) { // skip $ properties
|
|
261
|
+
if (!proto)
|
|
262
|
+
r[prop] = copyExpr( pd.value, location );
|
|
263
|
+
|
|
264
|
+
else if (!pd.enumerable || prop.charAt(0) === '$')
|
|
273
265
|
Object.defineProperty( r, prop, pd );
|
|
274
|
-
|
|
266
|
+
|
|
267
|
+
else if (prop === 'location')
|
|
268
|
+
r[prop] = location || pd.value;
|
|
269
|
+
|
|
270
|
+
else
|
|
271
|
+
r[prop] = copyExpr( pd.value, location );
|
|
275
272
|
}
|
|
276
273
|
return r;
|
|
277
274
|
}
|
|
@@ -558,8 +555,26 @@ function setExpandStatusAnnotate( elem, status ) {
|
|
|
558
555
|
}
|
|
559
556
|
|
|
560
557
|
function isDirectComposition( art ) {
|
|
561
|
-
const
|
|
562
|
-
return
|
|
558
|
+
const path = art.type?.path;
|
|
559
|
+
return path?.length === 1 && path[0].id === 'cds.Composition';
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function targetCantBeAspect( elem, calledForTargetAspectProp ) {
|
|
563
|
+
// Remark: we do not check `on` and `keys` here - the error should complain
|
|
564
|
+
// at the `on`/`keys`, not the aspect
|
|
565
|
+
if (!isDirectComposition( elem ) || elem.targetAspect && !calledForTargetAspectProp)
|
|
566
|
+
return (elem.type && !elem.type.$inferred) ? 'std' : 'redirected';
|
|
567
|
+
if (!elem._main)
|
|
568
|
+
return elem.kind; // type or annotation
|
|
569
|
+
// TODO: extra for "in many"?
|
|
570
|
+
let art = elem;
|
|
571
|
+
while (art.kind === 'element')
|
|
572
|
+
art = art._parent;
|
|
573
|
+
if (![ 'entity', 'aspect', 'event' ].includes( art.kind ))
|
|
574
|
+
return (art.kind !== 'mixin') ? art.kind : 'select';
|
|
575
|
+
return ((art.query || art.kind === 'event') && !(calledForTargetAspectProp && elem.target))
|
|
576
|
+
? art.kind
|
|
577
|
+
: elem._parent.kind === 'element' && 'sub';
|
|
563
578
|
}
|
|
564
579
|
|
|
565
580
|
function userQuery( user ) {
|
|
@@ -648,7 +663,8 @@ function artifactRefLocation( ref ) {
|
|
|
648
663
|
}
|
|
649
664
|
|
|
650
665
|
function compositionTextVariant( art, composition, association = 'std' ) {
|
|
651
|
-
|
|
666
|
+
const builtin = getUnderlyingBuiltinType( art );
|
|
667
|
+
return (!builtin._main && builtin.name.id === 'cds.Composition')
|
|
652
668
|
? composition
|
|
653
669
|
: association;
|
|
654
670
|
}
|
|
@@ -683,6 +699,7 @@ module.exports = {
|
|
|
683
699
|
setExpandStatus,
|
|
684
700
|
setExpandStatusAnnotate,
|
|
685
701
|
isDirectComposition,
|
|
702
|
+
targetCantBeAspect,
|
|
686
703
|
userQuery,
|
|
687
704
|
pathStartsWithSelf,
|
|
688
705
|
columnRefStartsWithSelf,
|
package/lib/edm/.eslintrc.json
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
"plugins": ["sonarjs"],
|
|
6
6
|
"extends": ["../../.eslintrc-ydkjsi.json", "plugin:sonarjs/recommended"],
|
|
7
7
|
"rules": {
|
|
8
|
+
"cds-compiler/message-no-quotes": "off",
|
|
9
|
+
"cds-compiler/message-template-string": "off",
|
|
8
10
|
"prefer-const": "error",
|
|
9
11
|
"quotes": ["error", "single", "avoid-escape"],
|
|
10
12
|
"prefer-template": "error",
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// facet definitions, optional could either be true or array of edm types
|
|
4
|
+
// remove indicates wether or not the canonic facet shall be removed when applying @odata.Type
|
|
5
|
+
const EdmTypeFacetMap = {
|
|
6
|
+
MaxLength: {
|
|
7
|
+
v2: true, v4: true, remove: true, optional: true,
|
|
8
|
+
},
|
|
9
|
+
Precision: {
|
|
10
|
+
v2: true, v4: true, remove: true, optional: true,
|
|
11
|
+
},
|
|
12
|
+
Scale: {
|
|
13
|
+
v2: true, v4: true, remove: true, optional: true, extra: 'sap:variable-scale',
|
|
14
|
+
},
|
|
15
|
+
SRID: { v4: true, remove: true, optional: true },
|
|
16
|
+
// 'FixedLength': { v2: true },
|
|
17
|
+
// 'Collation': { v2: true },
|
|
18
|
+
// 'Unicode': { v2: true, v4: true },
|
|
19
|
+
};
|
|
20
|
+
const EdmTypeFacetNames = Object.keys(EdmTypeFacetMap);
|
|
21
|
+
|
|
22
|
+
// Merged primitive type map with descriptions taken from V4 spec and filled up with V2 spec
|
|
23
|
+
const EdmPrimitiveTypeMap = {
|
|
24
|
+
'Edm.Binary': {
|
|
25
|
+
v2: true,
|
|
26
|
+
v4: true,
|
|
27
|
+
MaxLength: true,
|
|
28
|
+
FixedLength: true,
|
|
29
|
+
max: 1,
|
|
30
|
+
desc: 'Binary data',
|
|
31
|
+
},
|
|
32
|
+
'Edm.Boolean': {
|
|
33
|
+
v2: true,
|
|
34
|
+
v4: true,
|
|
35
|
+
exact: 0,
|
|
36
|
+
desc: 'Binary-valued logic',
|
|
37
|
+
},
|
|
38
|
+
'Edm.Byte': {
|
|
39
|
+
v2: true,
|
|
40
|
+
v4: true,
|
|
41
|
+
exact: 0,
|
|
42
|
+
desc: 'Unsigned 8-bit integer',
|
|
43
|
+
},
|
|
44
|
+
'Edm.Date': {
|
|
45
|
+
v4: true,
|
|
46
|
+
exact: 0,
|
|
47
|
+
desc: 'Date without a time-zone offset',
|
|
48
|
+
},
|
|
49
|
+
'Edm.DateTime': {
|
|
50
|
+
v2: true,
|
|
51
|
+
Precision: true,
|
|
52
|
+
max: 1,
|
|
53
|
+
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.',
|
|
54
|
+
},
|
|
55
|
+
'Edm.DateTimeOffset': {
|
|
56
|
+
v2: true,
|
|
57
|
+
v4: true,
|
|
58
|
+
Precision: true,
|
|
59
|
+
max: 1,
|
|
60
|
+
desc: 'Date and time with a time-zone offset, no leap seconds',
|
|
61
|
+
},
|
|
62
|
+
'Edm.Decimal': {
|
|
63
|
+
v2: true,
|
|
64
|
+
v4: true,
|
|
65
|
+
Precision: true,
|
|
66
|
+
Scale: true,
|
|
67
|
+
max: 2,
|
|
68
|
+
desc: 'Numeric values with decimal representation',
|
|
69
|
+
},
|
|
70
|
+
'Edm.Double': {
|
|
71
|
+
v2: true,
|
|
72
|
+
v4: true,
|
|
73
|
+
exact: 0,
|
|
74
|
+
desc: 'IEEE 754 binary64 floating-point number (15-17 decimal digits)',
|
|
75
|
+
},
|
|
76
|
+
'Edm.Duration': {
|
|
77
|
+
v4: true,
|
|
78
|
+
Precision: true,
|
|
79
|
+
max: 1,
|
|
80
|
+
desc: 'Signed duration in days, hours, minutes, and (sub)seconds',
|
|
81
|
+
},
|
|
82
|
+
'Edm.Guid': {
|
|
83
|
+
v2: true,
|
|
84
|
+
v4: true,
|
|
85
|
+
exact: 0,
|
|
86
|
+
desc: '16-byte (128-bit) unique identifier',
|
|
87
|
+
},
|
|
88
|
+
'Edm.Int16': {
|
|
89
|
+
v2: true,
|
|
90
|
+
v4: true,
|
|
91
|
+
exact: 0,
|
|
92
|
+
desc: 'Signed 16-bit integer',
|
|
93
|
+
},
|
|
94
|
+
'Edm.Int32': {
|
|
95
|
+
v2: true,
|
|
96
|
+
v4: true,
|
|
97
|
+
exact: 0,
|
|
98
|
+
desc: 'Signed 32-bit integer',
|
|
99
|
+
},
|
|
100
|
+
'Edm.Int64': {
|
|
101
|
+
v2: true,
|
|
102
|
+
v4: true,
|
|
103
|
+
exact: 0,
|
|
104
|
+
desc: 'Signed 64-bit integer',
|
|
105
|
+
},
|
|
106
|
+
'Edm.SByte': {
|
|
107
|
+
v2: true,
|
|
108
|
+
v4: true,
|
|
109
|
+
exact: 0,
|
|
110
|
+
desc: 'Signed 8-bit integer',
|
|
111
|
+
},
|
|
112
|
+
'Edm.Single': {
|
|
113
|
+
v2: true,
|
|
114
|
+
v4: true,
|
|
115
|
+
exact: 0,
|
|
116
|
+
desc: 'IEEE 754 binary32 floating-point number (6-9 decimal digits)',
|
|
117
|
+
},
|
|
118
|
+
'Edm.Stream': {
|
|
119
|
+
v4: true,
|
|
120
|
+
MaxLength: true,
|
|
121
|
+
max: 1,
|
|
122
|
+
desc: 'Binary data stream',
|
|
123
|
+
},
|
|
124
|
+
'Edm.String': {
|
|
125
|
+
v2: true,
|
|
126
|
+
v4: true,
|
|
127
|
+
MaxLength: true,
|
|
128
|
+
FixedLength: true,
|
|
129
|
+
Collation: true,
|
|
130
|
+
Unicode: true,
|
|
131
|
+
max: 1,
|
|
132
|
+
desc: 'Sequence of characters',
|
|
133
|
+
},
|
|
134
|
+
'Edm.Time': {
|
|
135
|
+
v2: true,
|
|
136
|
+
Precision: true,
|
|
137
|
+
max: 1,
|
|
138
|
+
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',
|
|
139
|
+
},
|
|
140
|
+
'Edm.TimeOfDay': {
|
|
141
|
+
v4: true,
|
|
142
|
+
Precision: true,
|
|
143
|
+
max: 1,
|
|
144
|
+
desc: 'Clock time 00:00-23:59:59.999999999999',
|
|
145
|
+
},
|
|
146
|
+
'Edm.Geography': {
|
|
147
|
+
v4: true,
|
|
148
|
+
SRID: true,
|
|
149
|
+
max: 1,
|
|
150
|
+
desc: 'Abstract base type for all Geography types',
|
|
151
|
+
},
|
|
152
|
+
'Edm.GeographyPoint': {
|
|
153
|
+
v4: true,
|
|
154
|
+
SRID: true,
|
|
155
|
+
max: 1,
|
|
156
|
+
desc: 'A point in a round-earth coordinate system',
|
|
157
|
+
},
|
|
158
|
+
'Edm.GeographyLineString': {
|
|
159
|
+
v4: true,
|
|
160
|
+
SRID: true,
|
|
161
|
+
max: 1,
|
|
162
|
+
desc: 'Line string in a round-earth coordinate system',
|
|
163
|
+
},
|
|
164
|
+
'Edm.GeographyPolygon': {
|
|
165
|
+
v4: true,
|
|
166
|
+
SRID: true,
|
|
167
|
+
max: 1,
|
|
168
|
+
desc: 'Polygon in a round-earth coordinate system',
|
|
169
|
+
},
|
|
170
|
+
'Edm.GeographyMultiPoint': {
|
|
171
|
+
v4: true,
|
|
172
|
+
SRID: true,
|
|
173
|
+
max: 1,
|
|
174
|
+
desc: 'Collection of points in a round-earth coordinate system',
|
|
175
|
+
},
|
|
176
|
+
'Edm.GeographyMultiLineString': {
|
|
177
|
+
v4: true,
|
|
178
|
+
SRID: true,
|
|
179
|
+
max: 1,
|
|
180
|
+
desc: 'Collection of line strings in a round-earth coordinate system',
|
|
181
|
+
},
|
|
182
|
+
'Edm.GeographyMultiPolygon': {
|
|
183
|
+
v4: true,
|
|
184
|
+
SRID: true,
|
|
185
|
+
max: 1,
|
|
186
|
+
desc: 'Collection of polygons in a round-earth coordinate system',
|
|
187
|
+
},
|
|
188
|
+
'Edm.GeographyCollection': {
|
|
189
|
+
v4: true,
|
|
190
|
+
SRID: true,
|
|
191
|
+
max: 1,
|
|
192
|
+
desc: 'Collection of arbitrary Geography values',
|
|
193
|
+
},
|
|
194
|
+
'Edm.Geometry': {
|
|
195
|
+
v4: true,
|
|
196
|
+
SRID: true,
|
|
197
|
+
max: 1,
|
|
198
|
+
desc: 'Abstract base type for all Geometry types',
|
|
199
|
+
},
|
|
200
|
+
'Edm.GeometryPoint': {
|
|
201
|
+
v4: true,
|
|
202
|
+
SRID: true,
|
|
203
|
+
max: 1,
|
|
204
|
+
desc: 'Point in a flat-earth coordinate system',
|
|
205
|
+
},
|
|
206
|
+
'Edm.GeometryLineString': {
|
|
207
|
+
v4: true,
|
|
208
|
+
SRID: true,
|
|
209
|
+
max: 1,
|
|
210
|
+
desc: 'Line string in a flat-earth coordinate system',
|
|
211
|
+
},
|
|
212
|
+
'Edm.GeometryPolygon': {
|
|
213
|
+
v4: true,
|
|
214
|
+
SRID: true,
|
|
215
|
+
max: 1,
|
|
216
|
+
descr: 'Polygon in a flat-earth coordinate system',
|
|
217
|
+
},
|
|
218
|
+
'Edm.GeometryMultiPoint': {
|
|
219
|
+
v4: true,
|
|
220
|
+
SRID: true,
|
|
221
|
+
max: 1,
|
|
222
|
+
desc: 'Collection of points in a flat-earth coordinate system',
|
|
223
|
+
},
|
|
224
|
+
'Edm.GeometryMultiLineString': {
|
|
225
|
+
v4: true,
|
|
226
|
+
SRID: true,
|
|
227
|
+
max: 1,
|
|
228
|
+
desc: 'Collection of line strings in a flat-earth coordinate system',
|
|
229
|
+
},
|
|
230
|
+
'Edm.GeometryMultiPolygon': {
|
|
231
|
+
v4: true,
|
|
232
|
+
SRID: true,
|
|
233
|
+
max: 1,
|
|
234
|
+
desc: 'Collection of polygons in a flat-earth coordinate system',
|
|
235
|
+
},
|
|
236
|
+
'Edm.GeometryCollection': {
|
|
237
|
+
v4: true,
|
|
238
|
+
SRID: true,
|
|
239
|
+
max: 1,
|
|
240
|
+
desc: 'Collection of arbitrary Geometry values',
|
|
241
|
+
},
|
|
242
|
+
'Edm.PrimitiveType': {
|
|
243
|
+
v4: true,
|
|
244
|
+
exact: 0,
|
|
245
|
+
desc: 'Abstract meta type',
|
|
246
|
+
},
|
|
247
|
+
// 'Edm.Untyped': { v4: true, desc: 'Abstract void type' },
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
module.exports = {
|
|
251
|
+
EdmTypeFacetMap, EdmTypeFacetNames, EdmPrimitiveTypeMap,
|
|
252
|
+
};
|