@sap/cds 9.0.3 → 9.0.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@
4
4
  - The format is based on [Keep a Changelog](https://keepachangelog.com/).
5
5
  - This project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## Version 9.0.4 - 2025-06-18
8
+
9
+ ### Fixed
10
+
11
+ - In some cases, the app crashed if an element was named like a reserved CSN key.
12
+ - Locale detection does not enforce `<http-req>.query` to be present. Some protocol adapters do not set it.
13
+ - `between` operator for remote OData requests
14
+ - `cds serve/watch` and `cds.test()` no longer try to connect to an SQLite database if none is configured.
15
+ - `cds.connect.to` for required queueable services if no persistence is configured
16
+ - Persistent queue is not enabled if no persistence is configured
17
+
7
18
  ## Version 9.0.3 - 2025-06-04
8
19
 
9
20
  ### Fixed
package/bin/serve.js CHANGED
@@ -337,16 +337,18 @@ function _chdir_to (project) {
337
337
  }
338
338
 
339
339
 
340
- /** handles --in-memory option */
340
+ /** handles --in-memory[?] option */
341
341
  function _in_memory (o) {
342
- const {env} = cds, db = env.requires.db
343
- if (o['in-memory'] || o['in-memory?'] && !db) {
344
- env.add ({ requires: { db: {
345
- kind:'sqlite', ...env.requires.kinds.sqlite,
346
- credentials: db?.credentials?.url ? {url:':memory:'} : {database:':memory:'}
347
- }}})
348
- return true
349
- }
342
+ const {env} = cds, db = env.requires.db, sqlite = env.requires.kinds.sqlite
343
+ try {
344
+ if (o['in-memory'] || (o['in-memory?'] && !db && require.resolve(sqlite.impl, {paths: [cds.root, cds.home]}))) {
345
+ env.add ({ requires: { db: {
346
+ kind:'sqlite', ...sqlite,
347
+ credentials: db?.credentials?.url ? {url:':memory:'} : {database:':memory:'}
348
+ }}})
349
+ return true
350
+ }
351
+ } catch (e) { if (e.code !== 'MODULE_NOT_FOUND') throw e }
350
352
  if (db && db.credentials && (db.credentials.database || db.credentials.url) === ':memory:') {
351
353
  return true
352
354
  }
@@ -18,7 +18,8 @@ function normalized_locale_from (req) {
18
18
 
19
19
  function raw_locale_from (req) {
20
20
  return !req ? undefined :
21
- req.query['sap-locale'] || SAP_LANGUAGES[req.query['sap-language']] ||
21
+ // req.query is guaranteed by express, but not by others like websockets or plain Node http
22
+ req.query?.['sap-locale'] || SAP_LANGUAGES[req.query?.['sap-language']] ||
22
23
  req.headers['x-sap-request-language'] ||
23
24
  req.headers['accept-language']
24
25
  }
@@ -44,7 +44,7 @@ connect.to = (datasource, options) => {
44
44
  }
45
45
  // construct new service instance
46
46
  let srv = await new Service (datasource,m,o); await (Service._is_service_class ? srv.init?.() : Service.init?.(srv))
47
- if (!(srv instanceof cds.DatabaseService) && _is_queued(o)) srv = cds.queued(srv)
47
+ if (!srv.isDatabaseService && _is_queued(o)) srv = cds.queued(srv)
48
48
  if (datasource && !options) {
49
49
  if (datasource === 'db') cds.db = srv
50
50
  cds.services[datasource] = srv
@@ -12,8 +12,7 @@ function _getDefinition(definition, name, namespace) {
12
12
  return (
13
13
  definition?.definitions?.[name] ||
14
14
  definition?.elements?.[name] ||
15
- (definition.actions && (definition.actions[name] || definition.actions[name.replace(namespace + '.', '')])) ||
16
- definition[name]
15
+ (definition.actions && (definition.actions[name] || definition.actions[name.replace(namespace + '.', '')]))
17
16
  )
18
17
  }
19
18
 
@@ -167,8 +167,8 @@ function _xpr(expr, target, kind, isLambda, navPrefix = []) {
167
167
  const operator = isOrIsNotValue[1] /* 'is not' */ ? 'ne' : 'eq'
168
168
  res.push(...[operator, _format({ val: isOrIsNotValue[2] })])
169
169
  } else if (cur === 'between') {
170
- // ref gt low.val and ref lt high.val
171
- const between = [expr[i - 1], 'gt', expr[i + 1], 'and', expr[i - 1], 'lt', expr[i + 3]]
170
+ // between is inclusive, so we need to use ge and le
171
+ const between = [expr[i - 1], 'ge', expr[i + 1], 'and', expr[i - 1], 'le', expr[i + 3]]
172
172
  // cleanup previous ref
173
173
  res.pop()
174
174
  res.push(`(${_xpr(between, target, kind, isLambda, navPrefix)})`)
@@ -36,6 +36,7 @@ const _isProviderTenant = tenant =>
36
36
  cds.requires.multitenancy.t0 === tenant
37
37
 
38
38
  const _hasPersistentQueue = tenant => {
39
+ if (!cds.db) return false // no persistence configured
39
40
  if (cds.requires.multitenancy && tenant && _isProviderTenant(tenant)) return false // no persistence for provider account
40
41
  return true
41
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds",
3
- "version": "9.0.3",
3
+ "version": "9.0.4",
4
4
  "description": "SAP Cloud Application Programming Model - CDS for Node.js",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "keywords": [