@sap/cds-dk 4.4.2 → 4.5.4

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 (45) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/bin/activate.js +1 -2
  3. package/bin/deploy/index.js +3 -2
  4. package/bin/deploy/to-sqlite.js +2 -2
  5. package/bin/extend.js +2 -4
  6. package/bin/help.js +1 -1
  7. package/bin/import.js +105 -23
  8. package/bin/login.js +7 -8
  9. package/bin/logout.js +1 -2
  10. package/bin/repl.js +1 -1
  11. package/bin/watch.js +30 -11
  12. package/lib/client/activate.js +243 -0
  13. package/lib/client/auth_manager.js +115 -0
  14. package/lib/client/base_command.js +55 -0
  15. package/lib/client/extend.js +179 -0
  16. package/lib/client/helper/cf_helper.js +186 -0
  17. package/lib/client/helper/dependency_helper.js +26 -0
  18. package/lib/client/helper/env_helper.js +4 -0
  19. package/lib/client/helper/fs_helper.js +83 -0
  20. package/lib/client/helper/logging.js +37 -0
  21. package/lib/client/helper/question.js +50 -0
  22. package/lib/client/helper/string_helper.js +53 -0
  23. package/lib/client/helper/url_helper.js +17 -0
  24. package/lib/client/index.js +14 -0
  25. package/lib/client/params.js +435 -0
  26. package/lib/client/settings_manager.js +526 -0
  27. package/lib/import/common.js +24 -1
  28. package/lib/import/importapi.js +1 -1
  29. package/lib/import/index.js +25 -41
  30. package/lib/import/message.js +10 -6
  31. package/lib/import/v2parser.js +301 -47
  32. package/lib/import/v4parser.js +391 -71
  33. package/lib/init/constants.js +1 -1
  34. package/lib/init/index.js +15 -10
  35. package/lib/init/template/data/index.js +38 -46
  36. package/lib/init/template/hana/index.js +2 -2
  37. package/lib/init/template/lint/index.js +8 -6
  38. package/lib/init/template/mta/projectReader.js +8 -5
  39. package/lib/init/template/nodejs/files/.vscode/extensions.json +1 -1
  40. package/lib/init/template/nodejs/index.js +1 -8
  41. package/lib/lint/Linter.js +62 -60
  42. package/lib/lint/generators.js +1 -1
  43. package/lib/lint/io.js +9 -33
  44. package/npm-shrinkwrap.json +5179 -10848
  45. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -6,6 +6,66 @@ This project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
