@sap/cds-compiler 2.11.2 → 2.13.6

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 (140) hide show
  1. package/CHANGELOG.md +175 -2
  2. package/bin/.eslintrc.json +1 -2
  3. package/bin/cds_update_identifiers.js +10 -8
  4. package/bin/cdsc.js +23 -17
  5. package/bin/cdsse.js +2 -2
  6. package/bin/cdsv2m.js +3 -2
  7. package/doc/CHANGELOG_ARCHIVE.md +1 -1
  8. package/doc/CHANGELOG_BETA.md +25 -6
  9. package/doc/CHANGELOG_DEPRECATED.md +22 -6
  10. package/doc/NameResolution.md +21 -16
  11. package/lib/api/main.js +32 -79
  12. package/lib/api/options.js +3 -2
  13. package/lib/api/validate.js +2 -1
  14. package/lib/backends.js +16 -26
  15. package/lib/base/dictionaries.js +0 -8
  16. package/lib/base/error.js +26 -0
  17. package/lib/base/keywords.js +10 -19
  18. package/lib/base/location.js +9 -4
  19. package/lib/base/message-registry.js +75 -9
  20. package/lib/base/messages.js +31 -35
  21. package/lib/base/model.js +2 -62
  22. package/lib/base/optionProcessorHelper.js +246 -183
  23. package/lib/checks/.eslintrc.json +2 -0
  24. package/lib/checks/actionsFunctions.js +2 -1
  25. package/lib/checks/annotationsOData.js +1 -1
  26. package/lib/checks/cdsPersistence.js +2 -1
  27. package/lib/checks/emptyOrOnlyVirtual.js +2 -2
  28. package/lib/checks/enricher.js +17 -1
  29. package/lib/checks/foreignKeys.js +4 -4
  30. package/lib/checks/invalidTarget.js +3 -1
  31. package/lib/checks/managedInType.js +4 -4
  32. package/lib/checks/managedWithoutKeys.js +3 -1
  33. package/lib/checks/queryNoDbArtifacts.js +1 -3
  34. package/lib/checks/selectItems.js +4 -4
  35. package/lib/checks/sql-snippets.js +94 -0
  36. package/lib/checks/types.js +1 -1
  37. package/lib/checks/unknownMagic.js +1 -1
  38. package/lib/checks/validator.js +12 -7
  39. package/lib/compiler/assert-consistency.js +12 -8
  40. package/lib/compiler/base.js +0 -1
  41. package/lib/compiler/builtins.js +42 -21
  42. package/lib/compiler/checks.js +46 -12
  43. package/lib/compiler/cycle-detector.js +1 -1
  44. package/lib/compiler/define.js +1103 -0
  45. package/lib/compiler/extend.js +983 -0
  46. package/lib/compiler/finalize-parse-cdl.js +231 -0
  47. package/lib/compiler/index.js +46 -39
  48. package/lib/compiler/kick-start.js +190 -0
  49. package/lib/compiler/moduleLayers.js +4 -4
  50. package/lib/compiler/populate.js +1226 -0
  51. package/lib/compiler/propagator.js +113 -47
  52. package/lib/compiler/resolve.js +1433 -0
  53. package/lib/compiler/shared.js +100 -65
  54. package/lib/compiler/tweak-assocs.js +529 -0
  55. package/lib/compiler/utils.js +215 -33
  56. package/lib/edm/.eslintrc.json +5 -0
  57. package/lib/edm/annotations/genericTranslation.js +38 -25
  58. package/lib/edm/annotations/preprocessAnnotations.js +3 -3
  59. package/lib/edm/csn2edm.js +10 -9
  60. package/lib/edm/edm.js +19 -20
  61. package/lib/edm/edmPreprocessor.js +166 -95
  62. package/lib/edm/edmUtils.js +127 -34
  63. package/lib/gen/Dictionary.json +92 -43
  64. package/lib/gen/language.checksum +1 -1
  65. package/lib/gen/language.interp +11 -1
  66. package/lib/gen/language.tokens +86 -82
  67. package/lib/gen/languageLexer.interp +18 -1
  68. package/lib/gen/languageLexer.js +925 -847
  69. package/lib/gen/languageLexer.tokens +78 -74
  70. package/lib/gen/languageParser.js +5434 -4298
  71. package/lib/json/from-csn.js +59 -17
  72. package/lib/json/to-csn.js +189 -71
  73. package/lib/language/antlrParser.js +3 -3
  74. package/lib/language/docCommentParser.js +3 -3
  75. package/lib/language/errorStrategy.js +26 -8
  76. package/lib/language/genericAntlrParser.js +144 -53
  77. package/lib/language/language.g4 +424 -200
  78. package/lib/language/multiLineStringParser.js +536 -0
  79. package/lib/main.d.ts +550 -61
  80. package/lib/main.js +38 -11
  81. package/lib/model/api.js +3 -1
  82. package/lib/model/csnRefs.js +322 -198
  83. package/lib/model/csnUtils.js +226 -370
  84. package/lib/model/enrichCsn.js +124 -69
  85. package/lib/model/revealInternalProperties.js +29 -7
  86. package/lib/model/sortViews.js +10 -2
  87. package/lib/modelCompare/compare.js +17 -12
  88. package/lib/optionProcessor.js +8 -3
  89. package/lib/render/.eslintrc.json +1 -2
  90. package/lib/render/DuplicateChecker.js +1 -1
  91. package/lib/render/manageConstraints.js +36 -33
  92. package/lib/render/toCdl.js +174 -275
  93. package/lib/render/toHdbcds.js +203 -122
  94. package/lib/render/toRename.js +7 -10
  95. package/lib/render/toSql.js +161 -82
  96. package/lib/render/utils/common.js +22 -8
  97. package/lib/render/utils/sql.js +10 -7
  98. package/lib/render/utils/stringEscapes.js +111 -0
  99. package/lib/sql-identifier.js +1 -1
  100. package/lib/transform/.eslintrc.json +5 -0
  101. package/lib/transform/braceExpression.js +4 -2
  102. package/lib/transform/db/.eslintrc.json +2 -0
  103. package/lib/transform/db/applyTransformations.js +212 -0
  104. package/lib/transform/db/assertUnique.js +1 -1
  105. package/lib/transform/db/associations.js +187 -0
  106. package/lib/transform/db/cdsPersistence.js +150 -0
  107. package/lib/transform/db/constraints.js +61 -56
  108. package/lib/transform/db/expansion.js +50 -29
  109. package/lib/transform/db/flattening.js +556 -106
  110. package/lib/transform/db/groupByOrderBy.js +3 -1
  111. package/lib/transform/db/temporal.js +236 -0
  112. package/lib/transform/db/transformExists.js +103 -28
  113. package/lib/transform/db/views.js +92 -44
  114. package/lib/transform/draft/.eslintrc.json +38 -0
  115. package/lib/transform/{db/draft.js → draft/db.js} +9 -7
  116. package/lib/transform/draft/odata.js +227 -0
  117. package/lib/transform/forHanaNew.js +98 -783
  118. package/lib/transform/forOdataNew.js +22 -175
  119. package/lib/transform/localized.js +36 -32
  120. package/lib/transform/odata/generateForeignKeyElements.js +3 -3
  121. package/lib/transform/odata/referenceFlattener.js +95 -89
  122. package/lib/transform/odata/structureFlattener.js +1 -1
  123. package/lib/transform/odata/toFinalBaseType.js +86 -12
  124. package/lib/transform/odata/typesExposure.js +5 -5
  125. package/lib/transform/odata/utils.js +2 -2
  126. package/lib/transform/transformUtilsNew.js +47 -33
  127. package/lib/transform/translateAssocsToJoins.js +13 -30
  128. package/lib/transform/universalCsn/.eslintrc.json +36 -0
  129. package/lib/transform/universalCsn/coreComputed.js +170 -0
  130. package/lib/transform/universalCsn/universalCsnEnricher.js +715 -0
  131. package/lib/transform/universalCsn/utils.js +63 -0
  132. package/lib/utils/file.js +8 -3
  133. package/lib/utils/objectUtils.js +30 -0
  134. package/lib/utils/timetrace.js +8 -2
  135. package/package.json +1 -1
  136. package/share/messages/README.md +26 -0
  137. package/lib/compiler/definer.js +0 -2349
  138. package/lib/compiler/resolver.js +0 -2922
  139. package/lib/transform/db/helpers.js +0 -58
  140. package/lib/transform/universalCsnEnricher.js +0 -67
