@sap/cds-dk 6.8.3 → 7.0.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 +15 -7
- package/bin/add.js +29 -15
- package/bin/bind.js +49 -116
- package/bin/build.js +114 -0
- package/bin/cds.js +67 -24
- package/bin/compile/index.js +2 -2
- package/bin/deploy/index.js +46 -39
- package/bin/deploy/to-hana.js +11 -8
- package/bin/deploy/to-postgres.js +8 -2
- package/bin/deploy/to-sqlite.js +0 -1
- package/bin/env.js +75 -41
- package/bin/eval.js +3 -3
- package/bin/extend.js +17 -10
- package/bin/help.js +22 -21
- package/bin/import.js +10 -7
- package/bin/init.js +38 -17
- package/bin/login.js +69 -55
- package/bin/logout.js +12 -9
- package/bin/migrate.js +10 -4
- package/bin/pull.js +12 -5
- package/bin/push.js +24 -13
- package/bin/repl.js +1 -0
- package/bin/run.js +25 -0
- package/bin/subscribe.js +13 -8
- package/bin/unsubscribe.js +15 -8
- package/bin/upgrade.js +15 -9
- package/bin/util/log.js +24 -0
- package/bin/version.js +124 -0
- package/bin/watch.js +1 -35
- package/bin/watched.js +39 -0
- package/lib/bind/KubernetesApiAccessor.js +2 -2
- package/lib/bind/bindingManager.js +1 -1
- package/lib/bind/bindingUtil.js +0 -9
- package/lib/bind/cfKeyProvider.js +10 -72
- package/lib/bind/index.js +114 -0
- package/lib/bind/kubernetesCredentialsProvider.js +2 -2
- package/lib/bind/userCdsrcJsonStorageProvider.js +7 -44
- package/lib/build/buildTaskEngine.js +355 -0
- package/lib/build/buildTaskFactory.js +284 -0
- package/lib/build/buildTaskHandler.js +240 -0
- package/lib/build/buildTaskProvider.js +22 -0
- package/lib/build/buildTaskProviderFactory.js +182 -0
- package/lib/build/constants.js +56 -0
- package/lib/build/index.js +21 -0
- package/lib/build/provider/buildTaskHandlerEdmx.js +83 -0
- package/lib/build/provider/buildTaskHandlerFeatureToggles.js +132 -0
- package/lib/build/provider/buildTaskHandlerInternal.js +228 -0
- package/lib/build/provider/buildTaskProviderInternal.js +370 -0
- package/lib/build/provider/fiori/index.js +167 -0
- package/lib/build/provider/hana/2migration.js +179 -0
- package/lib/build/provider/hana/index.js +522 -0
- package/lib/build/provider/hana/migrationtable.js +472 -0
- package/lib/build/provider/hana/template/.hdiconfig-all +163 -0
- package/lib/build/provider/hana/template/.hdiconfig-cloud +137 -0
- package/lib/build/provider/hana/template/.hdinamespace +4 -0
- package/lib/build/provider/hana/template/package.json +12 -0
- package/lib/build/provider/hana/template/undeploy.json +5 -0
- package/lib/build/provider/java/index.js +93 -0
- package/lib/build/provider/java-cf/index.js +1 -0
- package/lib/build/provider/mtx/index.js +37 -0
- package/lib/build/provider/mtx/resourcesTarBuilder.js +94 -0
- package/lib/build/provider/mtx-extension/index.js +131 -0
- package/lib/build/provider/mtx-sidecar/index.js +138 -0
- package/lib/build/provider/node-cf/index.js +1 -0
- package/lib/build/provider/nodejs/index.js +178 -0
- package/lib/build/util.js +263 -0
- package/lib/cds.js +9 -21
- package/lib/client/auth_manager.js +39 -16
- package/lib/client/helper/dependency_helper.js +7 -6
- package/lib/client/push.js +2 -1
- package/lib/client/settings_manager.js +10 -39
- package/lib/deploy/to-hana/hana.js +273 -0
- package/lib/deploy/to-hana/hdiDeployUtil.js +68 -0
- package/lib/deploy/to-hana/mtaUtil.js +171 -0
- package/lib/import/asyncapi/importAsyncAPI.js +3 -2
- package/lib/import/asyncapi/index.js +5 -2
- package/lib/import/asyncapi/parserContext.js +67 -26
- package/lib/import/asyncapi/utils.js +34 -3
- package/lib/import/common.js +40 -30
- package/lib/import/importapi.js +36 -35
- package/lib/index.js +12 -17
- package/lib/init/constants.js +36 -71
- package/lib/init/index.js +18 -52
- package/lib/init/template/_merging/registry-mta.js +21 -3
- package/lib/init/template/approuter/files/mta.yaml.hbs +29 -29
- package/lib/init/template/approuter/files/values.yaml.hbs +5 -5
- package/lib/init/template/approuter/files/xs-app.json.hbs +8 -2
- package/lib/init/template/approuter/index.js +7 -8
- package/lib/init/template/auditlog/files/mta.yaml.hbs +5 -5
- package/lib/init/template/auditlog/files/package.json.hbs +13 -13
- package/lib/init/template/auditlog/index.js +3 -3
- package/lib/init/template/cf-manifest/files/manifest.yml.hbs +22 -22
- package/lib/init/template/cf-manifest/files/services-manifest.yml.hbs +3 -3
- package/lib/init/template/connectivity/files/mta.yaml.hbs +14 -0
- package/lib/init/template/connectivity/files/package.json.hbs +17 -0
- package/lib/init/template/connectivity/index.js +21 -4
- package/lib/init/template/data/index.js +5 -1
- package/lib/init/template/destination/files/mta.yaml.hbs +14 -0
- package/lib/init/template/destination/files/package.json.hbs +17 -0
- package/lib/init/template/{destinations → destination}/index.js +19 -13
- package/lib/init/template/enterprise-messaging/files/event-mesh.json.hbs +3 -3
- package/lib/init/template/enterprise-messaging/files/mta.yaml.hbs +5 -5
- package/lib/init/template/enterprise-messaging/files/package.json.hbs +9 -9
- package/lib/init/template/enterprise-messaging/files/xs-security.json.hbs +19 -0
- package/lib/init/template/enterprise-messaging/index.js +27 -6
- package/lib/init/template/enterprise-messaging-shared/files/event-mesh.json.hbs +3 -3
- package/lib/init/template/enterprise-messaging-shared/files/mta.yaml.hbs +5 -5
- package/lib/init/template/enterprise-messaging-shared/files/package.json.hbs +9 -9
- package/lib/init/template/enterprise-messaging-shared/index.js +4 -5
- package/lib/init/template/extensibility/files/package.json.hbs +10 -10
- package/lib/init/template/extensibility/index.js +8 -9
- package/lib/init/template/file-based-messaging/files/package.json.hbs +9 -9
- package/lib/init/template/file-based-messaging/index.js +3 -4
- package/lib/init/template/hana/files/db/package.json +1 -1
- package/lib/init/template/hana/files/mta.yaml.hbs +21 -21
- package/lib/init/template/hana/files/package.json.hbs +16 -22
- package/lib/init/template/hana/files/values.yaml.hbs +1 -1
- package/lib/init/template/hana/index.js +5 -15
- package/lib/init/template/helm/files/Chart.yaml.hbs +4 -4
- package/lib/init/template/helm/files/values.yaml.hbs +6 -6
- package/lib/init/template/helm/index.js +5 -10
- package/lib/init/template/helm/subcharts/content-deployment/Chart.yaml +2 -0
- package/lib/init/template/helm/subcharts/content-deployment/templates/_helpers.tpl +37 -31
- package/lib/init/template/helm/subcharts/content-deployment/templates/job.yaml +13 -14
- package/lib/init/template/helm/subcharts/content-deployment/templates/secret.yaml +2 -2
- package/lib/init/template/helm/subcharts/content-deployment/templates/service-account.yaml +1 -1
- package/lib/init/template/helm/subcharts/content-deployment/templates/service-binding.yaml +3 -3
- package/lib/init/template/helm/subcharts/content-deployment/values.md +116 -116
- package/lib/init/template/helm/subcharts/service-instance/Chart.yaml +2 -0
- package/lib/init/template/helm/subcharts/service-instance/templates/_helpers.tpl +9 -9
- package/lib/init/template/helm/subcharts/service-instance/templates/serviceinstance.yaml +2 -2
- package/lib/init/template/helm/subcharts/service-instance/values.md +15 -15
- package/lib/init/template/helm/subcharts/web-application/Chart.yaml +2 -0
- package/lib/init/template/helm/subcharts/web-application/templates/NOTES.txt +15 -0
- package/lib/init/template/helm/subcharts/web-application/templates/_helpers.tpl +23 -23
- package/lib/init/template/helm/subcharts/web-application/templates/api-rule.yaml +4 -4
- package/lib/init/template/helm/subcharts/web-application/templates/deployment.yaml +17 -17
- package/lib/init/template/helm/subcharts/web-application/templates/network-policy.yaml +24 -3
- package/lib/init/template/helm/subcharts/web-application/templates/pod-disruption-budget.yaml +3 -3
- package/lib/init/template/helm/subcharts/web-application/templates/secret.yaml +2 -2
- package/lib/init/template/helm/subcharts/web-application/templates/service-account.yaml +1 -1
- package/lib/init/template/helm/subcharts/web-application/templates/service-binding.yaml +3 -3
- package/lib/init/template/helm/subcharts/web-application/templates/service.yaml +3 -3
- package/lib/init/template/helm/subcharts/web-application/values.md +141 -123
- package/lib/init/template/helm/subcharts/web-application/values.schema.json +7 -0
- package/lib/init/template/helm/subcharts/web-application/values.yaml +1 -0
- package/lib/init/template/html5-repo/index.js +4 -5
- package/lib/init/template/java/index.js +5 -5
- package/lib/init/template/kibana-logging/files/mta.yaml.hbs +5 -5
- package/lib/init/template/kibana-logging/files/package.json.hbs +9 -9
- package/lib/init/template/kibana-logging/index.js +3 -4
- package/lib/init/template/lint/index.js +3 -3
- package/lib/init/template/mta/files/mta.yaml.hbs +14 -14
- package/lib/init/template/mta/files/package.json +5 -0
- package/lib/init/template/mta/index.js +12 -13
- package/lib/init/template/mtx/index.js +2 -2
- package/lib/init/template/multitenancy/files/mta.yaml.hbs +29 -27
- package/lib/init/template/multitenancy/files/package.json.hbs +17 -14
- package/lib/init/template/multitenancy/files/package.sidecar.json.hbs +7 -7
- package/lib/init/template/multitenancy/files/values.yaml.hbs +19 -19
- package/lib/init/template/multitenancy/index.js +14 -16
- package/lib/init/template/nodejs/files/package.json.hbs +1 -1
- package/lib/init/template/nodejs/index.js +5 -8
- package/lib/init/template/redis-messaging/files/mta.yaml.hbs +5 -5
- package/lib/init/template/redis-messaging/files/package.json.hbs +9 -9
- package/lib/init/template/redis-messaging/index.js +4 -5
- package/lib/init/template/sample/files/app/_i18n/i18n.properties +43 -0
- package/lib/init/template/sample/files/app/_i18n/i18n_de.properties +14 -0
- package/lib/init/template/sample/files/app/admin-books/fiori-service.cds +114 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/Component.js +8 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/i18n/i18n.properties +11 -0
- package/lib/init/template/sample/files/app/admin-books/webapp/manifest.json +129 -0
- package/lib/init/template/sample/files/app/appconfig/fioriSandboxConfig.json +57 -0
- package/lib/init/template/sample/files/app/common.cds +263 -0
- package/lib/init/template/sample/files/app/index.html +30 -0
- package/lib/init/template/sample/files/app/services.cds +5 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +5 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books.csv +6 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Books_texts.csv +5 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Genres.csv +16 -0
- package/lib/init/template/sample/files/db/schema.cds +31 -0
- package/lib/init/template/sample/files/nodejs/admin-service.js +12 -0
- package/lib/init/template/sample/files/nodejs/cat-service.js +26 -0
- package/lib/init/template/sample/files/srv/admin-service.cds +5 -0
- package/lib/init/template/sample/files/srv/cat-service.cds +16 -0
- package/lib/init/template/sample/index.js +24 -0
- package/lib/init/template/sample-tiny/index.js +39 -0
- package/lib/init/template/samples/index.js +5 -56
- package/lib/init/template/sqlite/files/package.json.hbs +13 -13
- package/lib/init/template/sqlite/index.js +2 -2
- package/lib/init/template/templateBase.js +24 -1
- package/lib/init/template/toggles/files/package.json.hbs +10 -10
- package/lib/init/template/toggles/index.js +3 -3
- package/lib/init/template/typer/files/gitignore +1 -0
- package/lib/init/template/typer/files/package.json +8 -0
- package/lib/init/template/typer/files/xsconfig.json +9 -0
- package/lib/init/template/typer/index.js +36 -0
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +12 -12
- package/lib/init/template/xsuaa/files/package.json.hbs +13 -13
- package/lib/init/template/xsuaa/files/values.yaml.hbs +8 -8
- package/lib/init/template/xsuaa/index.js +8 -19
- package/lib/init/util/merge.js +73 -59
- package/lib/init/util/mvn.js +21 -17
- package/lib/init/util/projectReader.js +49 -87
- package/lib/init/util/xml.js +14 -23
- package/lib/util/cfUtil.js +366 -0
- package/lib/util/command.js +3 -3
- package/lib/util/gitUtil.js +55 -0
- package/lib/util/version.js +27 -0
- package/npm-shrinkwrap.json +337 -275
- package/package.json +6 -6
- package/CHANGELOG.md +0 -1460
- package/bin/build/all.js +0 -88
- package/bin/build/index.js +0 -82
- package/lib/compile/index.js +0 -14
- /package/lib/init/template/{samples → sample-tiny}/files/nodejs/db/data/my.bookshop-Books.csv +0 -0
- /package/lib/init/template/{samples → sample-tiny}/files/nodejs/db/data-model.cds +0 -0
- /package/lib/init/template/{samples → sample-tiny}/files/nodejs/srv/cat-service.cds.hbs +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const cds = require('../../cds')
|
|
4
|
+
const { DEFAULT_CSN_FILE_NAME, OUTPUT_MODE, OUTPUT_MODE_RESULT } = require('../constants')
|
|
5
|
+
const BuildTaskHandlerInternal = require('./buildTaskHandlerInternal')
|
|
6
|
+
|
|
7
|
+
class FeatureToggleBuilder extends BuildTaskHandlerInternal {
|
|
8
|
+
init() {
|
|
9
|
+
if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
|
|
10
|
+
this._result = {
|
|
11
|
+
dest: this.task.dest,
|
|
12
|
+
edmx: new Map(),
|
|
13
|
+
languages: new Set(),
|
|
14
|
+
services: new Set()
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get ftsName() {
|
|
20
|
+
return path.dirname(cds.env.features.folders || 'fts/*')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async compileAll(csn, destBase, destFts) {
|
|
24
|
+
const sources = await this._resolveSourcePaths(csn)
|
|
25
|
+
const dictionary = { base: null, features: null }
|
|
26
|
+
|
|
27
|
+
if (sources.features) {
|
|
28
|
+
// create base model as the given CSN is containing all features
|
|
29
|
+
dictionary.base = await cds.load(sources.base, this.options())
|
|
30
|
+
} else {
|
|
31
|
+
// CSN already represents the base model as no features exist
|
|
32
|
+
dictionary.base = csn
|
|
33
|
+
}
|
|
34
|
+
// preserve @location as @source properties
|
|
35
|
+
const csnStr = await this.compileToJson(dictionary.base, path.join(destBase, DEFAULT_CSN_FILE_NAME))
|
|
36
|
+
const csnModel = JSON.parse(csnStr)
|
|
37
|
+
csnModel.meta = csn.meta
|
|
38
|
+
if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
|
|
39
|
+
this._result.csn = csnModel
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (sources.features) {
|
|
43
|
+
dictionary.features = await this._compileFeatures(sources.features, destBase, destFts, dictionary.base)
|
|
44
|
+
}
|
|
45
|
+
return { dictionary, sources }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async collectAllLanguageBundles(dictionary, paths, destBase, destFts) {
|
|
49
|
+
const i18nFolder = cds.env.i18n.folders?.[0] || 'i18n'
|
|
50
|
+
// create language bundle for base model
|
|
51
|
+
const i18n = await this.collectLanguageBundles(dictionary.base, path.join(destBase, i18nFolder))
|
|
52
|
+
if (i18n && this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
|
|
53
|
+
this._result.languageBundles = i18n.bundles
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (dictionary.features) {
|
|
57
|
+
// create language bundles for all features
|
|
58
|
+
for (const ftName in dictionary.features) {
|
|
59
|
+
// attach the sources information for i18n location reference
|
|
60
|
+
dictionary.features[ftName]['$sources'] = paths.features[ftName]
|
|
61
|
+
await this.collectLanguageBundles(dictionary.features[ftName], path.join(destFts, this.ftsName, ftName, i18nFolder))
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async _resolveSourcePaths(csn) {
|
|
67
|
+
const regex = new RegExp(path.resolve(cds.root, this.ftsName).replace(/\\/g, '\\\\') + '[/|\\\\](?<ftName>[^/|\\\\]*)')
|
|
68
|
+
let paths = { base: [] }
|
|
69
|
+
|
|
70
|
+
// add ROOT source file paths for the base model
|
|
71
|
+
paths.base = this._resolveModel().reduce((acc, file) => {
|
|
72
|
+
const match = file.match(regex)
|
|
73
|
+
if (!match) {
|
|
74
|
+
acc.push(file)
|
|
75
|
+
}
|
|
76
|
+
return acc
|
|
77
|
+
}, [])
|
|
78
|
+
|
|
79
|
+
// keep existing behavior and return paths returned by cds.resolve if features are not supported by this project
|
|
80
|
+
if (!fs.existsSync(path.join(cds.root, this.ftsName))) {
|
|
81
|
+
return paths
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// add source file paths for the features
|
|
85
|
+
paths.features = csn['$sources'].reduce((acc, file) => {
|
|
86
|
+
const match = file.match(regex)
|
|
87
|
+
if (match) {
|
|
88
|
+
const { ftName } = match.groups
|
|
89
|
+
//feature
|
|
90
|
+
if (!acc[ftName]) {
|
|
91
|
+
acc[ftName] = []
|
|
92
|
+
}
|
|
93
|
+
acc[ftName].push(file)
|
|
94
|
+
}
|
|
95
|
+
return acc
|
|
96
|
+
}, {})
|
|
97
|
+
|
|
98
|
+
return paths
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async _compileFeatures(ftsPaths, destBase, destFts, baseCsn) {
|
|
102
|
+
if (!ftsPaths) {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
const features = {}
|
|
106
|
+
const options = { ...this.options(), flavor: 'parsed' }
|
|
107
|
+
|
|
108
|
+
// create feature models
|
|
109
|
+
for (const ftName in ftsPaths) {
|
|
110
|
+
const ftCsn = await cds.load(ftsPaths[ftName], options)
|
|
111
|
+
const ftPath = path.join(destFts, this.ftsName, ftName)
|
|
112
|
+
|
|
113
|
+
// replace require paths by base model path to ensure precedence of feature annotations
|
|
114
|
+
// see https://pages.github.tools.sap/cap/docs/cds/compiler-messages#anno-duplicate-unrelated-layer
|
|
115
|
+
ftCsn.requires = [path.join(path.relative(ftPath, destBase), DEFAULT_CSN_FILE_NAME).replace(/\\/g, '/')]
|
|
116
|
+
|
|
117
|
+
await this.compileToJson(ftCsn, path.join(ftPath, DEFAULT_CSN_FILE_NAME))
|
|
118
|
+
this._validateFeature(ftCsn, baseCsn)
|
|
119
|
+
features[ftName] = ftCsn
|
|
120
|
+
}
|
|
121
|
+
return features
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
_validateFeature(ftCsn, baseCsn) {
|
|
125
|
+
// features must not have other dependencies than base model dependencies - cross feature dependencies are not supported
|
|
126
|
+
// do not pass options.messages in order to avoid duplicate compiler messages
|
|
127
|
+
// version 2.13.9 of compileSources does not read the requires definition of parsed CSNs
|
|
128
|
+
cds.compiler.compileSources({ '../..csn.json': baseCsn, 'feature.csn': ftCsn }, this.options())
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
module.exports = FeatureToggleBuilder
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const cds = require('../../cds')
|
|
4
|
+
const BuildTaskHandler = require('../buildTaskHandler')
|
|
5
|
+
const { hasOptionValue } = require('../util')
|
|
6
|
+
const { FOLDER_GEN } = require('../constants')
|
|
7
|
+
|
|
8
|
+
class BuildTaskHandlerInternal extends BuildTaskHandler {
|
|
9
|
+
/**
|
|
10
|
+
* Returns the logger that has been passed the build task engine.
|
|
11
|
+
* @returns {object}
|
|
12
|
+
*/
|
|
13
|
+
get logger() {
|
|
14
|
+
//injected by framework
|
|
15
|
+
return this._logger;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Custom build handlers are executed before internal handlers in order
|
|
19
|
+
* ensure and content cannot be overwritten by mistake.
|
|
20
|
+
*/
|
|
21
|
+
get priority() {
|
|
22
|
+
return BuildTaskHandlerInternal.PRIORITY_MAX_VALUE
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async clean() {
|
|
26
|
+
// build results are deleted by the BuildTaskEngine if the build.target !== '.'
|
|
27
|
+
// make sure that src is not a subfolder of dest
|
|
28
|
+
if (cds.env.build.target === '.' && this.task.src !== this.task.dest && !this._isSubDirectory(this.task.dest, this.task.src)) {
|
|
29
|
+
await fs.promises.rm(this.task.dest, { force: true, recursive: true })
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Maximum allowed priority for internal build tasks.
|
|
34
|
+
*/
|
|
35
|
+
static get PRIORITY_MAX_VALUE() {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Minimum allowed priority for custom build tasks.
|
|
40
|
+
*/
|
|
41
|
+
static get PRIORITY_MIN_VALUE() {
|
|
42
|
+
return Number.MIN_SAFE_INTEGER;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Called by the framework after {@link #init()}. Handlers may want to perform more elaborate preparation.
|
|
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 buildOptions section.
|
|
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.
|
|
52
|
+
* @deprecated
|
|
53
|
+
*/
|
|
54
|
+
async prepare() {
|
|
55
|
+
// cancel subsequent prepare calls for other handlers of the same type by default
|
|
56
|
+
return false
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Returns whether cds env has a property with the specified value.
|
|
61
|
+
* If the value is omitted the existence of the given property name is checked.
|
|
62
|
+
* @param {string} qualifiedName
|
|
63
|
+
* @param {any=} value
|
|
64
|
+
*/
|
|
65
|
+
hasCdsEnvOption(qualifiedName, value) {
|
|
66
|
+
return hasOptionValue(cds.env.get(qualifiedName), value)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Determines whether the given build option value has been set for this build task.
|
|
71
|
+
* If the value is omitted, the existence of the given property name is checked.
|
|
72
|
+
* @param {string} qualifiedName
|
|
73
|
+
* @param {any=} value
|
|
74
|
+
*/
|
|
75
|
+
hasBuildOption(qualifiedName, value) {
|
|
76
|
+
return hasOptionValue(this._getBuildOption(qualifiedName), value)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Returns the value of the given build option defined for this build task.
|
|
81
|
+
* @param {string} qualifiedName
|
|
82
|
+
*/
|
|
83
|
+
getBuildOption(qualifiedName) {
|
|
84
|
+
return super._getBuildOption(qualifiedName)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Returns a list of CDS model files defining the transitive closure of the CDS model based on the model options
|
|
89
|
+
* defined for this build task.
|
|
90
|
+
*/
|
|
91
|
+
resolveModel() {
|
|
92
|
+
return this._resolveModel()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Returns whether the build results of this build plugin are created inplace
|
|
97
|
+
* or in a separate staging folder which is not part of the build tasks src folder.
|
|
98
|
+
*/
|
|
99
|
+
isStagingBuild() {
|
|
100
|
+
return !this.task.src.startsWith(this.task.dest)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async copyNativeContent(srcDir, destDir, customFilter) {
|
|
104
|
+
const files = BuildTaskHandlerInternal._find(srcDir, (src) => {
|
|
105
|
+
// do not copy files that:
|
|
106
|
+
// - from 'cds.env.build.target'
|
|
107
|
+
// - from 'dest'
|
|
108
|
+
// - from some generation folder
|
|
109
|
+
// - do not match filter function
|
|
110
|
+
return this._commonStagingBuildFilter(src, destDir) && (!customFilter || customFilter.call(this, src))
|
|
111
|
+
})
|
|
112
|
+
return Promise.all(
|
|
113
|
+
files.map((srcFile) => {
|
|
114
|
+
let relFile = path.relative(srcDir, srcFile)
|
|
115
|
+
let destFile = path.join(destDir, relFile)
|
|
116
|
+
return this.copy(srcFile).to(destFile)
|
|
117
|
+
})
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async compileToJson(model, csnFile) {
|
|
122
|
+
// This will als add a @source prop containing the relative path to the origin .cds source file
|
|
123
|
+
// and a parsed _where clause for @restrict.{grant,where} annotations.
|
|
124
|
+
// The @source annotation is required for correct custom handler resolution if no @impl annotation has been defined as
|
|
125
|
+
// custom service handler implementations are relative to the origin .cds source files.
|
|
126
|
+
// For staging builds (task.src !== task.dest) the csn.json file that is served at runtime is copied into a corresponding srv subfolder.
|
|
127
|
+
// As a consequence the src folder name has to be included in the @source file name while for inplace builds (task.src === task.dest) this is not the case.
|
|
128
|
+
// This ensures that the paths are relative to the cwd when executing cds run.
|
|
129
|
+
const jsonOptions = {
|
|
130
|
+
cwd: cds.root,
|
|
131
|
+
src: this.task.src
|
|
132
|
+
}
|
|
133
|
+
const csnStr = cds.compile.to.json(model, jsonOptions)
|
|
134
|
+
await this.write(csnStr).to(csnFile)
|
|
135
|
+
return csnStr
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Collect and write language bundles into a single i18n.json file.
|
|
140
|
+
* @param {Object} model
|
|
141
|
+
* @param {string} bundleDest
|
|
142
|
+
*/
|
|
143
|
+
async collectLanguageBundles(model, bundleDest) {
|
|
144
|
+
// collect effective i18n properties...
|
|
145
|
+
let bundles = {}
|
|
146
|
+
const bundleGenerator = cds.localize.bundles4(model)
|
|
147
|
+
if (bundleGenerator && bundleGenerator[Symbol.iterator]) {
|
|
148
|
+
for (let [locale, bundle] of bundleGenerator) {
|
|
149
|
+
// fallback bundle has the name ""
|
|
150
|
+
if (typeof locale === 'string') {
|
|
151
|
+
bundles[locale] = bundle
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// omit bundles in case the fallback bundle is the only existing entry
|
|
157
|
+
const keys = Object.keys(bundles)
|
|
158
|
+
if (keys.length === 1 && keys[0] === "" && Object.keys(bundles[keys[0]]).length === 0) {
|
|
159
|
+
bundles = {}
|
|
160
|
+
}
|
|
161
|
+
// copied from ../compile/i18n.js
|
|
162
|
+
const { file: base = 'i18n' } = cds.env.i18n
|
|
163
|
+
const file = path.join(bundleDest, base + '.json')
|
|
164
|
+
|
|
165
|
+
// bundleDest might be null
|
|
166
|
+
if (bundleDest && Object.keys(bundles).length > 0) {
|
|
167
|
+
await this.write(bundles).to(file)
|
|
168
|
+
return { file, bundles }
|
|
169
|
+
}
|
|
170
|
+
return null
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
_isSubDirectory(parent, child) {
|
|
174
|
+
return !path.relative(parent, child).startsWith('..')
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
_commonStagingBuildFilter(src, destDir) {
|
|
178
|
+
if (typeof src !== "string" || typeof destDir !== "string") {
|
|
179
|
+
return false
|
|
180
|
+
}
|
|
181
|
+
if (!fs.statSync(src).isDirectory()) {
|
|
182
|
+
return true //file
|
|
183
|
+
}
|
|
184
|
+
if (src === destDir) {
|
|
185
|
+
return false
|
|
186
|
+
}
|
|
187
|
+
const regex = new RegExp(FOLDER_GEN + "\\b")
|
|
188
|
+
if (src === path.resolve(cds.root, cds.env.build.target)) {
|
|
189
|
+
return false
|
|
190
|
+
}
|
|
191
|
+
return !regex.exec(path.basename(src))
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
static _find(srcDir, filter) {
|
|
195
|
+
const files = []
|
|
196
|
+
this._traverseFileSystem(srcDir, files, filter)
|
|
197
|
+
return files;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static _traverseFileSystem(srcDir, files, filter) {
|
|
201
|
+
let entries = []
|
|
202
|
+
try {
|
|
203
|
+
entries = fs.readdirSync(srcDir)
|
|
204
|
+
} catch (e) {
|
|
205
|
+
// ignore if not existing
|
|
206
|
+
}
|
|
207
|
+
entries.map(subDirEntry => path.join(srcDir, subDirEntry)).forEach((entry) => {
|
|
208
|
+
this._handleResource(entry, files, filter)
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
static _handleResource(entry, files, filter) {
|
|
213
|
+
if (!filter || filter.call(this, entry)) {
|
|
214
|
+
var stats = this._getResourceStatus(entry)
|
|
215
|
+
if (stats.isDirectory()) {
|
|
216
|
+
this._traverseFileSystem(entry, files, filter)
|
|
217
|
+
} else if (stats.isFile() || stats.isSymbolicLink()) {
|
|
218
|
+
files.push(entry)
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// for testing purposes
|
|
224
|
+
static _getResourceStatus(entry) {
|
|
225
|
+
return fs.lstatSync(entry)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
module.exports = BuildTaskHandlerInternal
|