@sap/cds-dk 9.6.0 → 9.6.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/CHANGELOG.md CHANGED
@@ -6,6 +6,20 @@ This project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/).
8
8
 
9
+ ## Version 9.6.1 - 2026-01-09
10
+
11
+ ### Changed
12
+
13
+ - All commands use colored logs in GitHub Actions workflows by default.
14
+
15
+ ### Fixed
16
+
17
+ - CVE-2025-15284: update `express` to fix vulnerability with `qs` <6.14.1.
18
+ - `cds watch` is more efficient on Linux with respect to `inotify` events. This fixes some crash and stall situations on Linux, especially in SAP Business Application Studio where resources are shared.
19
+ - `cds build --production` correctly includes `message.properties` from i18n files provided by CAP plugins.
20
+ - `cds add sample` fixes a warning about unused imports in _app/common.cds_.
21
+ - `cds init` fixes some rare argument parsing errors.
22
+
9
23
  ## Version 9.6.0 - 2025-12-16
10
24
 
11
25
  ### Added
package/bin/cds.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const path = require('node:path')
4
- const { sep } = { path }
4
+ const { sep } = path
5
5
  const fs = require('node:fs')
6
6
 
7
7
  const cli = {
@@ -1,5 +1,3 @@
1
- const path = require('path')
2
- const {colors} = require('../../lib/util/term')
3
1
 
4
2
  module.exports = Object.assign ( compile, {
5
3
  handleCompletion,
@@ -188,6 +186,8 @@ module.exports = Object.assign ( compile, {
188
186
 
189
187
  `})
190
188
 
189
+ const path = require('path')
190
+
191
191
  async function handleCompletion(currentWord, previousWord, argv, util) {
192
192
  const allOptionsFlags = [
193
193
  ...compile.options ?? [],
@@ -389,6 +389,7 @@ async function compile (models, options={}) {
389
389
  function consoleLog(o) {
390
390
  if (typeof o === 'string') return console.log (o)
391
391
  if (process.stdout.isTTY) {
392
+ const { enabled: colors } = require('../../lib').utils.colors
392
393
  o = inspect(o,{colors, depth: 111, compact:false}).replace(/\[Object: null prototype\] /g, '')
393
394
  } else
394
395
  o = JSON.stringify(o, null, 2)
@@ -152,10 +152,33 @@ class InternalBuildPlugin extends Plugin {
152
152
  // bundleDest might be null
153
153
  if (bundleDest && Object.keys(bundles).length > 0) {
154
154
  await this.write(bundles).to(file)
155
+ // also collect and write messages from plugins
156
+ await this.collectMessageBundles(bundleDest)
155
157
  return { file, bundles }
156
158
  }
157
159
  return null
158
160
  }
161
+
162
+ /**
163
+ * Collect and write message bundles from CAP plugins into messages.properties files.
164
+ * @param {string} bundleDest
165
+ */
166
+ async collectMessageBundles(bundleDest) {
167
+ const messageBundle = cds.i18n.bundle4('messages')
168
+ const messagesData = messageBundle.translations4?.(cds.env.i18n.languages) ?? {}
169
+
170
+ // Write messages.properties files for each locale
171
+ for (const [locale, messages] of Object.entries(messagesData)) {
172
+ if (Object.keys(messages).length > 0) {
173
+ const fileName = locale ? `messages_${locale}.properties` : 'messages.properties'
174
+ const filePath = path.join(bundleDest, fileName)
175
+ const content = Object.entries(messages)
176
+ .map(([key, value]) => `${key}=${value}`)
177
+ .join('\n') + '\n'
178
+ await this.write(content).to(filePath)
179
+ }
180
+ }
181
+ }
159
182
  }
160
183
 
161
184
  // Emits the 'compile.for.runtime' event, as the produced CSN is for runtime usage.
@@ -5,7 +5,7 @@ module.exports = {
5
5
  COMMAND_ADD: 'add',
6
6
 
7
7
  JAVA_LTS_VERSIONS: [17, 21],
8
- MAVEN_ARCHETYPE_VERSION: '4.6.0',
8
+ MAVEN_ARCHETYPE_VERSION: '4.6.1',
9
9
 
10
10
  OPTIONS: Object.freeze({
11
11
  COMPLETION: 'completion',
package/lib/init/index.js CHANGED
@@ -174,7 +174,8 @@ module.exports = class CDSGenerator {
174
174
  for (const plugin of sorted) {
175
175
  const Plugin = registered.get(plugin) ?? require('./template/' + plugin)
176
176
  const template = new Plugin()
177
- const inProduction = Plugin.hasInProduction(env4('production')) || cds.cli.argv[0]?.includes(plugin) || cds.cli.options.add?.has(plugin)
177
+ const added = cds.cli.command === 'add' && cds.cli.argv[0]?.split(',').includes(plugin) || cds.cli.options.add?.has(plugin)
178
+ const inProduction = Plugin.hasInProduction(env4('production')) || added
178
179
  DEBUG && console.log(inProduction ? '✅' : '❌', plugin)
179
180
  if (inProduction) await template.combine()
180
181
  }
@@ -76,7 +76,7 @@ module.exports = new class ProjectReader {
76
76
  const _isESM = () => pkgJson().type === 'module'
77
77
  const _isTypescript = () => !!pkgJson().dependencies?.typescript || !!pkgJson().devDependencies?.typescript
78
78
  const _hasTyper = () => !!pkgJson().dependencies?.['@cap-js/cds-typer'] || !!pkgJson().devDependencies?.['@cap-js/cds-typer']
79
- const _inProd = plugin => require(`./template/${plugin}`).hasInProduction(env) || cds.cli.argv[0]?.includes(plugin) || cds.cli.options.add?.has(plugin)
79
+ const _inProd = plugin => require(`./template/${plugin}`).hasInProduction(env) || cds.cli.command === 'add' && cds.cli.argv[0]?.split(',').includes(plugin) || cds.cli.options.add?.has(plugin)
80
80
  const _uiEmbedded = () => exists(join(env.folders.app, 'xs-app.json'))
81
81
  const _uiModule = () => !_uiEmbedded() && isdir(env.folders.app) && fs.readdirSync(resolve(cds.root, env.folders.app)).length > 0
82
82
  const _isJava = () => this.isJava
@@ -215,7 +215,7 @@ module.exports = new class ProjectReader {
215
215
  const facet = p.slice(prefix.length).replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase()
216
216
  const inProd = _inProd(facet)
217
217
  if (prefix === 'add') {
218
- const adding = facet => cds.cli.argv[0]?.includes(facet) || cds.cli.options.add?.has(facet)
218
+ const adding = plugin => cds.cli.command === 'add' && cds.cli.argv[0]?.split(',').includes(plugin) || cds.cli.options.add?.has(plugin)
219
219
  const caller = new Error().stack.split('\n')[3].replace(/\\/g, '/').match(/lib\/init\/template\/([^/]+)\/index\.js/)[1]
220
220
  return inProd && (adding(facet) || adding(caller))
221
221
  }
@@ -1,7 +1,7 @@
1
1
  const cds = require('../../../cds')
2
2
  const { exists } = cds.utils
3
- const { bold } = require('../../../util/term')
4
3
  const { readProject } = require('../../projectReader')
4
+ const { bold } = require('../../../util/term')
5
5
  const { merge, sort } = require('../../merge')
6
6
  const { mvn } = require('../../add')
7
7
 
@@ -226,7 +226,7 @@ annotate common.Currencies with @(UI : {
226
226
  //
227
227
  // Currencies Elements
228
228
  //
229
- annotate common.Currencies with {
229
+ annotate sap.common.Currencies with {
230
230
  numcode @title: '{i18n>NumCode}';
231
231
  minor @title: '{i18n>MinorUnit}';
232
232
  exponent @title: '{i18n>Exponent}';
package/lib/util/term.js CHANGED
@@ -34,7 +34,9 @@ const format = module.exports.format = (o, severity='Error', asInternalError=fal
34
34
  default : return format.info (o)
35
35
  }
36
36
  }
37
- format.colors = process.stdout.isTTY && process.stderr.isTTY && process.env.NO_COLOR !== 'true' || (process.env.FORCE_COLOR && process.env.FORCE_COLOR !== 'false')
37
+ const forceColor = process.env.FORCE_COLOR && process.env.FORCE_COLOR !== 'false'
38
+ const rendersColors = process.stdout.isTTY && process.stderr.isTTY || process.env.GITHUB_ACTIONS
39
+ format.colors = rendersColors && process.env.NO_COLOR !== 'true' || forceColor
38
40
 
39
41
  // decorate.error, .warning, .info
40
42
  // 'Error: foo' -> '[ERROR] foo' (Maven-like, allows for better grepping in logs)
@@ -5,10 +5,11 @@ const ws = require('ws')
5
5
  const express = require('express')
6
6
  const { URL } = require('url')
7
7
  const { relative, sep } = require ('path')
8
+ const escapedSep = sep === '\\' ? '\\\\' : sep
8
9
 
9
10
  const ext = 'css,gif,html,jpg,png,svg,ts,mjs,cjs,js,json,properties,change,variant,ctrl_variant,ctrl_variant_change,ctrl_variant_management_change'
10
11
  const watchIncludes = RegExp(`\\.(${ext.replace(/,/g,'|')})$|\\${sep}(webapp|appconfig)`)
11
- const watchExcludes = RegExp(`@cds-models\\${sep}|@types\\${sep}`)
12
+ const watchExcludes = new RegExp(`${escapedSep}(node_modules|\\.git|dist)(${escapedSep}|$)|@cds-models${escapedSep}|@types${escapedSep}`)
12
13
 
13
14
  module.exports = class LiveReload {
14
15
  async start(port, cwd, delay=0) {
@@ -83,14 +84,14 @@ module.exports = class LiveReload {
83
84
  })
84
85
 
85
86
  // Watching for touched files...
86
- const watch = require('node-watch')
87
+ const watch = require('./watcher')
87
88
  const filter = f => {
88
89
  const isIn = !watchExcludes.test(f) && watchIncludes.test(f)
89
90
  if (!isIn) DEBUG?. (`livereload ignored: ${relative(cwd||process.cwd(), f)}`)
90
91
  // else DEBUG?. (`livereload NOT ignored: ${relative(cwd||process.cwd(), f)}`, watchIncludes)
91
92
  return isIn
92
93
  }
93
- const watcher = watch (cwd||process.cwd(),{ recursive:true, filter, delay:0 })
94
+ const watcher = watch (cwd||process.cwd(),{ filter, ignore: watchExcludes })
94
95
  if (DEBUG) watcher.on('close', ()=> DEBUG('⚡️', 'cds watch - livereload file watcher closed'))
95
96
  watcher.on('change', _coalesceEvents(delay, (files) => {
96
97
  DEBUG?. (`livereload for: ${files.map(f => f.name)}`)
@@ -49,7 +49,7 @@ module.exports = ({ cwd = process.cwd(), script, ext, ignore=RegExp(), watched,
49
49
  process.on('shutdown', ()=> _kill(child))
50
50
 
51
51
  // Watching for touched files...
52
- const watch = require('node-watch')
52
+ const watch = require('./watcher')
53
53
  const include = RegExp(`\\.(${ext.replace(/,/g,'|')})$`)
54
54
  const filter = f => {
55
55
  const isIn = !ignore.test(f) && include.test(f)
@@ -57,7 +57,7 @@ module.exports = ({ cwd = process.cwd(), script, ext, ignore=RegExp(), watched,
57
57
  // else DEBUG?. (`NOT ignored: ${relative(cwd||process.cwd(), f)}`, include.test(f), include)
58
58
  return isIn
59
59
  }
60
- const watcher = watch (watched,{ recursive:true, filter, delay:0 })
60
+ const watcher = watch (watched,{ filter, ignore })
61
61
  if (DEBUG) watcher.on('close', ()=> DEBUG('⚡️', 'cds watch - file watcher closed'))
62
62
  watcher.on('change', restart)
63
63
  process.on('shutdown', ()=> watcher.close())
@@ -78,12 +78,9 @@ module.exports = ({ cwd = process.cwd(), script, ext, ignore=RegExp(), watched,
78
78
 
79
79
  emitter.restart = restart
80
80
  emitter.stop = () => _kill(child)
81
- emitter.setEnv = (name, value) => {
82
- if (typeof value === "undefined") {
83
- delete env[name]
84
- } else {
85
- env[name] // REVISIT: no value assigned ???
86
- }
81
+ emitter.setEnv = (name, value) => {
82
+ if (typeof value === 'undefined') delete env[name]
83
+ else env[name] = value
87
84
  }
88
85
  return emitter
89
86
  }
@@ -0,0 +1,136 @@
1
+ const fs = require('node:fs')
2
+ const { resolve, sep } = require('node:path')
3
+ const { EventEmitter } = require('node:events')
4
+
5
+ module.exports = function watch(paths, { filter, ignore } = {}) {
6
+ const ee = new EventEmitter()
7
+ const roots = [...new Set((Array.isArray(paths) ? paths : [paths]).filter(Boolean).map(p => resolve(p)))]
8
+ const ac = new AbortController() // eslint-disable-line no-undef
9
+ let closed = false
10
+
11
+ const _allow = p => !filter || (filter instanceof RegExp ? filter.test(p) : filter(p))
12
+
13
+ const useNativeRecursive = process.platform === 'darwin' || process.platform === 'win32'
14
+ if (useNativeRecursive) {
15
+ const _watch = async root => {
16
+ try {
17
+ if (!fs.existsSync(root)) return
18
+ const watcher = fs.promises.watch(root, { recursive: true, signal: ac.signal })
19
+ for await (const event of watcher) {
20
+ if (closed) break
21
+ const name = event.filename?.toString?.() ?? event.filename ?? ''
22
+ const fullPath = resolve(root, name)
23
+ if (_allow(fullPath)) {
24
+ ee.emit('change', fs.existsSync(fullPath) ? 'update' : 'remove', fullPath)
25
+ }
26
+ }
27
+ } catch (e) {
28
+ if (e.name !== 'AbortError') ee.emit('error', e)
29
+ }
30
+ }
31
+
32
+ roots.forEach(r => _watch(r).catch(e => ee.emit('error', e)))
33
+
34
+ ee.close = () => {
35
+ if (closed) return
36
+ closed = true
37
+ ac.abort()
38
+ ee.emit('close')
39
+ }
40
+
41
+ return ee
42
+ } else {
43
+ return _linuxCompat()
44
+ }
45
+
46
+ // On Linux, recursive watchers allocates OS watchers for the whole tree,
47
+ // so we avoid it to skip ignored dirs before allocating watchers.
48
+ function _linuxCompat() {
49
+ const watching = new Set()
50
+ const queued = new Set()
51
+ const queue = []
52
+ const active = new Set()
53
+ const max = 32
54
+
55
+ const _ignored = p => {
56
+ if (!ignore) return false
57
+ const test = ignore instanceof RegExp ? s => ignore.test(s) : ignore
58
+ return test(p) || test(p + sep) // allow trailing sep
59
+ }
60
+ const _enqueue = d => {
61
+ if (closed) return
62
+ const dir = resolve(d)
63
+ if (_ignored(dir)) return
64
+ if (watching.has(dir) || queued.has(dir)) return
65
+ queued.add(dir)
66
+ queue.push(dir)
67
+ _pump()
68
+ }
69
+ const _startWatch = dir => {
70
+ if (watching.has(dir)) return
71
+ watching.add(dir)
72
+ ;(async () => {
73
+ try {
74
+ if (!fs.existsSync(dir)) return
75
+ const watcher = fs.promises.watch(dir, { signal: ac.signal }) // non-recursive
76
+ for await (const event of watcher) {
77
+ if (closed) break
78
+ const name = event.filename?.toString?.() ?? event.filename ?? ''
79
+ const fullPath = name ? resolve(dir, name) : dir
80
+
81
+ // if a new dir appears, start watching it (unless ignored)
82
+ if (name && !_ignored(fullPath) && fs.existsSync(fullPath)) {
83
+ try {
84
+ if (fs.lstatSync(fullPath).isDirectory()) _enqueue(fullPath)
85
+ } catch { /* ignore */ }
86
+ }
87
+ if (_allow(fullPath)) {
88
+ ee.emit('change', fs.existsSync(fullPath) ? 'update' : 'remove', fullPath)
89
+ }
90
+ }
91
+ } catch (e) {
92
+ if (e.name !== 'AbortError' && !closed) ee.emit('error', e)
93
+ }
94
+ })().catch(e => ee.emit('error', e))
95
+ }
96
+
97
+ const _scan = async dir => {
98
+ _startWatch(dir)
99
+
100
+ let entries = []
101
+ try { entries = await fs.promises.readdir(dir, { withFileTypes: true }) }
102
+ catch { return }
103
+
104
+ for (const e of entries) {
105
+ if (e.isSymbolicLink?.()) continue
106
+ if (!e.isDirectory?.()) continue
107
+ const child = resolve(dir, e.name)
108
+ if (!_ignored(child)) _enqueue(child)
109
+ }
110
+ }
111
+
112
+ const _pump = () => {
113
+ while (!closed && queue.length && active.size < max) {
114
+ const dir = queue.shift()
115
+ queued.delete(dir)
116
+
117
+ const p = _scan(dir)
118
+ .catch(e => ee.emit('error', e))
119
+ .finally(() => {
120
+ active.delete(p)
121
+ _pump()
122
+ })
123
+
124
+ active.add(p)
125
+ }
126
+ }
127
+ roots.forEach(_enqueue)
128
+ ee.close = () => {
129
+ if (closed) return
130
+ closed = true
131
+ ac.abort()
132
+ ee.emit('close')
133
+ }
134
+ return ee
135
+ }
136
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@sap/cds-dk",
3
- "version": "9.6.0",
3
+ "version": "9.6.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@sap/cds-dk",
9
- "version": "9.6.0",
9
+ "version": "9.6.1",
10
10
  "license": "SEE LICENSE IN LICENSE",
11
11
  "dependencies": {
12
12
  "@cap-js/asyncapi": "^1.0.0",
@@ -15,11 +15,10 @@
15
15
  "@sap/cds-mtxs": ">=2",
16
16
  "@sap/hdi-deploy": "^5",
17
17
  "axios": "^1",
18
- "express": "^4.17.3",
18
+ "express": "^4.22.1",
19
19
  "hdb": "^2.0.0",
20
20
  "livereload-js": "^4.0.1",
21
21
  "mustache": "^4.0.1",
22
- "node-watch": ">=0.7",
23
22
  "ws": "^8.4.2",
24
23
  "xml-js": "^1.6.11",
25
24
  "yaml": "^2"
@@ -42,8 +41,8 @@
42
41
  }
43
42
  },
44
43
  "node_modules/@cap-js/db-service": {
45
- "version": "2.8.0",
46
- "integrity": "sha512-Ub+ywq2Nk5UmKH5pZnqZ7qC37DIRfF9IhOozjByhevjB/j7A6p9SpLkTwElSEMkhPSJnRYafILOGde1XH/wseQ==",
44
+ "version": "2.8.1",
45
+ "integrity": "sha512-p2MHv97d+yiUBJYSAI/qusZzdEtOVfv6GZH51mkfxNXLeOGpV1wjr6UhLDmZrt6h7gTfqJA6cR1WUrrVOq38Ag==",
47
46
  "devOptional": true,
48
47
  "license": "Apache-2.0",
49
48
  "dependencies": {
@@ -54,8 +53,8 @@
54
53
  }
55
54
  },
56
55
  "node_modules/@cap-js/openapi": {
57
- "version": "1.3.0",
58
- "integrity": "sha512-bLb7BadSA8cqcYJLXDgZ6lrDlk8SaAb2amSZY3pi9rd02yCJI3a2Z4a3F2HFXhX0C9ioC22IRd6Yf5mE0fDAfQ==",
56
+ "version": "1.3.1",
57
+ "integrity": "sha512-2QqqZlOxfvp/DDmGgTdwbBAAMjaPrrdPCbNC4+z6wjn2jXXk40j0XX7DHNnF4BU8R9LFxaUCHt2x8/9PzE83uA==",
59
58
  "license": "Apache-2.0",
60
59
  "dependencies": {
61
60
  "pluralize": "^8.0.0"
@@ -65,12 +64,12 @@
65
64
  }
66
65
  },
67
66
  "node_modules/@cap-js/sqlite": {
68
- "version": "2.1.1",
69
- "integrity": "sha512-6u4A3TQLbF5/of9JrtuNEva97wp5KOl6finhE4CaD4MgOp/uCVZFBb06wF3WYRF6ZhD8rMtgQ/PGv+sWfrLrVQ==",
67
+ "version": "2.1.2",
68
+ "integrity": "sha512-q8fQuIzwCfUF+l36BoL3LP32JYw389cmsZzE0Ec3JVz7k1sL+WzZ1XIbL1Ua/we3cHrDV+U3E9iAd0FOlcFumw==",
70
69
  "license": "Apache-2.0",
71
70
  "optional": true,
72
71
  "dependencies": {
73
- "@cap-js/db-service": "^2.8.0",
72
+ "@cap-js/db-service": "^2.8.1",
74
73
  "better-sqlite3": "^12.0.0"
75
74
  },
76
75
  "peerDependencies": {
@@ -90,8 +89,8 @@
90
89
  }
91
90
  },
92
91
  "node_modules/@sap/cds": {
93
- "version": "9.6.0",
94
- "integrity": "sha512-KZdAQZl8B2hvY71eh0FlXezTMuAsFILNgPZwqcT45ibAU4GSQB1eDc51jqA3t6UnpWN+jLSZDYNOagpztBkwJg==",
92
+ "version": "9.6.2",
93
+ "integrity": "sha512-BBn2k3fZFfOC8Qmgo/kC9Sjs7ClhtVjf480++LmY/vtthfuybnLA2g4SdisTbCBVePALN44JNA339wVfHCAPSw==",
95
94
  "license": "SEE LICENSE IN LICENSE",
96
95
  "dependencies": {
97
96
  "@sap/cds-compiler": "^6.3",
@@ -970,8 +969,8 @@
970
969
  }
971
970
  },
972
971
  "node_modules/hdb": {
973
- "version": "2.26.3",
974
- "integrity": "sha512-+fTSzgUZoThsQPlakxOYDYigkSAJfewr72y3cN8PLutGCugwym88A+7nV82+3bMYi/SaDB9JfIPPfi1Otv2iow==",
972
+ "version": "2.26.4",
973
+ "integrity": "sha512-v0uIr9mD9iw2Ws+H6+iLNO6W+uIqeXwt8Mwe1c0CZQOn1Sk631Uy4zgdz1wOz4IY3WgxdVjBAYWZ9AS8A/dLIQ==",
975
974
  "license": "Apache-2.0",
976
975
  "dependencies": {
977
976
  "iconv-lite": "0.7.0"
@@ -1263,14 +1262,6 @@
1263
1262
  "node": ">= 8.0.0"
1264
1263
  }
1265
1264
  },
1266
- "node_modules/node-watch": {
1267
- "version": "0.7.4",
1268
- "integrity": "sha512-RinNxoz4W1cep1b928fuFhvAQ5ag/+1UlMDV7rbyGthBIgsiEouS4kvRayvvboxii4m8eolKOIBo3OjDqbc+uQ==",
1269
- "license": "MIT",
1270
- "engines": {
1271
- "node": ">=6"
1272
- }
1273
- },
1274
1265
  "node_modules/object-inspect": {
1275
1266
  "version": "1.13.4",
1276
1267
  "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
@@ -1377,8 +1368,8 @@
1377
1368
  }
1378
1369
  },
1379
1370
  "node_modules/qs": {
1380
- "version": "6.14.0",
1381
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
1371
+ "version": "6.14.1",
1372
+ "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
1382
1373
  "license": "BSD-3-Clause",
1383
1374
  "dependencies": {
1384
1375
  "side-channel": "^1.1.0"
@@ -1466,9 +1457,12 @@
1466
1457
  "license": "MIT"
1467
1458
  },
1468
1459
  "node_modules/sax": {
1469
- "version": "1.4.3",
1470
- "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==",
1471
- "license": "BlueOak-1.0.0"
1460
+ "version": "1.4.4",
1461
+ "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==",
1462
+ "license": "BlueOak-1.0.0",
1463
+ "engines": {
1464
+ "node": ">=11.0.0"
1465
+ }
1472
1466
  },
1473
1467
  "node_modules/semver": {
1474
1468
  "version": "7.7.3",
@@ -1822,8 +1816,8 @@
1822
1816
  "optional": true
1823
1817
  },
1824
1818
  "node_modules/ws": {
1825
- "version": "8.18.3",
1826
- "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
1819
+ "version": "8.19.0",
1820
+ "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
1827
1821
  "license": "MIT",
1828
1822
  "engines": {
1829
1823
  "node": ">=10.0.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-dk",
3
- "version": "9.6.0",
3
+ "version": "9.6.1",
4
4
  "description": "Command line client and development toolkit for the SAP Cloud Application Programming Model",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "keywords": [
@@ -23,11 +23,10 @@
23
23
  "@sap/cds-mtxs": ">=2",
24
24
  "@sap/hdi-deploy": "^5",
25
25
  "axios": "^1",
26
- "express": "^4.17.3",
26
+ "express": "^4.22.1",
27
27
  "hdb": "^2.0.0",
28
28
  "livereload-js": "^4.0.1",
29
29
  "mustache": "^4.0.1",
30
- "node-watch": ">=0.7",
31
30
  "ws": "^8.4.2",
32
31
  "xml-js": "^1.6.11",
33
32
  "yaml": "^2"