@sap/cds-compiler 2.11.4 → 2.13.8

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 (133) hide show
  1. package/CHANGELOG.md +159 -1
  2. package/bin/cds_update_identifiers.js +7 -7
  3. package/bin/cdsc.js +22 -23
  4. package/bin/cdsse.js +2 -2
  5. package/doc/CHANGELOG_ARCHIVE.md +1 -1
  6. package/doc/CHANGELOG_BETA.md +25 -6
  7. package/doc/CHANGELOG_DEPRECATED.md +22 -6
  8. package/doc/NameResolution.md +21 -16
  9. package/lib/api/main.js +30 -63
  10. package/lib/api/options.js +5 -5
  11. package/lib/api/validate.js +0 -5
  12. package/lib/backends.js +15 -23
  13. package/lib/base/dictionaries.js +0 -8
  14. package/lib/base/error.js +26 -0
  15. package/lib/base/keywords.js +7 -17
  16. package/lib/base/location.js +9 -4
  17. package/lib/base/message-registry.js +52 -2
  18. package/lib/base/messages.js +16 -26
  19. package/lib/base/model.js +2 -62
  20. package/lib/base/optionProcessorHelper.js +246 -183
  21. package/lib/checks/.eslintrc.json +2 -0
  22. package/lib/checks/actionsFunctions.js +2 -1
  23. package/lib/checks/annotationsOData.js +1 -1
  24. package/lib/checks/cdsPersistence.js +2 -1
  25. package/lib/checks/enricher.js +17 -1
  26. package/lib/checks/foreignKeys.js +4 -4
  27. package/lib/checks/invalidTarget.js +3 -1
  28. package/lib/checks/managedInType.js +4 -4
  29. package/lib/checks/managedWithoutKeys.js +3 -1
  30. package/lib/checks/queryNoDbArtifacts.js +1 -3
  31. package/lib/checks/selectItems.js +4 -4
  32. package/lib/checks/sql-snippets.js +94 -0
  33. package/lib/checks/types.js +1 -1
  34. package/lib/checks/validator.js +12 -7
  35. package/lib/compiler/assert-consistency.js +10 -6
  36. package/lib/compiler/base.js +0 -1
  37. package/lib/compiler/builtins.js +8 -6
  38. package/lib/compiler/checks.js +46 -12
  39. package/lib/compiler/cycle-detector.js +1 -1
  40. package/lib/compiler/define.js +1103 -0
  41. package/lib/compiler/extend.js +983 -0
  42. package/lib/compiler/finalize-parse-cdl.js +231 -0
  43. package/lib/compiler/index.js +33 -14
  44. package/lib/compiler/kick-start.js +190 -0
  45. package/lib/compiler/moduleLayers.js +4 -4
  46. package/lib/compiler/populate.js +1226 -0
  47. package/lib/compiler/propagator.js +113 -47
  48. package/lib/compiler/resolve.js +1433 -0
  49. package/lib/compiler/shared.js +76 -38
  50. package/lib/compiler/tweak-assocs.js +529 -0
  51. package/lib/compiler/utils.js +204 -33
  52. package/lib/edm/.eslintrc.json +5 -0
  53. package/lib/edm/annotations/genericTranslation.js +38 -25
  54. package/lib/edm/annotations/preprocessAnnotations.js +3 -3
  55. package/lib/edm/csn2edm.js +10 -9
  56. package/lib/edm/edm.js +19 -20
  57. package/lib/edm/edmPreprocessor.js +166 -95
  58. package/lib/edm/edmUtils.js +127 -34
  59. package/lib/gen/Dictionary.json +92 -43
  60. package/lib/gen/language.checksum +1 -1
  61. package/lib/gen/language.interp +11 -1
  62. package/lib/gen/language.tokens +86 -82
  63. package/lib/gen/languageLexer.interp +18 -1
  64. package/lib/gen/languageLexer.js +925 -847
  65. package/lib/gen/languageLexer.tokens +78 -74
  66. package/lib/gen/languageParser.js +5434 -4298
  67. package/lib/json/from-csn.js +59 -17
  68. package/lib/json/to-csn.js +143 -71
  69. package/lib/language/antlrParser.js +3 -3
  70. package/lib/language/docCommentParser.js +3 -3
  71. package/lib/language/genericAntlrParser.js +144 -54
  72. package/lib/language/language.g4 +424 -203
  73. package/lib/language/multiLineStringParser.js +536 -0
  74. package/lib/main.d.ts +472 -61
  75. package/lib/main.js +38 -11
  76. package/lib/model/api.js +3 -1
  77. package/lib/model/csnRefs.js +321 -204
  78. package/lib/model/csnUtils.js +224 -263
  79. package/lib/model/enrichCsn.js +97 -40
  80. package/lib/model/revealInternalProperties.js +27 -6
  81. package/lib/model/sortViews.js +2 -1
  82. package/lib/modelCompare/compare.js +17 -12
  83. package/lib/optionProcessor.js +7 -6
  84. package/lib/render/DuplicateChecker.js +1 -1
  85. package/lib/render/manageConstraints.js +36 -33
  86. package/lib/render/toCdl.js +174 -275
  87. package/lib/render/toHdbcds.js +201 -115
  88. package/lib/render/toRename.js +7 -10
  89. package/lib/render/toSql.js +149 -75
  90. package/lib/render/utils/common.js +22 -8
  91. package/lib/render/utils/sql.js +10 -7
  92. package/lib/render/utils/stringEscapes.js +111 -0
  93. package/lib/sql-identifier.js +1 -1
  94. package/lib/transform/.eslintrc.json +5 -0
  95. package/lib/transform/braceExpression.js +4 -2
  96. package/lib/transform/db/.eslintrc.json +2 -0
  97. package/lib/transform/db/applyTransformations.js +35 -12
  98. package/lib/transform/db/assertUnique.js +1 -1
  99. package/lib/transform/db/associations.js +187 -0
  100. package/lib/transform/db/cdsPersistence.js +150 -0
  101. package/lib/transform/db/constraints.js +61 -56
  102. package/lib/transform/db/expansion.js +50 -29
  103. package/lib/transform/db/flattening.js +552 -105
  104. package/lib/transform/db/groupByOrderBy.js +3 -1
  105. package/lib/transform/db/temporal.js +236 -0
  106. package/lib/transform/db/transformExists.js +94 -28
  107. package/lib/transform/db/views.js +5 -4
  108. package/lib/transform/draft/.eslintrc.json +38 -0
  109. package/lib/transform/{db/draft.js → draft/db.js} +9 -7
  110. package/lib/transform/draft/odata.js +227 -0
  111. package/lib/transform/forHanaNew.js +94 -801
  112. package/lib/transform/forOdataNew.js +22 -175
  113. package/lib/transform/localized.js +36 -32
  114. package/lib/transform/odata/generateForeignKeyElements.js +3 -3
  115. package/lib/transform/odata/referenceFlattener.js +95 -89
  116. package/lib/transform/odata/structureFlattener.js +1 -1
  117. package/lib/transform/odata/toFinalBaseType.js +86 -12
  118. package/lib/transform/odata/typesExposure.js +5 -5
  119. package/lib/transform/odata/utils.js +2 -2
  120. package/lib/transform/transformUtilsNew.js +47 -33
  121. package/lib/transform/translateAssocsToJoins.js +10 -27
  122. package/lib/transform/universalCsn/.eslintrc.json +36 -0
  123. package/lib/transform/universalCsn/coreComputed.js +170 -0
  124. package/lib/transform/universalCsn/universalCsnEnricher.js +715 -0
  125. package/lib/transform/universalCsn/utils.js +63 -0
  126. package/lib/utils/file.js +2 -1
  127. package/lib/utils/objectUtils.js +30 -0
  128. package/lib/utils/timetrace.js +8 -2
  129. package/package.json +1 -1
  130. package/share/messages/README.md +26 -0
  131. package/lib/compiler/definer.js +0 -2340
  132. package/lib/compiler/resolver.js +0 -2988
  133. package/lib/transform/universalCsnEnricher.js +0 -67
