@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.
Files changed (128) hide show
  1. package/CHANGELOG.md +221 -15
  2. package/bin/cdsc.js +125 -50
  3. package/bin/cdsse.js +2 -2
  4. package/doc/CHANGELOG_BETA.md +13 -6
  5. package/doc/CHANGELOG_DEPRECATED.md +22 -6
  6. package/doc/NameResolution.md +21 -16
  7. package/lib/api/main.js +47 -84
  8. package/lib/api/options.js +5 -6
  9. package/lib/api/validate.js +6 -11
  10. package/lib/backends.js +15 -23
  11. package/lib/base/dictionaries.js +0 -8
  12. package/lib/base/error.js +26 -0
  13. package/lib/base/keywords.js +7 -17
  14. package/lib/base/location.js +9 -4
  15. package/lib/base/message-registry.js +114 -18
  16. package/lib/base/messages.js +101 -90
  17. package/lib/base/model.js +2 -63
  18. package/lib/base/optionProcessorHelper.js +177 -123
  19. package/lib/checks/annotationsOData.js +12 -33
  20. package/lib/checks/arrayOfs.js +1 -34
  21. package/lib/checks/cdsPersistence.js +2 -1
  22. package/lib/checks/enricher.js +17 -1
  23. package/lib/checks/invalidTarget.js +3 -1
  24. package/lib/checks/managedWithoutKeys.js +3 -1
  25. package/lib/checks/selectItems.js +4 -4
  26. package/lib/checks/sql-snippets.js +27 -26
  27. package/lib/checks/types.js +1 -1
  28. package/lib/checks/validator.js +6 -11
  29. package/lib/compiler/assert-consistency.js +6 -3
  30. package/lib/compiler/base.js +1 -0
  31. package/lib/compiler/builtins.js +19 -6
  32. package/lib/compiler/checks.js +23 -60
  33. package/lib/compiler/cycle-detector.js +1 -1
  34. package/lib/compiler/define.js +1151 -0
  35. package/lib/compiler/extend.js +1000 -0
  36. package/lib/compiler/finalize-parse-cdl.js +237 -0
  37. package/lib/compiler/index.js +107 -39
  38. package/lib/compiler/kick-start.js +190 -0
  39. package/lib/compiler/moduleLayers.js +4 -4
  40. package/lib/compiler/populate.js +1227 -0
  41. package/lib/compiler/propagator.js +114 -46
  42. package/lib/compiler/resolve.js +1521 -0
  43. package/lib/compiler/shared.js +126 -65
  44. package/lib/compiler/tweak-assocs.js +535 -0
  45. package/lib/compiler/utils.js +197 -33
  46. package/lib/edm/.eslintrc.json +5 -0
  47. package/lib/edm/annotations/genericTranslation.js +38 -24
  48. package/lib/edm/annotations/preprocessAnnotations.js +2 -2
  49. package/lib/edm/csn2edm.js +219 -100
  50. package/lib/edm/edm.js +302 -230
  51. package/lib/edm/edmPreprocessor.js +554 -419
  52. package/lib/edm/edmUtils.js +138 -44
  53. package/lib/gen/Dictionary.json +100 -19
  54. package/lib/gen/language.checksum +1 -1
  55. package/lib/gen/language.interp +11 -1
  56. package/lib/gen/language.tokens +86 -83
  57. package/lib/gen/languageLexer.interp +10 -1
  58. package/lib/gen/languageLexer.js +860 -833
  59. package/lib/gen/languageLexer.tokens +78 -75
  60. package/lib/gen/languageParser.js +5765 -4480
  61. package/lib/json/csnVersion.js +10 -11
  62. package/lib/json/from-csn.js +15 -3
  63. package/lib/json/to-csn.js +126 -68
  64. package/lib/language/docCommentParser.js +4 -4
  65. package/lib/language/genericAntlrParser.js +123 -5
  66. package/lib/language/language.g4 +355 -156
  67. package/lib/language/multiLineStringParser.js +5 -5
  68. package/lib/main.d.ts +486 -59
  69. package/lib/main.js +41 -9
  70. package/lib/model/api.js +3 -1
  71. package/lib/model/csnRefs.js +252 -156
  72. package/lib/model/csnUtils.js +384 -297
  73. package/lib/model/enrichCsn.js +71 -29
  74. package/lib/model/revealInternalProperties.js +29 -8
  75. package/lib/model/sortViews.js +2 -1
  76. package/lib/modelCompare/compare.js +23 -18
  77. package/lib/optionProcessor.js +63 -26
  78. package/lib/render/manageConstraints.js +35 -32
  79. package/lib/render/toCdl.js +897 -947
  80. package/lib/render/toHdbcds.js +205 -257
  81. package/lib/render/toSql.js +264 -225
  82. package/lib/render/utils/common.js +136 -25
  83. package/lib/render/utils/sql.js +4 -3
  84. package/lib/render/utils/stringEscapes.js +111 -0
  85. package/lib/sql-identifier.js +1 -1
  86. package/lib/transform/.eslintrc.json +5 -0
  87. package/lib/transform/db/.eslintrc.json +3 -1
  88. package/lib/transform/db/applyTransformations.js +35 -12
  89. package/lib/transform/db/assertUnique.js +1 -1
  90. package/lib/transform/db/associations.js +104 -306
  91. package/lib/transform/db/cdsPersistence.js +2 -2
  92. package/lib/transform/db/constraints.js +58 -53
  93. package/lib/transform/db/expansion.js +60 -33
  94. package/lib/transform/db/flattening.js +582 -104
  95. package/lib/transform/db/groupByOrderBy.js +3 -1
  96. package/lib/transform/db/transformExists.js +66 -13
  97. package/lib/transform/db/views.js +11 -7
  98. package/lib/transform/draft/.eslintrc.json +38 -0
  99. package/lib/transform/{db/draft.js → draft/db.js} +6 -5
  100. package/lib/transform/draft/odata.js +227 -0
  101. package/lib/transform/forHanaNew.js +109 -208
  102. package/lib/transform/forOdataNew.js +59 -212
  103. package/lib/transform/localized.js +46 -26
  104. package/lib/transform/odata/toFinalBaseType.js +85 -11
  105. package/lib/transform/odata/typesExposure.js +147 -199
  106. package/lib/transform/odata/utils.js +2 -2
  107. package/lib/transform/transformUtilsNew.js +44 -33
  108. package/lib/transform/translateAssocsToJoins.js +3 -20
  109. package/lib/transform/universalCsn/.eslintrc.json +36 -0
  110. package/lib/transform/universalCsn/coreComputed.js +172 -0
  111. package/lib/transform/universalCsn/universalCsnEnricher.js +737 -0
  112. package/lib/transform/universalCsn/utils.js +63 -0
  113. package/lib/utils/moduleResolve.js +13 -6
  114. package/lib/utils/objectUtils.js +30 -0
  115. package/package.json +1 -1
  116. package/share/messages/README.md +26 -0
  117. package/share/messages/message-explanations.json +2 -1
  118. package/share/messages/syntax-expected-integer.md +37 -0
  119. package/lib/compiler/definer.js +0 -2361
  120. package/lib/compiler/resolver.js +0 -3079
  121. package/lib/transform/odata/attachPath.js +0 -96
  122. package/lib/transform/odata/expandStructKeysInAssociations.js +0 -59
  123. package/lib/transform/odata/generateForeignKeyElements.js +0 -261
  124. package/lib/transform/odata/referenceFlattener.js +0 -290
  125. package/lib/transform/odata/sortByAssociationDependency.js +0 -105
  126. package/lib/transform/odata/structuralPath.js +0 -72
  127. package/lib/transform/odata/structureFlattener.js +0 -171
  128. package/lib/transform/universalCsnEnricher.js +0 -237
