@sap/cds-compiler 6.2.2 → 6.3.0

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 (57) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/bin/cdsc.js +11 -4
  3. package/lib/api/options.js +1 -1
  4. package/lib/base/message-registry.js +36 -7
  5. package/lib/base/messages.js +11 -4
  6. package/lib/base/model.js +0 -1
  7. package/lib/checks/assocOutsideService.js +17 -30
  8. package/lib/checks/checkForTypes.js +0 -18
  9. package/lib/checks/checkPathsInStoredCalcElement.js +2 -1
  10. package/lib/checks/onConditions.js +2 -2
  11. package/lib/checks/queryNoDbArtifacts.js +16 -15
  12. package/lib/checks/types.js +1 -1
  13. package/lib/checks/utils.js +30 -6
  14. package/lib/checks/validator.js +4 -5
  15. package/lib/compiler/checks.js +47 -18
  16. package/lib/compiler/index.js +88 -6
  17. package/lib/compiler/resolve.js +7 -7
  18. package/lib/compiler/tweak-assocs.js +47 -25
  19. package/lib/gen/BaseParser.js +1 -1
  20. package/lib/gen/CdlGrammar.checksum +1 -1
  21. package/lib/gen/CdlParser.js +381 -378
  22. package/lib/gen/Dictionary.json +0 -2
  23. package/lib/model/csnRefs.js +9 -4
  24. package/lib/model/csnUtils.js +67 -2
  25. package/lib/optionProcessor.js +2 -3
  26. package/lib/parsers/AstBuildingParser.js +5 -6
  27. package/lib/render/toCdl.js +10 -4
  28. package/lib/render/utils/common.js +4 -2
  29. package/lib/transform/db/assertUnique.js +2 -1
  30. package/lib/transform/db/associations.js +37 -1
  31. package/lib/transform/db/assocsToQueries/transformExists.js +21 -32
  32. package/lib/transform/db/assocsToQueries/utils.js +1 -1
  33. package/lib/transform/db/cdsPersistence.js +1 -1
  34. package/lib/transform/db/expansion.js +37 -36
  35. package/lib/transform/draft/db.js +20 -20
  36. package/lib/transform/draft/odata.js +38 -40
  37. package/lib/transform/effective/associations.js +1 -1
  38. package/lib/transform/effective/flattening.js +40 -47
  39. package/lib/transform/effective/main.js +6 -4
  40. package/lib/transform/forOdata.js +135 -115
  41. package/lib/transform/forRelationalDB.js +151 -142
  42. package/lib/transform/localized.js +116 -109
  43. package/lib/transform/odata/adaptAnnotationRefs.js +21 -16
  44. package/lib/transform/odata/createForeignKeys.js +73 -70
  45. package/lib/transform/odata/flattening.js +216 -200
  46. package/lib/transform/odata/foreignKeyRefsInXprAnnos.js +47 -45
  47. package/lib/transform/odata/toFinalBaseType.js +40 -39
  48. package/lib/transform/odata/typesExposure.js +151 -133
  49. package/lib/transform/odata/utils.js +7 -6
  50. package/lib/transform/parseExpr.js +165 -162
  51. package/lib/transform/transformUtils.js +184 -551
  52. package/lib/transform/translateAssocsToJoins.js +510 -571
  53. package/lib/transform/tupleExpansion.js +495 -0
  54. package/lib/transform/universalCsn/universalCsnEnricher.js +1 -0
  55. package/package.json +1 -1
  56. package/lib/base/cleanSymbols.js +0 -17
  57. package/lib/checks/nonexpandableStructured.js +0 -39
@@ -8,8 +8,10 @@
8
8
 
9
9
  const { setProp, isBetaEnabled } = require('../../base/model');
10
10
  const { defNameWithoutServiceOrContextName, isArtifactInService } = require('./utils');
11
- const { getNamespace, copyAnnotations,
12
- forEachDefinition, forEachMember, forEachGeneric, isEdmPropertyRendered } = require('../../model/csnUtils');
11
+ const {
12
+ getNamespace, copyAnnotations,
13
+ forEachDefinition, forEachMember, forEachGeneric, isEdmPropertyRendered,
14
+ } = require('../../model/csnUtils');
13
15
  const { isBuiltinType } = require('../../base/builtins');
