@sap/cds 5.8.2 → 5.9.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 +214 -78
- package/app/fiori/preview.js +16 -11
- package/app/fiori/routes.js +3 -0
- package/app/index.js +1 -1
- package/bin/build/buildTaskFactory.js +3 -3
- package/bin/build/buildTaskProviderFactory.js +1 -1
- package/bin/build/constants.js +1 -1
- package/bin/build/provider/buildTaskHandlerEdmx.js +12 -7
- package/bin/build/provider/buildTaskHandlerInternal.js +1 -1
- package/bin/build/provider/buildTaskProviderInternal.js +8 -2
- package/bin/build/provider/hana/2migration.js +27 -24
- package/bin/build/provider/hana/index.js +17 -18
- package/bin/build/provider/hana/migrationtable.js +9 -10
- package/bin/build/provider/java-cf/index.js +4 -5
- package/bin/build/provider/node-cf/index.js +99 -6
- package/bin/cds.js +20 -17
- package/bin/deploy/to-hana/cfUtil.js +16 -19
- package/bin/deploy/to-hana/hana.js +7 -24
- package/bin/deploy/to-hana/hdiDeployUtil.js +8 -4
- package/bin/mtx/in-cds.js +2 -2
- package/bin/serve.js +12 -5
- package/bin/utils/modules.js +7 -0
- package/bin/version.js +56 -3
- package/lib/compile/cdsc.js +26 -3
- package/lib/compile/etc/_localized.js +36 -25
- package/lib/compile/etc/csv.js +8 -8
- package/lib/compile/for/drafts.js +9 -0
- package/lib/compile/for/java.js +16 -0
- package/lib/compile/for/nodejs.js +12 -0
- package/lib/compile/for/odata.js +1 -1
- package/lib/compile/index.js +3 -0
- package/lib/compile/minify.js +16 -2
- package/lib/compile/parse.js +2 -2
- package/lib/compile/resolve.js +35 -18
- package/lib/compile/to/json.js +3 -1
- package/lib/compile/to/sql.js +2 -2
- package/lib/compile/to/srvinfo.js +4 -2
- package/lib/connect/index.js +1 -1
- package/lib/core/entities.js +15 -14
- package/lib/core/index.js +39 -36
- package/lib/core/reflect.js +4 -2
- package/lib/deploy.js +114 -127
- package/lib/env/defaults.js +1 -0
- package/lib/env/index.js +165 -165
- package/lib/env/presets.js +1 -0
- package/lib/env/requires.js +120 -49
- package/lib/index.js +1 -0
- package/lib/log/format/kibana.js +2 -2
- package/lib/ql/SELECT.js +10 -0
- package/lib/ql/parse.js +1 -0
- package/lib/req/cds-context.js +4 -1
- package/lib/req/context.js +50 -56
- package/lib/req/event.js +1 -6
- package/lib/req/locale.js +6 -5
- package/lib/req/request.js +2 -0
- package/lib/req/user.js +7 -5
- package/lib/serve/Service-api.js +10 -7
- package/lib/serve/Service-dispatch.js +9 -11
- package/lib/serve/Service-methods.js +30 -41
- package/lib/serve/Transaction.js +10 -7
- package/lib/serve/adapters.js +7 -5
- package/lib/serve/index.js +24 -12
- package/lib/utils/data.js +1 -1
- package/lib/utils/index.js +27 -30
- package/lib/utils/resources/index.js +101 -0
- package/lib/utils/resources/tar.js +71 -0
- package/lib/utils/resources/utils.js +11 -0
- package/libx/_runtime/audit/Service.js +36 -39
- package/libx/_runtime/audit/generic/personal/access.js +3 -4
- package/libx/_runtime/audit/generic/personal/modification.js +3 -4
- package/libx/_runtime/audit/utils/v2.js +1 -2
- package/libx/_runtime/auth/index.js +126 -84
- package/libx/_runtime/auth/strategies/JWT.js +12 -19
- package/libx/_runtime/auth/strategies/dummy.js +1 -5
- package/libx/_runtime/auth/strategies/dwc.js +11 -9
- package/libx/_runtime/auth/strategies/mock.js +0 -4
- package/libx/_runtime/auth/strategies/{utils/xssec.js → xssecUtils.js} +7 -4
- package/libx/_runtime/auth/strategies/xsuaa.js +12 -19
- package/libx/_runtime/auth/utils.js +22 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +104 -98
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +13 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/language.js +2 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -29
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +2 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +3 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +4 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +24 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +8 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/DeserializerFactory.js +2 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/ResourceJsonDeserializer.js +5 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DispatcherCommand.js +2 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/utils/UriHelper.js +4 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -12
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +33 -9
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +50 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +10 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +9 -11
- package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +6 -3
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +4 -2
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +1 -1
- package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +1 -1
- package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +2 -3
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +6 -4
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +1 -0
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +8 -5
- package/libx/_runtime/cds-services/services/Service.js +40 -0
- package/libx/_runtime/cds-services/services/utils/columns.js +4 -3
- package/libx/_runtime/cds-services/services/utils/compareJson.js +4 -4
- package/libx/_runtime/cds-services/services/utils/differ.js +3 -3
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +4 -4
- package/libx/_runtime/cds-services/services/utils/restrictions.js +78 -0
- package/libx/_runtime/cds-services/util/assert.js +20 -14
- package/libx/_runtime/cds.js +9 -1
- package/libx/_runtime/common/aspects/any.js +5 -0
- package/libx/_runtime/common/aspects/entity.js +25 -7
- package/libx/_runtime/common/aspects/utils.js +2 -2
- package/libx/_runtime/common/composition/data.js +6 -0
- package/libx/_runtime/common/composition/insert.js +3 -2
- package/libx/_runtime/common/composition/tree.js +4 -10
- package/libx/_runtime/common/composition/update.js +4 -4
- package/libx/_runtime/common/constants/draft.js +29 -26
- package/libx/_runtime/common/error/constants.js +2 -2
- package/libx/_runtime/common/error/frontend.js +7 -15
- package/libx/_runtime/common/generic/auth/capabilities.js +59 -0
- package/libx/_runtime/common/generic/auth/constants.js +20 -0
- package/libx/_runtime/common/generic/auth/expand.js +54 -0
- package/libx/_runtime/common/generic/auth/index.js +32 -0
- package/libx/_runtime/common/generic/auth/insertOnly.js +15 -0
- package/libx/_runtime/common/generic/auth/readOnly.js +26 -0
- package/libx/_runtime/common/generic/auth/requires.js +34 -0
- package/libx/_runtime/common/generic/auth/restrict.js +296 -0
- package/libx/_runtime/common/generic/auth/utils.js +213 -0
- package/libx/_runtime/common/generic/crud.js +14 -10
- package/libx/_runtime/common/generic/etag.js +1 -1
- package/libx/_runtime/common/generic/input.js +35 -35
- package/libx/_runtime/common/generic/sorting.js +2 -3
- package/libx/_runtime/common/generic/temporal.js +2 -2
- package/libx/_runtime/common/i18n/index.js +2 -31
- package/libx/_runtime/common/i18n/messages.properties +1 -1
- package/libx/_runtime/common/toggles/handler.js +21 -0
- package/libx/_runtime/common/utils/copy.js +10 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +100 -29
- package/libx/_runtime/common/utils/csn.js +63 -1
- package/libx/_runtime/common/utils/dollar.js +10 -1
- package/libx/_runtime/common/utils/draft.js +46 -7
- package/libx/_runtime/common/utils/entityFromCqn.js +13 -9
- package/libx/_runtime/common/utils/extensibilityUtils.js +18 -0
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +88 -104
- package/libx/_runtime/common/utils/generateOnCond.js +9 -6
- package/libx/_runtime/common/utils/quotingStyles.js +2 -0
- package/libx/_runtime/common/utils/resolveStructured.js +25 -9
- package/libx/_runtime/common/utils/resolveView.js +4 -1
- package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -16
- package/libx/_runtime/common/utils/structured.js +33 -37
- package/libx/_runtime/common/utils/template.js +17 -8
- package/libx/_runtime/common/utils/templateProcessor.js +28 -28
- package/libx/_runtime/db/data-conversion/post-processing.js +118 -417
- package/libx/_runtime/db/expand/expandCQNToJoin.js +45 -41
- package/libx/_runtime/db/expand/rawToExpanded.js +29 -8
- package/libx/_runtime/db/generic/index.js +1 -3
- package/libx/_runtime/db/generic/input.js +5 -10
- package/libx/_runtime/db/generic/rewrite.js +5 -2
- package/libx/_runtime/db/generic/structured.js +2 -2
- package/libx/_runtime/db/query/delete.js +2 -2
- package/libx/_runtime/db/query/insert.js +1 -1
- package/libx/_runtime/db/query/update.js +9 -14
- package/libx/_runtime/db/sql-builder/CreateBuilder.js +4 -3
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +14 -1
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +3 -2
- package/libx/_runtime/db/sql-builder/dataTypes.js +3 -3
- package/libx/_runtime/db/utils/columns.js +3 -3
- package/libx/_runtime/db/utils/normalizeTimeData.js +2 -2
- package/libx/_runtime/db/utils/propagateForeignKeys.js +6 -2
- package/libx/_runtime/extensibility/mps/index.js +5 -0
- package/libx/_runtime/extensibility/mps/service.js +111 -0
- package/libx/_runtime/extensibility/mps/tar.js +42 -0
- package/libx/_runtime/extensibility/mps/utils.js +11 -0
- package/libx/_runtime/{fiori → extensibility}/uiflex/handler/transformREAD.js +0 -0
- package/libx/_runtime/{fiori → extensibility}/uiflex/handler/transformRESULT.js +17 -5
- package/libx/_runtime/{fiori → extensibility}/uiflex/handler/transformWRITE.js +1 -0
- package/libx/_runtime/extensibility/uiflex/index.js +54 -0
- package/libx/_runtime/extensibility/uiflex/service.js +276 -0
- package/libx/_runtime/{fiori → extensibility}/uiflex/utils.js +22 -7
- package/libx/_runtime/fiori/generic/activate.js +2 -2
- package/libx/_runtime/fiori/generic/before.js +4 -4
- package/libx/_runtime/fiori/generic/new.js +3 -3
- package/libx/_runtime/fiori/generic/patch.js +1 -1
- package/libx/_runtime/fiori/generic/read.js +58 -66
- package/libx/_runtime/fiori/generic/readOverDraft.js +71 -16
- package/libx/_runtime/fiori/utils/handler.js +6 -13
- package/libx/_runtime/fiori/utils/where.js +6 -5
- package/libx/_runtime/hana/Service.js +4 -10
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +2 -2
- package/libx/_runtime/hana/driver.js +2 -2
- package/libx/_runtime/hana/execute.js +29 -75
- package/libx/_runtime/hana/pool.js +1 -1
- package/libx/_runtime/hana/streaming.js +2 -1
- package/libx/_runtime/index.js +6 -6
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +5 -21
- package/libx/_runtime/messaging/Outbox.js +2 -2
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -14
- package/libx/_runtime/messaging/common-utils/connections.js +5 -7
- package/libx/_runtime/messaging/common-utils/normalizeIncomingMessage.js +30 -0
- package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +36 -30
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +19 -12
- package/libx/_runtime/messaging/enterprise-messaging.js +8 -8
- package/libx/_runtime/messaging/file-based.js +5 -5
- package/libx/_runtime/messaging/message-queuing.js +14 -12
- package/libx/_runtime/messaging/outbox/utils.js +18 -19
- package/libx/_runtime/messaging/redis-messaging.js +91 -0
- package/libx/_runtime/messaging/service.js +8 -6
- package/libx/_runtime/remote/Service.js +44 -8
- package/libx/_runtime/remote/utils/client.js +25 -13
- package/libx/_runtime/remote/utils/data.js +11 -11
- package/libx/_runtime/sqlite/Service.js +6 -9
- package/libx/_runtime/sqlite/customBuilder/CustomFunctionBuilder.js +5 -2
- package/libx/_runtime/types/api.js +10 -2
- package/libx/common/utils/ucsn.js +109 -0
- package/libx/gql/resolvers/crud/create.js +6 -1
- package/libx/gql/resolvers/crud/delete.js +6 -1
- package/libx/gql/resolvers/crud/read.js +6 -1
- package/libx/gql/resolvers/crud/update.js +9 -1
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +3 -1
- package/libx/gql/schema/typeDefMap.js +2 -2
- package/libx/odata/afterburner.js +110 -16
- package/libx/odata/grammar.pegjs +9 -1
- package/libx/odata/parseToCqn.js +39 -0
- package/libx/odata/parser.js +1 -1
- package/libx/rest/RestAdapter.js +9 -1
- package/libx/rest/middleware/input.js +54 -0
- package/libx/rest/middleware/operation.js +14 -1
- package/libx/rest/middleware/parse.js +11 -7
- package/package.json +1 -1
- package/server.js +34 -19
- package/srv/audit-log.cds +2 -2
- package/srv/flex.cds +8 -2
- package/srv/flex.js +1 -1
- package/srv/mps.cds +23 -0
- package/srv/mps.js +1 -0
- package/libx/_runtime/auth/strategies/utils/uaa.js +0 -21
- package/libx/_runtime/common/generic/auth.js +0 -874
- package/libx/_runtime/common/toggles/alpha.js +0 -43
- package/libx/_runtime/db/generic/arrayed.js +0 -33
- package/libx/_runtime/fiori/uiflex/index.js +0 -35
- package/libx/_runtime/fiori/uiflex/service.js +0 -150
- package/libx/rest/utils/data.js +0 -60
|
@@ -1,30 +1,21 @@
|
|
|
1
1
|
const resolveStructured = require('./resolveStructured')
|
|
2
2
|
const { ensureNoDraftsSuffix } = require('../../common/utils/draft')
|
|
3
|
+
const { traverseFroms } = require('../../common/utils/entityFromCqn')
|
|
3
4
|
// TODO move to commons as also used in cqn2cqn4sql
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}, new Set())
|
|
19
|
-
)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (Array.isArray(from.args)) {
|
|
23
|
-
// TODO this only considers first level refs and not from sub selects
|
|
24
|
-
return from.args.filter(arg => arg.ref).map(arg => ensureNoDraftsSuffix(arg.ref[0]))
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return []
|
|
5
|
+
const OPERATIONS_MAP = ['=', '>', '<', '!=', '<>', '>=', '<=', 'like', 'between', 'in', 'not in'].reduce((acc, cur) => {
|
|
6
|
+
acc[cur] = 1
|
|
7
|
+
return acc
|
|
8
|
+
}, {})
|
|
9
|
+
|
|
10
|
+
const _getEntityNamesAndIds = from => {
|
|
11
|
+
const nameAndIds = []
|
|
12
|
+
traverseFroms(from, from => {
|
|
13
|
+
const nameAndId = { name: ensureNoDraftsSuffix(from.ref[0].id || from.ref[0]), id: from.as || from.ref[0] }
|
|
14
|
+
if (nameAndIds.some(x => x.name === nameAndId.name)) return // no duplicates
|
|
15
|
+
nameAndIds.push(nameAndId)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
return nameAndIds
|
|
28
19
|
}
|
|
29
20
|
|
|
30
21
|
const _flattenStructuredInExpand = (column, { _target: expandedEntity }) => {
|
|
@@ -117,8 +108,8 @@ const _filterForStructProperty = (structElement, structData, op, prefix = '', na
|
|
|
117
108
|
)
|
|
118
109
|
} else {
|
|
119
110
|
if (element.isAssociation) continue
|
|
120
|
-
|
|
121
|
-
|
|
111
|
+
const assocName = element._foreignKey4
|
|
112
|
+
if (assocName) {
|
|
122
113
|
const assoc = structElement.elements[assocName]
|
|
123
114
|
if (assoc.is2one && !assoc.on) {
|
|
124
115
|
for (const key in assoc._target.keys) {
|
|
@@ -214,7 +205,7 @@ const flattenStructuredWhereHaving = (filterArray, csnEntity, model) => {
|
|
|
214
205
|
|
|
215
206
|
const newFilterArray = []
|
|
216
207
|
for (let i = 0; i < filterArray.length; i++) {
|
|
217
|
-
if (
|
|
208
|
+
if (filterArray[i + 1] in OPERATIONS_MAP) {
|
|
218
209
|
const refElement = filterArray[i].ref ? filterArray[i] : filterArray[i + 2]
|
|
219
210
|
|
|
220
211
|
// copy for processing
|
|
@@ -254,42 +245,47 @@ const getNavigationIfStruct = (entity, ref) => {
|
|
|
254
245
|
return element
|
|
255
246
|
}
|
|
256
247
|
|
|
257
|
-
const _flattenColumns = (SELECT, flattenedElements, toBeDeleted, csnEntity) => {
|
|
248
|
+
const _flattenColumns = (SELECT, flattenedElements, toBeDeleted, csnEntity, tableId) => {
|
|
258
249
|
for (const column of SELECT.columns) {
|
|
259
250
|
if (!column.ref) continue
|
|
260
251
|
|
|
261
|
-
//
|
|
262
|
-
const
|
|
252
|
+
// might begin with table id
|
|
253
|
+
const cleanedUpRef = column.ref.length > 1 && column.ref[0] === tableId ? column.ref.slice(1) : column.ref
|
|
254
|
+
const structName = cleanedUpRef[0]
|
|
263
255
|
|
|
264
256
|
const element = csnEntity.elements[structName]
|
|
265
257
|
if (!element) continue
|
|
266
258
|
|
|
267
259
|
if (column.expand) {
|
|
268
|
-
_flattenStructuredInExpand(column, getNavigationIfStruct(csnEntity,
|
|
260
|
+
_flattenStructuredInExpand(column, getNavigationIfStruct(csnEntity, cleanedUpRef))
|
|
269
261
|
continue
|
|
270
262
|
}
|
|
271
263
|
|
|
272
264
|
if (element._isStructured) {
|
|
273
265
|
toBeDeleted.push(structName) // works with aliases?
|
|
274
266
|
flattenedElements.push(
|
|
275
|
-
...resolveStructured({ structName, structProperties:
|
|
267
|
+
...resolveStructured({ structName, structProperties: cleanedUpRef.slice(1) }, element.elements)
|
|
276
268
|
)
|
|
277
269
|
}
|
|
270
|
+
if (cleanedUpRef.length < column.ref.length) {
|
|
271
|
+
flattenedElements.forEach(e => e.ref.unshift(tableId))
|
|
272
|
+
}
|
|
278
273
|
}
|
|
279
274
|
}
|
|
280
275
|
|
|
281
276
|
const flattenStructuredSelect = ({ SELECT }, model) => {
|
|
282
|
-
const
|
|
277
|
+
const entityNamesAndIds = _getEntityNamesAndIds(SELECT.from)
|
|
283
278
|
|
|
284
|
-
for (const
|
|
285
|
-
const entity = model.definitions[
|
|
279
|
+
for (const entityNameAndId of entityNamesAndIds) {
|
|
280
|
+
const entity = model.definitions[entityNameAndId.name]
|
|
281
|
+
const tableId = entityNameAndId.id
|
|
286
282
|
|
|
287
283
|
if (Array.isArray(SELECT.columns) && SELECT.columns.length > 0) {
|
|
288
284
|
const flattenedElements = []
|
|
289
285
|
const toBeDeleted = []
|
|
290
|
-
_flattenColumns(SELECT, flattenedElements, toBeDeleted, entity)
|
|
286
|
+
_flattenColumns(SELECT, flattenedElements, toBeDeleted, entity, tableId)
|
|
291
287
|
SELECT.columns = SELECT.columns.filter(column => {
|
|
292
|
-
const columnName = column.ref ? column.ref[0] : column.as
|
|
288
|
+
const columnName = column.ref ? (column.ref[0] === tableId ? column.ref[1] : column.ref[0]) : column.as
|
|
293
289
|
return (columnName && !toBeDeleted.includes(columnName)) || column.func || column.expand || 'val' in column
|
|
294
290
|
})
|
|
295
291
|
if (flattenedElements.length) SELECT.columns.push(...flattenedElements)
|
|
@@ -73,15 +73,25 @@ const _getNextTarget = (model, element, currentPath = []) => {
|
|
|
73
73
|
* @param {array} [targetPath=[]]
|
|
74
74
|
*/
|
|
75
75
|
function _getTemplate(model, cache, targetEntity, callbacks, parent = null, _entityMap = new Map(), targetPath = []) {
|
|
76
|
-
const { pick, ignore } = callbacks
|
|
76
|
+
const { pick, ignore, flatAccess } = callbacks
|
|
77
77
|
const templateElements = new Map()
|
|
78
78
|
const template = { target: targetEntity, elements: templateElements }
|
|
79
79
|
const currentPath = [...targetPath, targetEntity.name]
|
|
80
80
|
_entityMap.set(currentPath.join(DELIMITER), { template })
|
|
81
|
-
|
|
81
|
+
const elements = targetEntity.elements || targetEntity.params
|
|
82
|
+
if (!elements) return template
|
|
83
|
+
|
|
84
|
+
if (flatAccess) {
|
|
85
|
+
if (targetEntity._flat2struct) {
|
|
86
|
+
for (const elementName in targetEntity._flat2struct) {
|
|
87
|
+
const element = targetEntity._flat2struct[elementName]
|
|
88
|
+
_pick(pick, element, targetEntity, parent, templateElements, elementName)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
82
92
|
|
|
83
|
-
for (const elementName in
|
|
84
|
-
const element =
|
|
93
|
+
for (const elementName in elements) {
|
|
94
|
+
const element = elements[elementName]
|
|
85
95
|
if (ignore && ignore(element, targetEntity, parent)) continue
|
|
86
96
|
|
|
87
97
|
_pick(pick, element, targetEntity, parent, templateElements, elementName)
|
|
@@ -99,12 +109,11 @@ function _getTemplate(model, cache, targetEntity, callbacks, parent = null, _ent
|
|
|
99
109
|
// For associations and _typed_ structured elements, there's a (cacheable) target,
|
|
100
110
|
// inline structures must be handled separately.
|
|
101
111
|
const subTemplate = _isInlineStructured(element)
|
|
102
|
-
? _getTemplate(model, cache, nextTarget,
|
|
103
|
-
: cache.for(nextTarget, getTemplate(model,
|
|
112
|
+
? _getTemplate(model, cache, nextTarget, callbacks, targetEntity, _entityMap, currentPath)
|
|
113
|
+
: cache.for(nextTarget, getTemplate(model, callbacks, targetEntity, _entityMap))
|
|
104
114
|
_addSubTemplate(templateElements, elementName, subTemplate)
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
|
-
|
|
108
117
|
return template
|
|
109
118
|
}
|
|
110
119
|
|
|
@@ -131,7 +140,7 @@ module.exports = (usecase, tx, target, ...args) => {
|
|
|
131
140
|
// double-check with get target from model
|
|
132
141
|
// since target might come from anywhere like via cqn etc
|
|
133
142
|
if (!target) return
|
|
134
|
-
const root = (model && model.definitions[target.name]) ||
|
|
143
|
+
const root = (model && model.definitions[target.name]) || target
|
|
135
144
|
if (!root) return
|
|
136
145
|
|
|
137
146
|
// tx could be the service itself
|
|
@@ -6,54 +6,57 @@ const _formatRowContext = (tKey, keyNames, row) => {
|
|
|
6
6
|
return `${tKey}(${keyValuePairsSerialized})`
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const _processElement = (processFn, row, key,
|
|
10
|
-
const
|
|
11
|
-
const element = elements[key]
|
|
9
|
+
const _processElement = (processFn, row, key, target, picked = {}, isRoot, path) => {
|
|
10
|
+
const element = (target.elements || target.params)[key]
|
|
12
11
|
const { plain } = picked
|
|
13
12
|
|
|
14
|
-
if (plain)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
if (!plain) return
|
|
14
|
+
/**
|
|
15
|
+
* @type import('../../types/api').templateProcessorProcessFnArgs
|
|
16
|
+
*/
|
|
17
|
+
const elementInfo = { row, key, element, target, plain, isRoot, path }
|
|
18
|
+
if (!element && target._flat2struct && target._flat2struct[key]) {
|
|
19
|
+
elementInfo.path = path.slice(0)
|
|
20
|
+
elementInfo.path.push(...target._flat2struct[key].map(key => ({ key })))
|
|
22
21
|
}
|
|
22
|
+
processFn(elementInfo)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const _processRow = (processFn, row, template, tKey, tValue, isRoot, pathOptions) => {
|
|
26
26
|
const { template: subTemplate, picked } = tValue
|
|
27
27
|
const key = tKey.split(DELIMITER).pop()
|
|
28
28
|
|
|
29
|
-
_processElement(processFn, row, key, template.target
|
|
29
|
+
_processElement(processFn, row, key, template.target, picked, isRoot, pathOptions.path)
|
|
30
30
|
|
|
31
31
|
// process deep
|
|
32
|
-
if (subTemplate) {
|
|
33
|
-
|
|
34
|
-
subRows = Array.isArray(subRows) ? subRows : [subRows]
|
|
35
|
-
_processComplex(processFn, subRows, subTemplate, key, pathOptions)
|
|
32
|
+
if (subTemplate && typeof row === 'object' && row) {
|
|
33
|
+
_processComplex(processFn, row, subTemplate, key, pathOptions)
|
|
36
34
|
}
|
|
37
35
|
}
|
|
38
36
|
|
|
39
|
-
const _processComplex = (processFn,
|
|
37
|
+
const _processComplex = (processFn, row, template, key, pathOptions) => {
|
|
38
|
+
const value = row && row[key]
|
|
39
|
+
const _is2many = Array.isArray(value)
|
|
40
|
+
const rows = _is2many ? value : [value]
|
|
40
41
|
if (rows.length === 0) return
|
|
42
|
+
const keyNames = (template.target.keys && Object.keys(template.target.keys)) || []
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
for (const row of rows) {
|
|
44
|
+
for (let idx = 0; idx < rows.length; idx++) {
|
|
45
|
+
const row = rows[idx]
|
|
46
46
|
if (row == null) continue
|
|
47
47
|
const args = { processFn, row, template, isRoot: false, pathOptions }
|
|
48
48
|
|
|
49
|
+
let url
|
|
49
50
|
if (pathOptions.includeKeyValues) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const pathSegment = _formatRowContext(tKey, keyNames, { ...row, ...pathOptions.extraKeys })
|
|
53
|
-
args.pathOptions.segments = segments ? [...segments, pathSegment] : [pathSegment]
|
|
51
|
+
if (pathOptions.rowKeysGenerator) pathOptions.rowKeysGenerator(keyNames, row, template)
|
|
52
|
+
url = _formatRowContext(key, keyNames, Object.assign({}, row, pathOptions.extraKeys))
|
|
54
53
|
}
|
|
55
54
|
|
|
55
|
+
if (pathOptions.path) pathOptions.path.push({ key, idx: _is2many && idx, url })
|
|
56
|
+
|
|
56
57
|
templateProcessor(args)
|
|
58
|
+
|
|
59
|
+
if (pathOptions.path) pathOptions.path.pop()
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
62
|
|
|
@@ -61,10 +64,7 @@ const _processComplex = (processFn, rows, template, tKey, pathOptions) => {
|
|
|
61
64
|
* @param {import("../../types/api").TemplateProcessor} args
|
|
62
65
|
*/
|
|
63
66
|
const templateProcessor = ({ processFn, row, template, isRoot = true, pathOptions = {} }) => {
|
|
64
|
-
const segments = pathOptions.segments && [...pathOptions.segments]
|
|
65
|
-
|
|
66
67
|
for (const [tKey, tValue] of template.elements) {
|
|
67
|
-
if (segments) pathOptions.segments = [...segments]
|
|
68
68
|
_processRow(processFn, row, template, tKey, tValue, isRoot, pathOptions)
|
|
69
69
|
}
|
|
70
70
|
}
|