@sap/cds-dk 10.0.3 → 10.0.5

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 (82) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/bin/debug.js +6 -2
  3. package/bin/up.js +1 -1
  4. package/bin/watch.js +1 -0
  5. package/lib/build/plugins/helm/files/templates/_deployment_helpers.tpl +2 -0
  6. package/lib/build/plugins/nodejs/index.js +6 -3
  7. package/lib/build/util.js +1 -1
  8. package/lib/init/template/ams/files/containerize.yaml.hbs +1 -0
  9. package/lib/init/template/approuter/files/values.yaml.hbs +9 -1
  10. package/lib/init/template/data/as-csv.js +4 -2
  11. package/lib/init/template/data/as-json.js +4 -1
  12. package/lib/init/template/github-actions/files/workflows/cf.yaml.hbs +6 -6
  13. package/lib/init/template/ias/files/values.yaml.hbs +4 -4
  14. package/lib/init/template/portal/files/values.yaml.hbs +12 -0
  15. package/lib/init/template/sample/files/app/browse/fiori-service.cds +2 -0
  16. package/lib/init/template/typer/files/xsconfig.json +1 -1
  17. package/lib/init/template/typescript/files/package.json +1 -1
  18. package/lib/lint/eslintHelp.json +1 -1
  19. package/lib/watch/esm-resolve-registration.js +27 -0
  20. package/lib/watch/vite-watch.js +1 -1
  21. package/node_modules/@cap-js/db-service/CHANGELOG.md +768 -0
  22. package/node_modules/@cap-js/db-service/LICENSE +201 -0
  23. package/node_modules/@cap-js/db-service/README.md +26 -0
  24. package/node_modules/@cap-js/db-service/index.js +19 -0
  25. package/node_modules/@cap-js/db-service/lib/InsertResults.js +122 -0
  26. package/node_modules/@cap-js/db-service/lib/SQLService.js +581 -0
  27. package/node_modules/@cap-js/db-service/lib/common/DatabaseService.js +179 -0
  28. package/node_modules/@cap-js/db-service/lib/common/factory.d.ts +5 -0
  29. package/node_modules/@cap-js/db-service/lib/common/generic-pool.js +310 -0
  30. package/node_modules/@cap-js/db-service/lib/common/session-context.js +46 -0
  31. package/node_modules/@cap-js/db-service/lib/converters.d.ts +24 -0
  32. package/node_modules/@cap-js/db-service/lib/cql-functions.js +464 -0
  33. package/node_modules/@cap-js/db-service/lib/cqn2pql.js +116 -0
  34. package/node_modules/@cap-js/db-service/lib/cqn2sql.js +1612 -0
  35. package/node_modules/@cap-js/db-service/lib/cqn4sql.js +2895 -0
  36. package/node_modules/@cap-js/db-service/lib/deep-queries.js +290 -0
  37. package/node_modules/@cap-js/db-service/lib/fill-in-keys.js +75 -0
  38. package/node_modules/@cap-js/db-service/lib/infer/cqn.d.ts +42 -0
  39. package/node_modules/@cap-js/db-service/lib/infer/index.js +1290 -0
  40. package/node_modules/@cap-js/db-service/lib/infer/join-tree.js +278 -0
  41. package/node_modules/@cap-js/db-service/lib/infer/pseudos.js +24 -0
  42. package/node_modules/@cap-js/db-service/lib/search.js +220 -0
  43. package/node_modules/@cap-js/db-service/lib/utils.js +177 -0
  44. package/node_modules/@cap-js/db-service/package.json +36 -0
  45. package/node_modules/@cap-js/sqlite/CHANGELOG.md +404 -0
  46. package/node_modules/@cap-js/sqlite/LICENSE +201 -0
  47. package/node_modules/@cap-js/sqlite/README.md +34 -0
  48. package/node_modules/@cap-js/sqlite/cds-plugin.js +0 -0
  49. package/node_modules/@cap-js/sqlite/index.js +2 -0
  50. package/node_modules/@cap-js/sqlite/lib/SQLiteService.js +324 -0
  51. package/node_modules/@cap-js/sqlite/lib/cql-functions.js +160 -0
  52. package/node_modules/@cap-js/sqlite/lib/node-sqlite.js +36 -0
  53. package/node_modules/@cap-js/sqlite/lib/session.json +3 -0
  54. package/node_modules/@cap-js/sqlite/lib/sql.js.js +99 -0
  55. package/node_modules/@cap-js/sqlite/package.json +68 -0
  56. package/node_modules/@sap/cds-compiler/CHANGELOG.md +14 -0
  57. package/node_modules/@sap/cds-compiler/bin/cdsse.js +1 -1
  58. package/node_modules/@sap/cds-compiler/bin/cdsv2m.js +1 -1
  59. package/node_modules/@sap/cds-compiler/doc/IncompatibleChanges_v7.md +20 -13
  60. package/node_modules/@sap/cds-compiler/lib/base/builtins.js +4 -1
  61. package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +15 -2
  62. package/node_modules/@sap/cds-compiler/lib/checks/defaultValues.js +0 -1
  63. package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +6 -5
  64. package/node_modules/@sap/cds-compiler/lib/compiler/tweak-assocs.js +27 -6
  65. package/node_modules/@sap/cds-compiler/lib/edm/annotations/edmJson.js +5 -0
  66. package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +3 -3
  67. package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +5 -4
  68. package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +14 -3
  69. package/node_modules/@sap/cds-compiler/lib/tool-lib/enrichCsn.js +1 -1
  70. package/node_modules/@sap/cds-compiler/lib/transform/db/cdsPersistence.js +3 -2
  71. package/node_modules/@sap/cds-compiler/lib/transform/db/views.js +2 -2
  72. package/node_modules/@sap/cds-compiler/lib/transform/transformUtils.js +1 -2
  73. package/node_modules/@sap/cds-compiler/package.json +1 -1
  74. package/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
  75. package/node_modules/iconv-lite/encodings/utf32.js +10 -3
  76. package/node_modules/iconv-lite/package.json +2 -2
  77. package/node_modules/iconv-lite/types/encodings.d.ts +2 -0
  78. package/node_modules/ws/lib/receiver.js +15 -32
  79. package/node_modules/ws/lib/websocket-server.js +4 -4
  80. package/node_modules/ws/lib/websocket.js +4 -4
  81. package/node_modules/ws/package.json +5 -1
  82. package/package.json +5 -3
