@sap/cds-compiler 5.8.2 → 5.9.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 (87) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/bin/cds_remove_invalid_whitespace.js +5 -3
  3. package/bin/cds_update_identifiers.js +9 -6
  4. package/bin/cdsc.js +79 -59
  5. package/bin/cdsse.js +14 -10
  6. package/bin/cdsv2m.js +3 -1
  7. package/lib/api/options.js +28 -6
  8. package/lib/base/message-registry.js +15 -4
  9. package/lib/checks/validator.js +3 -0
  10. package/lib/compiler/base.js +1 -1
  11. package/lib/compiler/checks.js +70 -50
  12. package/lib/compiler/extend.js +1 -1
  13. package/lib/compiler/generate.js +8 -2
  14. package/lib/compiler/index.js +1 -1
  15. package/lib/compiler/lsp-api.js +1 -1
  16. package/lib/compiler/propagator.js +2 -2
  17. package/lib/compiler/resolve.js +78 -31
  18. package/lib/compiler/shared.js +3 -3
  19. package/lib/compiler/tweak-assocs.js +1 -1
  20. package/lib/compiler/utils.js +10 -0
  21. package/lib/compiler/xpr-rewrite.js +1 -1
  22. package/lib/edm/annotations/edmJson.js +42 -39
  23. package/lib/edm/annotations/genericTranslation.js +55 -55
  24. package/lib/edm/annotations/preprocessAnnotations.js +5 -5
  25. package/lib/edm/csn2edm.js +16 -16
  26. package/lib/edm/edm.js +62 -62
  27. package/lib/edm/edmAnnoPreprocessor.js +2 -2
  28. package/lib/edm/edmInboundChecks.js +1 -1
  29. package/lib/edm/edmPreprocessor.js +32 -32
  30. package/lib/edm/edmUtils.js +8 -8
  31. package/lib/gen/CdlGrammar.checksum +1 -1
  32. package/lib/gen/CdlParser.js +77 -81
  33. package/lib/gen/Dictionary.json +3062 -3072
  34. package/lib/gen/language.checksum +1 -1
  35. package/lib/gen/language.interp +1 -1
  36. package/lib/gen/languageParser.js +1238 -1236
  37. package/lib/json/from-csn.js +1 -1
  38. package/lib/json/to-csn.js +30 -3
  39. package/lib/language/genericAntlrParser.js +16 -0
  40. package/lib/main.d.ts +79 -1
  41. package/lib/model/csnRefs.js +12 -5
  42. package/lib/model/xprAsTree.js +71 -0
  43. package/lib/modelCompare/utils/filter.js +1 -1
  44. package/lib/optionProcessor.js +46 -32
  45. package/lib/parsers/CdlGrammar.g4 +33 -28
  46. package/lib/parsers/Lexer.js +1 -1
  47. package/lib/parsers/XprTree.js +25 -16
  48. package/lib/render/toCdl.js +902 -414
  49. package/lib/render/toHdbcds.js +1 -1
  50. package/lib/render/toSql.js +8 -0
  51. package/lib/render/utils/common.js +2 -2
  52. package/lib/render/utils/operators.js +160 -0
  53. package/lib/render/utils/pretty.js +337 -0
  54. package/lib/sql-identifier.js +7 -9
  55. package/lib/transform/addTenantFields.js +39 -41
  56. package/lib/transform/db/applyTransformations.js +4 -4
  57. package/lib/transform/db/assertUnique.js +6 -5
  58. package/lib/transform/db/associations.js +3 -3
  59. package/lib/transform/db/assocsToQueries/transformExists.js +13 -13
  60. package/lib/transform/db/assocsToQueries/utils.js +8 -0
  61. package/lib/transform/db/backlinks.js +19 -14
  62. package/lib/transform/db/constraints.js +6 -6
  63. package/lib/transform/db/expansion.js +1 -1
  64. package/lib/transform/db/flattening.js +2 -2
  65. package/lib/transform/db/groupByOrderBy.js +1 -1
  66. package/lib/transform/db/processSqlServices.js +3 -3
  67. package/lib/transform/db/rewriteCalculatedElements.js +2 -2
  68. package/lib/transform/db/temporal.js +7 -9
  69. package/lib/transform/db/views.js +6 -6
  70. package/lib/transform/draft/odata.js +2 -0
  71. package/lib/transform/effective/annotations.js +1 -1
  72. package/lib/transform/effective/associations.js +1 -1
  73. package/lib/transform/effective/main.js +1 -0
  74. package/lib/transform/effective/service.js +2 -2
  75. package/lib/transform/forRelationalDB.js +11 -5
  76. package/lib/transform/localized.js +2 -0
  77. package/lib/transform/odata/adaptAnnotationRefs.js +10 -9
  78. package/lib/transform/parseExpr.js +2 -2
  79. package/lib/transform/transformUtils.js +9 -7
  80. package/lib/transform/translateAssocsToJoins.js +0 -2
  81. package/lib/transform/universalCsn/coreComputed.js +2 -2
  82. package/lib/utils/moduleResolve.js +7 -5
  83. package/package.json +1 -1
  84. package/share/messages/def-upcoming-virtual-change.md +55 -0
  85. package/share/messages/file-unexpected-case-mismatch.md +61 -0
  86. package/share/messages/message-explanations.json +2 -0
  87. package/lib/transform/braceExpression.js +0 -77