@@ -8,6 +8,7 @@ const {
8
8
  } = require('../../model/csnUtils');
9
9
  const { csnRefs, implicitAs } = require('../../model/csnRefs');
10
10
  const { setProp, isBetaEnabled } = require('../../base/model');
11
+ const { forEach } = require('../../utils/objectUtils');
11
12
 
12
13
  /**
13
14
  * For keys, columns, groupBy and orderBy, expand structured things.
@@ -19,9 +20,10 @@ const { setProp, isBetaEnabled } = require('../../base/model');
19
20
  * @param {object} messageFunctions
20
21
  * @param {Function} messageFunctions.error
21
22
  * @param {Function} messageFunctions.info
22
- * @param {Function} messageFunctions.throwWithError
23
+ * @param {Function} messageFunctions.throwWithAnyError
24
+ * @param {object} iterateOptions
23
25
  */
24
- function expandStructureReferences(csn, options, pathDelimiter, { error, info, throwWithError }) {
26
+ function expandStructureReferences(csn, options, pathDelimiter, { error, info, throwWithAnyError }, iterateOptions = {}) {
25
27
  const {
26
28
  isStructured, get$combined, getFinalBaseType, getServiceName,
27
29
  } = getUtils(csn);
@@ -39,7 +41,11 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
39
41
  const artifact = csn.definitions[path[1]];
40
42
  if (!hasAnnotationValue(artifact, '@cds.persistence.table')) {
41
43
  const root = get$combined({ SELECT: parent });
42
- parent.columns = replaceStar(root, columns, parent.excluding);
44
+ // TODO: replace with the correct options.transformation?
45
+ // Do not expand the * in OData for a moment, not to introduce changes
46
+ // while the OData CSN is still official
47
+ if (!options.toOdata)
48
+ parent.columns = replaceStar(root, columns, parent.excluding);
43
49
  parent.columns = expand(parent.columns, path.concat('columns'), true);
44
50
  }
45
51
  },
@@ -49,7 +55,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
49
55
  orderBy: (parent, name, orderBy, path) => {
50
56
  parent.orderBy = expand(orderBy, path.concat('orderBy'));
51
57
  },
52
- });
58
+ }, [], iterateOptions);
53
59
 