14
16
  const { CompilerAssertion } = require('../../base/error');
15
17
  const { cloneCsnNonDict } = require('../../model/cloneCsn');
@@ -81,23 +83,24 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
81
83
  if (propertyName === 'elements') {
82
84
  const newTypeName = getNewTypeName(element, elementName, defName, serviceName);
83
85
  exposeTypeOf(element, element.key, elementName, defName, serviceName, newTypeName, defName, path);
84
- } else if (propertyName === 'params') {
85
- const newTypeName = getNewTypeName(element, elementName, `ep_${defName.replace(/\./g, '_')}`, serviceName);
86
+ }
87
+ else if (propertyName === 'params') {
88
+ const newTypeName = getNewTypeName(element, elementName, `ep_${ defName.replace(/\./g, '_') }`, serviceName);
86
89
  exposeTypeOf(element, true, elementName, defName, serviceName, newTypeName, defName, path);
87
90
  }
88
91
  }, path);
89
92
  }
90
93
 
91
- if (def.kind === 'action' || def.kind === 'function') {
94
+ if (def.kind === 'action' || def.kind === 'function')
92
95
  exposeTypesOfAction(def, defName, defName, serviceName, path, false);
93
- }
94
- def.actions && Object.entries(def.actions).forEach(([actionName, action]) => {
95
- exposeTypesOfAction(action, `${defName}_${actionName}`, defName, serviceName, path.concat(['actions', actionName]), true);
96
+
97
+ Object.entries(def.actions || {}).forEach(([ actionName, action ]) => {
98
+ exposeTypesOfAction(action, `${ defName }_${ actionName }`, defName, serviceName, path.concat([ 'actions', actionName ]), true);
96
99
  });
97
100
  }
98
101
  });
99
102
 
