@sap/cds 9.0.2 → 9.0.3
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 +8 -0
- package/lib/log/cds-error.js +8 -7
- package/libx/_runtime/common/generic/temporal.js +0 -1
- package/libx/_runtime/common/utils/normalizeTimestamp.js +10 -1
- package/libx/odata/utils/metadata.js +9 -4
- package/libx/odata/utils/normalizeTimeData.js +1 -1
- package/libx/queue/index.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@
|
|
|
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.3 - 2025-06-04
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Handling of bad timestamps in URL ($filter and temporals)
|
|
12
|
+
- View metadata for requests with $apply
|
|
13
|
+
- Server crash for some URLs
|
|
14
|
+
|
|
7
15
|
## Version 9.0.2 - 2025-05-28
|
|
8
16
|
|
|
9
17
|
### Changed
|
package/lib/log/cds-error.js
CHANGED
|
@@ -62,13 +62,14 @@ exports.expected = ([,type], arg) => {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
TypeError
|
|
67
|
-
ReferenceError
|
|
68
|
-
SyntaxError
|
|
69
|
-
RangeError
|
|
70
|
-
URIError
|
|
71
|
-
|
|
65
|
+
const system_errors = [
|
|
66
|
+
TypeError,
|
|
67
|
+
ReferenceError,
|
|
68
|
+
SyntaxError,
|
|
69
|
+
RangeError,
|
|
70
|
+
URIError
|
|
71
|
+
]
|
|
72
|
+
exports.isSystemError = err => system_errors.some(e => err instanceof e)
|
|
72
73
|
|
|
73
74
|
|
|
74
75
|
//
|
|
@@ -4,7 +4,6 @@ const normalizeTimestamp = require('../utils/normalizeTimestamp')
|
|
|
4
4
|
const _getDateFromQueryOptions = str => {
|
|
5
5
|
if (str) {
|
|
6
6
|
const match = str.match(/^date'(.+)'$/)
|
|
7
|
-
// REVISIT: What happens with invalid date values in query parameter? if match.length > 1
|
|
8
7
|
return normalizeTimestamp(match ? match[1] : str)
|
|
9
8
|
}
|
|
10
9
|
}
|
|
@@ -9,13 +9,22 @@ const _lengthIfNotFoundIndex = (index, length) => (index > -1 ? index : length)
|
|
|
9
9
|
module.exports = value => {
|
|
10
10
|
if (value instanceof Date) value = value.toISOString()
|
|
11
11
|
if (typeof value === 'number') value = new Date(value).toISOString()
|
|
12
|
+
if (typeof value !== 'string') {
|
|
13
|
+
const msg = `Value "${value}" is not a valid Timestamp`
|
|
14
|
+
throw Object.assign(new Error(msg), { statusCode: 400 })
|
|
15
|
+
}
|
|
12
16
|
|
|
13
17
|
const decimalPointIndex = _lengthIfNotFoundIndex(value.lastIndexOf('.'), value.length)
|
|
14
18
|
const tzRegexMatch = TZ_REGEX.exec(value)
|
|
15
19
|
const tz = tzRegexMatch?.[0] || ''
|
|
16
20
|
const tzIndex = _lengthIfNotFoundIndex(tzRegexMatch?.index, value.length)
|
|
17
21
|
const dateEndIndex = Math.min(decimalPointIndex, tzIndex)
|
|
18
|
-
|
|
22
|
+
let dt = new Date(value.slice(0, dateEndIndex) + tz)
|
|
23
|
+
if (isNaN(dt)) {
|
|
24
|
+
const msg = `Value "${value}" is not a valid Timestamp`
|
|
25
|
+
throw Object.assign(new Error(msg), { statusCode: 400 })
|
|
26
|
+
}
|
|
27
|
+
const dateNoMillisNoTZ = dt.toISOString().slice(0, 19)
|
|
19
28
|
const normalizedFractionalDigits = value
|
|
20
29
|
.slice(dateEndIndex + 1, tzIndex)
|
|
21
30
|
.replace(NON_DIGIT_REGEX, '')
|
|
@@ -32,6 +32,14 @@ const _lastValidRef = ref => {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
const _getRef = query => {
|
|
36
|
+
if (query.SELECT?.from?.SELECT) return _getRef(query.SELECT.from)
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
query.SELECT?.from?.ref ?? query.UPDATE?.entity?.ref ?? query.INSERT?.into?.ref ?? query.DELETE?.from?.ref ?? []
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
const _toBinaryKeyValue = value => `binary'${value.toString('base64')}'`
|
|
36
44
|
|
|
37
45
|
const _odataContext = (query, options) => {
|
|
@@ -49,10 +57,7 @@ const _odataContext = (query, options) => {
|
|
|
49
57
|
|
|
50
58
|
path += '#'
|
|
51
59
|
|
|
52
|
-
|
|
53
|
-
const ref =
|
|
54
|
-
query.SELECT?.from?.ref ?? query.UPDATE?.entity?.ref ?? query.INSERT?.into?.ref ?? query.DELETE?.from?.ref ?? []
|
|
55
|
-
|
|
60
|
+
const ref = _getRef(query)
|
|
56
61
|
const isNavToDraftAdmin = _isNavToDraftAdmin(ref)
|
|
57
62
|
|
|
58
63
|
let edmName
|
|
@@ -8,7 +8,7 @@ const _processorFn = elementInfo => {
|
|
|
8
8
|
const { row, key } = elementInfo
|
|
9
9
|
if (!(row[key] == null) && row[key] !== '$now') {
|
|
10
10
|
const dt = typeof row[key] === 'string' && new Date(row[key])
|
|
11
|
-
if (!isNaN(dt)) {
|
|
11
|
+
if (dt && !isNaN(dt)) {
|
|
12
12
|
switch (category) {
|
|
13
13
|
case 'cds.DateTime':
|
|
14
14
|
row[key] = new Date(row[key]).toISOString().replace(/\.\d\d\d/, '')
|
package/libx/queue/index.js
CHANGED
|
@@ -423,6 +423,7 @@ const _createTask = (name, msg, context, taskOpts) => {
|
|
|
423
423
|
delete _msg.query._target
|
|
424
424
|
delete _msg.query.__target
|
|
425
425
|
delete _msg.query.target
|
|
426
|
+
delete _msg.data // `req.data` should be a getter to whatever is in `req.query`
|
|
426
427
|
}
|
|
427
428
|
const taskMsg = {
|
|
428
429
|
ID: cds.utils.uuid(),
|