@@ -20,8 +20,9 @@ const { setProp, isBetaEnabled } = require('../../base/model');
20
20
  * @param {Function} messageFunctions.error
21
21
  * @param {Function} messageFunctions.info
22
22
  * @param {Function} messageFunctions.throwWithError
23
+ * @param {object} iterateOptions
23
24
  */
24
- function expandStructureReferences(csn, options, pathDelimiter, { error, info, throwWithError }) {
25
+ function expandStructureReferences(csn, options, pathDelimiter, { error, info, throwWithError }, iterateOptions = {}) {
25
26
  const {
26
27
  isStructured, get$combined, getFinalBaseType, getServiceName,
27
28
  } = getUtils(csn);
@@ -39,7 +40,11 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
39
40
  const artifact = csn.definitions[path[1]];
40
41
  if (!hasAnnotationValue(artifact, '@cds.persistence.table')) {
41
42
  const root = get$combined({ SELECT: parent });
42
- parent.columns = replaceStar(root, columns, parent.excluding);
43
+ // TODO: replace with the correct options.transformation?
44
+ // Do not expand the * in OData for a moment, not to introduce changes
45
+ // while the OData CSN is still official
46
+ if (!options.toOdata)
47
+ parent.columns = replaceStar(root, columns, parent.excluding);
43
48
  parent.columns = expand(parent.columns, path.concat('columns'), true);
44
49
  }
45
50
  },
@@ -49,7 +54,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
49
54
  orderBy: (parent, name, orderBy, path) => {
50
55
  parent.orderBy = expand(orderBy, path.concat('orderBy'));
51
56
  },
52
- });
57
+ }, [], iterateOptions);
53
58
 
