@sap/cds-dk 7.2.0 → 7.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 (56) hide show
  1. package/bin/activate.js +2 -2
  2. package/bin/build.js +6 -3
  3. package/bin/compile/index.js +9 -5
  4. package/bin/env.js +0 -3
  5. package/bin/extend.js +25 -3
  6. package/bin/import.js +7 -3
  7. package/bin/push.js +10 -6
  8. package/bin/watch.js +1 -1
  9. package/lib/build/{buildTaskHandler.js → buildPlugin.js} +23 -25
  10. package/lib/build/buildTaskEngine.js +73 -73
  11. package/lib/build/buildTaskFactory.js +6 -23
  12. package/lib/build/buildTaskProvider.js +24 -19
  13. package/lib/build/buildTaskProviderFactory.js +170 -57
  14. package/lib/build/constants.js +4 -4
  15. package/lib/build/index.js +3 -2
  16. package/lib/build/provider/{buildTaskHandlerEdmx.js → edmxBuildPlugin.js} +6 -6
  17. package/lib/build/provider/{buildTaskHandlerFeatureToggles.js → featureToggleBuildPlugin.js} +3 -3
  18. package/lib/build/provider/fiori/index.js +5 -6
  19. package/lib/build/provider/hana/index.js +54 -30
  20. package/lib/build/provider/{buildTaskHandlerInternal.js → internalBuildPlugin.js} +10 -10
  21. package/lib/build/provider/{buildTaskProviderInternal.js → internalBuildTaskProvider.js} +27 -28
  22. package/lib/build/provider/java/index.js +24 -24
  23. package/lib/build/provider/mtx/index.js +4 -4
  24. package/lib/build/provider/mtx/resourcesTarBuilder.js +8 -8
  25. package/lib/build/provider/mtx-extension/index.js +17 -9
  26. package/lib/build/provider/mtx-sidecar/index.js +17 -11
  27. package/lib/build/provider/nodejs/index.js +14 -13
  28. package/lib/client/auth_manager.js +6 -12
  29. package/lib/client/base_command.js +1 -1
  30. package/lib/client/download_legacy.js +48 -0
  31. package/lib/client/params.js +5 -0
  32. package/lib/client/push.js +41 -1
  33. package/lib/client/settings_manager.js +12 -3
  34. package/lib/env/schema.js +36 -0
  35. package/lib/env/schemas/cds-rc.json +101 -0
  36. package/lib/import/common.js +23 -10
  37. package/lib/import/importapi.js +2 -2
  38. package/lib/import/message.js +3 -1
  39. package/lib/import/odata/v4parser.js +23 -7
  40. package/lib/index.js +5 -0
  41. package/lib/init/constants.js +4 -2
  42. package/lib/init/index.js +2 -3
  43. package/lib/init/template/_merging/registry-mta.js +21 -0
  44. package/lib/init/template/approuter/files/mta.yaml.hbs +1 -1
  45. package/lib/init/template/approuter/index.js +9 -9
  46. package/lib/init/template/connectivity/index.js +5 -4
  47. package/lib/init/template/destination/index.js +2 -5
  48. package/lib/init/template/html5-repo/index.js +27 -3
  49. package/lib/init/template/mta/index.js +9 -3
  50. package/lib/init/template/postgres/files/mta.yaml.hbs +27 -0
  51. package/lib/init/template/postgres/files/package.json.hbs +5 -0
  52. package/lib/init/template/postgres/index.js +52 -0
  53. package/lib/init/util/projectReader.js +0 -1
  54. package/lib/util/pruneAxiosErrors.js +22 -8
  55. package/npm-shrinkwrap.json +1829 -23
  56. package/package.json +1 -1
@@ -2,12 +2,12 @@ const fs = require('fs')
2
2
  const path = require('path')
3
3
  const cds = require('../../../cds')
4
4
  const to_hdbmigration = require('./2migration')
5
- const BuildTaskHandlerInternal = require('../buildTaskHandlerInternal')
5
+ const InternalBuildPlugin = require('../internalBuildPlugin')
6
6
  const { BuildError, relativePaths, BuildMessage } = require('../../util')
7
7
 
8
8
  const { OUTPUT_MODE_NONE, OUTPUT_MODE, CONTENT_PACKAGE_JSON, CONTENT_HDBTABLEDATA, CSV_FILE_DETECTION,
9
9
  CONTENT_ENV, CONTENT_DEFAULT_ENV_JSON, CONTENT_NODE_MODULES, OUTPUT_MODE_RESULT, CONTINUE_UNRESOLVED_SCHEMA_CHANGES } = require('../../constants')
10
- const { WARNING } = BuildTaskHandlerInternal
10
+ const { WARNING } = InternalBuildPlugin
11
11
 
12
12
  const DEFAULT_COMPILE_DEST_FOLDER = path.normalize("src/gen")
13
13
 
