@sap/cds-dk 8.6.0 → 8.7.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/bin/cds.js +1 -1
  3. package/bin/debug.js +122 -26
  4. package/bin/deploy/index.js +7 -0
  5. package/bin/import.js +54 -29
  6. package/bin/repl.js +2 -2
  7. package/bin/util/fuzzySearch.js +10 -10
  8. package/bin/watch.js +46 -16
  9. package/lib/build/buildTaskProviderFactory.js +8 -5
  10. package/lib/build/plugins/helm/files/subcharts/content-deployment/Chart.yaml +1 -1
  11. package/lib/build/plugins/helm/files/subcharts/content-deployment/templates/job.yaml +3 -2
  12. package/lib/build/plugins/helm/files/subcharts/content-deployment/values.yaml +1 -1
  13. package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
  14. package/lib/build/plugins/helm/files/subcharts/web-application/templates/_helpers.tpl +3 -3
  15. package/lib/build/plugins/helm/files/subcharts/web-application/templates/api-rule.yaml +1 -1
  16. package/lib/build/plugins/helm/files/subcharts/web-application/templates/deployment.yaml +13 -5
  17. package/lib/build/plugins/helm/files/subcharts/web-application/templates/service-binding.yaml +1 -0
  18. package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +28 -15
  19. package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +22 -1
  20. package/lib/build/util.js +3 -1
  21. package/lib/import/common.js +174 -44
  22. package/lib/import/importapi.js +1 -1
  23. package/lib/import/message.js +1 -1
  24. package/lib/import/odata/ParserContext.js +46 -0
  25. package/lib/import/odata/index.js +20 -11
  26. package/lib/import/odata/v4parser.js +25 -51
  27. package/lib/init/add.js +0 -2
  28. package/lib/init/constants.js +3 -3
  29. package/lib/init/index.js +1 -1
  30. package/lib/init/merge.js +67 -66
  31. package/lib/init/mvn.js +16 -12
  32. package/lib/init/projectReader.js +2 -2
  33. package/lib/init/template/ams/files/package.json.hbs +1 -1
  34. package/lib/init/template/approuter/files/mta.yaml.hbs +2 -4
  35. package/lib/init/template/hana/index.js +12 -8
  36. package/lib/init/template/ias/files/mta.yaml.hbs +15 -0
  37. package/lib/init/template/ias/index.js +22 -5
  38. package/lib/init/template/mta/files/mta.yaml.hbs +3 -13
  39. package/lib/init/template/multitenancy/files/mta.yaml.hbs +1 -0
  40. package/lib/init/template/multitenancy/index.js +5 -0
  41. package/lib/init/template/nodejs/files/package.json.hbs +1 -1
  42. package/lib/init/template/portal/files/portal-site/i18n/catalog.properties +1 -1
  43. package/lib/init/template/portal/files/portal-site/i18n/catalog_de.properties +1 -1
  44. package/lib/init/template/portal/files/portal-site/i18n/group.properties +1 -1
  45. package/lib/init/template/portal/files/portal-site/i18n/group_de.properties +1 -1
  46. package/lib/init/template/sample/files/typescript/admin-service.ts.hbs +16 -0
  47. package/lib/init/template/sample/files/typescript/cat-service.ts.hbs +38 -0
  48. package/lib/init/template/sample/index.js +16 -12
  49. package/lib/init/template/typescript/files/package.json +1 -1
  50. package/lib/lint/io.js +6 -16
  51. package/lib/watch/node-watch.js +3 -3
  52. package/npm-shrinkwrap.json +49 -33
  53. package/package.json +1 -1
  54. /package/lib/init/template/sample/files/{nodejs → javascript}/admin-service.js.hbs +0 -0
  55. /package/lib/init/template/sample/files/{nodejs → javascript}/cat-service.js.hbs +0 -0
@@ -24,6 +24,11 @@ module.exports = class MultitenancyTemplate extends require('../../plugin') {
24
24
  return options?.add?.has('mtx') || options?.add?.has('multitenancy') || !!env.requires?.multitenancy || false
25
25
  }
26
26
 