package/CHANGELOG.md CHANGED
@@ -6,6 +6,34 @@ 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 10.0.5 - 2026-07-16
10
+
11
+ ### Fixed
12
+
13
+ - `cds add typer` now generates a `jsconfig.json` file that works with VS Code.
14
+ - `cds debug <app> --force` on Kyma now preserves existing `NODE_OPTIONS` flags (e.g. `--max-old-space-size`) instead of overwriting them when enabling the inspector.
15
+ - `cds add sample` now selects `stock` in the Books list and object pages, so the overstock discount shows up in the UI.
16
+ - `cds add data` now generates correct foreign-key columns for nested compositions of aspects, e.g. `up__up__ID,up__ID,ID,name` instead of a broken `up__up_` header.
17
+ - `cds build` no longer fails with `npm ls -ws: unknown option` on npm 12, which dropped the short `-ws` flag.
18
+ - `cds build` now packages transitive npm workspace dependencies again on npm 12, which changed `npm pack --json` to emit an object keyed by package name instead of an array.
19
+ - `cds up` uses `helm --rollback-on-failure` instead of the deprecated `--atomic`.
20
+ - `cds add portal` on Java + IAS disables JWT proof-of-possession on `srv` (`SAP_SPRING_SECURITY_IDENTITY_PROOFTOKEN=false`) so Portal-proxied tile OData works.
21
+ - `cds add ias` forwards client certificates from the approuter to `srv-api` (`backendDestinations.srv-api.forwardAuthCertificates`).
22
+ - `cds add ias` always enables `xsuaa-cross-consumption` in the identity service parameters.
23
+ - `cds add ias` no longer sets an mTLS `expose.host` on the approuter, restoring a plain approuter host for the browser flow.
24
+ - `cds add portal` on Java multitenant now binds the Portal service instance to `srv` so CAP Java's `getDependencies` reports Portal to the SaaS Registry.
25
+ - `cds add kyma` uses a tenant-agnostic (tcpSocket) startup probe for the multitenant approuter, avoiding 400s from `TENANT_HOST_PATTERN` on kubelet probes.
26
+ - `cds add kyma` no longer emits the dead `Authentication: OAuth2UserTokenExchange` key on `backendDestinations.srv-api`.
27
+ - `cds add github-actions` uses updated versions.
28
+ - `cds watch` now works in ESM scenarios where only a global `cds-dk` is installed, where it would formerly fail with `ERR_MODULE_NOT_FOUND` for `@sap/cds`.
29
+ - `cds watch`no longer shows a `'server.hmr.protocol/host/port/path/clientPort/timeout/server' is deprecated` warning when running a Vite application.
30
+
31
+ ## Version 10.0.4 - 2026-07-08
32
+
33
+ ### Fixed
34
+
35
+ - `cds watch` now starts apps with a SQLite database again in cases where they don't have a `@cap-js/sqlite` dependency or a `package.json`.
36
+
9
37
  ## Version 10.0.3 - 2026-07-02