@@ -22,7 +22,7 @@ const PATH_LAST_DEV_CSN = "last-dev/csn.json"
22
22
  const FILE_NAME_UNDEPLOY_JSON = "undeploy.json"
23
23
  const DEPLOY_FORMAT = "deploy-format"
24
24
 
25
- class HanaModuleBuilder extends BuildTaskHandlerInternal {
25
+ class HanaBuildPlugin extends InternalBuildPlugin {
26
26
  init() {
27
27
  if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
28
28
  this._result = {
@@ -153,7 +153,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
153
153
 
154
154
  // handle *.csv and *.hdbtabledata located in '<dbSrc>/data' and '<dbSrc>/csv' folder
155
155
  const allFiles = csvDirs.reduce((acc, csvDir) => {
156
- return acc.concat(BuildTaskHandlerInternal._find(csvDir, (entry) => {
156
+ return acc.concat(InternalBuildPlugin._find(csvDir, (entry) => {
157
157
  if (fs.statSync(entry).isDirectory()) {
158
158
  return false
159
159
  }
@@ -181,7 +181,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
181
181
  const tableDataDirs = new Set()
182
182
  const destSrcDir = path.join(this.task.dest, "src")
183
183
 
184
- const allCsvFiles = BuildTaskHandlerInternal._find(destSrcDir, (entry) => {
184
+ const allCsvFiles = InternalBuildPlugin._find(destSrcDir, (entry) => {
185
185
  if (fs.statSync(entry).isDirectory()) {
186
186
  return true
187
187
  }
@@ -248,7 +248,8 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
248
248
  return Promise.reject(new Error(`Invalid deploy-format defined: ${format}`))
249
249
  }
250
250
 
251
- if (this.hasCdsEnvOption('features.journal', false) || format === 'hdbcds') {
251
+ let no_migration = cds.env.features.journal === false || format === 'hdbcds' || Object.values(model.definitions).every(def => !def['@cds.persistence.journal'])
252
+ if (no_migration) {
252
253
  return await this._compileToHdb(model, format)
253
254
  } else {
254
255
  return await this._compileToHdbmigration(model, format)
@@ -264,12 +265,24 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
264
265
  const promises = []
265
266
 
266
267
  for (const [content, key] of result) {
267
- hdiPlugins.add(key.suffix || path.extname(key.file))
268
+ const suffix = key.suffix || path.extname(key.file)
268
269
  const file = key.file ? key.file : key.name + key.suffix
270
+
271
+ hdiPlugins.add(suffix)
269
272
  if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
270
273
  this._result.hana.push(path.join(relDest, file))
271
274
  }
272
275
  promises.push(this.write(content).to(path.join(this.task.options.compileDest, file)))
276
+ if (suffix === FILE_EXT_HDBTABLE) {
277
+ const name = key.name || path.parse(key.file).name
278
+ const dbSrcDir = path.join(this.task.src, "src")
279
+ // issue an error in case a .hdbmigrationtable file already exists
280
+ if (fs.existsSync(path.join(dbSrcDir, name + FILE_EXT_HDBMIGRATIONTABLE))) {
281
+ const relDbSrcDir = path.relative(cds.root, dbSrcDir)
282
+ const relDbDestDir = path.relative(cds.root, this.task.options.compileDest)
283
+ throw new BuildError(`Multiple files exist defining the same HANA artifact - [${path.join(relDbSrcDir, name + FILE_EXT_HDBMIGRATIONTABLE)}, ${path.join(relDbDestDir, file)}].\nEither annotate the model entity using @cds.persistence.journal or undeploy the file [${path.join('src', name + FILE_EXT_HDBMIGRATIONTABLE)}] using an undeploy.json file.`)
284
+ }
285
+ }
273
286
  }
274
287
  await Promise.all(promises)
275
288
  return hdiPlugins
@@ -296,6 +309,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
296
309
  const compilationResult = await to_hdbmigration(model, lastDev, dbSrcDir, options)
297
310
  const definitions = compilationResult.definitions
298
311
  const afterImage = compilationResult.afterImage
312
+ let validationError
299
313
 
300
314
  for (const { name, suffix, content, changed } of definitions) {
301
315
  hdiPlugins.add(suffix)
@@ -318,28 +332,38 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
318
332
  if (suffix === FILE_EXT_HDBTABLE) {
319
333
  // issue an error in case a .hdbmigrationtable file already exists
320
334
  if (fs.existsSync(path.join(dbSrcDir, name + FILE_EXT_HDBMIGRATIONTABLE))) {
321
- throw new BuildError(`Multiple files exist defining the same HANA artifact - [${path.join(relDbSrcDir, name + FILE_EXT_HDBMIGRATIONTABLE)}, ${path.join(relDbDestDir, file)}].\nEither annotate the model entity using @cds.persistence.journal or undeploy the file [${path.join('src', name + FILE_EXT_HDBMIGRATIONTABLE)}] using an undeploy.json file.`)
335
+ validationError = new BuildError(`Multiple files exist defining the same HANA artifact - [${path.join(relDbSrcDir, name + FILE_EXT_HDBMIGRATIONTABLE)}, ${path.join(relDbDestDir, file)}].\nEither annotate the model entity using @cds.persistence.journal or undeploy the file [${path.join('src', name + FILE_EXT_HDBMIGRATIONTABLE)}] using an undeploy.json file.`)
322
336
  }
323
337
  }
324
338
  }
325
339
  }
340
+ // the last-dev CSN shall only be updated, if all .hdbmigrationtable files could be successfully updated
341
+ // of course, .hdbmigrationtable files already written would need to be manually reverted before the
342
+ // cds build command is again executed
326
343
  await Promise.all(promises)
327
- await this._validateMigrationTableFiles()
328
-
329
- // update last development version
330
- if (afterImage) {
331
- if (migrationTableFiles.length > 0) {
332
- if (!HanaModuleBuilder._toEqualIgnoreMeta(lastDev, afterImage)) {
333
- await this.write(afterImage).to(lastDevCsnDir)
334
- }
335
344
 
336
- // add src/.hdiconfig if not existing
337
- if (!fs.existsSync(path.join(dbSrcDir, FILE_NAME_HDICONFIG))) {
338
- const template = await HanaModuleBuilder._readTemplateAsJson('.hdiconfig-cloud')
339
- await this.write(template).to(path.join(dbSrcDir, FILE_NAME_HDICONFIG))
345
+ // ensure
346
+ try {
347
+ if (validationError) {
348
+ throw validationError
349
+ }
350
+ await this._validateMigrationTableFiles()
351
+ } finally {
352
+ // update last-dev CSN version
353
+ if (afterImage) {
354
+ if (migrationTableFiles.length > 0) {
355
+ if (!HanaBuildPlugin._toEqualIgnoreMeta(lastDev, afterImage)) {
356
+ await this.write(afterImage).to(lastDevCsnDir)
357
+ }
358
+ // add src/.hdiconfig if not existing
359
+ if (!fs.existsSync(path.join(dbSrcDir, FILE_NAME_HDICONFIG))) {
360
+ const template = await HanaBuildPlugin._readTemplateAsJson('.hdiconfig-cloud')
361
+ await this.write(template).to(path.join(dbSrcDir, FILE_NAME_HDICONFIG))
362
+ }
340
363
  }
341
364
  }
342
- } else {
365
+ }
366
+ if (!afterImage) {
343
367
  throw new BuildError(`Inconsistent CDS compilation results - file ${lastDevCsnFolder} missing`)
344
368
  }
345
369
  return hdiPlugins
@@ -353,7 +377,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
353
377
  this.logger._debug && this.logger.debug(`skip create [${relativePaths(cds.root, packageJson)}], already existing`)
354
378
  }
355
379
  if (this.isStagingBuild() && !exists) {
356
- const content = await HanaModuleBuilder._readTemplateAsJson(FILE_NAME_PACKAGE_JSON)
380
+ const content = await HanaBuildPlugin._readTemplateAsJson(FILE_NAME_PACKAGE_JSON)
357
381
  await this.write(content).to(path.join(this.task.dest, FILE_NAME_PACKAGE_JSON))
358
382
  }
359
383
  }
@@ -372,11 +396,11 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
372
396
  // && !fs.existsSync(path.join(this.task.dest, FILE_NAME_HDICONFIG))
373
397
  // && !fs.existsSync(path.join(this.task.dest, 'cfg', FILE_NAME_HDICONFIG))) {
374
398
  // // in 'gen/db' if none exists
375
- // // ensures correct deployment of all artifacts including HANA native artifacts
399
+ // // ensures correct deployment of all artifacts including HANA native artifacts
376
400
  // // without the need of creating a static .hdiconfig file in the 'db' folder
377
401
 
378
402
  // // add all known plugins
379
- // const defaultHdiConfig = await HanaModuleBuilder._readTemplateAsJson('.hdiconfig-cloud')
403
+ // const defaultHdiConfig = await HanaBuildPlugin._readTemplateAsJson('.hdiconfig-cloud')
380
404
  // for (const plugin in defaultHdiConfig['file_suffixes']) {
381
405
  // hdiPlugins.add('.' + plugin)
382
406
  // }
@@ -388,7 +412,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
388
412
  hdiConfigPath = path.join(this.task.options.compileDest, FILE_NAME_HDICONFIG)
389
413
  // }
390
414
 
391
- const template = await HanaModuleBuilder._readTemplateAsJson('.hdiconfig-all')
415
+ const template = await HanaBuildPlugin._readTemplateAsJson('.hdiconfig-all')
392
416
  let content = {
393
417
  'file_suffixes': {}
394
418
  }
@@ -410,7 +434,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
410
434
  async _writeHdiNamespace() {
411
435
  // see issue #64 - add .hdinamespace file to prevent HDI from adding gen/ folder to the namespace.
412
436
  const hdiNamespace = path.join(this.task.options.compileDest, FILE_NAME_HDINAMESPACE)
413
- const content = await HanaModuleBuilder._readTemplateAsJson(FILE_NAME_HDINAMESPACE)
437
+ const content = await HanaBuildPlugin._readTemplateAsJson(FILE_NAME_HDINAMESPACE)
414
438
  return await this.write(content).to(hdiNamespace)
415
439
  }
416
440
 
@@ -422,7 +446,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
422
446
  // see issue #64 - add .hdinamespace file to prevent HDI from adding gen/ folder to the namespace.
423
447
  const undeployJsonDest = path.join(this.task.dest, FILE_NAME_UNDEPLOY_JSON)
424
448
  const undeployJsonSrc = path.join(this.task.src, FILE_NAME_UNDEPLOY_JSON)
425
- const templateEntries = await HanaModuleBuilder._readTemplateAsJson(FILE_NAME_UNDEPLOY_JSON)
449
+ const templateEntries = await HanaBuildPlugin._readTemplateAsJson(FILE_NAME_UNDEPLOY_JSON)
426
450
  let newEntries = []
427
451
  if (fs.existsSync(undeployJsonSrc)) {
428
452
  newEntries = await JSON.parse((await fs.promises.readFile(undeployJsonSrc, 'utf-8')).toString())
@@ -452,7 +476,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
452
476
  if (fs.existsSync(file)) {
453
477
  const undeployList = JSON.parse((await fs.promises.readFile(file)).toString(), 'utf-8')
454
478
  if (Array.isArray(undeployList)) {
455
- const hdiconfig = await HanaModuleBuilder._readTemplateAsJson('.hdiconfig-all')
479
+ const hdiconfig = await HanaBuildPlugin._readTemplateAsJson('.hdiconfig-all')
456
480
  const keys = new Set(Object.keys(hdiconfig['file_suffixes']).map(key => '.' + key))
457
481
  undeployList.forEach(entry => {
458
482
  const extName = path.extname(entry)
@@ -471,7 +495,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
471
495
 
472
496
  async _validateMigrationTableFiles() {
473
497
  const dbSrcDir = path.join(this.task.src, "src")
474
- const migrationTableFiles = BuildTaskHandlerInternal._find(dbSrcDir, (res) => {
498
+ const migrationTableFiles = InternalBuildPlugin._find(dbSrcDir, (res) => {
475
499
  return fs.statSync(res).isFile() && path.extname(res) === FILE_EXT_HDBMIGRATIONTABLE
476
500
  })
477
501
  if (migrationTableFiles.length > 0) {
@@ -526,4 +550,4 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
526
550
  return toString(csn1) === toString(csn2)
527
551
  }
528
552
  }
529
- module.exports = HanaModuleBuilder
553
+ module.exports = HanaBuildPlugin
@@ -1,11 +1,11 @@
1
1
  const fs = require('fs')
2
2
  const path = require('path')
3
3
  const cds = require('../../cds')
4
- const BuildTaskHandler = require('../buildTaskHandler')
4
+ const BuildPlugin = require('../buildPlugin')
5
5
  const { hasOptionValue } = require('../util')
6
6
  const { FOLDER_GEN } = require('../constants')
7
7
 
8
- class BuildTaskHandlerInternal extends BuildTaskHandler {
8
+ class InternalBuildPlugin extends BuildPlugin {
9
9
  /**
10
10
  * Returns the logger that has been passed the build task engine.
11
11
  * @returns {object}
@@ -15,11 +15,11 @@ class BuildTaskHandlerInternal extends BuildTaskHandler {
15
15
  return this._logger;
16
16
  }
17
17
  /**
18
- * Custom build handlers are executed before internal handlers in order
18
+ * Custom build plugins are executed before internal build plugins in order
19
19
  * ensure and content cannot be overwritten by mistake.
20
20
  */
21
21
  get priority() {
22
- return BuildTaskHandlerInternal.PRIORITY_MAX_VALUE
22
+ return InternalBuildPlugin.PRIORITY_MAX_VALUE
23
23
  }
24
24
 
25
25
  async clean() {
@@ -45,14 +45,14 @@ class BuildTaskHandlerInternal extends BuildTaskHandler {
45
45
  /**
46
46
  * Called by the framework after {@link #init()}, used to perform more elaborate preparation.
47
47
  * E.g. caching some pre-calculated data that can be used across multiple build tasks. This kind of data
48
- * has to be stored in the handler type specific options section.
48
+ * has to be stored in the plugin type specific options section.
49
49
  * @returns {Promise<boolean>} A value 'false' indicates that {@link #prepare()} will not be called for other instances
50
- * of this handler type.
51
- * True indicates that {@link #prepare()} will be called for other instances of this of this handler type.
50
+ * of this plugin type.
51
+ * True indicates that {@link #prepare()} will be called for other instances of this of this plugin type.
52
52
  * @deprecated
53
53
  */
54
54
  async prepare() {
55
- // cancel subsequent prepare calls for other handlers of the same type by default
55
+ // cancel subsequent prepare calls for other plugins of the same type by default
56
56
  return false
57
57
  }
58
58
 
@@ -101,7 +101,7 @@ class BuildTaskHandlerInternal extends BuildTaskHandler {
101
101
  }
102
102
 
103
103
  async copyNativeContent(srcDir, destDir, customFilter) {
104
- const files = BuildTaskHandlerInternal._find(srcDir, (src) => {
104
+ const files = InternalBuildPlugin._find(srcDir, (src) => {
105
105
  // do not copy files that:
106
106
  // - from 'cds.env.build.target'
107
107
  // - from 'dest'
@@ -225,4 +225,4 @@ class BuildTaskHandlerInternal extends BuildTaskHandler {
225
225
  return fs.lstatSync(entry)
226
226
  }
227
227
  }
228
- module.exports = BuildTaskHandlerInternal
228
+ module.exports = InternalBuildPlugin
@@ -8,7 +8,7 @@ const { FILE_EXT_CDS, BUILD_TASK_HANA, BUILD_TASK_FIORI, BUILD_TASK_JAVA, BUILD_
8
8
  BUILD_TASK_PREFIX, BUILD_TASKS, BUILD_TASK_MTX_SIDECAR, MTX_SIDECAR_FOLDER, BUILD_TASK_MTX_EXTENSION, NODEJS_MODEL_EXCLUDE_LIST,
9
9
  IGNORE_DEFAULT_MODELS } = require("../constants")
10
10
 
11
- class BuildTaskProviderInternal extends BuildTaskProvider {
11
+ class InternalBuildTaskProvider extends BuildTaskProvider {
12
12
  constructor(logger) {
13
13
  super()
14
14
  this._logger = logger
@@ -22,33 +22,32 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
22
22
  return this._logger
23
23
  }
24
24
 
25
- canHandleTask(task) {
26
- return BUILD_TASKS.includes(task.for)
27
- || task.use && task.use.startsWith(BUILD_TASK_PREFIX)
28
- // support different build task implementations of the same build task ID defined by 'for'
29
- //return (BUILD_TASKS.includes(task.for) && !task.use) || (task.use && task.use.startsWith(BUILD_TASK_PREFIX))
25
+ providesTask(key) {
26
+ return BUILD_TASKS.includes(key.for) || key.use && key.use.startsWith(BUILD_TASK_PREFIX)
27
+ // REVISIT: do not support different build task implementations of the same build task ID defined by 'for'
28
+ // return (BUILD_TASKS.includes(key.for) && !key.use) || (key.use && key.use.startsWith(BUILD_TASK_PREFIX))
30
29
  }
31
30
 
32
- loadHandler(task) {
33
- return require(`./${BuildTaskProviderInternal._getForValueFromTask(task)}`)
34
- }
35
-
36
- async lookupTasks(tasks) {
37
- return this._createTasks(tasks, tasks.length > 0)
31
+ async lookupTasks(tasks, dependencies) {
32
+ return this._createTasks(tasks, dependencies)
38
33
  }
39
34
 
40
35
  async applyTaskDefaults(task) {
41
- const taskFor = BuildTaskProviderInternal._getForValueFromTask(task)
36
+ const taskFor = InternalBuildTaskProvider._getForValueFromTask(task)
42
37
  task.for = task.for || taskFor
43
38
  task.use = task.use || `${BUILD_TASK_PREFIX}/${taskFor}`
44
39
 
45
40
  // src folder needs to be initialized first
46
- BuildTaskProviderInternal._setDefaultSrcFolder(task)
41
+ InternalBuildTaskProvider._setDefaultSrcFolder(task)
42
+
43
+ InternalBuildTaskProvider._setDefaultModel(task)
44
+ }
47
45
 
48
- BuildTaskProviderInternal._setDefaultModel(task)
46
+ loadPlugin(task) {
47
+ return require(`./${InternalBuildTaskProvider._getForValueFromTask(task)}`)
49
48
  }
50
49
 
51
- async _createTasks(tasks, addRequiredTasks) {
50
+ async _createTasks(tasks, dependencies) {
52
51
  let db = typeof cds.env.folders.db === "string" ? [normalizePath(cds.env.folders.db)] : cds.env.folders.db
53
52
  let srv = typeof cds.env.folders.srv === "string" ? [normalizePath(cds.env.folders.srv)] : cds.env.folders.srv
54
53
 
@@ -59,20 +58,20 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
59
58
  model: []
60
59
  }
61
60
  if (Array.isArray(db) && db.length > 0) {
62
- db = BuildTaskProviderInternal._getModuleFolder(db) || null
63
- if (!db && !addRequiredTasks) { // log once
61
+ db = InternalBuildTaskProvider._getModuleFolder(db) || null
62
+ if (!db && !dependencies) { // log once
64
63
  this.logger.debug("No database module found")
65
64
  }
66
65
  }
67
66
  if (Array.isArray(srv) && srv.length > 0) {
68
- srv = BuildTaskProviderInternal._getModuleFolder(srv) || null
69
- if (!srv && !addRequiredTasks) { // log once
67
+ srv = InternalBuildTaskProvider._getModuleFolder(srv) || null
68
+ if (!srv && !dependencies) { // log once
70
69
  this.logger.debug("No service module found")
71
70
  }
72
71
  }
73
72
 
74
73
  // order of creation is relevant
75
- if (addRequiredTasks) {
74
+ if (dependencies) {
76
75
  const mtxTask = tasks.find(task => task.for === BUILD_TASK_MTX || task.for === BUILD_TASK_MTX_SIDECAR)
77
76
  if (mtxTask) {
78
77
  //restore used tasks as they might have been filtered by 'cds build --for mtx'
@@ -124,7 +123,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
124
123
 
125
124
  _createDbTask(src, taskOptions) {
126
125
  this.logger.debug("determining database kind")
127
- if (!src || BuildTaskProviderInternal._isMtxExtension()) {
126
+ if (!src || InternalBuildTaskProvider._isMtxExtension()) {
128
127
  return null
129
128
  }
130
129
  let task = null
@@ -166,12 +165,12 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
166
165
  this.logger.debug("determining MTX architecture")
167
166
 
168
167
  // preserve order of creation
169
- if (BuildTaskProviderInternal._isMtxExtension()) {
168
+ if (InternalBuildTaskProvider._isMtxExtension()) {
170
169
  this.logger.debug("MTX extension app")
171
170
  return { for: BUILD_TASK_MTX_EXTENSION }
172
171
  }
173
172
 
174
- if (BuildTaskProviderInternal._isMtxs()) {
173
+ if (InternalBuildTaskProvider._isMtxs()) {
175
174
  const sidecarPath = path.join(cds.root, MTX_SIDECAR_FOLDER)
176
175
  let sidecarEnv
177
176
  if (fs.existsSync(sidecarPath)) {
@@ -204,7 +203,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
204
203
  }
205
204
 
206
205
  // mtxs nodejs app without sidecar
207
- if (!BuildTaskProviderInternal._hasJavaNature(src)) {
206
+ if (!InternalBuildTaskProvider._hasJavaNature(src)) {
208
207
  this.logger.debug("MTX Nodejs app without sidecar")
209
208
  return {
210
209
  for: BUILD_TASK_MTX,
@@ -216,11 +215,11 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
216
215
 
217
216
  _createSrvTask(src, taskOptions) {
218
217
  this.logger.debug("determining implementation technology")
219
- if (!src || BuildTaskProviderInternal._isMtxExtension()) {
218
+ if (!src || InternalBuildTaskProvider._isMtxExtension()) {
220
219
  return null
221
220
  }
222
221
  let task = null
223
- if (BuildTaskProviderInternal._hasJavaNature(src)) {
222
+ if (InternalBuildTaskProvider._hasJavaNature(src)) {
224
223
  task = this._createJavaTask(src, taskOptions)
225
224
  } else {
226
225
  task = this._createNodeTask(src, taskOptions)
@@ -365,4 +364,4 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
365
364
  }, null)
366
365
  }
367
366
  }
368
- module.exports = BuildTaskProviderInternal
367
+ module.exports = InternalBuildTaskProvider
@@ -1,35 +1,34 @@
1
1
  const fs = require('fs')
2
2
  const path = require('path')
3
3
  const cds = require('../../../cds')
4
- const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
5
- const { OUTPUT_MODE, OUTPUT_MODE_RESULT, FILE_EXT_CDS, CONTENT_LANGUAGE_BUNDLES, CONTENT_DEFAULT_CSN, DEFAULT_CSN_FILE_NAME, OUTPUT_MODE_FILESYSTEM } = require('../../constants')
4
+ const EdmxBuildPlugin = require('../edmxBuildPlugin')
5
+ const { OUTPUT_MODE, OUTPUT_MODE_RESULT, FILE_EXT_CDS, CONTENT_LANGUAGE_BUNDLES, CONTENT_DEFAULT_CSN, DEFAULT_CSN_FILE_NAME,
6
+ OUTPUT_MODE_FILESYSTEM, FLAVOR_LOCALIZED_EDMX } = require('../../constants')
6
7
  const { getI18nDefaultFolder } = require('../../util')
7
8
  const DEFAULT_COMPILE_DEST_FOLDER = path.normalize('src/main/resources/edmx')
8
9
 
9
- class JavaModuleBuilder extends BuildTaskHandlerEdmx {
10
+ class JavaBuildPlugin extends EdmxBuildPlugin {
10
11
  init() {
11
12
  super.init()
12
13
  this.task.options.compileDest = path.resolve(this.task.dest, this.task.options.compileDest || DEFAULT_COMPILE_DEST_FOLDER)
13
14
  }
14
15
 
15
16
  async build() {
17
+ const compileDest = this.task.options.compileDest
16
18
  const { src, dest } = this.task
17
-
18
- const odataOptions = {
19
- version: cds.env.odata?.version
20
- }
21
-
22
19
  const model = await this.model()
23
20
  if (!model) {
24
21
  return
25
22
  }
26
23
 
27
- const odata = await this._compileForOdata(model, this.task.options.compileDest, odataOptions)
28
- await this.compileToEdmx(odata, this.task.options.compileDest, odataOptions)
24
+ // generate edmx files containing all features
25
+ const odata = await this._compileForOdata(model, compileDest)
26
+ await this.compileToEdmx(odata, compileDest) // localized edmx for backward compatibility
27
+ await this.compileToEdmx(odata, path.join(compileDest, 'odata', cds.env.odata.version), { [FLAVOR_LOCALIZED_EDMX]: false }) // non-localized edmx
29
28
 
30
- if (this.hasBuildOption(CONTENT_LANGUAGE_BUNDLES, true)) {
31
- // collect and write language bundles into single i18n.json file
32
- const i18n = await this.collectLanguageBundles(model, path.join(this.task.dest, getI18nDefaultFolder()))
29
+ if (!this.hasBuildOption(CONTENT_LANGUAGE_BUNDLES, false)) {
30
+ // collect and write language bundles containing all features
31
+ const i18n = await this.collectLanguageBundles(model, path.join(compileDest, getI18nDefaultFolder()))
33
32
  if (i18n && this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
34
33
  this._result.languageBundles = i18n.bundles
35
34
  }
@@ -59,28 +58,29 @@ class JavaModuleBuilder extends BuildTaskHandlerEdmx {
59
58
  })
60
59
  }
61
60
 
62
- async _compileForOdata(model, csnDest, compileOptions) {
61
+ async _compileForOdata(model, csnDest, compileOptions = {}) {
63
62
  // csn for service providers
64
63
  const m = cds.compile.for.java(model, {
65
64
  ...this._options4odata(),
66
65
  ...compileOptions
67
66
  })
68
67
  const csnFile = path.join(csnDest, DEFAULT_CSN_FILE_NAME)
69
- let csnModel
70
68
  // adding csn to build result containing @source and _where persisted properties
71
69
  if (this.hasBuildOption(CONTENT_DEFAULT_CSN, true)) { //default true or undefined
72
70
  const csnStr = await this.compileToJson(model, csnFile)
73
- csnModel = JSON.parse(csnStr)
74
- csnModel.meta = model.meta
71
+ if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
72
+ const csnModel = JSON.parse(csnStr)
73
+ csnModel.meta = model.meta
74
+ this._result.csn = csnModel
75
+ }
75
76
  } else {
76
77
  const csnStr = await this.compileToJson(m, csnFile)
77
- csnModel = JSON.parse(csnStr)
78
- csnModel.meta = m.meta
79
- }
80
- if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
81
- this._result.csn = csnModel
78
+ if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
79
+ const csnModel = JSON.parse(csnStr)
80
+ csnModel.meta = m.meta
81
+ this._result.csn = csnModel
82
+ }
82
83
  }
83
-
84
84
  return m
85
85
  }
86
86
 
@@ -90,4 +90,4 @@ class JavaModuleBuilder extends BuildTaskHandlerEdmx {
90
90
  return match && match[1] === 1
91
91
  }
92
92
  }
93
- module.exports = JavaModuleBuilder
93
+ module.exports = JavaBuildPlugin
@@ -2,15 +2,15 @@
2
2
  const fs = require('fs')
3
3
  const path = require('path')
4
4
  const cds = require('../../../cds')
5
- const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
5
+ const EdmxBuildPlugin = require('../edmxBuildPlugin')
6
6
  const ResourcesTarProvider = require('./resourcesTarBuilder')
7
7
  const { FOLDER_GEN } = require('../../constants')
8
8
  const { BuildError } = require('../../util')
9
9
 
10
- class MtxModuleBuilder extends BuildTaskHandlerEdmx {
10
+ class MtxBuildPlugin extends EdmxBuildPlugin {
11
11
  get priority() {
12
12
  // should be scheduled after 'hana' build tasks are finished
13
- return BuildTaskHandlerEdmx.PRIORITY_MIN_VALUE
13
+ return EdmxBuildPlugin.PRIORITY_MIN_VALUE
14
14
  }
15
15
  init() {
16
16
  super.init()
@@ -40,4 +40,4 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
40
40
  }
41
41
  }
42
42
  }
43
- module.exports = MtxModuleBuilder
43
+ module.exports = MtxBuildPlugin
@@ -1,24 +1,24 @@
1
1
  const path = require('path')
2
2
  const cds = require('../../../cds')
3
- const BuildTaskHandlerInternal = require('../buildTaskHandlerInternal')
3
+ const InternalBuildPlugin = require('../internalBuildPlugin')
4
4
 
5
5
  const { BUILD_TASK_HANA } = require('../../constants')
6
6
  const fs = require('fs')
7
- const { WARNING } = BuildTaskHandlerInternal
7
+ const { WARNING } = InternalBuildPlugin
8
8
  const DEFAULT_TAR_NAME = "resources.tgz"
9
9
 
10
10
  class ResourcesTarBuilder {
11
- constructor(handler) {
12
- this._handler = handler
11
+ constructor(plugin) {
12
+ this._plugin = plugin
13
13
  }
14
14
 
15
- get handler() { return this._handler }
15
+ get plugin() { return this._plugin }
16
16
 
17
17
  async createTar(dest, model) {
18
18
  const { root, resources } = await this._getResources(model)
19
19
  if (resources.length === 0) {
20
20
  // packTarArchive fails otherwise
21
- this.handler.pushMessage("No deployment resources found - skip resources.tgz", WARNING)
21
+ this.plugin.pushMessage("No deployment resources found - skip resources.tgz", WARNING)
22
22
  return
23
23
  }
24
24
  await this.writeTarFile(path.join(dest, DEFAULT_TAR_NAME), root, resources)
@@ -36,7 +36,7 @@ class ResourcesTarBuilder {
36
36
  async writeTarFile(tarFile, root, resources) {
37
37
  const { tar } = require('../../../../lib').utils
38
38
  await tar.czfd(tarFile, root, resources)
39
- this.handler.pushFile(tarFile)
39
+ this.plugin.pushFile(tarFile)
40
40
  }
41
41
 
42
42
  async _getResources(model) {
@@ -83,7 +83,7 @@ class ResourcesTarBuilder {
83
83
  }
84
84
 
85
85
  async _getHanaTenantDbDest() {
86
- const hanaTask = this.handler.context.tasks.find(task => task.for === BUILD_TASK_HANA)
86
+ const hanaTask = this.plugin.context.tasks.find(task => task.for === BUILD_TASK_HANA)
87
87
  return hanaTask?.dest
88
88
  }
89
89
  }
@@ -2,12 +2,12 @@ const path = require('path')
2
2
  const fs = require('fs')
3
3
  const cds = require('../../../cds')
4
4
 
5
- const BuildTaskHandlerInternal = require('../buildTaskHandlerInternal')
5
+ const InternalBuildPlugin = require('../internalBuildPlugin')
6
6
  const { FOLDER_GEN, EXTENSION_POINT_VALIDATION } = require('../../constants')
7
7
  const ResourcesTarBuilder = require('../mtx/resourcesTarBuilder')
8
8
  const { BuildError, BuildMessage } = require('../../util')
9
9
 
10
- class MtxExtensionModuleBuilder extends BuildTaskHandlerInternal {
10
+ class MtxExtensionBuildPlugin extends InternalBuildPlugin {
11
11
  init() {
12
12
  super.init()
13
13
  if (cds.env.build.target === '.') {
@@ -37,12 +37,10 @@ class MtxExtensionModuleBuilder extends BuildTaskHandlerInternal {
37
37
  extModel.requires.length = 0
38
38
  }
39
39
 
40
- if (!this.hasBuildOption(EXTENSION_POINT_VALIDATION, false)) {
41
- this._lintExtModel(extModel, model) // throws error in case of linting errors
42
- }
43
-
40
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
41
+ // perform all model operations before the linter is called as the linter
42
+ // will modify the model causing the creation of 'unresolved' associations
44
43
  await this.compileToJson(extModel, path.join(destExt, 'extension.csn'))
45
-
46
44
  await this.collectLanguageBundles(extModel, path.join(destExt, 'i18n'))
47
45
 
48
46
  const files = Object.keys(await cds.deploy.resources(model))
@@ -56,6 +54,16 @@ class MtxExtensionModuleBuilder extends BuildTaskHandlerInternal {
56
54
  })
57
55
  )
58
56
  }
57
+ if (!this.hasBuildOption(EXTENSION_POINT_VALIDATION, false)) {
58
+ try {
59
+ // throws error in case of linting errors
60
+ this._lintExtModel(extModel, model)
61
+ } catch(error) {
62
+ // cleanup existing files in case of an error
63
+ await fs.promises.rm(this.task.dest, { recursive: true })
64
+ throw error
65
+ }
66
+ }
59
67
  }
60
68
 
61
69
  const packageJson = path.join(src, 'package.json')
@@ -90,7 +98,7 @@ class MtxExtensionModuleBuilder extends BuildTaskHandlerInternal {
90
98
 
91
99
  return paths
92
100
  }
93
-
101
+
94
102
  _lintExtModel(extModel, model) {
95
103
  const linter = this._linter()
96
104
  if (!linter) {
@@ -128,4 +136,4 @@ class MtxExtensionModuleBuilder extends BuildTaskHandlerInternal {
128
136
  }
129
137
  }
130
138
 
131
- module.exports = MtxExtensionModuleBuilder
139
+ module.exports = MtxExtensionBuildPlugin