@sap/cds-dk 7.2.0 → 7.3.1
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/add.js +1 -1
- package/bin/build.js +6 -3
- package/bin/compile/index.js +9 -5
- package/bin/env.js +0 -3
- package/bin/extend.js +29 -3
- package/bin/import.js +7 -3
- package/bin/init.js +31 -37
- package/bin/push.js +10 -6
- package/bin/repl.js +23 -43
- package/bin/watch.js +5 -9
- package/lib/bind/bindingResolver.js +2 -1
- package/lib/bind/index.js +1 -1
- package/lib/build/{buildTaskHandler.js → buildPlugin.js} +40 -27
- package/lib/build/buildTaskEngine.js +75 -74
- package/lib/build/buildTaskFactory.js +39 -32
- package/lib/build/buildTaskProvider.js +24 -19
- package/lib/build/buildTaskProviderFactory.js +125 -58
- package/lib/build/constants.js +6 -4
- package/lib/build/index.js +7 -3
- package/lib/build/plugins.js +35 -0
- package/lib/build/provider/{buildTaskHandlerEdmx.js → edmxBuildPlugin.js} +11 -7
- package/lib/build/provider/{buildTaskHandlerFeatureToggles.js → featureToggleBuildPlugin.js} +5 -5
- package/lib/build/provider/fiori/index.js +5 -6
- package/lib/build/provider/hana/index.js +54 -30
- package/lib/build/provider/{buildTaskHandlerInternal.js → internalBuildPlugin.js} +14 -10
- package/lib/build/provider/{buildTaskProviderInternal.js → internalBuildTaskProvider.js} +27 -28
- package/lib/build/provider/java/index.js +30 -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 +14 -13
- package/lib/build/util.js +5 -0
- package/lib/client/auth_manager.js +6 -12
- package/lib/client/base_command.js +1 -1
- package/lib/client/download_legacy.js +43 -0
- package/lib/client/params.js +6 -0
- package/lib/client/push.js +41 -1
- package/lib/client/settings_manager.js +28 -17
- package/lib/compile/openapi/csdl2openapi.js +1 -1
- package/lib/env/schema.js +36 -0
- package/lib/env/schemas/cds-rc.json +101 -0
- package/lib/import/common.js +23 -10
- 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 +11 -0
- package/lib/init/constants.js +5 -2
- package/lib/init/index.js +2 -3
- package/lib/init/template/_merging/registry-mta.js +33 -0
- package/lib/init/template/approuter/files/mta.yaml.hbs +1 -1
- package/lib/init/template/approuter/index.js +9 -9
- package/lib/init/template/connectivity/index.js +5 -4
- package/lib/init/template/destination/index.js +2 -5
- package/lib/init/template/helm/subcharts/content-deployment/Chart.yaml +4 -4
- package/lib/init/template/helm/subcharts/content-deployment/templates/_helpers.tpl +4 -2
- package/lib/init/template/helm/subcharts/content-deployment/templates/job.yaml +4 -3
- package/lib/init/template/helm/subcharts/content-deployment/values.schema.json +9 -83
- package/lib/init/template/helm/subcharts/content-deployment/values.yaml +54 -15
- package/lib/init/template/helm/subcharts/service-instance/Chart.yaml +4 -4
- package/lib/init/template/helm/subcharts/service-instance/templates/serviceinstance.yaml +1 -1
- package/lib/init/template/helm/subcharts/service-instance/values.schema.json +0 -17
- package/lib/init/template/helm/subcharts/service-instance/values.yaml +28 -0
- package/lib/init/template/helm/subcharts/web-application/Chart.yaml +5 -5
- package/lib/init/template/helm/subcharts/web-application/templates/_api.tpl +60 -0
- package/lib/init/template/helm/subcharts/web-application/templates/_helpers.tpl +34 -73
- 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 +96 -17
- package/lib/init/template/helm/subcharts/web-application/templates/network-policy.yaml +19 -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/rbac.yaml +26 -0
- package/lib/init/template/helm/subcharts/web-application/templates/secret.yaml +1 -1
- 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 +1 -1
- package/lib/init/template/helm/subcharts/web-application/templates/service.yaml +21 -3
- package/lib/init/template/helm/subcharts/web-application/templates/virtual-service.yaml +36 -0
- package/lib/init/template/helm/subcharts/web-application/values.schema.json +535 -142
- package/lib/init/template/helm/subcharts/web-application/values.yaml +168 -44
- package/lib/init/template/html5-repo/index.js +27 -3
- package/lib/init/template/mta/index.js +9 -3
- package/lib/init/template/nodejs/files/.vscode/launch.json +0 -3
- package/lib/init/template/notifications/files/mta.yaml.hbs +17 -0
- package/lib/init/template/notifications/files/notificationtypes.json.hbs +16 -0
- package/lib/init/template/notifications/files/package.json.hbs +14 -0
- package/lib/init/template/notifications/index.js +52 -0
- 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/util/projectReader.js +0 -1
- package/lib/util/pruneAxiosErrors.js +25 -8
- package/lib/util/term.js +1 -2
- package/lib/watch/livereload-server.js +38 -2
- package/lib/watch/node-watch.js +3 -2
- package/npm-shrinkwrap.json +334 -335
- package/package.json +2 -2
- package/lib/init/template/helm/subcharts/content-deployment/templating.md +0 -37
- package/lib/init/template/helm/subcharts/content-deployment/values-lint.yaml +0 -5
- package/lib/init/template/helm/subcharts/content-deployment/values.md +0 -1011
- package/lib/init/template/helm/subcharts/service-instance/templating.md +0 -18
- package/lib/init/template/helm/subcharts/service-instance/values-lint.yaml +0 -2
- package/lib/init/template/helm/subcharts/service-instance/values.md +0 -186
- package/lib/init/template/helm/subcharts/web-application/templating.md +0 -51
- package/lib/init/template/helm/subcharts/web-application/values-lint.yaml +0 -8
- package/lib/init/template/helm/subcharts/web-application/values.md +0 -1363
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const cds = require('../cds')
|
|
4
|
-
const { LOG_MODULE_NAMES, OUTPUT_MODE_FILESYSTEM } = require(
|
|
5
|
-
const
|
|
4
|
+
const { LOG_MODULE_NAMES, OUTPUT_MODE_FILESYSTEM, DEFAULT_SRC_FOLDER } = require('./constants')
|
|
5
|
+
const InternalBuildTaskProvider = require('./provider/internalBuildTaskProvider')
|
|
6
6
|
const BuildTaskProvider = require('./buildTaskProvider')
|
|
7
|
+
const { BuildError } = require('./util')
|
|
8
|
+
const BuildPlugin = require('./buildPlugin')
|
|
7
9
|
|
|
8
10
|
class BuildTaskProviderFactory {
|
|
9
11
|
constructor(options = {}) {
|
|
12
|
+
// REVISIT: Logger is never passed to BuildTaskProviderFactory except for tests
|
|
13
|
+
// -> tests shouldn't pollute library coding
|
|
14
|
+
// see cds-dk/test/bin/eval.test.js for a non-invasive solution (intercepting console.log)
|
|
10
15
|
options.logger = options.logger || cds.log(LOG_MODULE_NAMES)
|
|
11
16
|
options.outputMode = options.outputMode || OUTPUT_MODE_FILESYSTEM
|
|
12
17
|
if (options.clean === undefined) {
|
|
@@ -31,22 +36,16 @@ class BuildTaskProviderFactory {
|
|
|
31
36
|
return this._providers
|
|
32
37
|
}
|
|
33
38
|
|
|
39
|
+
getTask(key) {
|
|
40
|
+
return this._getProvider(key).getTask(key)
|
|
41
|
+
}
|
|
42
|
+
|
|
34
43
|
async applyTaskDefaults(tasks) {
|
|
35
|
-
return Promise.all(tasks.map(async task => {
|
|
44
|
+
return Promise.all(tasks.map(async (task) => {
|
|
36
45
|
if (!task.for && !task.use) {
|
|
37
|
-
throw new Error(
|
|
38
|
-
}
|
|
39
|
-
const provider = this.providers.find(provider => {
|
|
40
|
-
try {
|
|
41
|
-
return provider.canHandleTask(task)
|
|
42
|
-
} catch (e) {
|
|
43
|
-
this.logger.error(`Build task provider ${provider.constructor.name} returned error:\n` + e)
|
|
44
|
-
throw e
|
|
45
|
-
}
|
|
46
|
-
})
|
|
47
|
-
if (!provider) {
|
|
48
|
-
throw new Error(`No provider found for build task '${task.for || task.use}'`)
|
|
46
|
+
throw new Error(`Invalid build task definition - property 'for' and property 'use' missing`)
|
|
49
47
|
}
|
|
48
|
+
const provider = this._getProvider(task)
|
|
50
49
|
if (provider instanceof DefaultBuildTaskProvider) {
|
|
51
50
|
this.logger._debug && this.logger.debug(`No provider found for build task '${task.use}', using default provider`)
|
|
52
51
|
}
|
|
@@ -54,11 +53,11 @@ class BuildTaskProviderFactory {
|
|
|
54
53
|
}))
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
async lookupTasks(tasks = []) {
|
|
56
|
+
async lookupTasks(tasks = [], dependencies) {
|
|
58
57
|
for (let i = 0; i < this.providers.length; i++) {
|
|
59
58
|
const provider = this.providers[i]
|
|
60
59
|
const existingTasks = [...tasks]
|
|
61
|
-
await this._lookupTasks(provider, tasks)
|
|
60
|
+
await this._lookupTasks(provider, tasks, dependencies)
|
|
62
61
|
if (existingTasks.length < tasks.length) {
|
|
63
62
|
// apply defaults
|
|
64
63
|
const newTasks = tasks.filter(task => !existingTasks.includes(task))
|
|
@@ -70,46 +69,45 @@ class BuildTaskProviderFactory {
|
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
/**
|
|
73
|
-
* Create a
|
|
72
|
+
* Create a BuildPlugin instance for the given build task.
|
|
74
73
|
* The implementation is loaded based on the build task's 'for' or 'use' option.
|
|
75
74
|
* @param {*} task
|
|
76
75
|
*/
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
const resolvedTask = this.
|
|
80
|
-
this.logger._debug && this.logger.debug(`loaded build
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
76
|
+
createPlugin(task) {
|
|
77
|
+
const BuildPluginClass = this.getPluginClass(task)
|
|
78
|
+
const resolvedTask = this._resolveTask(task)
|
|
79
|
+
this.logger._debug && this.logger.debug(`loaded build plugin [${resolvedTask.use}]`)
|
|
80
|
+
|
|
81
|
+
const plugin = new BuildPluginClass()
|
|
82
|
+
if (!(plugin instanceof BuildPlugin)) {
|
|
83
|
+
throw new Error(`Invalid Build plugin type ${task.for}`)
|
|
84
|
+
}
|
|
85
|
+
plugin._task = resolvedTask
|
|
86
|
+
plugin._logger = this.logger
|
|
87
|
+
plugin._context = this.context
|
|
86
88
|
this.context.tasks.push(resolvedTask)
|
|
87
|
-
this.logger._debug && this.logger.debug(`created
|
|
88
|
-
return
|
|
89
|
+
this.logger._debug && this.logger.debug(`created build plugin [${resolvedTask.use}]`)
|
|
90
|
+
return plugin
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
/**
|
|
92
|
-
* Loads the build
|
|
93
|
-
* 'for' defines an alias for built-in
|
|
94
|
-
* 'use' defines the fully qualified module name of
|
|
94
|
+
* Loads the build plugin implementation for the given build task.
|
|
95
|
+
* 'for' defines an alias for built-in plugins like 'hana', 'java', 'node', 'fiori' or 'mtx'.
|
|
96
|
+
* 'use' defines the fully qualified module name of custom build plugins implementations.
|
|
95
97
|
* @param {object} task
|
|
96
98
|
*/
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (!provider) {
|
|
100
|
-
throw new Error(`No provider found for build task '${task.for || task.use}'`)
|
|
101
|
-
}
|
|
99
|
+
getPluginClass(task) {
|
|
100
|
+
const provider = this._getProvider(task)
|
|
102
101
|
try {
|
|
103
|
-
return provider.
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
this.logger.error(`Provider failed to load handler class - provider: ${provider.constructor.name}, task: ${task.for || task.use} :\n` + e)
|
|
102
|
+
return provider.getPluginClass(task)
|
|
103
|
+
} catch (e) {
|
|
104
|
+
this.logger.error(`Provider failed to load build plugin class - provider: ${provider.constructor.name}, task: ${task.for || task.use} :\n` + e)
|
|
107
105
|
throw e
|
|
108
106
|
}
|
|
109
107
|
}
|
|
110
108
|
|
|
111
109
|
resolveTasks(tasks) {
|
|
112
|
-
return tasks.map(task => this.
|
|
110
|
+
return tasks.map(task => this._resolveTask(task))
|
|
113
111
|
}
|
|
114
112
|
|
|
115
113
|
/**
|
|
@@ -117,10 +115,7 @@ class BuildTaskProviderFactory {
|
|
|
117
115
|
* The task is validated in order to ensure that 'src' refers to a valid folder and 'for' or 'use' reference can be required.
|
|
118
116
|
* @param {*} task
|
|
119
117
|
*/
|
|
120
|
-
|
|
121
|
-
// first validate handler implementation
|
|
122
|
-
this.loadHandler(task)
|
|
123
|
-
|
|
118
|
+
_resolveTask(task) {
|
|
124
119
|
// second validate src path
|
|
125
120
|
const resolvedTask = JSON.parse(JSON.stringify(task))
|
|
126
121
|
|
|
@@ -139,8 +134,23 @@ class BuildTaskProviderFactory {
|
|
|
139
134
|
return resolvedTask
|
|
140
135
|
}
|
|
141
136
|
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
_getProvider(key) {
|
|
138
|
+
const provider = this.providers.find(provider => {
|
|
139
|
+
try {
|
|
140
|
+
return provider.providesTask(key)
|
|
141
|
+
} catch (e) {
|
|
142
|
+
this.logger.error(`Build task provider ${provider.constructor.name} returned an error:\n` + e)
|
|
143
|
+
throw e
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
if (!provider) {
|
|
147
|
+
throw new BuildError(`No provider found for build task '${key.for || key.use}'. Ensure that all required dependencies have been added and 'npm install' has been executed.`)
|
|
148
|
+
}
|
|
149
|
+
return provider
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async _lookupTasks(provider, tasks, dependencies) {
|
|
153
|
+
return provider.lookupTasks(tasks, dependencies)
|
|
144
154
|
}
|
|
145
155
|
|
|
146
156
|
async _applyTaskDefaults(provider, tasks) {
|
|
@@ -150,8 +160,9 @@ class BuildTaskProviderFactory {
|
|
|
150
160
|
_loadProviders() {
|
|
151
161
|
// DefaultBuildTaskProvider must be last entry
|
|
152
162
|
return [
|
|
153
|
-
new
|
|
154
|
-
new
|
|
163
|
+
new InternalBuildTaskProvider(this.logger),
|
|
164
|
+
new PluginBuildTaskProvider(this.logger),
|
|
165
|
+
new DefaultBuildTaskProvider(this.logger)
|
|
155
166
|
]
|
|
156
167
|
}
|
|
157
168
|
}
|
|
@@ -161,19 +172,75 @@ class BuildTaskProviderFactory {
|
|
|
161
172
|
* Has to be the last entry in the providers list.
|
|
162
173
|
*/
|
|
163
174
|
class DefaultBuildTaskProvider extends BuildTaskProvider {
|
|
164
|
-
|
|
165
|
-
|
|
175
|
+
constructor(logger) {
|
|
176
|
+
super()
|
|
177
|
+
this._logger = logger
|
|
166
178
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
179
|
+
|
|
180
|
+
providesTask(key) {
|
|
181
|
+
return !!key.use
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
getPluginClass(task) {
|
|
171
185
|
try {
|
|
172
186
|
return require(require.resolve(task.use, { paths: [cds.root] }))
|
|
173
|
-
}
|
|
174
|
-
catch (e) {
|
|
187
|
+
} catch (e) {
|
|
175
188
|
throw new Error(`Build task could not be resolved - module [${task.use}] cannot be loaded:\n` + e)
|
|
176
189
|
}
|
|
177
190
|
}
|
|
178
191
|
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Default provider implementation handling fully qualified custom build task declarations.
|
|
195
|
+
*/
|
|
196
|
+
class PluginBuildTaskProvider extends BuildTaskProvider {
|
|
197
|
+
constructor(logger) {
|
|
198
|
+
super()
|
|
199
|
+
this._logger = logger
|
|
200
|
+
this._plugins = require('./plugins').getPlugins()
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
get plugins() {
|
|
204
|
+
return this._plugins
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
providesTask(key) {
|
|
208
|
+
return this.plugins.has(key.for)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
getPluginClass(task) {
|
|
212
|
+
return this.plugins.get(task.for).class
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async lookupTasks(tasks, dependencies) {
|
|
216
|
+
if (!dependencies) {
|
|
217
|
+
this.plugins.forEach(plugin => {
|
|
218
|
+
if (plugin.class?.hasTask()) {
|
|
219
|
+
const task = this.getTask({ for: plugin.id })
|
|
220
|
+
if (!task) {
|
|
221
|
+
throw new Error(`Build task '${plugin.id}' required for custom plugin '${plugin.impl}'`)
|
|
222
|
+
}
|
|
223
|
+
task.for = plugin.id
|
|
224
|
+
tasks.push(task)
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async applyTaskDefaults(task) {
|
|
231
|
+
const defaultTask = this.getTask(task)
|
|
232
|
+
const names = Object.getOwnPropertyNames(defaultTask)
|
|
233
|
+
names.forEach(name => {
|
|
234
|
+
task[name] ??= defaultTask[name]
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
getTask(key) {
|
|
239
|
+
const task = this.plugins.get(key.for).taskDefaults
|
|
240
|
+
task.for = key.for
|
|
241
|
+
task.src ??= DEFAULT_SRC_FOLDER
|
|
242
|
+
task.src = task.src.replace(/\/$/, '')
|
|
243
|
+
return task
|
|
244
|
+
}
|
|
245
|
+
}
|
|
179
246
|
module.exports = BuildTaskProviderFactory
|
package/lib/build/constants.js
CHANGED
|
@@ -3,6 +3,7 @@ exports.OUTPUT_MODE_NONE = 0x0
|
|
|
3
3
|
exports.OUTPUT_MODE_FILESYSTEM = 0x1
|
|
4
4
|
exports.OUTPUT_MODE_RESULT = 0x2
|
|
5
5
|
|
|
6
|
+
exports.DEFAULT_SRC_FOLDER = '.'
|
|
6
7
|
exports.BUILD_TASK_NPM_SCOPE = "@sap"
|
|
7
8
|
exports.BUILD_TASK_PREFIX = exports.BUILD_TASK_NPM_SCOPE + "/cds/build"
|
|
8
9
|
exports.BUILD_TASK_JAVA = "java"
|
|
@@ -19,9 +20,11 @@ exports.BUILD_TASKS = [this.BUILD_TASK_JAVA, this.BUILD_TASK_JAVA_CF, this.BUILD
|
|
|
19
20
|
exports.ODATA_VERSION_V2 = "v2"
|
|
20
21
|
exports.ODATA_VERSION_V4 = "v4"
|
|
21
22
|
|
|
22
|
-
exports.CONTENT_LANGUAGE_BUNDLES = "contentLanguageBundles" // create i18n.json language bundles
|
|
23
|
-
exports.CONTENT_DEFAULT_CSN = "contentDefaultCsn" // create default CSN format flavor: "inferred"
|
|
24
|
-
exports.
|
|
23
|
+
exports.CONTENT_LANGUAGE_BUNDLES = "contentLanguageBundles" // create i18n.json language bundles
|
|
24
|
+
exports.CONTENT_DEFAULT_CSN = "contentDefaultCsn" // create default CSN format flavor: "inferred"
|
|
25
|
+
exports.FLAVOR_LOCALIZED_EDMX = "flavorLocalizedEdmx" // create localized EDMX languages based on existing properties files
|
|
26
|
+
exports.CONTENT_EDMX = "contentEdmx" // create EDMX for required languages - ENABLED by default
|
|
27
|
+
exports.CONTENT_LOCALIZED_EDMX = "contentLocalizedEdmx" // create EDMX for required languages - ENABLED for Java by default
|
|
25
28
|
exports.CONTENT_PACKAGE_JSON = "contentPackageJson" // create package.json file if not existing, or modify existing package.json - ENABLED by default
|
|
26
29
|
exports.CONTENT_PACKAGELOCK_JSON = "contentPackageLockJson" // copy package-lock.json file if existing into deployment folder - ENABLED by default
|
|
27
30
|
exports.CONTENT_HDBTABLEDATA = "contentHdbtabledata" // create .hdbtabledata files for .csv files if not existing - ENABLED by default
|
|
@@ -56,4 +59,3 @@ exports.LOG_LEVEL_INFO = "info"
|
|
|
56
59
|
exports.LOG_LEVEL_DEBUG = "debug"
|
|
57
60
|
exports.LOG_LEVELS = [exports.LOG_LEVEL_ERROR, exports.LOG_LEVEL_WARN, exports.LOG_LEVEL_INFO, exports.LOG_LEVEL_DEBUG]
|
|
58
61
|
exports.LOG_MODULE_NAMES = "cds|build"
|
|
59
|
-
exports.OVERRIDE_METHOD_MSG = "Must override method"
|
package/lib/build/index.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const cds = require('../cds')
|
|
3
3
|
const BuildTaskEngine = require('./buildTaskEngine')
|
|
4
|
-
const
|
|
5
|
-
const BuildTaskHandler = require('./buildTaskHandler')
|
|
4
|
+
const BuildPlugin = require('./buildPlugin')
|
|
6
5
|
const { BuildError } = require('./util')
|
|
7
6
|
|
|
8
|
-
module.exports = { build,
|
|
7
|
+
module.exports = { build, register, BuildPlugin }
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Executes cds build in the directory defined by cds.root.
|
|
@@ -21,10 +20,15 @@ async function build(options = {}) {
|
|
|
21
20
|
} catch (e) {
|
|
22
21
|
if (e instanceof BuildError || e.constructor.name === 'CompilationError') {
|
|
23
22
|
cds._log(e.messages.length ? e.messages : e.message, { 'log-level': options['log-level'] || cds.env['log-level'] })
|
|
23
|
+
console.log('')
|
|
24
24
|
// CompilationError.message also includes the detail messages - do not log twice
|
|
25
25
|
const message = e.constructor.name === 'CompilationError' ? 'CDS compilation failed' : e.messages.length ? e.message : 'CDS build failed'
|
|
26
26
|
throw message
|
|
27
27
|
}
|
|
28
28
|
throw e
|
|
29
29
|
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function register(id, options) {
|
|
33
|
+
return require('./plugins').register(id, options)
|
|
30
34
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const cds = require('../cds')
|
|
2
|
+
|
|
3
|
+
module.exports = new (class BuildPlugins {
|
|
4
|
+
constructor() {
|
|
5
|
+
this._plugins = new Map()
|
|
6
|
+
}
|
|
7
|
+
getPlugins() {
|
|
8
|
+
return this._plugins
|
|
9
|
+
}
|
|
10
|
+
getPlugin(id) {
|
|
11
|
+
return this._plugins.get(id)
|
|
12
|
+
}
|
|
13
|
+
register(id, options) {
|
|
14
|
+
if (!id || !options?.impl) {
|
|
15
|
+
throw Error("Invalid build plugin parameter")
|
|
16
|
+
}
|
|
17
|
+
if (this._plugins.has(id)) {
|
|
18
|
+
throw Error(`Build plugin ${id} already registered`)
|
|
19
|
+
}
|
|
20
|
+
this._plugins.set(id, {
|
|
21
|
+
id,
|
|
22
|
+
class: this._loadPlugin(id, options.impl),
|
|
23
|
+
description: options.description,
|
|
24
|
+
taskDefaults: options.taskDefaults ?? {}
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
_loadPlugin(id, impl) {
|
|
28
|
+
try {
|
|
29
|
+
// project-local module is preferred - otherwise from our own dependencies
|
|
30
|
+
return require(require.resolve(impl, { paths: [cds.root, __dirname] }))
|
|
31
|
+
} catch (e) {
|
|
32
|
+
throw new Error(`Custom build plugin implementation '${impl}' for '${id}' cannot be loaded:\n` + e)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
})
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const cds = require('../../cds')
|
|
3
|
-
const
|
|
4
|
-
const { OUTPUT_MODE, OUTPUT_MODE_RESULT } = require('../constants')
|
|
3
|
+
const FeatureToggleBuildPlugin = require('./featureToggleBuildPlugin')
|
|
4
|
+
const { OUTPUT_MODE, OUTPUT_MODE_RESULT, FLAVOR_LOCALIZED_EDMX } = require('../constants')
|
|
5
5
|
|
|
6
|
-
class
|
|
6
|
+
class EdmxBuildPlugin extends FeatureToggleBuildPlugin {
|
|
7
7
|
async compileToEdmx(model, edmxDest, compileOptions = {}) { // NOSONAR
|
|
8
8
|
const promises = []
|
|
9
9
|
|
|
@@ -24,12 +24,12 @@ class BuildTaskHandlerEdmx extends BuildTaskHandlerFeatureToggles {
|
|
|
24
24
|
const result = cds.compile.to.edmx(model, options)
|
|
25
25
|
|
|
26
26
|
if (result) {
|
|
27
|
-
let langs = this.task.options.lang || cds.env.i18n.languages
|
|
27
|
+
let langs = compileOptions[FLAVOR_LOCALIZED_EDMX] === false ? [] : this.task.options.lang || cds.env.i18n.languages
|
|
28
28
|
if (langs.split) { // string to array
|
|
29
29
|
langs = langs.split(',')
|
|
30
30
|
}
|
|
31
31
|
if (langs.length > 0 && langs[0] !== 'all' && langs.indexOf('') < 0) {
|
|
32
|
-
langs.push('') // make sure fallback language is in,
|
|
32
|
+
langs.push('') // make sure fallback language is in, runtime expects it
|
|
33
33
|
}
|
|
34
34
|
for (let [content, key] of result) {
|
|
35
35
|
const serviceName = key.file ? key.file : key.name
|
|
@@ -51,7 +51,11 @@ class BuildTaskHandlerEdmx extends BuildTaskHandlerFeatureToggles {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
_isOdataProtocol(srv) {
|
|
54
|
-
|
|
54
|
+
let protocols = cds.service.protocols.protocol4(srv)
|
|
55
|
+
if (typeof protocols === "string") {
|
|
56
|
+
protocols = [protocols]
|
|
57
|
+
}
|
|
58
|
+
return protocols.some(p => p && p.startsWith('odata'))
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
_options4odata() {
|
|
@@ -80,4 +84,4 @@ class BuildTaskHandlerEdmx extends BuildTaskHandlerFeatureToggles {
|
|
|
80
84
|
return Promise.resolve()
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
|
-
module.exports =
|
|
87
|
+
module.exports = EdmxBuildPlugin
|
package/lib/build/provider/{buildTaskHandlerFeatureToggles.js → featureToggleBuildPlugin.js}
RENAMED
|
@@ -2,10 +2,10 @@ const fs = require('fs')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const cds = require('../../cds')
|
|
4
4
|
const { DEFAULT_CSN_FILE_NAME, OUTPUT_MODE, OUTPUT_MODE_RESULT } = require('../constants')
|
|
5
|
-
const
|
|
5
|
+
const InternalBuildPlugin = require('./internalBuildPlugin')
|
|
6
6
|
const { getI18nDefaultFolder } = require('../util')
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class FeatureToggleBuildPlugin extends InternalBuildPlugin {
|
|
9
9
|
init() {
|
|
10
10
|
if (this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_RESULT)) {
|
|
11
11
|
this._result = {
|
|
@@ -125,9 +125,9 @@ class FeatureToggleBuilder extends BuildTaskHandlerInternal {
|
|
|
125
125
|
_validateFeature(ftCsn, baseCsn) {
|
|
126
126
|
// features must not have other dependencies than base model dependencies - cross feature dependencies are not supported
|
|
127
127
|
// do not pass options.messages in order to avoid duplicate compiler messages
|
|
128
|
-
// version 2.13.9 of compileSources does not read the requires definition of parsed CSNs
|
|
129
|
-
cds.compiler.compileSources({
|
|
128
|
+
// version 2.13.9 of compileSources does not read the 'requires' definition of parsed CSNs
|
|
129
|
+
cds.compiler.compileSources({ [ftCsn.requires[0]]: baseCsn, 'feature.csn': ftCsn }, this.options())
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
module.exports =
|
|
133
|
+
module.exports = FeatureToggleBuildPlugin
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const cds = require('../../../cds')
|
|
3
|
-
const
|
|
3
|
+
const EdmxBuildPlugin = require('../edmxBuildPlugin')
|
|
4
4
|
const URL = require('url')
|
|
5
5
|
const { getProperty, relativePaths } = require('../../util')
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ const { OUTPUT_MODE, OUTPUT_MODE_RESULT, BUILD_TASK_FIORI, CDS_CONFIG_PATH_SEP,
|
|
|
11
11
|
* For SAP Web IDE Full-Stack compatibility a corresponding metadata.xml is still generated.
|
|
12
12
|
* Though, 'fiori' build tasks can still be configured for UI5 mock server usage - see https://github.wdf.sap.corp/cap/issues/issues/8673
|
|
13
13
|
*/
|
|
14
|
-
class
|
|
14
|
+
class FioriBuildPlugin extends EdmxBuildPlugin {
|
|
15
15
|
init() {
|
|
16
16
|
// enforce
|
|
17
17
|
this._result = {
|
|
@@ -26,7 +26,7 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
26
26
|
this.context.for = this.context.for || {}
|
|
27
27
|
this.context.for[BUILD_TASK_FIORI] = this.context.for[BUILD_TASK_FIORI] || {}
|
|
28
28
|
|
|
29
|
-
// cache for later use across multiple
|
|
29
|
+
// cache for later use across multiple FioriBuildPlugin instances
|
|
30
30
|
const fioriBuildOptions = this.context.for[BUILD_TASK_FIORI]
|
|
31
31
|
fioriBuildOptions.appModel = new Map()
|
|
32
32
|
fioriBuildOptions.appEdmx = new Map()
|
|
@@ -57,7 +57,6 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
57
57
|
this.context.options[OUTPUT_MODE] |= OUTPUT_MODE_RESULT
|
|
58
58
|
|
|
59
59
|
try {
|
|
60
|
-
const edmxOptions = { version: cds.env.odata?.version }
|
|
61
60
|
for (let [appFolder, appModelGroup] of appModelGroups.entries()) {
|
|
62
61
|
this.logger.debug(`building module [${appFolder}] using [${this.constructor.name}]`)
|
|
63
62
|
const modelPaths = cds.resolve(Array.from(appModelGroup.values()))
|
|
@@ -71,7 +70,7 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
71
70
|
const model = await cds.load(modelPaths, options)
|
|
72
71
|
fioriBuildOptions.appModel.set(appFolder, model)
|
|
73
72
|
|
|
74
|
-
await this.compileToEdmx(model
|
|
73
|
+
await this.compileToEdmx(model)
|
|
75
74
|
|
|
76
75
|
// cache edmx per fiori app root folder
|
|
77
76
|
fioriBuildOptions.appEdmx.set(appFolder, this._result.edmx)
|
|
@@ -165,4 +164,4 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
165
164
|
}
|
|
166
165
|
}
|
|
167
166
|
|
|
168
|
-
module.exports =
|
|
167
|
+
module.exports = FioriBuildPlugin
|