54
60
  /**
55
61
  * Turn .expand/.inline into normal refs. @cds.persistence.skip .expand with to-many (and all transitive views).
@@ -71,16 +77,25 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
71
77
  if (!hasAnnotationValue(artifact, '@cds.persistence.table')) {
72
78
  const rewritten = rewrite(root, parent.columns, parent.excluding);
73
79
  parent.columns = rewritten.columns;
74
- if (rewritten.toMany.length > 0) {
80
+ /*
81
+ * Do not remove unexpandable many columns in OData
82
+ */
83
+ if (rewritten.toMany.length > 0 && !options.toOdata) {
75
84
  markAsToDummyfy(artifact, path[1]);
76
85
  if (getServiceName(path[1]) === null)
77
86
  error( null, [ 'definitions', path[1] ], { name: path[1] }, 'Unexpected .expand with to-many association in entity $(NAME), which is outside any service');
78
87
  }
88
+ else {
89
+ parent.columns = rewritten.columns;
90
+ }
79
91
  }
80
92
  },
81
93
  });
82
94
 
83
- dummyfy();
95
+ // OData must keep @cds.persistence.skip definitions
96
+ // to present them in the API (and CSN)
97
+ if (!options.toOdata)
98
+ dummyfy();
84
99
 
85
100
  cleanup.forEach(fn => fn());
86
101
 
@@ -88,23 +103,26 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
88
103
 
89
104
 
90
105
  const publishing = [];
91
-
92
- applyTransformations(csn, {
93
- target: (parent, name, target, path) => {
94
- if (toDummyfy.indexOf(target) !== -1) {
95
- publishing.push({
96
- parent, name, target, path: [ ...path ],
97
- });
98
- }
99
- },
100
- from: check,
101
- columns: check,
102
- where: check,
103
- groupBy: check,
104
- orderBy: check,
105
- having: check,
106
- limit: check,
107
- });
106
+ // OData must allow navigations to @cds.persistence.skip targets
107
+ // as valid navigations in the API
108
+ if (!options.toOdata) {
109
+ applyTransformations(csn, {
110
+ target: (parent, name, target, path) => {
111
+ if (toDummyfy.indexOf(target) !== -1) {
112
+ publishing.push({
113
+ parent, name, target, path: [ ...path ],
114
+ });
115
+ }
116
+ },
117
+ from: check,
118
+ columns: check,
119
+ where: check,
120
+ groupBy: check,
121
+ orderBy: check,
122
+ having: check,
123
+ limit: check,
124
+ });
125
+ }
108
126
 
109
127
 
