@sap/cds-dk 7.1.1 → 7.2.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/build.js +3 -3
- package/bin/compile/index.js +5 -1
- package/bin/gen.js +27 -0
- package/bin/help.js +2 -1
- package/bin/watch.js +3 -4
- package/bin/watched.js +2 -3
- package/lib/bind/bindingUtil.js +1 -0
- package/lib/build/buildTaskEngine.js +12 -17
- package/lib/build/buildTaskFactory.js +23 -27
- package/lib/build/buildTaskHandler.js +2 -5
- package/lib/build/buildTaskProviderFactory.js +9 -12
- package/lib/build/constants.js +2 -1
- package/lib/build/index.js +1 -1
- package/lib/build/provider/buildTaskHandlerInternal.js +2 -2
- package/lib/build/provider/buildTaskProviderInternal.js +15 -25
- package/lib/build/provider/hana/index.js +14 -7
- package/lib/build/provider/nodejs/index.js +51 -18
- package/lib/build/util.js +11 -19
- package/lib/compile/openapi/csdl2openapi.js +30 -21
- package/lib/compile/openapi/index.js +7 -3
- package/lib/import/common.js +1 -1
- package/lib/init/constants.js +6 -11
- package/lib/init/index.js +84 -71
- package/lib/init/template/_merging/registry-mta.js +0 -12
- package/lib/init/template/approuter/files/mta.yaml.hbs +1 -1
- package/lib/init/template/approuter/index.js +7 -6
- 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/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/lint/index.js +3 -7
- 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/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 +3 -7
- package/lib/init/util/template.js +7 -6
- package/lib/watch/node-watch.js +6 -1
- package/npm-shrinkwrap.json +324 -307
- 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
package/bin/build.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module.exports = Object.assign(build, {
|
|
2
|
-
options: ['--project', '--src', '--dest', '--for', '--use', '--opts', '--log-level', '--options-model', '--clean'],
|
|
3
|
-
shortcuts: ['-in', '-s', '-o', '-4'],
|
|
2
|
+
options: ['--project', '--src', '--dest', '--for', '--workspaces', '--use', '--opts', '--log-level', '--options-model', '--clean'],
|
|
3
|
+
shortcuts: ['-in', '-s', '-o', '-4', '-ws'],
|
|
4
4
|
help: `
|
|
5
5
|
# SYNOPSIS
|
|
6
6
|
|
|
@@ -92,7 +92,7 @@ async function build([project], options = {}) {
|
|
|
92
92
|
// IMPORTANT: call plugins before subsequent access to cds.env
|
|
93
93
|
await cds.plugins
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
cds.root = path.resolve(process.cwd(), project || options.project || '.')
|
|
96
96
|
cds.env = cds.env.for('cds', cds.root);
|
|
97
97
|
delete options.project // avoid that relative project paths are resolved twice
|
|
98
98
|
|
package/bin/compile/index.js
CHANGED
|
@@ -2,7 +2,7 @@ const path = require("path");
|
|
|
2
2
|
|
|
3
3
|
module.exports = Object.assign ( compile, {
|
|
4
4
|
options: [
|
|
5
|
-
'--from', '--service', '--lang', '--for', '--to', '--dest', '--log-level', '--flavor', '--dialect', '--sql-dialect', '--openapi:url', '--openapi:servers'
|
|
5
|
+
'--from', '--service', '--lang', '--for', '--to', '--dest', '--log-level', '--flavor', '--dialect', '--sql-dialect', '--openapi:url', '--openapi:servers', '--odata-version'
|
|
6
6
|
],
|
|
7
7
|
shortcuts: [
|
|
8
8
|
undefined, '-s', '-l', '-4', '-2', '-o', undefined, '-f'
|
|
@@ -114,6 +114,10 @@ module.exports = Object.assign ( compile, {
|
|
|
114
114
|
The servers definition used in the generated OpenAPI document. *--openapi:url* is
|
|
115
115
|
ignored when this option is specified.
|
|
116
116
|
|
|
117
|
+
*--odata-version* 4.0|4.01
|
|
118
|
+
|
|
119
|
+
Adds the OData version's functionality of the input CDS/CSN file to the generated OpenAPI document.
|
|
120
|
+
|
|
117
121
|
*--openapi:diagram*
|
|
118
122
|
|
|
119
123
|
Include YUML diagram in the generated OpenAPI document, default: *false*.
|
package/bin/gen.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { join } = require('path')
|
|
2
|
+
const DEBUG = /\b(y|all|cli)\b/.test(process.env.DEBUG) ? console.debug : undefined
|
|
3
|
+
|
|
4
|
+
module.exports = require(global('@sap/cds-gen', 'bin/cds-gen'))
|
|
5
|
+
|
|
6
|
+
function global (id, subpath) {
|
|
7
|
+
const pkgPath = join(id, 'package.json') // package.json gives a stable entry path
|
|
8
|
+
let mod
|
|
9
|
+
try {
|
|
10
|
+
mod = require.resolve (pkgPath, { paths: [ process.cwd(), __dirname ] })
|
|
11
|
+
} catch (err) { // one more try w/ NPM global paths
|
|
12
|
+
const paths = [ process.cwd(), __dirname, npmGlobalModules() ]
|
|
13
|
+
try {
|
|
14
|
+
mod = require.resolve (pkgPath, { paths })
|
|
15
|
+
} catch (error) {
|
|
16
|
+
DEBUG?.(error)
|
|
17
|
+
throw `\nNo '${id}' package found. Install it with\n\n npm i -g ${id}\n`
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return join(mod, '..', subpath)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function npmGlobalModules() {
|
|
24
|
+
try {
|
|
25
|
+
return require ('child_process').execSync('npm root -g').toString().trim()
|
|
26
|
+
} catch (err) { DEBUG?.(err); return '' }
|
|
27
|
+
}
|
package/bin/help.js
CHANGED
|
@@ -10,6 +10,7 @@ module.exports = exports = Object.assign (help, {formatHelp, help:`
|
|
|
10
10
|
|
|
11
11
|
*i* | *init* jump-start cds-based projects
|
|
12
12
|
*a* | *add* add a feature to an existing project
|
|
13
|
+
* * | *gen* generate models/data using a descriptive prompt [beta]
|
|
13
14
|
*y* | *bind* bind application to remote services
|
|
14
15
|
*m* | *import* add models from external sources
|
|
15
16
|
*c* | *compile* compile cds models to different outputs
|
|
@@ -27,7 +28,7 @@ module.exports = exports = Object.assign (help, {formatHelp, help:`
|
|
|
27
28
|
* * | *logout* logout from extensible multitenant SaaS app
|
|
28
29
|
* * | *pull* pull base model of extensible SaaS app
|
|
29
30
|
* * | *push* push extension to extensible SaaS app
|
|
30
|
-
*t* | *lint*
|
|
31
|
+
*t* | *lint* run linter for env or model checks [beta]
|
|
31
32
|
*v* | *version* get detailed version information
|
|
32
33
|
*?* | *help* get detailed usage information
|
|
33
34
|
|
package/bin/watch.js
CHANGED
|
@@ -60,7 +60,7 @@ const t = module.exports.codes = {
|
|
|
60
60
|
}
|
|
61
61
|
const extDefaults = 'cds,csn,csv,ts,mjs,cjs,js,json,properties,edmx,xml,env'
|
|
62
62
|
const fioriIncludes = /_?(change|variant)$/ // according to fiori: change,variant,ctrl_variant,ctrl_variant_change,ctrl_variant_management_change.
|
|
63
|
-
|
|
63
|
+
const ignore = RegExp(`app${sep}.*${sep}?webapp${sep}|node_modules|target|\\.cds-services\\.json$`)
|
|
64
64
|
|
|
65
65
|
async function watch ([cwd], {
|
|
66
66
|
args = ['serve', 'all'],
|
|
@@ -99,8 +99,6 @@ async function watch ([cwd], {
|
|
|
99
99
|
env.CDS_LIVERELOAD_PATH = require.resolve ('../lib/watch/livereload-connect')
|
|
100
100
|
env.CDS_LIVERELOAD_URL = await liveReload.start (options['livereload'])
|
|
101
101
|
.catch(err => { console.log(`Error starting live reload: ${err.message}`); liveReload = null })
|
|
102
|
-
} else {
|
|
103
|
-
ignore = RegExp(`app${sep}.*\\.(js|ts)|`+ignore.source) // exclude more frontend stuff
|
|
104
102
|
}
|
|
105
103
|
|
|
106
104
|
const log = (first,...more) => console.log (t.yellow + (first||''), ...more, t.reset)
|
|
@@ -115,7 +113,8 @@ async function watch ([cwd], {
|
|
|
115
113
|
log ()
|
|
116
114
|
log (`${t.bold}cds ${args.join(' ')}`)
|
|
117
115
|
DEBUG && log (process.pid, 'watching:', ext, '...')
|
|
118
|
-
|
|
116
|
+
includes && DEBUG && log (`also watching: ${includes.source}`)
|
|
117
|
+
DEBUG && log ('ignoring:', ignore.source)
|
|
119
118
|
if (liveReload) log (`live reload enabled for browsers`)
|
|
120
119
|
|
|
121
120
|
const BindingManager = require('../lib/bind/bindingManager')
|
package/bin/watched.js
CHANGED
|
@@ -21,9 +21,8 @@
|
|
|
21
21
|
case 'NO_SERVICES_FOUND': return _no_services_found(e)
|
|
22
22
|
case 'MODEL_NOT_FOUND': return _no_models_found(e)
|
|
23
23
|
case 'EADDRINUSE': return process.send(e) //> tell cds watch
|
|
24
|
-
default: if (
|
|
25
|
-
|
|
26
|
-
}
|
|
24
|
+
default: if (e.messages?.length) return cds._log(e.messages, { 'log-level': cds.env.log.levels.cli }) // REVISIT: no special handling for compiler messages
|
|
25
|
+
else console.error('\n❗️ ERROR on server start: ❗️\n\n', e)
|
|
27
26
|
}}
|
|
28
27
|
|
|
29
28
|
function _no_models_found(e) { console.log (`
|
package/lib/bind/bindingUtil.js
CHANGED
|
@@ -5,7 +5,6 @@ const { sortMessagesSeverityAware, deduplicateMessages, CompilationError } = cds
|
|
|
5
5
|
const { relativePaths, BuildError, resolveRequiredSapModels } = require('./util')
|
|
6
6
|
const { SEVERITIES, LOG_LEVELS } = require('./constants')
|
|
7
7
|
const BuildTaskFactory = require('./buildTaskFactory')
|
|
8
|
-
const BuildTaskProviderFactory = require('./buildTaskProviderFactory')
|
|
9
8
|
const BuildTaskHandlerInternal = require('./provider/buildTaskHandlerInternal')
|
|
10
9
|
|
|
11
10
|
const COMPILATION_ERROR = 'CompilationError'
|
|
@@ -13,27 +12,26 @@ const COMPILE_MESSAGE = 'CompileMessage'
|
|
|
13
12
|
|
|
14
13
|
class BuildTaskEngine {
|
|
15
14
|
constructor(options) {
|
|
16
|
-
this.
|
|
15
|
+
this._taskFactory = new BuildTaskFactory(options)
|
|
17
16
|
}
|
|
18
|
-
get
|
|
19
|
-
return this.
|
|
17
|
+
get taskFactory() {
|
|
18
|
+
return this._taskFactory
|
|
20
19
|
}
|
|
21
20
|
get logger() {
|
|
22
|
-
return this.
|
|
21
|
+
return this.taskFactory.logger
|
|
23
22
|
}
|
|
24
|
-
get
|
|
25
|
-
return this.
|
|
23
|
+
get options() {
|
|
24
|
+
return this.taskFactory.options
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
async processTasks(tasks) {
|
|
29
28
|
const startTime = Date.now()
|
|
30
29
|
|
|
31
|
-
this.logger.log(`building project [${cds.root}], clean [${this.
|
|
30
|
+
this.logger.log(`building project [${cds.root}], clean [${this.options.clean}]`)
|
|
32
31
|
this.logger.log(`cds-dk [${require('../../package.json').version}], cds [${cds.version}], compiler [${cds.compiler.version()}], home [${cds.home}]\n`)
|
|
33
32
|
|
|
34
33
|
if (!tasks) {
|
|
35
|
-
|
|
36
|
-
tasks = await buildTaskFactory.getTasks()
|
|
34
|
+
tasks = await this.taskFactory.getTasks()
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
// validate required @sap namespace models - log only
|
|
@@ -51,9 +49,6 @@ class BuildTaskEngine {
|
|
|
51
49
|
}
|
|
52
50
|
})
|
|
53
51
|
|
|
54
|
-
// use resolved tasks
|
|
55
|
-
this.providerFactory.context.tasks = handlers.map(handler => handler.task)
|
|
56
|
-
|
|
57
52
|
try {
|
|
58
53
|
await this._executePrepare(handlers)
|
|
59
54
|
await this._executeCleanBuildTasks(handlers)
|
|
@@ -113,7 +108,7 @@ class BuildTaskEngine {
|
|
|
113
108
|
}
|
|
114
109
|
|
|
115
110
|
async _executeCleanBuildTasks(handlers) {
|
|
116
|
-
if (this.
|
|
111
|
+
if (this.options.clean) {
|
|
117
112
|
// clean entire build staging folder once
|
|
118
113
|
if (cds.env.build.target !== '.') {
|
|
119
114
|
const target = path.resolve(cds.root, cds.env.build.target)
|
|
@@ -208,7 +203,7 @@ class BuildTaskEngine {
|
|
|
208
203
|
}
|
|
209
204
|
|
|
210
205
|
_createHandler(task) {
|
|
211
|
-
const handler = this.
|
|
206
|
+
const handler = this.taskFactory.createHandler(task)
|
|
212
207
|
handler.init()
|
|
213
208
|
|
|
214
209
|
if (!(handler instanceof BuildTaskHandlerInternal) && handler.priority !== 1) {
|
|
@@ -318,7 +313,7 @@ class BuildTaskEngine {
|
|
|
318
313
|
/**
|
|
319
314
|
* Sort and filter the given errors of type CompileMessage or BuildMessage according to their severity and location,
|
|
320
315
|
* but leave any other errors untouched as part of the result array.<br>
|
|
321
|
-
* The log level
|
|
316
|
+
* The log level ('command line' or 'cds.env' option) is used to filter the given messages.
|
|
322
317
|
* @param {...Error} messages
|
|
323
318
|
*/
|
|
324
319
|
_sortMessagesUnique(...messages) {
|
|
@@ -337,7 +332,7 @@ class BuildTaskEngine {
|
|
|
337
332
|
* Return user defined log level or default value 'warn'
|
|
338
333
|
*/
|
|
339
334
|
_getLogLevel() {
|
|
340
|
-
return this.
|
|
335
|
+
return this.options["log-level"] || cds.env["log-level"]
|
|
341
336
|
}
|
|
342
337
|
}
|
|
343
338
|
module.exports = BuildTaskEngine
|
|
@@ -15,8 +15,8 @@ class BuildTaskFactory {
|
|
|
15
15
|
get logger() {
|
|
16
16
|
return this.providerFactory.logger
|
|
17
17
|
}
|
|
18
|
-
get
|
|
19
|
-
return this.providerFactory.
|
|
18
|
+
get options() {
|
|
19
|
+
return this.providerFactory.options
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// the following order for determining build tasks is used
|
|
@@ -41,12 +41,16 @@ class BuildTaskFactory {
|
|
|
41
41
|
|
|
42
42
|
// always resolve tasks for input validation
|
|
43
43
|
const resolvedTasks = this.providerFactory.resolveTasks(tasks)
|
|
44
|
-
if (this.
|
|
44
|
+
if (this.options.resolve) {
|
|
45
45
|
return resolvedTasks
|
|
46
46
|
}
|
|
47
47
|
return tasks
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
createHandler(task) {
|
|
51
|
+
return this.providerFactory.createHandler(task)
|
|
52
|
+
}
|
|
53
|
+
|
|
50
54
|
async _createTasks() {
|
|
51
55
|
this.logger.debug(`determining build tasks for project [${cds.root}].`)
|
|
52
56
|
|
|
@@ -148,24 +152,24 @@ class BuildTaskFactory {
|
|
|
148
152
|
}
|
|
149
153
|
|
|
150
154
|
_applyCliOptionsFilter(tasks) {
|
|
151
|
-
const
|
|
155
|
+
const options = this.options
|
|
152
156
|
// filter tasks using either option for, use, src
|
|
153
157
|
let resultTasks = tasks.filter(task => {
|
|
154
|
-
return (!
|
|
155
|
-
&& (!
|
|
156
|
-
&& (!
|
|
158
|
+
return (!options.use || options.use === task.use)
|
|
159
|
+
&& (!options.for || options.for === task.for)
|
|
160
|
+
&& (!options.src || options.src === task.src)
|
|
157
161
|
})
|
|
158
162
|
if (resultTasks.length === 0) {
|
|
159
|
-
if (
|
|
163
|
+
if (options.for || options.use) {
|
|
160
164
|
const task = {}
|
|
161
|
-
if ((
|
|
162
|
-
task.for =
|
|
165
|
+
if ((options.for)) {
|
|
166
|
+
task.for = options.for
|
|
163
167
|
}
|
|
164
|
-
if ((
|
|
165
|
-
task.use =
|
|
168
|
+
if ((options.use)) {
|
|
169
|
+
task.use = options.use
|
|
166
170
|
}
|
|
167
|
-
if (
|
|
168
|
-
task.src =
|
|
171
|
+
if (options.src) {
|
|
172
|
+
task.src = options.src
|
|
169
173
|
}
|
|
170
174
|
resultTasks.push(task)
|
|
171
175
|
}
|
|
@@ -180,14 +184,14 @@ class BuildTaskFactory {
|
|
|
180
184
|
}
|
|
181
185
|
|
|
182
186
|
_applyCliOptions(tasks) {
|
|
183
|
-
const
|
|
187
|
+
const options = this.options
|
|
184
188
|
// apply remaining cli options to filtered tasks
|
|
185
189
|
tasks.forEach(task => {
|
|
186
|
-
if (
|
|
187
|
-
task.dest =
|
|
190
|
+
if (options.dest) {
|
|
191
|
+
task.dest = options.dest
|
|
188
192
|
}
|
|
189
|
-
if (
|
|
190
|
-
const opts = BuildTaskFactory._scanTaskOptionParams(
|
|
193
|
+
if (options.opts) {
|
|
194
|
+
const opts = BuildTaskFactory._scanTaskOptionParams(options.opts)
|
|
191
195
|
task.options = task.options ? Object.assign(task.options, opts) : opts
|
|
192
196
|
}
|
|
193
197
|
})
|
|
@@ -237,14 +241,6 @@ class BuildTaskFactory {
|
|
|
237
241
|
return taskOptions
|
|
238
242
|
}
|
|
239
243
|
|
|
240
|
-
/**
|
|
241
|
-
* For valid paths remove trailing '/'. Otherwise return as is - important!!
|
|
242
|
-
* @param {*} dir
|
|
243
|
-
*/
|
|
244
|
-
static _normalizePath(dir) {
|
|
245
|
-
return typeof dir === "string" ? dir.replace(/\/$/, '') : dir
|
|
246
|
-
}
|
|
247
|
-
|
|
248
244
|
/**
|
|
249
245
|
* Determines the module folder from the past list that may represent files or folders w or w/o .cds file extension.
|
|
250
246
|
* @param {Array} filesOrFolders
|
|
@@ -3,7 +3,7 @@ const fs = require('fs').promises
|
|
|
3
3
|
const cds = require('../cds')
|
|
4
4
|
|
|
5
5
|
const { OUTPUT_MODE, OUTPUT_MODE_FILESYSTEM, SEVERITY_INFO, SEVERITY_WARNING, SEVERITY_ERROR, OVERRIDE_METHOD_MSG } = require('./constants')
|
|
6
|
-
const { hasOptionValue, getProperty, relativePaths,
|
|
6
|
+
const { hasOptionValue, getProperty, relativePaths, BuildMessage } = require('./util')
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The build task handler creates the build output for a dedicated build task. It is uniquely identified
|
|
@@ -155,10 +155,7 @@ class BuildTaskHandler {
|
|
|
155
155
|
dest = path.resolve(this.task.dest, dest)
|
|
156
156
|
}
|
|
157
157
|
this.pushFile(dest)
|
|
158
|
-
|
|
159
|
-
return fs.cp(src, dest, { recursive: true })
|
|
160
|
-
}
|
|
161
|
-
return copy(src, dest)
|
|
158
|
+
return fs.cp(src, dest, { recursive: true })
|
|
162
159
|
}
|
|
163
160
|
return dest
|
|
164
161
|
}
|
|
@@ -13,12 +13,12 @@ class BuildTaskProviderFactory {
|
|
|
13
13
|
options.clean = true
|
|
14
14
|
}
|
|
15
15
|
this._buildOptions = options
|
|
16
|
-
this._context = { options }
|
|
16
|
+
this._context = { options, tasks: [] } // resolved tasks
|
|
17
17
|
}
|
|
18
18
|
get logger() {
|
|
19
|
-
return this.
|
|
19
|
+
return this.options.logger
|
|
20
20
|
}
|
|
21
|
-
get
|
|
21
|
+
get options() {
|
|
22
22
|
return this._context.options
|
|
23
23
|
}
|
|
24
24
|
get context() {
|
|
@@ -83,6 +83,7 @@ class BuildTaskProviderFactory {
|
|
|
83
83
|
handler._task = resolvedTask
|
|
84
84
|
handler._logger = this.logger
|
|
85
85
|
handler._context = this.context
|
|
86
|
+
this.context.tasks.push(resolvedTask)
|
|
86
87
|
this.logger._debug && this.logger.debug(`created BuildTaskHandler [${resolvedTask.use}]`)
|
|
87
88
|
return handler
|
|
88
89
|
}
|
|
@@ -147,15 +148,11 @@ class BuildTaskProviderFactory {
|
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
_loadProviders() {
|
|
150
|
-
//
|
|
151
|
-
return [
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const provider = new clazz()
|
|
156
|
-
provider._logger = this.logger
|
|
157
|
-
provider._plugin = plugin
|
|
158
|
-
return provider
|
|
151
|
+
// DefaultBuildTaskProvider must be last entry
|
|
152
|
+
return [
|
|
153
|
+
new BuildTaskProviderInternal(this.logger),
|
|
154
|
+
new DefaultBuildTaskProvider()
|
|
155
|
+
]
|
|
159
156
|
}
|
|
160
157
|
}
|
|
161
158
|
|
package/lib/build/constants.js
CHANGED
|
@@ -33,8 +33,9 @@ exports.CONTENT_DEFAULT_ENV_JSON = "contentDefaultEnvJson" // copy default-
|
|
|
33
33
|
|
|
34
34
|
exports.CSV_FILE_DETECTION = "csvFileDetection" // detect CSV files based on CDS model location - ENABLED by default
|
|
35
35
|
exports.EXTENSION_POINT_VALIDATION = "extensionPointValidation" // validate extension point restrictions defined by the extended SaaS app - ENABLED by default
|
|
36
|
-
exports.DEFAULT_BUILT_IN_MODELS = "defaultBuiltInModels" // add @sap/cds* built-in models to build tasks - ENABLED by default
|
|
37
36
|
exports.MTX_SIDECAR_DB_VALIDATION = "mtxSidecarDbValidation" // validate consistency of app and sidecar db configuration - ENABLED by default
|
|
37
|
+
exports.CONTINUE_UNRESOLVED_SCHEMA_CHANGES = "continueUnresolvedSchemaChanges" // build doesn't fail if unresolved HANA schema changes are detected
|
|
38
|
+
exports.IGNORE_DEFAULT_MODELS = "ignoreDefaultModels" // do not add default models (@sap/cds-*, fts/*) to existing build task model options
|
|
38
39
|
|
|
39
40
|
exports.FOLDER_GEN = "gen"
|
|
40
41
|
exports.FILE_EXT_CDS = ".cds"
|
package/lib/build/index.js
CHANGED
|
@@ -20,7 +20,7 @@ async function build(options = {}) {
|
|
|
20
20
|
return await new BuildTaskEngine(options).processTasks()
|
|
21
21
|
} catch (e) {
|
|
22
22
|
if (e instanceof BuildError || e.constructor.name === 'CompilationError') {
|
|
23
|
-
cds._log(e.messages.length ?
|
|
23
|
+
cds._log(e.messages.length ? e.messages : e.message, { 'log-level': options['log-level'] || cds.env['log-level'] })
|
|
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
|
|
@@ -43,9 +43,9 @@ 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 handler type specific
|
|
48
|
+
* has to be stored in the handler type specific options section.
|
|
49
49
|
* @returns {Promise<boolean>} A value 'false' indicates that {@link #prepare()} will not be called for other instances
|
|
50
50
|
* of this handler type.
|
|
51
51
|
* True indicates that {@link #prepare()} will be called for other instances of this of this handler type.
|
|
@@ -1,12 +1,12 @@
|
|
|
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
11
|
class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
12
12
|
constructor(logger) {
|
|
@@ -49,8 +49,8 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
async _createTasks(tasks, addRequiredTasks) {
|
|
52
|
-
let db = typeof cds.env.folders.db === "string" ? [
|
|
53
|
-
let srv = typeof cds.env.folders.srv === "string" ? [
|
|
52
|
+
let db = typeof cds.env.folders.db === "string" ? [normalizePath(cds.env.folders.db)] : cds.env.folders.db
|
|
53
|
+
let srv = typeof cds.env.folders.srv === "string" ? [normalizePath(cds.env.folders.srv)] : cds.env.folders.srv
|
|
54
54
|
|
|
55
55
|
const dbOptions = {
|
|
56
56
|
model: []
|
|
@@ -269,16 +269,16 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
269
269
|
static _setDefaultSrcFolder(task) {
|
|
270
270
|
switch (task.for) {
|
|
271
271
|
case BUILD_TASK_HANA:
|
|
272
|
-
task.src = task.src ||
|
|
272
|
+
task.src = task.src || normalizePath(cds.env.folders.db)
|
|
273
273
|
break
|
|
274
274
|
case BUILD_TASK_JAVA:
|
|
275
275
|
case BUILD_TASK_JAVA_CF:
|
|
276
276
|
case BUILD_TASK_NODEJS:
|
|
277
277
|
case BUILD_TASK_NODE_CF:
|
|
278
|
-
task.src = task.src ||
|
|
278
|
+
task.src = task.src || normalizePath(cds.env.folders.srv)
|
|
279
279
|
break
|
|
280
280
|
case BUILD_TASK_FIORI:
|
|
281
|
-
task.src = task.src ||
|
|
281
|
+
task.src = task.src || normalizePath(cds.env.folders.app)
|
|
282
282
|
break
|
|
283
283
|
case BUILD_TASK_MTX_SIDECAR:
|
|
284
284
|
task.src = task.src || MTX_SIDECAR_FOLDER
|
|
@@ -288,7 +288,7 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
288
288
|
break
|
|
289
289
|
case BUILD_TASK_MTX:
|
|
290
290
|
// mtxs with nodejs, but without sidecar
|
|
291
|
-
task.src = task.src ||
|
|
291
|
+
task.src = task.src || normalizePath(cds.env.folders.srv)
|
|
292
292
|
break
|
|
293
293
|
default:
|
|
294
294
|
throw new Error(`Unknown build task '${task.use || task.for}'`)
|
|
@@ -300,29 +300,27 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
300
300
|
if (taskModelPaths && !Array.isArray(taskModelPaths)) {
|
|
301
301
|
taskModelPaths = [taskModelPaths]
|
|
302
302
|
}
|
|
303
|
+
const toggles = cds.env.features.folders
|
|
304
|
+
const allowList = new RegExp(`^@sap/cds${toggles ? '|^' + toggles.replace('*', '') : ''}`)
|
|
303
305
|
task.options = task.options || {}
|
|
304
306
|
let defaultModelPaths = []
|
|
305
|
-
// add default models to custom build tasks if this hasn't been disabled
|
|
306
307
|
if (taskModelPaths?.length) {
|
|
307
|
-
if (!hasOptionValue(task.options?.[
|
|
308
|
-
|
|
309
|
-
defaultModelPaths = getDefaultModelOptions().filter(p => p.match('@sap/cds'))
|
|
308
|
+
if (!hasOptionValue(task.options?.[IGNORE_DEFAULT_MODELS], true)) {
|
|
309
|
+
defaultModelPaths = getDefaultModelOptions().filter(p => p.match(allowList))
|
|
310
310
|
}
|
|
311
311
|
} else {
|
|
312
312
|
defaultModelPaths = getDefaultModelOptions()
|
|
313
313
|
defaultModelPaths.push(task.src)
|
|
314
|
-
if (hasOptionValue(task.options?.[
|
|
314
|
+
if (hasOptionValue(task.options?.[IGNORE_DEFAULT_MODELS], true)) {
|
|
315
315
|
// all default models except the built-in models
|
|
316
|
-
defaultModelPaths = defaultModelPaths.filter(p => !p.match(
|
|
316
|
+
defaultModelPaths = defaultModelPaths.filter(p => !p.match(allowList))
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
|
-
|
|
320
319
|
// REVISIT: filter nodejs bootstrap service models for Java - issues/12770#issuecomment-1805719
|
|
321
320
|
if (this._hasJavaNature()) {
|
|
322
321
|
defaultModelPaths = defaultModelPaths.filter(p => !NODEJS_MODEL_EXCLUDE_LIST.includes(p))
|
|
323
322
|
}
|
|
324
|
-
|
|
325
|
-
if (!taskModelPaths || defaultModelPaths.length) {
|
|
323
|
+
if (defaultModelPaths.length) {
|
|
326
324
|
task.options.model = [...new Set(taskModelPaths?.length ? taskModelPaths.concat(defaultModelPaths) : defaultModelPaths)]
|
|
327
325
|
}
|
|
328
326
|
}
|
|
@@ -340,14 +338,6 @@ Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/doc
|
|
|
340
338
|
return task.for ? task.for : task.use && task.use.substring(BUILD_TASK_PREFIX.length + 1)
|
|
341
339
|
}
|
|
342
340
|
|
|
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
341
|
/**
|
|
352
342
|
* Determines the module folder from the past list that may represent files or folders w or w/o .cds file extension.
|
|
353
343
|
* @param {Array} filesOrFolders
|
|
@@ -3,11 +3,11 @@ const path = require('path')
|
|
|
3
3
|
const cds = require('../../../cds')
|
|
4
4
|
const to_hdbmigration = require('./2migration')
|
|
5
5
|
const BuildTaskHandlerInternal = require('../buildTaskHandlerInternal')
|
|
6
|
-
const { BuildError, relativePaths } = require('../../util')
|
|
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 } = BuildTaskHandlerInternal
|
|
11
11
|
|
|
12
12
|
const DEFAULT_COMPILE_DEST_FOLDER = path.normalize("src/gen")
|
|
13
13
|
|
|
@@ -15,13 +15,11 @@ 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
25
|
class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
@@ -478,18 +476,27 @@ class HanaModuleBuilder extends BuildTaskHandlerInternal {
|
|
|
478
476
|
})
|
|
479
477
|
if (migrationTableFiles.length > 0) {
|
|
480
478
|
const parser = require('./migrationtable')
|
|
479
|
+
const resolutionMessages = []
|
|
481
480
|
|
|
482
481
|
await Promise.all(migrationTableFiles.map(async file => {
|
|
483
482
|
try {
|
|
484
483
|
const tableModel = await parser.read(file)
|
|
485
484
|
if (/^>>>>>/m.test(tableModel.migrations.toString())) {
|
|
486
485
|
// as this is not a build error, we do not abort cds build, instead only log as error
|
|
487
|
-
|
|
486
|
+
resolutionMessages.push(new BuildMessage(`Manual resolution required for file ${path.relative(cds.root, file)}. Check migration version content for further details.`))
|
|
488
487
|
}
|
|
489
488
|
} catch (e) {
|
|
490
|
-
throw new Error(`${path.relative(cds.root, file)}: ${e.toString()}
|
|
489
|
+
throw new Error(`${path.relative(cds.root, file)}: ${e.toString()}`)
|
|
491
490
|
}
|
|
492
491
|
}))
|
|
492
|
+
if (resolutionMessages.length) {
|
|
493
|
+
// REVISIT: undocumented, we may want to delete in future versions
|
|
494
|
+
if (!this.hasBuildOption(CONTINUE_UNRESOLVED_SCHEMA_CHANGES, true)) {
|
|
495
|
+
throw new BuildError('Current model changes require manual resolution', resolutionMessages)
|
|
496
|
+
}
|
|
497
|
+
// adding to the task's message list
|
|
498
|
+
resolutionMessages.forEach(m => this._messages.push(m))
|
|
499
|
+
}
|
|
493
500
|
}
|
|
494
501
|
}
|
|
495
502
|
|