@sap/cds-dk 7.1.1 → 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.
- package/bin/activate.js +2 -2
- package/bin/build.js +5 -2
- package/bin/compile/index.js +13 -5
- package/bin/env.js +0 -3
- package/bin/extend.js +25 -3
- package/bin/gen.js +27 -0
- package/bin/help.js +2 -1
- package/bin/import.js +7 -3
- package/bin/push.js +10 -6
- package/bin/watch.js +3 -4
- package/bin/watched.js +2 -3
- package/lib/bind/bindingUtil.js +1 -0
- package/lib/build/{buildTaskHandler.js → buildPlugin.js} +25 -30
- package/lib/build/buildTaskEngine.js +84 -89
- package/lib/build/buildTaskFactory.js +23 -44
- package/lib/build/buildTaskProvider.js +24 -19
- package/lib/build/buildTaskProviderFactory.js +176 -66
- package/lib/build/constants.js +6 -5
- package/lib/build/index.js +4 -3
- package/lib/build/provider/{buildTaskHandlerEdmx.js → edmxBuildPlugin.js} +6 -6
- package/lib/build/provider/{buildTaskHandlerFeatureToggles.js → featureToggleBuildPlugin.js} +3 -3
- package/lib/build/provider/fiori/index.js +5 -6
- package/lib/build/provider/hana/index.js +67 -36
- package/lib/build/provider/{buildTaskHandlerInternal.js → internalBuildPlugin.js} +11 -11
- package/lib/build/provider/{buildTaskProviderInternal.js → internalBuildTaskProvider.js} +42 -53
- package/lib/build/provider/java/index.js +24 -24
- package/lib/build/provider/mtx/index.js +4 -4
- package/lib/build/provider/mtx/resourcesTarBuilder.js +8 -8
- package/lib/build/provider/mtx-extension/index.js +17 -9
- package/lib/build/provider/mtx-sidecar/index.js +17 -11
- package/lib/build/provider/nodejs/index.js +63 -29
- package/lib/build/util.js +11 -19
- package/lib/client/auth_manager.js +6 -12
- package/lib/client/base_command.js +1 -1
- package/lib/client/download_legacy.js +48 -0
- package/lib/client/params.js +5 -0
- package/lib/client/push.js +41 -1
- package/lib/client/settings_manager.js +12 -3
- package/lib/compile/openapi/csdl2openapi.js +30 -21
- package/lib/compile/openapi/index.js +7 -3
- package/lib/env/schema.js +36 -0
- package/lib/env/schemas/cds-rc.json +101 -0
- package/lib/import/common.js +24 -11
- package/lib/import/importapi.js +2 -2
- package/lib/import/message.js +3 -1
- package/lib/import/odata/v4parser.js +23 -7
- package/lib/index.js +5 -0
- package/lib/init/constants.js +9 -12
- package/lib/init/index.js +86 -74
- package/lib/init/template/_merging/registry-mta.js +21 -12
- package/lib/init/template/approuter/files/mta.yaml.hbs +1 -1
- package/lib/init/template/approuter/index.js +3 -2
- package/lib/init/template/cf-manifest/files/services-manifest.yml.hbs +0 -5
- package/lib/init/template/cf-manifest/index.js +2 -2
- package/lib/init/template/connectivity/index.js +5 -4
- package/lib/init/template/destination/index.js +2 -5
- package/lib/init/template/h2/index.js +16 -0
- package/lib/init/template/hana/index.js +2 -3
- package/lib/init/template/helm/chart/values.root.schema.json +0 -5
- package/lib/init/template/helm/chart/values.schema.json +0 -4
- package/lib/init/template/helm/index.js +1 -1
- package/lib/init/template/html5-repo/index.js +27 -3
- package/lib/init/template/lint/index.js +3 -7
- package/lib/init/template/mta/index.js +9 -3
- package/lib/init/template/multitenancy/files/package.json.hbs +0 -3
- package/lib/init/template/multitenancy/index.js +2 -0
- package/lib/init/template/nodejs/index.js +3 -3
- package/lib/init/template/pipeline/index.js +2 -4
- package/lib/init/template/postgres/files/mta.yaml.hbs +27 -0
- package/lib/init/template/postgres/files/package.json.hbs +5 -0
- package/lib/init/template/postgres/index.js +52 -0
- package/lib/init/template/sample/index.js +5 -7
- package/lib/init/template/sqlite/index.js +8 -3
- package/lib/init/template/tiny-sample/index.js +16 -30
- package/lib/init/util/mvn.js +25 -1
- package/lib/init/util/projectReader.js +2 -7
- package/lib/init/util/template.js +7 -6
- package/lib/util/pruneAxiosErrors.js +22 -8
- package/lib/watch/node-watch.js +6 -1
- package/npm-shrinkwrap.json +2207 -384
- package/package.json +3 -3
- package/lib/init/template/auditlog/files/mta.yaml.hbs +0 -14
- package/lib/init/template/auditlog/files/package.json.hbs +0 -27
- package/lib/init/template/auditlog/index.js +0 -74
|
@@ -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
|
|
6
|
-
const { BuildError, relativePaths } = require('../../util')
|
|
5
|
+
const InternalBuildPlugin = require('../internalBuildPlugin')
|
|
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
|
-
CONTENT_ENV, CONTENT_DEFAULT_ENV_JSON, CONTENT_NODE_MODULES, OUTPUT_MODE_RESULT } = require('../../constants')
|
|
10
|
-
const {
|
|
9
|
+
CONTENT_ENV, CONTENT_DEFAULT_ENV_JSON, CONTENT_NODE_MODULES, OUTPUT_MODE_RESULT, CONTINUE_UNRESOLVED_SCHEMA_CHANGES } = require('../../constants')
|
|
10
|
+
const { WARNING } = InternalBuildPlugin
|
|
11
11
|
|
|
12
12
|
const DEFAULT_COMPILE_DEST_FOLDER = path.normalize("src/gen")
|
|
13
13
|
|
|
@@ -15,16 +15,14 @@ const FILE_EXT_CSV = ".csv"
|
|
|
15
15
|
const FILE_EXT_HDBTABLEDATA = ".hdbtabledata"
|
|
16
16
|
const FILE_EXT_HDBTABLE = ".hdbtable"
|
|
17
17
|
const FILE_EXT_HDBMIGRATIONTABLE = ".hdbmigrationtable"
|
|
18
|
-
|
|
19
18
|
const FILE_NAME_HDICONFIG = ".hdiconfig"
|
|
20
19
|
const FILE_NAME_HDINAMESPACE = ".hdinamespace"
|
|
21
20
|
const FILE_NAME_PACKAGE_JSON = "package.json"
|
|
22
21
|
const PATH_LAST_DEV_CSN = "last-dev/csn.json"
|
|
23
22
|
const FILE_NAME_UNDEPLOY_JSON = "undeploy.json"
|
|
24
|
-
|
|
25
23
|
const DEPLOY_FORMAT = "deploy-format"
|
|
26
24
|
|
|
27
|
-
class
|
|
25
|
+
class HanaBuildPlugin extends InternalBuildPlugin {
|
|
28
26
|
init() {
|
|
29
27
|
if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
|
|
30
28
|
this._result = {
|
|
@@ -155,7 +153,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
155
153
|
|
|
156
154
|
// handle *.csv and *.hdbtabledata located in '<dbSrc>/data' and '<dbSrc>/csv' folder
|
|
157
155
|
const allFiles = csvDirs.reduce((acc, csvDir) => {
|
|
158
|
-
return acc.concat(
|
|
156
|
+
return acc.concat(InternalBuildPlugin._find(csvDir, (entry) => {
|
|
159
157
|
if (fs.statSync(entry).isDirectory()) {
|
|
160
158
|
return false
|
|
161
159
|
}
|
|
@@ -183,7 +181,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
183
181
|
const tableDataDirs = new Set()
|
|
184
182
|
const destSrcDir = path.join(this.task.dest, "src")
|
|
185
183
|
|
|
186
|
-
const allCsvFiles =
|
|
184
|
+
const allCsvFiles = InternalBuildPlugin._find(destSrcDir, (entry) => {
|
|
187
185
|
if (fs.statSync(entry).isDirectory()) {
|
|
188
186
|
return true
|
|
189
187
|
}
|
|
@@ -250,7 +248,8 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
250
248
|
return Promise.reject(new Error(`Invalid deploy-format defined: ${format}`))
|
|
251
249
|
}
|
|
252
250
|
|
|
253
|
-
|
|
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) {
|
|
254
253
|
return await this._compileToHdb(model, format)
|
|
255
254
|
} else {
|
|
256
255
|
return await this._compileToHdbmigration(model, format)
|
|
@@ -266,12 +265,24 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
266
265
|
const promises = []
|
|
267
266
|
|
|
268
267
|
for (const [content, key] of result) {
|
|
269
|
-
|
|
268
|
+
const suffix = key.suffix || path.extname(key.file)
|
|
270
269
|
const file = key.file ? key.file : key.name + key.suffix
|
|
270
|
+
|
|
271
|
+
hdiPlugins.add(suffix)
|
|
271
272
|
if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
|
|
272
273
|
this._result.hana.push(path.join(relDest, file))
|
|
273
274
|
}
|
|
274
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
|
+
}
|
|
275
286
|
}
|
|
276
287
|
await Promise.all(promises)
|
|
277
288
|
return hdiPlugins
|
|
@@ -298,6 +309,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
298
309
|
const compilationResult = await to_hdbmigration(model, lastDev, dbSrcDir, options)
|
|
299
310
|
const definitions = compilationResult.definitions
|
|
300
311
|
const afterImage = compilationResult.afterImage
|
|
312
|
+
let validationError
|
|
301
313
|
|
|
302
314
|
for (const { name, suffix, content, changed } of definitions) {
|
|
303
315
|
hdiPlugins.add(suffix)
|
|
@@ -320,28 +332,38 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
320
332
|
if (suffix === FILE_EXT_HDBTABLE) {
|
|
321
333
|
// issue an error in case a .hdbmigrationtable file already exists
|
|
322
334
|
if (fs.existsSync(path.join(dbSrcDir, name + FILE_EXT_HDBMIGRATIONTABLE))) {
|
|
323
|
-
|
|
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.`)
|
|
324
336
|
}
|
|
325
337
|
}
|
|
326
338
|
}
|
|
327
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
|
|
328
343
|
await Promise.all(promises)
|
|
329
|
-
await this._validateMigrationTableFiles()
|
|
330
|
-
|
|
331
|
-
// update last development version
|
|
332
|
-
if (afterImage) {
|
|
333
|
-
if (migrationTableFiles.length > 0) {
|
|
334
|
-
if (!HanaModuleBuilder._toEqualIgnoreMeta(lastDev, afterImage)) {
|
|
335
|
-
await this.write(afterImage).to(lastDevCsnDir)
|
|
336
|
-
}
|
|
337
344
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
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
|
+
}
|
|
342
363
|
}
|
|
343
364
|
}
|
|
344
|
-
}
|
|
365
|
+
}
|
|
366
|
+
if (!afterImage) {
|
|
345
367
|
throw new BuildError(`Inconsistent CDS compilation results - file ${lastDevCsnFolder} missing`)
|
|
346
368
|
}
|
|
347
369
|
return hdiPlugins
|
|
@@ -355,7 +377,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
355
377
|
this.logger._debug && this.logger.debug(`skip create [${relativePaths(cds.root, packageJson)}], already existing`)
|
|
356
378
|
}
|
|
357
379
|
if (this.isStagingBuild() && !exists) {
|
|
358
|
-
const content = await
|
|
380
|
+
const content = await HanaBuildPlugin._readTemplateAsJson(FILE_NAME_PACKAGE_JSON)
|
|
359
381
|
await this.write(content).to(path.join(this.task.dest, FILE_NAME_PACKAGE_JSON))
|
|
360
382
|
}
|
|
361
383
|
}
|
|
@@ -374,11 +396,11 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
374
396
|
// && !fs.existsSync(path.join(this.task.dest, FILE_NAME_HDICONFIG))
|
|
375
397
|
// && !fs.existsSync(path.join(this.task.dest, 'cfg', FILE_NAME_HDICONFIG))) {
|
|
376
398
|
// // in 'gen/db' if none exists
|
|
377
|
-
// // ensures correct deployment of all artifacts including HANA native artifacts
|
|
399
|
+
// // ensures correct deployment of all artifacts including HANA native artifacts
|
|
378
400
|
// // without the need of creating a static .hdiconfig file in the 'db' folder
|
|
379
401
|
|
|
380
402
|
// // add all known plugins
|
|
381
|
-
// const defaultHdiConfig = await
|
|
403
|
+
// const defaultHdiConfig = await HanaBuildPlugin._readTemplateAsJson('.hdiconfig-cloud')
|
|
382
404
|
// for (const plugin in defaultHdiConfig['file_suffixes']) {
|
|
383
405
|
// hdiPlugins.add('.' + plugin)
|
|
384
406
|
// }
|
|
@@ -390,7 +412,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
390
412
|
hdiConfigPath = path.join(this.task.options.compileDest, FILE_NAME_HDICONFIG)
|
|
391
413
|
// }
|
|
392
414
|
|
|
393
|
-
const template = await
|
|
415
|
+
const template = await HanaBuildPlugin._readTemplateAsJson('.hdiconfig-all')
|
|
394
416
|
let content = {
|
|
395
417
|
'file_suffixes': {}
|
|
396
418
|
}
|
|
@@ -412,7 +434,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
412
434
|
async _writeHdiNamespace() {
|
|
413
435
|
// see issue #64 - add .hdinamespace file to prevent HDI from adding gen/ folder to the namespace.
|
|
414
436
|
const hdiNamespace = path.join(this.task.options.compileDest, FILE_NAME_HDINAMESPACE)
|
|
415
|
-
const content = await
|
|
437
|
+
const content = await HanaBuildPlugin._readTemplateAsJson(FILE_NAME_HDINAMESPACE)
|
|
416
438
|
return await this.write(content).to(hdiNamespace)
|
|
417
439
|
}
|
|
418
440
|
|
|
@@ -424,7 +446,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
424
446
|
// see issue #64 - add .hdinamespace file to prevent HDI from adding gen/ folder to the namespace.
|
|
425
447
|
const undeployJsonDest = path.join(this.task.dest, FILE_NAME_UNDEPLOY_JSON)
|
|
426
448
|
const undeployJsonSrc = path.join(this.task.src, FILE_NAME_UNDEPLOY_JSON)
|
|
427
|
-
const templateEntries = await
|
|
449
|
+
const templateEntries = await HanaBuildPlugin._readTemplateAsJson(FILE_NAME_UNDEPLOY_JSON)
|
|
428
450
|
let newEntries = []
|
|
429
451
|
if (fs.existsSync(undeployJsonSrc)) {
|
|
430
452
|
newEntries = await JSON.parse((await fs.promises.readFile(undeployJsonSrc, 'utf-8')).toString())
|
|
@@ -454,7 +476,7 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
454
476
|
if (fs.existsSync(file)) {
|
|
455
477
|
const undeployList = JSON.parse((await fs.promises.readFile(file)).toString(), 'utf-8')
|
|
456
478
|
if (Array.isArray(undeployList)) {
|
|
457
|
-
const hdiconfig = await
|
|
479
|
+
const hdiconfig = await HanaBuildPlugin._readTemplateAsJson('.hdiconfig-all')
|
|
458
480
|
const keys = new Set(Object.keys(hdiconfig['file_suffixes']).map(key => '.' + key))
|
|
459
481
|
undeployList.forEach(entry => {
|
|
460
482
|
const extName = path.extname(entry)
|
|
@@ -473,23 +495,32 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
473
495
|
|
|
474
496
|
async _validateMigrationTableFiles() {
|
|
475
497
|
const dbSrcDir = path.join(this.task.src, "src")
|
|
476
|
-
const migrationTableFiles =
|
|
498
|
+
const migrationTableFiles = InternalBuildPlugin._find(dbSrcDir, (res) => {
|
|
477
499
|
return fs.statSync(res).isFile() && path.extname(res) === FILE_EXT_HDBMIGRATIONTABLE
|
|
478
500
|
})
|
|
479
501
|
if (migrationTableFiles.length > 0) {
|
|
480
502
|
const parser = require('./migrationtable')
|
|
503
|
+
const resolutionMessages = []
|
|
481
504
|
|
|
482
505
|
await Promise.all(migrationTableFiles.map(async file => {
|
|
483
506
|
try {
|
|
484
507
|
const tableModel = await parser.read(file)
|
|
485
508
|
if (/^>>>>>/m.test(tableModel.migrations.toString())) {
|
|
486
509
|
// as this is not a build error, we do not abort cds build, instead only log as error
|
|
487
|
-
|
|
510
|
+
resolutionMessages.push(new BuildMessage(`Manual resolution required for file ${path.relative(cds.root, file)}. Check migration version content for further details.`))
|
|
488
511
|
}
|
|
489
512
|
} catch (e) {
|
|
490
|
-
throw new Error(`${path.relative(cds.root, file)}: ${e.toString()}
|
|
513
|
+
throw new Error(`${path.relative(cds.root, file)}: ${e.toString()}`)
|
|
491
514
|
}
|
|
492
515
|
}))
|
|
516
|
+
if (resolutionMessages.length) {
|
|
517
|
+
// REVISIT: undocumented, we may want to delete in future versions
|
|
518
|
+
if (!this.hasBuildOption(CONTINUE_UNRESOLVED_SCHEMA_CHANGES, true)) {
|
|
519
|
+
throw new BuildError('Current model changes require manual resolution', resolutionMessages)
|
|
520
|
+
}
|
|
521
|
+
// adding to the task's message list
|
|
522
|
+
resolutionMessages.forEach(m => this._messages.push(m))
|
|
523
|
+
}
|
|
493
524
|
}
|
|
494
525
|
}
|
|
495
526
|
|
|
@@ -519,4 +550,4 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
519
550
|
return toString(csn1) === toString(csn2)
|
|
520
551
|
}
|
|
521
552
|
}
|
|
522
|
-
module.exports =
|
|
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
|
|
4
|
+
const BuildPlugin = require('../buildPlugin')
|
|
5
5
|
const { hasOptionValue } = require('../util')
|
|
6
6
|
const { FOLDER_GEN } = require('../constants')
|
|
7
7
|
|
|
8
|
-
class
|
|
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
|
|
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
|
|
22
|
+
return InternalBuildPlugin.PRIORITY_MAX_VALUE
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
async clean() {
|
|
@@ -43,16 +43,16 @@ class BuildTaskHandlerInternal extends BuildTaskHandler {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* Called by the framework after {@link #init()}
|
|
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
|
|
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
|
|
51
|
-
* True indicates that {@link #prepare()} will be called for other instances of this of this
|
|
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
|
|
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 =
|
|
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 =
|
|
228
|
+
module.exports = InternalBuildPlugin
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const cds = require('../../cds')
|
|
4
|
-
const { hasJavaNature, getDefaultModelOptions, BuildError, hasOptionValue, isClassicMtx } = require('../util')
|
|
4
|
+
const { hasJavaNature, getDefaultModelOptions, BuildError, hasOptionValue, isClassicMtx, normalizePath } = require('../util')
|
|
5
5
|
const BuildTaskProvider = require('../buildTaskProvider')
|
|
6
6
|
|
|
7
7
|
const { FILE_EXT_CDS, BUILD_TASK_HANA, BUILD_TASK_FIORI, BUILD_TASK_JAVA, BUILD_TASK_JAVA_CF, BUILD_TASK_NODEJS, BUILD_TASK_NODE_CF, BUILD_TASK_MTX,
|
|
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
|
|
11
|
+
class InternalBuildTaskProvider extends BuildTaskProvider {
|
|
12
12
|
constructor(logger) {
|
|
13
13
|
super()
|
|
14
14
|
this._logger = logger
|
|
@@ -22,35 +22,34 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
22
22
|
return this._logger
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
return BUILD_TASKS.includes(
|
|
27
|
-
|
|
28
|
-
//
|
|
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
|
-
|
|
33
|
-
return
|
|
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 =
|
|
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
|
-
|
|
41
|
+
InternalBuildTaskProvider._setDefaultSrcFolder(task)
|
|
47
42
|
|
|
48
|
-
|
|
43
|
+
InternalBuildTaskProvider._setDefaultModel(task)
|
|
49
44
|
}
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
loadPlugin(task) {
|
|
47
|
+
return require(`./${InternalBuildTaskProvider._getForValueFromTask(task)}`)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async _createTasks(tasks, dependencies) {
|
|
51
|
+
let db = typeof cds.env.folders.db === "string" ? [normalizePath(cds.env.folders.db)] : cds.env.folders.db
|
|
52
|
+
let srv = typeof cds.env.folders.srv === "string" ? [normalizePath(cds.env.folders.srv)] : cds.env.folders.srv
|
|
54
53
|
|
|
55
54
|
const dbOptions = {
|
|
56
55
|
model: []
|
|
@@ -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 =
|
|
63
|
-
if (!db && !
|
|
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 =
|
|
69
|
-
if (!srv && !
|
|
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 (
|
|
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 ||
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
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 ||
|
|
218
|
+
if (!src || InternalBuildTaskProvider._isMtxExtension()) {
|
|
220
219
|
return null
|
|
221
220
|
}
|
|
222
221
|
let task = null
|
|
223
|
-
if (
|
|
222
|
+
if (InternalBuildTaskProvider._hasJavaNature(src)) {
|
|
224
223
|
task = this._createJavaTask(src, taskOptions)
|
|
225
224
|
} else {
|
|
226
225
|
task = this._createNodeTask(src, taskOptions)
|
|
@@ -269,16 +268,16 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
269
268
|
static _setDefaultSrcFolder(task) {
|
|
270
269
|
switch (task.for) {
|
|
271
270
|
case BUILD_TASK_HANA:
|
|
272
|
-
task.src = task.src ||
|
|
271
|
+
task.src = task.src || normalizePath(cds.env.folders.db)
|
|
273
272
|
break
|
|
274
273
|
case BUILD_TASK_JAVA:
|
|
275
274
|
case BUILD_TASK_JAVA_CF:
|
|
276
275
|
case BUILD_TASK_NODEJS:
|
|
277
276
|
case BUILD_TASK_NODE_CF:
|
|
278
|
-
task.src = task.src ||
|
|
277
|
+
task.src = task.src || normalizePath(cds.env.folders.srv)
|
|
279
278
|
break
|
|
280
279
|
case BUILD_TASK_FIORI:
|
|
281
|
-
task.src = task.src ||
|
|
280
|
+
task.src = task.src || normalizePath(cds.env.folders.app)
|
|
282
281
|
break
|
|
283
282
|
case BUILD_TASK_MTX_SIDECAR:
|
|
284
283
|
task.src = task.src || MTX_SIDECAR_FOLDER
|
|
@@ -288,7 +287,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
288
287
|
break
|
|
289
288
|
case BUILD_TASK_MTX:
|
|
290
289
|
// mtxs with nodejs, but without sidecar
|
|
291
|
-
task.src = task.src ||
|
|
290
|
+
task.src = task.src || normalizePath(cds.env.folders.srv)
|
|
292
291
|
break
|
|
293
292
|
default:
|
|
294
293
|
throw new Error(`Unknown build task '${task.use || task.for}'`)
|
|
@@ -300,29 +299,27 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
300
299
|
if (taskModelPaths && !Array.isArray(taskModelPaths)) {
|
|
301
300
|
taskModelPaths = [taskModelPaths]
|
|
302
301
|
}
|
|
302
|
+
const toggles = cds.env.features.folders
|
|
303
|
+
const allowList = new RegExp(`^@sap/cds${toggles ? '|^' + toggles.replace('*', '') : ''}`)
|
|
303
304
|
task.options = task.options || {}
|
|
304
305
|
let defaultModelPaths = []
|
|
305
|
-
// add default models to custom build tasks if this hasn't been disabled
|
|
306
306
|
if (taskModelPaths?.length) {
|
|
307
|
-
if (!hasOptionValue(task.options?.[
|
|
308
|
-
|
|
309
|
-
defaultModelPaths = getDefaultModelOptions().filter(p => p.match('@sap/cds'))
|
|
307
|
+
if (!hasOptionValue(task.options?.[IGNORE_DEFAULT_MODELS], true)) {
|
|
308
|
+
defaultModelPaths = getDefaultModelOptions().filter(p => p.match(allowList))
|
|
310
309
|
}
|
|
311
310
|
} else {
|
|
312
311
|
defaultModelPaths = getDefaultModelOptions()
|
|
313
312
|
defaultModelPaths.push(task.src)
|
|
314
|
-
if (hasOptionValue(task.options?.[
|
|
313
|
+
if (hasOptionValue(task.options?.[IGNORE_DEFAULT_MODELS], true)) {
|
|
315
314
|
// all default models except the built-in models
|
|
316
|
-
defaultModelPaths = defaultModelPaths.filter(p => !p.match(
|
|
315
|
+
defaultModelPaths = defaultModelPaths.filter(p => !p.match(allowList))
|
|
317
316
|
}
|
|
318
317
|
}
|
|
319
|
-
|
|
320
318
|
// REVISIT: filter nodejs bootstrap service models for Java - issues/12770#issuecomment-1805719
|
|
321
319
|
if (this._hasJavaNature()) {
|
|
322
320
|
defaultModelPaths = defaultModelPaths.filter(p => !NODEJS_MODEL_EXCLUDE_LIST.includes(p))
|
|
323
321
|
}
|
|
324
|
-
|
|
325
|
-
if (!taskModelPaths || defaultModelPaths.length) {
|
|
322
|
+
if (defaultModelPaths.length) {
|
|
326
323
|
task.options.model = [...new Set(taskModelPaths?.length ? taskModelPaths.concat(defaultModelPaths) : defaultModelPaths)]
|
|
327
324
|
}
|
|
328
325
|
}
|
|
@@ -340,14 +337,6 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
340
337
|
return task.for ? task.for : task.use && task.use.substring(BUILD_TASK_PREFIX.length + 1)
|
|
341
338
|
}
|
|
342
339
|
|
|
343
|
-
/**
|
|
344
|
-
* For valid paths remove trailing '/'. Otherwise return as is - important!!
|
|
345
|
-
* @param {*} dir
|
|
346
|
-
*/
|
|
347
|
-
static _normalizePath(dir) {
|
|
348
|
-
return typeof dir === "string" ? dir.replace(/\/$/, '') : dir
|
|
349
|
-
}
|
|
350
|
-
|
|
351
340
|
/**
|
|
352
341
|
* Determines the module folder from the past list that may represent files or folders w or w/o .cds file extension.
|
|
353
342
|
* @param {Array} filesOrFolders
|
|
@@ -375,4 +364,4 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
375
364
|
}, null)
|
|
376
365
|
}
|
|
377
366
|
}
|
|
378
|
-
module.exports =
|
|
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
|
|
5
|
-
const { OUTPUT_MODE, OUTPUT_MODE_RESULT, FILE_EXT_CDS, CONTENT_LANGUAGE_BUNDLES, CONTENT_DEFAULT_CSN, DEFAULT_CSN_FILE_NAME,
|
|
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
|
|
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
|
-
|
|
28
|
-
await this.
|
|
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,
|
|
31
|
-
// collect and write language bundles
|
|
32
|
-
const i18n = await this.collectLanguageBundles(model, path.join(
|
|
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
|
-
|
|
74
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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 =
|
|
93
|
+
module.exports = JavaBuildPlugin
|