@sap/cds-compiler 2.12.0 → 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 (118) hide show
  1. package/CHANGELOG.md +110 -15
  2. package/bin/cdsc.js +13 -13
  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 +28 -63
  8. package/lib/api/options.js +3 -3
  9. package/lib/api/validate.js +0 -5
  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 +25 -4
  16. package/lib/base/messages.js +16 -26
  17. package/lib/base/model.js +2 -63
  18. package/lib/base/optionProcessorHelper.js +158 -123
  19. package/lib/checks/annotationsOData.js +1 -1
  20. package/lib/checks/cdsPersistence.js +2 -1
  21. package/lib/checks/enricher.js +17 -1
  22. package/lib/checks/invalidTarget.js +3 -1
  23. package/lib/checks/managedWithoutKeys.js +3 -1
  24. package/lib/checks/selectItems.js +4 -4
  25. package/lib/checks/sql-snippets.js +27 -26
  26. package/lib/checks/types.js +1 -1
  27. package/lib/checks/validator.js +4 -7
  28. package/lib/compiler/assert-consistency.js +5 -3
  29. package/lib/compiler/builtins.js +8 -6
  30. package/lib/compiler/checks.js +14 -3
  31. package/lib/compiler/cycle-detector.js +1 -1
  32. package/lib/compiler/define.js +1103 -0
  33. package/lib/compiler/extend.js +983 -0
  34. package/lib/compiler/finalize-parse-cdl.js +231 -0
  35. package/lib/compiler/index.js +32 -13
  36. package/lib/compiler/kick-start.js +190 -0
  37. package/lib/compiler/moduleLayers.js +4 -4
  38. package/lib/compiler/populate.js +1226 -0
  39. package/lib/compiler/propagator.js +111 -46
  40. package/lib/compiler/resolve.js +1433 -0
  41. package/lib/compiler/shared.js +64 -37
  42. package/lib/compiler/tweak-assocs.js +529 -0
  43. package/lib/compiler/utils.js +197 -33
  44. package/lib/edm/.eslintrc.json +5 -0
  45. package/lib/edm/annotations/genericTranslation.js +5 -9
  46. package/lib/edm/annotations/preprocessAnnotations.js +2 -2
  47. package/lib/edm/csn2edm.js +9 -8
  48. package/lib/edm/edm.js +11 -12
  49. package/lib/edm/edmPreprocessor.js +137 -73
  50. package/lib/edm/edmUtils.js +116 -22
  51. package/lib/gen/Dictionary.json +10 -3
  52. package/lib/gen/language.checksum +1 -1
  53. package/lib/gen/language.interp +9 -1
  54. package/lib/gen/language.tokens +86 -83
  55. package/lib/gen/languageLexer.interp +10 -1
  56. package/lib/gen/languageLexer.js +860 -833
  57. package/lib/gen/languageLexer.tokens +78 -75
  58. package/lib/gen/languageParser.js +5282 -4265
  59. package/lib/json/from-csn.js +12 -1
  60. package/lib/json/to-csn.js +126 -66
  61. package/lib/language/docCommentParser.js +2 -2
  62. package/lib/language/genericAntlrParser.js +76 -3
  63. package/lib/language/language.g4 +297 -130
  64. package/lib/language/multiLineStringParser.js +5 -5
  65. package/lib/main.d.ts +468 -59
  66. package/lib/main.js +35 -9
  67. package/lib/model/api.js +3 -1
  68. package/lib/model/csnRefs.js +225 -156
  69. package/lib/model/csnUtils.js +192 -223
  70. package/lib/model/enrichCsn.js +70 -29
  71. package/lib/model/revealInternalProperties.js +27 -6
  72. package/lib/model/sortViews.js +2 -1
  73. package/lib/modelCompare/compare.js +17 -12
  74. package/lib/optionProcessor.js +5 -4
  75. package/lib/render/manageConstraints.js +35 -32
  76. package/lib/render/toCdl.js +73 -288
  77. package/lib/render/toHdbcds.js +25 -23
  78. package/lib/render/toSql.js +98 -41
  79. package/lib/render/utils/common.js +5 -10
  80. package/lib/render/utils/sql.js +4 -3
  81. package/lib/render/utils/stringEscapes.js +111 -0
  82. package/lib/sql-identifier.js +1 -1
  83. package/lib/transform/.eslintrc.json +5 -0
  84. package/lib/transform/db/.eslintrc.json +2 -0
  85. package/lib/transform/db/applyTransformations.js +35 -12
  86. package/lib/transform/db/assertUnique.js +1 -1
  87. package/lib/transform/db/associations.js +103 -305
  88. package/lib/transform/db/cdsPersistence.js +2 -2
  89. package/lib/transform/db/constraints.js +55 -52
  90. package/lib/transform/db/expansion.js +46 -24
  91. package/lib/transform/db/flattening.js +553 -102
  92. package/lib/transform/db/groupByOrderBy.js +3 -1
  93. package/lib/transform/db/transformExists.js +59 -6
  94. package/lib/transform/db/views.js +5 -4
  95. package/lib/transform/draft/.eslintrc.json +38 -0
  96. package/lib/transform/{db/draft.js → draft/db.js} +6 -5
  97. package/lib/transform/draft/odata.js +227 -0
  98. package/lib/transform/forHanaNew.js +67 -183
  99. package/lib/transform/forOdataNew.js +17 -171
  100. package/lib/transform/localized.js +34 -19
  101. package/lib/transform/odata/generateForeignKeyElements.js +1 -1
  102. package/lib/transform/odata/referenceFlattener.js +95 -89
  103. package/lib/transform/odata/structureFlattener.js +1 -1
  104. package/lib/transform/odata/toFinalBaseType.js +86 -12
  105. package/lib/transform/odata/typesExposure.js +5 -5
  106. package/lib/transform/odata/utils.js +2 -2
  107. package/lib/transform/transformUtilsNew.js +36 -22
  108. package/lib/transform/translateAssocsToJoins.js +2 -19
  109. package/lib/transform/universalCsn/.eslintrc.json +36 -0
  110. package/lib/transform/universalCsn/coreComputed.js +170 -0
  111. package/lib/transform/universalCsn/universalCsnEnricher.js +715 -0
  112. package/lib/transform/universalCsn/utils.js +63 -0
  113. package/lib/utils/objectUtils.js +30 -0
  114. package/package.json +1 -1
  115. package/share/messages/README.md +26 -0
  116. package/lib/compiler/definer.js +0 -2361
  117. package/lib/compiler/resolver.js +0 -3079
  118. package/lib/transform/universalCsnEnricher.js +0 -237
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
  const { setProp } = require('../base/model');