10
38
 
11
39
  ### Fixed
package/bin/debug.js CHANGED
@@ -101,7 +101,11 @@ async function debug() {
101
101
 
102
102
  if (force) {
103
103
  console.log(`\nEnabling Node inspector on deployment/${appName} at 0.0.0.0:${portLocal} ...`)
104
- _execSyncSafe(`kubectl ${ns} set env deployment/${appName} NODE_OPTIONS="--inspect=0.0.0.0:${portLocal}"`, { stdio: 'inherit' })
104
+ const existingOpts = _execSyncSafe(`kubectl ${ns} get deploy ${appName} -o jsonpath="{.spec.template.spec.containers[0].env[?(@.name=='NODE_OPTIONS')].value}"`)
105
+ const inspectFlag = `--inspect=0.0.0.0:${portLocal}`
106
+ const stripped = existingOpts ? existingOpts.replace(/--inspect(-brk)?(=\S+)?\s*/g, '').trim() : ''
107
+ const newOpts = stripped ? `${stripped} ${inspectFlag}` : inspectFlag
108
+ _execSyncSafe(`kubectl ${ns} set env deployment/${appName} NODE_OPTIONS="${newOpts.replace(/"/g, '\\"')}"`, { stdio: 'inherit' })
105
109
  _execSyncSafe(`kubectl ${ns} rollout restart deployment/${appName}`, { stdio: 'inherit' })
106
110
  k(`rollout status deployment/${appName} --timeout=180s`, { stdio: 'inherit' })
107
111
  } else {
@@ -281,7 +285,7 @@ async function debug() {
281
285
  return _execSync(...args)
282
286
  } catch { /* ignore */ }
283
287
  }
284
- function _execSync(cmd, options={ encoding: 'utf-8', shell: true }) {
288
+ function _execSync(cmd, options={ encoding: 'utf-8', shell: true, maxBuffer: 10 * 1024 * 1024 }) {
285
289
  try {
286
290
  return execSync(cmd, options)?.trim()
287
291
  } catch (err) {
package/bin/up.js CHANGED
@@ -346,7 +346,7 @@ async function up() {
346
346
  }
347
347
  })
348
348
 
349
- let helmUpgrade = `helm upgrade --install ${appName} ./gen/chart ${nsHelm} --atomic --wait --wait-for-jobs --timeout=10m`
349
+ let helmUpgrade = `helm upgrade --install ${appName} ./gen/chart ${nsHelm} --rollback-on-failure --wait --wait-for-jobs --timeout=20m`
350
350
  if (hasXsuaa) helmArgs.push(' --set-file xsuaa.jsonParameters=xs-security.json')
351
351
  if (helmArgs.length > 0) helmUpgrade += ` ${helmArgs.join(' ')}`
352
352
  run(helmUpgrade)
package/bin/watch.js CHANGED
@@ -148,6 +148,7 @@ async function watch ([cwd], {
148
148
  // if sap/cds is not installed locally, run with cds-dk's deps. (sap/cds, sqlite etc)
149
149
  if (!installed('@sap/cds', cwd)) {
150
150
  env.NODE_PATH = [...paths(cwd), ...paths(__dirname)].join(delimiter)
151
+ env.NODE_OPTIONS = [env.NODE_OPTIONS, `--import ${require.resolve('../lib/watch/esm-resolve-registration.js')}`].filter(Boolean).join(' ')
151
152
  }
152
153
 
153
154
  const delay = parseInt(process.env.CDS_WATCH_DELAY) || 200
@@ -88,6 +88,8 @@ Backend Destinations
88
88
  {{- end -}}
89
89
  {{- $currentDestination := dict $nameKey $destination.name $urlKey (print $protocol "://" $destinationHost ) -}}
90
90
  {{- $currentDestination := merge $currentDestination $.defaultParameters -}}
91
+ {{- $extras := omit $destination "name" "service" "external" -}}
92
+ {{- $currentDestination := merge $extras $currentDestination -}}
91
93
  {{- $destinations = (append $destinations $currentDestination) -}}
92
94
  {{- end -}}
93
95
  {{- $destinations | toJson }}
@@ -296,14 +296,17 @@ module.exports = class NodejsBuildPlugin extends require('../edmx') {
296
296
  * @param {import('fs').PathLike} dest - destination folder
297
297
  * @param {import('fs').PathLike} wsRoot - workspace root folder
298
298
  * @param {string[]} workspaces - list of workspace names
299
- * @returns {Promise<JSON>} - returns a promise that resolves to the result of the command
299
+ * @returns {Promise<object[]>} - array of pack descriptors ({ name, filename, ... })
300
300
  * @private
301
301
  */
302
302
  static async _execNpmPack(dest, wsRoot, workspaces) {
303
- const args = ['pack', '-ws', '--json', `--pack-destination=${dest}`]
303
+ const args = ['pack', '--ws', '--json', `--pack-destination=${dest}`]
304
304
  workspaces.forEach(w => args.push(`-w=${w}`))
305
305
  const result = await cmd.spawnCommand('npm', args, { cwd: wsRoot }, true, !!LOG._debug)
306
306
  DEBUG?.(result)
307
- return JSON.parse(result)
307
+ const parsed = JSON.parse(result)
308
+ // `npm pack --json` returns an array up to npm 11, but an object keyed by
309
+ // package name as of npm 12 — normalize to an array of descriptors.
310
+ return Array.isArray(parsed) ? parsed : Object.values(parsed)
308
311
  }
309
312
  }
package/lib/build/util.js CHANGED
@@ -300,7 +300,7 @@ async function _execNpmWs(wsRoot) {
300
300
  /** @type {string[]} */
301
301
  let result = []
302
302
  try {
303
- const cmdLine = 'npm ls -ws --json'
303
+ const cmdLine = 'npm ls --ws --json'
304
304
  DEBUG?.(`execute ${cmdLine}`)
305
305
  // @ts-expect-error - TODO: shell should be a string. But can probably be removed altogether?
306
306
  const { stdout } = await execAsync(cmdLine, { shell: IS_WIN, stdio: ['inherit', 'pipe', 'inherit'], cwd: wsRoot })
@@ -17,4 +17,5 @@ modules:
17
17
  {{/isJava}}
18
18
  env:
19
19
  BP_NODE_RUN_SCRIPTS: ""
20
+ BP_NODE_VERSION: "24"
20
21
 
@@ -16,11 +16,20 @@ approuter:
16
16
  ephemeral-storage: 1G
17
17
  cpu: 500m
18
18
  memory: 500M
19
+ {{^hasMultitenancy}}
19
20
  health:
20
21
  liveness:
21
22
  path: /
22
23
  readiness:
23
24
  path: /
25
+ {{/hasMultitenancy}}
26
+ {{#hasMultitenancy}}
27
+ health:
28
+ liveness:
29
+ path: ""
30
+ readiness:
31
+ path: ""
32
+ {{/hasMultitenancy}}
24
33
  {{=<% %>=}}
25
34
  envFrom:
26
35
  - configMapRef:
@@ -29,7 +38,6 @@ approuter:
29
38
  backendDestinations:
30
39
  srv-api:
31
40
  service: srv
32
- Authentication: OAuth2UserTokenExchange
33
41
  {{#hasMultitenancy}}
34
42
  mtx-api:
35
43
  service: {{#isJava}}srv{{/isJava}}{{^isJava}}sidecar{{/isJava}}
@@ -37,10 +37,12 @@ module.exports = async (data={}, csn, { headerOnly=false, separator=',' }={}) =>
37
37
  if (element.on) {
38
38
  continue // skip unmanaged associations with explicit on condition
39
39
  }
40
+ // flatten nested foreign keys (composite keys of nested aspects) into up__up__ID columns
41
+ const {headers: fkHeaders, records: fkRecords} = resolveStruct(value, name)
40
42
  if (i === 0) {
41
- header.push(...Object.keys(value).map(foreignKey => name + '_' + foreignKey))
43
+ header.push(...fkHeaders)
42
44
  }
43
- record.push(...Object.values(value))
45
+ record.push(...fkRecords)
44
46
  }
45
47
  else if (element.is_struct && element.type !== 'cds.Map') {
46
48
  const {headers: structHeaders, records: structRecords} = resolveStruct(value, name);
@@ -257,7 +257,10 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
257
257
 
258
258
  const [ownKey, ownKeyStructured, targetKey] = findKeysInOnCondition(element, target)
259
259
  if (ownKey && targetKey) {
260
- const value = ownKeyStructured ? { [ownKey]: record[ownKey] } : record[ownKey]
260
+ // carry over all parent keys, not just the first, so composite/nested keys survive
261
+ const value = ownKeyStructured
262
+ ? Object.fromEntries(Object.keys(artifact.keys).map(k => [k, record[k]]))
263
+ : record[ownKey]
261
264
  targetRecords.forEach(targetRecord => {
262
265
  // Set parent in target as non-enumerable. Json serialization doesn't need it, but csv does.
263
266
  Object.defineProperty(targetRecord, targetKey, { value, enumerable: false })
@@ -44,13 +44,13 @@ jobs:
44
44
  echo "${PWD}/apache-maven-${MAVEN_VERSION}/bin" >> "$GITHUB_PATH"
45
45
  {{/sap}}
46
46
  {{/isJava}}
47
- - uses: cap-js/cf-setup@v1
47
+ - uses: cap-js/cf-setup@v2
48
48
  with:
49
- cf-api: {{#literal}}${{ vars.CF_API }}{{/literal}}
50
- cf-org: {{#literal}}${{ vars.CF_ORG }}{{/literal}}
51
- cf-space: {{#literal}}${{ vars.CF_SPACE }}{{/literal}}
52
- cf-username: {{#literal}}${{ vars.CF_USERNAME }}{{/literal}}
53
- cf-password: {{#literal}}${{ secrets.CF_PASSWORD }}{{/literal}}
49
+ api: {{#literal}}${{ vars.CF_API }}{{/literal}}
50
+ org: {{#literal}}${{ vars.CF_ORG }}{{/literal}}
51
+ space: {{#literal}}${{ vars.CF_SPACE }}{{/literal}}
52
+ username: {{#literal}}${{ vars.CF_USERNAME }}{{/literal}}
53
+ password: {{#literal}}${{ secrets.CF_PASSWORD }}{{/literal}}
54
54
  - run: npm install
55
55
  - run: npx cds up
56
56
 
@@ -13,14 +13,16 @@ sidecar:
13
13
  {{#hasApprouter}}
14
14
  approuter:
15
15
  expose:
16
- gateway: {{#literal}}"{{ .Release.Namespace }}/kyma-mtls-gateway"{{/literal}}
17
- host: {{#literal}}"{{ .Release.Name }}-approuter-{{ .Release.Namespace }}.cert"{{/literal}}
16
+ host: {{#literal}}"{{ .Release.Name }}-approuter-{{ .Release.Namespace }}"{{/literal}}
18
17
  bindings:
19
18
  auth:
20
19
  serviceInstanceName: identity
21
20
  parameters:
22
21
  credential-type: X509_GENERATED
23
22
  app-identifier: approuter
23
+ backendDestinations:
24
+ srv-api:
25
+ forwardAuthCertificates: true
24
26
  {{/hasApprouter}}
25
27
  srv:
26
28
  expose:
@@ -41,9 +43,7 @@ identity:
41
43
  {{#hasMultitenancy}}
42
44
  multi-tenant: true
43
45
  {{/hasMultitenancy}}
44
- {{#hasXsuaa}}
45
46
  xsuaa-cross-consumption: true
46
- {{/hasXsuaa}}
47
47
  provided-apis:
48
48
  - name: {{appName}}-ias-api
49
49
  description: API exposed by the application
@@ -6,9 +6,21 @@ approuter:
6
6
  portal:
7
7
  serviceOfferingName: portal
8
8
  servicePlanName: standard
9
+ {{#isJava}}{{#hasIas}}
10
+ srv:
11
+ env:
12
+ # Portal Service proxies tile OData without forwarding the client cert.
13
+ SAP_SPRING_SECURITY_IDENTITY_PROOFTOKEN: "false"
14
+ {{/hasIas}}{{/isJava}}
9
15
  {{#hasMultitenancy}}
10
16
  sidecar:
11
17
  bindings:
12
18
  portal:
13
19
  serviceInstanceName: portal
20
+ {{#isJava}}
21
+ srv:
22
+ bindings:
23
+ portal:
24
+ serviceInstanceName: portal
25
+ {{/isJava}}
14
26
  {{/hasMultitenancy}}
@@ -27,6 +27,7 @@ annotate CatalogService.Books with @(UI : {
27
27
  Value : currency.symbol,
28
28
  Label : '{i18n>Currency}'
29
29
  },
30
+ {Value : stock},
30
31
  ]},
31
32
  });
32
33
 
@@ -53,5 +54,6 @@ annotate CatalogService.Books with @(UI : {
53
54
  {Value : genre.name},
54
55
  {Value : price},
55
56
  {Value : currency.symbol},
57
+ {Value : stock},
56
58
  ]
57
59
  });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "moduleResolution": "nodenext",
3
+ "module": "NodeNext",
4
4
  "paths": {
5
5
  "#cds-models/*": ["./@cds-models/*"],
6
6
  "@sap/cds": ["./node_modules/@cap-js/cds-types"]
@@ -3,6 +3,6 @@
3
3
  "@cap-js/cds-types": "^0.18.0",
4
4
  "@types/node": "^24.0.0",
5
5
  "tsx": "^4",
6
- "typescript": "^6.0.0"
6
+ "typescript": "^7.0.0"
7
7
  }
8
8
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "10.6.0",
2
+ "version": "10.7.0",
3
3
  "help": "\n# SYNOPSIS\n\n *cds lint* [options] file.js [file.js] [dir]\n\n Runs environment checks and/or checks the specified models\n based on the ESLint framework\n\n# OPTIONS\n \n Basic configuration:\n --no-config-lookup Disable look up for eslint.config.js\n -c, --config path::String Use this configuration instead of eslint.config.js, eslint.config.mjs, or eslint.config.cjs\n --inspect-config Open the config inspector with the current configuration\n --ext [String] Specify additional file extensions to lint\n --global [String] Define global variables\n --parser String Specify the parser to be used\n --parser-options Object Specify parser options\n \n Specify Rules and Plugins:\n --plugin [String] Specify plugins\n --rule Object Specify rules\n \n Fix Problems:\n --fix Automatically fix problems\n --fix-dry-run Automatically fix problems without saving the changes to the file system\n --fix-type Array Specify the types of fixes to apply (directive, problem, suggestion, layout)\n \n Ignore Files:\n --no-ignore Disable use of ignore files and patterns\n --ignore-pattern [String] Patterns of files to ignore\n \n Use stdin:\n --stdin Lint code provided on <STDIN> - default: false\n --stdin-filename String Specify filename to process STDIN as\n \n Handle Warnings:\n --quiet Report errors only - default: false\n --max-warnings Int Number of warnings to trigger nonzero exit code - default: -1\n \n Output:\n -o, --output-file path::String Specify file to write report to\n -f, --format String Use a specific output format - default: stylish\n --color, --no-color Force enabling/disabling of color\n \n Inline configuration comments:\n --no-inline-config Prevent comments from changing config or rules\n --report-unused-disable-directives Adds reported errors for unused eslint-disable and eslint-enable directives\n --report-unused-disable-directives-severity String Chooses severity level for reporting unused eslint-disable and eslint-enable directives - either: off, warn, error, 0, 1, or 2\n --report-unused-inline-configs String Adds reported errors for unused eslint inline config comments - either: off, warn, error, 0, 1, or 2\n \n Caching:\n --cache Only check changed files - default: false\n --cache-file path::String Path to the cache file. Deprecated: use --cache-location - default: .eslintcache\n --cache-location path::String Path to the cache file or directory\n --cache-strategy String Strategy to use for detecting changed files in the cache - either: metadata or content - default: metadata\n \n Suppressing Violations:\n --suppress-all Suppress all violations - default: false\n --suppress-rule [String] Suppress specific rules\n --suppressions-location path::String Specify the location of the suppressions file\n --prune-suppressions Prune unused suppressions - default: false\n --pass-on-unpruned-suppressions Ignore unused suppressions - default: false\n \n Miscellaneous:\n --init Run config initialization wizard - default: false\n --env-info Output execution environment information - default: false\n --no-error-on-unmatched-pattern Prevent errors when pattern is unmatched\n --exit-on-fatal-error Exit with exit code 2 in case of fatal error - default: false\n --no-warn-ignored Suppress warnings when the file list includes ignored files\n --pass-on-no-patterns Exit with exit code 0 in case no file patterns are passed\n --debug Output debugging information\n -h, --help Show help\n -v, --version Output the version number\n --print-config path::String Print the configuration for the given file\n --stats Add statistics to the lint report - default: false\n --flag [String] Enable a feature flag\n --mcp Start the ESLint MCP server\n --concurrency Int|String Number of linting threads, auto to choose automatically, off for no multithreading - default: off\n \n",
4
4
  "options": [
5
5
  "--config",
@@ -0,0 +1,27 @@
1
+ // we want to allow starting projects with having nothing but a global cds-dk installed in a watched context.
2
+ // In that case, we want to fall back to resolving internal packages from the global cds-dk's own node_modules.
3
+ // Enriching NODE_PATH can be used in CJS (require(...)), but not in ESM (import ... from and import(...)),
4
+ // which requires a custom loader instead.
5
+ // https://nodejs.org/api/esm.html#no-node_path
6
+ const { createRequire, registerHooks } = require('node:module')
7
+ const { pathToFileURL } = require('node:url')
8
+
9
+ const ourModules = new Set(['@sap/cds'])
10
+
11
+ const requireFromHere = createRequire(__filename)
12
+ const resolveFromHere = url => pathToFileURL(requireFromHere.resolve(url)).href
13
+
14
+ registerHooks({
15
+ resolve(specifier, context, nextResolve) {
16
+ try {
17
+ // use default Node resolver first.
18
+ // Note: registering more hooks is UB!
19
+ return nextResolve(specifier, context)
20
+ } catch (error) {
21
+ if (error.code === 'ERR_MODULE_NOT_FOUND' && ourModules.has(specifier)) {
22
+ return { url: resolveFromHere(specifier), shortCircuit: true }
23
+ }
24
+ throw error
25
+ }
26
+ }
27
+ })
@@ -79,7 +79,7 @@ cds.on('bootstrap', app => {
79
79
 
80
80
  for (const viteApp of viteApps) {
81
81
  const base = viteApp.root ? '/' : normalizeBase(viteApp.name)
82
- const server = await createServer({ base, root: viteApp.path, server: { middlewareMode: true, hmr: { port: hmrPort++ } }})
82
+ const server = await createServer({ base, root: viteApp.path, server: { middlewareMode: true, ws: { port: hmrPort++ } }})
83
83
  viteServers.push({ base, root: viteApp.root, middlewares: server.middlewares })
84
84
  }
85
85