@sap/cds 9.2.0 → 9.3.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.
- package/CHANGELOG.md +87 -1
- package/_i18n/i18n_es.properties +3 -3
- package/_i18n/i18n_es_MX.properties +3 -3
- package/_i18n/i18n_fr.properties +2 -2
- package/_i18n/messages.properties +6 -0
- package/app/index.js +0 -1
- package/bin/deploy.js +1 -1
- package/bin/serve.js +7 -20
- package/lib/compile/cdsc.js +3 -0
- package/lib/compile/for/flows.js +102 -0
- package/lib/compile/for/nodejs.js +28 -0
- package/lib/compile/to/edm.js +11 -4
- package/lib/core/classes.js +1 -1
- package/lib/core/linked-csn.js +8 -0
- package/lib/dbs/cds-deploy.js +12 -12
- package/lib/env/cds-env.js +1 -1
- package/lib/env/cds-requires.js +21 -20
- package/lib/env/defaults.js +2 -1
- package/lib/index.js +5 -6
- package/lib/log/cds-log.js +6 -5
- package/lib/log/format/aspects/cf.js +2 -2
- package/lib/plugins.js +1 -1
- package/lib/ql/UPDATE.js +3 -1
- package/lib/ql/cds-ql.js +0 -3
- package/lib/req/request.js +3 -3
- package/lib/req/response.js +12 -7
- package/lib/srv/bindings.js +17 -17
- package/lib/srv/cds-connect.js +6 -9
- package/lib/srv/cds-serve.js +74 -137
- package/lib/srv/cds.Service.js +49 -0
- package/lib/srv/factory.js +4 -4
- package/lib/srv/middlewares/auth/ias-auth.js +31 -11
- package/lib/srv/middlewares/auth/index.js +3 -2
- package/lib/srv/middlewares/auth/jwt-auth.js +19 -6
- package/lib/srv/protocols/hcql.js +16 -1
- package/lib/srv/srv-dispatch.js +1 -1
- package/lib/utils/cds-utils.js +4 -8
- package/lib/utils/csv-reader.js +27 -7
- package/libx/_runtime/cds.js +0 -6
- package/libx/_runtime/common/Service.js +5 -0
- package/libx/_runtime/common/generic/crud.js +1 -1
- package/libx/_runtime/common/generic/flows.js +106 -0
- package/libx/_runtime/common/generic/paging.js +3 -3
- package/libx/_runtime/common/utils/differ.js +5 -15
- package/libx/_runtime/common/utils/resolveView.js +2 -2
- package/libx/_runtime/common/utils/rewriteAsterisks.js +2 -2
- package/libx/_runtime/fiori/lean-draft.js +76 -40
- package/libx/_runtime/messaging/enterprise-messaging.js +1 -1
- package/libx/_runtime/messaging/file-based.js +2 -1
- package/libx/_runtime/remote/Service.js +68 -62
- package/libx/_runtime/remote/utils/client.js +29 -216
- package/libx/_runtime/remote/utils/query.js +197 -0
- package/libx/_runtime/ucl/Service.js +180 -112
- package/libx/_runtime/ucl/queries.js +61 -0
- package/libx/odata/ODataAdapter.js +1 -4
- package/libx/odata/index.js +2 -10
- package/libx/odata/middleware/error.js +8 -1
- package/libx/odata/middleware/stream.js +1 -1
- package/libx/odata/middleware/update.js +12 -2
- package/libx/odata/parse/afterburner.js +113 -20
- package/libx/odata/parse/cqn2odata.js +1 -3
- package/libx/odata/parse/grammar.peggy +4 -2
- package/libx/odata/parse/parser.js +1 -1
- package/libx/queue/index.js +1 -1
- package/libx/rest/middleware/parse.js +9 -2
- package/package.json +2 -2
- package/server.js +2 -0
- package/srv/app-service.js +1 -0
- package/srv/db-service.js +1 -0
- package/srv/msg-service.js +1 -0
- package/srv/remote-service.js +1 -0
- package/srv/ucl-service.cds +32 -0
- package/srv/ucl-service.js +1 -0
- package/lib/ql/resolve.js +0 -45
- package/libx/common/assert/type-strict.js +0 -109
- package/libx/common/assert/utils.js +0 -60
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
const { cds } = global
|
|
2
|
-
|
|
3
|
-
const { Readable } = require('stream')
|
|
4
|
-
|
|
5
|
-
const { getNormalizedDecimal, getTarget, isBase64String } = require('./utils')
|
|
6
|
-
|
|
7
|
-
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i //> "i" is acutally not OK, but we'll leave as is for now to avoid breaking changes
|
|
8
|
-
const RELAXED_UUID_REGEX = /^[0-9a-z]{8}-?[0-9a-z]{4}-?[0-9a-z]{4}-?[0-9a-z]{4}-?[0-9a-z]{12}$/i
|
|
9
|
-
|
|
10
|
-
const ISO_DATE_PART1 =
|
|
11
|
-
'[1-9]\\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)'
|
|
12
|
-
const ISO_DATE_PART2 = '(?:[1-9]\\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29'
|
|
13
|
-
const ISO_DATE = `(?:${ISO_DATE_PART1}|${ISO_DATE_PART2})`
|
|
14
|
-
const ISO_TIME_NO_MILLIS = '(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d'
|
|
15
|
-
const ISO_TIME = `${ISO_TIME_NO_MILLIS}(?:\\.\\d{1,9})?`
|
|
16
|
-
const ISO_DATE_TIME = `${ISO_DATE}T${ISO_TIME_NO_MILLIS}(?:Z|[+-][01]\\d:?[0-5]\\d)`
|
|
17
|
-
const ISO_TIMESTAMP = `${ISO_DATE}T${ISO_TIME}(?:Z|[+-][01]\\d:?[0-5]\\d)`
|
|
18
|
-
const ISO_DATE_REGEX = new RegExp(`^${ISO_DATE}$`, 'i')
|
|
19
|
-
const ISO_TIME_NO_MILLIS_REGEX = new RegExp(`^${ISO_TIME_NO_MILLIS}$`, 'i')
|
|
20
|
-
const ISO_DATE_TIME_REGEX = new RegExp(`^${ISO_DATE_TIME}$`, 'i')
|
|
21
|
-
const ISO_TIMESTAMP_REGEX = new RegExp(`^${ISO_TIMESTAMP}$`, 'i')
|
|
22
|
-
|
|
23
|
-
const _checkString = value => typeof value === 'string'
|
|
24
|
-
|
|
25
|
-
const _checkNumber = value => typeof value === 'number' && !Number.isNaN(value)
|
|
26
|
-
|
|
27
|
-
const _oldCheckDecimal = (value, element) => {
|
|
28
|
-
const [left, right] = String(value).split('.')
|
|
29
|
-
return (
|
|
30
|
-
_checkNumber(value) &&
|
|
31
|
-
(!element.precision || left.length <= element.precision - (element.scale || 0)) &&
|
|
32
|
-
(!element.scale || ((right || '').length <= element.scale && parseFloat(right) !== 0))
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// REVISIT: only use a cheaper check if not in strictDecimal mode?
|
|
37
|
-
const _checkDecimal = (v, ele, errs, path, k) => {
|
|
38
|
-
if (!errs) return _oldCheckDecimal(v, ele)
|
|
39
|
-
|
|
40
|
-
const { precision, scale } = ele
|
|
41
|
-
let val = getNormalizedDecimal(v)
|
|
42
|
-
if (precision != null && scale != null) {
|
|
43
|
-
let isValid = true
|
|
44
|
-
if (!val.match(/\./)) val += '.0'
|
|
45
|
-
if (precision === scale) {
|
|
46
|
-
if (!val.match(new RegExp(`^-?0\\.\\d{0,${scale}}$`, 'g'))) isValid = false
|
|
47
|
-
} else if (scale === 0) {
|
|
48
|
-
if (!val.match(new RegExp(`^-?\\d{1,${precision - scale}}\\.0{0,1}$`, 'g'))) isValid = false
|
|
49
|
-
} else if (!val.match(new RegExp(`^-?\\d{1,${precision - scale}}\\.\\d{0,${scale}}$`, 'g'))) {
|
|
50
|
-
isValid = false
|
|
51
|
-
}
|
|
52
|
-
if (!isValid) {
|
|
53
|
-
const args = [v, `Decimal(${precision},${scale})`]
|
|
54
|
-
const target = getTarget(path, k)
|
|
55
|
-
errs.push(new cds.error('ASSERT_DATA_TYPE', { args, target, statusCode: 400, code: '400' }))
|
|
56
|
-
}
|
|
57
|
-
} else if (precision != null) {
|
|
58
|
-
if (!val.match(new RegExp(`^-?\\d{1,${precision}}$`, 'g'))) {
|
|
59
|
-
const args = [v, `Decimal(${precision})`]
|
|
60
|
-
const target = getTarget(path, k)
|
|
61
|
-
errs.push(new cds.error('ASSERT_DATA_TYPE', { args, target, statusCode: 400, code: '400' }))
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const _checkInt = value => _checkNumber(value) && parseInt(value, 10) === value
|
|
67
|
-
|
|
68
|
-
const _checkInt64 = value => typeof value === 'string' ? value.match(/^\d+$/) : _checkInt(value)
|
|
69
|
-
|
|
70
|
-
const _checkBoolean = value => typeof value === 'boolean'
|
|
71
|
-
|
|
72
|
-
const _checkBuffer = value => Buffer.isBuffer(value) || value.type === 'Buffer' || isBase64String(value)
|
|
73
|
-
|
|
74
|
-
const _checkStreamOrBuffer = value => value instanceof Readable || _checkBuffer(value)
|
|
75
|
-
|
|
76
|
-
const _checkUUID = value => _checkString(value) && UUID_REGEX.test(value)
|
|
77
|
-
|
|
78
|
-
const _checkRelaxedUUID = value => _checkString(value) && RELAXED_UUID_REGEX.test(value)
|
|
79
|
-
|
|
80
|
-
const _checkISODate = value => (_checkString(value) && ISO_DATE_REGEX.test(value)) || value instanceof Date
|
|
81
|
-
|
|
82
|
-
const _checkISOTime = value => _checkString(value) && ISO_TIME_NO_MILLIS_REGEX.test(value)
|
|
83
|
-
|
|
84
|
-
const _checkISODateTime = value => (_checkString(value) && ISO_DATE_TIME_REGEX.test(value)) || value instanceof Date
|
|
85
|
-
|
|
86
|
-
const _checkISOTimestamp = value => (_checkString(value) && ISO_TIMESTAMP_REGEX.test(value)) || value instanceof Date
|
|
87
|
-
|
|
88
|
-
module.exports = {
|
|
89
|
-
'cds.UUID': _checkUUID,
|
|
90
|
-
'relaxed.UUID': _checkRelaxedUUID,
|
|
91
|
-
'cds.Boolean': _checkBoolean,
|
|
92
|
-
'cds.Integer': _checkInt,
|
|
93
|
-
'cds.UInt8': _checkInt,
|
|
94
|
-
'cds.Int16': _checkInt,
|
|
95
|
-
'cds.Int32': _checkInt,
|
|
96
|
-
'cds.Integer64': _checkInt64,
|
|
97
|
-
'cds.Int64': _checkInt64,
|
|
98
|
-
'cds.Decimal': _checkDecimal,
|
|
99
|
-
'cds.DecimalFloat': _checkNumber,
|
|
100
|
-
'cds.Double': _checkNumber,
|
|
101
|
-
'cds.Date': _checkISODate,
|
|
102
|
-
'cds.Time': _checkISOTime,
|
|
103
|
-
'cds.DateTime': _checkISODateTime,
|
|
104
|
-
'cds.Timestamp': _checkISOTimestamp,
|
|
105
|
-
'cds.String': _checkString,
|
|
106
|
-
'cds.Binary': _checkBuffer,
|
|
107
|
-
'cds.LargeString': _checkString,
|
|
108
|
-
'cds.LargeBinary': _checkStreamOrBuffer
|
|
109
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
const getNormalizedDecimal = val => {
|
|
2
|
-
let v = `${val}`
|
|
3
|
-
const cgs = v.match(/^(\d*\.*\d*)e([+|-]*)(\d*)$/)
|
|
4
|
-
if (cgs) {
|
|
5
|
-
let [l, r = ''] = cgs[1].split('.')
|
|
6
|
-
const dir = cgs[2] || '+'
|
|
7
|
-
const exp = Number(cgs[3])
|
|
8
|
-
if (dir === '+') {
|
|
9
|
-
// move decimal point to the right
|
|
10
|
-
r = r.padEnd(exp, '0')
|
|
11
|
-
l += r.substring(0, exp)
|
|
12
|
-
r = r.slice(exp)
|
|
13
|
-
v = `${l}${r ? '.' + r : ''}`
|
|
14
|
-
} else {
|
|
15
|
-
// move decimal point to the left
|
|
16
|
-
l = l.padStart(exp, '0')
|
|
17
|
-
r = l.substring(0, exp) + r
|
|
18
|
-
l = l.slice(exp)
|
|
19
|
-
v = `${l ? l : '0'}.${r}`
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return v
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function getTarget(path, k) {
|
|
26
|
-
return path.length && path[path.length - 1].match(/\[\d+\]$/) ? path.join('/') : path.concat(k).join('/')
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// non-strict mode also allows url-safe base64 strings
|
|
30
|
-
function isBase64String(string, strict = false) {
|
|
31
|
-
if (typeof string !== 'string') return false
|
|
32
|
-
|
|
33
|
-
if (strict && string.length % 4 !== 0) return false
|
|
34
|
-
|
|
35
|
-
let length = string.length
|
|
36
|
-
if (string.endsWith('==')) length -= 2
|
|
37
|
-
else if (string.endsWith('=')) length -= 1
|
|
38
|
-
|
|
39
|
-
let char
|
|
40
|
-
for (let i = 0; i < length; i++) {
|
|
41
|
-
char = string[i]
|
|
42
|
-
if (char >= 'A' && char <= 'Z') continue
|
|
43
|
-
else if (char >= 'a' && char <= 'z') continue
|
|
44
|
-
else if (char >= '0' && char <= '9') continue
|
|
45
|
-
else if (char === '+' || char === '/') continue
|
|
46
|
-
else if (!strict && (char === '-' || char === '_')) continue
|
|
47
|
-
return false
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return true
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
module.exports = {
|
|
57
|
-
getNormalizedDecimal,
|
|
58
|
-
getTarget,
|
|
59
|
-
isBase64String
|
|
60
|
-
}
|