54
59
  /**
55
60
  * Turn .expand/.inline into normal refs. @cds.persistence.skip .expand with to-many (and all transitive views).
@@ -71,16 +76,25 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
71
76
  if (!hasAnnotationValue(artifact, '@cds.persistence.table')) {
72
77
  const rewritten = rewrite(root, parent.columns, parent.excluding);
73
78
  parent.columns = rewritten.columns;
74
- if (rewritten.toMany.length > 0) {
79
+ /*
80
+ * Do not remove unexpandable many columns in OData
81
+ */
82
+ if (rewritten.toMany.length > 0 && !options.toOdata) {
75
83
  markAsToDummyfy(artifact, path[1]);
76
84
  if (getServiceName(path[1]) === null)
77
85
  error( null, [ 'definitions', path[1] ], { name: path[1] }, 'Unexpected .expand with to-many association in entity $(NAME), which is outside any service');
78
86
  }
87
+ else {
88
+ parent.columns = rewritten.columns;
89
+ }
79
90
  }
80
91
  },
81
92
  });
82
93
 
83
- dummyfy();
94
+ // OData must keep @cds.persistence.skip definitions
95
+ // to present them in the API (and CSN)
96
+ if (!options.toOdata)
97
+ dummyfy();
84
98
 
85
99
  cleanup.forEach(fn => fn());
86
100
 
@@ -88,23 +102,26 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
88
102
 
89
103
 
90
104
  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