100
- if(isBetaEnabled(options, 'odataTerms')) {
103
+ if (isBetaEnabled(options, 'odataTerms')) {
101
104
  forEachGeneric(csn, 'vocabularies', (def, defName, _propertyName, path) => {
102
105
  const serviceName = whatsMyServiceName(defName, false);
103
106
  if (serviceName && requestedServiceNames.includes(serviceName)) {
@@ -108,9 +111,9 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
108
111
  // link def into definitions for later use
109
112
  def.kind = 'annotation';
110
113
  csn.definitions[defName] = def;
111
- const artificialName = `term_${defName.replace(/\./g, '_')}`;//_${paramName}`;
114
+ const artificialName = `term_${ defName.replace(/\./g, '_') }`;// _${paramName}`;
112
115
  const newTypeName = getNewTypeName(undefined, undefined, artificialName, serviceName);
113
- exposeTypeOf(def, false, defName, defName, serviceName, newTypeName, defName, path.concat(['vocabularies', defName]), undefined, true);
116
+ exposeTypeOf(def, false, defName, defName, serviceName, newTypeName, defName, path.concat([ 'vocabularies', defName ]), undefined, true);
114
117
  }
115
118
  }
116
119
  });
@@ -118,7 +121,7 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
118
121
 
119
122
  return schemas;
120
123
 
121
- /**
124
+ /**
122
125
  * If an 'action' uses structured types as parameters or return values that are not exposed in 'service'
123
126
  * (because the types are anonymous or have a definition outside of 'service'),
124
127
  * create equivalent types in 'service' and make 'action' use them instead,
@@ -128,15 +131,15 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
128
131
  */
129
132
  function exposeTypesOfAction(action, actionName, defName, serviceName, path, isBound) {
130
133
  if (action.returns) {
131
- const artificialName = `return_${actionName.replace(/\./g, '_')}`;
134
+ const artificialName = `return_${ actionName.replace(/\./g, '_') }`;
132
135
  const newTypeName = getNewTypeName(action.returns, undefined, artificialName, serviceName);
133
- exposeTypeOf(action.returns, false, actionName, defName, serviceName, newTypeName, defName, path.concat(['returns']));
136
+ exposeTypeOf(action.returns, false, actionName, defName, serviceName, newTypeName, defName, path.concat([ 'returns' ]));
134
137
  }
135
138
 
136
- action.params && Object.entries(action.params).forEach(([paramName, param]) => {
137
- const artificialName = `${isBound ? 'bap' : 'ap'}_${actionName.replace(/\./g, '_')}`;//_${paramName}`;
139
+ Object.entries(action.params || {}).forEach(([ paramName, param ]) => {
140
+ const artificialName = `${ isBound ? 'bap' : 'ap' }_${ actionName.replace(/\./g, '_') }`;// _${paramName}`;
138
141
  const newTypeName = getNewTypeName(param, paramName, artificialName, serviceName);
139
- exposeTypeOf(param, false, actionName, defName, serviceName, newTypeName, defName, path.concat(['params', paramName]));
142
+ exposeTypeOf(param, false, actionName, defName, serviceName, newTypeName, defName, path.concat([ 'params', paramName ]));
140
143
  });
141
144
  }
142
145
 
@@ -149,25 +152,27 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
149
152
  * @param {String} serviceName
150
153
  * @param {String} newTypeName
151
154
  */
152
- function exposeTypeOf(node, isKey, memberName, defName, serviceName, newTypeName, lastNonAnonymousFQDefName, path, parentName, isTermDef=false, ignoreInAPI=false) {
153
- const { isExposable, typeDef, typeName, elements, isAnonymous } = isTypeExposable();
155
+ function exposeTypeOf(node, isKey, memberName, defName, serviceName, newTypeName, lastNonAnonymousFQDefName, path, parentName, isTermDef = false, ignoreInAPI = false) {
156
+ const {
157
+ isExposable, typeDef, typeName, elements, isAnonymous,
158
+ } = isTypeExposable();
154
159
  if (isExposable) {
155
160
  // this is the name used to register the new type in csn.definitions
156
- let fullQualifiedNewTypeName =
157
- isMultiSchema
158
- ? (node.type || (node.items?.type)
159
- ? getTypeNameInMultiSchema(node.type|| (node.items?.type), serviceName)
160
- : getAnonymousTypeNameInMultiSchema(newTypeName, parentName || defName))
161
- : `${serviceName}.${newTypeName}`;
161
+ // eslint-disable-next-line no-nested-ternary
162
+ let fullQualifiedNewTypeName = isMultiSchema
163
+ ? (node.type || (node.items?.type)
164
+ ? getTypeNameInMultiSchema(node.type || (node.items?.type), serviceName)
165
+ : getAnonymousTypeNameInMultiSchema(newTypeName, parentName || defName))
166
+ : `${ serviceName }.${ newTypeName }`;
162
167
 
163
168
  if (!isAnonymous) {
164
169
  // as soon as we leave of the anonymous world,
165
170
  // we're no longer in a key def => don't set notNull:true on named types
166
- if(isKey)
171
+ if (isKey)
167
172
  isKey = false;
168
173
  // in case this was a named type and if the openness does not match the type definition
169
174
  // expose the type as a new one not changing the original definition.
170
- if(elements && node['@open'] != null && !!node['@open'] !== !!typeDef['@open'])
175
+ if (elements && node['@open'] != null && !!node['@open'] !== !!typeDef['@open'])
171
176
  fullQualifiedNewTypeName += node['@open'] ? '_open' : '_closed';
172
177
  lastNonAnonymousFQDefName = fullQualifiedNewTypeName;
173
178
  }
@@ -178,84 +183,86 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
178
183
  if (!exposedTypes[fullQualifiedNewTypeName]) {
179
184
  setProp(node, '$NameClashReported', true);
180
185
  error(null, path, { type: fullQualifiedNewTypeName, name: memberName },
181
- 'Can\'t create artificial type $(TYPE) for $(NAME) because the name is already used');
182
- return { isExposable, typeDef, typeName, isAnonymous };
186
+ 'Can\'t create artificial type $(TYPE) for $(NAME) because the name is already used');
187
+ return {
188
+ isExposable, typeDef, typeName, isAnonymous,
189
+ };
183
190
  }
184
191
  }
185
- else {
192
+ else if (elements) {
186
193
  /* Expose new structured type
187
194
  * Treat items.elements as ordinary elements for now.
188
195
  */
189
- if(elements) {
190
- newType = createNewStructType(elements);
191
- // if using node enforces open/closed, set it on type
192
- if (node['@open'] !== undefined)
193
- newType['@open'] = node['@open']
194
- if (node.$location)
195
- setProp(newType, '$location', node.$location);
196
- ignoreInAPI ||= !isEdmPropertyRendered(node, options);
197
- setProp(newType, '$ignoreInAPI', ignoreInAPI);
196
+ newType = createNewStructType(elements);
197
+ // if using node enforces open/closed, set it on type
198
+ if (node['@open'] !== undefined)
199
+ newType['@open'] = node['@open'];
200
+ if (node.$location)
201
+ setProp(newType, '$location', node.$location);
202
+ ignoreInAPI ||= !isEdmPropertyRendered(node, options);
203
+ setProp(newType, '$ignoreInAPI', ignoreInAPI);
198
204
 
199
- csn.definitions[fullQualifiedNewTypeName] = newType;
200
- exposedTypes[fullQualifiedNewTypeName] = 1;
205
+ csn.definitions[fullQualifiedNewTypeName] = newType;
206
+ exposedTypes[fullQualifiedNewTypeName] = 1;
201
207
 
202
- // Recurse into elements of 'type' (if any) and expose them as well (is needed)
203
- newType.elements && Object.entries(newType.elements).forEach(([elemName, newElem]) => {
204
- if (node.elements && node.elements[elemName].$location)
205
- setProp(newElem, '$location', node.elements[elemName].$location);
206
- if (newElem.$path)
207
- newElem.$path[1] = lastNonAnonymousFQDefName;
208
- defName = typeDef.kind === 'type' ? typeName : defName;
209
- {
210
- const { isExposable, typeDef, typeName } = exposeTypeOf(newElem, isKey, elemName, defName, serviceName,
211
- getNewTypeName(newElem, elemName, newTypeName, serviceName), lastNonAnonymousFQDefName, path, fullQualifiedNewTypeName, isTermDef, ignoreInAPI);
208
+ // Recurse into elements of 'type' (if any) and expose them as well (is needed)
209
+ Object.entries(newType.elements || {}).forEach(([ elemName, newElem ]) => {
210
+ if (node.elements && node.elements[elemName].$location)
211
+ setProp(newElem, '$location', node.elements[elemName].$location);
212
+ if (newElem.$path)
213
+ newElem.$path[1] = lastNonAnonymousFQDefName;
214
+ defName = typeDef.kind === 'type' ? typeName : defName;
215
+ {
216
+ const { isExposable, typeDef, typeName } = exposeTypeOf(
217
+ newElem, isKey, elemName, defName, serviceName,
218
+ getNewTypeName(newElem, elemName, newTypeName, serviceName), lastNonAnonymousFQDefName, path, fullQualifiedNewTypeName, isTermDef, ignoreInAPI
219
+ );
212
220
  // if the type for the newElem was not exposed it may be a scalar type def from an external service that hasn't
213
221
  // been caught by expandToFinalBaseType() (forODataNew must not modify external imported services)
214
- if(!isExposable && isBuiltinType(typeName) && !isBuiltinType((newElem.items?.type || newElem.type))) {
215
- if(typeDef.items) {
216
- newElem.items = typeDef.items;
217
- delete newElem.type;
218
- }
219
- else if(newElem.items) {
220
- newElem.items.type = typeName;
221
- if(typeDef.enum)
222
- newElem.items.enum = typeDef.enum;
223
- }
224
- else {
225
- newElem.type = typeName;
226
- if(typeDef.enum)
227
- newElem.enum = typeDef.enum;
228
- }
222
+ if (!isExposable && isBuiltinType(typeName) && !isBuiltinType((newElem.items?.type || newElem.type))) {
223
+ if (typeDef.items) {
224
+ newElem.items = typeDef.items;
225
+ delete newElem.type;
226
+ }
227
+ else if (newElem.items) {
228
+ newElem.items.type = typeName;
229
+ if (typeDef.enum)
230
+ newElem.items.enum = typeDef.enum;
231
+ }
232
+ else {
233
+ newElem.type = typeName;
234
+ if (typeDef.enum)
235
+ newElem.enum = typeDef.enum;
229
236
  }
230
237
  }
231
- });
232
-
233
- // Annotations are propagated only from user defined structured
234
- // types that need to be added to a service
235
- if (!isAnonymous) {
236
- copyAnnotations(typeDef, newType);
237
238
  }
239
+ });
238
240
 
239
- // if the origin type had items, add items to exposed type
240
- if(typeDef.kind === 'type') {
241
- if(typeDef.items) {
242
- newType.items = { elements: newType.elements };
243
- delete newType.elements;
244
- }
245
- }
246
- }
247
- else if(isTermDef) {
248
- newType = Object.create(null);
249
- for(const n in typeDef) {
250
- newType[n] = typeDef[n];
241
+ // Annotations are propagated only from user defined structured
242
+ // types that need to be added to a service
243
+ if (!isAnonymous)
244
+ copyAnnotations(typeDef, newType);
245
+
246
+
247
+ // if the origin type had items, add items to exposed type
248
+ if (typeDef.kind === 'type') {
249
+ if (typeDef.items) {
250
+ newType.items = { elements: newType.elements };
251
+ delete newType.elements;
251
252
  }
252
- newType.kind = 'type';
253
- csn.definitions[fullQualifiedNewTypeName] = newType;
254
- exposedTypes[fullQualifiedNewTypeName] = 1;
255
253
  }
256
254
  }
255
+ else if (isTermDef) {
256
+ newType = Object.create(null);
257
+ for (const n in typeDef)
258
+ newType[n] = typeDef[n];
259
+
260
+ newType.kind = 'type';
261
+ csn.definitions[fullQualifiedNewTypeName] = newType;
262
+ exposedTypes[fullQualifiedNewTypeName] = 1;
263
+ }
257
264
  // adjust current node to new type
258
- if(node.items) {
265
+ if (node.items) {
259
266
  delete node.items.elements;
260
267
  delete node.type;
261
268
  node.items.type = fullQualifiedNewTypeName;
@@ -265,7 +272,9 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
265
272
  node.type = fullQualifiedNewTypeName;
266
273
  }
267
274
  }
268
- return { isExposable, typeDef, typeName, isAnonymous };
275
+ return {
276
+ isExposable, typeDef, typeName, isAnonymous,
277
+ };
269
278
 
270
279
  /**
271
280
  * Check if the node's type can be exposed:
@@ -283,31 +292,37 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
283
292
  * @returns {object} { isExposable, typeDef, typeName, elements, isAnonymous }
284
293
  */
285
294
  function isTypeExposable() {
286
- let typeName = undefined;
295
+ let typeName;
287
296
  let typeDef = node;
288
- const elements = (node.items?.elements || node.elements)
297
+ const elements = (node.items?.elements || node.elements);
289
298
  // anonymous structured type
290
- if(elements)
291
- return { isExposable: true, typeDef, typeName, elements, isAnonymous: true };
299
+ if (elements) {
300
+ return {
301
+ isExposable: true, typeDef, typeName, elements, isAnonymous: true,
302
+ };
303
+ }
292
304
  // named type, resolve the type to inspect it
293
305
  let type = node.items?.type || node.type;
294
- if(type) {
306
+ if (type) {
295
307
  typeName = (type.ref && csnUtils.artifactRef(type)) || type;
296
- const rc = { isExposable: true, typeDef, typeName, isAnonymous: false };
297
- if((!isBuiltinType(typeName) || typeName === 'cds.Map') && typeName !== special$self) {
298
- rc.typeDef = typeDef = csnUtils.artifactRef(typeName, typeName);
299
- if(!isArtifactInService(typeName, serviceName)) {
300
- while(!isBuiltinType(typeName) || typeDef.$emtpyMapType) {
308
+ const rc = {
309
+ isExposable: true, typeDef, typeName, isAnonymous: false,
310
+ };
311
+ if ((!isBuiltinType(typeName) || typeName === 'cds.Map') && typeName !== special$self) {
312
+ typeDef = csnUtils.artifactRef(typeName, typeName);
313
+ rc.typeDef = typeDef;
314
+ if (!isArtifactInService(typeName, serviceName)) {
315
+ while (!isBuiltinType(typeName) || typeDef.$emtpyMapType) {
301
316
  typeDef = csnUtils.artifactRef(typeName, typeName);
302
- if(typeDef !== typeName) {
317
+ if (typeDef !== typeName) {
303
318
  // Implementation note: For `type S: T:struct;`, elements from `T:struct` were already propagated to `S`.
304
- if((isTermDef && typeDef.enum) || (rc.elements = (typeDef.items?.elements || typeDef.elements)) !== undefined)
319
+ if ((isTermDef && typeDef.enum) || (rc.elements = (typeDef.items?.elements || typeDef.elements)) !== undefined)
305
320
  return rc;
306
321
  type = typeDef.items?.type || typeDef.type;
307
322
  typeName = (type.ref && csnUtils.artifactRef(type)) || type;
308
323
  }
309
324
  else {
310
- throw new CompilerAssertion(`Debug me: ${typeName} not found`);
325
+ throw new CompilerAssertion(`Debug me: ${ typeName } not found`);
311
326
  }
312
327
  }
313
328
  }
@@ -320,7 +335,9 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
320
335
  // return rc;
321
336
  // }
322
337
  }
323
- return { isExposable: false, typeDef, typeName, isAnonymous: false };
338
+ return {
339
+ isExposable: false, typeDef, typeName, isAnonymous: false,
340
+ };
324
341
  }
325
342
 
326
343
 
@@ -336,24 +353,24 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
336
353
  if (typeService) {
337
354
  // new type name without any prefixes
338
355
  const typePlainName = defNameWithoutServiceOrContextName(typeName, typeService);
339
- const newSchemaName = `${serviceName}.${typeService}`;
356
+ const newSchemaName = `${ serviceName }.${ typeService }`;
340
357
  createSchema(newSchemaName);
341
358
  // return the new type name
342
- return `${newSchemaName}.${typePlainName.replace(/\./g, '_')}`;
343
- } else {
344
- const typeContext = csnUtils.getContextOfArtifact(typeName);
345
- const typeNamespace = getNamespace(csn, typeName);
346
- const newSchemaName = `${serviceName}.${typeContext || typeNamespace || fallBackSchemaName}`;
347
- // new type name without any prefixes
348
- const typePlainName = typeContext
349
- ? defNameWithoutServiceOrContextName(typeName, typeContext)
350
- : (typeNamespace
351
- ? typeName.replace(typeNamespace + '.', '')
352
- : typeName);
353
- createSchema(newSchemaName);
354
- // return the new type name
355
- return `${newSchemaName}.${typePlainName.replace(/\./g, '_')}`;
359
+ return `${ newSchemaName }.${ typePlainName.replace(/\./g, '_') }`;
356
360
  }
361
+ const typeContext = csnUtils.getContextOfArtifact(typeName);
362
+ const typeNamespace = getNamespace(csn, typeName);
363
+ const newSchemaName = `${ serviceName }.${ typeContext || typeNamespace || fallBackSchemaName }`;
364
+ // new type name without any prefixes
365
+ // eslint-disable-next-line no-nested-ternary
366
+ const typePlainName = typeContext
367
+ ? defNameWithoutServiceOrContextName(typeName, typeContext)
368
+ : (typeNamespace
369
+ ? typeName.replace(`${ typeNamespace }.`, '')
370
+ : typeName);
371
+ createSchema(newSchemaName);
372
+ // return the new type name
373
+ return `${ newSchemaName }.${ typePlainName.replace(/\./g, '_') }`;
357
374
  }
358
375
 
359
376
  /**
@@ -370,7 +387,7 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
370
387
  const typePlainName = defNameWithoutServiceOrContextName(typeName, newSchemaName);
371
388
 
372
389
  createSchema(newSchemaName);
373
- return `${newSchemaName}.${typePlainName.replace(/\./g, '_')}`;
390
+ return `${ newSchemaName }.${ typePlainName.replace(/\./g, '_') }`;
374
391
  }
375
392
 
376
393
  /**
@@ -394,18 +411,18 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
394
411
  setProp(type, '$exposedBy', 'typeExposure');
395
412
 
396
413
  // Duplicate elements
397
- Object.entries(elements).forEach(([elemName, element]) => {
414
+ Object.entries(elements).forEach(([ elemName, element ]) => {
398
415
  const cloned = cloneCsnNonDict(element, options);
399
416
  // if this was an anonymous sub element of a key, mark it as not nullable
400
- if(isAnonymous && isKey && !cloned.key) {
401
- if(cloned.target) {
402
- if(cloned.cardinality === undefined)
417
+ if (isAnonymous && isKey && !cloned.key) {
418
+ if (cloned.target) {
419
+ if (cloned.cardinality === undefined)
403
420
  cloned.cardinality = {};
404
421
  cloned.cardinality.min = 1;
405
422
  }
406
423
  // if odata-unexpected-nullable-key is checking on min>1, this can
407
424
  // be an else if
408
- if(cloned.notNull === undefined)
425
+ if (cloned.notNull === undefined)
409
426
  cloned.notNull = true;
410
427
  }
411
428
  type.elements[elemName] = cloned;
@@ -418,18 +435,19 @@ function typesExposure(csn, whatsMyServiceName, requestedServiceNames, fallBackS
418
435
  * Calculate the name of the exposed type based on the information, the element can provide
419
436
  * If the element is typed, use the type name
420
437
  * else assume it's a de-anonymized type, concatenate the element name to the defName
421
- */
438
+ */
422
439
  function getNewTypeName(element, elementName, typeNamePrefix, serviceName) {
423
440
  // for the new type name node.type has precedence over node.items.type
424
441
  const typeName = (!element?.elements && element?.type || !element?.items?.elements && element?.items?.type);
425
- return typeName
426
- ? `${isMultiSchema
427
- ? typeName.split('.').pop() // use leaf element
428
- : typeName.replace(/\./g, '_')}` // concatenate path
429
- : ( elementName // returns has no elementName, return the precalculated prefix
430
- ? `${defNameWithoutServiceOrContextName(typeNamePrefix, serviceName).replace(/\./g, '_')}_${elementName}`
431
- : typeNamePrefix
432
- );
442
+ if (typeName) {
443
+ return `${ isMultiSchema
444
+ ? typeName.split('.').pop() // use leaf element
445
+ : typeName.replace(/\./g, '_') }`; // concatenate path
446
+ }
447
+ return ( elementName // returns has no elementName, return the precalculated prefix
448
+ ? `${ defNameWithoutServiceOrContextName(typeNamePrefix, serviceName).replace(/\./g, '_') }_${ elementName }`
449
+ : typeNamePrefix
450
+ );
433
451
  }
434
452
  }
435
453
 
@@ -6,7 +6,7 @@
6
6
  * @param {string} srvOrCtx
7
7
  */
8
8
  function defNameWithoutServiceOrContextName(name, srvOrCtx) {
9
- return name.replace(`${srvOrCtx}.`, '');
9
+ return name.replace(`${ srvOrCtx }.`, '');
10
10
  }
11
11
 
12
12
  /**
@@ -20,7 +20,7 @@ function defNameWithoutServiceOrContextName(name, srvOrCtx) {
20
20
  * @param {string[]} services
21
21
  */
22
22
  function getServiceOfArtifact(artName, services) {
23
- return services.find(serviceName => artName.startsWith(`${serviceName}.`));
23
+ return services.find(serviceName => artName.startsWith(`${ serviceName }.`));
24
24
  }
25
25
 
26
26
  /**
@@ -29,7 +29,7 @@ function getServiceOfArtifact(artName, services) {
29
29
  * @param {string} service Name of the service
30
30
  */
31
31
  function isArtifactInService(artName, service) {
32
- return typeof artName === 'string' ? artName.startsWith(`${service}.`) : false;
32
+ return typeof artName === 'string' ? artName.startsWith(`${ service }.`) : false;
33
33
  }
34
34
 
35
35
  /**
@@ -40,7 +40,7 @@ function isArtifactInService(artName, service) {
40
40
  * @param {string[]} services
41
41
  */
42
42
  function isArtifactInSomeService(artName, services) {
43
- return services.some(serviceName => artName.startsWith(`${serviceName}.`));
43
+ return services.some(serviceName => artName.startsWith(`${ serviceName }.`));
44
44
  }
45
45
 
46
46
  /**
@@ -51,7 +51,8 @@ function isArtifactInSomeService(artName, services) {
51
51
  * @param {string[]} services
52
52
  */
53
53
  function isLocalizedArtifactInService(artName, services) {
54
- if (!artName.startsWith('localized.')) return false;
54
+ if (!artName.startsWith('localized.'))
55
+ return false;
55
56
  return isArtifactInSomeService(artName.split('.').slice(1).join('.'), services);
56
57
  }
57
58
 
@@ -61,4 +62,4 @@ module.exports = {
61
62
  isArtifactInService,
62
63
  isArtifactInSomeService,
63
64
  isLocalizedArtifactInService,
64
- }
65
+ };