@sap/cds 5.9.8 → 6.0.3
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 +277 -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 +83 -41
- 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 +21 -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 +15 -13
- package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
- package/bin/mtx/in-cds.js +19 -7
- package/bin/serve.js +49 -22
- package/bin/utils/log.js +13 -30
- package/bin/version.js +4 -3
- 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 +10 -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 +22 -20
- package/lib/serve/index.js +51 -54
- package/lib/utils/axios.js +8 -12
- package/lib/utils/index.js +13 -4
- 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 +127 -41
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +9 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +93 -73
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +25 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +10 -14
- 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 +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +21 -26
- 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 +97 -92
- 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 +82 -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 +13 -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 +2 -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 +4 -16
- package/libx/_runtime/fiori/generic/index.js +31 -0
- package/libx/_runtime/fiori/generic/new.js +5 -21
- package/libx/_runtime/fiori/generic/patch.js +10 -15
- package/libx/_runtime/fiori/generic/prepare.js +13 -22
- package/libx/_runtime/fiori/generic/read.js +148 -163
- package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
- package/libx/_runtime/fiori/utils/handler.js +10 -22
- 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 +30 -22
- 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 +3 -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 +90 -48
- 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 +263 -156
- 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 = (
|
|
@@ -133,6 +120,11 @@ const DRAFT_COLUMNS_CASTED = [
|
|
|
133
120
|
}
|
|
134
121
|
]
|
|
135
122
|
|
|
123
|
+
const DRAFT_COLUMNS_CASTED_WITH_DRAFTADMIN_UUID = [
|
|
124
|
+
...DRAFT_COLUMNS_CASTED,
|
|
125
|
+
{ ref: ['DraftAdministrativeData_DraftUUID'] }
|
|
126
|
+
]
|
|
127
|
+
|
|
136
128
|
// default draft values for active entities
|
|
137
129
|
const _getDefaultDraftProperties = ({ hasDraft, isActive = true, withDraftUUID = true }) => {
|
|
138
130
|
const columns = [
|
|
@@ -162,7 +154,6 @@ const _getDefaultDraftProperties = ({ hasDraft, isActive = true, withDraftUUID =
|
|
|
162
154
|
// draft values for active entities with calculated hasDraft property
|
|
163
155
|
const _getDraftPropertiesDetermineDraft = (req, where, tableName, calcDraftUUID = false) => {
|
|
164
156
|
const { table } = _getTableName(req, true)
|
|
165
|
-
|
|
166
157
|
tableName = tableName || table
|
|
167
158
|
|
|
168
159
|
const hasDraftQuery = SELECT.from(tableName, [{ val: 1 }])
|
|
@@ -209,18 +200,18 @@ function _copyCQNPartial(partial) {
|
|
|
209
200
|
return newPartial
|
|
210
201
|
}
|
|
211
202
|
|
|
212
|
-
|
|
203
|
+
if (partial.ref) {
|
|
204
|
+
return Object.assign({}, partial, { ref: _copyArray(partial.ref) })
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return Object.assign({}, partial)
|
|
213
208
|
}
|
|
214
209
|
|
|
215
210
|
function _copyArray(array) {
|
|
216
|
-
return array.map(entry =>
|
|
217
|
-
return typeof entry === 'object' && !(entry instanceof String) ? _copyCQNPartial(entry) : entry
|
|
218
|
-
})
|
|
211
|
+
return array.map(entry => (typeof entry === 'object' && !(entry instanceof String) ? _copyCQNPartial(entry) : entry))
|
|
219
212
|
}
|
|
220
213
|
|
|
221
|
-
const _isValidDraftOfWhichIAmOwner = isActiveEntity =>
|
|
222
|
-
return isActiveEntity.op === '=' && _isFalse(isActiveEntity.value.val)
|
|
223
|
-
}
|
|
214
|
+
const _isValidDraftOfWhichIAmOwner = isActiveEntity => isActiveEntity.op === '=' && _isFalse(isActiveEntity.value.val)
|
|
224
215
|
|
|
225
216
|
const _isValidActiveWithoutDraft = (isActiveEntity, hasDraftEntity) => {
|
|
226
217
|
return (
|
|
@@ -293,7 +284,7 @@ const _getOuterMostColumns = (columnsFromRequest, additionalDraftColumns) => {
|
|
|
293
284
|
// adds base columns 'InProcessByUser' and 'CreatedByUser' to columns param if needed
|
|
294
285
|
// those are required for calculating 'DraftIsProcessedByMe' and 'DraftIsCreatedByMe'
|
|
295
286
|
const _ensureDraftAdminColumnsForCalculation = columns => {
|
|
296
|
-
columns.forEach(
|
|
287
|
+
columns.forEach(c => {
|
|
297
288
|
if (c.ref && c.ref[0] === 'DraftIsCreatedByMe' && !columns.find(e => e.ref && e.ref[0] === 'CreatedByUser')) {
|
|
298
289
|
columns.push({ ref: ['CreatedByUser'] })
|
|
299
290
|
} else if (
|
|
@@ -337,13 +328,7 @@ const _allInactive = (req, columns) => {
|
|
|
337
328
|
// ensure only own drafts are read
|
|
338
329
|
const cqn = SELECT.from(table)
|
|
339
330
|
.join('DRAFT.DraftAdministrativeData', 'filterAdmin')
|
|
340
|
-
.on([
|
|
341
|
-
{ ref: [table.as, 'DraftAdministrativeData_DraftUUID'] },
|
|
342
|
-
'=',
|
|
343
|
-
{
|
|
344
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
345
|
-
}
|
|
346
|
-
])
|
|
331
|
+
.on([{ ref: [table.as, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
|
|
347
332
|
.where(_inProcessByUserWhere(req.user.id))
|
|
348
333
|
|
|
349
334
|
if (isCount) {
|
|
@@ -353,7 +338,6 @@ const _allInactive = (req, columns) => {
|
|
|
353
338
|
}
|
|
354
339
|
|
|
355
340
|
cqn.where(req.query.SELECT.where)
|
|
356
|
-
|
|
357
341
|
return { cqn: getEnrichedCQN(cqn, req.query.SELECT, []), scenario: SCENARIO.ALL_INACTIVE }
|
|
358
342
|
}
|
|
359
343
|
|
|
@@ -377,22 +361,7 @@ const _buildWhere = (where, table) => {
|
|
|
377
361
|
}
|
|
378
362
|
}
|
|
379
363
|
|
|
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) => {
|
|
364
|
+
const _allActive = (req, columns) => {
|
|
396
365
|
const { table } = _getTableName(req)
|
|
397
366
|
if (!table.as) {
|
|
398
367
|
table.as = 'active'
|
|
@@ -405,7 +374,6 @@ const _allActive = (req, columns, model) => {
|
|
|
405
374
|
|
|
406
375
|
const ids = filterKeys(req.target.keys)
|
|
407
376
|
const isCount = columns.some(element => element.func === 'count')
|
|
408
|
-
|
|
409
377
|
const xpr = {
|
|
410
378
|
xpr: [
|
|
411
379
|
'case',
|
|
@@ -437,15 +405,12 @@ const _allActive = (req, columns, model) => {
|
|
|
437
405
|
}
|
|
438
406
|
|
|
439
407
|
const scenarioAlias = 'active'
|
|
440
|
-
|
|
441
|
-
req.query.SELECT.where = _getWhereWithAppendedDraftRestrictions(req.query.SELECT.where, req, scenarioAlias, model)
|
|
408
|
+
req.query.SELECT.where = _getWhereWithAppendedDraftRestrictions(req.query.SELECT.where, req)
|
|
442
409
|
|
|
443
410
|
if (req.query.SELECT.where) {
|
|
444
411
|
_buildWhere(req.query.SELECT.where, table)
|
|
445
412
|
}
|
|
446
413
|
|
|
447
|
-
_buildOrderBy(req.query, cqn.SELECT.columns, table)
|
|
448
|
-
|
|
449
414
|
return {
|
|
450
415
|
cqn: getEnrichedCQN(cqn, req.query.SELECT, req.query.SELECT.where, scenarioAlias),
|
|
451
416
|
scenario: SCENARIO.ALL_ACTIVE
|
|
@@ -472,31 +437,25 @@ const _activeWithoutDraft = (req, draftWhere, columns) => {
|
|
|
472
437
|
)
|
|
473
438
|
|
|
474
439
|
const outerMostColumns = _getOuterMostColumns(columns, _getDefaultDraftProperties({ hasDraft: false }))
|
|
475
|
-
|
|
476
440
|
const cqn = SELECT.from(active.table)
|
|
477
441
|
.columns(...outerMostColumns)
|
|
478
442
|
.where(['not exists', subSelect])
|
|
479
443
|
|
|
480
444
|
draftWhere = _getWhereWithAppendedDraftRestrictions(draftWhere, req)
|
|
481
|
-
|
|
482
445
|
return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.ACTIVE_WITHOUT_DRAFT }
|
|
483
446
|
}
|
|
484
447
|
|
|
485
448
|
const _draftOfWhichIAmOwner = (req, draftWhere, columns) => {
|
|
486
449
|
const { table, name } = _getTableName(req, true)
|
|
487
|
-
|
|
488
|
-
|
|
450
|
+
const outerMostColumns = _getOuterMostColumns(
|
|
451
|
+
addColumnAlias(columns, name),
|
|
452
|
+
DRAFT_COLUMNS_CASTED_WITH_DRAFTADMIN_UUID
|
|
453
|
+
)
|
|
489
454
|
|
|
490
455
|
const cqn = SELECT.from(table)
|
|
491
456
|
.columns(...outerMostColumns)
|
|
492
457
|
.join('DRAFT.DraftAdministrativeData', 'filterAdmin')
|
|
493
|
-
.on([
|
|
494
|
-
{ ref: [name, 'DraftAdministrativeData_DraftUUID'] },
|
|
495
|
-
'=',
|
|
496
|
-
{
|
|
497
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
498
|
-
}
|
|
499
|
-
])
|
|
458
|
+
.on([{ ref: [name, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
|
|
500
459
|
.where(_inProcessByUserWhere(req.user.id))
|
|
501
460
|
|
|
502
461
|
return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.DRAFT_WHICH_OWNER }
|
|
@@ -512,13 +471,7 @@ const _activeWithDraftInProcess = (req, draftWhere, columns, isLocked) => {
|
|
|
512
471
|
let subSelect = SELECT.from(draftName)
|
|
513
472
|
.columns(...keys)
|
|
514
473
|
.join('DRAFT.DraftAdministrativeData', 'filterAdmin')
|
|
515
|
-
.on([
|
|
516
|
-
{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] },
|
|
517
|
-
'=',
|
|
518
|
-
{
|
|
519
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
520
|
-
}
|
|
521
|
-
])
|
|
474
|
+
.on([{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
|
|
522
475
|
|
|
523
476
|
const DRAFT_CANCEL_TIMEOUT_IN_SEC = ((cds.env.drafts && cds.env.drafts.cancellationTimeout) || 15) * 60
|
|
524
477
|
|
|
@@ -530,25 +483,20 @@ const _activeWithDraftInProcess = (req, draftWhere, columns, isLocked) => {
|
|
|
530
483
|
{ ref: ['filterAdmin', 'InProcessByUser'] },
|
|
531
484
|
'is not null',
|
|
532
485
|
'and',
|
|
533
|
-
{
|
|
534
|
-
func: 'seconds_between',
|
|
535
|
-
args: [{ ref: ['filterAdmin', 'LastChangeDateTime'] }, 'CURRENT_TIMESTAMP']
|
|
536
|
-
},
|
|
486
|
+
{ func: 'seconds_between', args: [{ ref: ['filterAdmin', 'LastChangeDateTime'] }, 'CURRENT_TIMESTAMP'] },
|
|
537
487
|
isLocked ? '<' : '>',
|
|
538
488
|
{ val: DRAFT_CANCEL_TIMEOUT_IN_SEC }
|
|
539
489
|
])
|
|
540
490
|
|
|
541
491
|
subSelect = keys.reduce(
|
|
542
|
-
(
|
|
492
|
+
(_select, key) => subSelect.where([{ ref: [active.name, key] }, '=', { ref: [draftName, key] }]),
|
|
543
493
|
subSelect
|
|
544
494
|
)
|
|
545
495
|
|
|
546
496
|
const outerMostColumns = _getOuterMostColumns(columns, draftColumns)
|
|
547
|
-
|
|
548
497
|
const cqn = SELECT.from(active.table).columns(outerMostColumns)
|
|
549
498
|
cqn.where(_getWhereWithAppendedDraftRestrictions([], req))
|
|
550
499
|
cqn.where(['exists', subSelect])
|
|
551
|
-
|
|
552
500
|
return { cqn: getEnrichedCQN(cqn, req.query.SELECT, draftWhere), scenario: SCENARIO.DRAFT_IN_PROCESS }
|
|
553
501
|
}
|
|
554
502
|
|
|
@@ -572,10 +520,12 @@ const _joinFromWhere = (where, parentAlias, targetAlias) => {
|
|
|
572
520
|
return where.reduce((links, el, idx, where) => {
|
|
573
521
|
if (el.xpr) {
|
|
574
522
|
const result = _joinFromWhere(el.xpr, parentAlias, targetAlias)
|
|
523
|
+
|
|
575
524
|
if (result.length) {
|
|
576
525
|
if (links.length) links.push('and')
|
|
577
526
|
links.push(...result)
|
|
578
527
|
}
|
|
528
|
+
|
|
579
529
|
return links
|
|
580
530
|
}
|
|
581
531
|
|
|
@@ -584,11 +534,13 @@ const _joinFromWhere = (where, parentAlias, targetAlias) => {
|
|
|
584
534
|
if (links.length) links.push('and')
|
|
585
535
|
links.push(el, '=', where[idx - 2])
|
|
586
536
|
}
|
|
537
|
+
|
|
587
538
|
if (where[idx + 1] && where[idx + 1] === '=' && isTargetRef(where[idx + 2], targetAlias)) {
|
|
588
539
|
if (links.length) links.push('and')
|
|
589
540
|
links.push(el, '=', where[idx + 2])
|
|
590
541
|
}
|
|
591
542
|
}
|
|
543
|
+
|
|
592
544
|
return links
|
|
593
545
|
}, [])
|
|
594
546
|
}
|
|
@@ -609,6 +561,7 @@ const _functionContainsDraftField = obj =>
|
|
|
609
561
|
})
|
|
610
562
|
|
|
611
563
|
const _isLogicalFunction = (where, index) => {
|
|
564
|
+
// REVISIT
|
|
612
565
|
const borders = ['(', ')', 'and', 'or', undefined]
|
|
613
566
|
|
|
614
567
|
return borders.includes(where[index - 1]) && borders.includes(where[index + 1])
|
|
@@ -621,6 +574,7 @@ const _getWhereForActive = where => {
|
|
|
621
574
|
activeWhere.push({ xpr: _getWhereForActive(where[i].xpr) })
|
|
622
575
|
continue
|
|
623
576
|
}
|
|
577
|
+
|
|
624
578
|
if (_isDraftField(where[i])) {
|
|
625
579
|
activeWhere.push({ val: null })
|
|
626
580
|
} else if (_functionContainsDraftField(where[i])) {
|
|
@@ -666,9 +620,10 @@ const _siblingEntity = (
|
|
|
666
620
|
const subScenario = _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, model, onCond, req)
|
|
667
621
|
const isSiblingDraft = subScenario
|
|
668
622
|
? subScenario.isSiblingActive || subScenario.scenario === 'ACTIVE' || subScenario.scenario === 'ALL_ACTIVE'
|
|
669
|
-
: keys.IsActiveEntity && keys.IsActiveEntity !==
|
|
623
|
+
: keys.IsActiveEntity && keys.IsActiveEntity !== false
|
|
670
624
|
const { table } = _getTableName({ query, target }, isSiblingDraft)
|
|
671
625
|
const cqn = SELECT.from(table)
|
|
626
|
+
|
|
672
627
|
if (siblingIndex === 0) {
|
|
673
628
|
const columnCqnPartial = columns.map(col => {
|
|
674
629
|
const colName = col.ref ? col.ref[col.ref.length - 1] : col
|
|
@@ -698,14 +653,16 @@ const _siblingEntity = (
|
|
|
698
653
|
for (const key in keys) {
|
|
699
654
|
if (key !== 'IsActiveEntity') cqn.where([{ ref: [table.as, key] }, '=', { val: keys[key] }])
|
|
700
655
|
}
|
|
656
|
+
|
|
701
657
|
if (subScenario) {
|
|
702
658
|
cqn.where(['exists', subScenario.cqn])
|
|
703
659
|
}
|
|
660
|
+
|
|
704
661
|
// in DraftAdminData scenario parent is linked via join
|
|
705
662
|
if (draftAdminAlias) {
|
|
706
663
|
cqn.where([{ ref: [draftAdminAlias, 'DraftUUID'] }, '=', { ref: ['draftAdmin', 'DraftUUID'] }])
|
|
707
664
|
} else if (parentLinks.length) {
|
|
708
|
-
cqn.where(
|
|
665
|
+
cqn.where({ xpr: [...parentLinks] })
|
|
709
666
|
}
|
|
710
667
|
|
|
711
668
|
return { cqn, scenario: SCENARIO.SIBLING_ENTITY, isSiblingActive: !isSiblingDraft }
|
|
@@ -722,6 +679,7 @@ function _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, mo
|
|
|
722
679
|
params: [...params].reverse(),
|
|
723
680
|
user: req.user
|
|
724
681
|
}
|
|
682
|
+
|
|
725
683
|
if (subSiblingIndex > -1) {
|
|
726
684
|
subScenario = _getSiblingScenario(subReq, [{ val: 1 }], model, subSiblingIndex, subNav, params)
|
|
727
685
|
if (subSiblingIndex > 0) {
|
|
@@ -732,12 +690,14 @@ function _siblingSubScenario(nav, siblingIndex, siblingQuery, target, params, mo
|
|
|
732
690
|
}
|
|
733
691
|
} else {
|
|
734
692
|
subReq.query = SELECT.from(siblingQuery.SELECT.from).columns([{ val: 1 }])
|
|
693
|
+
|
|
735
694
|
const existsIdx = siblingQuery.SELECT.where.indexOf('exists')
|
|
736
695
|
if (existsIdx > -1) subReq.query.where(siblingQuery.SELECT.where.slice(existsIdx, existsIdx + 2))
|
|
737
696
|
const subOrigFrom = { ref: [...subNav].reverse() }
|
|
738
697
|
subScenario = _generateCQN(subOrigFrom, subReq, [{ val: 1 }], model)
|
|
739
698
|
subScenario.cqn.where(onCond)
|
|
740
699
|
}
|
|
700
|
+
|
|
741
701
|
return subScenario
|
|
742
702
|
}
|
|
743
703
|
|
|
@@ -753,6 +713,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
|
|
|
753
713
|
queryIndex - 1,
|
|
754
714
|
query
|
|
755
715
|
)
|
|
716
|
+
|
|
756
717
|
if (sibilingQueryFromWhere) return sibilingQueryFromWhere
|
|
757
718
|
}
|
|
758
719
|
|
|
@@ -761,6 +722,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
|
|
|
761
722
|
}
|
|
762
723
|
}
|
|
763
724
|
}
|
|
725
|
+
|
|
764
726
|
const target = { name: query.SELECT.from.ref[0].id || query.SELECT.from.ref[0], as: query.SELECT.from.as }
|
|
765
727
|
return _siblingEntity(
|
|
766
728
|
{ query, target, params, nav },
|
|
@@ -772,6 +734,7 @@ const _getSiblingScenario = (req, columns, model, siblingIndex, nav) => {
|
|
|
772
734
|
req
|
|
773
735
|
)
|
|
774
736
|
}
|
|
737
|
+
|
|
775
738
|
return _getSiblingQueryFromWhere(req.query, siblingIndex)
|
|
776
739
|
}
|
|
777
740
|
|
|
@@ -807,9 +770,7 @@ const _getDraftDoc = (req, draftName, draftWhere) => {
|
|
|
807
770
|
.on([
|
|
808
771
|
{ ref: [req.query.SELECT.from.as || draftName, 'DraftAdministrativeData_DraftUUID'] },
|
|
809
772
|
'=',
|
|
810
|
-
{
|
|
811
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
812
|
-
}
|
|
773
|
+
{ ref: ['filterAdmin', 'DraftUUID'] }
|
|
813
774
|
])
|
|
814
775
|
.where(_inProcessByUserWhere(req.user.id)),
|
|
815
776
|
req.query.SELECT,
|
|
@@ -835,6 +796,7 @@ const _getOrderByEnrichedColumns = (orderBy, columns, entity) => {
|
|
|
835
796
|
}
|
|
836
797
|
}
|
|
837
798
|
}
|
|
799
|
+
|
|
838
800
|
return enrichedCol
|
|
839
801
|
}
|
|
840
802
|
|
|
@@ -911,28 +873,24 @@ const _getUnionCQN = (req, draftName, columns, subSelect, draftWhere, model, ent
|
|
|
911
873
|
draftDocs.columns(draftColumns)
|
|
912
874
|
|
|
913
875
|
const activeName = activeDocs.SELECT.from.as || (activeDocs.SELECT.from.ref && activeDocs.SELECT.from.ref[0])
|
|
914
|
-
|
|
915
876
|
const hasDraftWhere = []
|
|
916
|
-
|
|
877
|
+
const targetKeys = _getTargetKeys(req)
|
|
878
|
+
for (const key of targetKeys) {
|
|
917
879
|
// add 'and' token if not the first iteration
|
|
918
880
|
if (hasDraftWhere.length) hasDraftWhere.push('and')
|
|
919
881
|
hasDraftWhere.push({ ref: [activeName, key] }, '=', { ref: [draftName, key] })
|
|
920
882
|
}
|
|
921
883
|
|
|
922
|
-
const
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
)
|
|
929
|
-
]
|
|
884
|
+
const draftColumnsBySelected = _filterDraftColumnsBySelected(
|
|
885
|
+
_getDraftPropertiesDetermineDraft(req, hasDraftWhere, ensureDraftsSuffix(req.target.name), true),
|
|
886
|
+
req.query.SELECT.columns
|
|
887
|
+
)
|
|
888
|
+
|
|
889
|
+
const activeColumns = [...columns, ...enrichedColumns, ...draftColumnsBySelected]
|
|
930
890
|
activeDocs.columns(activeColumns)
|
|
931
891
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
_alignAliasForUnion(ensureNoDraftsSuffix(req.target.name), req.query.SELECT.from.as, subSelect)
|
|
935
|
-
])
|
|
892
|
+
const aliasForUnion = _alignAliasForUnion(ensureNoDraftsSuffix(req.target.name), req.query.SELECT.from.as, subSelect)
|
|
893
|
+
activeDocs.where(['not exists', aliasForUnion])
|
|
936
894
|
|
|
937
895
|
// groupBy, orderBy and limit do not support partial CQNs
|
|
938
896
|
if (req.query.SELECT.groupBy) {
|
|
@@ -958,17 +916,12 @@ const _excludeActiveDraftExists = (req, draftWhere, columns, model) => {
|
|
|
958
916
|
|
|
959
917
|
const subSelect = SELECT.from(draftName, [1])
|
|
960
918
|
.join('DRAFT.DraftAdministrativeData', 'filterAdmin')
|
|
961
|
-
.on([
|
|
962
|
-
{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] },
|
|
963
|
-
'=',
|
|
964
|
-
{
|
|
965
|
-
ref: ['filterAdmin', 'DraftUUID']
|
|
966
|
-
}
|
|
967
|
-
])
|
|
919
|
+
.on([{ ref: [draftName, 'DraftAdministrativeData_DraftUUID'] }, '=', { ref: ['filterAdmin', 'DraftUUID'] }])
|
|
968
920
|
.where(_inProcessByUserWhere(req.user.id))
|
|
969
921
|
|
|
970
922
|
const targetName = ensureNoDraftsSuffix(req.target.name)
|
|
971
|
-
|
|
923
|
+
const targetKeys = _getTargetKeys(req)
|
|
924
|
+
for (const key of targetKeys) {
|
|
972
925
|
subSelect.where([{ ref: [targetName, key] }, '=', { ref: [draftName, key] }])
|
|
973
926
|
}
|
|
974
927
|
|
|
@@ -1013,17 +966,18 @@ const _validatedWithSiblingInProcess = (req, draftWhere, draftParameters, column
|
|
|
1013
966
|
_isValidExcludeActiveDraftExists(draftParameters.isActiveEntity, draftParameters.siblingIsActive)
|
|
1014
967
|
)
|
|
1015
968
|
return _excludeActiveDraftExists(req, draftWhere, columns, model)
|
|
969
|
+
|
|
1016
970
|
if (
|
|
1017
971
|
draftInProcessByUser &&
|
|
1018
972
|
draftInProcessByUser.op === '!=' &&
|
|
1019
973
|
_isValidWithDraftLocked(isActiveEntity, siblingIsActive, draftInProcessByUser)
|
|
1020
974
|
) {
|
|
1021
975
|
return _activeWithDraftInProcess(req, draftWhere, columns, req.user.id)
|
|
1022
|
-
} else if (draftInProcessByUser && _isValidWithDraftTimeout(isActiveEntity, siblingIsActive, draftInProcessByUser)) {
|
|
1023
|
-
return _activeWithDraftInProcess(req, draftWhere, columns, null)
|
|
1024
976
|
}
|
|
1025
977
|
|
|
1026
|
-
|
|
978
|
+
if (draftInProcessByUser && _isValidWithDraftTimeout(isActiveEntity, siblingIsActive, draftInProcessByUser)) {
|
|
979
|
+
return _activeWithDraftInProcess(req, draftWhere, columns, null)
|
|
980
|
+
}
|
|
1027
981
|
}
|
|
1028
982
|
|
|
1029
983
|
const _validatedDraftOfWhichIAmOwner = (req, draftWhere, draftParameters, columns) =>
|
|
@@ -1034,6 +988,7 @@ const _draftInSubSelect = (where, req) => {
|
|
|
1034
988
|
if (xpr) {
|
|
1035
989
|
return _draftInSubSelect(xpr, req)
|
|
1036
990
|
}
|
|
991
|
+
|
|
1037
992
|
if (SELECT && SELECT.where) {
|
|
1038
993
|
const isActiveEntity = readAndDeleteKeywords(['IsActiveEntity'], SELECT.where, false)
|
|
1039
994
|
if (isActiveEntity) {
|
|
@@ -1065,9 +1020,9 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1065
1020
|
siblingScenario = _getSiblingScenario(req, columns, model, siblingIndex, nav)
|
|
1066
1021
|
if (siblingIndex === 0) {
|
|
1067
1022
|
return siblingScenario
|
|
1068
|
-
} else {
|
|
1069
|
-
_mergeSiblingIntoCQN(req.query, siblingScenario, siblingIndex - 1)
|
|
1070
1023
|
}
|
|
1024
|
+
|
|
1025
|
+
_mergeSiblingIntoCQN(req.query, siblingScenario, siblingIndex - 1)
|
|
1071
1026
|
}
|
|
1072
1027
|
|
|
1073
1028
|
if (_isDraftAdminScenario(req)) {
|
|
@@ -1075,7 +1030,7 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1075
1030
|
}
|
|
1076
1031
|
|
|
1077
1032
|
if (!req.query.SELECT.where) {
|
|
1078
|
-
return _allActive(req, columns
|
|
1033
|
+
return _allActive(req, columns)
|
|
1079
1034
|
}
|
|
1080
1035
|
|
|
1081
1036
|
// REVISIT this function does not only read, but modifies where!
|
|
@@ -1087,7 +1042,7 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1087
1042
|
!(draftParameters.siblingIsActive && draftParameters.siblingIsActive.value.val === null) &&
|
|
1088
1043
|
!draftParameters.hasDraftEntity
|
|
1089
1044
|
) {
|
|
1090
|
-
return _allActive(req, columns
|
|
1045
|
+
return _allActive(req, columns)
|
|
1091
1046
|
}
|
|
1092
1047
|
|
|
1093
1048
|
if (!draftParameters.isActiveEntity) {
|
|
@@ -1095,7 +1050,8 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1095
1050
|
// this is only the case when navigating into tree
|
|
1096
1051
|
return _allInactive(req, columns)
|
|
1097
1052
|
}
|
|
1098
|
-
|
|
1053
|
+
|
|
1054
|
+
return _allActive(req, columns)
|
|
1099
1055
|
}
|
|
1100
1056
|
|
|
1101
1057
|
if (draftParameters.hasDraftEntity) {
|
|
@@ -1109,14 +1065,10 @@ const _generateCQN = (originalFrom, req, columns, model) => {
|
|
|
1109
1065
|
return _validatedDraftOfWhichIAmOwner(req, req.query.SELECT.where, draftParameters, columns)
|
|
1110
1066
|
}
|
|
1111
1067
|
|
|
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
|
-
}
|
|
1068
|
+
const _getColumns = ({ query: { SELECT } }) =>
|
|
1069
|
+
SELECT.columns.filter(
|
|
1070
|
+
col => (col.ref && !(col.ref[col.ref.length - 1] in DRAFT_COLUMNS_MAP)) || (!col.ref && !(col in DRAFT_COLUMNS_MAP))
|
|
1071
|
+
)
|
|
1120
1072
|
|
|
1121
1073
|
const _isIsActiveEntity = element => element.ref && element.ref[element.ref.length - 1] === 'IsActiveEntity'
|
|
1122
1074
|
|
|
@@ -1170,20 +1122,19 @@ const _adaptDraftColumnsForSiblingEntity = (result, isSiblingActive) => {
|
|
|
1170
1122
|
}
|
|
1171
1123
|
|
|
1172
1124
|
const _collectAliases = (from, aliases) => {
|
|
1173
|
-
if (from)
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
}
|
|
1125
|
+
if (!from) return
|
|
1126
|
+
if (from.ref && from.as) {
|
|
1127
|
+
// Actually table names in where annotations should be provided with '.' separator.
|
|
1128
|
+
// Normalization to '_' is done for the exceptional case if '_' is still used (based on db table names).
|
|
1129
|
+
aliases.set(from.ref[0].replace(/\./g, '_'), from.as)
|
|
1130
|
+
} else if (from.args) {
|
|
1131
|
+
from.args.forEach(arg => {
|
|
1132
|
+
_collectAliases(arg, aliases)
|
|
1133
|
+
})
|
|
1134
|
+
} else if (from.SET && from.SET.args) {
|
|
1135
|
+
from.SET.args.forEach(arg => {
|
|
1136
|
+
_collectAliases(arg, aliases)
|
|
1137
|
+
})
|
|
1187
1138
|
}
|
|
1188
1139
|
}
|
|
1189
1140
|
|
|
@@ -1217,6 +1168,7 @@ const _getLocalizedEntity = (model, target, user) => {
|
|
|
1217
1168
|
if (cds.env.i18n.for_sqlite.includes(user.locale)) {
|
|
1218
1169
|
localizedEntity = model.definitions[`${prefix}.${user.locale}.${target.name}`]
|
|
1219
1170
|
}
|
|
1171
|
+
|
|
1220
1172
|
return localizedEntity || model.definitions[`${prefix}.${target.name}`]
|
|
1221
1173
|
}
|
|
1222
1174
|
|
|
@@ -1241,12 +1193,18 @@ const _getOriginalColumns = req => {
|
|
|
1241
1193
|
for (const c of req.query.SELECT.columns) {
|
|
1242
1194
|
originalColumns[c.ref ? c.ref[c.ref.length - 1] : c.as || c] = true
|
|
1243
1195
|
}
|
|
1196
|
+
|
|
1244
1197
|
return originalColumns
|
|
1245
1198
|
}
|
|
1246
1199
|
|
|
1200
|
+
const _handlerStreaming = (req, query) => {
|
|
1201
|
+
adaptStreamCQN(query)
|
|
1202
|
+
query._streaming = true
|
|
1203
|
+
return cds.tx(req).run(query)
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1247
1206
|
const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
|
|
1248
1207
|
const resultAsArray = Array.isArray(result) ? result : result ? [result] : []
|
|
1249
|
-
|
|
1250
1208
|
if (!result || !resultAsArray.length) return result
|
|
1251
1209
|
|
|
1252
1210
|
if (cqnScenario.scenario === SCENARIO.SIBLING_ENTITY) {
|
|
@@ -1257,11 +1215,11 @@ const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
|
|
|
1257
1215
|
|
|
1258
1216
|
const removeDraftUUIDIfNecessaryFn = removeDraftUUIDIfNecessary(req)
|
|
1259
1217
|
let notRequestedColumns
|
|
1260
|
-
|
|
1261
|
-
if (!req.query.SELECT._4odata && !cds.env.features.auto_fetch_expand_keys) {
|
|
1218
|
+
if (!req.query.SELECT._4odata) {
|
|
1262
1219
|
const originalColumns = _getOriginalColumns(req)
|
|
1263
1220
|
notRequestedColumns = originalColumns && Object.keys(resultAsArray[0]).filter(key => !originalColumns[key])
|
|
1264
1221
|
}
|
|
1222
|
+
|
|
1265
1223
|
if (cqnScenario.scenario === SCENARIO.DRAFT_ADMIN) {
|
|
1266
1224
|
_calculateDraftAdminColumns(resultAsArray[0], req.user.id, deleteLastChangeDateTime)
|
|
1267
1225
|
if (notRequestedColumns) {
|
|
@@ -1280,31 +1238,60 @@ const _postProcess = (result, req, cqnScenario, deleteLastChangeDateTime) => {
|
|
|
1280
1238
|
return result
|
|
1281
1239
|
}
|
|
1282
1240
|
|
|
1241
|
+
const _fnCompare = elName => c => (c.as && c.as === elName) || (c.ref && c.ref[c.ref.length - 1] === elName)
|
|
1242
|
+
const _adaptColumns4readAfterWrite = (req, cqnScenario, query4sql) => {
|
|
1243
|
+
if (
|
|
1244
|
+
!(req.context.event === 'EDIT' && cqnScenario.scenario === SCENARIO.DRAFT_WHICH_OWNER) &&
|
|
1245
|
+
!(req.context.event === 'draftActivate' && cqnScenario.scenario === SCENARIO.ALL_ACTIVE)
|
|
1246
|
+
)
|
|
1247
|
+
return
|
|
1248
|
+
|
|
1249
|
+
// cleanup columns if not requested with $select or $expand
|
|
1250
|
+
cqnScenario.cqn.SELECT.columns = cqnScenario.cqn.SELECT.columns.reduce((columns, column) => {
|
|
1251
|
+
const elName = column.as || (column.ref && column.ref[column.ref.length - 1])
|
|
1252
|
+
if (query4sql.SELECT.columns.find(_fnCompare(elName)) || elName in req.target.keys) columns.push(column)
|
|
1253
|
+
return columns
|
|
1254
|
+
}, [])
|
|
1255
|
+
|
|
1256
|
+
// add missing keys
|
|
1257
|
+
const isActive = req.context.event === 'draftActivate'
|
|
1258
|
+
// aliasing is fixed by scenarios
|
|
1259
|
+
const alias = isActive ? 'active' : req.target.drafts.name
|
|
1260
|
+
for (const key in req.target.keys) {
|
|
1261
|
+
if (req.target.keys[key].isAssociation) continue
|
|
1262
|
+
if (!cqnScenario.cqn.SELECT.columns.find(_fnCompare(key))) {
|
|
1263
|
+
const column =
|
|
1264
|
+
key === 'IsActiveEntity'
|
|
1265
|
+
? { val: isActive, as: 'IsActiveEntity', cast: { type: 'cds.Boolean' } }
|
|
1266
|
+
: { ref: [alias, key] }
|
|
1267
|
+
cqnScenario.cqn.SELECT.columns.push(column)
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1283
1272
|
/**
|
|
1284
1273
|
* Generic Handler for READ requests in the context of draft.
|
|
1285
1274
|
*
|
|
1286
1275
|
* @param req
|
|
1287
1276
|
*/
|
|
1288
1277
|
const _handler = async function (req) {
|
|
1278
|
+
const query = req.query
|
|
1279
|
+
const originalFrom = _copyCQNPartial(query.SELECT.from)
|
|
1280
|
+
|
|
1289
1281
|
// handle localized here as it was previously handled for req.target
|
|
1290
1282
|
req.target = _getLocalizedEntity(this.model, req.target, req.user) || req.target
|
|
1291
1283
|
|
|
1292
|
-
const originalFrom = _copyCQNPartial(req.query.SELECT.from)
|
|
1293
|
-
|
|
1294
1284
|
// REVISIT DRAFT HANDLING: cqn2cqn4sql must not be called here
|
|
1295
1285
|
const query4sql = cqn2cqn4sql(req.query, this.model, { _4fiori: true })
|
|
1296
1286
|
|
|
1297
|
-
//
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1287
|
+
// Clone the request. Do not clone with Object.assign as that would skip all non-enumerable properties.
|
|
1288
|
+
// REVISIT: query4sql.clone() doesn't really clone the original query, hence _generateCQN will heavily modify
|
|
1289
|
+
// it, e.g. IsActiveEntity is stripped. This is a problem for subsequent handlers which rely on this information.
|
|
1290
|
+
const reqClone = { __proto__: req, query: query4sql.clone() }
|
|
1291
|
+
// Clone draft restrictions to the cloned query.
|
|
1292
|
+
reqClone.query._draftRestrictions = query._draftRestrictions
|
|
1302
1293
|
|
|
1303
|
-
if (
|
|
1304
|
-
adaptStreamCQN(reqClone.query)
|
|
1305
|
-
reqClone.query._streaming = true
|
|
1306
|
-
return cds.tx(req).run(reqClone.query)
|
|
1307
|
-
}
|
|
1294
|
+
if (query._streaming) return _handlerStreaming(req, reqClone.query)
|
|
1308
1295
|
|
|
1309
1296
|
let cqnScenario
|
|
1310
1297
|
|
|
@@ -1312,16 +1299,15 @@ const _handler = async function (req) {
|
|
|
1312
1299
|
// just to make existing tests working with new parser. not really tested, not needed to be supported
|
|
1313
1300
|
if (reqClone.query.SELECT.from.SELECT) {
|
|
1314
1301
|
const subQueryReq = { __proto__: req, query: _copyCQNPartial(_getLastSubQuery(reqClone.query)) }
|
|
1315
|
-
|
|
1302
|
+
const columns = _getColumns(subQueryReq)
|
|
1303
|
+
cqnScenario = _generateCQN(originalFrom.SELECT.from, subQueryReq, columns, this.model)
|
|
1316
1304
|
cqnScenario.cqn = _setLastSubQuery(reqClone.query, cqnScenario.cqn)
|
|
1317
1305
|
} else {
|
|
1318
|
-
|
|
1306
|
+
const columns = _getColumns(reqClone)
|
|
1307
|
+
cqnScenario = _generateCQN(originalFrom, reqClone, columns, this.model)
|
|
1319
1308
|
}
|
|
1320
1309
|
|
|
1321
|
-
if (!cqnScenario)
|
|
1322
|
-
req.reject(400)
|
|
1323
|
-
return
|
|
1324
|
-
}
|
|
1310
|
+
if (!cqnScenario) req.reject(400)
|
|
1325
1311
|
|
|
1326
1312
|
// ensure base columns for calculation are selected in draft admin expand
|
|
1327
1313
|
_adaptDraftAdminExpand(cqnScenario.cqn)
|
|
@@ -1341,13 +1327,12 @@ const _handler = async function (req) {
|
|
|
1341
1327
|
// unlocalize for db and after handlers as it was before
|
|
1342
1328
|
req.target = this.model.definitions[ensureUnlocalized(req.target.name)]
|
|
1343
1329
|
|
|
1344
|
-
|
|
1330
|
+
_adaptColumns4readAfterWrite(req, cqnScenario, query4sql)
|
|
1345
1331
|
|
|
1332
|
+
const result = await cds.tx(req).send({ query: cqnScenario.cqn, target: req.target })
|
|
1346
1333
|
return _postProcess(result, req, cqnScenario, enhancedWithLastChangeDateTime)
|
|
1347
1334
|
}
|
|
1348
1335
|
|
|
1349
|
-
module.exports = cds.service.impl(function () {
|
|
1350
|
-
|
|
1351
|
-
this.on('READ', entity, _handler)
|
|
1352
|
-
}
|
|
1336
|
+
module.exports = cds.service.impl(function (srv, entity) {
|
|
1337
|
+
srv.on('READ', entity, _handler)
|
|
1353
1338
|
})
|