3
3
  const { isBuiltinType, isEdmPropertyRendered } = require('../model/csnUtils');
4
+ const { escapeString, hasControlCharacters, hasUnpairedUnicodeSurrogate } = require("../render/utils/stringEscapes");
4
5
 
5
6
  /* eslint max-statements-per-line:off */
6
7
  function validateOptions(_options)
@@ -22,7 +23,7 @@ function validateOptions(_options)
22
23
  options.odataForeignKeys = options.toOdata.odataForeignKeys;
23
24
  if(options.toOdata.odataV2PartialConstr)
24
25
  options.odataV2PartialConstr = options.toOdata.odataV2PartialConstr;
25
- // global flag that indicates wether or not FKs shall be rendered in general
26
+ // global flag that indicates whether or not FKs shall be rendered in general
26
27
  // V2/V4 flat: yes
27
28
  // V4/struct: depending on odataForeignKeys
28
29
  options.renderForeignKeys =
@@ -123,7 +124,7 @@ function isSingleton(entityCsn) {
123
124
 
124
125
  function isEntity(artifact)
125
126
  {
126
- return ['entity'].includes(artifact.kind);
127
+ return artifact.kind === 'entity';
127
128
  }
128
129
 
129
130
  function isParameterizedEntity(artifact) {
@@ -138,15 +139,15 @@ function isStructuredArtifact(artifact) {
138
139
 
139
140
  // Return true if 'artifact' is a real structured type (not an entity)
140
141
  function isStructuredType(artifact) {
141
- return ['type'].includes(artifact.kind) && isStructuredArtifact(artifact);
142
+ return artifact.kind === 'type' && isStructuredArtifact(artifact);
142
143
  }
143
144
 
144
145
  function isDerivedType(artifact) {
145
- return ['type'].includes(artifact.kind) && !isStructuredArtifact(artifact);
146
+ return artifact.kind === 'type' && !isStructuredArtifact(artifact);
146
147
  }
147
148
 
148
149
  function isActionOrFunction(artifact) {
149
- return ['action', 'function'].includes(artifact.kind);
150
+ return artifact.kind === 'action' || artifact.kind === 'function';
150
151
  }
151
152
 
152
153
  function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions) {
@@ -179,7 +180,7 @@ function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions
179
180
  const originAssocCsn = resolveOriginAssoc(csn, (assocCsn._originalTarget || assocCsn._target), partnerPath);
180
181
  const parentName = assocCsn.$abspath[0];
181
182
  const parent = csn.definitions[parentName];
182
- if(originAssocCsn) {
183
+ if(originAssocCsn && originAssocCsn.$abspath) {
183
184
  const originParentName = originAssocCsn.$abspath[0];
184
185
  if(parent.$mySchemaName && originAssocCsn._originalTarget !== parent && originAssocCsn._target !== parent) {
185
186
  isBacklink = false;
@@ -253,7 +254,7 @@ function resolveOnConditionAndPrepareConstraints(csn, assocCsn, messageFunctions
253
254
  {
254
255
  let lhs = expr[pos-1];
255
256
  let rhs = expr[pos+1];
256
- if(['='].includes(arg))
257
+ if(arg === '=')
257
258
  {
258
259
  assocCsn._constraints.termCount++;
259
260
  if(lhs.ref && rhs.ref) // ref is a path
@@ -556,7 +557,7 @@ function mapCdsToEdmType(csn, messageFunctions, isV2=false, isMediaType=false)
556
557
  // other: date/time, boolean
557
558
  'cds.Date': 'Edm.Date',
558
559
  'cds.Time': 'Edm.TimeOfDay',
559
- // For a very long time it was unclear wether or not to map the Date types to a different Edm Type in V2,
560
+ // For a very long time it was unclear whether or not to map the Date types to a different Edm Type in V2,
560
561
  // no one has ever asked about it in the meantime. The falsy if is just there to remember the eventual mapping.
561
562
  'cds.DateTime': 'Edm.DateTimeOffset', // (isV2 && false) ? 'Edm.DateTime'
562
563
  'cds.Timestamp': 'Edm.DateTimeOffset', // (isV2 && false) ? 'Edm.DateTime'
@@ -664,19 +665,111 @@ function isODataSimpleIdentifier(identifier){
664
665
  return identifier && identifier.match(regex);
665
666
  }
666
667
 
667
- function escapeString(str) {
668
- // first regex: replace & if not followed by apos; or quot; or gt; or lt; or amp; or #
669
- // Do not always escape > as it is a marker for {i18n>...} translated string values
670
- let result = str;
671
- if (typeof str === 'string') {
672
- result = str.replace(/&(?!(?:apos|quot|[gl]t|amp);|#)/g, '&')
673
- .replace(/</g, '&lt;')
674
- .replace(/"/g, '&quot;')
675
- .replace(/\r\n|\n/g, '&#xa;');
676
- if (!result.startsWith('{i18n>') && !result.startsWith('{bi18n'))
677
- result = result.replace(/>/g, '&gt;')
678
- }
679
- return result;
668
+ /**
669
+ * Escape the given string for attribute values. We follow the spec as
670
+ * described in §2.3 <https://www.w3.org/TR/xml/#NT-AttValue>:
671
+ *
672
+ * AttValue ::= '"' ([^<&"] | Reference)* '"'
673
+ * | "'" ([^<&'] | Reference)* "'"
674
+ *
675
+ * This function assumes that the attribute value is surrounded by double quotes ("),
676
+ * hence single quotes are not escaped.
677
+ *
678
+ * Note that even though certain special characters such as newline (LF) are allowed,
679
+ * they may be normalized to something different. For example LF is normalized
680
+ * to a space. Therefore we need to escape it.
681
+ * See §3.3.3 <https://www.w3.org/TR/xml/#AVNormalize>.
682
+ *
683
+ * Furthermore, control characters need to be escaped, see §2.2:
684
+ * <https://www.w3.org/TR/xml/#charsets>
685
+ * We also encode LF (#xA), etc. because of XML normalization in XML parsers.
686
+ *
687
+ * @param {string} str
688
+ * @returns {string}
689
+ */
690
+ function escapeStringForAttributeValue(str) {
691
+ if (typeof str !== 'string')
692
+ return str;
693
+
694
+ if (!/[&<"]/.test(str) && !hasControlCharacters(str) && !hasUnpairedUnicodeSurrogate(str))
695
+ return str;
696
+
697
+ str = escapeString(str, {
698
+ '&': '&amp;',
699
+ '<': '&lt;',
700
+ '"': '&quot;',
701
+ control: encodeNonCharacters,
702
+ unpairedSurrogate: encodeNonCharacters,
703
+ });
704
+
705
+ // Notes
706
+ // -----
707
+ // According to the specification, "§2.11: End-of-Line Handling", we should normalize line endings:
708
+ // > ... by translating both the two-character sequence #xD #xA and any #xD that is not
709
+ // > followed by #xA to a single #xA character.
710
+ // However, line endings were already normalized in the CDL parser.
711
+ // If we were to normalize it again, it would be work done twice, possibly resulting in
712
+ // unwanted normalization (once is expected, twice is not).
713
+ // If we were to ever change this, use this RegEx:
714
+ // /\r\n?|\n/g => '&#xA;'
715
+
716
+ return str;
717
+ }
718
+
719
+ /**
720
+ * Escape the given string for element content. We follow the spec as
721
+ * described in §3.1 <https://www.w3.org/TR/xml/#NT-content>:
722
+ *
723
+ * content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)*
724
+ * CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
725
+ *
726
+ * i.e., we need to escape '<', '&' as well as `>` if it is preceded by `]]`.
727
+ * See also $2.4: “'>' MUST be replaced for compatibility reasons if it appears as ]]>”
728
+ *
729
+ * Furthermore, control characters need to be escaped, see §2.2:
730
+ * <https://www.w3.org/TR/xml/#charsets>
731
+ * We also encode LF (#xA), etc. because of XML normalization in XML parsers.
732
+ *
733
+ * In contrast to `escapeStringForAttributeValue()`, newlines do
734
+ * not need to be escaped.
735
+ *
736
+ * @param {string} str
737
+ * @returns {string}
738
+ */
739
+ function escapeStringForText(str) {
740
+ if (typeof str !== 'string')
741
+ return str;
742
+
743
+ if (!/[&<>]/.test(str) && !hasControlCharacters(str) && !hasUnpairedUnicodeSurrogate(str))
744
+ return str;
745
+
746
+ str = escapeString(str, {
747
+ '&': '&amp;',
748
+ '<': '&lt;',
749
+ control: encodeNonCharacters,
750
+ unpairedSurrogate: encodeNonCharacters,
751
+ });
752
+
753
+ // Note: You can test this with <https://www.w3schools.com/xml/xml_validator.asp>:
754
+ // This sequence is allowed in attribute values but not element content.
755
+ str = str.replace(/]]>/g, ']]&gt;');
756
+
757
+ return str;
758
+ }
759
+
760
+ /**
761
+ * Control characters need to be escaped, see §2.2:
762
+ * <https://www.w3.org/TR/xml/#charsets>
763
+ *
764
+ * Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
765
+ * --> any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
766
+ *
767
+ * @param {number} codePoint
768
+ * @returns {string}
769
+ */
770
+ function encodeNonCharacters(codePoint) {
771
+ const hex = codePoint.toString(16).toUpperCase();
772
+ return `&#x${hex};`;
680
773
  }
681
774
 
682
775
  // return the path prefix of a given name or if no prefix available 'root'
@@ -728,7 +821,8 @@ module.exports = {
728
821
  mapCdsToEdmType,
729
822
  addTypeFacets,
730
823
  isODataSimpleIdentifier,
731
- escapeString,
824
+ escapeStringForAttributeValue,
825
+ escapeStringForText,
732
826
  getSchemaPrefix,
733
827
  getBaseName
734
828
  }
@@ -409,6 +409,7 @@
409
409
  "Capabilities.MediaLocationUpdateSupported": {
410
410
  "Type": "Core.Tag",
411
411
  "AppliesTo": [
412
+ "EntityType",
412
413
  "Property"
413
414
  ]
414
415
  },
@@ -657,7 +658,8 @@
657
658
  "Type": "Common.FieldControlType",
658
659
  "AppliesTo": [
659
660
  "Property",
660
- "Record"
661
+ "Record",
662
+ "EntityType"
661
663
  ]
662
664
  },
663
665
  "Common.ExceptionCategory": {
@@ -1066,7 +1068,8 @@
1066
1068
  "Common.mediaUploadLink": {
1067
1069
  "Type": "Edm.String",
1068
1070
  "AppliesTo": [
1069
- "Property"
1071
+ "Property",
1072
+ "EntityType"
1070
1073
  ],
1071
1074
  "$experimental": true
1072
1075
  },
@@ -1279,6 +1282,7 @@
1279
1282
  "Core.MediaType": {
1280
1283
  "Type": "Edm.String",
1281
1284
  "AppliesTo": [
1285
+ "EntityType",
1282
1286
  "Property",
1283
1287
  "Term",
1284
1288
  "TypeDefinition",
@@ -1317,6 +1321,7 @@
1317
1321
  "Core.AutoExpand": {
1318
1322
  "Type": "Core.Tag",
1319
1323
  "AppliesTo": [
1324
+ "EntityType",
1320
1325
  "NavigationProperty",
1321
1326
  "Property"
1322
1327
  ]
@@ -1699,7 +1704,8 @@
1699
1704
  "UI.IsImage": {
1700
1705
  "Type": "Core.Tag",
1701
1706
  "AppliesTo": [
1702
- "Property"
1707
+ "Property",
1708
+ "EntityType"
1703
1709
  ],
1704
1710
  "$experimental": true
1705
1711
  },
@@ -2695,6 +2701,7 @@
2695
2701
  "EditAction": "Common.QualifiedName",
2696
2702
  "NewAction": "Common.QualifiedName",
2697
2703
  "AdditionalNewActions": "Collection(Common.QualifiedName)",
2704
+ "ShareAction": "Common.QualifiedName",
2698
2705
  "PreparationAction": "Common.QualifiedName",
2699
2706
  "ValidationFunction": "Common.QualifiedName"
2700
2707
  }
@@ -1 +1 @@
1
- 08b778f3db88cf2de248a5fbf7ed4c8a
1
+ 78ff41e0af1a8064856dea9850968eb6