@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.
Files changed (105) hide show
  1. package/bin/activate.js +2 -2
  2. package/bin/add.js +1 -1
  3. package/bin/build.js +6 -3
  4. package/bin/compile/index.js +9 -5
  5. package/bin/env.js +0 -3
  6. package/bin/extend.js +29 -3
  7. package/bin/import.js +7 -3
  8. package/bin/init.js +31 -37
  9. package/bin/push.js +10 -6
  10. package/bin/repl.js +23 -43
  11. package/bin/watch.js +5 -9
  12. package/lib/bind/bindingResolver.js +2 -1
  13. package/lib/bind/index.js +1 -1
  14. package/lib/build/{buildTaskHandler.js → buildPlugin.js} +40 -27
  15. package/lib/build/buildTaskEngine.js +75 -74
  16. package/lib/build/buildTaskFactory.js +39 -32
  17. package/lib/build/buildTaskProvider.js +24 -19
  18. package/lib/build/buildTaskProviderFactory.js +125 -58
  19. package/lib/build/constants.js +6 -4
  20. package/lib/build/index.js +7 -3
  21. package/lib/build/plugins.js +35 -0
  22. package/lib/build/provider/{buildTaskHandlerEdmx.js → edmxBuildPlugin.js} +11 -7
  23. package/lib/build/provider/{buildTaskHandlerFeatureToggles.js → featureToggleBuildPlugin.js} +5 -5
  24. package/lib/build/provider/fiori/index.js +5 -6
  25. package/lib/build/provider/hana/index.js +54 -30
  26. package/lib/build/provider/{buildTaskHandlerInternal.js → internalBuildPlugin.js} +14 -10
  27. package/lib/build/provider/{buildTaskProviderInternal.js → internalBuildTaskProvider.js} +27 -28
  28. package/lib/build/provider/java/index.js +30 -24
  29. package/lib/build/provider/mtx/index.js +4 -4
  30. package/lib/build/provider/mtx/resourcesTarBuilder.js +8 -8
  31. package/lib/build/provider/mtx-extension/index.js +17 -9
  32. package/lib/build/provider/mtx-sidecar/index.js +17 -11
  33. package/lib/build/provider/nodejs/index.js +14 -13
  34. package/lib/build/util.js +5 -0
  35. package/lib/client/auth_manager.js +6 -12
  36. package/lib/client/base_command.js +1 -1
  37. package/lib/client/download_legacy.js +43 -0
  38. package/lib/client/params.js +6 -0
  39. package/lib/client/push.js +41 -1
  40. package/lib/client/settings_manager.js +28 -17
  41. package/lib/compile/openapi/csdl2openapi.js +1 -1
  42. package/lib/env/schema.js +36 -0
  43. package/lib/env/schemas/cds-rc.json +101 -0
  44. package/lib/import/common.js +23 -10
  45. package/lib/import/importapi.js +2 -2
  46. package/lib/import/message.js +3 -1
  47. package/lib/import/odata/v4parser.js +23 -7
  48. package/lib/index.js +11 -0
  49. package/lib/init/constants.js +5 -2
  50. package/lib/init/index.js +2 -3
  51. package/lib/init/template/_merging/registry-mta.js +33 -0
  52. package/lib/init/template/approuter/files/mta.yaml.hbs +1 -1
  53. package/lib/init/template/approuter/index.js +9 -9
  54. package/lib/init/template/connectivity/index.js +5 -4
  55. package/lib/init/template/destination/index.js +2 -5
  56. package/lib/init/template/helm/subcharts/content-deployment/Chart.yaml +4 -4
  57. package/lib/init/template/helm/subcharts/content-deployment/templates/_helpers.tpl +4 -2
  58. package/lib/init/template/helm/subcharts/content-deployment/templates/job.yaml +4 -3
  59. package/lib/init/template/helm/subcharts/content-deployment/values.schema.json +9 -83
  60. package/lib/init/template/helm/subcharts/content-deployment/values.yaml +54 -15
  61. package/lib/init/template/helm/subcharts/service-instance/Chart.yaml +4 -4
  62. package/lib/init/template/helm/subcharts/service-instance/templates/serviceinstance.yaml +1 -1
  63. package/lib/init/template/helm/subcharts/service-instance/values.schema.json +0 -17
  64. package/lib/init/template/helm/subcharts/service-instance/values.yaml +28 -0
  65. package/lib/init/template/helm/subcharts/web-application/Chart.yaml +5 -5
  66. package/lib/init/template/helm/subcharts/web-application/templates/_api.tpl +60 -0
  67. package/lib/init/template/helm/subcharts/web-application/templates/_helpers.tpl +34 -73
  68. package/lib/init/template/helm/subcharts/web-application/templates/api-rule.yaml +4 -4
  69. package/lib/init/template/helm/subcharts/web-application/templates/deployment.yaml +96 -17
  70. package/lib/init/template/helm/subcharts/web-application/templates/network-policy.yaml +19 -3
  71. package/lib/init/template/helm/subcharts/web-application/templates/pod-disruption-budget.yaml +3 -3
  72. package/lib/init/template/helm/subcharts/web-application/templates/rbac.yaml +26 -0
  73. package/lib/init/template/helm/subcharts/web-application/templates/secret.yaml +1 -1
  74. package/lib/init/template/helm/subcharts/web-application/templates/service-account.yaml +1 -1
  75. package/lib/init/template/helm/subcharts/web-application/templates/service-binding.yaml +1 -1
  76. package/lib/init/template/helm/subcharts/web-application/templates/service.yaml +21 -3
  77. package/lib/init/template/helm/subcharts/web-application/templates/virtual-service.yaml +36 -0
  78. package/lib/init/template/helm/subcharts/web-application/values.schema.json +535 -142
  79. package/lib/init/template/helm/subcharts/web-application/values.yaml +168 -44
  80. package/lib/init/template/html5-repo/index.js +27 -3
  81. package/lib/init/template/mta/index.js +9 -3
  82. package/lib/init/template/nodejs/files/.vscode/launch.json +0 -3
  83. package/lib/init/template/notifications/files/mta.yaml.hbs +17 -0
  84. package/lib/init/template/notifications/files/notificationtypes.json.hbs +16 -0
  85. package/lib/init/template/notifications/files/package.json.hbs +14 -0
  86. package/lib/init/template/notifications/index.js +52 -0
  87. package/lib/init/template/postgres/files/mta.yaml.hbs +27 -0
  88. package/lib/init/template/postgres/files/package.json.hbs +5 -0
  89. package/lib/init/template/postgres/index.js +52 -0
  90. package/lib/init/util/projectReader.js +0 -1
  91. package/lib/util/pruneAxiosErrors.js +25 -8
  92. package/lib/util/term.js +1 -2
  93. package/lib/watch/livereload-server.js +38 -2
  94. package/lib/watch/node-watch.js +3 -2
  95. package/npm-shrinkwrap.json +334 -335
  96. package/package.json +2 -2
  97. package/lib/init/template/helm/subcharts/content-deployment/templating.md +0 -37
  98. package/lib/init/template/helm/subcharts/content-deployment/values-lint.yaml +0 -5
  99. package/lib/init/template/helm/subcharts/content-deployment/values.md +0 -1011
  100. package/lib/init/template/helm/subcharts/service-instance/templating.md +0 -18
  101. package/lib/init/template/helm/subcharts/service-instance/values-lint.yaml +0 -2
  102. package/lib/init/template/helm/subcharts/service-instance/values.md +0 -186
  103. package/lib/init/template/helm/subcharts/web-application/templating.md +0 -51
  104. package/lib/init/template/helm/subcharts/web-application/values-lint.yaml +0 -8
  105. 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("./constants")