@@ -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 =
@@ -30,18 +31,18 @@ function validateOptions(_options)
30
31
 
31
32
  }
32
33
 
33
- const v2 = options.version.match(/v2/i) != undefined;
34
- const v4 = options.version.match(/v4/i) != undefined;
34
+ const v2 = options.version.match(/v2/i) !== null;
35
+ const v4 = options.version.match(/v4/i) !== null;
35
36
 
36
37
  options.v = [v2, v4];
37
38
  options.isStructFormat = options.odataFormat && options.odataFormat === 'structured';
38
39
  options.isFlatFormat = !options.isStructFormat;
39
40
 
40
- if(options.v.filter(v=>v).length != 1)
41
+ if(options.v.filter(v=>v).length !== 1)
41
42
  throw Error(`Please debug me: EDM V2:${v2}, V4:${v4}`);
42
43
 
43
- options.isV2 = function() { return this.v[0] == true; }
44
- options.isV4 = function() { return this.v[1] == true; }
44
+ options.isV2 = function() { return this.v[0]; }
45
+ options.isV4 = function() { return this.v[1]; }
45
46
 
46
47
  options.pathDelimiter = options.isStructFormat ? '/' : '_';
47
48
 
@@ -115,15 +116,15 @@ function isToMany(assoc) {
115
116
  return targetMax === '*' || Number(targetMax) > 1;
116
117
  }