- });
105
+ // OData must allow navigations to @cds.persistence.skip targets
106
+ // as valid navigations in the API
107
+ if (!options.toOdata) {
108
+ applyTransformations(csn, {
109
+ target: (parent, name, target, path) => {
110
+ if (toDummyfy.indexOf(target) !== -1) {
111
+ publishing.push({
112
+ parent, name, target, path: [ ...path ],
113
+ });
114
+ }
115
+ },
116
+ from: check,
117
+ columns: check,
118
+ where: check,
119
+ groupBy: check,
120
+ orderBy: check,
121
+ having: check,
122
+ limit: check,
123
+ });
124
+ }
108
125
 
109
126
 
110
127
  /**
@@ -239,15 +256,14 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
239
256
  * @param {CSN.Artifact} root All elements visible fromt he query source ($combined)
240
257
  * @param {CSN.Column[]} columns
241
258
  * @param {string[]} excluding
242
- * @returns {{columns: Array, toManys: Array}} Object with rewritten columns (.expand/.inline) and with any .expand + to-many
259
+ * @returns {{columns: Array, toMany: Array}} Object with rewritten columns (.expand/.inline) and with any .expand + to-many
243
260
  */
244
261
  function rewrite(root, columns, excluding) {
245
262
  const allToMany = [];
246
263
  const newThing = [];
247
264
  // Replace stars - needs to happen here since the .expand/.inline first path step affects the root *
248
265
  columns = replaceStar(root, columns, excluding);
249
- for (let i = 0; i < columns.length; i++) {
250
- const col = columns[i];
266
+ for (const col of columns) {
251
267
  if (col.expand) {
252
268
  // TODO: Can col.ref be empty without an as? Assumption is it cannot - if it has, it's an error, we throw, compiler checks.
253
269
  const { expanded, toManys } = expandInline(root, col, col.ref || [], [ dbName(col) ]);
@@ -270,7 +286,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
270
286
  }
271
287
 
272
288
  /**
273
- * Check wether the given object is a to-many association
289
+ * Check whether the given object is a to-many association
274
290
  *
275
291
  * @param {CSN.Element} obj
276
292
  * @returns {boolean}
@@ -302,6 +318,11 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
302
318
  while (stack.length > 0) {
303
319
  const [ base, current, currentRef, currentAlias ] = stack.pop();
304
320
  if (isToMany(current) && current.expand) {
321
+ expanded.push({
322
+ expand: current.expand,
323
+ ref: currentRef,
324
+ as: currentAlias.join(pathDelimiter),
325
+ });
305
326
  toManys.push({ art: current, ref: currentRef, as: currentAlias.join(pathDelimiter) });
306
327
  }
307
328
  else if (current.expand) {
@@ -436,7 +457,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
436
457
  *
437
458
  * @param {Array} thing
438
459
  * @param {CSN.Path} path
439
- * @param {boolean} [withAlias=false] Wether to "expand" the (implicit) alias aswell.
460
+ * @param {boolean} [withAlias=false] Whether to "expand" the (implicit) alias aswell.
440
461
  * @returns {Array} New array - with all structured things expanded
441
462
  */
442
463
  function expand(thing, path, withAlias = false) {
@@ -477,6 +498,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
477
498
  */
478
499
  function expandRef(art, ref, alias, isKey, withAlias) {
479
500
  const expanded = [];
501
+ /** @type {Array<[CSN.Element, any[], any[]]>} */
480
502
  const stack = [ [ art, ref, [ alias || ref[ref.length - 1] ] ] ];
481
503
  while (stack.length > 0) {
482
504
  const [ current, currentRef, currentAlias ] = stack.pop();
@@ -564,8 +586,7 @@ function expandStructureReferences(csn, options, pathDelimiter, { error, info, t
564
586
  }
565
587
  }
566
588
  // Finally: Replace the stars and leave out the shadowed things
567
- for (let i = 0; i < subs.length; i++) {
568
- const sub = subs[i];
589
+ for (const sub of subs) {
569
590
  if (sub !== '*' && !replaced[dbName(sub)])
570
591
  final.push(sub);
571
592
  else if (sub === '*')