@sap/cds-compiler 4.1.2 → 4.2.4

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 (74) hide show
  1. package/CHANGELOG.md +107 -1
  2. package/bin/cdsc.js +6 -3
  3. package/doc/CHANGELOG_BETA.md +5 -0
  4. package/doc/CHANGELOG_DEPRECATED.md +15 -0
  5. package/lib/api/main.js +2 -2
  6. package/lib/api/options.js +2 -2
  7. package/lib/api/validate.js +24 -24
  8. package/lib/base/message-registry.js +41 -6
  9. package/lib/base/messages.js +7 -0
  10. package/lib/base/model.js +38 -8
  11. package/lib/checks/elements.js +11 -10
  12. package/lib/checks/manyNavigations.js +33 -0
  13. package/lib/checks/onConditions.js +5 -2
  14. package/lib/checks/queryNoDbArtifacts.js +2 -3
  15. package/lib/checks/selectItems.js +4 -55
  16. package/lib/checks/utils.js +3 -2
  17. package/lib/checks/validator.js +3 -1
  18. package/lib/compiler/.eslintrc.json +2 -1
  19. package/lib/compiler/assert-consistency.js +27 -24
  20. package/lib/compiler/base.js +6 -2
  21. package/lib/compiler/builtins.js +34 -34
  22. package/lib/compiler/checks.js +179 -208
  23. package/lib/compiler/classes.js +2 -2
  24. package/lib/compiler/cycle-detector.js +6 -6
  25. package/lib/compiler/define.js +66 -45
  26. package/lib/compiler/extend.js +81 -72
  27. package/lib/compiler/finalize-parse-cdl.js +26 -26
  28. package/lib/compiler/generate.js +61 -45
  29. package/lib/compiler/index.js +47 -49
  30. package/lib/compiler/kick-start.js +8 -7
  31. package/lib/compiler/moduleLayers.js +1 -1
  32. package/lib/compiler/populate.js +42 -35
  33. package/lib/compiler/propagator.js +6 -6
  34. package/lib/compiler/resolve.js +170 -126
  35. package/lib/compiler/shared.js +122 -45
  36. package/lib/compiler/tweak-assocs.js +93 -40
  37. package/lib/compiler/utils.js +15 -12
  38. package/lib/edm/.eslintrc.json +40 -1
  39. package/lib/edm/annotations/genericTranslation.js +721 -707
  40. package/lib/edm/annotations/preprocessAnnotations.js +88 -77
  41. package/lib/edm/csn2edm.js +389 -378
  42. package/lib/edm/edm.js +678 -772
  43. package/lib/edm/edmAnnoPreprocessor.js +132 -146
  44. package/lib/edm/edmInboundChecks.js +29 -27
  45. package/lib/edm/edmPreprocessor.js +686 -646
  46. package/lib/edm/edmUtils.js +277 -296
  47. package/lib/gen/language.checksum +1 -1
  48. package/lib/gen/language.interp +1 -1
  49. package/lib/gen/languageParser.js +1253 -1276
  50. package/lib/json/from-csn.js +34 -4
  51. package/lib/json/to-csn.js +4 -4
  52. package/lib/language/language.g4 +2 -5
  53. package/lib/main.d.ts +61 -1
  54. package/lib/model/csnUtils.js +31 -2
  55. package/lib/model/revealInternalProperties.js +1 -1
  56. package/lib/modelCompare/compare.js +37 -2
  57. package/lib/modelCompare/utils/filter.js +1 -1
  58. package/lib/optionProcessor.js +15 -3
  59. package/lib/render/toCdl.js +30 -4
  60. package/lib/render/toSql.js +5 -9
  61. package/lib/render/utils/common.js +8 -6
  62. package/lib/transform/db/applyTransformations.js +1 -1
  63. package/lib/transform/db/cdsPersistence.js +1 -1
  64. package/lib/transform/db/constraints.js +47 -17
  65. package/lib/transform/db/expansion.js +133 -50
  66. package/lib/transform/db/flattening.js +75 -7
  67. package/lib/transform/forOdata.js +4 -1
  68. package/lib/transform/forRelationalDB.js +80 -62
  69. package/lib/transform/localized.js +91 -54
  70. package/lib/transform/transformUtils.js +9 -10
  71. package/lib/utils/file.js +7 -7
  72. package/lib/utils/moduleResolve.js +210 -121
  73. package/lib/utils/objectUtils.js +1 -1
  74. package/package.json +5 -5