117
118
 
118
- function isSingleton(entityCsn, v) {
119
+ function isSingleton(entityCsn) {
119
120
  const singleton = entityCsn['@odata.singleton'];
120
121
  const hasNullable = entityCsn['@odata.singleton.nullable'] !== undefined && entityCsn['@odata.singleton.nullable'] !== null;
121
- return v && singleton || ((singleton === undefined || singleton === null) && hasNullable);
122
+ return singleton || ((singleton === undefined || singleton === null) && hasNullable);
122
123
  }
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
@@ -358,7 +359,7 @@ function finalizeReferentialConstraints(csn, assocCsn, options, info)
358
359
  // in structured mode only resolve top level element (path rewriting is done elsewhere)
359
360
  const depEltName = ( options.isFlatFormat ? c[0].join('_') : c[0][0] );
360
361
  const principalEltName = ( options.isFlatFormat ? c[1].join('_') : c[1][0] );
361
- const fk = (isEntity(dependentEntity) && dependentEntity.elements[ depEltName ]) ||
362
+ const fk = (isEntity(dependentEntity) && dependentEntity.elements[ depEltName ]) ||
362
363
  (localDepEntity && localDepEntity.elements && localDepEntity.elements[ depEltName ]);
363
364
  const pk = principalEntity.$keys && principalEntity.$keys[ principalEltName ];
364
365
  if(isConstraintCandidate(fk) && isConstraintCandidate(pk)) {
@@ -463,12 +464,11 @@ function finalizeReferentialConstraints(csn, assocCsn, options, info)
463
464
  * The element must never be an association or composition and be renderable.
464
465
  */
465
466
  function isConstraintCandidate(elt) {
466
- let rc= (elt &&
467
+ return (elt &&
467
468
  elt.type &&
468
469
  (!options.isFlatFormat || options.isFlatFormat && isBuiltinType(elt.type)) &&
469
470
  !['cds.Association', 'cds.Composition'].includes(elt.type) &&
470
471
  isEdmPropertyRendered(elt, options));
471
- return rc;
472
472
  }
473
473
  }
474
474
 
@@ -557,7 +557,7 @@ function mapCdsToEdmType(csn, messageFunctions, isV2=false, isMediaType=false)
557
557
  // other: date/time, boolean
558
558
  'cds.Date': 'Edm.Date',
559
559
  'cds.Time': 'Edm.TimeOfDay',
560
- // 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,
561
561
  // no one has ever asked about it in the meantime. The falsy if is just there to remember the eventual mapping.
562
562
  'cds.DateTime': 'Edm.DateTimeOffset', // (isV2 && false) ? 'Edm.DateTime'
563
563
  'cds.Timestamp': 'Edm.DateTimeOffset', // (isV2 && false) ? 'Edm.DateTime'
@@ -665,19 +665,111 @@ function isODataSimpleIdentifier(identifier){
665
665
  return identifier && identifier.match(regex);
666
666
  }
667
667
 
668
- function escapeString(str) {
669
- // first regex: replace & if not followed by apos; or quot; or gt; or lt; or amp; or #
670
- // Do not always escape > as it is a marker for {i18n>...} translated string values
671
- let result = str;
672
- if (typeof str === 'string') {
673
- result = str.replace(/&(?!(?:apos|quot|[gl]t|amp);|#)/g, '&')
674
- .replace(/</g, '&lt;')
675
- .replace(/"/g, '&quot;')
676
- .replace(/\r\n|\n/g, '&#xa;');
677
- if (!result.startsWith('{i18n>') && !result.startsWith('{bi18n'))
678
- result = result.replace(/>/g, '&gt;')
679
- }
680
- 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};`;
681
773
  }
682
774
 
683
775
  // return the path prefix of a given name or if no prefix available 'root'
@@ -694,10 +786,10 @@ function getBaseName(name) {
694
786
 
695
787
  // This is a poor mans path resolver for $self partner paths only
696
788
  function resolveOriginAssoc(csn, env, path) {
697
- for(let i = 0; i < path.length; i++) {
789
+ for(const segment of path) {
698
790
  let elements = (env.items && env.items.elements || env.elements);
699
791
  if(elements)
700
- env = env.elements[path[i]];
792
+ env = env.elements[segment];
701
793
  let type = (env.items && env.items.type || env.type);
702
794
  if(type && !isBuiltinType(type) && !(env.items && env.items.elements || env.elements))
703
795
  env = csn.definitions[env.type];
@@ -729,7 +821,8 @@ module.exports = {
729
821
  mapCdsToEdmType,
730
822
  addTypeFacets,
731
823
  isODataSimpleIdentifier,
732
- escapeString,
824
+ escapeStringForAttributeValue,
825
+ escapeStringForText,
733
826
  getSchemaPrefix,
734
827
  getBaseName
735
828
  }
@@ -4,7 +4,8 @@
4
4
  "Type": "Aggregation.ApplySupportedType",
5
5
  "AppliesTo": [
6
6
  "EntitySet",
7
- "Collection"
7
+ "Collection",
8
+ "EntityType"
8
9
  ]
9
10
  },
10
11
  "Aggregation.ApplySupportedDefaults": {
@@ -36,7 +37,8 @@
36
37
  "AppliesTo": [
37
38
  "EntitySet",
38
39
  "Collection",
39
- "EntityContainer"
40
+ "EntityContainer",
41
+ "EntityType"
40
42
  ]
41
43
  },
42
44
  "Aggregation.ContextDefiningProperties": {
@@ -207,38 +209,44 @@
207
209
  "Type": "Capabilities.CountRestrictionsType",
208
210
  "AppliesTo": [
209
211
  "EntitySet",
210
- "Singleton"
212
+ "Singleton",
213
+ "Collection"
211
214
  ]
212
215
  },
213
216
  "Capabilities.NavigationRestrictions": {
214
217
  "Type": "Capabilities.NavigationRestrictionsType",
215
218
  "AppliesTo": [
216
219
  "EntitySet",
217
- "Singleton"
220
+ "Singleton",
221
+ "Collection"
218
222
  ]
219
223
  },
220
224
  "Capabilities.IndexableByKey": {
221
225
  "Type": "Core.Tag",
222
226
  "AppliesTo": [
223
- "EntitySet"
227
+ "EntitySet",
228
+ "Collection"
224
229
  ]
225
230
  },
226
231
  "Capabilities.TopSupported": {
227
232
  "Type": "Core.Tag",
228
233
  "AppliesTo": [
229
- "EntitySet"
234
+ "EntitySet",
235
+ "Collection"
230
236
  ]
231
237
  },
232
238
  "Capabilities.SkipSupported": {
233
239
  "Type": "Core.Tag",
234
240
  "AppliesTo": [
235
- "EntitySet"
241
+ "EntitySet",
242
+ "Collection"
236
243
  ]
237
244
  },
238
245
  "Capabilities.ComputeSupported": {
239
246
  "Type": "Core.Tag",
240
247
  "AppliesTo": [
241
- "EntitySet"
248
+ "EntitySet",
249
+ "Collection"
242
250
  ]
243
251
  },
244
252
  "Capabilities.SelectSupport": {
@@ -246,7 +254,8 @@
246
254
  "AppliesTo": [
247
255
  "EntityContainer",
248
256
  "EntitySet",
249
- "Singleton"
257
+ "Singleton",
258
+ "Collection"
250
259
  ]
251
260
  },
252
261
  "Capabilities.BatchSupported": {
@@ -265,32 +274,37 @@
265
274
  "Type": "Collection(Edm.String)",
266
275
  "AppliesTo": [
267
276
  "EntityContainer",
268
- "EntitySet"
277
+ "EntitySet",
278
+ "Collection"
269
279
  ]
270
280
  },
271
281
  "Capabilities.FilterRestrictions": {
272
282
  "Type": "Capabilities.FilterRestrictionsType",
273
283
  "AppliesTo": [
274
- "EntitySet"
284
+ "EntitySet",
285
+ "Collection"
275
286
  ]
276
287
  },
277
288
  "Capabilities.SortRestrictions": {
278
289
  "Type": "Capabilities.SortRestrictionsType",
279
290
  "AppliesTo": [
280
- "EntitySet"
291
+ "EntitySet",
292
+ "Collection"
281
293
  ]
282
294
  },
283
295
  "Capabilities.ExpandRestrictions": {
284
296
  "Type": "Capabilities.ExpandRestrictionsType",
285
297
  "AppliesTo": [
286
298
  "EntitySet",
287
- "Singleton"
299
+ "Singleton",
300
+ "Collection"
288
301
  ]
289
302
  },
290
303
  "Capabilities.SearchRestrictions": {
291
304
  "Type": "Capabilities.SearchRestrictionsType",
292
305
  "AppliesTo": [
293
- "EntitySet"
306
+ "EntitySet",
307
+ "Collection"
294
308
  ]
295
309
  },
296
310
  "Capabilities.KeyAsSegmentSupported": {
@@ -309,14 +323,15 @@
309
323
  "Type": "Capabilities.InsertRestrictionsType",
310
324
  "AppliesTo": [
311
325
  "EntitySet",
312
- "EntityType"
326
+ "Collection"
313
327
  ]
314
328
  },
315
329
  "Capabilities.DeepInsertSupport": {
316
330
  "Type": "Capabilities.DeepInsertSupportType",
317
331
  "AppliesTo": [
318
332
  "EntityContainer",
319
- "EntitySet"
333
+ "EntitySet",
334
+ "Collection"
320
335
  ]
321
336
  },
322
337
  "Capabilities.UpdateRestrictions": {
@@ -324,14 +339,15 @@
324
339
  "AppliesTo": [
325
340
  "EntitySet",
326
341
  "Singleton",
327
- "EntityType"
342
+ "Collection"
328
343
  ]
329
344
  },
330
345
  "Capabilities.DeepUpdateSupport": {
331
346
  "Type": "Capabilities.DeepUpdateSupportType",
332
347
  "AppliesTo": [
333
348
  "EntityContainer",
334
- "EntitySet"
349
+ "EntitySet",
350
+ "Collection"
335
351
  ]
336
352
  },
337
353
  "Capabilities.DeleteRestrictions": {
@@ -339,7 +355,7 @@
339
355
  "AppliesTo": [
340
356
  "EntitySet",
341
357
  "Singleton",
342
- "EntityType"
358
+ "Collection"
343
359
  ]
344
360
  },
345
361
  "Capabilities.CollectionPropertyRestrictions": {
@@ -374,7 +390,8 @@
374
390
  "Type": "Capabilities.ReadRestrictionsType",
375
391
  "AppliesTo": [
376
392
  "EntitySet",
377
- "Singleton"
393
+ "Singleton",
394
+ "Collection"
378
395
  ]
379
396
  },
380
397
  "Capabilities.CustomHeaders": {
@@ -392,6 +409,7 @@
392
409
  "Capabilities.MediaLocationUpdateSupported": {
393
410
  "Type": "Core.Tag",
394
411
  "AppliesTo": [
412
+ "EntityType",
395
413
  "Property"
396
414
  ]
397
415
  },
@@ -581,7 +599,7 @@
581
599
  "Property"
582
600
  ],
583
601
  "$deprecated": true,
584
- "$deprecationText": "Use terms `MaskedValue` and `MaskedAlways` instead"
602
+ "$deprecationText": "Use terms `MaskedValue` instead"
585
603
  },
586
604
  "Common.MaskedValue": {
587
605
  "Type": "Edm.String",
@@ -590,8 +608,8 @@
590
608
  ],
591
609
  "$experimental": true
592
610
  },
593
- "Common.MaskedAlways": {
594
- "Type": "Core.Tag",
611
+ "Common.RevealOnDemand": {
612
+ "Type": "Edm.Boolean",
595
613
  "AppliesTo": [
596
614
  "Property"
597
615
  ],
@@ -602,7 +620,8 @@
602
620
  "AppliesTo": [
603
621
  "EntitySet",
604
622
  "EntityType",
605
- "Property"
623
+ "Property",
624
+ "NavigationProperty"
606
625
  ]
607
626
  },
608
627
  "Common.SemanticObjectMapping": {
@@ -639,7 +658,8 @@
639
658
  "Type": "Common.FieldControlType",
640
659
  "AppliesTo": [
641
660
  "Property",
642
- "Record"
661
+ "Record",
662
+ "EntityType"
643
663
  ]
644
664
  },
645
665
  "Common.ExceptionCategory": {
@@ -1048,7 +1068,8 @@
1048
1068
  "Common.mediaUploadLink": {
1049
1069
  "Type": "Edm.String",
1050
1070
  "AppliesTo": [
1051
- "Property"
1071
+ "Property",
1072
+ "EntityType"
1052
1073
  ],
1053
1074
  "$experimental": true
1054
1075
  },
@@ -1060,6 +1081,13 @@
1060
1081
  ],
1061
1082
  "$experimental": true
1062
1083
  },
1084
+ "Common.WebSocketBaseURL": {
1085
+ "Type": "Edm.String",
1086
+ "AppliesTo": [
1087
+ "EntityContainer"
1088
+ ],
1089
+ "$experimental": true
1090
+ },
1063
1091
  "Communication.Contact": {
1064
1092
  "Type": "Communication.ContactType",
1065
1093
  "AppliesTo": [
@@ -1165,12 +1193,6 @@
1165
1193
  "Term"
1166
1194
  ]
1167
1195
  },
1168
- "Core.AppliesToTypeIfDynamic": {
1169
- "Type": "Core.Tag",
1170
- "AppliesTo": [
1171
- "Term"
1172
- ]
1173
- },
1174
1196
  "Core.AppliesViaContainer": {
1175
1197
  "Type": "Core.Tag",
1176
1198
  "AppliesTo": [
@@ -1260,6 +1282,7 @@
1260
1282
  "Core.MediaType": {
1261
1283
  "Type": "Edm.String",
1262
1284
  "AppliesTo": [
1285
+ "EntityType",
1263
1286
  "Property",
1264
1287
  "Term",
1265
1288
  "TypeDefinition",
@@ -1277,6 +1300,7 @@
1277
1300
  "Core.ContentDisposition": {
1278
1301
  "Type": "Core.ContentDispositionType",
1279
1302
  "AppliesTo": [
1303
+ "EntityType",
1280
1304
  "Property",
1281
1305
  "Term"
1282
1306
  ]
@@ -1297,6 +1321,7 @@
1297
1321
  "Core.AutoExpand": {
1298
1322
  "Type": "Core.Tag",
1299
1323
  "AppliesTo": [
1324
+ "EntityType",
1300
1325
  "NavigationProperty",
1301
1326
  "Property"
1302
1327
  ]
@@ -1417,8 +1442,7 @@
1417
1442
  "Type": "PersonalData.EntitySemanticsType",
1418
1443
  "AppliesTo": [
1419
1444
  "EntitySet"
1420
- ],
1421
- "$experimental": true
1445
+ ]
1422
1446
  },
1423
1447
  "PersonalData.DataSubjectRole": {
1424
1448
  "Type": "Edm.String",
@@ -1438,15 +1462,13 @@
1438
1462
  "Type": "PersonalData.FieldSemanticsType",
1439
1463
  "AppliesTo": [
1440
1464
  "Property"
1441
- ],
1442
- "$experimental": true
1465
+ ]
1443
1466
  },
1444
1467
  "PersonalData.IsPotentiallyPersonal": {
1445
1468
  "Type": "Core.Tag",
1446
1469
  "AppliesTo": [
1447
1470
  "Property"
1448
- ],
1449
- "$experimental": true
1471
+ ]
1450
1472
  },
1451
1473
  "PersonalData.IsPotentiallySensitive": {
1452
1474
  "Type": "Core.Tag",
@@ -1682,7 +1704,8 @@
1682
1704
  "UI.IsImage": {
1683
1705
  "Type": "Core.Tag",
1684
1706
  "AppliesTo": [
1685
- "Property"
1707
+ "Property",
1708
+ "EntityType"
1686
1709
  ],
1687
1710
  "$experimental": true
1688
1711
  },
@@ -2678,6 +2701,7 @@
2678
2701
  "EditAction": "Common.QualifiedName",
2679
2702
  "NewAction": "Common.QualifiedName",
2680
2703
  "AdditionalNewActions": "Collection(Common.QualifiedName)",
2704
+ "ShareAction": "Common.QualifiedName",
2681
2705
  "PreparationAction": "Common.QualifiedName",
2682
2706
  "ValidationFunction": "Common.QualifiedName"
2683
2707
  }
@@ -3001,6 +3025,7 @@
3001
3025
  "Core.ContentDispositionType": {
3002
3026
  "$kind": "ComplexType",
3003
3027
  "Properties": {
3028
+ "Type": "Edm.String",
3004
3029
  "Filename": "Edm.String"
3005
3030
  }
3006
3031
  },
@@ -3128,18 +3153,17 @@
3128
3153
  },
3129
3154
  "PersonalData.EntitySemanticsType": {
3130
3155
  "$kind": "TypeDefinition",
3131
- "UnderlyingType": "Edm.String",
3132
- "$experimental": true
3156
+ "UnderlyingType": "Edm.String"
3133
3157
  },
3134
3158
  "PersonalData.FieldSemanticsType": {
3135
3159
  "$kind": "TypeDefinition",
3136
- "UnderlyingType": "Edm.String",
3137
- "$experimental": true
3160
+ "UnderlyingType": "Edm.String"
3138
3161
  },
3139
3162
  "Session.StickySessionSupportedType": {
3140
3163
  "$kind": "ComplexType",
3141
3164
  "Properties": {
3142
3165
  "NewAction": "Common.QualifiedName",
3166
+ "AdditionalNewActions": "Collection(Common.QualifiedName)",
3143
3167
  "EditAction": "Common.QualifiedName",
3144
3168
  "SaveAction": "Common.QualifiedName",
3145
3169
  "DiscardAction": "Common.SimpleIdentifier"
@@ -3583,6 +3607,18 @@
3583
3607
  "IconUrl": "Edm.String"
3584
3608
  }
3585
3609
  },
3610
+ "UI.DataFieldForActionGroup": {
3611
+ "$kind": "ComplexType",
3612
+ "BaseType": "UI.DataFieldAbstract",
3613
+ "Properties": {
3614
+ "Actions": "Collection(UI.DataFieldForActionAbstract)",
3615
+ "Label": "Edm.String",
3616
+ "Criticality": "UI.CriticalityType",
3617
+ "CriticalityRepresentation": "UI.CriticalityRepresentationType",
3618
+ "IconUrl": "Edm.String"
3619
+ },
3620
+ "$experimental": true
3621
+ },
3586
3622
  "UI.DataField": {
3587
3623
  "$kind": "ComplexType",
3588
3624
  "BaseType": "UI.DataFieldAbstract",
@@ -3645,6 +3681,19 @@
3645
3681
  "IconUrl": "Edm.String"
3646
3682
  }
3647
3683
  },
3684
+ "UI.DataFieldWithActionGroup": {
3685
+ "$kind": "ComplexType",
3686
+ "BaseType": "UI.DataField",
3687
+ "Properties": {
3688
+ "Actions": "Collection(UI.DataField)",
3689
+ "Value": "Edm.PrimitiveType",
3690
+ "Label": "Edm.String",
3691
+ "Criticality": "UI.CriticalityType",
3692
+ "CriticalityRepresentation": "UI.CriticalityRepresentationType",
3693
+ "IconUrl": "Edm.String"
3694
+ },
3695
+ "$experimental": true
3696
+ },
3648
3697
  "UI.RecommendationListType": {
3649
3698
  "$kind": "ComplexType",
3650
3699
  "Properties": {
@@ -1 +1 @@
1
- cde5224056abde61cc2eb0b1b30bf694
1
+ 78ff41e0af1a8064856dea9850968eb6