@sap/cds 5.4.6 → 5.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 +208 -2
- package/apis/ql.d.ts +17 -15
- package/app/index.js +1 -1
- package/bin/build/buildTaskEngine.js +26 -42
- package/bin/build/buildTaskFactory.js +6 -10
- package/bin/build/buildTaskHandler.js +2 -4
- package/bin/build/buildTaskProvider.js +3 -1
- package/bin/build/buildTaskProviderFactory.js +9 -15
- package/bin/build/constants.js +15 -3
- package/bin/build/index.js +5 -4
- package/bin/build/mtaUtil.js +8 -11
- package/bin/build/provider/buildTaskHandlerEdmx.js +63 -6
- package/bin/build/provider/buildTaskHandlerInternal.js +2 -34
- package/bin/build/provider/buildTaskProviderInternal.js +16 -42
- package/bin/build/provider/fiori/index.js +13 -24
- package/bin/build/provider/hana/2migration.js +17 -15
- package/bin/build/provider/hana/2tabledata.js +52 -48
- package/bin/build/provider/hana/index.js +27 -25
- package/bin/build/provider/hana/migrationtable.js +91 -67
- package/bin/build/provider/java-cf/index.js +14 -24
- package/bin/build/provider/mtx/index.js +12 -14
- package/bin/build/provider/node-cf/index.js +18 -32
- package/bin/cds.js +5 -5
- package/bin/serve.js +29 -23
- package/bin/version.js +0 -1
- package/lib/compile/etc/_localized.js +4 -9
- package/lib/compile/for/sql.js +5 -2
- package/lib/compile/parse.js +25 -17
- package/lib/compile/to/srvinfo.js +2 -1
- package/lib/connect/bindings.js +2 -1
- package/lib/connect/index.js +48 -49
- package/lib/core/classes.js +1 -1
- package/lib/core/reflect.js +10 -2
- package/lib/deploy.js +26 -23
- package/lib/env/defaults.js +13 -6
- package/lib/env/index.js +73 -78
- package/lib/env/requires.js +38 -19
- package/lib/index.js +9 -10
- package/lib/lazy.js +2 -2
- package/lib/log/index.js +33 -45
- package/lib/log/service/index.js +2 -2
- package/lib/ql/CREATE.js +14 -9
- package/lib/ql/DELETE.js +6 -5
- package/lib/ql/DROP.js +12 -9
- package/lib/ql/INSERT.js +40 -16
- package/lib/ql/Query.js +67 -40
- package/lib/ql/SELECT.js +162 -127
- package/lib/ql/UPDATE.js +74 -42
- package/lib/ql/Whereable.js +77 -87
- package/lib/ql/index.js +36 -24
- package/lib/ql/parse.js +35 -0
- package/lib/req/context.js +44 -8
- package/lib/req/locale.js +7 -7
- package/lib/serve/Service-api.js +21 -14
- package/lib/serve/Service-dispatch.js +28 -12
- package/lib/serve/Transaction.js +22 -10
- package/lib/serve/index.js +16 -11
- package/lib/utils/axios.js +23 -16
- package/lib/utils/data.js +35 -0
- package/lib/utils/tests.js +27 -18
- package/libx/_runtime/audit/generic/personal/access.js +81 -0
- package/libx/_runtime/audit/generic/personal/constants.js +4 -0
- package/libx/_runtime/audit/generic/personal/index.js +50 -0
- package/libx/_runtime/audit/generic/personal/modification.js +138 -0
- package/libx/_runtime/audit/generic/personal/utils.js +186 -0
- package/libx/_runtime/audit/utils/v2.js +10 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +5 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +5 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +2 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +4 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +7 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +59 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +11 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +6 -10
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +3 -46
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +2 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/createToCQN.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/deleteToCQN.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +1 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +0 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectHelper.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/updateToCQN.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +16 -18
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityType.js +6 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/format/RepresentationKind.js +4 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/OdataRequest.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +15 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/validator/OperationValidator.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +8 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +6 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +12 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +1 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +7 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +14 -18
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +13 -13
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -1
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +2 -1
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +2 -2
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +2 -4
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +4 -2
- package/libx/_runtime/cds-services/services/Service.js +40 -5
- package/libx/_runtime/cds-services/services/utils/columns.js +13 -7
- package/libx/_runtime/cds-services/services/utils/compareJson.js +88 -4
- package/libx/_runtime/cds-services/services/utils/differ.js +24 -6
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +2 -2
- package/libx/_runtime/common/composition/data.js +44 -55
- package/libx/_runtime/common/composition/delete.js +97 -71
- package/libx/_runtime/common/composition/index.js +2 -1
- package/libx/_runtime/common/composition/insert.js +34 -11
- package/libx/_runtime/common/composition/tree.js +119 -92
- package/libx/_runtime/common/composition/update.js +4 -1
- package/libx/_runtime/common/composition/utils.js +1 -3
- package/libx/_runtime/common/constants/draft.js +12 -1
- package/libx/_runtime/common/generic/auth.js +6 -22
- package/libx/_runtime/common/generic/crud.js +14 -13
- package/libx/_runtime/common/generic/input.js +23 -26
- package/libx/_runtime/common/generic/put.js +1 -1
- package/libx/_runtime/common/generic/sorting.js +16 -16
- package/libx/_runtime/common/i18n/index.js +1 -1
- package/libx/_runtime/common/i18n/messages.properties +4 -0
- package/libx/_runtime/common/utils/backlinks.js +12 -5
- package/libx/_runtime/common/utils/cqn.js +6 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +102 -101
- package/libx/_runtime/common/utils/csn.js +47 -4
- package/libx/_runtime/common/utils/data.js +0 -37
- package/libx/_runtime/common/utils/enrichWithKeysFromWhere.js +1 -1
- package/libx/_runtime/common/utils/entityFromCqn.js +7 -24
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +39 -7
- package/libx/_runtime/common/utils/generateOnCond.js +11 -12
- package/libx/_runtime/common/utils/onlyKeysRemain.js +10 -0
- package/libx/_runtime/common/utils/path.js +35 -0
- package/libx/_runtime/common/utils/postProcessing.js +86 -0
- package/libx/_runtime/common/utils/quotingStyles.js +37 -26
- package/libx/_runtime/common/utils/resolveView.js +223 -171
- package/libx/_runtime/common/utils/rewriteAsterisk.js +46 -26
- package/libx/_runtime/common/utils/structured.js +6 -12
- package/libx/_runtime/common/utils/template.js +10 -5
- package/libx/_runtime/common/utils/templateDelimiter.js +1 -0
- package/libx/_runtime/common/utils/templateProcessor.js +22 -30
- package/libx/_runtime/common/utils/union.js +31 -0
- package/libx/_runtime/common/utils/unionCqnTemplate.js +184 -0
- package/libx/_runtime/db/Service.js +1 -1
- package/libx/_runtime/db/data-conversion/timestamp.js +2 -9
- package/libx/_runtime/db/expand/expandCQNToJoin.js +204 -297
- package/libx/_runtime/db/expand/index.js +3 -3
- package/libx/_runtime/db/expand/rawToExpanded.js +36 -7
- package/libx/_runtime/db/generic/index.js +1 -1
- package/libx/_runtime/db/generic/input.js +5 -7
- package/libx/_runtime/db/generic/integrity.js +1 -1
- package/libx/_runtime/db/generic/rewrite.js +2 -10
- package/libx/_runtime/db/generic/update.js +13 -5
- package/libx/_runtime/db/generic/virtual.js +22 -58
- package/libx/_runtime/db/query/delete.js +7 -4
- package/libx/_runtime/db/query/insert.js +6 -4
- package/libx/_runtime/db/query/read.js +13 -20
- package/libx/_runtime/db/query/run.js +4 -1
- package/libx/_runtime/db/query/update.js +5 -4
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +35 -2
- package/libx/_runtime/db/sql-builder/FunctionBuilder.js +17 -2
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +6 -5
- package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +10 -0
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +35 -24
- package/libx/_runtime/db/sql-builder/UpdateBuilder.js +14 -4
- package/libx/_runtime/db/sql-builder/arrayed.js +4 -0
- package/libx/_runtime/db/utils/deep.js +8 -0
- package/libx/_runtime/db/utils/generateAliases.js +2 -1
- package/libx/_runtime/fiori/generic/activate.js +19 -15
- package/libx/_runtime/fiori/generic/before.js +3 -11
- package/libx/_runtime/fiori/generic/cancel.js +1 -1
- package/libx/_runtime/fiori/generic/delete.js +3 -1
- package/libx/_runtime/fiori/generic/edit.js +12 -2
- package/libx/_runtime/fiori/generic/new.js +5 -5
- package/libx/_runtime/fiori/generic/patch.js +0 -18
- package/libx/_runtime/fiori/generic/read.js +241 -189
- package/libx/_runtime/fiori/utils/delete.js +36 -7
- package/libx/_runtime/fiori/utils/handler.js +43 -44
- package/libx/_runtime/fiori/utils/where.js +30 -15
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +4 -6
- package/libx/_runtime/hana/execute.js +2 -2
- package/libx/_runtime/hana/localized.js +4 -4
- package/libx/_runtime/hana/pool.js +29 -14
- package/libx/_runtime/hana/search2cqn4sql.js +2 -1
- package/libx/_runtime/hana/searchToContains.js +18 -14
- package/libx/_runtime/index.js +0 -5
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +13 -5
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +4 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +31 -19
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +1 -2
- package/libx/_runtime/messaging/enterprise-messaging.js +6 -4
- package/libx/_runtime/messaging/service.js +7 -6
- package/libx/_runtime/odata/cqn2odata.js +110 -43
- package/libx/_runtime/odata/index.js +26 -48
- package/libx/_runtime/odata/odata2cqn.js +1 -6154
- package/libx/_runtime/odata/odata2cqn.pegjs +559 -0
- package/libx/_runtime/odata/readToCqn.js +94 -64
- package/libx/_runtime/remote/Service.js +74 -21
- package/libx/_runtime/remote/cqn2odata/index.js +1 -5
- package/libx/_runtime/remote/utils/client.js +24 -101
- package/libx/_runtime/remote/utils/dataConversion.js +27 -12
- package/libx/_runtime/sqlite/Service.js +3 -5
- package/libx/_runtime/sqlite/execute.js +23 -24
- package/libx/_runtime/sqlite/localized.js +12 -7
- package/libx/_runtime/types/api.js +10 -0
- package/package.json +1 -1
- package/server.js +16 -2
- package/lib/ql/grammar.pegjs +0 -208
- package/lib/ql/parser.js +0 -1
- package/lib/ql/rt/DELETE.js +0 -29
- package/lib/ql/rt/INSERT.js +0 -23
- package/lib/ql/rt/Query.js +0 -84
- package/lib/ql/rt/SELECT.js +0 -174
- package/lib/ql/rt/UPDATE.js +0 -119
- package/lib/ql/rt/_helpers.js +0 -91
- package/lib/ql/rt/index.js +0 -32
- package/libx/_runtime/audit/generic/personal.js +0 -260
- package/libx/_runtime/cds-services/statements/BaseStatement.js +0 -72
- package/libx/_runtime/cds-services/statements/Create.js +0 -57
- package/libx/_runtime/cds-services/statements/Delete.js +0 -33
- package/libx/_runtime/cds-services/statements/Drop.js +0 -42
- package/libx/_runtime/cds-services/statements/Insert.js +0 -201
- package/libx/_runtime/cds-services/statements/Select.js +0 -826
- package/libx/_runtime/cds-services/statements/Update.js +0 -181
- package/libx/_runtime/cds-services/statements/Where.js +0 -726
- package/libx/_runtime/cds-services/statements/index.js +0 -25
- package/libx/_runtime/common/generic/resolve-mock.js +0 -9
|
@@ -30,5 +30,16 @@ module.exports = {
|
|
|
30
30
|
{ ref: ['HasActiveEntity'], cast: { type: 'cds.Boolean' } },
|
|
31
31
|
{ ref: ['HasDraftEntity'], cast: { type: 'cds.Boolean' } },
|
|
32
32
|
{ ref: ['DraftAdministrativeData_DraftUUID'] }
|
|
33
|
-
]
|
|
33
|
+
],
|
|
34
|
+
SCENARIO: {
|
|
35
|
+
ACTIVE: 'ACTIVE',
|
|
36
|
+
ACTIVE_WITHOUT_DRAFT: 'ACTIVE_WITHOUT_DRAFT',
|
|
37
|
+
ALL_ACTIVE: 'ALL_ACTIVE',
|
|
38
|
+
ALL_INACTIVE: 'ALL_INACTIVE',
|
|
39
|
+
DRAFT_ADMIN: 'DRAFT_ADMIN',
|
|
40
|
+
DRAFT_IN_PROCESS: 'DRAFT_IN_PROCESS',
|
|
41
|
+
DRAFT_WHICH_OWNER: 'DRAFT_WHICH_OWNER',
|
|
42
|
+
SIBLING_ENTITY: 'SIBLING_ENTITY',
|
|
43
|
+
UNION: 'UNION'
|
|
44
|
+
}
|
|
34
45
|
}
|
|
@@ -26,9 +26,6 @@ const RESTRICTIONS = {
|
|
|
26
26
|
DELETABLE: 'DeleteRestrictions.Deletable'
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
// REVISIT: remove everywhere
|
|
30
|
-
const SYMBOL_FROM_ANNOTATION = Symbol.for('sap.cds.FROM_ANNOTATION')
|
|
31
|
-
|
|
32
29
|
const _reject = req => {
|
|
33
30
|
// unauthorized or forbidden?
|
|
34
31
|
if (req.user._is_anonymous) {
|
|
@@ -177,19 +174,10 @@ const _evalStatic = (op, vals) => {
|
|
|
177
174
|
}
|
|
178
175
|
}
|
|
179
176
|
|
|
180
|
-
const _addSymbol = element => {
|
|
181
|
-
// NOTE: will not be needed with cds^5.5 as the symbol was removed
|
|
182
|
-
if (cds.env.features.skip_restrict_symbol) return element
|
|
183
|
-
|
|
184
|
-
element = typeof element === 'string' ? new String(element) : element
|
|
185
|
-
element[SYMBOL_FROM_ANNOTATION] = true
|
|
186
|
-
return element
|
|
187
|
-
}
|
|
188
|
-
|
|
189
177
|
const _getMergedWhere = restricts => {
|
|
190
178
|
const xprs = []
|
|
191
179
|
restricts.forEach(ele => {
|
|
192
|
-
xprs.push('(', ...ele._xpr
|
|
180
|
+
xprs.push('(', ...ele._xpr, ')', 'or')
|
|
193
181
|
})
|
|
194
182
|
xprs.pop()
|
|
195
183
|
return xprs
|
|
@@ -245,16 +233,9 @@ const _ensureTableAlias = (ref, aliases, targetFrom, model, hasExpand) => {
|
|
|
245
233
|
} else {
|
|
246
234
|
_adaptTableName(ref, nameObj.refIndex, nameObj.name)
|
|
247
235
|
}
|
|
248
|
-
|
|
249
|
-
if (hasExpand && nameObj.aliasIndex === 0) {
|
|
250
|
-
_addSymbol(ref)
|
|
251
|
-
}
|
|
252
236
|
}
|
|
253
237
|
|
|
254
238
|
const _enhanceAnnotationSubSelect = (select, model, targetName, targetFrom, hasExpand) => {
|
|
255
|
-
if (select.from && select.from.ref) {
|
|
256
|
-
_addSymbol(select.from.ref)
|
|
257
|
-
}
|
|
258
239
|
if (select.where) {
|
|
259
240
|
for (const v of select.where) {
|
|
260
241
|
if (v.ref && select.from.ref) {
|
|
@@ -384,8 +365,10 @@ const _getRestrictionForTarget = (resolvedApplicables, target) => {
|
|
|
384
365
|
}
|
|
385
366
|
|
|
386
367
|
const _addRestrictionsToRead = async (req, model, resolvedApplicables) => {
|
|
387
|
-
|
|
388
|
-
|
|
368
|
+
if (req.target._isDraftEnabled) {
|
|
369
|
+
req.query._draftRestrictions = resolvedApplicables.map(ra => ra._xpr)
|
|
370
|
+
return
|
|
371
|
+
}
|
|
389
372
|
|
|
390
373
|
if (typeof req.query.SELECT.from === 'object')
|
|
391
374
|
req.query.SELECT.from.ref = _addWheresToRef(req.query.SELECT.from.ref, model, resolvedApplicables)
|
|
@@ -393,6 +376,7 @@ const _addRestrictionsToRead = async (req, model, resolvedApplicables) => {
|
|
|
393
376
|
const restrictionForTarget = _getRestrictionForTarget(resolvedApplicables, req.target)
|
|
394
377
|
if (restrictionForTarget) {
|
|
395
378
|
req.query.where(restrictionForTarget)
|
|
379
|
+
// REVISIT: remove with cds^6
|
|
396
380
|
_enhanceAnnotationWhere(req.query, restrictionForTarget, model)
|
|
397
381
|
}
|
|
398
382
|
}
|
|
@@ -5,16 +5,7 @@ const getTemplate = require('../utils/template')
|
|
|
5
5
|
const templateProcessor = require('../utils/templateProcessor')
|
|
6
6
|
const replaceManagedData = require('../utils/dollar')
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
// if custom handlers uses only expression like {col: {'+=': 1}},
|
|
10
|
-
// req.data will only contain the keys
|
|
11
|
-
if (req.query.UPDATE.with && Object.keys(req.query.UPDATE.with).length > 0) {
|
|
12
|
-
return false
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const keys = Object.keys(req.target.keys)
|
|
16
|
-
return !Object.keys(req.data).some(k => !keys.includes(k))
|
|
17
|
-
}
|
|
8
|
+
const onlyKeysRemain = require('../utils/onlyKeysRemain')
|
|
18
9
|
|
|
19
10
|
const _targetEntityDoesNotExist = async req => {
|
|
20
11
|
const { query } = req
|
|
@@ -39,7 +30,7 @@ const _processorFn = req => {
|
|
|
39
30
|
const { event, user, timestamp } = req
|
|
40
31
|
const ts = new Date(timestamp).toISOString()
|
|
41
32
|
|
|
42
|
-
return (row, key,
|
|
33
|
+
return ({ row, key, plain }) => {
|
|
43
34
|
const categories = plain.categories
|
|
44
35
|
|
|
45
36
|
for (const category of categories) {
|
|
@@ -89,8 +80,8 @@ module.exports = function () {
|
|
|
89
80
|
|
|
90
81
|
let result
|
|
91
82
|
|
|
92
|
-
// no changes, no op (otherwise, @cds.on.update gets new values), but we need to check
|
|
93
|
-
if (req.event === 'UPDATE' &&
|
|
83
|
+
// no changes, no op (otherwise, @cds.on.update gets new values), but we need to check existence
|
|
84
|
+
if (req.event === 'UPDATE' && onlyKeysRemain(req)) {
|
|
94
85
|
if (await _targetEntityDoesNotExist(req)) {
|
|
95
86
|
req.reject(404)
|
|
96
87
|
}
|
|
@@ -98,6 +89,16 @@ module.exports = function () {
|
|
|
98
89
|
result = req.data
|
|
99
90
|
}
|
|
100
91
|
|
|
92
|
+
if (req.event === 'DELETE' && req.target._isSingleton) {
|
|
93
|
+
if (!req.target['@odata.singleton.nullable']) {
|
|
94
|
+
req.reject(400, 'SINGLETON_NOT_NULLABLE')
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const singleton = await cds.tx(req).run(SELECT.one(req.target))
|
|
98
|
+
if (!singleton) req.reject(404)
|
|
99
|
+
req.query.where(singleton)
|
|
100
|
+
}
|
|
101
|
+
|
|
101
102
|
if (!result) {
|
|
102
103
|
result = await cds.tx(req).run(req.query, req.data)
|
|
103
104
|
}
|
|
@@ -16,9 +16,8 @@ const templateProcessor = require('../utils/templateProcessor')
|
|
|
16
16
|
const { getDataFromCQN, setDataFromCQN } = require('../utils/data')
|
|
17
17
|
const { isMandatory, isReadOnly } = require('../aspects/utils')
|
|
18
18
|
|
|
19
|
-
const shouldSuppressErrorPropagation = ({ event, value
|
|
19
|
+
const shouldSuppressErrorPropagation = ({ event, value }) => {
|
|
20
20
|
return (
|
|
21
|
-
suppress ||
|
|
22
21
|
event === 'NEW' ||
|
|
23
22
|
event === 'PATCH' ||
|
|
24
23
|
(event === 'UPDATE' && value.val === undefined) ||
|
|
@@ -35,7 +34,7 @@ const getSimpleCategory = category => {
|
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
const rowKeysGenerator = eventName => {
|
|
38
|
-
return (
|
|
37
|
+
return (keyNames, row, template) => {
|
|
39
38
|
if (eventName === 'UPDATE') return
|
|
40
39
|
|
|
41
40
|
for (const keyName of keyNames) {
|
|
@@ -96,7 +95,7 @@ const _processCategory = ({ row, key, category, isRoot, event, value, req, eleme
|
|
|
96
95
|
const processorFn = (errors, req) => {
|
|
97
96
|
const { event } = req
|
|
98
97
|
|
|
99
|
-
return (row, key, element, plain, isRoot, pathSegments
|
|
98
|
+
return ({ row, key, element, plain, isRoot, pathSegments }) => {
|
|
100
99
|
const categories = plain.categories
|
|
101
100
|
// ugly pointer passing for sonar
|
|
102
101
|
const value = { mandatory: false, val: row && row[key] }
|
|
@@ -105,7 +104,7 @@ const processorFn = (errors, req) => {
|
|
|
105
104
|
_processCategory({ row, key, category, isRoot, event, value, req, element })
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
if (shouldSuppressErrorPropagation({ event, value
|
|
107
|
+
if (shouldSuppressErrorPropagation({ event, value })) {
|
|
109
108
|
return
|
|
110
109
|
}
|
|
111
110
|
|
|
@@ -211,34 +210,30 @@ function _handler(req) {
|
|
|
211
210
|
_callError(req, errors)
|
|
212
211
|
}
|
|
213
212
|
|
|
214
|
-
const processorFnForActionsFunctions =
|
|
215
|
-
|
|
213
|
+
const processorFnForActionsFunctions =
|
|
214
|
+
(errors, opName) =>
|
|
215
|
+
({ row, key, element }) => {
|
|
216
|
+
const value = row && row[key]
|
|
216
217
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const KINDS_TO_VALIDATE = {
|
|
222
|
-
entity: 1,
|
|
223
|
-
type: 1
|
|
224
|
-
}
|
|
218
|
+
// REVISIT: Convert checkInputConstraints to template mechanism
|
|
219
|
+
checkInputConstraints({ element, value, errors, key: opName })
|
|
220
|
+
}
|
|
225
221
|
|
|
226
222
|
const _processActionFunctionRow = (row, param, key, errors, event, service) => {
|
|
227
223
|
const values = Array.isArray(row[key]) ? row[key] : [row[key]]
|
|
228
|
-
|
|
229
224
|
// unstructured
|
|
230
225
|
for (const value of values) {
|
|
231
226
|
checkInputConstraints({ element: param, value, errors, key })
|
|
232
227
|
}
|
|
233
228
|
|
|
234
229
|
// structured
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
230
|
+
const template = getTemplate('app-input-operation', service, param, {
|
|
231
|
+
pick: _pick
|
|
232
|
+
})
|
|
233
|
+
if (template && template.elements.size) {
|
|
234
|
+
for (const value of values) {
|
|
235
|
+
const args = { processFn: processorFnForActionsFunctions(errors, key), row: value, template }
|
|
236
|
+
templateProcessor(args)
|
|
242
237
|
}
|
|
243
238
|
}
|
|
244
239
|
}
|
|
@@ -246,7 +241,8 @@ const _processActionFunctionRow = (row, param, key, errors, event, service) => {
|
|
|
246
241
|
const _processActionFunction = (row, eventParams, errors, event, service) => {
|
|
247
242
|
for (const key in eventParams) {
|
|
248
243
|
let param = eventParams[key]
|
|
249
|
-
|
|
244
|
+
const _type = param.type
|
|
245
|
+
if (!_type && param.items) param = param.items
|
|
250
246
|
_processActionFunctionRow(row, param, key, errors, event, service)
|
|
251
247
|
}
|
|
252
248
|
}
|
|
@@ -280,8 +276,9 @@ function _actionFunctionHandler(req) {
|
|
|
280
276
|
// REVISIT: find better solution, maybe compiler?
|
|
281
277
|
// resolve enums like format, range, etc.
|
|
282
278
|
for (const param of Object.values(eventParams)) {
|
|
283
|
-
|
|
284
|
-
|
|
279
|
+
const _type = param.type && this.model && this.model.definitions[param.type]
|
|
280
|
+
if (_type) {
|
|
281
|
+
param.enum = _type.enum
|
|
285
282
|
}
|
|
286
283
|
}
|
|
287
284
|
|
|
@@ -25,7 +25,7 @@ const _fillStructure = (row, parts, element, category, args) => {
|
|
|
25
25
|
const processorFn = req => {
|
|
26
26
|
const REST = req.constructor.name === 'RestRequest'
|
|
27
27
|
|
|
28
|
-
return (row, key, element, plain) => {
|
|
28
|
+
return ({ row, key, element, plain }) => {
|
|
29
29
|
if (!row || row[key] !== undefined) return
|
|
30
30
|
|
|
31
31
|
const { category, args } = plain
|
|
@@ -5,7 +5,6 @@ const DRAFT_COLUMNS = ['IsActiveEntity', 'HasDraftEntity', 'HasActiveEntity']
|
|
|
5
5
|
|
|
6
6
|
const _getStaticOrders = req => {
|
|
7
7
|
const { target: entity, query } = req
|
|
8
|
-
|
|
9
8
|
const defaultOrders = entity['@cds.default.order'] || entity['@odata.default.order'] || []
|
|
10
9
|
|
|
11
10
|
if (!cds._deprecationWarningForDefaultSort && defaultOrders.length > 0) {
|
|
@@ -60,25 +59,26 @@ const _handler = function (req) {
|
|
|
60
59
|
|
|
61
60
|
// remove defaultOrder if not part of group by
|
|
62
61
|
if (select.groupBy && select.groupBy.length > 0) {
|
|
63
|
-
staticOrders = staticOrders.filter(d =>
|
|
64
|
-
return select.groupBy.find(e => e.ref[0] === d.by['='])
|
|
65
|
-
})
|
|
62
|
+
staticOrders = staticOrders.filter(d => select.groupBy.find(e => e.ref[0] === d.by['=']))
|
|
66
63
|
}
|
|
67
64
|
|
|
65
|
+
if (!select.orderBy && staticOrders.length === 0) return
|
|
68
66
|
select.orderBy = select.orderBy || []
|
|
67
|
+
|
|
69
68
|
for (const defaultOrder of staticOrders) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
69
|
+
const some = select.orderBy.some(orderBy => {
|
|
70
|
+
const managedKey = orderBy.ref && orderBy.ref.length > 1 && orderBy.ref.join('_')
|
|
71
|
+
const element = managedKey && req.target.elements[managedKey]
|
|
72
|
+
const isManagedKey = element && element.key && !element.is2one
|
|
73
|
+
|
|
74
|
+
// don't add duplicates
|
|
75
|
+
return (
|
|
76
|
+
(orderBy.ref && orderBy.ref.length === 1 && orderBy.ref[0] === defaultOrder.by['=']) ||
|
|
77
|
+
(isManagedKey && managedKey === defaultOrder.by['='])
|
|
78
|
+
)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
if (!some) {
|
|
82
82
|
const orderByItem = { ref: [defaultOrder.by['=']], sort: defaultOrder.desc ? 'desc' : 'asc' }
|
|
83
83
|
select.orderBy.push(orderByItem)
|
|
84
84
|
}
|
|
@@ -98,7 +98,7 @@ module.exports = (key, locale = '', args = {}) => {
|
|
|
98
98
|
|
|
99
99
|
// for locale OR app default OR cds default
|
|
100
100
|
let text = i18ns[locale][key] || i18ns[''][key] || i18ns.default[key]
|
|
101
|
-
|
|
101
|
+
if (!text) return
|
|
102
102
|
// best effort replacement
|
|
103
103
|
try {
|
|
104
104
|
const matches = text.match(/\{[\w][\w]*\}/g) || []
|
|
@@ -71,6 +71,7 @@ ENTITY_IS_READ_ONLY=Entity "{0}" is read-only
|
|
|
71
71
|
ENTITY_IS_NOT_CRUD=Entity "{0}" is not {1}
|
|
72
72
|
ENTITY_IS_NOT_CRUD_VIA_NAVIGATION=Entity "{0}" is not {1} via association "{2}"
|
|
73
73
|
ENTITY_IS_AUTOEXPOSED=Entity "{0}" is not explicitely exposed as part of the service
|
|
74
|
+
EXPAND_IS_RESTRICTED=Navigation property "{0}" is not allowed for expand operation
|
|
74
75
|
|
|
75
76
|
# rest protocol adapter
|
|
76
77
|
INVALID_RESOURCE="{0}" is not a valid resource
|
|
@@ -87,3 +88,6 @@ CRUD_VIA_NAVIGATION_NOT_SUPPORTED=CRUD via navigations is not yet supported
|
|
|
87
88
|
# draft
|
|
88
89
|
DRAFT_ALREADY_EXISTS=A draft for this entity already exists
|
|
89
90
|
DRAFT_LOCKED_BY_ANOTHER_USER=The entity is locked by another user
|
|
91
|
+
|
|
92
|
+
# singleton
|
|
93
|
+
SINGLETON_NOT_NULLABLE=The singleton entity is not nullable
|
|
@@ -33,15 +33,22 @@ const _getBacklinkNameFromOnCond = element => {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const isBacklink = (element, parent, checkContained) => {
|
|
36
|
+
const isBacklink = (element, parent, checkContained, backLinkName) => {
|
|
37
37
|
if (!element._isAssociationStrict) return false
|
|
38
38
|
if (!parent || !(element.keys || element.on)) return false
|
|
39
39
|
if (element.target !== parent.name) return false
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
const _isBackLink = parentElement =>
|
|
42
|
+
(!checkContained || parentElement._isContained) && _getBacklinkNameFromOnCond(parentElement) === element.name
|
|
43
|
+
|
|
44
|
+
if (backLinkName) {
|
|
45
|
+
const parentElement = parent.elements[backLinkName]
|
|
46
|
+
return parentElement.isAssociation && _isBackLink(parentElement)
|
|
47
|
+
}
|
|
48
|
+
for (const parentElementName in parent.elements) {
|
|
49
|
+
const parentElement = parent.elements[parentElementName]
|
|
50
|
+
if (!parentElement.isAssociation) continue
|
|
51
|
+
if (_isBackLink(parentElement)) return true
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
return false
|
|
@@ -12,6 +12,11 @@ const getEntityNameFromDeleteCQN = cqn => {
|
|
|
12
12
|
return from
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
const getEntityNameFromUpdateCQN = cqn => {
|
|
16
|
+
return (cqn.UPDATE.entity.ref && cqn.UPDATE.entity.ref[0]) || cqn.UPDATE.entity.name || cqn.UPDATE.entity
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
module.exports = {
|
|
16
|
-
getEntityNameFromDeleteCQN
|
|
20
|
+
getEntityNameFromDeleteCQN,
|
|
21
|
+
getEntityNameFromUpdateCQN
|
|
17
22
|
}
|