@@ -1,7 +1,15 @@
1
1
  // Custom resolve functionality for the CDS compiler
2
2
  //
3
3
  // See `internalDoc/ModuleResolution.md` for details on the algorithm.
4
+ // See also <https://cap.cloud.sap/docs/cds/cdl#model-resolution>.
4
5
  // The algorithm is based on NodeJS's `require()`.
6
+ //
7
+ // For debugging purpose, if the option variable `options.traceFs` is set,
8
+ // we log file lookups. This makes it easier to debug why a file was not
9
+ // found when setting custom search directories.
10
+ //
11
+ // You can set this option via your `.cdsrc.json` or `package.json`:
12
+ // `{ "cds": { "cdsc": { "traceFs": true } } }`.
5
13
 
6
14
  'use strict';
7
15
 
@@ -14,18 +22,24 @@ const DEFAULT_ENCODING = 'utf-8';
14
22
  /**
15
23
  * Default lookup-extensions. If a module "./index" is requested, then
16
24
  * "./index.cds" is checked first, then "index.csn" and so on.
25
+ *
26
+ * Keep in sync with documentation!
17
27
  */
18
28
  const extensions = [ '.cds', '.csn', '.json' ];
29
+ /**
30
+ * Default module-lookup directories. Used when resolving modules.
31
+ * Since version v4.2, this option can be configured. Before that,
32
+ * only node_modules/ was a valid module-lookup directory.
33
+ *
34
+ * @type {string[]}
35
+ */
36
+ const defaultLookupDirectories = [ 'node_modules/' ];
19
37
 
20
38
  /**
21
- * A global cds.home configuration can be set that forces the cds-compiler to
22
- * use a certain directory for all @sap/cds/ includes.
39
+ * A global `cds.home` or local `options.cdsHome` configuration can be set that
40
+ * forces the cds-compiler to use a certain directory for all @sap/cds/ includes.
23
41
  * This function handles such module paths.
24
42
  *
25
- * @todo Re-think:
26
- * - Why can't a JAVA installation set a (symbolic) link?
27
- * - Preferred to a local installation? Not the node-way!
28
- *
29
43
  * @param {string} modulePath
30
44
  * @param {CSN.Options} options
31
45
  * @returns {string}
@@ -43,127 +57,193 @@ function adaptCdsModule( modulePath, options = {} ) {
43
57
  }
44
58
 
45
59
  /**
46
- * @param {object} dep
47
- * @param {object} fileCache
60
+ * Create the module resolver, namely `resolveModule(dep)`.
61
+ *
48
62
  * @param {CSN.Options} options
63
+ * @param {object} fileCache
49
64
  * @param {object} messageFunctions
50
65
  */
