@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
|
@@ -1,31 +1,87 @@
|
|
|
1
1
|
const cds = require('../../../../cds')
|
|
2
|
-
const {
|
|
2
|
+
const {
|
|
3
|
+
Request,
|
|
4
|
+
ql: { SELECT }
|
|
5
|
+
} = cds
|
|
6
|
+
const LOG = cds.log()
|
|
7
|
+
const { normalizeError } = require('../../../../common/error/frontend')
|
|
3
8
|
|
|
4
|
-
const { getDeepSelect } = require('
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
9
|
+
const { getDeepSelect, getSimpleSelectCQN } = require('./handlerUtils')
|
|
10
|
+
const { hasDeepUpdate } = require('../../../../common/composition/update')
|
|
11
|
+
const { WRITE_EVENTS, CDS_EVENTS, DRAFT_MOD_EVENTS } = require('../../../../common/constants/events')
|
|
7
12
|
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
const setLocationHeader = (req, { model }) => {
|
|
14
|
+
const { odataRes } = req._
|
|
15
|
+
const cqn = getSimpleSelectCQN(req.target, req.data)
|
|
16
|
+
const { path: location } = cds.odata.urlify(cqn, { kind: 'odata', model, method: 'GET' })
|
|
17
|
+
odataRes.setHeader('Location', location.replace(/\?.*$/, ''))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const _isNoAccessError = e => Number(e.code) === 403 || Number(e.code) === 401
|
|
21
|
+
const _isNotFoundError = e => Number(e.code) === 404
|
|
22
|
+
const _isEntityNotReadableError = e => Number(e.code) === 405
|
|
23
|
+
|
|
24
|
+
const _handleReadError = (err, req) => {
|
|
25
|
+
if (!(_isNoAccessError(err) || _isEntityNotReadableError(err) || _isNotFoundError(err))) throw err
|
|
26
|
+
const log = Object.assign(err, { level: 'ERROR', message: normalizeError(err, req).error.message })
|
|
27
|
+
process.env.NODE_ENV !== 'production' && LOG._warn && LOG.warn(log)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const _getOperationQueryColumns = urlQueryOptions => {
|
|
31
|
+
if (!urlQueryOptions || !(urlQueryOptions.$select || urlQueryOptions.$expand)) return []
|
|
32
|
+
const url = []
|
|
33
|
+
if (urlQueryOptions.$select) url.push(`$select=${urlQueryOptions.$select}`)
|
|
34
|
+
if (urlQueryOptions.$expand) url.push(`$expand=${urlQueryOptions.$expand}`)
|
|
35
|
+
const {
|
|
36
|
+
SELECT: { columns }
|
|
37
|
+
} = cds.odata.parse(`?${url.join('&')}`)
|
|
13
38
|
return columns
|
|
14
39
|
}
|
|
15
40
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
41
|
+
const _isDraftAction = req => req.event in DRAFT_MOD_EVENTS
|
|
42
|
+
const _isActionOrFunction = req => !(req.event in CDS_EVENTS) || _isDraftAction(req)
|
|
43
|
+
const _isWriteWithResponse = req => req.event in WRITE_EVENTS && !(req.event in { CANCEL: 1, DELETE: 1 })
|
|
44
|
+
|
|
45
|
+
const readAfterWrite = async (req, srv, { operation, isBefore } = { isBefore: false }) => {
|
|
46
|
+
let query
|
|
47
|
+
|
|
48
|
+
if (_isActionOrFunction(req)) {
|
|
49
|
+
const { result, returnType } = operation
|
|
50
|
+
query = getSimpleSelectCQN(returnType, result, _getOperationQueryColumns(req._queryOptions))
|
|
51
|
+
if (_isDraftAction(req)) query.where({ IsActiveEntity: req.event === 'draftActivate' })
|
|
52
|
+
} else if (req.event === 'UPDATE' && !hasDeepUpdate(srv.model, req.query)) {
|
|
53
|
+
query = Array.isArray(req.data) ? SELECT.from(req.query.UPDATE.entity) : SELECT.one(req.query.UPDATE.entity)
|
|
26
54
|
} else {
|
|
27
|
-
|
|
55
|
+
query = getDeepSelect(req)
|
|
56
|
+
}
|
|
57
|
+
Object.defineProperty(query.SELECT, '_4odata', { value: true })
|
|
58
|
+
// gracefully set location and no body if no read auth or not readable capability
|
|
59
|
+
let result
|
|
60
|
+
try {
|
|
61
|
+
const _req = new Request({ query, event: 'READ', _: req._ })
|
|
62
|
+
result = await srv.dispatch(_req)
|
|
63
|
+
if (result === null && !isBefore && (_isWriteWithResponse(req) || _isDraftAction(req))) {
|
|
64
|
+
// > something must be written and no READ error <=> @restrict or static where
|
|
65
|
+
_req.reject({
|
|
66
|
+
code: 404,
|
|
67
|
+
internal: {
|
|
68
|
+
reason: `No data found for "READ" after "${req.method}" of "${query._target.name}"`,
|
|
69
|
+
source: `"@restrict" or "where" of "${query._target.name}" or underlying entities`
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
} catch (e) {
|
|
74
|
+
_handleReadError(e, req)
|
|
75
|
+
result = null
|
|
76
|
+
}
|
|
77
|
+
// draft actions have own logic to set location header
|
|
78
|
+
if (result === null && _isWriteWithResponse(req) && !_isDraftAction(req)) {
|
|
79
|
+
setLocationHeader(req, srv)
|
|
28
80
|
}
|
|
29
|
-
const result = await cds.tx(req).run(deepSelect)
|
|
30
81
|
return result
|
|
31
82
|
}
|
|
83
|
+
|
|
84
|
+
module.exports = {
|
|
85
|
+
readAfterWrite,
|
|
86
|
+
setLocationHeader
|
|
87
|
+
}
|
|
@@ -8,16 +8,8 @@ const {
|
|
|
8
8
|
|
|
9
9
|
const getError = require('../../../../common/error')
|
|
10
10
|
|
|
11
|
-
const _unboundActionsAndFunctions =
|
|
12
|
-
const
|
|
13
|
-
acc[cur] = 1
|
|
14
|
-
return acc
|
|
15
|
-
}, {})
|
|
16
|
-
const _actionsAndFunctions = [..._unboundActionsAndFunctions, 'BOUND.ACTION', 'BOUND.FUNCTION']
|
|
17
|
-
const _boundCustomOperationKinds = _actionsAndFunctions.reduce((acc, cur) => {
|
|
18
|
-
acc[cur] = 1
|
|
19
|
-
return acc
|
|
20
|
-
}, {})
|
|
11
|
+
const _unboundActionsAndFunctions = { 'ACTION.IMPORT': 1, 'FUNCTION.IMPORT': 1 }
|
|
12
|
+
const _actionsAndFunctions = { ..._unboundActionsAndFunctions, 'BOUND.ACTION': 1, 'BOUND.FUNCTION': 1 }
|
|
21
13
|
|
|
22
14
|
/**
|
|
23
15
|
* Checks if a custom operation was requested.
|
|
@@ -29,7 +21,7 @@ const _boundCustomOperationKinds = _actionsAndFunctions.reduce((acc, cur) => {
|
|
|
29
21
|
*/
|
|
30
22
|
const isCustomOperation = (pathSegments, includingBound = true) => {
|
|
31
23
|
const kind = pathSegments[pathSegments.length - 1].getKind()
|
|
32
|
-
const kinds = includingBound ?
|
|
24
|
+
const kinds = includingBound ? _actionsAndFunctions : _unboundActionsAndFunctions
|
|
33
25
|
if (kind in kinds) {
|
|
34
26
|
return kind
|
|
35
27
|
}
|
|
@@ -6,6 +6,7 @@ const { big } = require('@sap/cds-foss')
|
|
|
6
6
|
const getTemplate = require('../../../../common/utils/template')
|
|
7
7
|
const templateProcessor = require('../../../../common/utils/templateProcessor')
|
|
8
8
|
const { omitValue, applyOmitValuesPreference } = require('./omitValues')
|
|
9
|
+
const { setLocationHeader } = require('./readAfterWrite')
|
|
9
10
|
|
|
10
11
|
const METADATA = {
|
|
11
12
|
$context: '*@odata.context',
|
|
@@ -44,6 +45,35 @@ const _getPropertyName = req => {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
const _cleanupMetadata = (odataResult, result, req) => {
|
|
49
|
+
if (typeof result !== 'object') return odataResult
|
|
50
|
+
// backwards compatibility for content-type in stream
|
|
51
|
+
if ('*@odata.mediaContentType' in result) result.$mediaContentType = result['*@odata.mediaContentType']
|
|
52
|
+
if ('$mediaContentDispositionFilename' in result && req) {
|
|
53
|
+
const cdt = result.$mediaContentDispositionType || 'attachment'
|
|
54
|
+
req._.odataRes.setHeader(
|
|
55
|
+
'Content-Disposition',
|
|
56
|
+
`${cdt}; filename="${encodeURIComponent(result.$mediaContentDispositionFilename)}"`
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const keysToCleanup = {
|
|
61
|
+
// do not set "@odata.context" as it may be inherited of remote service
|
|
62
|
+
$context: true,
|
|
63
|
+
// REVISIT: okra doesn't support content disposition
|
|
64
|
+
$mediaContentDispositionFilename: true,
|
|
65
|
+
$mediaContentDispositionType: true
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
for (const key in METADATA) {
|
|
69
|
+
if (!(key in result)) continue
|
|
70
|
+
if (!keysToCleanup[key]) odataResult[METADATA[key]] = result[key]
|
|
71
|
+
delete result[key]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return odataResult
|
|
75
|
+
}
|
|
76
|
+
|
|
47
77
|
/**
|
|
48
78
|
* Convert any result to the result object structure, which is expected of odata-v4.
|
|
49
79
|
*
|
|
@@ -51,63 +81,55 @@ const _getPropertyName = req => {
|
|
|
51
81
|
* @param {*} [req]
|
|
52
82
|
* @returns {string | object}
|
|
53
83
|
*/
|
|
54
|
-
// eslint-disable-next-line complexity
|
|
55
84
|
const toODataResult = (result, req) => {
|
|
56
85
|
if (result == null) return ''
|
|
57
86
|
|
|
58
|
-
let propertyName, isStream
|
|
87
|
+
let propertyName, isStream, isCollection
|
|
59
88
|
if (req) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
req.
|
|
63
|
-
req.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
89
|
+
if (cds.env.features.odata_new_parser) {
|
|
90
|
+
propertyName = req._metaInfo.propertyName
|
|
91
|
+
isStream = req._metaInfo.isStream
|
|
92
|
+
isCollection = req._metaInfo.isCollection
|
|
93
|
+
} else {
|
|
94
|
+
propertyName = _getPropertyName(req)
|
|
95
|
+
isStream =
|
|
96
|
+
req._.odataReq.getUriInfo().getLastSegment().getProperty() &&
|
|
97
|
+
req._.odataReq.getUriInfo().getLastSegment().getProperty().getType().toString() === 'Edm.Stream'
|
|
98
|
+
|
|
99
|
+
isCollection =
|
|
100
|
+
!propertyName &&
|
|
101
|
+
!(req.event in { NEW: 1, CREATE: 1, UPDATE: 1, UPSERT: 1, EDIT: 1, PATCH: 1 }) &&
|
|
102
|
+
req._.odataReq.getUriInfo().getLastSegment().isCollection()
|
|
103
|
+
}
|
|
68
104
|
}
|
|
69
105
|
|
|
106
|
+
if (isCollection && !Array.isArray(result)) result = [result]
|
|
107
|
+
else if (!isCollection && Array.isArray(result)) result = result[0]
|
|
108
|
+
|
|
70
109
|
let value = result
|
|
71
110
|
if (typeof result === 'object') {
|
|
72
111
|
if ('value' in result && (result.value instanceof Readable || isStream)) value = result.value
|
|
73
112
|
else if (propertyName) value = result[propertyName]
|
|
74
113
|
}
|
|
75
114
|
|
|
76
|
-
const odataResult = { value }
|
|
115
|
+
const odataResult = _cleanupMetadata({ value }, result, req)
|
|
77
116
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
for (const key in METADATA) {
|
|
83
|
-
// do not set "@odata.context" as it may be inherited of remote service
|
|
84
|
-
if (key === '$context') {
|
|
85
|
-
delete result[key]
|
|
86
|
-
continue
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// REVISIT: okra doesn't support content disposition
|
|
90
|
-
if (key === '$mediaContentDispositionFilename' && result[key] && req) {
|
|
91
|
-
const cdt = result.$mediaContentDispositionType || 'attachment'
|
|
92
|
-
req._.odataRes.setHeader('Content-Disposition', `${cdt}; filename="${encodeURIComponent(result[key])}"`)
|
|
93
|
-
delete result[key]
|
|
94
|
-
continue
|
|
95
|
-
}
|
|
96
|
-
if (key === '$mediaContentDispositionType') {
|
|
97
|
-
delete result[key]
|
|
98
|
-
continue
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (key in result) {
|
|
102
|
-
odataResult[METADATA[key]] = result[key]
|
|
103
|
-
delete result[key]
|
|
104
|
-
}
|
|
105
|
-
}
|
|
117
|
+
const { metadata } = _getOptions(req)
|
|
118
|
+
if (cds.env.features.odata_new_parser && metadata !== 'none') {
|
|
119
|
+
return _setContext(odataResult, req, isCollection)
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
return odataResult
|
|
109
123
|
}
|
|
110
124
|
|
|
125
|
+
const _setContext = (odataResult, req, isCollection) => {
|
|
126
|
+
if (req && req._metaInfo) {
|
|
127
|
+
const result = isCollection ? odataResult : odataResult.value
|
|
128
|
+
if (result != null) Object.assign(result, { [METADATA.$context]: req._metaInfo.contextUrl })
|
|
129
|
+
}
|
|
130
|
+
return odataResult
|
|
131
|
+
}
|
|
132
|
+
|
|
111
133
|
const addEtags = (row, key) => {
|
|
112
134
|
row['*@odata.etag'] = row[key]
|
|
113
135
|
}
|
|
@@ -158,12 +180,12 @@ const localizeAfterDraftActivate = (row, key, locale) => {
|
|
|
158
180
|
}
|
|
159
181
|
}
|
|
160
182
|
|
|
161
|
-
const _processCategory = (
|
|
162
|
-
const { row, key, element } =
|
|
183
|
+
const _processCategory = (req, category, elementInfo, options, previousResult) => {
|
|
184
|
+
const { row, key, element } = elementInfo
|
|
163
185
|
|
|
164
186
|
switch (category) {
|
|
165
187
|
case '@odata.omitValues':
|
|
166
|
-
omitValue(
|
|
188
|
+
omitValue(elementInfo, req, options.omitValuesPreference, previousResult)
|
|
167
189
|
break
|
|
168
190
|
|
|
169
191
|
case '@odata.etag':
|
|
@@ -190,13 +212,13 @@ const _processCategory = (category, processArgs, req, options, previousResult) =
|
|
|
190
212
|
}
|
|
191
213
|
}
|
|
192
214
|
|
|
193
|
-
const _processorFn = (req, previousResult, options) =>
|
|
194
|
-
const { row, key, plain } =
|
|
215
|
+
const _processorFn = (req, previousResult, options) => elementInfo => {
|
|
216
|
+
const { row, key, plain } = elementInfo
|
|
195
217
|
if (typeof row !== 'object' || !Object.prototype.hasOwnProperty.call(row, key)) return
|
|
196
218
|
const categories = plain.categories
|
|
197
219
|
|
|
198
220
|
for (const category of categories) {
|
|
199
|
-
_processCategory(
|
|
221
|
+
_processCategory(req, category, elementInfo, options, previousResult)
|
|
200
222
|
}
|
|
201
223
|
}
|
|
202
224
|
|
|
@@ -243,15 +265,18 @@ const _assocs = (element, target) => {
|
|
|
243
265
|
return []
|
|
244
266
|
}
|
|
245
267
|
|
|
246
|
-
const _pick = options => (element, target
|
|
268
|
+
const _pick = options => (element, target) => {
|
|
247
269
|
const categories = []
|
|
248
270
|
|
|
249
271
|
if (element['@odata.etag']) categories.push('@odata.etag')
|
|
250
|
-
|
|
251
272
|
if (element._type === 'cds.Decimal') categories.push('@cds.Decimal')
|
|
252
273
|
|
|
253
274
|
categories.push(..._assocs(element, target))
|
|
254
275
|
|
|
276
|
+
// REVISIT: It makes no sense to store static values inside the template, it would just
|
|
277
|
+
// blow up the memory of the template.
|
|
278
|
+
// For operations concering _all_ elements, the templating mechanism doesn't make sense
|
|
279
|
+
// and should not be used.
|
|
255
280
|
if (options.omitValuesPreference) categories.push('@odata.omitValues')
|
|
256
281
|
if (options.event === 'draftActivate' && options.locale && options.locale !== 'en' && element.localized === true) {
|
|
257
282
|
categories.push('localizeAfterDraftActivate')
|
|
@@ -260,12 +285,15 @@ const _pick = options => (element, target, parent) => {
|
|
|
260
285
|
if (categories.length) return { categories }
|
|
261
286
|
}
|
|
262
287
|
|
|
263
|
-
const _getOptions =
|
|
288
|
+
const _getOptions = req => {
|
|
289
|
+
if (!req) return {}
|
|
290
|
+
const { headers, locale, event } = req
|
|
264
291
|
const options = {
|
|
265
292
|
decimals: null,
|
|
266
293
|
omitValuesPreference: null,
|
|
267
294
|
locale,
|
|
268
|
-
event
|
|
295
|
+
event,
|
|
296
|
+
metadata: 'minimal'
|
|
269
297
|
}
|
|
270
298
|
|
|
271
299
|
if (!headers) return options
|
|
@@ -278,6 +306,9 @@ const _getOptions = ({ headers, locale, event }) => {
|
|
|
278
306
|
options.decimals = { exponential: acceptHeader.includes('ExponentialDecimals=true') }
|
|
279
307
|
}
|
|
280
308
|
|
|
309
|
+
const metadataMatch = acceptHeader && acceptHeader.match(/metadata=(minimal|full|none)/)
|
|
310
|
+
if (metadataMatch) options.metadata = metadataMatch[1]
|
|
311
|
+
|
|
281
312
|
const preferHeader = headers.prefer
|
|
282
313
|
|
|
283
314
|
if (preferHeader && preferHeader.includes('omit-values=')) {
|
|
@@ -304,6 +335,7 @@ const postProcess = (req, res, service, result, previousResult) => {
|
|
|
304
335
|
const options = _getOptions(req)
|
|
305
336
|
const cacheKey = _generateCacheKey(headers, options)
|
|
306
337
|
const parent = _getParent(model, target.name)
|
|
338
|
+
// REVISIT: Why so many templates? -> Create only one (superset) template to reduce memory consumption
|
|
307
339
|
const template = getTemplate(cacheKey, service, target, { pick: _pick(options) }, parent)
|
|
308
340
|
|
|
309
341
|
if (template.elements.size === 0) return
|
|
@@ -318,40 +350,30 @@ const postProcess = (req, res, service, result, previousResult) => {
|
|
|
318
350
|
const processFn = _processorFn(req, previousResult, options)
|
|
319
351
|
|
|
320
352
|
for (const row of rows) {
|
|
321
|
-
|
|
353
|
+
templateProcessor({
|
|
322
354
|
processFn,
|
|
323
355
|
row,
|
|
324
356
|
template
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
templateProcessor(args)
|
|
357
|
+
})
|
|
328
358
|
}
|
|
329
359
|
}
|
|
330
360
|
|
|
331
361
|
applyOmitValuesPreference(res, options.omitValuesPreference)
|
|
332
362
|
}
|
|
333
363
|
|
|
334
|
-
const postProcessMinimal = (req, result) => {
|
|
335
|
-
const { target } = req
|
|
364
|
+
const postProcessMinimal = (req, service, result) => {
|
|
365
|
+
const { target, timestamp } = req
|
|
336
366
|
|
|
337
367
|
if (!target || !result) return
|
|
338
368
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
if (!etagElement) return
|
|
369
|
+
setLocationHeader(req, service)
|
|
342
370
|
|
|
343
|
-
const etag =
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
result = result.value && Object.keys(result).filter(k => !k.match(/^\W/)).length === 1 ? result.value : result
|
|
347
|
-
const rows = Array.isArray(result) ? result : [result]
|
|
348
|
-
|
|
349
|
-
// process each row
|
|
350
|
-
for (const row of rows) {
|
|
351
|
-
if (typeof row !== 'object' || !Object.prototype.hasOwnProperty.call(row, etag)) return
|
|
352
|
-
|
|
353
|
-
addEtags(row, etag)
|
|
371
|
+
const etag = target._etag && target._etag.name
|
|
372
|
+
if (timestamp && etag && etag in result) {
|
|
373
|
+
return { '*@odata.etag': result[etag] === '$now' ? new Date(timestamp).toISOString() : result[etag] }
|
|
354
374
|
}
|
|
375
|
+
|
|
376
|
+
return null
|
|
355
377
|
}
|
|
356
378
|
|
|
357
379
|
module.exports = {
|
|
@@ -3,11 +3,12 @@ const LOG = cds.log('odata')
|
|
|
3
3
|
|
|
4
4
|
const { SELECT } = cds.ql
|
|
5
5
|
|
|
6
|
-
const {
|
|
6
|
+
const { isPathToDraft } = require('../../../../common/utils/cqn')
|
|
7
7
|
const { deepCopyArray } = require('../../../../common/utils/copy')
|
|
8
8
|
const { cqn2cqn4sql } = require('../../../../common/utils/cqn2cqn4sql')
|
|
9
9
|
const { ensureDraftsSuffix } = require('../../../../fiori/utils/handler')
|
|
10
10
|
const { removeIsActiveEntityRecursively, isActiveEntityRequested } = require('../../../../fiori/utils/where')
|
|
11
|
+
const { getTransition } = require('../../../../common/utils/resolveView')
|
|
11
12
|
|
|
12
13
|
const isStreaming = segments => {
|
|
13
14
|
const lastSegment = segments[segments.length - 1]
|
|
@@ -44,8 +45,19 @@ const adaptStreamCQN = (cqn, isDraft = false) => {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
// eslint-disable-next-line complexity
|
|
47
49
|
const getStreamProperties = (req, model) => {
|
|
48
|
-
|
|
50
|
+
// new odata parser sets streaming property in SELECT.from
|
|
51
|
+
const ref = (req.query.SELECT.columns && req.query.SELECT.columns[0].ref) || req.query.SELECT.from.ref
|
|
52
|
+
const propertyName = ref[ref.length - 1]
|
|
53
|
+
let mediaTypeProperty
|
|
54
|
+
for (let key in req.target.elements) {
|
|
55
|
+
const val = req.target.elements[key]
|
|
56
|
+
if (val['@Core.MediaType'] && val.name === propertyName) {
|
|
57
|
+
mediaTypeProperty = val
|
|
58
|
+
break
|
|
59
|
+
}
|
|
60
|
+
}
|
|
49
61
|
|
|
50
62
|
let contentType, contentDispositionFilename
|
|
51
63
|
const columns = []
|
|
@@ -56,10 +68,12 @@ const getStreamProperties = (req, model) => {
|
|
|
56
68
|
LOG.warn(
|
|
57
69
|
`@Core.MediaType in entity "${req.target.name}" points to property "${contentTypeProperty}" which was renamed or is not part of the projection. You must update the annotation value.`
|
|
58
70
|
)
|
|
59
|
-
|
|
71
|
+
const mapping = getTransition(req.target, cds.db).mapping
|
|
72
|
+
const key = [...mapping.entries()].find(({ 1: val }) => val.ref[0] === contentTypeProperty)
|
|
73
|
+
contentTypeProperty = key && key.length && key[0]
|
|
60
74
|
}
|
|
61
75
|
if (!req.target.elements[contentTypeProperty]) {
|
|
62
|
-
LOG._warn && LOG.warn(`
|
|
76
|
+
LOG._warn && LOG.warn(`MediaType ${contentTypeProperty} not found in entity "${req.target.name}".`)
|
|
63
77
|
} else {
|
|
64
78
|
columns.push({ ref: [contentTypeProperty], as: 'contentType' })
|
|
65
79
|
}
|
|
@@ -68,12 +82,19 @@ const getStreamProperties = (req, model) => {
|
|
|
68
82
|
}
|
|
69
83
|
if (mediaTypeProperty['@Core.ContentDisposition.Filename']) {
|
|
70
84
|
if (typeof mediaTypeProperty['@Core.ContentDisposition.Filename'] === 'object') {
|
|
71
|
-
|
|
85
|
+
let contentDispositionProperty = mediaTypeProperty['@Core.ContentDisposition.Filename']['=']
|
|
72
86
|
if (!req.target.elements[contentDispositionProperty]) {
|
|
73
87
|
LOG._warn &&
|
|
74
88
|
LOG.warn(
|
|
75
89
|
`@Core.ContentDisposition.Filename in entity "${req.target.name}" points to property "${contentDispositionProperty}" which was renamed or is not part of the projection. You must update the annotation value.`
|
|
76
90
|
)
|
|
91
|
+
const mapping = getTransition(req.target, cds.db).mapping
|
|
92
|
+
const key = [...mapping.entries()].find(({ 1: val }) => val.ref[0] === contentDispositionProperty)
|
|
93
|
+
contentDispositionProperty = key && key.length && key[0]
|
|
94
|
+
}
|
|
95
|
+
if (!req.target.elements[contentDispositionProperty]) {
|
|
96
|
+
LOG._warn &&
|
|
97
|
+
LOG.warn(`ContentDisposition ${contentDispositionProperty} not found in entity "${req.target.name}".`)
|
|
77
98
|
} else {
|
|
78
99
|
columns.push({ ref: [contentDispositionProperty], as: 'contentDispositionFilename' })
|
|
79
100
|
}
|
|
@@ -88,7 +109,7 @@ const getStreamProperties = (req, model) => {
|
|
|
88
109
|
let select = SELECT.one.from({ ref: deepCopyArray(req.query.SELECT.from.ref) }).columns(columns)
|
|
89
110
|
|
|
90
111
|
// new parser has media property as last ref element -> remove
|
|
91
|
-
if (
|
|
112
|
+
if (req._metaInfo && req._metaInfo.propertyName) select.SELECT.from.ref.pop()
|
|
92
113
|
|
|
93
114
|
const pathToDraft = isPathToDraft(select.SELECT.from.ref, model)
|
|
94
115
|
if (req.target._isDraftEnabled && pathToDraft) {
|
|
@@ -57,17 +57,6 @@ const _buildTypeErrorObject = (type, value) => {
|
|
|
57
57
|
return { type, value }
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
const _checkArray = (type, check, data) => {
|
|
61
|
-
return data.filter(value => !check(value)).map(value => _buildTypeErrorObject(type, value))
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const _checkSingle = (type, check, data) => {
|
|
65
|
-
if (!check(data)) {
|
|
66
|
-
return [_buildTypeErrorObject(type, data)]
|
|
67
|
-
}
|
|
68
|
-
return []
|
|
69
|
-
}
|
|
70
|
-
|
|
71
60
|
/**
|
|
72
61
|
* Validate the return type values of custom operations (actions and functions) for primitive or complex values as
|
|
73
62
|
* single values or arrays.
|
|
@@ -85,17 +74,18 @@ const validateReturnType = (operation, data) => {
|
|
|
85
74
|
const returnType = operation.returns.items ? operation.returns.items : operation.returns
|
|
86
75
|
|
|
87
76
|
if (typeof data === 'undefined') return true
|
|
77
|
+
if (returnType['@open']) return true
|
|
88
78
|
|
|
89
79
|
let checkResult
|
|
90
80
|
|
|
91
81
|
// .type of action/function behaves different to .type of other csn elements
|
|
92
82
|
// Return type contains primitives
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
83
|
+
// eslint-disable-next-line no-proto
|
|
84
|
+
const _type = typeof returnType._type === 'object' ? returnType.__proto__._type : returnType._type // REVISIT: super dirty hack for compiler's to.edmx polluting the csn definitions with ._type -> please use Symbols instead
|
|
85
|
+
const check = CDS_TYPE_CHECKS[_type] // IMPORTANT: use ._type
|
|
86
|
+
if (check) {
|
|
87
|
+
const array = Array.isArray(data) ? data : [data]
|
|
88
|
+
checkResult = array.filter(value => !check(value)).map(value => _buildTypeErrorObject(_type, value))
|
|
99
89
|
} else {
|
|
100
90
|
if (typeof data !== 'object') {
|
|
101
91
|
throw new Error(
|