27
+ canRun() {
28
+ if (cds.requires.workzone) throw `There is no 'cds add multitenancy' support for SAP BTP WorkZone yet.`
29
+ return true
30
+ }
31
+
27
32
  async run() {
28
33
  const project = readProject()
29
34
  const { isNodejs, isJava, configFile } = project
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "devDependencies": {
13
13
  "@cap-js/sqlite": "^1",
14
- "@cap-js/cds-types": "^0.8.0"
14
+ "@cap-js/cds-types": "^0.9.0"
15
15
  },
16
16
  "scripts": {
17
17
  "start": "cds-serve"
@@ -1 +1 @@
1
- title=Bookshop
1
+ title=Application Title
@@ -1 +1 @@
1
- title=Bücherladen
1
+ title=Name der Anwendung
@@ -1 +1 @@
1
- title=Bookshop
1
+ title=Application Title
@@ -1 +1 @@
1
- title=Bücherladen
1
+ title=Name der Anwendung
@@ -0,0 +1,16 @@
1
+ import cds from '@sap/cds'
2
+
3
+ import { Books } from '#cds-models/AdminService'
4
+
5
+ export class AdminService extends cds.ApplicationService { async init() {
6
+
7
+ /**
8
+ * Generate primary keys for target entity in request
9
+ */
10
+ this.before ('NEW', Books.drafts, async req => {
11
+ if (req.data.ID) return
12
+ const { ID } = await SELECT.one.from(Books).columns('max(ID) as ID') ?? { ID: 0 }
13
+ req.data.ID = ID! - ID! % 100 + 100 + 1
14
+ })
15
+ return super.init()
16
+ }}
@@ -0,0 +1,38 @@
1
+ import cds from '@sap/cds'
2
+
3
+ import { Books } from '#cds-models/sap/capire/bookshop'
4
+ import { submitOrder, OrderedBook, ListOfBooks } from '#cds-models/CatalogService'
5
+
6
+ export class CatalogService extends cds.ApplicationService { async init() {
7
+
8
+ // Add some discount for overstocked books
9
+ this.after('each', ListOfBooks, book => {
10
+ if (book?.stock === undefined || book.stock === null) return
11
+ if (book?.stock > 111) book.title += ` -- 11% discount!`
12
+ })
13
+
14
+ // Reduce stock of ordered books if available stock suffices
15
+ this.on(submitOrder, async req => {
16
+ let { book:id, quantity } = req.data
17
+ if(!id) return req.error (400, `Book ID missing`) // FIXED
18
+ let book = await SELECT.from (Books, id, b => b.stock)
19
+
20
+ // Validate input data
21
+ if (!book) return req.error (404, `Book #${id} doesn't exist`)
22
+ if (!quantity || quantity < 1) return req.error (400, `quantity has to be 1 or more`)
23
+ if (quantity > book.stock!) return req.error (409, `${quantity} exceeds stock for book #${id}`)
24
+
25
+ // Reduce stock in database and return updated stock value
26
+ await UPDATE (Books, id) .with ({ stock: book.stock! -= quantity })
27
+ return book
28
+ })
29
+
30
+ // Emit event when an order has been submitted
31
+ this.after(submitOrder, async (_,req) => {
32
+ let { book, quantity } = req.data
33
+ await this.emit(OrderedBook, { book, quantity, buyer: req.user.id })
34
+ })
35
+
36
+ // Delegate requests to the underlying generic service
37
+ return super.init()
38
+ }}
@@ -1,5 +1,5 @@
1
1
  const { join } = require('path')
2
- const cds = require('../../../cds'), { exists, read, write, copy } = cds.utils
2
+ const cds = require('../../../cds'), { read, write, copy } = cds.utils
3
3
  const { env4, readProject } = require('../../projectReader')
4
4
  const { merge } = require('../../merge')
5
5
  const { renderAndCopy } = require('../../template')
@@ -12,19 +12,23 @@ module.exports = class SampleTemplate extends require('../../plugin') {
12
12
  }
13
13
 
14
14
  async run() {
15
- const { db, srv, app } = env4('production').folders
16
- const language = exists('pom.xml') ? 'java' : 'nodejs'
17
15
  const project = readProject()
16
+ const { db, srv, app } = env4('production').folders
18
17
 
19
- if (language === 'nodejs') {
20
- await Promise.all([
21
- copy(join(__dirname, 'files/db')).to(db),
22
- copy(join(__dirname, 'files/srv')).to(srv)
23
- ])
24
- await renderAndCopy(join(__dirname, 'files', language), srv, project)
25
- await copy(join(__dirname, 'files/app')).to(app)
26
- } else if (language === 'java') {
27
- await mvn.add('sample')
18
+ switch (project.language) {
19
+ case 'nodejs': {
20
+ await Promise.all([
21
+ copy(join(__dirname, 'files/db')).to(db),
22
+ copy(join(__dirname, 'files/srv')).to(srv)
23
+ ])
24
+ const lang = project.isTypescript ? 'typescript' : 'javascript'
25
+ await renderAndCopy(join(__dirname, 'files', lang), srv, project)
26
+ await copy(join(__dirname, 'files/app')).to(app)
27
+ break
28
+ }
29
+ case 'java':
30
+ await mvn.add('sample')
31
+ break
28
32
  }
29
33
 
30
34
  const { appName, appPath, appUIPaths } = project
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "devDependencies": {
3
- "@cap-js/cds-types": "^0.8.0",
3
+ "@cap-js/cds-types": "^0.9.0",
4
4
  "@types/node": "^22.0.0",
5
5
  "typescript": "^5"
6
6
  },
package/lib/lint/io.js CHANGED
@@ -52,15 +52,13 @@ module.exports = {
52
52
  */
53
53
  async readEslintConfig(configPath) {
54
54
  let config;
55
- const configFile = path.basename(configPath);
56
- switch (configFile) {
55
+ switch (path.basename(configPath)) {
56
+ case "eslint.config.mjs":
57
+ try { config = await import (configPath) } catch { config = null }
58
+ break
57
59
  case "eslint.config.js":
58
60
  case "eslint.config.cjs":
59
- case "eslint.config.mjs":
60
- config = this.safeRequire(configPath)
61
- break;
62
- default:
63
- break;
61
+ try { config = require (configPath) } catch { config = null }
64
62
  }
65
63
  return config;
66
64
  },
@@ -77,7 +75,7 @@ module.exports = {
77
75
  let configContents;
78
76
  const isFilePath = typeof configIn === "string";
79
77
  if (isFilePath) {
80
- configContents = this.safeRequire(configIn); // TODO error handling invalid json
78
+ configContents = await this.readEslintConfig(configIn)
81
79
  }
82
80
 
83
81
  configContents ??= { ...configIn };
@@ -372,12 +370,4 @@ export default [...cds.recommended, cdsPlugin.configs.recommended]
372
370
  }
373
371
  return userOpts;
374
372
  },
375
-
376
- safeRequire(module) {
377
- try {
378
- return require(module)
379
- } catch (e) {
380
- return null
381
- }
382
- }
383
373
  };
@@ -2,7 +2,7 @@ const cds = require ('../cds')
2
2
  const LOG = cds.log('cli|watch'), DEBUG = cds.debug('cli|watch')
3
3
  const { relative } = require('path')
4
4
 
5
- module.exports = ({ cwd, script, ext, ignore=RegExp(), env={}, delay=200, options={} })=>{
5
+ module.exports = ({ cwd = process.cwd(), script, ext, ignore=RegExp(), watched, env={}, delay=200, options={} })=>{
6
6
  const debugOpts = _debugOpts(options)
7
7
 
8
8
  let child
@@ -58,7 +58,7 @@ module.exports = ({ cwd, script, ext, ignore=RegExp(), env={}, delay=200, option
58
58
  // else DEBUG?. (`NOT ignored: ${relative(cwd||process.cwd(), f)}`, include.test(f), include)
59
59
  return isIn
60
60
  }
61
- const watcher = watch (cwd||process.cwd(),{ recursive:true, filter, delay:0 })
61
+ const watcher = watch (watched,{ recursive:true, filter, delay:0 })
62
62
  if (LOG._debug) watcher.on('close', ()=> DEBUG('⚡️', 'cds watch - file watcher closed'))
63
63
  watcher.on('change', restart)
64
64
  process.on('shutdown', ()=> watcher.close())
@@ -96,7 +96,7 @@ const ps = (child,env) => console.log (`\x1b[32m
96
96
  \x1b[0m`
97
97
  )
98
98
 
99
- // reduces mutiple node-watch events in a time frame into a bulk
99
+ // reduces multiple node-watch events in a time frame into a bulk
100
100
  function _coalesceEvents(delay, fn) {
101
101
  let timer, cache = []
102
102
  return function(type, name) { // node-watch callback signature
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@sap/cds-dk",
3
- "version": "8.6.0",
3
+ "version": "8.7.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@sap/cds-dk",
9
- "version": "8.6.0",
9
+ "version": "8.7.0",
10
10
  "license": "SEE LICENSE IN LICENSE",
11
11
  "dependencies": {
12
12
  "@cap-js/asyncapi": "^1.0.0",
@@ -43,7 +43,7 @@
43
43
  }
44
44
  },
45
45
  "node_modules/@cap-js/db-service": {
46
- "version": "1.16.1",
46
+ "version": "1.17.0",
47
47
  "license": "SEE LICENSE",
48
48
  "optional": true,
49
49
  "dependencies": {
@@ -54,7 +54,7 @@
54
54
  }
55
55
  },
56
56
  "node_modules/@cap-js/openapi": {
57
- "version": "1.1.1",
57
+ "version": "1.1.2",
58
58
  "license": "SEE LICENSE IN LICENSE",
59
59
  "dependencies": {
60
60
  "pluralize": "^8.0.0"
@@ -64,11 +64,11 @@
64
64
  }
65
65
  },
66
66
  "node_modules/@cap-js/sqlite": {
67
- "version": "1.7.8",
67
+ "version": "1.8.0",
68
68
  "license": "SEE LICENSE",
69
69
  "optional": true,
70
70
  "dependencies": {
71
- "@cap-js/db-service": "^1.14.1",
71
+ "@cap-js/db-service": "^1.17.0",
72
72
  "better-sqlite3": "^11.0.0"
73
73
  },
74
74
  "peerDependencies": {
@@ -121,7 +121,7 @@
121
121
  }
122
122
  },
123
123
  "node_modules/@eslint/core": {
124
- "version": "0.9.1",
124
+ "version": "0.10.0",
125
125
  "license": "Apache-2.0",
126
126
  "dependencies": {
127
127
  "@types/json-schema": "^7.0.15"
@@ -152,7 +152,7 @@
152
152
  }
153
153
  },
154
154
  "node_modules/@eslint/js": {
155
- "version": "9.17.0",
155
+ "version": "9.19.0",
156
156
  "license": "MIT",
157
157
  "engines": {
158
158
  "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -166,9 +166,10 @@
166
166
  }
167
167
  },
168
168
  "node_modules/@eslint/plugin-kit": {
169
- "version": "0.2.4",
169
+ "version": "0.2.5",
170
170
  "license": "Apache-2.0",
171
171
  "dependencies": {
172
+ "@eslint/core": "^0.10.0",
172
173
  "levn": "^0.4.1"
173
174
  },
174
175
  "engines": {
@@ -227,7 +228,7 @@
227
228
  }
228
229
  },
229
230
  "node_modules/@sap/cds": {
230
- "version": "8.6.0",
231
+ "version": "8.7.0",
231
232
  "license": "SEE LICENSE IN LICENSE",
232
233
  "dependencies": {
233
234
  "@sap/cds-compiler": ">=5.1",
@@ -244,16 +245,20 @@
244
245
  "node": ">=18"
245
246
  },
246
247
  "peerDependencies": {
247
- "express": ">=4"
248
+ "express": "^4",
249
+ "tar": "^7"
248
250
  },
249
251
  "peerDependenciesMeta": {
250
252
  "express": {
251
253
  "optional": true
254
+ },
255
+ "tar": {
256
+ "optional": true
252
257
  }
253
258
  }
254
259
  },
255
260
  "node_modules/@sap/cds-compiler": {
256
- "version": "5.6.0",
261
+ "version": "5.7.0",
257
262
  "license": "SEE LICENSE IN LICENSE",
258
263
  "dependencies": {
259
264
  "antlr4": "4.9.3"
@@ -268,7 +273,7 @@
268
273
  }
269
274
  },
270
275
  "node_modules/@sap/cds-fiori": {
271
- "version": "1.2.8",
276
+ "version": "1.3.0",
272
277
  "license": "SEE LICENSE IN LICENSE",
273
278
  "peerDependencies": {
274
279
  "@sap/cds": ">=7.6",
@@ -289,7 +294,7 @@
289
294
  }
290
295
  },
291
296
  "node_modules/@sap/cds-mtxs": {
292
- "version": "2.4.1",
297
+ "version": "2.5.0",
293
298
  "license": "SEE LICENSE IN LICENSE",
294
299
  "dependencies": {
295
300
  "@sap/hdi-deploy": ">=4",
@@ -315,13 +320,13 @@
315
320
  }
316
321
  },
317
322
  "node_modules/@sap/hdi": {
318
- "version": "4.6.0",
323
+ "version": "4.7.0",
319
324
  "license": "See LICENSE file",
320
325
  "dependencies": {
321
326
  "async": "^3.2.3"
322
327
  },
323
328
  "engines": {
324
- "node": ">=18 <=20"
329
+ "node": ">=18"
325
330
  },
326
331
  "peerDependencies": {
327
332
  "@sap/hana-client": "^2 >= 2.5",
@@ -501,7 +506,7 @@
501
506
  "optional": true
502
507
  },
503
508
  "node_modules/better-sqlite3": {
504
- "version": "11.7.0",
509
+ "version": "11.8.1",
505
510
  "hasInstallScript": true,
506
511
  "license": "MIT",
507
512
  "optional": true,
@@ -877,7 +882,7 @@
877
882
  }
878
883
  },
879
884
  "node_modules/es-object-atoms": {
880
- "version": "1.0.0",
885
+ "version": "1.1.1",
881
886
  "license": "MIT",
882
887
  "dependencies": {
883
888
  "es-errors": "^1.3.0"
@@ -901,16 +906,16 @@
901
906
  }
902
907
  },
903
908
  "node_modules/eslint": {
904
- "version": "9.17.0",
909
+ "version": "9.19.0",
905
910
  "license": "MIT",
906
911
  "dependencies": {
907
912
  "@eslint-community/eslint-utils": "^4.2.0",
908
913
  "@eslint-community/regexpp": "^4.12.1",
909
914
  "@eslint/config-array": "^0.19.0",
910
- "@eslint/core": "^0.9.0",
915
+ "@eslint/core": "^0.10.0",
911
916
  "@eslint/eslintrc": "^3.2.0",
912
- "@eslint/js": "9.17.0",
913
- "@eslint/plugin-kit": "^0.2.3",
917
+ "@eslint/js": "9.19.0",
918
+ "@eslint/plugin-kit": "^0.2.5",
914
919
  "@humanfs/node": "^0.16.6",
915
920
  "@humanwhocodes/module-importer": "^1.0.1",
916
921
  "@humanwhocodes/retry": "^0.4.1",
@@ -1264,19 +1269,19 @@
1264
1269
  }
1265
1270
  },
1266
1271
  "node_modules/get-intrinsic": {
1267
- "version": "1.2.6",
1272
+ "version": "1.2.7",
1268
1273
  "license": "MIT",
1269
1274
  "dependencies": {
1270
1275
  "call-bind-apply-helpers": "^1.0.1",
1271
- "dunder-proto": "^1.0.0",
1272
1276
  "es-define-property": "^1.0.1",
1273
1277
  "es-errors": "^1.3.0",
1274
1278
  "es-object-atoms": "^1.0.0",
1275
1279
  "function-bind": "^1.1.2",
1280
+ "get-proto": "^1.0.0",
1276
1281
  "gopd": "^1.2.0",
1277
1282
  "has-symbols": "^1.1.0",
1278
1283
  "hasown": "^2.0.2",
1279
- "math-intrinsics": "^1.0.0"
1284
+ "math-intrinsics": "^1.1.0"
1280
1285
  },
1281
1286
  "engines": {
1282
1287
  "node": ">= 0.4"
@@ -1285,6 +1290,17 @@
1285
1290
  "url": "https://github.com/sponsors/ljharb"
1286
1291
  }
1287
1292
  },
1293
+ "node_modules/get-proto": {
1294
+ "version": "1.0.1",
1295
+ "license": "MIT",
1296
+ "dependencies": {
1297
+ "dunder-proto": "^1.0.1",
1298
+ "es-object-atoms": "^1.0.0"
1299
+ },
1300
+ "engines": {
1301
+ "node": ">= 0.4"
1302
+ }
1303
+ },
1288
1304
  "node_modules/github-from-package": {
1289
1305
  "version": "0.0.0",
1290
1306
  "license": "MIT",
@@ -1367,7 +1383,7 @@
1367
1383
  }
1368
1384
  },
1369
1385
  "node_modules/hdb": {
1370
- "version": "0.19.11",
1386
+ "version": "0.19.12",
1371
1387
  "license": "Apache-2.0",
1372
1388
  "dependencies": {
1373
1389
  "iconv-lite": "^0.4.18"
@@ -1553,7 +1569,7 @@
1553
1569
  "license": "MIT"
1554
1570
  },
1555
1571
  "node_modules/math-intrinsics": {
1556
- "version": "1.0.0",
1572
+ "version": "1.1.0",
1557
1573
  "license": "MIT",
1558
1574
  "engines": {
1559
1575
  "node": ">= 0.4"
@@ -1663,7 +1679,7 @@
1663
1679
  }
1664
1680
  },
1665
1681
  "node_modules/napi-build-utils": {
1666
- "version": "1.0.2",
1682
+ "version": "2.0.0",
1667
1683
  "license": "MIT",
1668
1684
  "optional": true
1669
1685
  },
@@ -1683,7 +1699,7 @@
1683
1699
  "license": "MIT"
1684
1700
  },
1685
1701
  "node_modules/node-abi": {
1686
- "version": "3.71.0",
1702
+ "version": "3.73.0",
1687
1703
  "license": "MIT",
1688
1704
  "optional": true,
1689
1705
  "dependencies": {
@@ -1832,7 +1848,7 @@
1832
1848
  }
1833
1849
  },
1834
1850
  "node_modules/prebuild-install": {
1835
- "version": "7.1.2",
1851
+ "version": "7.1.3",
1836
1852
  "license": "MIT",
1837
1853
  "optional": true,
1838
1854
  "dependencies": {
@@ -1841,7 +1857,7 @@
1841
1857
  "github-from-package": "0.0.0",
1842
1858
  "minimist": "^1.2.3",
1843
1859
  "mkdirp-classic": "^0.5.3",
1844
- "napi-build-utils": "^1.0.1",
1860
+ "napi-build-utils": "^2.0.0",
1845
1861
  "node-abi": "^3.3.0",
1846
1862
  "pump": "^3.0.0",
1847
1863
  "rc": "^1.2.7",
@@ -2229,7 +2245,7 @@
2229
2245
  }
2230
2246
  },
2231
2247
  "node_modules/tar-fs": {
2232
- "version": "2.1.1",
2248
+ "version": "2.1.2",
2233
2249
  "license": "MIT",
2234
2250
  "optional": true,
2235
2251
  "dependencies": {
@@ -2425,7 +2441,7 @@
2425
2441
  }
2426
2442
  },
2427
2443
  "node_modules/yaml": {
2428
- "version": "2.6.1",
2444
+ "version": "2.7.0",
2429
2445
  "license": "ISC",
2430
2446
  "bin": {
2431
2447
  "yaml": "bin.mjs"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds-dk",
3
- "version": "8.6.0",
3
+ "version": "8.7.0",
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": [