110
128
  /**
@@ -165,7 +183,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
165
183
  }
166
184
 
167
185
  // We would be broken if we continue with assoc usage to now skipped
168
- throwWithError();
186
+ throwWithAnyError();
169
187
 
170
188
 
171
189
  for (const {
@@ -194,7 +212,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
194
212
  while (stack.length > 0) {
195
213
  const [ a, n ] = stack.pop();
196
214
  if (a[_dependents]) {
197
- Object.entries(a[_dependents]).forEach(([ dependentName, dependent ]) => {
215
+ forEach(a[_dependents], (dependentName, dependent) => {
198
216
  stack.push([ dependent, dependentName ]);
199
217
  });
200
218
  }
@@ -236,7 +254,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
236
254
  /**
237
255
  * Rewrite expand and inline to "normal" refs
238
256
  *
239
- * @param {CSN.Artifact} root All elements visible fromt he query source ($combined)
257
+ * @param {CSN.Artifact} root All elements visible from the query source ($combined)
240
258
  * @param {CSN.Column[]} columns
241
259
  * @param {string[]} excluding
242
260
  * @returns {{columns: Array, toMany: Array}} Object with rewritten columns (.expand/.inline) and with any .expand + to-many
@@ -244,8 +262,12 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
244
262
  function rewrite(root, columns, excluding) {
245
263
  const allToMany = [];
246
264
  const newThing = [];
247
- // Replace stars - needs to happen here since the .expand/.inline first path step affects the root *
248
- columns = replaceStar(root, columns, excluding);
265
+ const containsExpandInline = columns.some(col => col.expand || col.inline);
266
+ if (containsExpandInline) // Replace stars - needs to happen before resolving .expand/.inline since the .expand/.inline first path step affects the root *
267
+ columns = replaceStar(root, columns, excluding);
268
+ else
269
+ return { columns, toMany: [] };
270
+
249
271
  for (const col of columns) {
250
272
  if (col.expand) {
251
273
  // TODO: Can col.ref be empty without an as? Assumption is it cannot - if it has, it's an error, we throw, compiler checks.
@@ -269,7 +291,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
269
291
  }
270
292
 
271
293
  /**
272
- * Check wether the given object is a to-many association
294
+ * Check whether the given object is a to-many association
273
295
  *
274
296
  * @param {CSN.Element} obj
275
297
  * @returns {boolean}
@@ -301,6 +323,11 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
301
323
  while (stack.length > 0) {
302
324
  const [ base, current, currentRef, currentAlias ] = stack.pop();
303
325
  if (isToMany(current) && current.expand) {
326
+ expanded.push({
327
+ expand: current.expand,
328
+ ref: currentRef,
329
+ as: currentAlias.join(pathDelimiter),
330
+ });
304
331
  toManys.push({ art: current, ref: currentRef, as: currentAlias.join(pathDelimiter) });
305
332
  }
306
333
  else if (current.expand) {
@@ -380,8 +407,8 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
380
407
  * @returns {string|null} Name of any entity
381
408
  */
382
409
  function findAnEntity() {
383
- for (const [ name, artifact ] of Object.entries(csn.definitions)) {
384
- if (artifact.kind === 'entity' && !artifact.query)
410
+ for (const name in csn.definitions) {
411
+ if (Object.hasOwnProperty.call(csn.definitions, name) && csn.definitions[name].kind === 'entity' && !csn.definitions[name].query)
385
412
  return name;
386
413
  }
387
414
  return null;
@@ -435,7 +462,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
435
462
  *
436
463
  * @param {Array} thing
437
464
  * @param {CSN.Path} path
438
- * @param {boolean} [withAlias=false] Wether to "expand" the (implicit) alias aswell.
465
+ * @param {boolean} [withAlias=false] Whether to "expand" the (implicit) alias aswell.
439
466
  * @returns {Array} New array - with all structured things expanded
440
467
  */
441
468
  function expand(thing, path, withAlias = false) {
@@ -522,7 +549,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
522
549
  /**
523
550
  * Replace the star and correctly put shadowed things in the right place.
524
551
  *
525
- * @param {Object} base The raw set of things a * can expand to
552
+ * @param {object} base The raw set of things a * can expand to
526
553
  * @param {Array} subs Things - the .expand/.inline or .columns
527
554
  * @param {string[]} [excluding=[]]
528
555
  * @returns {Array} If there was a star, expand it and handle shadowing/excluding, else just return subs