@sap/cds 5.5.3 → 5.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 +134 -1
- package/apis/services.d.ts +27 -1
- package/app/index.js +22 -11
- package/bin/build/buildTaskFactory.js +1 -1
- package/bin/build/provider/buildTaskProviderInternal.js +1 -1
- package/bin/build/provider/fiori/index.js +1 -1
- package/bin/build/provider/hana/2migration.js +8 -7
- package/bin/build/provider/java-cf/index.js +1 -1
- package/bin/deploy/to-hana/hana.js +1 -17
- package/common.cds +8 -0
- package/lib/compile/index.js +1 -1
- package/lib/compile/to/sql.js +22 -2
- package/lib/connect/bindings.js +2 -1
- package/lib/connect/index.js +1 -1
- package/lib/core/infer.js +1 -1
- package/lib/core/reflect.js +3 -1
- package/lib/env/index.js +175 -41
- package/lib/env/requires.js +24 -3
- package/lib/i18n/localize.js +33 -5
- package/lib/index.js +7 -6
- package/lib/log/format/kibana.js +6 -2
- package/lib/ql/DELETE.js +1 -1
- package/lib/ql/INSERT.js +1 -1
- package/lib/ql/Query.js +13 -10
- package/lib/ql/SELECT.js +15 -8
- package/lib/ql/UPDATE.js +1 -1
- package/lib/ql/Whereable.js +5 -0
- package/lib/req/context.js +87 -37
- package/lib/req/{impl.js → request.js} +1 -1
- package/lib/req/{res.js → response.js} +0 -0
- package/lib/serve/Service-api.js +1 -1
- package/lib/serve/Service-dispatch.js +12 -2
- package/lib/serve/Service-handlers.js +21 -7
- package/lib/serve/Service-methods.js +1 -1
- package/lib/serve/Transaction.js +7 -6
- package/lib/serve/index.js +1 -1
- package/lib/utils/axios.js +7 -0
- package/lib/utils/data.js +1 -1
- package/libx/_runtime/audit/Service.js +18 -18
- package/libx/_runtime/audit/generic/personal/access.js +1 -1
- package/libx/_runtime/audit/generic/personal/modification.js +3 -2
- package/libx/_runtime/audit/generic/personal/utils.js +23 -63
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +6 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +37 -35
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +3 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +5 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +13 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +84 -34
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +10 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +9 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +8 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectHelper.js +11 -95
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/ResourcePathParser.js +17 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriParser.js +2 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +6 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +3 -34
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +3 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +48 -18
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +10 -5
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +1 -1
- package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +1 -1
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +1 -3
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +9 -2
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +20 -21
- package/libx/_runtime/cds-services/services/utils/columns.js +6 -1
- package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -8
- package/libx/_runtime/cds-services/services/utils/differ.js +7 -26
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +2 -4
- package/libx/_runtime/cds-services/util/assert.js +29 -13
- package/libx/_runtime/cds.js +2 -1
- package/libx/_runtime/common/aspects/Association.js +72 -0
- package/libx/_runtime/common/aspects/any.js +8 -45
- package/libx/_runtime/common/aspects/entity.js +0 -1
- package/libx/_runtime/common/aspects/relation.js +40 -0
- package/libx/_runtime/common/aspects/utils.js +73 -1
- package/libx/_runtime/common/auth/strategies/utils/uaa.js +10 -14
- package/libx/_runtime/common/composition/data.js +3 -2
- package/libx/_runtime/common/composition/delete.js +3 -1
- package/libx/_runtime/common/composition/tree.js +23 -18
- package/libx/_runtime/common/composition/utils.js +34 -8
- package/libx/_runtime/common/error/frontend.js +6 -1
- package/libx/_runtime/common/generic/auth.js +15 -13
- package/libx/_runtime/common/generic/crud.js +2 -2
- package/libx/_runtime/common/generic/etag.js +11 -8
- package/libx/_runtime/common/generic/input.js +3 -3
- package/libx/_runtime/common/generic/paging.js +9 -5
- package/libx/_runtime/common/generic/put.js +3 -2
- package/libx/_runtime/common/generic/sorting.js +3 -3
- package/libx/_runtime/common/generic/temporal.js +3 -3
- package/libx/_runtime/common/toggles/alpha.js +1 -1
- package/libx/_runtime/common/utils/cqn.js +20 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +125 -139
- package/libx/_runtime/common/utils/csn.js +50 -52
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +41 -176
- package/libx/_runtime/common/utils/generateOnCond.js +40 -70
- package/libx/_runtime/common/utils/{enrichWithKeysFromWhere.js → keys.js} +29 -28
- package/libx/_runtime/common/utils/postProcessing.js +3 -0
- package/libx/_runtime/common/utils/propagateForeignKeys.js +84 -0
- package/libx/_runtime/common/utils/resolveStructured.js +1 -1
- package/libx/_runtime/common/utils/resolveView.js +19 -9
- package/libx/_runtime/common/utils/rewriteAsterisks.js +94 -0
- package/libx/_runtime/common/utils/search2cqn4sql.js +9 -8
- package/libx/_runtime/common/utils/template.js +54 -46
- package/libx/_runtime/db/Service.js +9 -2
- package/libx/_runtime/db/expand/expandCQNToJoin.js +10 -24
- package/libx/_runtime/db/expand/rawToExpanded.js +2 -1
- package/libx/_runtime/db/generic/create.js +1 -0
- package/libx/_runtime/db/generic/input.js +7 -11
- package/libx/_runtime/db/generic/integrity.js +2 -2
- package/libx/_runtime/db/generic/rewrite.js +2 -5
- package/libx/_runtime/db/generic/update.js +1 -0
- package/libx/_runtime/db/query/read.js +10 -5
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +6 -0
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +7 -2
- package/libx/_runtime/db/sql-builder/annotations.js +1 -0
- package/libx/_runtime/db/utils/columns.js +14 -43
- package/libx/_runtime/db/utils/deep.js +5 -7
- package/libx/_runtime/fiori/generic/activate.js +3 -2
- package/libx/_runtime/fiori/generic/before.js +2 -2
- package/libx/_runtime/fiori/generic/cancel.js +3 -2
- package/libx/_runtime/fiori/generic/delete.js +3 -2
- package/libx/_runtime/fiori/generic/edit.js +2 -2
- package/libx/_runtime/fiori/generic/new.js +2 -2
- package/libx/_runtime/fiori/generic/patch.js +2 -2
- package/libx/_runtime/fiori/generic/prepare.js +2 -2
- package/libx/_runtime/fiori/generic/read.js +17 -63
- package/libx/_runtime/fiori/generic/readOverDraft.js +4 -4
- package/libx/_runtime/fiori/uiflex/extensibility/index.cds +15 -0
- package/libx/_runtime/fiori/uiflex/extensibility/index.js +148 -0
- package/libx/_runtime/fiori/uiflex/handler/transformREAD.js +119 -0
- package/libx/_runtime/fiori/uiflex/handler/transformRESULT.js +43 -0
- package/libx/_runtime/fiori/uiflex/handler/transformWRITE.js +62 -0
- package/libx/_runtime/fiori/uiflex/index.js +35 -0
- package/libx/_runtime/fiori/uiflex/utils.js +78 -0
- package/libx/_runtime/fiori/utils/handler.js +3 -13
- package/libx/_runtime/fiori/utils/where.js +6 -1
- package/libx/_runtime/hana/Service.js +5 -2
- package/libx/_runtime/hana/execute.js +1 -1
- package/libx/_runtime/hana/pool.js +12 -11
- package/libx/_runtime/hana/search2cqn4sql.js +34 -43
- package/libx/_runtime/hana/searchToContains.js +3 -3
- package/libx/_runtime/index.js +5 -2
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +1 -1
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +16 -3
- package/libx/_runtime/messaging/common-utils/connections.js +11 -14
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -1
- package/libx/_runtime/messaging/enterprise-messaging.js +1 -1
- package/libx/_runtime/messaging/message-queuing.js +18 -0
- package/libx/_runtime/remote/Service.js +14 -2
- package/libx/_runtime/remote/utils/client-types.d.ts +7 -0
- package/libx/_runtime/remote/utils/client.js +117 -23
- package/libx/_runtime/sqlite/Service.js +4 -3
- package/libx/_runtime/sqlite/convertAssocToOneManaged.js +1 -3
- package/libx/_runtime/sqlite/execute.js +1 -1
- package/libx/gql/GraphQLAdapter.js +33 -0
- package/libx/gql/constants/adapter.js +69 -0
- package/libx/gql/constants/cds.js +18 -0
- package/libx/gql/constants/graphql.js +33 -0
- package/libx/gql/resolvers/crud/create.js +15 -0
- package/libx/gql/resolvers/crud/delete.js +24 -0
- package/libx/gql/resolvers/crud/index.js +6 -0
- package/libx/gql/resolvers/crud/read.js +25 -0
- package/libx/gql/resolvers/crud/update.js +31 -0
- package/libx/gql/resolvers/crud/utils/index.js +36 -0
- package/libx/gql/resolvers/field.js +5 -0
- package/libx/gql/resolvers/index.js +7 -0
- package/libx/gql/resolvers/mutation.js +23 -0
- package/libx/gql/resolvers/parse/ast/enrich.js +51 -0
- package/libx/gql/resolvers/parse/ast/fragment.js +11 -0
- package/libx/gql/resolvers/parse/ast/fromObject.js +39 -0
- package/libx/gql/resolvers/parse/ast/index.js +3 -0
- package/libx/gql/resolvers/parse/ast/meta.js +4 -0
- package/libx/gql/resolvers/parse/ast/variable.js +7 -0
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +42 -0
- package/libx/gql/resolvers/parse/ast2cqn/entries.js +31 -0
- package/libx/gql/resolvers/parse/ast2cqn/index.js +8 -0
- package/libx/gql/resolvers/parse/ast2cqn/limit.js +6 -0
- package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +24 -0
- package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +3 -0
- package/libx/gql/resolvers/parse/ast2cqn/where.js +70 -0
- package/libx/gql/resolvers/parse/utils/index.js +8 -0
- package/libx/gql/resolvers/query.js +13 -0
- package/libx/gql/resolvers/root.js +34 -0
- package/libx/gql/schema/generate.js +18 -0
- package/libx/gql/schema/index.js +5 -0
- package/libx/gql/schema/mutation.js +76 -0
- package/libx/gql/schema/query.js +108 -0
- package/libx/gql/schema/typeDefMap.js +45 -0
- package/libx/gql/schema/utils/index.js +54 -0
- package/libx/gql/utils/index.js +12 -0
- package/libx/{_runtime/odata/cqn2odata.js → odata/cqn2odata/index.js} +39 -100
- package/libx/odata/index.js +80 -0
- package/libx/odata/odata2cqn/afterburner.js +170 -0
- package/libx/{_runtime/odata/odata2cqn.pegjs → odata/odata2cqn/grammar.pegjs} +102 -123
- package/libx/odata/odata2cqn/index.js +3 -0
- package/libx/odata/odata2cqn/parser.js +1 -0
- package/libx/odata/utils/index.js +64 -0
- package/libx/rest/RestAdapter.js +101 -0
- package/libx/rest/RestRequest.js +30 -0
- package/libx/rest/index.js +3 -0
- package/libx/rest/middleware/auth.js +22 -0
- package/libx/rest/middleware/content.js +15 -0
- package/libx/rest/middleware/create.js +40 -0
- package/libx/rest/middleware/delete.js +20 -0
- package/libx/rest/middleware/error.js +56 -0
- package/libx/rest/middleware/operation.js +39 -0
- package/libx/rest/middleware/parse.js +90 -0
- package/libx/rest/middleware/read.js +29 -0
- package/libx/rest/middleware/update.js +42 -0
- package/libx/rest/utils/data.js +65 -0
- package/package.json +4 -1
- package/server.js +42 -29
- package/lib/req/cls.js +0 -39
- package/libx/_runtime/cds-services/services/utils/diff.js +0 -53
- package/libx/_runtime/cds-services/util/auditlog.js +0 -247
- package/libx/_runtime/cds-services/util/xsenv.js +0 -51
- package/libx/_runtime/common/utils/backlinks.js +0 -83
- package/libx/_runtime/common/utils/rewriteAsterisk.js +0 -72
- package/libx/_runtime/odata/index.js +0 -55
- package/libx/_runtime/odata/odata2cqn.js +0 -1
- package/libx/_runtime/odata/readToCqn.js +0 -129
- package/libx/_runtime/remote/cqn2odata/index.js +0 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const getColumns = require('../utils/columns')
|
|
2
|
+
// REVISIT: Remove support for @odata.on... with @sap/cds ^6
|
|
2
3
|
const ANNOTATIONS = ['@cds.on.insert', '@odata.on.insert', '@cds.on.update', '@odata.on.update']
|
|
3
4
|
const { ensureNoDraftsSuffix } = require('../../common/utils/draft')
|
|
4
5
|
|
|
@@ -3,17 +3,6 @@ const resolveStructured = require('../../common/utils/resolveStructured')
|
|
|
3
3
|
|
|
4
4
|
const { DRAFT_COLUMNS } = require('../../common/constants/draft')
|
|
5
5
|
|
|
6
|
-
const _filterAssociationAndComposition = (entity, columnName) => {
|
|
7
|
-
return entity.elements[columnName]
|
|
8
|
-
? entity.elements[columnName].is2one !== true && entity.elements[columnName].is2many !== true
|
|
9
|
-
: true
|
|
10
|
-
}
|
|
11
|
-
const _filterDraft = (entity, columnName) => {
|
|
12
|
-
return DRAFT_COLUMNS.includes(columnName) !== true && _filterAssociationAndComposition(entity, columnName)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const _mapNameToValue = (entity, array) => array.map(key => entity.elements[key] || { name: key })
|
|
16
|
-
|
|
17
6
|
/**
|
|
18
7
|
* This method gets all columns for an entity.
|
|
19
8
|
* It includes the generated foreign keys from managed associations, structured elements and complex and custom types.
|
|
@@ -22,42 +11,24 @@ const _mapNameToValue = (entity, array) => array.map(key => entity.elements[key]
|
|
|
22
11
|
* @param entity - the csn entity
|
|
23
12
|
* @returns {Array} - array of columns
|
|
24
13
|
*/
|
|
25
|
-
const getColumns = entity => {
|
|
14
|
+
const getColumns = (entity, { db, onlyKeys } = { db: true, onlyKeys: false }) => {
|
|
26
15
|
// REVISIT is this correct or just a problem that occurs because of new structure we do not deal with yet?
|
|
27
|
-
if (!entity.elements) return []
|
|
28
|
-
|
|
29
|
-
let columnNames
|
|
16
|
+
if (!(entity && entity.elements)) return []
|
|
17
|
+
const columnNames = []
|
|
30
18
|
// REVISIT!!!
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
toBeDeleted.push(column)
|
|
41
|
-
columnNames.push(
|
|
42
|
-
...resolveStructured({ structName: element.name, structProperties: [] }, element.elements, false)
|
|
43
|
-
)
|
|
44
|
-
}
|
|
19
|
+
const elements = Object.getPrototypeOf(entity.elements) || entity.elements
|
|
20
|
+
for (const elementName in elements) {
|
|
21
|
+
const element = elements[elementName]
|
|
22
|
+
if (onlyKeys && !element.key) continue
|
|
23
|
+
if (element.isAssociation) continue
|
|
24
|
+
if (db && entity._isDraftEnabled && DRAFT_COLUMNS.includes(elementName)) continue
|
|
25
|
+
if (cds.env.effective.odata.structs && element.elements) {
|
|
26
|
+
columnNames.push(...resolveStructured({ structName: elementName, structProperties: [] }, element.elements, false))
|
|
27
|
+
continue
|
|
45
28
|
}
|
|
46
|
-
|
|
47
|
-
columnNames = columnNames.filter(col => !toBeDeleted.includes(col))
|
|
29
|
+
columnNames.push(elementName)
|
|
48
30
|
}
|
|
49
|
-
|
|
50
|
-
if (entity && entity._isDraftEnabled) {
|
|
51
|
-
return _mapNameToValue(
|
|
52
|
-
entity,
|
|
53
|
-
columnNames.filter(key => _filterDraft(entity, key))
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return _mapNameToValue(
|
|
58
|
-
entity,
|
|
59
|
-
columnNames.filter(key => _filterAssociationAndComposition(entity, key))
|
|
60
|
-
)
|
|
31
|
+
return columnNames.map(name => elements[name] || { name })
|
|
61
32
|
}
|
|
62
33
|
|
|
63
34
|
module.exports = getColumns
|
|
@@ -12,14 +12,12 @@ function getFlatArray(arg) {
|
|
|
12
12
|
|
|
13
13
|
async function _processChunk(processFn, model, dbc, cqns, user, locale, ts, indexes, results) {
|
|
14
14
|
const promises = []
|
|
15
|
-
for (const i of indexes)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
for (const i of indexes) promises.push(processFn(model, dbc, cqns[i], user, locale, ts))
|
|
16
|
+
const promisesResults = await Promise.allSettled(promises)
|
|
17
|
+
const firstRejected = promisesResults.find(r => r.status === 'rejected')
|
|
18
|
+
if (firstRejected) throw firstRejected.reason
|
|
19
19
|
// put results of queries into correct place of return results
|
|
20
|
-
for (let i = 0; i < promisesResults.length; i++)
|
|
21
|
-
results[indexes[i]] = promisesResults[i]
|
|
22
|
-
}
|
|
20
|
+
for (let i = 0; i < promisesResults.length; i++) results[indexes[i]] = promisesResults[i].value
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
async function processCQNs(processFn, cqns, model, dbc, user, locale, ts, chunks) {
|
|
@@ -93,6 +93,7 @@ const _draftCompositionTree = async (service, req) => {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
if (results[1].length === 1) {
|
|
96
|
+
_removeIsActiveEntityRecursively(results[1])
|
|
96
97
|
activeData = results[1][0]
|
|
97
98
|
}
|
|
98
99
|
|
|
@@ -175,8 +176,8 @@ const _handler = async function (req) {
|
|
|
175
176
|
return result
|
|
176
177
|
}
|
|
177
178
|
|
|
178
|
-
module.exports = function () {
|
|
179
|
+
module.exports = cds.service.impl(function () {
|
|
179
180
|
for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
|
|
180
181
|
this.on('draftActivate', entity, _handler)
|
|
181
182
|
}
|
|
182
|
-
}
|
|
183
|
+
})
|
|
@@ -186,7 +186,7 @@ const _deleteCancel = async function (req) {
|
|
|
186
186
|
await _addDraftDataFromExistingDraft(req, this)
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
module.exports = function () {
|
|
189
|
+
module.exports = cds.service.impl(function () {
|
|
190
190
|
_new._initial = true
|
|
191
191
|
_patchUpdate._initial = true
|
|
192
192
|
_deleteCancel._initial = true
|
|
@@ -196,4 +196,4 @@ module.exports = function () {
|
|
|
196
196
|
this.before(['PATCH', 'UPDATE'], entity, _patchUpdate)
|
|
197
197
|
this.before(['DELETE', 'CANCEL'], entity, _deleteCancel)
|
|
198
198
|
}
|
|
199
|
-
}
|
|
199
|
+
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const cds = require('../../cds')
|
|
1
2
|
const { deleteDraft } = require('../utils/delete')
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -11,8 +12,8 @@ const _handler = function (req) {
|
|
|
11
12
|
return deleteDraft(req, this)
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
module.exports = function () {
|
|
15
|
+
module.exports = cds.service.impl(function () {
|
|
15
16
|
for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
|
|
16
17
|
this.on('CANCEL', entity, _handler)
|
|
17
18
|
}
|
|
18
|
-
}
|
|
19
|
+
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const cds = require('../../cds')
|
|
1
2
|
const { deleteDraft } = require('../utils/delete')
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -13,8 +14,8 @@ const _handler = function (req) {
|
|
|
13
14
|
return deleteDraft(req, this, true)
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
module.exports = function () {
|
|
17
|
+
module.exports = cds.service.impl(function () {
|
|
17
18
|
for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
|
|
18
19
|
this.on('DELETE', entity, _handler)
|
|
19
20
|
}
|
|
20
|
-
}
|
|
21
|
+
})
|
|
@@ -172,8 +172,8 @@ const _handler = async function (req) {
|
|
|
172
172
|
return Object.assign({}, results[0][0], { HasDraftEntity: false, HasActiveEntity: true, IsActiveEntity: false })
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
module.exports = function () {
|
|
175
|
+
module.exports = cds.service.impl(function () {
|
|
176
176
|
for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
|
|
177
177
|
this.on('EDIT', entity, _handler)
|
|
178
178
|
}
|
|
179
|
-
}
|
|
179
|
+
})
|
|
@@ -96,8 +96,8 @@ const _handler = async function (req, next) {
|
|
|
96
96
|
return result[0]
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
module.exports = function () {
|
|
99
|
+
module.exports = cds.service.impl(function () {
|
|
100
100
|
for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
|
|
101
101
|
this.on('NEW', entity, _handler)
|
|
102
102
|
}
|
|
103
|
-
}
|
|
103
|
+
})
|
|
@@ -91,8 +91,8 @@ const _handler = async function (req) {
|
|
|
91
91
|
return result[0]
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
module.exports = function () {
|
|
94
|
+
module.exports = cds.service.impl(function () {
|
|
95
95
|
for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
|
|
96
96
|
this.on('PATCH', entity, _handler)
|
|
97
97
|
}
|
|
98
|
-
}
|
|
98
|
+
})
|
|
@@ -50,8 +50,8 @@ const _handler = async function (req) {
|
|
|
50
50
|
return result[0]
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
module.exports = function () {
|
|
53
|
+
module.exports = cds.service.impl(function () {
|
|
54
54
|
for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
|
|
55
55
|
this.on('draftPrepare', entity, _handler)
|
|
56
56
|
}
|
|
57
|
-
}
|
|
57
|
+
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const cds = require('../../cds')
|
|
2
2
|
const { SELECT } = cds.ql
|
|
3
3
|
|
|
4
|
-
const cqn2cqn4sql = require('../../common/utils/cqn2cqn4sql')
|
|
4
|
+
const { cqn2cqn4sql } = require('../../common/utils/cqn2cqn4sql')
|
|
5
5
|
const { getElementDeep } = require('../../common/utils/csn')
|
|
6
6
|
|
|
7
7
|
const { DRAFT_COLUMNS, DRAFT_COLUMNS_MAP, SCENARIO } = require('../../common/constants/draft')
|
|
@@ -15,7 +15,6 @@ const {
|
|
|
15
15
|
getEnrichedCQN,
|
|
16
16
|
removeDraftUUIDIfNecessary,
|
|
17
17
|
replaceRefWithDraft,
|
|
18
|
-
hasKeyInWhere,
|
|
19
18
|
filterKeys
|
|
20
19
|
} = require('../utils/handler')
|
|
21
20
|
const { deleteCondition, readAndDeleteKeywords, removeIsActiveEntityRecursively } = require('../utils/where')
|
|
@@ -186,34 +185,6 @@ function _copyArray(array) {
|
|
|
186
185
|
})
|
|
187
186
|
}
|
|
188
187
|
|
|
189
|
-
const _whereContainsKeys = (req, whereDraft) => {
|
|
190
|
-
const keys = _getTargetKeys(req)
|
|
191
|
-
if (whereDraft.length < keys.length * 4 - 1) {
|
|
192
|
-
return false
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
let i = 0
|
|
196
|
-
let keyCount = 0
|
|
197
|
-
while (i < whereDraft.length) {
|
|
198
|
-
const element = whereDraft[i]
|
|
199
|
-
const op = whereDraft[i + 1]
|
|
200
|
-
if (element.ref && keys.some(x => x === element.ref[element.ref.length - 1]) && op === '=') {
|
|
201
|
-
// op is EQ by keys
|
|
202
|
-
i = i + 4
|
|
203
|
-
keyCount++
|
|
204
|
-
continue
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
i++
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return keyCount === keys.length
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const _isValidActive = (isActiveEntity, req, whereDraft) => {
|
|
214
|
-
return isActiveEntity.op === '=' && _isTrue(isActiveEntity.value.val) && _whereContainsKeys(req, whereDraft)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
188
|
const _isValidDraftOfWhichIAmOwner = isActiveEntity => {
|
|
218
189
|
return isActiveEntity.op === '=' && _isFalse(isActiveEntity.value.val)
|
|
219
190
|
}
|
|
@@ -275,7 +246,7 @@ const _filterDraftColumnsBySelected = (draftColumns, columns) => {
|
|
|
275
246
|
)
|
|
276
247
|
}
|
|
277
248
|
|
|
278
|
-
const _isOnlyCount = columns => columns.length === 1 && columns[0].as === '_counted_'
|
|
249
|
+
const _isOnlyCount = columns => columns.length === 1 && (columns[0].as === '_counted_' || columns[0].as === '$count')
|
|
279
250
|
|
|
280
251
|
const _getOuterMostColumns = (columnsFromRequest, additionalDraftColumns) => {
|
|
281
252
|
if (_isOnlyCount(columnsFromRequest)) return columnsFromRequest
|
|
@@ -428,18 +399,6 @@ const _allActive = (req, columns, model) => {
|
|
|
428
399
|
}
|
|
429
400
|
}
|
|
430
401
|
|
|
431
|
-
const _active = (req, draftWhere, columns) => {
|
|
432
|
-
const { table } = _getTableName(req)
|
|
433
|
-
|
|
434
|
-
const outerMostColumns = _getOuterMostColumns(columns, _getDraftPropertiesDetermineDraft(req, draftWhere))
|
|
435
|
-
|
|
436
|
-
const cqn = SELECT.from(table).columns(...outerMostColumns)
|
|
437
|
-
|
|
438
|
-
draftWhere = _getWhereWithAppendedDraftRestrictions(draftWhere, req)
|
|
439
|
-
|
|
440
|
-
return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.ACTIVE }
|
|
441
|
-
}
|
|
442
|
-
|
|
443
402
|
const _activeWithoutDraft = (req, draftWhere, columns) => {
|
|
444
403
|
const { table } = _getTableName(req, true)
|
|
445
404
|
const draftName = table.ref[0]
|
|
@@ -805,7 +764,7 @@ const _getUnionCQN = (req, draftName, columns, subSelect, draftWhere) => {
|
|
|
805
764
|
_alignAliasForUnion(ensureNoDraftsSuffix(req.target.name), req.query.SELECT.from.as, subSelect)
|
|
806
765
|
])
|
|
807
766
|
|
|
808
|
-
return union.columns({ func: 'sum', args: [{ ref: ['
|
|
767
|
+
return union.columns({ func: 'sum', args: [{ ref: ['$count'] }], as: '$count' })
|
|
809
768
|
}
|
|
810
769
|
|
|
811
770
|
const enrichedColumns = _getOrderByEnrichedColumns(req.query.SELECT.orderBy, columns)
|
|
@@ -941,9 +900,6 @@ const _validatedWithSiblingInProcess = (req, draftWhere, draftParameters, column
|
|
|
941
900
|
}
|
|
942
901
|
}
|
|
943
902
|
|
|
944
|
-
const _validatedActive = (req, draftWhere, draftParameters, columns) =>
|
|
945
|
-
_isValidActive(draftParameters.isActiveEntity, req, draftWhere) && _active(req, draftWhere, columns)
|
|
946
|
-
|
|
947
903
|
const _validatedDraftOfWhichIAmOwner = (req, draftWhere, draftParameters, columns) =>
|
|
948
904
|
_isValidDraftOfWhichIAmOwner(draftParameters.isActiveEntity) && _draftOfWhichIAmOwner(req, draftWhere, columns)
|
|
949
905
|
|
|
@@ -989,20 +945,16 @@ const _generateCQN = (reqOriginal, req, columns, model) => {
|
|
|
989
945
|
return _allActive(req, columns, model)
|
|
990
946
|
}
|
|
991
947
|
|
|
992
|
-
|
|
993
|
-
// REVISIT ugly workaround until we support .xpr instead of '('...')' in draft choreo
|
|
994
|
-
req.query.SELECT.where = req.query.SELECT.where[0].xpr
|
|
995
|
-
}
|
|
948
|
+
// REVISIT this function does not only read, but modifies where!
|
|
996
949
|
const draftParameters = _readDraftParameters(req.query.SELECT.where)
|
|
997
950
|
|
|
998
951
|
if (
|
|
999
952
|
draftParameters.isActiveEntity &&
|
|
1000
953
|
_isTrue(draftParameters.isActiveEntity.value.val) &&
|
|
1001
954
|
!draftParameters.siblingIsActive &&
|
|
1002
|
-
!draftParameters.hasDraftEntity
|
|
1003
|
-
!hasKeyInWhere(reqOriginal.query.SELECT.from.ref[0].where, model.definitions[req.query.SELECT.from.ref[0]])
|
|
955
|
+
!draftParameters.hasDraftEntity
|
|
1004
956
|
) {
|
|
1005
|
-
return _allActive(req, columns)
|
|
957
|
+
return _allActive(req, columns, model)
|
|
1006
958
|
}
|
|
1007
959
|
|
|
1008
960
|
if (!draftParameters.isActiveEntity) {
|
|
@@ -1012,7 +964,7 @@ const _generateCQN = (reqOriginal, req, columns, model) => {
|
|
|
1012
964
|
// this is only the case when navigating into tree
|
|
1013
965
|
return _allInactive(req, columns)
|
|
1014
966
|
}
|
|
1015
|
-
return _allActive(req, columns)
|
|
967
|
+
return _allActive(req, columns, model)
|
|
1016
968
|
}
|
|
1017
969
|
|
|
1018
970
|
if (draftParameters.hasDraftEntity) {
|
|
@@ -1023,9 +975,7 @@ const _generateCQN = (reqOriginal, req, columns, model) => {
|
|
|
1023
975
|
return _validatedWithSiblingInProcess(req, req.query.SELECT.where, draftParameters, columns)
|
|
1024
976
|
}
|
|
1025
977
|
|
|
1026
|
-
return
|
|
1027
|
-
? _validatedActive(req, req.query.SELECT.where, draftParameters, columns)
|
|
1028
|
-
: _validatedDraftOfWhichIAmOwner(req, req.query.SELECT.where, draftParameters, columns)
|
|
978
|
+
return _validatedDraftOfWhichIAmOwner(req, req.query.SELECT.where, draftParameters, columns)
|
|
1029
979
|
}
|
|
1030
980
|
|
|
1031
981
|
const _getColumns = ({ query: { SELECT } }, model) => {
|
|
@@ -1183,7 +1133,7 @@ const _handler = async function (req) {
|
|
|
1183
1133
|
delete req.query._validationQuery
|
|
1184
1134
|
|
|
1185
1135
|
// REVISIT DRAFT HANDLING: cqn2cqn4sql must not be called here
|
|
1186
|
-
const sqlQuery = cqn2cqn4sql(req.query, this.model)
|
|
1136
|
+
const sqlQuery = cqn2cqn4sql(req.query, this.model, { draft: true })
|
|
1187
1137
|
|
|
1188
1138
|
// do not clone with Object.assign as that would skip all non-enumerable properties
|
|
1189
1139
|
const reqClone = { __proto__: req, query: _copyCQNPartial(sqlQuery) }
|
|
@@ -1204,7 +1154,11 @@ const _handler = async function (req) {
|
|
|
1204
1154
|
return
|
|
1205
1155
|
}
|
|
1206
1156
|
|
|
1207
|
-
|
|
1157
|
+
if (cqnScenario.scenario === SCENARIO.ALL_ACTIVE && cqnScenario.cqn.SELECT.where) {
|
|
1158
|
+
cqnScenario.cqn.SELECT.where = removeIsActiveEntityRecursively(cqnScenario.cqn.SELECT.where)
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
const enhancedWithLastChangeDateTime = enhanceQueryForTimeoutIfNeeded(
|
|
1208
1162
|
cqnScenario.scenario,
|
|
1209
1163
|
cqnScenario.cqn.SELECT.columns
|
|
1210
1164
|
)
|
|
@@ -1228,7 +1182,7 @@ const _handler = async function (req) {
|
|
|
1228
1182
|
_calculateDraftAdminColumns(resultAsArray[0], req.user.id)
|
|
1229
1183
|
}
|
|
1230
1184
|
|
|
1231
|
-
calculateDraftTimeout(cqnScenario.scenario, resultAsArray,
|
|
1185
|
+
calculateDraftTimeout(cqnScenario.scenario, resultAsArray, enhancedWithLastChangeDateTime)
|
|
1232
1186
|
|
|
1233
1187
|
if (cqnScenario.scenario === SCENARIO.SIBLING_ENTITY) {
|
|
1234
1188
|
if (!result || (Array.isArray(result) && !result.length)) return result
|
|
@@ -1247,8 +1201,8 @@ const _handler = async function (req) {
|
|
|
1247
1201
|
return result
|
|
1248
1202
|
}
|
|
1249
1203
|
|
|
1250
|
-
module.exports = function () {
|
|
1204
|
+
module.exports = cds.service.impl(function () {
|
|
1251
1205
|
for (const entity of Object.values(this.entities).filter(e => e._isDraftEnabled)) {
|
|
1252
1206
|
this.on('READ', entity, _handler)
|
|
1253
1207
|
}
|
|
1254
|
-
}
|
|
1208
|
+
})
|
|
@@ -2,7 +2,7 @@ const cds = require('../../cds')
|
|
|
2
2
|
const { SELECT } = cds.ql
|
|
3
3
|
const { getEnrichedCQN, hasDraft, ensureDraftsSuffix } = require('../utils/handler')
|
|
4
4
|
const { readAndDeleteKeywords } = require('../utils/where')
|
|
5
|
-
const cqn2cqn4sql = require('../../common/utils/cqn2cqn4sql')
|
|
5
|
+
const { cqn2cqn4sql } = require('../../common/utils/cqn2cqn4sql')
|
|
6
6
|
|
|
7
7
|
const _modifyCQN = (cqnDraft, where, context) => {
|
|
8
8
|
const whereDraft = [...where]
|
|
@@ -45,7 +45,7 @@ const _handler = async function (req) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// REVISIT DRAFT HANDLING: cqn2cqn4sql must not be called here
|
|
48
|
-
const sqlQuery = cqn2cqn4sql(req.query, this.model)
|
|
48
|
+
const sqlQuery = cqn2cqn4sql(req.query, this.model, { draft: true })
|
|
49
49
|
if (req.query._streaming) {
|
|
50
50
|
sqlQuery._streaming = true
|
|
51
51
|
}
|
|
@@ -70,8 +70,8 @@ const _handler = async function (req) {
|
|
|
70
70
|
return cds.tx(req).run(sqlQuery)
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
module.exports = function () {
|
|
73
|
+
module.exports = cds.service.impl(function () {
|
|
74
74
|
for (const entity of Object.values(this.entities).filter(e => !e._isDraftEnabled)) {
|
|
75
75
|
this.on('READ', entity, _handler)
|
|
76
76
|
}
|
|
77
|
-
}
|
|
77
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
namespace cds_r; //> cds system tables
|
|
2
|
+
|
|
3
|
+
service ExtensibilityService @(path:'/-/cds/extensibility') {
|
|
4
|
+
action addExtension(extensions : array of String); // TODO: change to array of CSN extensions
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
entity Extensions {
|
|
8
|
+
key ID : UUID;
|
|
9
|
+
csn : String;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// @open type Extension {
|
|
13
|
+
// extend: String;
|
|
14
|
+
// elements:{ /* */ }
|
|
15
|
+
// }
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
const cds = require('../../../cds')
|
|
2
|
+
const { ensureDraftsSuffix } = require('../../../common/utils/draft')
|
|
3
|
+
|
|
4
|
+
const { EXT_BACK_PACK } = require('../utils')
|
|
5
|
+
|
|
6
|
+
const _getDraftTable = (view, cds) => {
|
|
7
|
+
return cds.model.definitions[view]._isDraftEnabled ? ensureDraftsSuffix(view) : undefined
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const _addAnnotation = extension => {
|
|
11
|
+
Object.values(extension.elements).forEach(el => {
|
|
12
|
+
el['@cds.extension'] = true
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const _isProjection = target => target && target.query && target.query._target
|
|
17
|
+
|
|
18
|
+
const _resolveViews = (target, views_ = []) => {
|
|
19
|
+
if (_isProjection(target)) {
|
|
20
|
+
views_.push(target)
|
|
21
|
+
return _resolveViews(target.query._target, views_)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return target
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const _getCsn = req => {
|
|
28
|
+
const csn = {
|
|
29
|
+
extensions: req.data.extensions.map(ext => JSON.parse(ext))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return csn
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const _addViews = csn => {
|
|
36
|
+
csn.extensions.forEach(extension => {
|
|
37
|
+
const target = cds.model.definitions[extension.extend]
|
|
38
|
+
const views_ = []
|
|
39
|
+
const view = _resolveViews(target, views_)
|
|
40
|
+
extension.extend = view && view.name
|
|
41
|
+
_addAnnotation(extension)
|
|
42
|
+
|
|
43
|
+
// All projection views leading to the db entity are extended with back pack in case view columns are explicitly listed.
|
|
44
|
+
// The views using projections with '*' obtain the back pack automatically.
|
|
45
|
+
views_.forEach(view => {
|
|
46
|
+
if (!view.projection || (view.projection.columns && !view.projection.columns.some(col => col === '*'))) {
|
|
47
|
+
csn.extensions.push({
|
|
48
|
+
extend: view.name,
|
|
49
|
+
columns: Object.keys(extension.elements).map(key => {
|
|
50
|
+
return { ref: [key] }
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const _handleDefaults = async (extension, dbEntity, req, cds, draftEntity) => {
|
|
59
|
+
const ext = Object.keys(extension.elements)
|
|
60
|
+
.filter(key => extension.elements[key].default)
|
|
61
|
+
.map(key => {
|
|
62
|
+
const element = extension.elements[key]
|
|
63
|
+
const t = cds.model.definitions[element.type] || cds.builtin.types[element.type]
|
|
64
|
+
const value = t && t instanceof cds.builtin.classes.string ? `"${element.default.val}"` : element.default.val
|
|
65
|
+
return `"${key}":${value}`
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
if (ext.length !== 0) {
|
|
69
|
+
const extStr = ext.join(',')
|
|
70
|
+
const changed = `'{${extStr},' || substr(${EXT_BACK_PACK}, 2, length(${EXT_BACK_PACK})-1)`
|
|
71
|
+
const assign = `${EXT_BACK_PACK} = CASE WHEN ${EXT_BACK_PACK} IS NULL THEN '{${extStr}}' ELSE ${changed} END`
|
|
72
|
+
await UPDATE(dbEntity).with(assign)
|
|
73
|
+
if (draftEntity) await UPDATE(draftEntity).with(assign)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const _validateCsn = (csn, req) => {
|
|
78
|
+
csn.extensions.forEach(extension => {
|
|
79
|
+
if (!extension.extend || !cds.model.definitions[extension.extend]) {
|
|
80
|
+
req.reject(400, 'Invalid extension. Parameter "extend" missing or malformed')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!extension.elements) {
|
|
84
|
+
req.reject(400, 'Invalid extension. Missing parameter "elements"')
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const _validateExtensionFields = async (csn, req) => {
|
|
90
|
+
csn.extensions.forEach(extension => {
|
|
91
|
+
if (extension.elements) {
|
|
92
|
+
Object.keys(extension.elements).forEach(name => {
|
|
93
|
+
if (!/^[A-Za-z]\w*$/.test(name)) {
|
|
94
|
+
req.reject(400, `Invalid extension. Bad element name "${name}"`)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (Object.keys(cds.model.definitions[extension.extend].elements).includes(name)) {
|
|
98
|
+
req.reject(400, `Invalid extension. Element "${name}" already exists`)
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const _getCompilerError = messages => {
|
|
106
|
+
const defaultMsg = 'Error while compiling extension'
|
|
107
|
+
if (!messages) return defaultMsg
|
|
108
|
+
|
|
109
|
+
for (const msg of messages) {
|
|
110
|
+
if (msg.severity === 'Error') return msg.message
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return defaultMsg
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const _validateExtension = async (csn, req) => {
|
|
117
|
+
try {
|
|
118
|
+
const base = await cds.load('*', cds.options)
|
|
119
|
+
const baseCsn = await cds.compile.to.json(base)
|
|
120
|
+
const extCsn = await cds.compile.to.json(csn)
|
|
121
|
+
await cds.compile.to.csn({ 'base.csn': baseCsn, 'ext.csn': extCsn })
|
|
122
|
+
} catch (err) {
|
|
123
|
+
req.reject(400, _getCompilerError(err.messages))
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
module.exports = function () {
|
|
128
|
+
this.on('addExtension', async req => {
|
|
129
|
+
const csn = _getCsn(req, cds)
|
|
130
|
+
_validateCsn(csn, req)
|
|
131
|
+
await _validateExtensionFields(csn, req)
|
|
132
|
+
_addViews(csn, cds)
|
|
133
|
+
await _validateExtension(csn, req)
|
|
134
|
+
|
|
135
|
+
const ID = cds.utils.uuid()
|
|
136
|
+
await INSERT.into('cds_r.Extensions').entries([{ ID, csn: JSON.stringify(csn) }])
|
|
137
|
+
|
|
138
|
+
for (const ext of req.data.extensions) {
|
|
139
|
+
const extension = JSON.parse(ext)
|
|
140
|
+
const draft = _getDraftTable(extension.extend, cds)
|
|
141
|
+
const target = cds.model.definitions[extension.extend]
|
|
142
|
+
const dbEntity = _resolveViews(target).name
|
|
143
|
+
await _handleDefaults(extension, dbEntity, req, cds, draft)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
setTimeout(() => process.send('restart'), 1111)
|
|
147
|
+
})
|
|
148
|
+
}
|