@sap/cds 5.9.7 → 6.0.2
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 +267 -20
- package/apis/services.d.ts +1 -1
- package/app/fiori/preview.js +2 -6
- package/app/index.js +3 -3
- package/bin/build/buildTaskEngine.js +17 -15
- package/bin/build/buildTaskFactory.js +29 -19
- package/bin/build/buildTaskHandler.js +27 -11
- package/bin/build/buildTaskProvider.js +2 -4
- package/bin/build/buildTaskProviderFactory.js +11 -16
- package/bin/build/constants.js +14 -6
- package/bin/build/csv-reader.js +2 -1
- package/bin/build/index.js +12 -18
- package/bin/build/provider/buildTaskHandlerEdmx.js +3 -39
- package/bin/build/provider/buildTaskHandlerFeatureToggles.js +149 -0
- package/bin/build/provider/buildTaskHandlerInternal.js +2 -3
- package/bin/build/provider/buildTaskProviderInternal.js +108 -239
- package/bin/build/provider/fiori/index.js +2 -2
- package/bin/build/provider/hana/2migration.js +11 -11
- package/bin/build/provider/hana/2tabledata.js +3 -3
- package/bin/build/provider/hana/index.js +89 -99
- package/bin/build/provider/hana/migrationtable.js +4 -3
- package/bin/build/provider/java/index.js +101 -0
- package/bin/build/provider/java-cf/index.js +1 -101
- package/bin/build/provider/mtx/index.js +90 -53
- package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
- package/bin/build/provider/mtx-sidecar/index.js +110 -0
- package/bin/build/provider/node-cf/index.js +1 -308
- package/bin/build/provider/nodejs/index.js +189 -0
- package/bin/build/util.js +19 -31
- package/bin/cds.js +5 -3
- package/bin/deploy/to-hana/cfUtil.js +31 -6
- package/bin/deploy/to-hana/gitUtil.js +5 -3
- package/bin/deploy/to-hana/hana.js +9 -10
- package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
- package/bin/mtx/in-cds.js +19 -7
- package/bin/serve.js +56 -21
- package/bin/utils/log.js +13 -30
- package/bin/version.js +5 -4
- package/common.cds +61 -16
- package/lib/compile/cdsc.js +3 -2
- package/lib/compile/etc/_localized.js +15 -14
- package/lib/compile/for/drafts.js +3 -4
- package/lib/compile/for/java.js +13 -10
- package/lib/compile/for/nodejs.js +8 -8
- package/lib/compile/for/odata.js +7 -12
- package/lib/compile/for/sql.js +5 -6
- package/lib/compile/index.js +5 -4
- package/lib/compile/load.js +9 -11
- package/lib/compile/minify.js +8 -5
- package/lib/compile/parse.js +4 -2
- package/lib/compile/resolve.js +18 -15
- package/lib/compile/to/edm.js +0 -1
- package/lib/compile/to/gql.js +3 -2
- package/lib/compile/to/json.js +24 -17
- package/lib/connect/bindings.js +3 -2
- package/lib/connect/index.js +5 -5
- package/lib/core/classes.js +74 -2
- package/lib/core/entities.js +52 -3
- package/lib/core/reflect.js +2 -1
- package/lib/deploy.js +11 -8
- package/lib/env/defaults.js +4 -3
- package/lib/env/index.js +71 -31
- package/lib/env/presets.js +1 -14
- package/lib/env/requires.js +71 -20
- package/lib/env/serviceBindings.js +147 -0
- package/lib/i18n/localize.js +22 -23
- package/lib/index.js +148 -144
- package/lib/log/errors.js +55 -12
- package/lib/log/format/kibana.js +1 -1
- package/lib/log/index.js +4 -0
- package/lib/ql/SELECT.js +7 -2
- package/lib/ql/Whereable.js +8 -2
- package/lib/ql/index.js +2 -2
- package/lib/req/assert.js +71 -0
- package/lib/req/cds-context.js +38 -70
- package/lib/req/context.js +34 -21
- package/lib/req/request.js +12 -18
- package/lib/req/response.js +6 -2
- package/lib/req/user.js +30 -22
- package/lib/serve/Service-api.js +17 -12
- package/lib/serve/Service-dispatch.js +5 -9
- package/lib/serve/Service-methods.js +4 -3
- package/lib/serve/Transaction.js +24 -21
- package/lib/serve/adapters.js +15 -5
- package/lib/serve/factory.js +23 -20
- package/lib/serve/index.js +51 -54
- package/lib/utils/axios.js +8 -12
- package/lib/utils/index.js +3 -3
- package/lib/utils/resources/index.js +1 -44
- package/lib/utils/resources/tar.js +2 -1
- package/lib/utils/tests.js +13 -15
- package/libx/_runtime/.eslintrc +1 -1
- package/libx/_runtime/audit/Service.js +6 -4
- package/libx/_runtime/audit/generic/personal/access.js +19 -43
- package/libx/_runtime/audit/generic/personal/index.js +40 -34
- package/libx/_runtime/audit/generic/personal/modification.js +11 -9
- package/libx/_runtime/audit/generic/personal/utils.js +13 -6
- package/libx/_runtime/audit/utils/v2.js +6 -3
- package/libx/_runtime/auth/index.js +71 -66
- package/libx/_runtime/auth/strategies/JWT.js +3 -2
- package/libx/_runtime/auth/strategies/mock.js +54 -53
- package/libx/_runtime/auth/strategies/xssecUtils.js +3 -4
- package/libx/_runtime/auth/strategies/xsuaa.js +3 -2
- package/libx/_runtime/auth/utils.js +2 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +128 -42
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +93 -73
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +10 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -9
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +9 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +60 -53
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +8 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +29 -41
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -13
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectToCQN.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +24 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityContainer.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/PrimitiveValueDecoder.js +4 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/validator/ValueValidator.js +5 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/ResponseHeaderSetter.js +2 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DebugSerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/PresetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ContextURLFactory.js +3 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ErrorJsonSerializer.js +3 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/TrustedResourceJsonSerializer.js +3 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +36 -25
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +100 -91
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +382 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +5 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +77 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +3 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +91 -69
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +27 -6
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +7 -17
- package/libx/_runtime/cds-services/services/Service.js +17 -76
- package/libx/_runtime/cds-services/services/utils/columns.js +6 -4
- package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -53
- package/libx/_runtime/cds-services/services/utils/differ.js +15 -19
- package/libx/_runtime/cds-services/util/assert.js +107 -34
- package/libx/_runtime/cds.js +1 -31
- package/libx/_runtime/common/aspects/Association.js +40 -54
- package/libx/_runtime/common/aspects/any.js +61 -6
- package/libx/_runtime/common/aspects/entity.js +19 -79
- package/libx/_runtime/common/composition/data.js +2 -2
- package/libx/_runtime/common/composition/delete.js +8 -7
- package/libx/_runtime/common/composition/tree.js +10 -10
- package/libx/_runtime/common/composition/update.js +3 -2
- package/libx/_runtime/common/constants/events.js +15 -0
- package/libx/_runtime/common/error/entry.js +9 -3
- package/libx/_runtime/common/error/frontend.js +13 -19
- package/libx/_runtime/common/error/index.js +8 -3
- package/libx/_runtime/common/generic/auth/capabilities.js +2 -1
- package/libx/_runtime/common/generic/auth/constants.js +1 -4
- package/libx/_runtime/common/generic/auth/requires.js +1 -1
- package/libx/_runtime/common/generic/auth/restrict.js +12 -28
- package/libx/_runtime/common/generic/auth/restrictions.js +12 -4
- package/libx/_runtime/common/generic/auth/utils.js +2 -1
- package/libx/_runtime/common/generic/crud.js +9 -60
- package/libx/_runtime/common/generic/etag.js +41 -7
- package/libx/_runtime/common/generic/input.js +128 -66
- package/libx/_runtime/common/generic/paging.js +9 -3
- package/libx/_runtime/common/generic/put.js +2 -2
- package/libx/_runtime/common/generic/sorting.js +7 -3
- package/libx/_runtime/common/generic/temporal.js +0 -5
- package/libx/_runtime/common/i18n/messages.properties +2 -1
- package/libx/_runtime/common/utils/binary.js +69 -0
- package/libx/_runtime/common/utils/cqn.js +39 -14
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +93 -59
- package/libx/_runtime/common/utils/csn.js +87 -85
- package/libx/_runtime/common/utils/dollar.js +8 -7
- package/libx/_runtime/common/utils/draft.js +1 -1
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +23 -7
- package/libx/_runtime/common/utils/generateOnCond.js +2 -1
- package/libx/_runtime/common/utils/keys.js +30 -13
- package/libx/_runtime/common/utils/postProcessing.js +6 -1
- package/libx/_runtime/common/utils/quotingStyles.js +0 -23
- package/libx/_runtime/common/utils/resolveStructured.js +23 -26
- package/libx/_runtime/common/utils/resolveView.js +4 -1
- package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -0
- package/libx/_runtime/common/utils/search2cqn4sql.js +4 -13
- package/libx/_runtime/common/utils/searchToLike.js +9 -13
- package/libx/_runtime/common/utils/streamProp.js +35 -0
- package/libx/_runtime/common/utils/structured.js +12 -18
- package/libx/_runtime/common/utils/template.js +3 -5
- package/libx/_runtime/common/utils/templateProcessor.js +22 -14
- package/libx/_runtime/common/utils/unionCqnTemplate.js +4 -14
- package/libx/_runtime/db/Service.js +2 -1
- package/libx/_runtime/db/expand/expand-v2.js +2 -2
- package/libx/_runtime/db/expand/expandCQNToJoin.js +7 -6
- package/libx/_runtime/db/generic/input.js +14 -17
- package/libx/_runtime/db/generic/integrity.js +1 -2
- package/libx/_runtime/db/generic/update.js +14 -1
- package/libx/_runtime/db/query/read.js +0 -1
- package/libx/_runtime/db/query/update.js +1 -1
- package/libx/_runtime/db/sql-builder/BaseBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +5 -31
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +0 -9
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +11 -10
- package/libx/_runtime/db/sql-builder/UpdateBuilder.js +2 -2
- package/libx/_runtime/db/sql-builder/annotations.js +1 -2
- package/libx/_runtime/db/utils/coloredTxCommands.js +5 -0
- package/libx/_runtime/db/utils/columns.js +1 -1
- package/libx/_runtime/db/utils/propagateForeignKeys.js +10 -2
- package/libx/_runtime/extensibility/activate.js +69 -0
- package/libx/_runtime/extensibility/add.js +41 -0
- package/libx/_runtime/extensibility/addExtension.js +68 -0
- package/libx/_runtime/extensibility/defaults.js +39 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformREAD.js +0 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformRESULT.js +2 -2
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformWRITE.js +2 -2
- package/libx/_runtime/extensibility/push.js +61 -0
- package/libx/_runtime/extensibility/service.js +21 -0
- package/libx/_runtime/extensibility/{uiflex/utils.js → utils.js} +39 -3
- package/libx/_runtime/extensibility/validation.js +53 -0
- package/libx/_runtime/extensibility/views.js +12 -0
- package/libx/_runtime/fiori/generic/activate.js +6 -4
- package/libx/_runtime/fiori/generic/before.js +17 -29
- package/libx/_runtime/fiori/generic/cancel.js +2 -4
- package/libx/_runtime/fiori/generic/delete.js +2 -4
- package/libx/_runtime/fiori/generic/edit.js +3 -7
- package/libx/_runtime/fiori/generic/index.js +31 -0
- package/libx/_runtime/fiori/generic/new.js +2 -4
- package/libx/_runtime/fiori/generic/patch.js +4 -8
- package/libx/_runtime/fiori/generic/prepare.js +2 -4
- package/libx/_runtime/fiori/generic/read.js +137 -162
- package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
- package/libx/_runtime/fiori/utils/handler.js +10 -5
- package/libx/_runtime/fiori/utils/where.js +1 -4
- package/libx/_runtime/hana/Service.js +14 -7
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +1 -1
- package/libx/_runtime/hana/dynatrace.js +2 -2
- package/libx/_runtime/hana/localized.js +7 -6
- package/libx/_runtime/hana/pool.js +9 -6
- package/libx/_runtime/hana/search.js +2 -3
- package/libx/_runtime/hana/{searchToContains.js → search2Contains.js} +5 -2
- package/libx/_runtime/hana/search2cqn4sql.js +20 -17
- package/libx/_runtime/index.js +2 -6
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +11 -2
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -3
- package/libx/_runtime/messaging/common-utils/appId.js +9 -0
- package/libx/_runtime/messaging/common-utils/authorizedRequest.js +2 -18
- package/libx/_runtime/messaging/common-utils/connections.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +305 -231
- package/libx/_runtime/messaging/enterprise-messaging-utils/cloudEvents.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-management.js +15 -8
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-messaging.js +57 -14
- package/libx/_runtime/messaging/enterprise-messaging.js +14 -19
- package/libx/_runtime/messaging/file-based.js +2 -1
- package/libx/_runtime/messaging/http-utils/token.js +18 -6
- package/libx/_runtime/messaging/message-queuing-utils/options-management.js +22 -12
- package/libx/_runtime/messaging/message-queuing-utils/options-messaging.js +27 -14
- package/libx/_runtime/messaging/message-queuing.js +138 -85
- package/libx/_runtime/messaging/outbox/utils.js +13 -7
- package/libx/_runtime/messaging/redis-messaging.js +0 -1
- package/libx/_runtime/messaging/service.js +4 -1
- package/libx/_runtime/remote/Service.js +24 -18
- package/libx/_runtime/remote/utils/client.js +84 -46
- package/libx/_runtime/remote/utils/data.js +23 -6
- package/libx/_runtime/sqlite/Service.js +14 -13
- package/libx/_runtime/sqlite/convertAssocToOneManaged.js +2 -0
- package/libx/_runtime/sqlite/customBuilder/CustomSelectBuilder.js +1 -0
- package/libx/_runtime/sqlite/execute.js +3 -9
- package/libx/_runtime/types/api.js +23 -11
- package/libx/common/utils/ucsn.js +15 -9
- package/libx/odata/afterburner.js +109 -29
- package/libx/odata/cqn2odata.js +48 -9
- package/libx/odata/grammar.pegjs +261 -157
- package/libx/odata/index.js +21 -9
- package/libx/odata/parseToCqn.js +8 -5
- package/libx/odata/parser.js +1 -1
- package/libx/odata/utils.js +13 -3
- package/libx/rest/RestAdapter.js +173 -113
- package/libx/rest/RestRequest.js +3 -2
- package/libx/rest/middleware/create.js +8 -6
- package/libx/rest/middleware/delete.js +6 -13
- package/libx/rest/middleware/error.js +1 -1
- package/libx/rest/middleware/input.js +6 -6
- package/libx/rest/middleware/operation.js +8 -3
- package/libx/rest/middleware/parse.js +3 -3
- package/libx/rest/middleware/payload.js +12 -0
- package/libx/rest/middleware/read.js +12 -2
- package/libx/rest/middleware/update.js +3 -3
- package/package.json +4 -6
- package/server.js +3 -44
- package/srv/extensibility-service.cds +56 -0
- package/srv/extensibility-service.js +1 -0
- package/srv/extensions.cds +8 -0
- package/srv/model-provider.cds +59 -0
- package/srv/model-provider.js +163 -0
- package/srv/mtx.cds +2 -0
- package/srv/mtx.js +22 -0
- package/srv/outbox.cds +2 -0
- package/tasks/enterprise-messaging-deploy.js +19 -12
- package/lib/serve/Service-compat.js +0 -36
- package/libx/_runtime/audit/generic/personal/constants.js +0 -4
- package/libx/_runtime/auth/strategies/dwc.js +0 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/Rest.js +0 -183
- package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -67
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -82
- package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +0 -39
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +0 -63
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +0 -52
- package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +0 -81
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +0 -33
- package/libx/_runtime/cds-services/adapter/rest/to.js +0 -8
- package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +0 -50
- package/libx/_runtime/cds-services/adapter/rest/utils/data.js +0 -117
- package/libx/_runtime/cds-services/adapter/rest/utils/header-checks.js +0 -14
- package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +0 -30
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +0 -250
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +0 -26
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +0 -200
- package/libx/_runtime/common/aspects/utils.js +0 -152
- package/libx/_runtime/common/toggles/handler.js +0 -21
- package/libx/_runtime/common/utils/extensibilityUtils.js +0 -18
- package/libx/_runtime/extensibility/mps/index.js +0 -5
- package/libx/_runtime/extensibility/mps/service.js +0 -111
- package/libx/_runtime/extensibility/mps/tar.js +0 -42
- package/libx/_runtime/extensibility/mps/utils.js +0 -11
- package/libx/_runtime/extensibility/uiflex/index.js +0 -54
- package/libx/_runtime/extensibility/uiflex/service.js +0 -276
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +0 -20
- package/libx/_runtime/remote/utils/client-types.d.ts +0 -7
- package/libx/gql/GraphQLAdapter.js +0 -33
- package/libx/gql/constants/adapter.js +0 -69
- package/libx/gql/constants/cds.js +0 -18
- package/libx/gql/constants/graphql.js +0 -33
- package/libx/gql/readme.md +0 -1
- package/libx/gql/resolvers/crud/create.js +0 -20
- package/libx/gql/resolvers/crud/delete.js +0 -29
- package/libx/gql/resolvers/crud/index.js +0 -6
- package/libx/gql/resolvers/crud/read.js +0 -30
- package/libx/gql/resolvers/crud/update.js +0 -42
- package/libx/gql/resolvers/crud/utils/index.js +0 -36
- package/libx/gql/resolvers/field.js +0 -5
- package/libx/gql/resolvers/index.js +0 -7
- package/libx/gql/resolvers/mutation.js +0 -23
- package/libx/gql/resolvers/parse/ast/enrich.js +0 -52
- package/libx/gql/resolvers/parse/ast/fragment.js +0 -11
- package/libx/gql/resolvers/parse/ast/fromObject.js +0 -39
- package/libx/gql/resolvers/parse/ast/index.js +0 -3
- package/libx/gql/resolvers/parse/ast/meta.js +0 -4
- package/libx/gql/resolvers/parse/ast/variable.js +0 -7
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +0 -44
- package/libx/gql/resolvers/parse/ast2cqn/entries.js +0 -31
- package/libx/gql/resolvers/parse/ast2cqn/index.js +0 -8
- package/libx/gql/resolvers/parse/ast2cqn/limit.js +0 -6
- package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +0 -24
- package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +0 -3
- package/libx/gql/resolvers/parse/ast2cqn/where.js +0 -70
- package/libx/gql/resolvers/parse/utils/index.js +0 -8
- package/libx/gql/resolvers/query.js +0 -13
- package/libx/gql/resolvers/root.js +0 -34
- package/libx/gql/schema/generate.js +0 -18
- package/libx/gql/schema/index.js +0 -5
- package/libx/gql/schema/mutation.js +0 -76
- package/libx/gql/schema/query.js +0 -108
- package/libx/gql/schema/typeDefMap.js +0 -45
- package/libx/gql/schema/utils/index.js +0 -54
- package/libx/gql/utils/index.js +0 -12
- package/libx/rest/middleware/auth.js +0 -20
- package/libx/rest/middleware/content.js +0 -19
- package/srv/flex.cds +0 -21
- package/srv/flex.js +0 -1
- package/srv/mps.cds +0 -23
- package/srv/mps.js +0 -1
- package/srv/outbox.js +0 -0
|
@@ -24,6 +24,7 @@ const _findSubselect = where => {
|
|
|
24
24
|
if (e.xpr) {
|
|
25
25
|
return _findSubselect(e.xpr)
|
|
26
26
|
}
|
|
27
|
+
|
|
27
28
|
return e.SELECT && where[i - 1] === 'exists'
|
|
28
29
|
})
|
|
29
30
|
}
|
|
@@ -33,29 +34,16 @@ const _findRootSubSelectFor = query => {
|
|
|
33
34
|
const subSelect = _findSubselect(query.SELECT.where)
|
|
34
35
|
return subSelect ? _findRootSubSelectFor(subSelect) : query
|
|
35
36
|
}
|
|
37
|
+
|
|
36
38
|
return query
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
// append where with clauses from @restrict
|
|
40
|
-
const _getWhereWithAppendedDraftRestrictions = (where = [], req
|
|
42
|
+
const _getWhereWithAppendedDraftRestrictions = (where = [], req) => {
|
|
41
43
|
if (req.query._draftRestrictions) {
|
|
42
44
|
for (const each of req.query._draftRestrictions) {
|
|
43
45
|
const xpr = each._xpr
|
|
44
46
|
if (each.target.name === ensureUnlocalized(req.target.name)) {
|
|
45
|
-
// > restriction directly on child
|
|
46
|
-
// REVISIT: remove support for selects in restriction with cds^6
|
|
47
|
-
// adjust alias of @restrict where "exists (select ...)"
|
|
48
|
-
if (scenarioAlias && model)
|
|
49
|
-
xpr
|
|
50
|
-
.filter(e => e.SELECT && e.SELECT.from && e.SELECT.where)
|
|
51
|
-
.forEach(e => {
|
|
52
|
-
const entity = model.definitions[e.SELECT.from.ref[0]]
|
|
53
|
-
e.SELECT.where = e.SELECT.where.map(w => {
|
|
54
|
-
if (w.ref && w.ref.length === 1 && !entity.elements[w.ref[0]]) w.ref.unshift(scenarioAlias)
|
|
55
|
-
return w
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
|
|
59
47
|
if (where.length) where.push('and')
|
|
60
48
|
// restriction might contain or clause -> use xpr for grouping
|
|
61
49
|
xpr.includes('or') ? where.push({ xpr }) : where.push(...xpr)
|
|
@@ -76,13 +64,12 @@ const _getWhereWithAppendedDraftRestrictions = (where = [], req, scenarioAlias,
|
|
|
76
64
|
}
|
|
77
65
|
}
|
|
78
66
|
}
|
|
67
|
+
|
|
79
68
|
return where
|
|
80
69
|
}
|
|
81
70
|
|
|
82
71
|
const _isTrue = val => val === true || val === 'true'
|
|
83
|
-
|
|
84
72
|
const _isFalse = val => val === false || val === 'false'
|
|
85
|
-
|
|
86
73
|
const _inProcessByUserWhere = userId => [{ ref: ['filterAdmin', 'InProcessByUser'] }, '=', { val: userId }]
|
|
87
74
|
|
|
88
75
|
const _getTableName = (
|
|
@@ -162,7 +149,6 @@ const _getDefaultDraftProperties = ({ hasDraft, isActive = true, withDraftUUID =
|
|
|
162
149
|
// draft values for active entities with calculated hasDraft property
|
|
163
150
|
const _getDraftPropertiesDetermineDraft = (req, where, tableName, calcDraftUUID = false) => {
|
|
164
151
|
const { table } = _getTableName(req, true)
|
|
165
|
-
|
|
166
152
|
tableName = tableName || table
|
|
167
153
|
|
|
168
154
|
const hasDraftQuery = SELECT.from(tableName, [{ val: 1 }])
|
|
@@ -209,18 +195,18 @@ function _copyCQNPartial(partial) {
|
|
|
209
195
|
return newPartial
|
|
210
196
|
}
|
|
211
197
|
|
|
212
|
-
|
|
198
|
+
if (partial.ref) {
|
|
199
|
+
return Object.assign({}, partial, { ref: _copyArray(partial.ref) })
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return Object.assign({}, partial)
|
|
213
203
|
}
|
|
214
204
|
|
|
215
205
|
function _copyArray(array) {
|
|
216
|
-
return array.map(entry =>
|
|
217
|
-
return typeof entry === 'object' && !(entry instanceof String) ? _copyCQNPartial(entry) : entry
|
|
218
|
-
})
|
|
206
|
+
return array.map(entry => (typeof entry === 'object' && !(entry instanceof String) ? _copyCQNPartial(entry) : entry))
|
|
219
207
|
}
|
|
220
208
|
|
|
221
|
-
const _isValidDraftOfWhichIAmOwner = isActiveEntity =>
|
|
222
|
-
return isActiveEntity.op === '=' && _isFalse(isActiveEntity.value.val)
|
|
223
|
-
}
|
|
209
|
+
const _isValidDraftOfWhichIAmOwner = isActiveEntity => isActiveEntity.op === '=' && _isFalse(isActiveEntity.value.val)
|
|
224
210
|
|
|
225
211
|
const _isValidActiveWithoutDraft = (isActiveEntity, hasDraftEntity) => {
|
|
226
212
|
return (
|
|
@@ -293,7 +279,7 @@ const _getOuterMostColumns = (columnsFromRequest, additionalDraftColumns) => {
|
|
|
293
279
|
// adds base columns 'InProcessByUser' and 'CreatedByUser' to columns param if needed
|
|
294
280
|
// those are required for calculating 'DraftIsProcessedByMe' and 'DraftIsCreatedByMe'
|
|
295
281
|
const _ensureDraftAdminColumnsForCalculation = columns => {
|
|
296
|
-
columns.forEach(
|
|
282
|
+
columns.forEach(c => {
|
|
297
283
|
if (c.ref && c.ref[0] === 'DraftIsCreatedByMe' && !columns.find(e => e.ref && e.ref[0] === 'CreatedByUser')) {
|
|
298
284
|
columns.push({ ref: ['CreatedByUser'] })
|
|
299
285
|
} else if (
|
|
@@ -337,13 +323,7 @@ const _allInactive = (req, columns) => {
|
|
|
337
323
|
// ensure only own drafts are read
|
|
338
324
|
const cqn = SELECT.from(table)
|
|
339
325
|
.join('DRAFT.DraftAdministrativeData', 'filterAdmin')
|
|
340
|
-
.on([
|
|
341
|
-
{ ref: [table.as, 'DraftAdministrativeData_DraftUUID'] },
|
|
342
|
-
'=',
|
|
343
|
-
{
|
|
344
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
345
|
-
}
|
|
346
|
-
])
|
|
326
|
+
.on([{ ref: [table.as, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
|
|
347
327
|
.where(_inProcessByUserWhere(req.user.id))
|
|
348
328
|
|
|
349
329
|
if (isCount) {
|
|
@@ -353,7 +333,6 @@ const _allInactive = (req, columns) => {
|
|
|
353
333
|
}
|
|
354
334
|
|
|
355
335
|
cqn.where(req.query.SELECT.where)
|
|
356
|
-
|
|
357
336
|
return { cqn: getEnrichedCQN(cqn, req.query.SELECT, []), scenario: SCENARIO.ALL_INACTIVE }
|
|
358
337
|
}
|
|
359
338
|
|
|
@@ -377,22 +356,7 @@ const _buildWhere = (where, table) => {
|
|
|
377
356
|
}
|
|
378
357
|
}
|
|
379
358
|
|
|
380
|
-
const
|
|
381
|
-
for (const entry of query.SELECT.orderBy || []) {
|
|
382
|
-
// detect if calculated value
|
|
383
|
-
if (entry.ref && columns.some(c => c.as === entry.ref[entry.ref.length - 1])) {
|
|
384
|
-
// remove table alias if present
|
|
385
|
-
if (entry.ref[0] === table.as) {
|
|
386
|
-
entry.ref.splice(0, 1)
|
|
387
|
-
}
|
|
388
|
-
} else if (table.as && entry.ref[0] !== table.as) {
|
|
389
|
-
// if regular column and no alias present, add it
|
|
390
|
-
entry.ref.unshift(table.as)
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
const _allActive = (req, columns, model) => {
|
|
359
|
+
const _allActive = (req, columns) => {
|
|
396
360
|
const { table } = _getTableName(req)
|
|
397
361
|
if (!table.as) {
|
|
398
362
|
table.as = 'active'
|
|
@@ -405,7 +369,6 @@ const _allActive = (req, columns, model) => {
|
|
|
405
369
|
|
|
406
370
|
const ids = filterKeys(req.target.keys)
|
|
407
371
|
const isCount = columns.some(element => element.func === 'count')
|
|
408
|
-
|
|
409
372
|
const xpr = {
|
|
410
373
|
xpr: [
|
|
411
374
|
'case',
|
|
@@ -437,15 +400,12 @@ const _allActive = (req, columns, model) => {
|
|
|
437
400
|
}
|
|
438
401
|
|
|
439
402
|
const scenarioAlias = 'active'
|
|
440
|
-
|
|
441
|
-
req.query.SELECT.where = _getWhereWithAppendedDraftRestrictions(req.query.SELECT.where, req, scenarioAlias, model)
|
|
403
|
+
req.query.SELECT.where = _getWhereWithAppendedDraftRestrictions(req.query.SELECT.where, req)
|
|
442
404
|
|
|
443
405
|
if (req.query.SELECT.where) {
|
|
444
406
|
_buildWhere(req.query.SELECT.where, table)
|
|
445
407
|
}
|
|
446
408
|
|
|
447
|
-
_buildOrderBy(req.query, cqn.SELECT.columns, table)
|
|
448
|
-
|
|
449
409
|
return {
|
|
450
410
|
cqn: getEnrichedCQN(cqn, req.query.SELECT, req.query.SELECT.where, scenarioAlias),
|
|
451
411
|
scenario: SCENARIO.ALL_ACTIVE
|
|
@@ -472,31 +432,22 @@ const _activeWithoutDraft = (req, draftWhere, columns) => {
|
|
|
472
432
|
)
|
|
473
433
|
|
|
474
434
|
const outerMostColumns = _getOuterMostColumns(columns, _getDefaultDraftProperties({ hasDraft: false }))
|
|
475
|
-
|
|
476
435
|
const cqn = SELECT.from(active.table)
|
|
477
436
|
.columns(...outerMostColumns)
|
|
478
437
|
.where(['not exists', subSelect])
|
|
479
438
|
|
|
480
439
|
draftWhere = _getWhereWithAppendedDraftRestrictions(draftWhere, req)
|
|
481
|
-
|
|
482
440
|
return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.ACTIVE_WITHOUT_DRAFT }
|
|
483
441
|
}
|
|
484
442
|
|
|
485
443
|
const _draftOfWhichIAmOwner = (req, draftWhere, columns) => {
|
|
486
444
|
const { table, name } = _getTableName(req, true)
|
|
487
|
-
|
|
488
445
|
const outerMostColumns = _getOuterMostColumns(addColumnAlias(columns, name), DRAFT_COLUMNS_CASTED)
|
|
489
446
|
|
|
490
447
|
const cqn = SELECT.from(table)
|
|
491
448
|
.columns(...outerMostColumns)
|
|
492
449
|
.join('DRAFT.DraftAdministrativeData', 'filterAdmin')
|
|
493
|
-
.on([
|
|
494
|
-
{ ref: [name, 'DraftAdministrativeData_DraftUUID'] },
|
|
495
|
-
'=',
|
|
496
|
-
{
|
|
497
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
498
|
-
}
|
|
499
|
-
])
|
|
450
|
+
.on([{ ref: [name, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
|
|
500
451
|
.where(_inProcessByUserWhere(req.user.id))
|
|
501
452
|
|
|
502
453
|
return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.DRAFT_WHICH_OWNER }
|
|
@@ -512,13 +463,7 @@ const _activeWithDraftInProcess = (req, draftWhere, columns, isLocked) => {
|
|
|
512
463
|
let subSelect = SELECT.from(draftName)
|
|
513
464
|
.columns(...keys)
|
|
514
465
|
.join('DRAFT.DraftAdministrativeData', 'filterAdmin')
|
|
515
|
-
.on([
|
|
516
|
-
{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] },
|
|
517
|
-
'=',
|
|
518
|
-
{
|
|
519
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
520
|
-
}
|
|
521
|
-
])
|
|
466
|
+
.on([{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
|
|
522
467
|
|
|
523
468
|
const DRAFT_CANCEL_TIMEOUT_IN_SEC = ((cds.env.drafts && cds.env.drafts.cancellationTimeout) || 15) * 60
|
|
524
469
|
|
|
@@ -530,25 +475,20 @@ const _activeWithDraftInProcess = (req, draftWhere, columns, isLocked) => {
|
|
|
530
475
|
{ ref: ['filterAdmin', 'InProcessByUser'] },
|
|
531
476
|
'is not null',
|
|
532
477
|
'and',
|
|
533
|
-
{
|
|
534
|
-
func: 'seconds_between',
|
|
535
|
-
args: [{ ref: ['filterAdmin', 'LastChangeDateTime'] }, 'CURRENT_TIMESTAMP']
|
|
536
|
-
},
|
|
478
|
+
{ func: 'seconds_between', args: [{ ref: ['filterAdmin', 'LastChangeDateTime'] }, 'CURRENT_TIMESTAMP'] },
|
|
537
479
|
isLocked ? '<' : '>',
|
|
538
480
|
{ val: DRAFT_CANCEL_TIMEOUT_IN_SEC }
|
|
539
481
|
])
|
|
540
482
|
|
|
541
483
|
subSelect = keys.reduce(
|
|
542
|
-
(
|
|
484
|
+
(_select, key) => subSelect.where([{ ref: [active.name, key] }, '=', { ref: [draftName, key] }]),
|
|
543
485
|
subSelect
|
|
544
486
|
)
|
|
545
487
|
|
|
546
488
|
const outerMostColumns = _getOuterMostColumns(columns, draftColumns)
|
|
547
|
-
|
|
548
489
|
const cqn = SELECT.from(active.table).columns(outerMostColumns)
|
|
549
490
|
cqn.where(_getWhereWithAppendedDraftRestrictions([], req))
|
|
550
491
|
cqn.where(['exists', subSelect])
|
|
551
|
-
|
|
552
492
|
return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.DRAFT_IN_PROCESS }
|
|
553
493
|
}
|
|
554
494
|
|
|
@@ -572,10 +512,12 @@ const _joinFromWhere = (where, parentAlias, targetAlias) => {
|
|
|
572
512
|
return where.reduce((links, el, idx, where) => {
|
|
573
513
|
if (el.xpr) {
|
|
574
514
|
const result = _joinFromWhere(el.xpr, parentAlias, targetAlias)
|
|
515
|
+
|
|
575
516
|
if (result.length) {
|
|
576
517
|
if (links.length) links.push('and')
|
|
577
518
|
links.push(...result)
|
|
578
519
|
}
|
|
520
|
+
|
|
579
521
|
return links
|
|
580
522
|
}
|
|
581
523
|
|
|
@@ -584,11 +526,13 @@ const _joinFromWhere = (where, parentAlias, targetAlias) => {
|
|
|
584
526
|
if (links.length) links.push('and')
|
|
585
527
|
links.push(el, '=', where[idx - 2])
|
|
586
528
|
}
|
|
529
|
+
|
|
587
530
|
if (where[idx + 1] && where[idx + 1] === '=' && isTargetRef(where[idx + 2], targetAlias)) {
|
|
588
531
|
if (links.length) links.push('and')
|
|
589
532
|
links.push(el, '=', where[idx + 2])
|
|
590
533
|
}
|
|
591
534
|
}
|
|
535
|
+
|
|
592
536
|
return links
|
|
593
537
|
}, [])
|
|
594
538
|
}
|
|
@@ -609,6 +553,7 @@ const _functionContainsDraftField = obj =>
|
|
|
609
553
|
})
|
|
610
554
|
|
|
611
555
|
const _isLogicalFunction = (where, index) => {
|
|
556
|
+
// REVISIT
|
|
612
557
|
const borders = ['(', ')', 'and', 'or', undefined]
|
|
613
558
|
|
|
614
559
|
return borders.includes(where[index - 1]) && borders.includes(where[index + 1])
|
|
@@ -621,6 +566,7 @@ const _getWhereForActive = where => {
|
|
|
621
566
|
activeWhere.push({ xpr: _getWhereForActive(where[i].xpr) })
|
|
622
567
|
continue
|
|
623
568
|
}
|
|
569
|
+
|
|
624
570
|
if (_isDraftField(where[i])) {
|
|
625
571
|
activeWhere.push({ val: null })
|
|
626
572
|
} else if (_functionContainsDraftField(where[i])) {
|
|
@@ -666,9 +612,10 @@ const _siblingEntity = (
|
|
|
666
612
|
const subScenario = _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, model, onCond, req)
|
|
667
613
|
const isSiblingDraft = subScenario
|
|
668
614
|
? subScenario.isSiblingActive || subScenario.scenario === 'ACTIVE' || subScenario.scenario === 'ALL_ACTIVE'
|
|
669
|
-
: keys.IsActiveEntity && keys.IsActiveEntity !==
|
|
615
|
+
: keys.IsActiveEntity && keys.IsActiveEntity !== false
|
|
670
616
|
const { table } = _getTableName({ query, target }, isSiblingDraft)
|
|
671
617
|
const cqn = SELECT.from(table)
|
|
618
|
+
|
|
672
619
|
if (siblingIndex === 0) {
|
|
673
620
|
const columnCqnPartial = columns.map(col => {
|
|
674
621
|
const colName = col.ref ? col.ref[col.ref.length - 1] : col
|
|
@@ -698,14 +645,16 @@ const _siblingEntity = (
|
|
|
698
645
|
for (const key in keys) {
|
|
699
646
|
if (key !== 'IsActiveEntity') cqn.where([{ ref: [table.as, key] }, '=', { val: keys[key] }])
|
|
700
647
|
}
|
|
648
|
+
|
|
701
649
|
if (subScenario) {
|
|
702
650
|
cqn.where(['exists', subScenario.cqn])
|
|
703
651
|
}
|
|
652
|
+
|
|
704
653
|
// in DraftAdminData scenario parent is linked via join
|
|
705
654
|
if (draftAdminAlias) {
|
|
706
655
|
cqn.where([{ ref: [draftAdminAlias, 'DraftUUID'] }, '=', { ref: ['draftAdmin', 'DraftUUID'] }])
|
|
707
656
|
} else if (parentLinks.length) {
|
|
708
|
-
cqn.where(
|
|
657
|
+
cqn.where({ xpr: [...parentLinks] })
|
|
709
658
|
}
|
|
710
659
|
|
|
711
660
|
return { cqn, scenario: SCENARIO.SIBLING_ENTITY, isSiblingActive: !isSiblingDraft }
|
|
@@ -722,6 +671,7 @@ function _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, mo
|
|
|
722
671
|
params: [...params].reverse(),
|
|
723
672
|
user: req.user
|
|
724
673
|
}
|
|
674
|
+
|
|
725
675
|
if (subSiblingIndex > -1) {
|
|
726
676
|
subScenario = _getSiblingScenario(subReq, [{ val: 1 }], model, subSiblingIndex, subNav, params)
|
|
727
677
|
if (subSiblingIndex > 0) {
|
|
@@ -732,12 +682,14 @@ function _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, mo
|
|
|
732
682
|
}
|
|
733
683
|
} else {
|
|
734
684
|
subReq.query = SELECT.from(siblingQuery.SELECT.from).columns([{ val: 1 }])
|
|
685
|
+
|
|
735
686
|
const existsIdx = siblingQuery.SELECT.where.indexOf('exists')
|
|
736
687
|
if (existsIdx > -1) subReq.query.where(siblingQuery.SELECT.where.slice(existsIdx, existsIdx + 2))
|
|
737
688
|
const subOrigFrom = { ref: [...subNav].reverse() }
|
|
738
689
|
subScenario = _generateCQN(subOrigFrom, subReq, [{ val: 1 }], model)
|
|
739
690
|
subScenario.cqn.where(onCond)
|
|
740
691
|
}
|
|
692
|
+
|
|
741
693
|
return subScenario
|
|
742
694
|
}
|
|
743
695
|
|
|
@@ -753,6 +705,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
|
|
|
753
705
|
queryIndex - 1,
|
|
754
706
|
query
|
|
755
707
|
)
|
|
708
|
+
|
|
756
709
|
if (sibilingQueryFromWhere) return sibilingQueryFromWhere
|
|
757
710
|
}
|
|
758
711
|
|
|
@@ -761,6 +714,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
|
|
|
761
714
|
}
|
|
762
715
|
}
|
|
763
716
|
}
|
|
717
|
+
|
|
764
718
|
const target = { name: query.SELECT.from.ref[0].id || query.SELECT.from.ref[0], as: query.SELECT.from.as }
|
|
765
719
|
return _siblingEntity(
|
|
766
720
|
{ query, target, params, nav },
|
|
@@ -772,6 +726,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
|
|
|
772
726
|
req
|
|
773
727
|
)
|
|
774
728
|
}
|
|
729
|
+
|
|
775
730
|
return _getSiblingQueryFromWhere(req.query, siblingIndex)
|
|
776
731
|
}
|
|
777
732
|
|
|
@@ -807,9 +762,7 @@ const _getDraftDoc = (req, draftName, draftWhere) => {
|
|
|
807
762
|
.on([
|
|
808
763
|
{ ref: [req.query.SELECT.from.as || draftName, 'DraftAdministrativeData_DraftUUID'] },
|
|
809
764
|
'=',
|
|
810
|
-
{
|
|
811
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
812
|
-
}
|
|
765
|
+
{ ref: ['filterAdmin', 'DraftUUID'] }
|
|
813
766
|
])
|
|
814
767
|
.where(_inProcessByUserWhere(req.user.id)),
|
|
815
768
|
req.query.SELECT,
|
|
@@ -835,6 +788,7 @@ const _getOrderByEnrichedColumns = (orderBy, columns, entity) => {
|
|
|
835
788
|
}
|
|
836
789
|
}
|
|
837
790
|
}
|
|
791
|
+
|
|
838
792
|
return enrichedCol
|
|
839
793
|
}
|
|
840
794
|
|
|
@@ -911,28 +865,24 @@ const _getUnionCQN = (req, draftName, columns, subSelect, draftWhere, model, ent
|
|
|
911
865
|
draftDocs.columns(draftColumns)
|
|
912
866
|
|
|
913
867
|
const activeName = activeDocs.SELECT.from.as || (activeDocs.SELECT.from.ref && activeDocs.SELECT.from.ref[0])
|
|
914
|
-
|
|
915
868
|
const hasDraftWhere = []
|
|
916
|
-
|
|
869
|
+
const targetKeys = _getTargetKeys(req)
|
|
870
|
+
for (const key of targetKeys) {
|
|
917
871
|
// add 'and' token if not the first iteration
|
|
918
872
|
if (hasDraftWhere.length) hasDraftWhere.push('and')
|
|
919
873
|
hasDraftWhere.push({ ref: [activeName, key] }, '=', { ref: [draftName, key] })
|
|
920
874
|
}
|
|
921
875
|
|
|
922
|
-
const
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
)
|
|
929
|
-
]
|
|
876
|
+
const draftColumnsBySelected = _filterDraftColumnsBySelected(
|
|
877
|
+
_getDraftPropertiesDetermineDraft(req, hasDraftWhere, ensureDraftsSuffix(req.target.name), true),
|
|
878
|
+
req.query.SELECT.columns
|
|
879
|
+
)
|
|
880
|
+
|
|
881
|
+
const activeColumns = [...columns, ...enrichedColumns, ...draftColumnsBySelected]
|
|
930
882
|
activeDocs.columns(activeColumns)
|
|
931
883
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
_alignAliasForUnion(ensureNoDraftsSuffix(req.target.name), req.query.SELECT.from.as, subSelect)
|
|
935
|
-
])
|
|
884
|
+
const aliasForUnion = _alignAliasForUnion(ensureNoDraftsSuffix(req.target.name), req.query.SELECT.from.as, subSelect)
|
|
885
|
+
activeDocs.where(['not exists', aliasForUnion])
|
|
936
886
|
|
|
937
887
|
// groupBy, orderBy and limit do not support partial CQNs
|
|
938
888
|
if (req.query.SELECT.groupBy) {
|
|
@@ -958,17 +908,12 @@ const _excludeActiveDraftExists = (req, draftWhere, columns, model) => {
|
|
|
958
908
|
|
|
959
909
|
const subSelect = SELECT.from(draftName, [1])
|
|
960
910
|
.join('DRAFT.DraftAdministrativeData', 'filterAdmin')
|
|
961
|
-
.on([
|
|
962
|
-
{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] },
|
|
963
|
-
'=',
|
|
964
|
-
{
|
|
965
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
966
|
-
}
|
|
967
|
-
])
|
|
911
|
+
.on([{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
|
|
968
912
|
.where(_inProcessByUserWhere(req.user.id))
|
|
969
913
|
|
|
970
914
|
const targetName = ensureNoDraftsSuffix(req.target.name)
|
|
971
|
-
|
|
915
|
+
const targetKeys = _getTargetKeys(req)
|
|
916
|
+
for (const key of targetKeys) {
|
|
972
917
|
subSelect.where([{ ref: [targetName, key] }, '=', { ref: [draftName, key] }])
|
|
973
918
|
}
|
|
974
919
|
|
|
@@ -1013,17 +958,18 @@ const _validatedWithSiblingInProcess = (req, draftWhere, draftParameters, column
|
|
|
1013
958
|
_isValidExcludeActiveDraftExists(draftParameters.isActiveEntity, draftParameters.siblingIsActive)
|
|
1014
959
|
)
|
|
1015
960
|
return _excludeActiveDraftExists(req, draftWhere, columns, model)
|
|
961
|
+
|
|
1016
962
|
if (
|
|
1017
963
|
draftInProcessByUser &&
|
|
1018
964
|
draftInProcessByUser.op === '!=' &&
|
|
1019
965
|
_isValidWithDraftLocked(isActiveEntity, siblingIsActive, draftInProcessByUser)
|
|
1020
966
|
) {
|
|
1021
967
|
return _activeWithDraftInProcess(req, draftWhere, columns, req.user.id)
|
|
1022
|
-
} else if (draftInProcessByUser && _isValidWithDraftTimeout(isActiveEntity, siblingIsActive, draftInProcessByUser)) {
|
|
1023
|
-
return _activeWithDraftInProcess(req, draftWhere, columns, null)
|
|
1024
968
|
}
|
|
1025
969
|
|
|
1026
|
-
|
|
970
|
+
if (draftInProcessByUser && _isValidWithDraftTimeout(isActiveEntity, siblingIsActive, draftInProcessByUser)) {
|
|
971
|
+
return _activeWithDraftInProcess(req, draftWhere, columns, null)
|
|
972
|
+
}
|
|
1027
973
|
}
|
|
1028
974
|
|
|
1029
975
|
const _validatedDraftOfWhichIAmOwner = (req, draftWhere, draftParameters, columns) =>
|
|
@@ -1034,6 +980,7 @@ const _draftInSubSelect = (where, req) => {
|
|
|
1034
980
|
if (xpr) {
|
|
1035
981
|
return _draftInSubSelect(xpr, req)
|
|
1036
982
|
}
|
|
983
|
+
|
|
1037
984
|
if (SELECT && SELECT.where) {
|
|
1038
985
|
const isActiveEntity = readAndDeleteKeywords(['IsActiveEntity'], SELECT.where, false)
|
|
1039
986
|
if (isActiveEntity) {
|
|
@@ -1065,9 +1012,9 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1065
1012
|
siblingScenario = _getSiblingScenario(req, columns, model, siblingIndex, nav)
|
|
1066
1013
|
if (siblingIndex === 0) {
|
|
1067
1014
|
return siblingScenario
|
|
1068
|
-
} else {
|
|
1069
|
-
_mergeSiblingIntoCQN(req.query, siblingScenario, siblingIndex - 1)
|
|
1070
1015
|
}
|
|
1016
|
+
|
|
1017
|
+
_mergeSiblingIntoCQN(req.query, siblingScenario, siblingIndex - 1)
|
|
1071
1018
|
}
|
|
1072
1019
|
|
|
1073
1020
|
if (_isDraftAdminScenario(req)) {
|
|
@@ -1075,7 +1022,7 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1075
1022
|
}
|
|
1076
1023
|
|
|
1077
1024
|
if (!req.query.SELECT.where) {
|
|
1078
|
-
return _allActive(req, columns
|
|
1025
|
+
return _allActive(req, columns)
|
|
1079
1026
|
}
|
|
1080
1027
|
|
|
1081
1028
|
// REVISIT this function does not only read, but modifies where!
|
|
@@ -1087,7 +1034,7 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1087
1034
|
!(draftParameters.siblingIsActive && draftParameters.siblingIsActive.value.val === null) &&
|
|
1088
1035
|
!draftParameters.hasDraftEntity
|
|
1089
1036
|
) {
|
|
1090
|
-
return _allActive(req, columns
|
|
1037
|
+
return _allActive(req, columns)
|
|
1091
1038
|
}
|
|
1092
1039
|
|
|
1093
1040
|
if (!draftParameters.isActiveEntity) {
|
|
@@ -1095,7 +1042,8 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1095
1042
|
// this is only the case when navigating into tree
|
|
1096
1043
|
return _allInactive(req, columns)
|
|
1097
1044
|
}
|
|
1098
|
-
|
|
1045
|
+
|
|
1046
|
+
return _allActive(req, columns)
|
|
1099
1047
|
}
|
|
1100
1048
|
|
|
1101
1049
|
if (draftParameters.hasDraftEntity) {
|
|
@@ -1109,14 +1057,10 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1109
1057
|
return _validatedDraftOfWhichIAmOwner(req, req.query.SELECT.where, draftParameters, columns)
|
|
1110
1058
|
}
|
|
1111
1059
|
|
|
1112
|
-
const _getColumns = ({ query: { SELECT }
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
(col.ref && !(col.ref[col.ref.length - 1] in DRAFT_COLUMNS_MAP)) || (!col.ref && !(col in DRAFT_COLUMNS_MAP))
|
|
1117
|
-
)
|
|
1118
|
-
: getColumns(target, { onlyNames: true, removeIgnore: true })
|
|
1119
|
-
}
|
|
1060
|
+
const _getColumns = ({ query: { SELECT } }) =>
|
|
1061
|
+
SELECT.columns.filter(
|
|
1062
|
+
col => (col.ref && !(col.ref[col.ref.length - 1] in DRAFT_COLUMNS_MAP)) || (!col.ref && !(col in DRAFT_COLUMNS_MAP))
|
|
1063
|
+
)
|
|
1120
1064
|
|
|
1121
1065
|
const _isIsActiveEntity = element => element.ref && element.ref[element.ref.length - 1] === 'IsActiveEntity'
|
|
1122
1066
|
|
|
@@ -1170,20 +1114,19 @@ const _adaptDraftColumnsForSiblingEntity = (result, isSiblingActive) => {
|
|
|
1170
1114
|
}
|
|
1171
1115
|
|
|
1172
1116
|
const _collectAliases = (from, aliases) => {
|
|
1173
|
-
if (from)
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
}
|
|
1117
|
+
if (!from) return
|
|
1118
|
+
if (from.ref && from.as) {
|
|
1119
|
+
// Actually table names in where annotations should be provided with '.' separator.
|
|
1120
|
+
// Normalization to '_' is done for the exceptional case if '_' is still used (based on db table names).
|
|
1121
|
+
aliases.set(from.ref[0].replace(/\./g, '_'), from.as)
|
|
1122
|
+
} else if (from.args) {
|
|
1123
|
+
from.args.forEach(arg => {
|
|
1124
|
+
_collectAliases(arg, aliases)
|
|
1125
|
+
})
|
|
1126
|
+
} else if (from.SET && from.SET.args) {
|
|
1127
|
+
from.SET.args.forEach(arg => {
|
|
1128
|
+
_collectAliases(arg, aliases)
|
|
1129
|
+
})
|
|
1187
1130
|
}
|
|
1188
1131
|
}
|
|
1189
1132
|
|
|
@@ -1217,6 +1160,7 @@ const _getLocalizedEntity = (model, target, user) => {
|
|
|
1217
1160
|
if (cds.env.i18n.for_sqlite.includes(user.locale)) {
|
|
1218
1161
|
localizedEntity = model.definitions[`${prefix}.${user.locale}.${target.name}`]
|
|
1219
1162
|
}
|
|
1163
|
+
|
|
1220
1164
|
return localizedEntity || model.definitions[`${prefix}.${target.name}`]
|
|
1221
1165
|
}
|
|
1222
1166
|
|
|
@@ -1241,12 +1185,18 @@ const _getOriginalColumns = req => {
|
|
|
1241
1185
|
for (const c of req.query.SELECT.columns) {
|
|
1242
1186
|
originalColumns[c.ref ? c.ref[c.ref.length - 1] : c.as || c] = true
|
|
1243
1187
|
}
|
|
1188
|
+
|
|
1244
1189
|
return originalColumns
|
|
1245
1190
|
}
|
|
1246
1191
|
|
|
1192
|
+
const _handlerStreaming = (req, query) => {
|
|
1193
|
+
adaptStreamCQN(query)
|
|
1194
|
+
query._streaming = true
|
|
1195
|
+
return cds.tx(req).run(query)
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1247
1198
|
const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
|
|
1248
1199
|
const resultAsArray = Array.isArray(result) ? result : result ? [result] : []
|
|
1249
|
-
|
|
1250
1200
|
if (!result || !resultAsArray.length) return result
|
|
1251
1201
|
|
|
1252
1202
|
if (cqnScenario.scenario === SCENARIO.SIBLING_ENTITY) {
|
|
@@ -1257,11 +1207,11 @@ const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
|
|
|
1257
1207
|
|
|
1258
1208
|
const removeDraftUUIDIfNecessaryFn = removeDraftUUIDIfNecessary(req)
|
|
1259
1209
|
let notRequestedColumns
|
|
1260
|
-
|
|
1261
|
-
if (!req.query.SELECT._4odata && !cds.env.features.auto_fetch_expand_keys) {
|
|
1210
|
+
if (!req.query.SELECT._4odata) {
|
|
1262
1211
|
const originalColumns = _getOriginalColumns(req)
|
|
1263
1212
|
notRequestedColumns = originalColumns && Object.keys(resultAsArray[0]).filter(key => !originalColumns[key])
|
|
1264
1213
|
}
|
|
1214
|
+
|
|
1265
1215
|
if (cqnScenario.scenario === SCENARIO.DRAFT_ADMIN) {
|
|
1266
1216
|
_calculateDraftAdminColumns(resultAsArray[0], req.user.id, deleteLastChangeDateTime)
|
|
1267
1217
|
if (notRequestedColumns) {
|
|
@@ -1280,31 +1230,58 @@ const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
|
|
|
1280
1230
|
return result
|
|
1281
1231
|
}
|
|
1282
1232
|
|
|
1233
|
+
const _fnCompare = elName => c => (c.as && c.as === elName) || (c.ref && c.ref[c.ref.length - 1] === elName)
|
|
1234
|
+
const _adaptColumns4readAfterWrite = (req, cqnScenario, query4sql) => {
|
|
1235
|
+
if (
|
|
1236
|
+
!(req.context.event === 'EDIT' && cqnScenario.scenario === SCENARIO.DRAFT_WHICH_OWNER) &&
|
|
1237
|
+
!(req.context.event === 'draftActivate' && cqnScenario.scenario === SCENARIO.ALL_ACTIVE)
|
|
1238
|
+
)
|
|
1239
|
+
return
|
|
1240
|
+
|
|
1241
|
+
// cleanup columns if not requested with $select or $expand
|
|
1242
|
+
cqnScenario.cqn.SELECT.columns = cqnScenario.cqn.SELECT.columns.reduce((columns, column) => {
|
|
1243
|
+
const elName = column.as || (column.ref && column.ref[column.ref.length - 1])
|
|
1244
|
+
if (query4sql.SELECT.columns.find(_fnCompare(elName)) || elName in req.target.keys) columns.push(column)
|
|
1245
|
+
return columns
|
|
1246
|
+
}, [])
|
|
1247
|
+
|
|
1248
|
+
// add missing keys
|
|
1249
|
+
const isActive = req.context.event === 'draftActivate'
|
|
1250
|
+
// aliasing is fixed by scenarios
|
|
1251
|
+
const alias = isActive ? 'active' : req.target.drafts.name
|
|
1252
|
+
for (const key in req.target.keys) {
|
|
1253
|
+
if (req.target.keys[key].isAssociation) continue
|
|
1254
|
+
if (!cqnScenario.cqn.SELECT.columns.find(_fnCompare(key))) {
|
|
1255
|
+
const column =
|
|
1256
|
+
key === 'IsActiveEntity'
|
|
1257
|
+
? { val: isActive, as: 'IsActiveEntity', cast: { type: 'cds.Boolean' } }
|
|
1258
|
+
: { ref: [alias, key] }
|
|
1259
|
+
cqnScenario.cqn.SELECT.columns.push(column)
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1283
1264
|
/**
|
|
1284
1265
|
* Generic Handler for READ requests in the context of draft.
|
|
1285
1266
|
*
|
|
1286
1267
|
* @param req
|
|
1287
1268
|
*/
|
|
1288
1269
|
const _handler = async function (req) {
|
|
1270
|
+
const query = req.query
|
|
1271
|
+
const originalFrom = _copyCQNPartial(query.SELECT.from)
|
|
1272
|
+
|
|
1289
1273
|
// handle localized here as it was previously handled for req.target
|
|
1290
1274
|
req.target = _getLocalizedEntity(this.model, req.target, req.user) || req.target
|
|
1291
1275
|
|
|
1292
|
-
const originalFrom = _copyCQNPartial(req.query.SELECT.from)
|
|
1293
|
-
|
|
1294
1276
|
// REVISIT DRAFT HANDLING: cqn2cqn4sql must not be called here
|
|
1295
1277
|
const query4sql = cqn2cqn4sql(req.query, this.model, { _4fiori: true })
|
|
1296
1278
|
|
|
1297
|
-
//
|
|
1298
|
-
const reqClone = { __proto__: req, query:
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
reqClone.query._draftRestrictions = req.query._draftRestrictions
|
|
1279
|
+
// Clone the request. Do not clone with Object.assign as that would skip all non-enumerable properties.
|
|
1280
|
+
const reqClone = { __proto__: req, query: query4sql.clone() }
|
|
1281
|
+
// Clone draft restrictions to the cloned query.
|
|
1282
|
+
reqClone.query._draftRestrictions = query._draftRestrictions
|
|
1302
1283
|
|
|
1303
|
-
if (
|
|
1304
|
-
adaptStreamCQN(reqClone.query)
|
|
1305
|
-
reqClone.query._streaming = true
|
|
1306
|
-
return cds.tx(req).run(reqClone.query)
|
|
1307
|
-
}
|
|
1284
|
+
if (query._streaming) return _handlerStreaming(req, reqClone.query)
|
|
1308
1285
|
|
|
1309
1286
|
let cqnScenario
|
|
1310
1287
|
|
|
@@ -1312,16 +1289,15 @@ const _handler = async function (req) {
|
|
|
1312
1289
|
// just to make existing tests working with new parser. not really tested, not needed to be supported
|
|
1313
1290
|
if (reqClone.query.SELECT.from.SELECT) {
|
|
1314
1291
|
const subQueryReq = { __proto__: req, query: _copyCQNPartial(_getLastSubQuery(reqClone.query)) }
|
|
1315
|
-
|
|
1292
|
+
const columns = _getColumns(subQueryReq)
|
|
1293
|
+
cqnScenario = _generateCQN(originalFrom.SELECT.from, subQueryReq, columns, this.model)
|
|
1316
1294
|
cqnScenario.cqn = _setLastSubQuery(reqClone.query, cqnScenario.cqn)
|
|
1317
1295
|
} else {
|
|
1318
|
-
|
|
1296
|
+
const columns = _getColumns(reqClone)
|
|
1297
|
+
cqnScenario = _generateCQN(originalFrom, reqClone, columns, this.model)
|
|
1319
1298
|
}
|
|
1320
1299
|
|
|
1321
|
-
if (!cqnScenario)
|
|
1322
|
-
req.reject(400)
|
|
1323
|
-
return
|
|
1324
|
-
}
|
|
1300
|
+
if (!cqnScenario) req.reject(400)
|
|
1325
1301
|
|
|
1326
1302
|
// ensure base columns for calculation are selected in draft admin expand
|
|
1327
1303
|
_adaptDraftAdminExpand(cqnScenario.cqn)
|
|
@@ -1341,13 +1317,12 @@ const _handler = async function (req) {
|
|
|
1341
1317
|
// unlocalize for db and after handlers as it was before
|
|
1342
1318
|
req.target = this.model.definitions[ensureUnlocalized(req.target.name)]
|
|
1343
1319
|
|
|
1344
|
-
|
|
1320
|
+
_adaptColumns4readAfterWrite(req, cqnScenario, query4sql)
|
|
1345
1321
|
|
|
1322
|
+
const result = await cds.tx(req).send({ query: cqnScenario.cqn, target: req.target })
|
|
1346
1323
|
return _postProcess(result, req, cqnScenario, enhancedWithLastChangeDateTime)
|
|
1347
1324
|
}
|
|
1348
1325
|
|
|
1349
|
-
module.exports = cds.service.impl(function () {
|
|
1350
|
-
|
|
1351
|
-
this.on('READ', entity, _handler)
|
|
1352
|
-
}
|
|
1326
|
+
module.exports = cds.service.impl(function (srv, entity) {
|
|
1327
|
+
srv.on('READ', entity, _handler)
|
|
1353
1328
|
})
|