7
  The format is based on [Keep a Changelog](http://keepachangelog.com/).
8
8
 
9
+ ## Version 4.5.4 - 2021-10-07
10
+
11
+ ### Fixed
12
+
13
+ - `cds watch` no longer fails if started with `--ext`, `--livereload`, or `--open` arguments
14
+
15
+ ## Version 4.5.3 - 2021-10-05
16
+
17
+ ### Fixed
18
+
19
+ - `cds import` fix for `--dry` shortcut `-`
20
+ - `cds import` fix for missing type properties in csn for unbounded action and function in OData V4.
21
+ - A bug with `cds init` when called in BAS project wizard
22
+
23
+ ## Version 4.5.2 - 2021-09-30
24
+
25
+ ### Changed
26
+
27
+ - `cds init` uses latest `Maven Java archetype` version `1.19.0` for creating Java projects.
28
+
29
+ ### Fixed
30
+
31
+ - `cds deploy --to sqlite` now writes `credentials.database` again to `package.json`
32
+
33
+ ## Version 4.5.1 - 2021-09-29
34
+
35
+ ### Added
36
+
37
+ - `cds import` introduced option `--as` which converts EDMX file to different file formats such as cds, csn and json.
38
+ - `cds import` introduced flag `--f` which forcefully overwrite the content of existing cds file when specified with `--as` option.
39
+
40
+ ### Changed
41
+
42
+ - Marked `cds lint` as beta again to further investigate issues from 'extends' via prettier plugin.
43
+
44
+ ## Version 4.5.0 - 2021-09-23
45
+
46
+ ### Added
47
+
48
+ - `cds import` supports import of functions, action, functionimport and actionimport from both OData V2 and V4 EDMX files.
49
+
50
+ ### Changed
51
+
52
+ - `cds init` uses latest `Maven Java archetype` version `1.18.1` for creating Java projects.
53
+
54
+ ### Fixed
55
+
56
+ - `cds watch` additional CLI args were not passed to launched process, for example, `--odata x4`.
57
+ - `cds import` fix for TypeError issue during OData V4 EDMX conversion to CSN.
58
+ - `cds import` fix for multi-line documentation text in OData V2 EDMX file.
59
+ - `cds import` fix for V4 CSN generation when non standard OData vocabularies are referred.
60
+ - `cds add data`
61
+ + no longer fails for entities without keys
62
+ + no longer creates csv files for synthetic draft entities
63
+ + no longer creates entries for virtual fields
64
+ + no longer skips over entities marked with `@cds.persistence.skip`, which is true for 'external' entities created by `cds import`.
65
+ - `cds init --add` handles comma list correctly.
66
+ - `cds import` fix for multi-line documentation text in OData V4 EDMX file.
67
+
68
+
9
69
  ## Version 4.4.2 - 2021-09-03
10
70
 
11
71
  ### Fixed
package/bin/activate.js CHANGED
@@ -49,8 +49,7 @@ async function activate ([projectFolder], options = {}) {
49
49
 
50
50
  Object.assign(options, { projectFolder })
51
51
 
52
- const client = require('@sap/cds-sidecar-client')
53
- await client.apply(injection, options)
52
+ await require('../lib/client/activate').run(injection, options);
54
53
  }
55
54
 
56
55
 
@@ -71,7 +71,7 @@ async function deploy (_model, options) { // NOSONAR
71
71
 
72
72
  const conf = cds.env.requires.db || {}
73
73
  const [,_kind,_db] = /(\w+)?(?::(.*))?/.exec(url||'')
74
- const kind = _kind || conf.use || conf.kind
74
+ const kind = _kind || conf.dialect || conf.use || conf.kind
75
75
 
76
76
  try {
77
77
  var deployer = require ('./to-'+kind)
@@ -94,7 +94,7 @@ async function deploy (_model, options) { // NOSONAR
94
94
  }
95
95
 
96
96
 
97
- async function updata_package_json (kind, model='*', database) {
97
+ async function updata_package_json (kind, model, database) {
98
98
  const { fs, path, isfile } = cds.utils
99
99
  const { readFile, writeFile } = fs.promises
100
100
  const package_json = path.resolve ('package.json'), exists = isfile (package_json)
@@ -102,6 +102,7 @@ async function updata_package_json (kind, model='*', database) {
102
102
  const requires = ['cds','requires'] .reduce ((p,n)=>p[n] || (p[n]={}), conf)
103
103
  requires.db = cds.env.requires.db = { kind, model }
104
104
  if (database) requires.db.credentials = { database }
105
+ else if (kind === 'sqlite') requires.db.credentials = { database:'sqlite.db' }
105
106
  await writeFile (package_json, JSON.stringify(conf,null,' '))
106
107
  console.log (`/> ${ exists ? 'updated' : 'created' } ./package.json`)
107
108
  }
@@ -10,9 +10,9 @@ exports.deploy = function deploy_to_sqlite (_model, _db, options) {
10
10
  .then (db => db && db.disconnect()) // REVISIT: we should NOT require to disconnect explicitly
11
11
  }
12
12
 
13
- function _database4 (_db,_dbrl,conf) {
13
+ function _database4 (_db,_dbrl,conf) {
14
14
  if (_db) return _db
15
15
  if (_dbrl === 'sqlite') return 'sqlite.db'
16
16
  if (_dbrl === 'sql') return ':memory:'
17
- return conf.credentials && conf.credentials.database
17
+ if (conf.credentials) return conf.credentials.database || conf.credentials.url
18
18
  }
package/bin/extend.js CHANGED
@@ -49,17 +49,15 @@ module.exports = Object.assign(extend, {
49
49
 
50
50
 
51
51
  async function extend ([url], options = {}) {
52
- const client = require('@sap/cds-sidecar-client')
53
-
54
52
  if (options.force) {
55
- if (! await client.question.askBooleanQuestion('Using option --force will overwrite existing files. Continue (yN)? ', false, false)) {
53
+ if (! await require('../lib/client/helper/question').askBooleanQuestion('Using option --force will overwrite existing files. Continue (yN)? ', false, false)) {
56
54
  console.log('Extend cancelled')
57
55
  return
58
56
  }
59
57
  }
60
58
 
61
59
  Object.assign(options, { url })
62
- client.extend(options)
60
+ await require('../lib/client/extend').run(options);
63
61
  }
64
62
 
65
63
 
package/bin/help.js CHANGED
@@ -20,7 +20,7 @@ module.exports = exports = Object.assign (help, {help:`
20
20
  *d* | *deploy* deploy to databases or cloud
21
21
  *l* | *login* login to extendable SaaS application
22
22
  *x* | *extend* create extension project from SaaS application
23
- *t* | *lint* run linter for env or model checks
23
+ *t* | *lint* [beta] run linter for env or model checks
24
24
  *v* | *version* get detailed version information
25
25
  *?* | *help* get detailed usage information
26
26
 
package/bin/import.js CHANGED
@@ -1,9 +1,9 @@
1
1
 
2
2
  module.exports = Object.assign(_import, {
3
3
  _name: 'import',
4
- options: ['--out', '--into'],
5
- flags: ['--dry', '--no-copy', '--no-save', '--keep-namespace'],
6
- shortcuts: ['-o', '-in', '-'],
4
+ options: ['--out', '--into', '--as'],
5
+ flags: ['--dry', '--force', '--no-copy', '--no-save', '--keep-namespace'],
6
+ shortcuts: ['-o', '-in', '-as', '-', '-f'],
7
7
  help: `
8
8
  # SYNOPSIS
9
9
 
@@ -38,23 +38,39 @@ module.exports = Object.assign(_import, {
38
38
  *- | --dry*
39
39
  Writes the converted csn to stdout only.
40
40
 
41
+ *-as | --as <output_file_format>*
42
+ Converts the input edmx or xml file into one of these supported formats "cds", "csn", "json"
43
+
44
+ *-f | --force*
45
+ Forcefully overwrites the contents in the CDS file and updates the checksum
46
+
47
+
48
+
41
49
 
42
50
  # EXAMPLES
43
51
 
44
52
  cds import ~/Downloads/API_BUSINESS_PARTNER.edmx
45
53
  cds import - ~/Downloads/API_BUSINESS_PARTNER.edmx
54
+ cds import ~/Downloads/API_BUSINESS_PARTNER.edmx --as cds
46
55
 
47
56
  `})
48
57
  const cds = require('@sap/cds/lib')
49
- const { fs, path, write, mkdirp, exists } = cds.utils
58
+ const { fs, path, write, mkdirp, exists, read} = cds.utils
50
59
  const edm2csn = require('../lib/import')
60
+ const messages = require('../lib/import/message').getMessages();
61
+ const common = require('../lib/import/common');
62
+ const cdsCompiler = require('../lib/compile').compile.to;
63
+ const md5 = require('md5');
51
64
  let cwd;
52
- async function _import(file, { out, dry, into,
65
+ async function _import(file, { out, dry, into, as,
53
66
  'no-save': no_save,
54
67
  'no-copy': no_copy,
55
- 'keep-namespace': keep_namespace
68
+ 'keep-namespace': keep_namespace,
69
+ force
56
70
  } = {}) {
57
71
  cwd = into || process.cwd();
72
+ if (as && !common.supportedFormats().includes(as))
73
+ throw new Error(messages.INVALID_AS_OPTION);
58
74
  if (Array.isArray(file)) file = file[0]
59
75
  if (!file) return this.help('import')
60
76
  file = await edm2csn.isValidInputFile(path.resolve(cwd, file))
@@ -62,25 +78,94 @@ async function _import(file, { out, dry, into,
62
78
  const dst = path.join(external, path.basename(file))
63
79
  if (!dry && !no_copy) file = await _copy_to_srv_external(file, dst)
64
80
  const src = await edm2csn.getMetadataFromFile(file)
65
- const csn = await edm2csn.edmx2csn(src, !keep_namespace && file, this)
66
- if (out) out = edm2csn.validateAndComputeOutputFilePath(out);
67
- const written = dry || await _write(csn, out = out || dst.replace(/\.[^.]+$/, '.csn'))
68
- const registered = dry || no_save || await _update_package_json(out, csn, this.oDataVersion)
69
- if (dry) return console.log(JSON.stringify(csn, 0, ' '))
81
+ let csn = await edm2csn.edmx2csn(src, !keep_namespace && file, this)
82
+ const service = _service_name_from(csn);
83
+ if (out) out = edm2csn.validateAndComputeOutputFilePath(out, as);
84
+ const result = await _getResult(csn, service, as, out || dst.replace(/\.[^.]+$/, ''), force);
85
+ const written = dry || await _write(result[0], result[1], result[2]);
86
+ const registered = dry || no_save || await _update_package_json(result[1].replace(/\.[^.]+$/, ''), service, this.oDataVersion);
87
+ if (dry) return console.log(result[0]);
70
88
  return Promise.all([written, registered])
71
89
  }
72
90
 
73
- async function _write(csn, dest) {
74
- await edm2csn.saveCSNModel(JSON.stringify(csn, null, ' '), dest);
75
- const service = _service_name_from(csn)
76
- let using = `using { ${service} as external } from './${path.relative('srv', dest).replace(/\\/g, '/')}';`
77
- using = require('../lib/util/term').info(using)
78
- console.log(
79
- `[cds] - imported API to ${path.relative(cwd, dest)}
91
+ async function _generateChecksumValidate(dest, output, force) {
92
+ let fileResolved = await exists(dest);
93
+ if (fileResolved === false) {
94
+ let checksum = md5(output);
95
+ output = "/* checksum : " + checksum + " */\n" + output;
96
+ return output;
97
+ }
98
+ else {
99
+ let fileContent = await read(dest, "utf-8");
100
+ fileContent = String(fileContent);
101
+ if (fileContent.indexOf("checksum") === -1){
102
+ let checksum = md5(fileContent);
103
+ output = "/* checksum : " + checksum + " */\n" + output;
104
+ return output;
105
+ }
106
+ let fileChecksum = fileContent.substring(fileContent.indexOf("checksum") + 11, fileContent.indexOf(" */"));
107
+ let newFile = fileContent.substring(fileContent.indexOf('*/') + 3);
108
+ let checksum = md5(newFile);
109
+ if (fileChecksum === checksum) {
110
+ output = "/* checksum : " + checksum + " */\n" + output;
111
+ return output;
112
+ }
113
+ else {
114
+ if (force) {
115
+ output = "/* checksum : " + checksum + " */\n" + newFile;
116
+ return output;
117
+ }
118
+ else {
119
+ throw new Error(messages.FILE_MODIFIED);
120
+ }
121
+ }
122
+ }
123
+ }
124
+
125
+ async function _getResult(output, service, as, dest, force) {
126
+ let using, message, extension;
127
+ as = (as === "cds") ? "cdl" : as;
128
+
129
+ if (!common.supportedFormats().includes(extension = dest.substring(dest.lastIndexOf(".") + 1))) {
130
+ // dest doesn't have any file extension, so get it
131
+ extension = common.getSuffix(as);
132
+ }
133
+
134
+ dest = dest.replace('.' + extension, '');
135
+ using = `using { ${service} as external } from './${path.relative('srv', dest).replace(/\\/g, '/')}'`;
136
+ using = require('../lib/util/term').info(using);
137
+ message = `[cds] - imported API to ${path.relative(cwd, dest)}
80
138
  > use it in your CDS models through the like of:
81
139
 
82
140
  ${using}
83
- `) // Please keep the newline above! -> it's intentional
141
+ `;
142
+
143
+ dest += '.' + extension;
144
+
145
+ if (as && as != "csn" && as != "json") {
146
+ // cdsCompiler[as] will convert the csn output into various output formats
147
+ output = cdsCompiler[as](output);
148
+ }
149
+
150
+ switch(as) {
151
+ case "cdl":
152
+ output = await _generateChecksumValidate(dest, output, force);
153
+ break;
154
+ case undefined:
155
+ case "csn":
156
+ case "json":
157
+ output = JSON.stringify(output, null, ' ');
158
+ break;
159
+ default:
160
+ break;
161
+ }
162
+
163
+ return [output, dest, message];
164
+ }
165
+
166
+ async function _write(output, dest, message) {
167
+ await edm2csn.saveCSNModel(output, dest);
168
+ console.log(message);
84
169
  }
85
170
 
86
171
  async function _copy_to_srv_external(file, dst) {
@@ -100,14 +185,11 @@ function _service_name_from(csn) {
100
185
  }
101
186
  }
102
187
 
103
- async function _update_package_json(dest, csn, version) {
188
+ async function _update_package_json(dest, service, version) {
104
189
  const package_json = path.resolve(cwd, 'package.json')
105
190
  const conf = await exists(package_json) ? require(package_json) : {}
106
- const service = _service_name_from(csn)
107
191
  const requires = ['cds', 'requires'].reduce((p, n) => p[n] || (p[n] = {}), conf)
108
192
  if (!requires[service]) {
109
- if (dest.endsWith(".json")) dest = dest.replace(/\.json$/, '').replace(/\\/g, '/');
110
- else dest = dest.replace(/\.csn$/, '').replace(/\\/g, '/');
111
193
  const model = path.relative(cwd, dest)
112
194
  cds.env.requires[service] = requires[service] = { kind: (version === "V2") ? 'odata-v2' : 'odata', model }
113
195
  await write(package_json, JSON.stringify(conf, null, ' '))
package/bin/login.js CHANGED
@@ -5,9 +5,9 @@ module.exports = Object.assign(login, {
5
5
  shortcuts: ['-s', '-d', '-p', '-c'],
6
6
  flags: ['--plain'],
7
7
  get help() {
8
- const client = require('@sap/cds-sidecar-client')
9
- const cdsExtendAndCdsActivate = `${bold('cds extend')} and ${bold('cds activate')}`
10
- const keyring = client.config.keyringDesignation
8
+ const config = require('../lib/client/settings_manager').SettingsManager.config
9
+ const cdsExtendAndCdsActivate = `${bold('cds extend')} and ${bold('cds activate')}`
10
+ const keyring = config.keyringDesignation
11
11
  return `
12
12
  # SYNOPSIS
13
13
 
@@ -42,13 +42,13 @@ module.exports = Object.assign(login, {
42
42
 
43
43
  Authentication data for all logins is saved by <app-url> and <tenant-subdomain> in the
44
44
  desktop keyring (${keyring} on your platform) or, if requested, in config
45
- file ${client.config.paths.auth}.
45
+ file ${config.paths.auth}.
46
46
 
47
47
  To make use of keyring storage, the 'keytar' Node.js module must be installed.
48
48
  A corresponding hint will be given in case the module is not found.
49
49
 
50
50
  Project settings are saved by project directory in config file
51
- ${client.config.paths.settings}.
51
+ ${config.paths.settings}.
52
52
 
53
53
  Note that local storage of authentication data incurs a certain security risk:
54
54
  a malicious locally-running application might be able to perform any action with
@@ -96,7 +96,7 @@ module.exports = Object.assign(login, {
96
96
  # SEE ALSO
97
97
 
98
98
  *cds logout* to remove any authentication data
99
- `;
99
+ `
100
100
  }})
101
101
 
102
102
 
@@ -108,8 +108,7 @@ async function login ([url], options = {}) {
108
108
  })
109
109
  delete options.plain
110
110
 
111
- const client = require('@sap/cds-sidecar-client')
112
- client.login(options)
111
+ await require('../lib/client/auth_manager').loginAndUpdateSettings(options)
113
112
  }
114
113
 
115
114
 
package/bin/logout.js CHANGED
@@ -56,8 +56,7 @@ module.exports = Object.assign(logout, {
56
56
  async function logout ([projectFolder], options = {}) {
57
57
  Object.assign(options, { projectFolder })
58
58
 
59
- const client = require('@sap/cds-sidecar-client')
60
- client.logout(options)
59
+ await require('../lib/client/auth_manager').logout(options)
61
60
  }
62
61
 
63
62
 
package/bin/repl.js CHANGED
@@ -27,7 +27,7 @@ function repl (_, options={}) {
27
27
  const info = colors ? require('../lib/util/term').info : s => s
28
28
  log(info('Welcome to cds repl v'+ cds.version))
29
29
 
30
- const cdsr = require('repl').start ({...options, writer:_writer, ignoreUndefined:true })
30
+ const cdsr = cds.repl = require('repl').start ({...options, writer:_writer, ignoreUndefined:true })
31
31
 
32
32
  cds.lazify (Object.assign (cdsr.context,{ cds,
33
33
  Foo: lazy => new cds.entity ({name:'Foo'}),
package/bin/watch.js CHANGED
@@ -1,6 +1,7 @@
1
+ const watchOnlyOptions = ['--ext', '--livereload', '--open']
1
2
  module.exports = Object.assign ( watch, {
2
3
  flags: [ '--debug', '--in-memory', '--in-memory?' ],
3
- options: [ '--port', '--ext', '--livereload', '--open' ],
4
+ options: [ '--port', ...watchOnlyOptions ],
4
5
  help: `
5
6
  # SYNOPSIS
6
7
 
@@ -59,22 +60,27 @@ let ignore = /node_modules|\.cds-services\.json$/
59
60
  async function watch ([cwd], {
60
61
  args = ['serve', 'all', '--with-mocks'],
61
62
  ext = extDefaults,
62
- ...etc
63
+ ...options
63
64
  }={}) {
64
-
65
- args.push (`--${Object.keys(etc).find(a => /^in-memory\??$/.test(a)) || 'in-memory?'}`)
66
- const env = Object.assign (process.env, { _args: JSON.stringify(args) })
65
+ args.push (`--${Object.keys(options).find(a => /^in-memory\??$/.test(a)) || 'in-memory?'}`)
66
+ args.push (...process.argv.slice(3)
67
+ .filter(removeArgsIn(watchOnlyOptions)) // remove all watch-only options, as `cds serve` would not accept them
68
+ .filter(a => a !== cwd))
69
+
70
+ const env = Object.assign (process.env, {
71
+ _args: JSON.stringify(args),
72
+ _options: JSON.stringify(options)
73
+ })
67
74
  if (typeof ext !== 'string') ext = extDefaults
68
- if ('port' in etc) env.PORT = etc.port
69
75
  env.NODE_PATH = path.resolve (__dirname,'../node_modules') // allow global sqlite to be resolved
70
76
 
71
77
  let liveReload //= ...
72
78
  let firstTime = true
73
- if (!/false|no/.test(etc['livereload'])) {
79
+ if (!/false|no/.test(options['livereload'])) {
74
80
  ext += ',css,gif,html,jpg,png,svg'
75
81
  liveReload = new (require ('../lib/watch/livereload-server'))
76
82
  env.CDS_LIVERELOAD_PATH = require.resolve ('connect-livereload')
77
- env.CDS_LIVERELOAD_URL = await liveReload.start (etc['livereload'])
83
+ env.CDS_LIVERELOAD_URL = await liveReload.start (options['livereload'])
78
84
  .catch(err => { console.log(`Error starting live reload: ${err.message}`); liveReload = null })
79
85
  } else {
80
86
  ignore = RegExp(`app${path.sep}.*\\.(js|ts)|`+ignore.source) // exclude more frontend stuff
@@ -99,7 +105,7 @@ async function watch ([cwd], {
99
105
  watch: ['*','.env','.cdsrc.json'],
100
106
  script:__filename, cwd, env, ext, ignore,
101
107
  delay: parseInt(process.env.CDS_WATCH_DELAY) || 200,
102
- options: etc
108
+ options
103
109
  }).on('restart', (files)=>{
104
110
  DEBUG && DEBUG (files)
105
111
  if (liveReload) liveReload.markPending(files)
@@ -115,7 +121,7 @@ async function watch ([cwd], {
115
121
  case 'listening':
116
122
  env.PORT = (msg.address && msg.address.port) || msg.port
117
123
  liveReload && liveReload.reload()
118
- firstTime && etc['open'] && require('../lib/watch/open').openURL (etc['open'], env.PORT)
124
+ firstTime && options['open'] && require('../lib/watch/open').openURL (options['open'], env.PORT)
119
125
  firstTime = false
120
126
  break
121
127
  case 'EADDRINUSE': env.PORT = 0; _addr_in_use(msg); break
@@ -139,7 +145,20 @@ const FileHandlers = {
139
145
  },
140
146
  }
141
147
 
142
-
148
+ function removeArgsIn (toRemove) {
149
+ let argRemoved = false
150
+ return arg => { // filter function
151
+ if (toRemove.includes(arg)) {
152
+ argRemoved = true
153
+ return false
154
+ }
155
+ else if (argRemoved) { // if next arg is a value, skip it as well
156
+ argRemoved = false
157
+ if (!arg.startsWith('-')) return false
158
+ }
159
+ return true
160
+ }
161
+ }
143
162
 
144
163
  //
145
164
  // Child process impl launched by watch