@sap/cds-compiler 4.3.2 → 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.
Files changed (81) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/lib/api/main.js +14 -24
  3. package/lib/api/options.js +1 -0
  4. package/lib/api/trace.js +38 -0
  5. package/lib/base/location.js +46 -1
  6. package/lib/base/message-registry.js +68 -16
  7. package/lib/base/messages.js +8 -3
  8. package/lib/checks/.eslintrc.json +1 -0
  9. package/lib/checks/actionsFunctions.js +1 -1
  10. package/lib/checks/annotationsOData.js +2 -2
  11. package/lib/checks/selectItems.js +4 -1
  12. package/lib/compiler/assert-consistency.js +3 -2
  13. package/lib/compiler/base.js +1 -1
  14. package/lib/compiler/builtins.js +25 -1
  15. package/lib/compiler/checks.js +6 -5
  16. package/lib/compiler/define.js +12 -10
  17. package/lib/compiler/extend.js +22 -22
  18. package/lib/compiler/finalize-parse-cdl.js +1 -1
  19. package/lib/compiler/generate.js +70 -53
  20. package/lib/compiler/kick-start.js +7 -5
  21. package/lib/compiler/populate.js +31 -22
  22. package/lib/compiler/propagator.js +6 -2
  23. package/lib/compiler/resolve.js +52 -17
  24. package/lib/compiler/shared.js +74 -38
  25. package/lib/compiler/tweak-assocs.js +64 -23
  26. package/lib/compiler/utils.js +40 -23
  27. package/lib/edm/.eslintrc.json +2 -0
  28. package/lib/edm/EdmPrimitiveTypeDefinitions.js +252 -0
  29. package/lib/edm/annotations/edmJson.js +994 -0
  30. package/lib/edm/annotations/genericTranslation.js +75 -421
  31. package/lib/edm/annotations/vocabularyDefinitions.js +160 -0
  32. package/lib/edm/csn2edm.js +12 -5
  33. package/lib/edm/edm.js +14 -73
  34. package/lib/edm/edmPreprocessor.js +6 -0
  35. package/lib/gen/Dictionary.json +187 -16
  36. package/lib/gen/language.checksum +1 -1
  37. package/lib/gen/language.interp +1 -1
  38. package/lib/gen/languageLexer.interp +1 -1
  39. package/lib/gen/languageLexer.js +1129 -671
  40. package/lib/gen/languageParser.js +4285 -4283
  41. package/lib/json/from-csn.js +13 -18
  42. package/lib/json/to-csn.js +11 -6
  43. package/lib/language/antlrParser.js +0 -1
  44. package/lib/language/docCommentParser.js +1 -1
  45. package/lib/language/errorStrategy.js +95 -30
  46. package/lib/language/genericAntlrParser.js +21 -1
  47. package/lib/main.js +13 -3
  48. package/lib/model/csnRefs.js +42 -8
  49. package/lib/model/csnUtils.js +14 -2
  50. package/lib/model/enrichCsn.js +33 -5
  51. package/lib/model/revealInternalProperties.js +5 -0
  52. package/lib/modelCompare/compare.js +76 -14
  53. package/lib/modelCompare/utils/filter.js +19 -12
  54. package/lib/optionProcessor.js +2 -0
  55. package/lib/render/.eslintrc.json +1 -1
  56. package/lib/render/manageConstraints.js +1 -0
  57. package/lib/render/toHdbcds.js +3 -0
  58. package/lib/render/toRename.js +3 -1
  59. package/lib/render/toSql.js +46 -92
  60. package/lib/render/utils/common.js +76 -0
  61. package/lib/render/utils/delta.js +17 -3
  62. package/lib/sql-identifier.js +1 -1
  63. package/lib/transform/db/.eslintrc.json +1 -0
  64. package/lib/transform/db/applyTransformations.js +30 -4
  65. package/lib/transform/db/associations.js +22 -10
  66. package/lib/transform/db/backlinks.js +6 -2
  67. package/lib/transform/db/expansion.js +2 -2
  68. package/lib/transform/db/transformExists.js +13 -39
  69. package/lib/transform/draft/db.js +14 -3
  70. package/lib/transform/draft/odata.js +5 -18
  71. package/lib/transform/effective/associations.js +46 -15
  72. package/lib/transform/effective/main.js +7 -2
  73. package/lib/transform/effective/misc.js +43 -24
  74. package/lib/transform/effective/queries.js +20 -22
  75. package/lib/transform/effective/types.js +6 -2
  76. package/lib/transform/forOdata.js +5 -2
  77. package/lib/transform/localized.js +1 -1
  78. package/lib/transform/parseExpr.js +73 -21
  79. package/lib/transform/translateAssocsToJoins.js +22 -15
  80. package/lib/utils/term.js +2 -2
  81. 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 do
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', excludeAssociation );
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 excludeAssociation( elem ) {
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
- if (!elem.$inferred) { // && !elem.target.$inferred
103
- info( 'assoc-target-not-in-service', [ elem.target.location, elem ],
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', [ elem.target.location, elem ],
115
- { target },
116
- 'Association target $(TARGET) is outside any service' );
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 fk = linkToOrigin( orig, name, elem, 'foreignKeys', elem.location );
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
- // TODO: re-check for case that foreign key is managed association
283
- if (orig._effectiveType !== undefined)
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
- let root = path[0];
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: path },
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
- root = { id: '$self', location: item.location };
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;
@@ -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: location || origin.name.location, id: name },
95
+ name: { location, id: origin.name.id },
94
96
  kind: origin.kind,
95
- location: location || origin.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, skipUnderscored, rewritePath ) {
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, skipUnderscored, rewritePath ) );
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 (!pd.enumerable) { // should include all properties starting with _
259
- if (!skipUnderscored ||
260
- prop === '_artifact' || prop === '_navigation' || prop === '_effectiveType')
261
- Object.defineProperty( r, prop, pd );
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 type = art.type && art.type.path;
562
- return type && type[0] && type[0].id === 'cds.Composition';
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
- return (getUnderlyingBuiltinType( art )?.name.absolute === 'cds.Composition')
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,
@@ -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
+ };