@sap/cds 7.4.2 → 7.5.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 +94 -0
- package/apis/cds.d.ts +1 -38
- package/apis/core.d.ts +21 -101
- package/apis/cqn.d.ts +18 -76
- package/apis/csn.d.ts +18 -114
- package/apis/events.d.ts +16 -123
- package/apis/internal/inference.d.ts +18 -32
- package/apis/linked.d.ts +18 -97
- package/apis/log.d.ts +19 -164
- package/apis/models.d.ts +18 -180
- package/apis/ql.d.ts +16 -323
- package/apis/reflect.d.ts +32 -0
- package/apis/server.d.ts +18 -135
- package/apis/services.d.ts +18 -380
- package/bin/cds-serve.js +5 -2
- package/bin/serve.js +7 -16
- package/lib/auth/basic-auth.js +3 -1
- package/lib/auth/ias-auth.js +62 -48
- package/lib/auth/ias-claims.js +34 -0
- package/lib/auth/index.js +54 -33
- package/lib/auth/jwt-auth.js +55 -52
- package/lib/compile/cdsc.js +2 -2
- package/lib/compile/to/edm.js +4 -4
- package/lib/compile/to/hdbtabledata.js +5 -8
- package/lib/compile/to/srvinfo.js +2 -2
- package/lib/env/cds-env.js +3 -9
- package/lib/env/cds-requires.js +16 -17
- package/lib/env/compat.js +0 -9
- package/lib/env/defaults.js +17 -6
- package/lib/i18n/localize.js +46 -42
- package/lib/index.js +6 -8
- package/lib/linked/classes.js +7 -118
- package/lib/linked/entities.js +1 -1
- package/lib/log/cds-log.js +15 -10
- package/lib/log/format/aspects/als.js +41 -0
- package/lib/log/format/aspects/cf.js +36 -0
- package/lib/log/format/json.js +96 -0
- package/lib/plugins.js +7 -3
- package/lib/req/context.js +4 -2
- package/lib/srv/cds-connect.js +3 -5
- package/lib/srv/cds-serve.js +13 -26
- package/lib/srv/factory.js +3 -3
- package/lib/srv/middlewares/index.js +0 -2
- package/lib/srv/middlewares/trace.js +2 -3
- package/lib/srv/protocols/_legacy.js +27 -30
- package/lib/srv/protocols/index.js +173 -58
- package/lib/srv/protocols/odata-v4.js +29 -16
- package/lib/srv/srv-api.js +8 -13
- package/lib/srv/srv-handlers.js +14 -14
- package/lib/utils/cds-utils.js +15 -0
- package/libx/_runtime/auth/index.js +4 -5
- package/libx/_runtime/auth/strategies/basic.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +23 -13
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +6 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +10 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +5 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +2 -1
- package/libx/_runtime/cds-services/services/utils/columns.js +3 -9
- package/libx/_runtime/cds.js +13 -0
- package/libx/_runtime/common/composition/data.js +3 -0
- package/libx/_runtime/common/composition/delete.js +1 -1
- package/libx/_runtime/common/error/frontend.js +2 -2
- package/libx/_runtime/common/generic/auth/readOnly.js +1 -1
- package/libx/_runtime/common/generic/auth/restrictions.js +1 -1
- package/libx/_runtime/common/generic/sorting.js +4 -5
- package/libx/_runtime/common/utils/csn.js +23 -18
- package/libx/_runtime/common/utils/restrictions.js +6 -15
- package/libx/_runtime/db/generic/input.js +3 -2
- package/libx/_runtime/fiori/generic/readOverDraft.js +2 -5
- package/libx/_runtime/fiori/lean-draft.js +69 -5
- package/libx/_runtime/hana/Service.js +1 -1
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +1 -1
- package/libx/_runtime/messaging/Outbox.js +3 -8
- package/libx/_runtime/messaging/enterprise-messaging.js +1 -1
- package/libx/_runtime/messaging/file-based.js +1 -1
- package/libx/_runtime/messaging/service.js +7 -10
- package/libx/_runtime/remote/Service.js +15 -45
- package/libx/_runtime/remote/utils/client.js +20 -33
- package/libx/_runtime/remote/utils/cloudSdkProvider.js +30 -0
- package/libx/_runtime/sqlite/Service.js +2 -2
- package/libx/odata/afterburner.js +29 -21
- package/libx/odata/cqn2odata.js +1 -1
- package/libx/odata/error.js +7 -0
- package/libx/odata/grammar.peggy +16 -20
- package/libx/odata/metadata.js +73 -78
- package/libx/odata/parser.js +1 -1
- package/libx/odata/read.js +94 -0
- package/libx/odata/result.js +91 -0
- package/libx/odata/service-document.js +31 -37
- package/libx/odata/utils.js +2 -1
- package/libx/outbox/index.js +9 -4
- package/libx/rest/RestAdapter.js +68 -67
- package/libx/rest/middleware/create.js +20 -26
- package/libx/rest/middleware/delete.js +5 -3
- package/libx/rest/middleware/error.js +2 -3
- package/libx/rest/middleware/input.js +5 -5
- package/libx/rest/middleware/operation.js +96 -41
- package/libx/rest/middleware/parse.js +4 -6
- package/libx/rest/middleware/payload.js +5 -5
- package/libx/rest/middleware/read.js +11 -17
- package/libx/rest/middleware/update.js +20 -25
- package/package.json +2 -1
- package/server.js +7 -4
- package/srv/outbox.cds +9 -10
- package/apis/env.d.ts +0 -25
- package/apis/test.d.ts +0 -81
- package/apis/utils.d.ts +0 -15
- package/lib/auth/passport-basic.js +0 -14
- package/lib/auth/passport-digest.js +0 -16
- package/lib/env/presets.js +0 -35
- package/lib/log/format/cf.js +0 -16
- package/lib/log/format/kibana.js +0 -92
- package/lib/srv/middlewares/ctx-auth.js +0 -11
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +0 -119
package/lib/log/format/kibana.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
const cds = require ('../../')
|
|
2
|
-
const util = require('util')
|
|
3
|
-
|
|
4
|
-
const _l2l = { 1: 'error', 2: 'warn', 3: 'info', 4: 'debug', 5: 'trace' }
|
|
5
|
-
|
|
6
|
-
/*
|
|
7
|
-
* log formatter for kibana
|
|
8
|
-
*/
|
|
9
|
-
module.exports = exports = (module, level, ...args) => {
|
|
10
|
-
const toLog = exports.addFields(module, level, ...args)
|
|
11
|
-
return exports.format(toLog)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
exports.addFields = (module, level, ...args) => {
|
|
15
|
-
// config
|
|
16
|
-
const { user: log_user , kibana_custom_fields } = cds.env.log
|
|
17
|
-
|
|
18
|
-
// build the object to log
|
|
19
|
-
const toLog = {
|
|
20
|
-
level: _l2l[level] || 'info',
|
|
21
|
-
logger: module,
|
|
22
|
-
component_type: 'application'
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// add correlation
|
|
26
|
-
if (cds.context) {
|
|
27
|
-
const { id, tenant, user } = cds.context
|
|
28
|
-
toLog.correlation_id = id
|
|
29
|
-
if (tenant) toLog.tenant_id = tenant
|
|
30
|
-
// log user id, if configured (data privacy)
|
|
31
|
-
if (user && log_user) toLog.remote_user = user.id
|
|
32
|
-
// add headers, if available, with _ instead of -
|
|
33
|
-
const req = cds.context._ && cds.context._.req
|
|
34
|
-
if (req && req.headers)
|
|
35
|
-
for (const k in req.headers)
|
|
36
|
-
toLog[k.replace(/-/g, '_')] = (() => {
|
|
37
|
-
if (k.match(/authorization/i)) return `${req.headers[k].split(' ')[0]} ***`
|
|
38
|
-
if (k.match(/cookie/i)) return '***'
|
|
39
|
-
return req.headers[k]
|
|
40
|
-
})()
|
|
41
|
-
}
|
|
42
|
-
toLog.timestamp = new Date()
|
|
43
|
-
|
|
44
|
-
// merge toLog with passed Error (or error-like object)
|
|
45
|
-
if (args.length && typeof args[0] === 'object' && args[0].message) {
|
|
46
|
-
const err = args.shift()
|
|
47
|
-
toLog.msg = err.message
|
|
48
|
-
if (typeof err.stack === 'string') toLog.stacktrace = err.stack.split(/\s*\r?\n\s*/)
|
|
49
|
-
Object.assign(toLog, err, { level: toLog.level })
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// append remaining args via util.format()
|
|
53
|
-
if (args.length) toLog.msg = toLog.msg ? util.format(toLog.msg, ...args) : util.format(...args)
|
|
54
|
-
|
|
55
|
-
// 4xx: remove stack and lower to warning (if error)
|
|
56
|
-
if (toLog.code >= 400 && toLog.code < 500) {
|
|
57
|
-
delete toLog.stacktrace
|
|
58
|
-
if (toLog.level && toLog.level.match(/error/i)) toLog.level = 'warn'
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// kibana custom fields
|
|
62
|
-
if (kibana_custom_fields) {
|
|
63
|
-
const cf = []
|
|
64
|
-
for (const k in kibana_custom_fields) if (toLog[k]) cf.push({ k, v: toLog[k], i: kibana_custom_fields[k] })
|
|
65
|
-
if (cf.length) toLog['#cf'] = { string: cf }
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return toLog
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
exports.format = toLog => {
|
|
72
|
-
const getCircularReplacer = () => {
|
|
73
|
-
const seen = new WeakSet()
|
|
74
|
-
return (key, value) => {
|
|
75
|
-
if (typeof value === "object" && value !== null) {
|
|
76
|
-
if (seen.has(value)) {
|
|
77
|
-
return 'cyclic'
|
|
78
|
-
}
|
|
79
|
-
seen.add(value)
|
|
80
|
-
}
|
|
81
|
-
return value
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// return array with the stringified toLog (to avoid multiple log lines) as the sole element
|
|
86
|
-
try {
|
|
87
|
-
return [JSON.stringify(toLog)]
|
|
88
|
-
} catch (e) {
|
|
89
|
-
// try again with removed circular references
|
|
90
|
-
return [JSON.stringify(toLog, getCircularReplacer())]
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const cds = require ('../../index')
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Propagates auth results to cds.context
|
|
5
|
-
*/
|
|
6
|
-
module.exports = ()=> function cds_context_auth (req, res, next) {
|
|
7
|
-
const ctx = cds.context
|
|
8
|
-
ctx.user = req.user
|
|
9
|
-
ctx.tenant = req.tenant || ctx.user?.tenant
|
|
10
|
-
next()
|
|
11
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
const { processDeep } = require('../../../util/dataProcessUtils')
|
|
2
|
-
const { checkKeys, checkStatic, CDS_TYPE_CHECKS } = require('../../../util/assert')
|
|
3
|
-
const getError = require('../../../../common/error')
|
|
4
|
-
const { MULTIPLE_ERRORS } = require('../../../../common/error/constants')
|
|
5
|
-
const cds = require('../../../../cds')
|
|
6
|
-
|
|
7
|
-
const validationChecks = (event, data, target) => {
|
|
8
|
-
const checkResult = []
|
|
9
|
-
|
|
10
|
-
let validateFn
|
|
11
|
-
|
|
12
|
-
if (event === 'UPDATE' && Array.isArray(data)) {
|
|
13
|
-
validateFn = (entry, entity) => {
|
|
14
|
-
checkResult.push(...checkKeys(entity, entry))
|
|
15
|
-
checkResult.push(...checkStatic(entity, entry, true))
|
|
16
|
-
}
|
|
17
|
-
} else {
|
|
18
|
-
validateFn = (entry, entity) => {
|
|
19
|
-
checkResult.push(...checkStatic(entity, entry, true))
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// REVISIT: adopt template mechanism?
|
|
24
|
-
processDeep(validateFn, data, target, false, true)
|
|
25
|
-
|
|
26
|
-
if (checkResult.length === 0) {
|
|
27
|
-
// > all good
|
|
28
|
-
return
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (checkResult.length === 1) {
|
|
32
|
-
return checkResult[0]
|
|
33
|
-
} else {
|
|
34
|
-
return Object.assign(new Error(MULTIPLE_ERRORS), { details: checkResult })
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// REVISIT: use i18n
|
|
39
|
-
const _enrichErrorDetails = (isPrimitive, error) => {
|
|
40
|
-
const element = error.target ? ` '${error.target}' ` : ' '
|
|
41
|
-
const typeDetails = isPrimitive ? '.' : ` according to type definition '${error.type}'.`
|
|
42
|
-
const value = typeof error.value === 'string' ? `'${error.value}'` : error.value
|
|
43
|
-
if (element && element.match(/\w/)) return `Value ${value} of element${element}is invalid${typeDetails}`
|
|
44
|
-
return `Value ${value} is invalid${typeDetails}`
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// REVISIT: use i18n
|
|
48
|
-
const _getTypeError = (operation, type, errorDetails) => {
|
|
49
|
-
const typeErrors = errorDetails.map(error => _enrichErrorDetails(cds.builtin.types[type], error))
|
|
50
|
-
const msg = `Failed to validate return value ${type ? `of type '${type}' ` : ''}for custom ${operation.kind} '${
|
|
51
|
-
operation.name
|
|
52
|
-
}': ${typeErrors.join(' ')}`
|
|
53
|
-
return getError(msg)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const _buildTypeErrorObject = (type, value) => {
|
|
57
|
-
return { type, value }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Validate the return type values of custom operations (actions and functions) for primitive or complex values as
|
|
62
|
-
* single values or arrays.
|
|
63
|
-
*
|
|
64
|
-
* @param {Operation} operation
|
|
65
|
-
* @param {object} data
|
|
66
|
-
* @throws Will throw an error with error code 500 if the validation fails. Contains a detailed error message of the
|
|
67
|
-
* type and name of the custom operation, the invalid values, their names and their expected types.
|
|
68
|
-
* @returns {boolean} Returns true if return type validation has passed.
|
|
69
|
-
*/
|
|
70
|
-
const validateReturnType = (operation, data) => {
|
|
71
|
-
// array of or single return type
|
|
72
|
-
// in case of modeled return type: { type: 'bookModel.Books', _type: csnDefinition }
|
|
73
|
-
// in case of inline return type: { elements: ... } and no explicit name of return type
|
|
74
|
-
const returnType = operation.returns.items ? operation.returns.items : operation.returns
|
|
75
|
-
|
|
76
|
-
if (typeof data === 'undefined') return true
|
|
77
|
-
if (returnType['@open']) return true
|
|
78
|
-
|
|
79
|
-
let checkResult
|
|
80
|
-
|
|
81
|
-
// .type of action/function behaves different to .type of other csn elements
|
|
82
|
-
// Return type contains primitives
|
|
83
|
-
// eslint-disable-next-line no-proto
|
|
84
|
-
const _type = typeof returnType._type === 'object' ? returnType.__proto__._type : returnType._type // REVISIT: super dirty hack for compiler's to.edmx polluting the csn definitions with ._type -> please use Symbols instead
|
|
85
|
-
const check = CDS_TYPE_CHECKS[_type] // IMPORTANT: use ._type
|
|
86
|
-
if (check) {
|
|
87
|
-
const array = Array.isArray(data) ? data : [data]
|
|
88
|
-
checkResult = array.filter(value => !check(value)).map(value => _buildTypeErrorObject(_type, value))
|
|
89
|
-
} else {
|
|
90
|
-
if (typeof data !== 'object') {
|
|
91
|
-
throw new Error(
|
|
92
|
-
`Invalid scalar value ${typeof data === 'string' ? `"${data}"` : data} for return type "${returnType.type}"`
|
|
93
|
-
)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Only check complex objects, ignore non-modelled data
|
|
97
|
-
data = (Array.isArray(data) ? data : [data]).filter(entry => typeof entry === 'object' && !Array.isArray(entry))
|
|
98
|
-
|
|
99
|
-
// Determine entity from bound or unbound action/function
|
|
100
|
-
const returnTypeCsnDefinition = returnType._type || returnType
|
|
101
|
-
|
|
102
|
-
// REVISIT: remove exception with cds^6
|
|
103
|
-
// mtx returns object instead of string (as in modell) -> skip validation
|
|
104
|
-
if (returnTypeCsnDefinition.type !== 'cds.String') {
|
|
105
|
-
checkResult = checkStatic(returnTypeCsnDefinition, data, true)
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (checkResult && checkResult.length !== 0) {
|
|
110
|
-
throw _getTypeError(operation, returnType.type, checkResult)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return true
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
module.exports = {
|
|
117
|
-
validationChecks,
|
|
118
|
-
validateReturnType
|
|
119
|
-
}
|