@@ -33,7 +33,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
33
33
 
34
34
  allKnownVocabularies.push(...Object.keys(mergedVocDefs));
35
35
  allKnownVocabularies.sort((a, b) => b.length - a.length);
36
- const whatsMyTermNamespace = anno => allKnownVocabularies.reduce((rc, ns) => (!rc && anno && anno.startsWith(`@${ns}.`) ? ns : rc), undefined);
36
+ const whatsMyTermNamespace = anno => allKnownVocabularies.reduce((rc, ns) => (!rc && anno && anno.startsWith(`@${ ns }.`) ? ns : rc), undefined);
37
37
 
38
38
  // annotation preprocessing
39
39
  preprocessAnnotations.preprocessAnnotations(reqDefs, serviceName, options, messageFunctions);
@@ -57,7 +57,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
57
57
  }
58
58
 
59
59
  forEachDefinition(reqDefs, (def, defName) => {
60
- if (defName.startsWith(`${serviceName}.`))
60
+ if (defName.startsWith(`${ serviceName }.`))
61
61
  assignParameterAnnotations(def);
62
62
  });
63
63
 
@@ -67,11 +67,11 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
67
67
  // Note: we assume that all objects lie flat in the service, i.e. objName always
68
68
  // looks like <service name, can contain dots>.<id>