51
- function resolveModule( dep, fileCache, options, messageFunctions ) {
66
+ function makeModuleResolver( options, fileCache, messageFunctions ) {
52
67
  const _fs = cdsFs(fileCache, options.traceFs);
53
- // let opts = { extensions, basedir: dep.basedir, preserveSymlinks: false };
54
- // `preserveSymlinks` option does not really work -> provide workaround anyway...
55
- // Hm, the resolve package also does not follow the node recommendation:
56
- // "Using fs.stat() to check for the existence of a file before calling
57
- // fs.open(), fs.readFile() or fs.writeFile() is not recommended"
68
+ /** @type {ResolveConfig} */
58
69
  const opts = {
59
70
  extensions,
60
- basedir: dep.basedir,
61
71
  isFile: _fs.isFile,
62
72
  readFile: _fs.readFile,
63
73
  realpath: _fs.realpath,
74
+ lookupDirs: _getLookupDirectories( options, messageFunctions ),
64
75
  };
65
- return new Promise( (fulfill, reject) => {
66
- const lookupPath = adaptCdsModule(dep.module, options);
67
- resolveCDS( lookupPath, opts, (err, res) => {
68
- // console.log('RESOLVE', dep, res, err)
69
- if (err) {
70
- reject(err);
71
- }
72
- else {
73
- const body = fileCache[res];
74
- if (body === undefined || body === true) { // use fs if no or just temp entry
75
- dep.absname = res;
76
- _fs.realpath( res, cb );
76
+
77
+ return {
78
+ resolveModule,
79
+ };
80
+
81
+ function resolveModule( dep ) {
82
+ return new Promise( (fulfill, reject) => {
83
+ const lookupPath = adaptCdsModule( dep.module, options );
84
+ _resolveCDS( lookupPath, dep.basedir, opts, (err, res) => {
85
+ // console.log('RESOLVE', dep, res, err)
86
+ if (err) {
87
+ reject(err);
77
88
  }
78
- else if (body && typeof body === 'object' && body.realname) {
79
- // dep.absname = body.realname;
80
- cb( null, body.realname ); // use fs.realpath name
89
+ else {
90
+ const body = fileCache[res];
91
+ if (body === undefined || body === true) { // use fs if no or just temp entry
92
+ dep.absname = res;
93
+ _fs.realpath( res, cb );
94
+ }
95
+ else if (body && typeof body === 'object' && body.realname) {
96
+ // dep.absname = body.realname;
97
+ cb( null, body.realname ); // use fs.realpath name
98
+ }
99
+ else {
100
+ // dep.absname = res;
101
+ cb( null, res );
102
+ }
103
+ }
104
+ });
105
+
106
+ function cb( err, res ) {
107
+ if (err) {
108
+ reject(err);
81
109
  }
82
110
  else {
83
- // dep.absname = res;
84
- cb( null, res );
111
+ if (dep.absname)
112
+ fileCache[dep.absname] = (dep.absname === res) || { realname: res };
113
+ dep.resolved = res; // store in dep that module resolve was successful
114
+ for (const from of dep.usingFroms)
115
+ from.realname = res;
116
+ fulfill(res);
85
117
  }
86
118
  }
119
+ }).catch( () => {
120
+ _errorFileNotFound(dep, options, messageFunctions);
121
+ return false;
87
122
  });
88
-
89
- function cb( err, res ) {
90
- if (err) {
91
- reject(err);
92
- }
93
- else {
94
- if (dep.absname)
95
- fileCache[dep.absname] = (dep.absname === res) || { realname: res };
96
- dep.resolved = res; // store in dep that module resolve was successful
97
- for (const from of dep.usingFroms)
98
- from.realname = res;
99
- fulfill(res);
100
- }
101
- }
102
- }).catch( () => {
103
- _errorFileNotFound(dep, options, messageFunctions);
104
- return false;
105
- });
123
+ }
106
124
  }
107
125
 
108
126
 
109
127
  /**
110
- * @param {object} dep
111
- * @param {object} fileCache
128
+ * Create the synchronous module resolver, namely `resolveModuleSync(dep)`.
129
+ *
112
130
  * @param {CSN.Options} options
131
+ * @param {object} fileCache
113
132
  * @param {object} messageFunctions
114
133
  */
115
- function resolveModuleSync( dep, fileCache, options, messageFunctions ) {
134
+ function makeModuleResolverSync( options, fileCache, messageFunctions ) {
116
135
  const _fs = cdsFs(fileCache, options.traceFs);
136
+ /** @type {ResolveConfig} */
117
137
  const opts = {
118
138
  extensions,
119
- basedir: dep.basedir,
120
139
  isFile: _fs.isFileSync,
121
140
  readFile: _fs.readFileSync,
122
141
  realpath: _fs.realpathSync,
142
+ lookupDirs: _getLookupDirectories( options, messageFunctions ),
123
143
  };
124
144
 
125
- let result = null;
126
- let error = null;
127
- const lookupPath = adaptCdsModule(dep.module, options);
128
-
129
- resolveCDS( lookupPath, opts, (err, res) => {
130
- if (err)
131
- error = err;
132
- if (res)
133
- result = res;
134
- });
145
+ return {
146
+ resolveModuleSync,
147
+ };
135
148
 
136
- if (error) {
137
- _errorFileNotFound(dep, options, messageFunctions);
138
- return false;
139
- }
149
+ function resolveModuleSync( dep ) {
150
+ let result = null;
151
+ let error = null;
152
+ const lookupPath = adaptCdsModule(dep.module, options);
140
153
 
141
- const body = result ? fileCache[result] : undefined;
142
- if (body === undefined || body === true) { // use fs if no or just temp entry
143
- dep.absname = result;
144
- _fs.realpathSync( result, (err, modulePath) => {
154
+ _resolveCDS( lookupPath, dep.basedir, opts, (err, res) => {
145
155
  if (err)
146
156
  error = err;
147
- else
148
- result = modulePath;
157
+ if (res)
158
+ result = res;
149
159
  });
160
+
161
+ if (error) {
162
+ _errorFileNotFound(dep, options, messageFunctions);
163
+ return false;
164
+ }
165
+
166
+ const body = result ? fileCache[result] : undefined;
167
+ if (body === undefined || body === true) { // use fs if no or just temp entry
168
+ dep.absname = result;
169
+ _fs.realpathSync( result, (err, modulePath) => {
170
+ if (err)
171
+ error = err;
172
+ else
173
+ result = modulePath;
174
+ });
175
+ }
176
+ else if (body && typeof body === 'object' && body.realname) {
177
+ result = body.realname;
178
+ }
179
+
180
+ if (error) {
181
+ _errorFileNotFound(dep, options, messageFunctions);
182
+ return false;
183
+ }
184
+
185
+ if (dep.absname)
186
+ fileCache[dep.absname] = (dep.absname === result) || { realname: result };
187
+ dep.resolved = result; // store in dep that module resolve was successful
188
+ for (const from of dep.usingFroms)
189
+ from.realname = result;
190
+
191
+ return result;
150
192
  }
151
- else if (body && typeof body === 'object' && body.realname) {
152
- result = body.realname;
193
+ }
194
+
195
+ /**
196
+ * Get a list of module-lookup directories and ensure that user-provided lookup
197
+ * directories match our expectations / validate them.
198
+ *
199
+ * In case of errors (e.g. invalid options), returns the default list.
200
+ *
201
+ * @param {CSN.Options} options
202
+ * @param {object} messageFunctions
203
+ * @return {string[]}
204
+ */
205
+ function _getLookupDirectories( options, messageFunctions ) {
206
+ const dirs = options?.moduleLookupDirectories || defaultLookupDirectories;
207
+
208
+ if (!Array.isArray(dirs)) {
209
+ messageFunctions.error('api-invalid-option', null, {
210
+ '#': 'type',
211
+ option: 'moduleLookupDirectories',
212
+ value: 'string[]',
213
+ othervalue: typeof options.moduleLookupDirectories,
214
+ });
215
+ return defaultLookupDirectories;
153
216
  }
154
217
 
155
- if (error) {
156
- _errorFileNotFound(dep, options, messageFunctions);
157
- return false;
218
+ if (!dirs.includes('node_modules/')) {
219
+ // Special case of call-side-errors and to ensure old behavior.
220
+ dirs.push('node_modules/');
158
221
  }
159
222
 
160
- if (dep.absname)
161
- fileCache[dep.absname] = (dep.absname === result) || { realname: result };
162
- dep.resolved = result; // store in dep that module resolve was successful
163
- for (const from of dep.usingFroms)
164
- from.realname = result;
223
+ for (const dir of dirs) {
224
+ if (!dir.endsWith('/')) {
225
+ messageFunctions.error('api-invalid-lookup-dir', null, {
226
+ '#': 'slash',
227
+ option: 'moduleLookupDirectories',
228
+ value: dir,
229
+ othervalue: '/',
230
+ } );
231
+ return defaultLookupDirectories;
232
+ }
233
+ if (dir.startsWith('./') || dir.startsWith('../')) {
234
+ // Avoid relative directories, as we don't want to give the impression that they
235
+ // are resolved relative to the caller.
236
+ messageFunctions.error('api-invalid-lookup-dir', null, {
237
+ '#': 'relative',
238
+ option: 'moduleLookupDirectories',
239
+ value: dir,
240
+ othervalue: './',
241
+ });
242
+ return defaultLookupDirectories;
243
+ }
244
+ }
165
245
 
166
- return result;
246
+ return dirs;
167
247
  }
168
248
 
169
249
  function _errorFileNotFound( dep, options, { error } ) {
@@ -201,16 +281,18 @@ function _errorFileNotFound( dep, options, { error } ) {
201
281
  * with existing code. This may change at a later point.
202
282
  *
203
283
  * @param {string} moduleName Module to load, e.g. `./Include.cds` or `@sap/cds/common`.
204
- * @param {ResolveOptions} options
284
+ * @param {ResolveConfig} config
285
+ * @param {string} baseDir
205
286
  * @param {(err, result) => void} callback
206
287
  */
207
- function resolveCDS( moduleName, options, callback ) {
288
+ function _resolveCDS( moduleName, baseDir, config, callback ) {
208
289
  const isWindows = (process.platform === 'win32');
209
- let resolvedBaseDir = path.resolve(options.basedir);
290
+ let resolvedBaseDir = path.resolve(baseDir);
291
+ const lookupDirs = [ ...config.lookupDirs ];
210
292
 
211
293
  // NodeJS does not preserve symbolic links when resolving modules.
212
294
  // So neither do we.
213
- options.realpath(resolvedBaseDir, (realPathErr, realPath) => {
295
+ config.realpath(resolvedBaseDir, (realPathErr, realPath) => {
214
296
  // There may be an error in resolving the symlink.
215
297
  // We ignore the error and simply use the original path.
216
298
  // Otherwise, cds-lsp tests would fail because they don't have real
@@ -224,7 +306,7 @@ function resolveCDS( moduleName, options, callback ) {
224
306
  if (isLocalFile(moduleName))
225
307
  loadFromLocalFileOrDirectory();
226
308
  else
227
- loadNodeModules(resolvedBaseDir);
309
+ loadAsModule(resolvedBaseDir);
228
310
  }
229
311
 
230
312
  /**
@@ -269,7 +351,7 @@ function resolveCDS( moduleName, options, callback ) {
269
351
  * @param {(err, filepath: string|null) => void} cb
270
352
  */
271
353
  function loadAsFile( absoluteModulePath, cb ) {
272
- const extensionsToTry = [ '' ].concat(options.extensions);
354
+ const extensionsToTry = [ '' ].concat(config.extensions);
273
355
  loadFileWithExtensions(extensionsToTry);
274
356
 
275
357
  /**
@@ -284,7 +366,7 @@ function resolveCDS( moduleName, options, callback ) {
284
366
  return;
285
367
  }
286
368
  const file = absoluteModulePath + exts.shift();
287
- options.isFile(file, (err, foundAndIsFile) => {
369
+ config.isFile(file, (err, foundAndIsFile) => {
288
370
  if (!err && foundAndIsFile)
289
371
  cb(null, file);
290
372
  else
@@ -332,28 +414,29 @@ function resolveCDS( moduleName, options, callback ) {
332
414
  }
333
415
 
334
416
  /**
335
- * Try to load the module from a node_modules directory.
336
- * Start at absoluteDir and go through all parent directories.
417
+ * Try to load the module from a specified module-lookup directory such
418
+ * as `node_modules/`.
419
+ * Start at `absoluteDir` and go through all parent directories.
337
420
  *
338
421
  * @param {string} absoluteDir
339
422
  */
340
- function loadNodeModules( absoluteDir ) {
341
- const dirs = nodeModulesPaths(absoluteDir);
342
- loadFromNodeDirs(dirs);
423
+ function loadAsModule( absoluteDir ) {
424
+ const dirGen = modulePaths(absoluteDir);
425
+ loadNextDir();
343
426
 
344
- function loadFromNodeDirs( nodeDirs ) {
345
- const dir = nodeDirs.shift();
346
- if (!dir) {
427
+ function loadNextDir() {
428
+ const dir = dirGen.next();
429
+ if (dir.done) {
347
430
  // We're at root
348
431
  callback(makeNotFoundError(), null);
349
432
  return;
350
433
  }
351
- const file = path.join(dir, moduleName);
434
+ const file = path.join(dir.value, moduleName);
352
435
  loadAsLocalFileOrDirectory(file, (err, filepath) => {
353
436
  if (!err && filepath)
354
437
  callback(null, filepath);
355
438
  else
356
- loadFromNodeDirs(nodeDirs);
439
+ loadNextDir();
357
440
  });
358
441
  }
359
442
  }
@@ -368,7 +451,7 @@ function resolveCDS( moduleName, options, callback ) {
368
451
  function loadAndParsePackageJsonInDirectory( packageDir, cb ) {
369
452
  const file = path.join(packageDir, 'package.json');
370
453
 
371
- options.readFile(file, DEFAULT_ENCODING, (err, content) => {
454
+ config.readFile(file, DEFAULT_ENCODING, (err, content) => {
372
455
  if (err) {
373
456
  cb(err, null);
374
457
  return;
@@ -385,16 +468,14 @@ function resolveCDS( moduleName, options, callback ) {
385
468
 
386
469
  /**
387
470
  * Get a list of all `node_modules` directories that MAY exist.
388
- * Starting from absoluteStart upwards until at root.
471
+ * Starting from `absoluteStart` upwards until at root.
389
472
  *
390
- * @param {string} absoluteStart
391
- * @returns {string[]} Array of possible "node_modules" folders for the given path.
473
+ * @param {string} absoluteStart *
474
+ * @return {Generator<string>} Possible module directories for the given path.
392
475
  */
393
- function nodeModulesPaths( absoluteStart ) {
476
+ function* modulePaths( absoluteStart ) {
394
477
  // Use platform-dependent separator. All NodeJS `path` methods use the system's path separator.
395
478
  const parts = absoluteStart.split(path.sep);
396
- // Do NOT use global node_modules directories.
397
- const dirs = [];
398
479
 
399
480
  // If we're on *nix systems, the first part is just an empty string ''
400
481
  // because the path is absolute. Re-add it here because `path.join()`
@@ -403,12 +484,18 @@ function resolveCDS( moduleName, options, callback ) {
403
484
  parts[0] = '/';
404
485
 
405
486
  for (let i = parts.length - 1; i >= 0; i--) {
406
- if (parts[i] === 'node_modules')
407
- continue;
408
- const dir = path.join(...parts.slice(0, i + 1), 'node_modules');
409
- dirs.push(dir);
487
+ for (let j = 0; j < lookupDirs.length; ++j) {
488
+ const dir = lookupDirs[j];
489
+ if (dir && path.isAbsolute(dir)) {
490
+ // Only look up absolute paths once.
491
+ lookupDirs[j] = null;
492
+ yield dir;
493
+ }
494
+ else if (dir && parts[i] && !lookupDirs.includes(`${ parts[i] }/`)) {
495
+ yield path.join(...parts.slice(0, i + 1), dir);
496
+ }
497
+ }
410
498
  }
411
- return dirs;
412
499
  }
413
500
 
414
501
  /**
@@ -417,7 +504,7 @@ function resolveCDS( moduleName, options, callback ) {
417
504
  * @returns {Error}
418
505
  */
419
506
  function makeNotFoundError() {
420
- const moduleError = new Error(`Can't find module '${ moduleName }' from '${ options.basedir }'`);
507
+ const moduleError = new Error(`Can't find module '${ moduleName }' from '${ config.basedir }'`);
421
508
  // eslint-disable-next-line
422
509
  moduleError['code'] = 'MODULE_NOT_FOUND';
423
510
  return moduleError;
@@ -437,7 +524,7 @@ function isLocalFile( moduleName ) {
437
524
  }
438
525
 
439
526
  /**
440
- * Get the cds.main entry of the package.json
527
+ * Get the `cds.main` entry of the package.json
441
528
  * @param {object} pkg
442
529
  */
443
530
  function packageCdsMain( pkg ) {
@@ -447,8 +534,9 @@ function packageCdsMain( pkg ) {
447
534
  }
448
535
 
449
536
  /**
450
- * @typedef {object} ResolveOptions
451
- * @property {string} basedir
537
+ * @typedef {object} ResolveConfig
538
+ * @property {string[]} lookupDirs
539
+ * Directories to look in for modules, e.g. node_modules/.
452
540
  * @property {string[]} extensions
453
541
  * @property {(path: string, callback: (err, foundAndIsFile) => void) => void} isFile
454
542
  * @property {(path: string, encoding, callback: (err, content) => void) => void} readFile
@@ -457,10 +545,11 @@ function packageCdsMain( pkg ) {
457
545
  */
458
546
 
459
547
  module.exports = {
460
- resolveModule,
461
- resolveModuleSync,
548
+ makeModuleResolver,
549
+ makeModuleResolverSync,
462
550
  // exported for unit tests
463
- resolveCDS,
551
+ _resolveCDS,
552
+ _getLookupDirectories,
464
553
  isLocalFile,
465
554
  extensions,
466
555
  };
@@ -15,7 +15,7 @@ function copyPropIfExist( sourceObj, property, targetObj ) {
15
15
 
16
16
  /**
17
17
  * Takes an object and creates a dictionary out of it.
18
- * This avoid cases where e.g. properties named "toString" are interpreted
18
+ * This avoids cases where e.g. properties named "toString" are interpreted
19
19
  * as JS internal functions.
20
20
  *
21
21
  * @param {object} obj Object with prototype.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-compiler",
3
- "version": "4.1.2",
3
+ "version": "4.2.4",
4
4
  "description": "CDS (Core Data Services) compiler and backends",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "author": "SAP SE (https://www.sap.com)",
@@ -22,15 +22,15 @@
22
22
  "testci": "node scripts/verifyGrammarChecksum.js && mocha --reporter-option maxDiffSize=0 scripts/testLazyLoading.js && mocha --parallel --reporter-option maxDiffSize=0 test/ test3/",
23
23
  "testverbose": "node scripts/verifyGrammarChecksum.js && mocha --parallel test/ test3/",
24
24
  "test3": "node scripts/verifyGrammarChecksum.js && mocha --reporter-option maxDiffSize=0 test3/",
25
- "deployTest3SQL": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/test.deploy.hana-sql.js",
26
- "deployTest3": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/testDeployment.js",
27
- "deployHanaDeltaSQL": "CDS_COMPILER_DEPLOY_HANA=1 mocha test3/test.deploy.hana-sql.delta.js",
28
- "deployDiffs": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/deployDiffs.js",
25
+ "deployHanaSql": "CDS_COMPILER_DEPLOY_HANA=1 mocha --reporter-option maxDiffSize=0 test3/test.deploy.hana-sql.js",
26
+ "deployHdiHdbcds": "CDS_COMPILER_DEPLOY_HANA=1 mocha --reporter-option maxDiffSize=0 test3/test.deploy.hdi.hdbcds.js",
27
+ "deployGitDiffs": "CDS_COMPILER_DEPLOY_HANA=1 mocha --reporter-option maxDiffSize=0 test3/test.deploy.git-diffs.js",
29
28
  "gentest3": "cross-env MAKEREFS=${MAKEREFS:-'true'} mocha --reporter-option maxDiffSize=0 test3/testRefFiles.js",
30
29
  "coverage": "cross-env nyc mocha --reporter-option maxDiffSize=0 test/ test3/ && nyc report --reporter=lcov",
31
30
  "lint": "eslint bin/ benchmark/ lib/ test/ test3/ scripts/ types/ && node scripts/linter/lintGrammar.js && node scripts/linter/lintTests.js test3/ && node scripts/linter/lintMessages.js && node scripts/linter/lintMessageIdCoverage.js lib/ && markdownlint README.md CHANGELOG.md doc/ internalDoc/ && cd share/messages && markdownlint .",
32
31
  "tslint": "tsc --pretty -p .",
33
32
  "updateVocs": "node scripts/odataAnnotations/generateDictMain.js && npm run generateAllRefs",
33
+ "updateTocs": "node scripts/update-toc.js",
34
34
  "generateCompilerRefs": "cross-env MAKEREFS='true' mocha test/testCompiler.js",
35
35
  "generateEdmRefs": "cross-env MAKEREFS='true' mocha test/testEdmPositive.js",
36
36
  "generateForHanaRefs": "cross-env MAKEREFS='true' mocha test/testHanaTransformation.js",