@sap/cds 8.6.0 → 8.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
@@ -4,6 +4,15 @@
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 8.6.1 - 2025-01-10
8
+
9
+ ### Fixed
10
+
11
+ - `default-env.json` was not loaded anymore when in production mode.
12
+ - i18n texts like `1` or `true` were returned as numbers, or booleans instead of strings
13
+ - CSN files produced by `cds build` now again contain information to resolve handler files. That was broken in case of reflected/linked models set by e.g. plugins.
14
+ - `average` aggregation used with draft enabled entities
15
+
7
16
  ## Version 8.6.0 - 2024-12-17
8
17
 
9
18
  ### Added
@@ -1,21 +1,19 @@
1
1
  const path = require('path')
2
2
  const fs = require('fs')
3
3
 
4
- const Properties = module.exports = { read, parse }
5
-
6
- function read (res, ext = '.properties') {
4
+ exports.read = function read (res, ext = '.properties', options) {
7
5
  try {
8
6
  // Although properties are actually latin1-encoded, people tend to have
9
7
  // unicode chars in them (e.g.German umlauts), so let's parse in utf-8.
10
8
  if (!/\.(env|.+rc)$/.test(res) && !path.extname(res)) res += ext
11
9
  const src = fs.readFileSync(path.resolve(res),'utf-8')
12
- return Object.defineProperty (Properties.parse(src), '_source', {value:res})
10
+ return Object.defineProperty (exports.parse(src,options), '_source', {value:res})
13
11
  } catch (e) {
14
12
  if (e.code !== 'ENOENT') throw new Error (`Corrupt ${ext} file: ${res+ext}`)
15
13
  }
16
14
  }
17
15
 
18
- function parse (props) {
16
+ exports.parse = function parse (props, options) {
19
17
  if (props.match(/^\s*{/)) return JSON.parse(props)
20
18
  const lines = props.split(/(?<![\\\r])\r?\n/)
21
19
  const rows = lines.filter(each => !!each.trim()).map(each => each.replace(/\\\r?\n/, '')).map(each => {
@@ -23,18 +21,23 @@ function parse (props) {
23
21
  if (index < 0) return [each, '']
24
22
  return [each.slice(0, index).trim(), each.slice(index + 1).trim()]
25
23
  })
24
+ const val = options?.strings ? string4 : value4
26
25
  const bundle = rows.reduce((all, [key, value]) => {
27
- if (key && !/^\s*[#;]/.test(key)) all[key] = value4(value)
26
+ if (key && !/^\s*[#;]/.test(key)) all[key] = val(value)
28
27
  return all
29
28
  }, {})
30
29
  return bundle
31
30
  }
32
31
 
33
- function value4(raw) {
32
+ function value4 (raw) {
34
33
  if (raw === 'true') return true
35
34
  if (raw === 'false') return false
36
35
  if (raw === '0') return 0
37
- else return Number(raw) || raw
36
+ else return Number(raw) || string4(raw)
37
+ }
38
+
39
+ function string4 (raw) {
40
+ return raw
38
41
  .replace(/''/g,"'") .replace(/^"(.*)"$/,"$1") .replace(/^'(.*)'$/,"$1")
39
42
  .replace(/\\u[\dA-F]{4}/gi, (match) => String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16)))
40
43
  }
@@ -6,8 +6,8 @@ module.exports = (csn,o={}) => {
6
6
  const relative_cds_home = RegExp ('^' + path.relative (o.src || o.cwd || cds.root, cds.home) + '/')
7
7
  const { moduleLookupDirectories } = cds.env.cdsc
8
8
 
9
- const resolver = (_,v) => {
10
-
9
+ const resolver = function (k) {
10
+ const v = this[k] // need the original value w/ non-enumerable $location, not the one that went through classes.toJSON()
11
11
  if (!v) return v
12
12
 
13
13
  else if (v.grant && v.where) try {
@@ -201,8 +201,8 @@ class Config {
201
201
  _add_process_env() {
202
202
  const prefix = this._context, cwd = this._home
203
203
  const {env} = process
204
+ this._add_to_env ('default-env.json', env)
204
205
  if (this._profiles.has('development')) {
205
- this._add_to_env ('default-env.json', env)
206
206
  for (let each of this._profiles)
207
207
  each === 'development' || this._add_to_env (`.${each}.env`, env)
208
208
  this._add_to_env ('.env', env)
package/lib/i18n/files.js CHANGED
@@ -83,8 +83,8 @@ class I18nFiles {
83
83
  const fn = `${this.basename}${_suffix}${ext}`; if (!this[dir].includes(fn)) return
84
84
  const file = path.join (dir, fn)
85
85
  try { switch (ext) {
86
- case '.properties': return _load_properties(file);
87
- case '.json': return _load_json(file);
86
+ case '.properties': return _load_properties(file)
87
+ case '.json': return _load_json(file)
88
88
  case '.csv': return _load_csv(file)
89
89
  }}
90
90
  finally { LOG.debug ('read:', file) }
@@ -119,7 +119,7 @@ class I18nFiles {
119
119
  }
120
120
 
121
121
 
122
- const _load_properties = cds.load.properties
122
+ const _load_properties = file => cds.load.properties(file, '.properties', { strings: true })
123
123
  const _load_json = require
124
124
  const _load_csv = file => {
125
125
  const csv = cds.load.csv(file); if (!csv) return
@@ -14,7 +14,7 @@ const { handleStreamProperties } = require('../common/utils/streamProp')
14
14
  const LOG = cds.log('fiori|drafts')
15
15
  const original = Symbol('original')
16
16
  const DRAFT_PARAMS = Symbol('draftParams')
17
- const AGGREGATION_FUNCTIONS = ['sum', 'min', 'max', 'avg', 'count']
17
+ const AGGREGATION_FUNCTIONS = ['sum', 'min', 'max', 'avg', 'average', 'count']
18
18
 
19
19
  const calcTimeMs = timeout => {
20
20
  const match = timeout.match(/^([0-9]+)(w|d|h|hrs|min)$/)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap/cds",
3
- "version": "8.6.0",
3
+ "version": "8.6.1",
4
4
  "description": "SAP Cloud Application Programming Model - CDS for Node.js",
5
5
  "homepage": "https://cap.cloud.sap/",
6
6
  "keywords": [