69
69
  forEachDefinition(reqDefs, (def, defName) => {
70
- if (defName === serviceName || defName.startsWith(`${serviceName}.`)) {
70
+ if (defName === serviceName || defName.startsWith(`${ serviceName }.`)) {
71
71
  const location = [ 'definitions', defName ];
72
72
  // the <objName> is not the carrier name for <objName>Type
73
73
  // and sometimes the object.name doesn't have a service prefix
74
- if (def.name && def.name.startsWith(`${serviceName}.`))
74
+ if (def.name && def.name.startsWith(`${ serviceName }.`))
75
75
  defName = def.name;
76
76
  if (def.kind === 'action' || def.kind === 'function')
77
77
  handleAction(defName, def, null, location);
@@ -161,15 +161,15 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
161
161
  const [ prefix, innerAnnotation ] = attr.split('.@');
162
162
  const ns = whatsMyTermNamespace(prefix);
163
163
  if (ns) {
164
- const steps = prefix.replace(`@${ns}.`, '').split('.');
164
+ const steps = prefix.replace(`@${ ns }.`, '').split('.');
165
165
  const paramAnnoParts = steps[0].split('#$parameters');
166
- const dictTerm = getDictTerm(`${ns}.${paramAnnoParts[0]}`, options);
166
+ const dictTerm = getDictTerm(`${ ns }.${ paramAnnoParts[0] }`, options);
167
167
  if (paramAnnoParts.length > 1 ||
168
168
  [ 'Singleton', 'EntitySet' ].some(y => dictTerm?.AppliesTo?.includes(y))) {
169
- steps[0] = `@${ns}.${paramAnnoParts.join('')}`;
169
+ steps[0] = `@${ ns }.${ paramAnnoParts.join('') }`;
170
170
  let newAnno = steps.join('.');
171
171
  if (innerAnnotation)
172
- newAnno += `.@${innerAnnotation}`;
172
+ newAnno += `.@${ innerAnnotation }`;
173
173
  edmUtils.assignAnnotation(def, newAnno, def._origin[attr]);
174
174
  transformAnnotationExpression(def._origin, attr, scopeCheck, def._origin.$path);
175
175
  if (paramAnnoParts.length > 1)
@@ -227,7 +227,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
227
227
  // definition bound element annotations
228
228
  if (def.$elementsAnnoProxies) {
229
229
  Object.entries(def.$elementsAnnoProxies).forEach(([ elemPath, element ]) => {
230
- const edmTargetName = `${defName}/${elemPath}`;
230
+ const edmTargetName = `${ defName }/${ elemPath }`;
231
231
  handleAnnotations(edmTargetName, element,
232
232
  {
233
233
  location: element.$path,
@@ -238,7 +238,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
238
238
  // element bound annotations
239
239
  if (def.elements) {
240
240
  Object.entries(def.elements).forEach(([ elemName, element ]) => {
241
- const edmTargetName = `${defName}/${elemName}`;
241
+ const edmTargetName = `${ defName }/${ elemName }`;
242
242
  const eLocation = [ ...location, 'elements', elemName ];
243
243
  handleAnnotations(edmTargetName, element, { location: eLocation });
244
244
  });
@@ -267,7 +267,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
267
267
 
268
268
  Object.entries(cObject.actions).forEach(([ n, action ]) => {
269
269
  setProp(action, '$isBound', true);
270
- const actionName = `${serviceName}.${isV2() ? `${entityName}_` : ''}${n}`;
270
+ const actionName = `${ serviceName }.${ isV2() ? `${ entityName }_` : '' }${ n }`;
271
271
  handleAction(actionName, action, cObjectname, [ ...location, 'actions', n ]);
272
272
  });
273
273
  }
@@ -283,7 +283,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
283
283
  if (isV2()) { // Replace up to last dot with <serviceName>.EntityContainer
284
284
  const lastDotIndex = actionName.lastIndexOf('.');
285
285
  if (lastDotIndex > -1)
286
- actionName = `${serviceName}.EntityContainer/${actionName.substring(lastDotIndex + 1)}`;
286
+ actionName = `${ serviceName }.EntityContainer/${ actionName.substring(lastDotIndex + 1) }`;
287
287
  }
288
288
  else { // add parameter type list
289
289
  actionName += relParList();
@@ -296,7 +296,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
296
296
  Object.entries(cAction.$paramsAnnoProxies).forEach(([ paramPath, param ]) => {
297
297
  // skip explicit binding parameter in V2
298
298
  if (!(options.isV2() && param.type === '$self' && paramPath === cAction.$bindingParam?.name)) {
299
- const edmTargetName = `${actionName}/${paramPath}`;
299
+ const edmTargetName = `${ actionName }/${ paramPath }`;
300
300
  handleAnnotations(edmTargetName, param,
301
301
  {
302
302
  location: param.$path,
@@ -309,7 +309,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
309
309
  // explicit binding parameter is removed from params in V2 during
310
310
  // createActionV2(), no need to check ;)
311
311
  Object.entries(cAction.params).forEach(([ n, p ]) => {
312
- const edmTargetName = `${actionName}/${n}`;
312
+ const edmTargetName = `${ actionName }/${ n }`;
313
313
  handleAnnotations(edmTargetName, p,
314
314
  {
315
315
  action: true,
@@ -321,7 +321,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
321
321
  if (cAction.returns) {
322
322
  if (cAction.$returnsAnnoProxies) {
323
323
  Object.entries(cAction.$returnsAnnoProxies).forEach(([ returnsPath, returns ]) => {
324
- const edmTargetName = `${actionName}/${returnsPath}`;
324
+ const edmTargetName = `${ actionName }/${ returnsPath }`;
325
325
  handleAnnotations(edmTargetName, returns,
326
326
  {
327
327
  location: returns.$path,
@@ -330,7 +330,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
330
330
  });
331
331
  });
332
332
  }
333
- const edmTargetName = `${actionName}/$ReturnType`;
333
+ const edmTargetName = `${ actionName }/$ReturnType`;
334
334
  setProp(cAction.returns, '$appliesToReturnType', true);
335
335
  handleAnnotations(edmTargetName, cAction.returns,
336
336
  {
@@ -349,7 +349,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
349
349
  cAction.$bindingParam?.viaAnno) {
350
350
  params.push(
351
351
  cAction.$bindingParam.items
352
- ? `Collection(${entityNameIfBound})`
352
+ ? `Collection(${ entityNameIfBound })`
353
353
  : entityNameIfBound
354
354
  );
355
355
  }
@@ -360,10 +360,10 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
360
360
  if (cAction.kind === 'function' && cAction.params) {
361
361
  Object.values(cAction.params).forEach((p) => {
362
362
  const isArrayType = !p.type && p.items && p.items.type;
363
- params.push(isArrayType ? `Collection(${mapType(p.items)})` : mapType(p));
363
+ params.push(isArrayType ? `Collection(${ mapType(p.items) })` : mapType(p));
364
364
  });
365
365
  }
366
- return `(${params.join(',')})`;
366
+ return `(${ params.join(',') })`;
367
367
 
368
368
  function mapType( p ) {
369
369
  if (isBuiltinType(p.type)) {
@@ -373,7 +373,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
373
373
  const schemaName = options.whatsMySchemaName(p._edmType || p.type);
374
374
  // strip the service namespace of from a parameter type
375
375
  if (schemaName && schemaName !== options.serviceName)
376
- return (p._edmType || p.type).replace(`${options.serviceName}.`, '');
376
+ return (p._edmType || p.type).replace(`${ options.serviceName }.`, '');
377
377
  }
378
378
  return p._edmType || p.type;
379
379
  }
@@ -571,7 +571,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
571
571
  alternativeEdmTargetNameP = carrier.$entitySetName || edmTargetName;
572
572
  const lastDotIndex = alternativeEdmTargetNameP.lastIndexOf('.');
573
573
  if (lastDotIndex > -1)
574
- alternativeEdmTargetNameP = `${serviceName}.EntityContainer/${alternativeEdmTargetNameP.substring(lastDotIndex + 1)}`;
574
+ alternativeEdmTargetNameP = `${ serviceName }.EntityContainer/${ alternativeEdmTargetNameP.substring(lastDotIndex + 1) }`;
575
575
  hasAlternativeCarrierP = carrier.$hasEntitySet;
576
576
  }
577
577
  else if (carrier.kind === 'type') {
@@ -586,8 +586,8 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
586
586
  testToAlternativeEdmTargetP = (x => (x ? x.includes(container) && !carrier.$isBound : true));
587
587
  const lastDotIndex = carrier.name.lastIndexOf('.');
588
588
  alternativeEdmTargetNameP = lastDotIndex > -1
589
- ? `${serviceName}.EntityContainer/${carrier.name.substring(lastDotIndex + 1)}`
590
- : `${serviceName}.EntityContainer/${carrier.name}`;
589
+ ? `${ serviceName }.EntityContainer/${ carrier.name.substring(lastDotIndex + 1) }`
590
+ : `${ serviceName }.EntityContainer/${ carrier.name }`;
591
591
  hasAlternativeCarrierP = true;
592
592
  }
593
593
  if (options.isV2())
@@ -604,7 +604,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
604
604
  // or AppliesTo=[Schema, EntityContainer]
605
605
  (x.includes('Schema') && x.includes('EntityContainer')))
606
606
  : true) );
607
- stdEdmTargetNameP = `${edmTargetName}.EntityContainer`;
607
+ stdEdmTargetNameP = `${ edmTargetName }.EntityContainer`;
608
608
  alternativeEdmTargetNameP = edmTargetName;
609
609
  hasAlternativeCarrierP = true; // EntityContainer is always available
610
610
  }
@@ -690,14 +690,14 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
690
690
  if (innerAnnotation) {
691
691
  // != null => also != undefined
692
692
  if (carrier[prefix] != null) {
693
- const valPrefix = `${prefix}.$value`;
693
+ const valPrefix = `${ prefix }.$value`;
694
694
  carrier[valPrefix] = carrier[prefix];
695
695
  delete carrier[prefix];
696
696
  rc = true;
697
697
  }
698
- const edmJsonPrefix = `${prefix}.$edmJson`;
698
+ const edmJsonPrefix = `${ prefix }.$edmJson`;
699
699
  if (carrier[edmJsonPrefix] != null) {
700
- const valPrefix = `${prefix}.$value.$edmJson`;
700
+ const valPrefix = `${ prefix }.$value.$edmJson`;
701
701
  carrier[valPrefix] = carrier[edmJsonPrefix];
702
702
  delete carrier[edmJsonPrefix];
703
703
  rc = true;
@@ -726,7 +726,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
726
726
  // takes care of assigning these annotations to the record members
727
727
  const [ prefix, innerAnnotation ] = a.split('.@');
728
728
  const ns = whatsMyTermNamespace(prefix);
729
- const steps = prefix.replace(`@${ns}.`, '').split('.');
729
+ const steps = prefix.replace(`@${ ns }.`, '').split('.');
730
730
  steps.splice(0, 0, ns);
731
731
  let i = steps.lastIndexOf('$edmJson');
732
732
  if (i > -1) {
@@ -738,13 +738,13 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
738
738
  // A voc annotation has two steps (Namespace+Name),
739
739
  // any further steps need to be rendered separately
740
740
  if (innerAnnotation.startsWith('sap.')) {
741
- steps.push(`@${innerAnnotation}`);
741
+ steps.push(`@${ innerAnnotation }`);
742
742
  }
743
743
  else {
744
744
  const innerAnnoSteps = innerAnnotation.split('.');
745
745
  const tailSteps = innerAnnoSteps.splice(2, innerAnnoSteps.length - 2);
746
746
  // prepend annotation prefix (path) to tail steps
747
- tailSteps.splice(0, 0, `@${innerAnnoSteps.join('.')}`);
747
+ tailSteps.splice(0, 0, `@${ innerAnnoSteps.join('.') }`);
748
748
  steps.push(...tailSteps);
749
749
  }
750
750
  }
@@ -785,7 +785,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
785
785
  mergePathStepsIntoPrefixTree(tree[name], pathSteps, index + 1);
786
786
  }
787
787
  else if (typeof tree === 'object' ) {
788
- tree[name] = carrier[`@${pathSteps.join('.')}`];
788
+ tree[name] = carrier[`@${ pathSteps.join('.') }`];
789
789
  }
790
790
  }
791
791
  }
@@ -802,13 +802,13 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
802
802
  // create an annotation tag <Annotation ...> for each term
803
803
  for (const voc of Object.keys(prefixTree)) {
804
804
  for (const term of Object.keys(prefixTree[voc])) {
805
- const fullTermName = `${voc}.${term}`;
805
+ const fullTermName = `${ voc }.${ term }`;
806
806
 
807
807
  // msg is "semantic" location message used for messages
808
808
  const msg = {
809
809
  fullTermName,
810
810
  stack: [],
811
- location: [ ...location, `@${fullTermName}` ],
811
+ location: [ ...location, `@${ fullTermName }` ],
812
812
  };
813
813
  msg.anno = () => msg.fullTermName + msg.stack.join('');
814
814
 
@@ -871,7 +871,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
871
871
  }
872
872
  else {
873
873
  // message if term is completely unknown or if vocabulary is unchecked
874
- const myVocDef = mergedVocDefs[whatsMyTermNamespace(`@${termNameWithoutQualifiers}`)];
874
+ const myVocDef = mergedVocDefs[whatsMyTermNamespace(`@${ termNameWithoutQualifiers }`)];
875
875
  if ((myVocDef?.int && myVocDef?.int?.filename) || !myVocDef)
876
876
  message('odata-anno-def', msg.location, { anno: termNameWithoutQualifiers });
877
877
  }
@@ -900,7 +900,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
900
900
  if (isEnumType(dTypeName)) {
901
901
  // if we find an array although we expect an enum, this may be a "flag enum"
902
902
  checkMultiEnumValue();
903
- oTarget.setJSON({ EnumMember: generateMultiEnumValue(false), 'EnumMember@odata.type': `#${dTypeName}` });
903
+ oTarget.setJSON({ EnumMember: generateMultiEnumValue(false), 'EnumMember@odata.type': `#${ dTypeName }` });
904
904
  oTarget.setXml( { EnumMember: generateMultiEnumValue(true) });
905
905
  }
906
906
  else {
@@ -931,8 +931,8 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
931
931
  {
932
932
  anno: msg.anno(),
933
933
  type: dTypeName,
934
- value: `"#${enumSymbol}"`,
935
- rawvalues: Object.keys(typeDef.$Allowed.Symbols).map(m => `#${m}`),
934
+ value: `"#${ enumSymbol }"`,
935
+ rawvalues: Object.keys(typeDef.$Allowed.Symbols).map(m => `#${ m }`),
936
936
  '#': 'enum',
937
937
  });
938
938
  }
@@ -941,14 +941,14 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
941
941
  }
942
942
  }
943
943
  else if (checkEnumValue(enumSymbol)) {
944
- oTarget.setXml( { EnumMember: `${dTypeName}/${enumSymbol}` });
944
+ oTarget.setXml( { EnumMember: `${ dTypeName }/${ enumSymbol }` });
945
945
  }
946
946
  else {
947
947
  oTarget.setXml( { String: enumSymbol });
948
948
  }
949
949
  }
950
950
  else {
951
- oTarget.setXml( { EnumMember: `${oTermName}Type/${enumSymbol}` });
951
+ oTarget.setXml( { EnumMember: `${ oTermName }Type/${ enumSymbol }` });
952
952
  }
953
953
  oTarget.setJSON({ 'Edm.String': enumSymbol });
954
954
  }
@@ -1014,7 +1014,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1014
1014
  {
1015
1015
  anno: msg.anno(),
1016
1016
  type: dTypeName,
1017
- value: `"#${value}"`,
1017
+ value: `"#${ value }"`,
1018
1018
  });
1019
1019
  rc = false;
1020
1020
  }
@@ -1023,8 +1023,8 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1023
1023
  {
1024
1024
  anno: msg.anno(),
1025
1025
  type: dTypeName,
1026
- value: `"#${value}"`,
1027
- rawvalues: expectedType.Members.map(m => `#${m}`),
1026
+ value: `"#${ value }"`,
1027
+ rawvalues: expectedType.Members.map(m => `#${ m }`),
1028
1028
  '#': 'enum',
1029
1029
  });
1030
1030
  }
@@ -1049,7 +1049,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1049
1049
 
1050
1050
  let index = 0;
1051
1051
  for (const value of cAnnoValue) {
1052
- msg.stack.push(`[${index}]`);
1052
+ msg.stack.push(`[${ index }]`);
1053
1053
  index++;
1054
1054
  if (value['#']) {
1055
1055
  checkEnumValue(value['#']);
@@ -1060,7 +1060,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1060
1060
  anno: msg.anno(),
1061
1061
  type: dTypeName,
1062
1062
  value: value['='] || value,
1063
- rawvalues: type.Members.map(m => `#${m}`),
1063
+ rawvalues: type.Members.map(m => `#${ m }`),
1064
1064
  '#': 'enum',
1065
1065
  });
1066
1066
  }
@@ -1072,7 +1072,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1072
1072
  // remove all invalid entries (warnining message has already been issued)
1073
1073
  // replace short enum name by the full name
1074
1074
  // concatenate all the enums to a string, separated by spaces
1075
- return cAnnoValue.filter( x => x['#']).map( x => (forXml ? `${dTypeName}/` : '') + x['#'] ).join(forXml ? ' ' : ',');
1075
+ return cAnnoValue.filter( x => x['#']).map( x => (forXml ? `${ dTypeName }/` : '') + x['#'] ).join(forXml ? ' ' : ',');
1076
1076
  }
1077
1077
  }
1078
1078
 
@@ -1120,7 +1120,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1120
1120
 
1121
1121
  if (isEnumType(resolvedType)) {
1122
1122
  const type = getDictType(resolvedType);
1123
- const expected = type.Members.map(m => `#${m}`);
1123
+ const expected = type.Members.map(m => `#${ m }`);
1124
1124
  message('odata-anno-value', msg.location,
1125
1125
  {
1126
1126
  anno: msg.anno(),
@@ -1334,7 +1334,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1334
1334
  // Set full qualified type in JSON
1335
1335
  // TODO: Adhoc type x-ref URIs (only if abstract types are allowed in CDS)
1336
1336
  if (myVocDef)
1337
- newRecord.setJSON( { Type: `${myVocDef.ref.Uri}#${actualTypeName}` });
1337
+ newRecord.setJSON( { Type: `${ myVocDef.ref.Uri }#${ actualTypeName }` });
1338
1338
  // don't add short actualTypeName into JSON as this would be wrong for a resolved! type.
1339
1339
  // A $Type w/o vocDef can only occur for adhoc type defs and these can't be abstract but
1340
1340
  // are fully resolvable due to their term usage via schema x-ref.
@@ -1372,7 +1372,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1372
1372
 
1373
1373
  // loop over elements
1374
1374
  for (const name of Object.keys(obj)) {
1375
- msg.stack.push(`.${name}`);
1375
+ msg.stack.push(`.${ name }`);
1376
1376
 
1377
1377
  if (name === '$Type') {
1378
1378
  // ignore, this is an "artificial" property used to indicate the type
@@ -1420,7 +1420,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1420
1420
 
1421
1421
  let index = 0;
1422
1422
  for (const value of annoValue) {
1423
- msg.stack.push(`[${index}]`);
1423
+ msg.stack.push(`[${ index }]`);
1424
1424
  index++;
1425
1425
 
1426
1426
  // for dealing with the single array entries we unfortunately cannot call handleValue(),
@@ -1514,7 +1514,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1514
1514
 
1515
1515
  if ((annoDef.items?.enum || annoDef.enum) && isBuiltinType(annoDef.items?.type || annoDef.type)) {
1516
1516
  const enumType = createTypeDefWithAllowedValues(annoDef, annoDef, dictDef.Type, [ 'vocabularies', termName ]);
1517
- const tName = `${termName}_$$$EnumType$$$$`;
1517
+ const tName = `${ termName }_$$$EnumType$$$$`;
1518
1518
  dict.types[tName] = enumType;
1519
1519
  dictDef.Type = tName;
1520
1520
  }
@@ -1531,7 +1531,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1531
1531
  // for type reuse in x-ref mode, the definition has already been
1532
1532
  // replaced by a reference object in edmPreprocessor.
1533
1533
  // Fall back to original type (the one of the other service).
1534
- const typeDef = reqDefs.definitions[typeName] || reqDefs.definitions[typeName.replace(`${serviceName}.`, '')];
1534
+ const typeDef = reqDefs.definitions[typeName] || reqDefs.definitions[typeName.replace(`${ serviceName }.`, '')];
1535
1535
  if (typeDef) {
1536
1536
  let dictDef = { };
1537
1537
  const elements = typeDef.items?.elements || typeDef.elements;
@@ -1612,10 +1612,10 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1612
1612
  if (!hasNSPrefix)
1613
1613
  paths.splice(0, 0, serviceName);
1614
1614
 
1615
- const fqName = `@${paths.join('.')}`;
1615
+ const fqName = `@${ paths.join('.') }`;
1616
1616
  const i = paths[1].indexOf('#');
1617
1617
  const termNameWithoutQualifiers = i > 0 ? paths[1].substring(0, i) : paths[1];
1618
- const def = reqDefs.definitions[`${paths[0]}.${termNameWithoutQualifiers}`];
1618
+ const def = reqDefs.definitions[`${ paths[0] }.${ termNameWithoutQualifiers }`];
1619
1619
  // if there is a term definition inside the service and the
1620
1620
  // annotation value is != null, then add the annotation to the list
1621
1621
  // of known annotations
@@ -1647,7 +1647,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1647
1647
  function getDictTerm( termName, msg ) {
1648
1648
  const dict = options.dictReplacement || oDataDictionary; // tests can set different dictionary via options
1649
1649
  const dictTerm = (dict.terms[termName] ||
1650
- userDefinedTermDict.terms[`${serviceName}.${termName}`] ||
1650
+ userDefinedTermDict.terms[`${ serviceName }.${ termName }`] ||
1651
1651
  userDefinedTermDict.terms[termName]);
1652
1652
  // register vocabulary usage if possible
1653
1653
  const vocName = termName.slice(0, termName.indexOf('.'));
@@ -1676,7 +1676,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
1676
1676
  function getDictType( typeName ) {
1677
1677
  const dict = options.dictReplacement || oDataDictionary; // tests can set different dictionary via options
1678
1678
  const dictType = (dict.types[typeName] ||
1679
- userDefinedTermDict.types[`${serviceName}.${typeName}`] ||
1679
+ userDefinedTermDict.types[`${ serviceName }.${ typeName }`] ||
1680
1680
  userDefinedTermDict.types[typeName]);
1681
1681
  if (dictType) {
1682
1682
  // register usage of vocabulary
@@ -57,7 +57,7 @@ function preprocessAnnotations( csn, serviceName, options, messageFunctions ) {
57
57
  function resolveShortcuts() {
58
58
  forEachDefinition(csn, (artifact, artifactName) => {
59
59
  const location = [ 'definitions', artifactName ];
60
- if (artifactName === serviceName || artifactName.startsWith(`${serviceName}.`)) {
60
+ if (artifactName === serviceName || artifactName.startsWith(`${ serviceName }.`)) {
61
61
  handleAnnotations(artifactName, artifactName, artifact, location);
62
62
  if (artifact.elements) {
63
63
  Object.entries(artifact.elements).forEach(([ elementName, element ]) => {
@@ -113,14 +113,14 @@ function preprocessAnnotations( csn, serviceName, options, messageFunctions ) {
113
113
  if (value === 'draftPrepare' || value === 'draftActivate' || value === 'draftEdit') {
114
114
  // mocha test has no whatsMySchemaName
115
115
  const schemaName = options.whatsMySchemaName && options.whatsMySchemaName(carrierName) || serviceName;
116
- carrier[aName] = `${schemaName}.${value}`;
116
+ carrier[aName] = `${ schemaName }.${ value }`;
117
117
  value = carrier[aName];
118
118
  }
119
119
  // for v2: function imports live inside EntityContainer -> path needs to contain "EntityContainer/"
120
120
  // we decided to prefix names of bound action/functions with entity name -> needs to be reflected in path, too
121
121
  if (isV2()) {
122
122
  const entityNameShort = carrierName.split('.').pop();
123
- carrier[aName] = value.replace(/(draft(Prepare|Activate|Edit))$/, (match, p1) => `EntityContainer/${entityNameShort}_${p1}`);
123
+ carrier[aName] = value.replace(/(draft(Prepare|Activate|Edit))$/, (match, p1) => `EntityContainer/${ entityNameShort }_${ p1 }`);
124
124
  }
125
125
  }
126
126
  }
@@ -186,7 +186,7 @@ function preprocessAnnotations( csn, serviceName, options, messageFunctions ) {
186
186
  // mocha test has no whatsMySchemaName
187
187
  const schemaName = options.whatsMySchemaName && options.whatsMySchemaName(defName) || serviceName;
188
188
  enameShort = annoVal['='] || annoVal;
189
- enameFull = `${schemaName}.${enameShort}`;
189
+ enameFull = `${ schemaName }.${ enameShort }`;
190
190
  }
191
191
 
192
192
  const vlEntity = csn.definitions[enameFull]; // (object) value list entity
@@ -214,7 +214,7 @@ function preprocessAnnotations( csn, serviceName, options, messageFunctions ) {
214
214
  if (carrier['@cds.api.ignore']) {
215
215
  const assocName = carrier['@odata.foreignKey4'];
216
216
  if (assocName && options.isV4())
217
- localDataProp = localDataProp.replace(assocName + fkSeparator, `${assocName}/`);
217
+ localDataProp = localDataProp.replace(assocName + fkSeparator, `${ assocName }/`);
218
218
  }
219
219
 
220
220
  // valueListProp: the (single) key field of the value list entity
@@ -170,7 +170,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
170
170
  -----------------------------------------------*/
171
171
  let LeadSchema;
172
172
  const fqSchemaXRef = [ serviceCsn.name ];
173
- const whatsMySchemaName = n => fqSchemaXRef.reduce((acc, sn) => (!acc && n && n.startsWith(`${sn}.`) ? sn : acc), undefined);
173
+ const whatsMySchemaName = n => fqSchemaXRef.reduce((acc, sn) => (!acc && n && n.startsWith(`${ sn }.`) ? sn : acc), undefined);
174
174
 
175
175
  // tunnel schema xref and servicename in options to edm.Typebase to rectify
176
176
  // type references that are eventually also prefixed with the service schema name.
@@ -205,13 +205,13 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
205
205
  // Add additional schema containers as sub contexts to the service
206
206
  forEach(allSchemas, (fqName, art) => {
207
207
  if (serviceCsn.name === whatsMyServiceRootName(fqName) &&
208
- fqName.startsWith(`${serviceCsn.name}.`)) {
208
+ fqName.startsWith(`${ serviceCsn.name }.`)) {
209
209
  if (art.kind === 'reference')
210
210
  fqSchemaXRef.push(fqName);
211
211
  if (art.kind === 'schema') {
212
212
  fqSchemaXRef.push(fqName);
213
213
  // Strip the toplevel service schema name (see comment above)
214
- const name = fqName.replace(`${serviceCsn.name}.`, '');
214
+ const name = fqName.replace(`${ serviceCsn.name }.`, '');
215
215
  subSchemaDictionary[name] = {
216
216
  name,
217
217
  fqName,
@@ -298,8 +298,8 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
298
298
  - not a type clash (reported in type exposure),
299
299
  - a @cds.external service member but can't be rendered
300
300
  */
301
- if (!typeName.startsWith(`${serviceCsn.name}.`))
302
- iTypeName = `${serviceCsn.name}.${typeName}`;
301
+ if (!typeName.startsWith(`${ serviceCsn.name }.`))
302
+ iTypeName = `${ serviceCsn.name }.${ typeName }`;
303
303
  const def = reqDefs.definitions[iTypeName];
304
304
 
305
305
  const usages = UsedTypes[typeName].filter(u => !u.$NameClashReported);
@@ -355,9 +355,9 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
355
355
  // except if the schema name is the service name itself.
356
356
  // Proxy names are not prefixed, as they need to be reused.
357
357
  if (mySchemaName !== serviceCsn.name) {
358
- art.name = fqName.replace(`${serviceCsn.name}.`, '');
358
+ art.name = fqName.replace(`${ serviceCsn.name }.`, '');
359
359
  fqName = art.name;
360
- mySchemaName = mySchemaName.replace(`${serviceCsn.name}.`, '');
360
+ mySchemaName = mySchemaName.replace(`${ serviceCsn.name }.`, '');
361
361
  }
362
362
  schemas[mySchemaName].definitions[fqName] = art;
363
363
  }
@@ -422,7 +422,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
422
422
  const Schema = new Edm.Schema(v, schema.name, undefined /* unset alias */, schema._csn, /* annotations */ [], schema.container);
423
423
  const EntityContainer = Schema._ec || (LeadSchema && LeadSchema._ec);
424
424
  // now namespace and alias are used to create the fullQualified(name)
425
- const schemaNamePrefix = `${schema.name}.`;
425
+ const schemaNamePrefix = `${ schema.name }.`;
426
426
  const schemaAliasPrefix = schemaNamePrefix;
427
427
  const schemaCsn = schema;
428
428
  const navigationProperties = [];
@@ -502,7 +502,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
502
502
 
503
503
  forEach(NamesInSchemaXRef, ( name, refs ) => {
504
504
  if (refs.length > 1) {
505
- error(null, [ 'definitions', `${Schema._edmAttributes.Namespace}.${name}` ], { name: Schema._edmAttributes.Namespace },
505
+ error(null, [ 'definitions', `${ Schema._edmAttributes.Namespace }.${ name }` ], { name: Schema._edmAttributes.Namespace },
506
506
  'Duplicate name in Schema $(NAME)');
507
507
  }
508
508
  });
@@ -516,7 +516,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
516
516
  const [ properties, hasStream ] = createProperties(entityCsn);
517
517
 
518
518
  const location = reqDefs.definitions[entityCsn.name] ? [ 'definitions', entityCsn.name ] : entityCsn.$path;
519
- const type = `${schema.name}.${EntityTypeName}`;
519
+ const type = `${ schema.name }.${ EntityTypeName }`;
520
520
  if (properties.length === 0)
521
521
  warning(null, location, { type }, 'EDM EntityType $(TYPE) has no properties');
522
522
  // only if this entity has an entity set, it is required to have a key
@@ -900,7 +900,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
900
900
  if (entityCsn) {
901
901
  // Make bound function names always unique as per Ralf's recommendation
902
902
  functionImport.setXml( { 'sap:action-for': fullQualified(entityCsn.name) } );
903
- const entityName = `${entityCsn.name.replace(schemaNamePrefix, '')}_${functionImport._edmAttributes.Name}`;
903
+ const entityName = `${ entityCsn.name.replace(schemaNamePrefix, '') }_${ functionImport._edmAttributes.Name }`;
904
904
  functionImport.setEdmAttribute('Name', entityName);
905
905
 
906
906
  // Binding Parameter: Primary Keys at first position in sequence, this is decisive!
@@ -915,7 +915,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
915
915
  // is this still required?
916
916
  forEach(actionCsn, ( key, val ) => {
917
917
  if (key.match(/^@sap\./))
918
- functionImport.setXml( { [`sap:${key.slice(5).replace(/\./g, '-')}`]: val });
918
+ functionImport.setXml( { [`sap:${ key.slice(5).replace(/\./g, '-') }`]: val });
919
919
  });
920
920
  // then append all other parameters
921
921
  // V2 XML: Parameters that are not explicitly marked as Nullable or NotNullable in the CSN must become Nullable=true
@@ -982,7 +982,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
982
982
  }
983
983
  }
984
984
  if (action.returns.$isCollection)
985
- type = `Collection(${type})`;
985
+ type = `Collection(${ type })`;
986
986
  }
987
987
  else {
988
988
  // type is missing
@@ -1014,7 +1014,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
1014
1014
  let assocName = plainAssocName;
1015
1015
  let i = 1;
1016
1016
  while (NamesInSchemaXRef[assocName] !== undefined)
1017
- assocName = `${plainAssocName}_${i++}`;
1017
+ assocName = `${ plainAssocName }_${ i++ }`;
1018
1018
 
1019
1019
 
1020
1020
  let fromRole = parentName;
@@ -1068,7 +1068,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
1068
1068
  assocName = plainAssocName;
1069
1069
  i = 1;
1070
1070
  while (NamesInSchemaXRef[assocName] !== undefined && !(NamesInSchemaXRef[assocName][0] instanceof Edm.Association))
1071
- assocName = `${plainAssocName}_${i++}`;
1071
+ assocName = `${ plainAssocName }_${ i++ }`;
1072
1072
 
1073
1073
 
1074
1074
  navigationProperty.setEdmAttribute('Relationship', fullQualified(assocName));
@@ -1136,7 +1136,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
1136
1136
  if (targetSchema === undefined)
1137
1137
  targetSchema = serviceCsn.name;
1138
1138
  if (targetSchema !== serviceCsn.name) {
1139
- const newTarget = anno._edmAttributes.Target.replace(`${serviceCsn.name}.`, '');
1139
+ const newTarget = anno._edmAttributes.Target.replace(`${ serviceCsn.name }.`, '');
1140
1140
  anno.setEdmAttribute('Target', newTarget);
1141
1141
  }
1142
1142
  edm._service._schemas[targetSchema]._annotations.push(anno);