5
- const BuildTaskProviderInternal = require('./provider/buildTaskProviderInternal')
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("Invalid build task definition - property 'for' and property 'use' missing")
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 BuildTaskHandler instance for the given build task.
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
- createHandler(task) {
78
- const BuildTaskHandlerClass = this.loadHandler(task)
79
- const resolvedTask = this.resolveTask(task)
80
- this.logger._debug && this.logger.debug(`loaded build task handler [${resolvedTask.use}]`)
81
-
82
- const handler = new BuildTaskHandlerClass()
83
- handler._task = resolvedTask
84
- handler._logger = this.logger
85
- handler._context = this.context
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 BuildTaskHandler [${resolvedTask.use}]`)
88
- return handler
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 task handler implementation for the given build task.
93
- * 'for' defines an alias for built-in handlers like 'hana', 'java', 'node', 'fiori' or 'mtx'.
94
- * 'use' defines the fully qualified module name of external build task handler implemenations.
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
- loadHandler(task) {
98
- let provider = this.providers.find(provider => provider.canHandleTask(task))
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.loadHandler(task)
104
- }
105
- catch (e) {
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.resolveTask(task))
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
- resolveTask(task) {
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
- async _lookupTasks(provider, tasks) {
143
- return provider.lookupTasks(tasks)
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 BuildTaskProviderInternal(this.logger),
154
- new DefaultBuildTaskProvider()
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
- canHandleTask(task) {
165
- return !!task.use
175
+ constructor(logger) {
176
+ super()
177
+ this._logger = logger
166
178
  }
167
- loadHandler(task) {
168
- if (!task.use) {
169
- throw new Error(`Invalid build task definition [${task.for}] - property 'use' missing`)
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
@@ -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 - build task specific
23
- exports.CONTENT_DEFAULT_CSN = "contentDefaultCsn" // create default CSN format flavor: "inferred" - build task specific
24
- exports.CONTENT_EDMX = "contentEdmx" // create EDMX for required languages - build task specific
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"
@@ -1,11 +1,10 @@
1
1
  const fs = require('fs')
2
2
  const cds = require('../cds')
3
3
  const BuildTaskEngine = require('./buildTaskEngine')
4
- const BuildTaskFactory = require('./buildTaskFactory')
5
- const BuildTaskHandler = require('./buildTaskHandler')
4
+ const BuildPlugin = require('./buildPlugin')
6
5
  const { BuildError } = require('./util')
7
6
 
8
- module.exports = { build, BuildTaskFactory, BuildTaskEngine, BuildTaskHandler, BuildError }
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 BuildTaskHandlerFeatureToggles = require('./buildTaskHandlerFeatureToggles')
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 BuildTaskHandlerEdmx extends BuildTaskHandlerFeatureToggles {
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, runtimes expect it
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
- return cds.service.protocols.protocol4(srv).startsWith('odata')
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 = BuildTaskHandlerEdmx
87
+ module.exports = EdmxBuildPlugin
@@ -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 BuildTaskHandlerInternal = require('./buildTaskHandlerInternal')
5
+ const InternalBuildPlugin = require('./internalBuildPlugin')
6
6
  const { getI18nDefaultFolder } = require('../util')
7
7
 
8
- class FeatureToggleBuilder extends BuildTaskHandlerInternal {
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({ '../..csn.json': baseCsn, 'feature.csn': ftCsn }, this.options())
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 = FeatureToggleBuilder
133
+ module.exports = FeatureToggleBuildPlugin
@@ -1,6 +1,6 @@
1
1
  const path = require('path')
2
2
  const cds = require('../../../cds')
3
- const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
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 FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
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 FioriAppModuleBuilder instances
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, null, edmxOptions)
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 = FioriAppModuleBuilder
167
+ module.exports = FioriBuildPlugin