@sap/cds 5.9.8 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +252 -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 +80 -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 +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 +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 +70 -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 +127 -41
- 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,88 +1,74 @@
|
|
|
1
|
-
|
|
2
|
-
const cds = global.cds
|
|
1
|
+
const cds = require('../../cds')
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
const LOG = cds.log()
|
|
3
|
+
const { foreignKeyPropagations } = require('../utils/foreignKeyPropagations')
|
|
6
4
|
|
|
7
|
-
const
|
|
5
|
+
const _hasJoinCondition = e => e.isAssociation && e.on && e.on.length > 2
|
|
8
6
|
|
|
9
|
-
const
|
|
10
|
-
const { foreignKeyPropagations } = require('../utils/foreignKeyPropagations')
|
|
7
|
+
const _isSelfRef = e => e.ref && e.ref[0] === '$self'
|
|
11
8
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
9
|
+
const _getBacklinkName = on => {
|
|
10
|
+
const i = on.findIndex(_isSelfRef)
|
|
11
|
+
if (i === -1) return
|
|
12
|
+
let ref
|
|
13
|
+
if (on[i + 1] && on[i + 1] === '=') ref = on[i + 2].ref
|
|
14
|
+
if (on[i - 1] && on[i - 1] === '=') ref = on[i - 2].ref
|
|
15
|
+
return ref && ref[ref.length - 1]
|
|
20
16
|
}
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
this.set('__isAssociationStrict', !!(this.isAssociation && !this.isComposition))
|
|
27
|
-
)
|
|
28
|
-
}
|
|
18
|
+
const isSelfManaged = e => {
|
|
19
|
+
if (!_hasJoinCondition(e)) return
|
|
20
|
+
return !!e.on.find(_isSelfRef)
|
|
21
|
+
}
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
)
|
|
23
|
+
const _isUnManagedAssociation = (e, checkComposition) =>
|
|
24
|
+
e.isAssociation && (!checkComposition || e.isComposition) && _hasJoinCondition(e)
|
|
25
|
+
|
|
26
|
+
const getAnchor = (e, checkComposition) => {
|
|
27
|
+
if (!(e._isAssociationStrict && (e.keys || e.on))) return
|
|
28
|
+
for (const anchor of Object.values(e._target.associations || {})) {
|
|
29
|
+
if (!_isUnManagedAssociation(anchor, checkComposition)) continue
|
|
30
|
+
if (_getBacklinkName(anchor.on) === e.name && anchor.target === e.parent.name) return anchor
|
|
39
31
|
}
|
|
32
|
+
}
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
)
|
|
34
|
+
const getBacklink = (e, checkComposition) => {
|
|
35
|
+
if (!_isUnManagedAssociation(e, checkComposition)) return
|
|
36
|
+
const backlinkName = _getBacklinkName(e.on)
|
|
37
|
+
if (backlinkName) return e._target && e._target.elements && e._target.elements[backlinkName]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = class {
|
|
41
|
+
get _isAssociationStrict() {
|
|
42
|
+
return this.own('__isAssociationStrict', () => !this.isComposition)
|
|
51
43
|
}
|
|
52
44
|
|
|
53
45
|
get _isContained() {
|
|
54
|
-
this[ODATA_CONTAINED] && _logDeprecationForODataContained()
|
|
55
46
|
return (
|
|
56
|
-
this.own('__isContained') ||
|
|
57
|
-
this.set(
|
|
58
|
-
'__isContained',
|
|
59
|
-
this.name !== 'DraftAdministrativeData_DraftUUID' &&
|
|
60
|
-
((this.isAssociation && this[ODATA_CONTAINED]) || (this.isComposition && cds.env.effective.odata.containment))
|
|
61
|
-
)
|
|
47
|
+
this.own('__isContained') || this.set('__isContained', this.isComposition && cds.env.effective.odata.containment)
|
|
62
48
|
)
|
|
63
49
|
}
|
|
64
50
|
|
|
65
51
|
get _isSelfManaged() {
|
|
66
|
-
return this.own('__isSelfManaged')
|
|
52
|
+
return this.own('__isSelfManaged', () => isSelfManaged(this))
|
|
67
53
|
}
|
|
68
54
|
|
|
69
55
|
get _isBacklink() {
|
|
70
|
-
return this.own('__isBacklink')
|
|
56
|
+
return this.own('__isBacklink', () => !!getAnchor(this))
|
|
71
57
|
}
|
|
72
58
|
|
|
73
59
|
get _isCompositionBacklink() {
|
|
74
|
-
return this.own('__isCompositionBacklink')
|
|
60
|
+
return this.own('__isCompositionBacklink', () => !!getAnchor(this, true))
|
|
75
61
|
}
|
|
76
62
|
|
|
77
63
|
get _anchor() {
|
|
78
|
-
return this.own('__anchor')
|
|
64
|
+
return this.own('__anchor', () => getAnchor(this))
|
|
79
65
|
}
|
|
80
66
|
|
|
81
67
|
get _backlink() {
|
|
82
|
-
return this.own('__backlink')
|
|
68
|
+
return this.own('__backlink', () => getBacklink(this))
|
|
83
69
|
}
|
|
84
70
|
|
|
85
71
|
get _foreignKeys() {
|
|
86
|
-
return this.own('__foreignKeys')
|
|
72
|
+
return this.own('__foreignKeys', () => foreignKeyPropagations(this))
|
|
87
73
|
}
|
|
88
74
|
}
|
|
@@ -1,27 +1,82 @@
|
|
|
1
|
-
const { getRelations, isMandatory, isReadOnly } = require('./utils')
|
|
2
1
|
const { foreignKey4 } = require('../../common/utils/foreignKeyPropagations')
|
|
3
2
|
|
|
4
3
|
// NOTE: Please only add things which are relevant to _any_ type,
|
|
5
4
|
// use specialized types otherwise (entity, Association, ...).
|
|
6
5
|
module.exports = class {
|
|
7
6
|
get _isStructured() {
|
|
8
|
-
return this.own('__isStructured')
|
|
7
|
+
return this.own('__isStructured', () => !!this.elements && this.kind !== 'entity')
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
get _isMandatory() {
|
|
12
|
-
return this.own('__isMandatory')
|
|
11
|
+
return this.own('__isMandatory', () => !this.isAssociation && isMandatory(this))
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
get _isReadOnly() {
|
|
16
|
-
return this.own('__isReadOnly')
|
|
15
|
+
return this.own('__isReadOnly', () => !this.key && isReadOnly(this))
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
// REVISIT: Where to put?
|
|
20
19
|
get _relations() {
|
|
21
|
-
return this.own('__relations')
|
|
20
|
+
return this.own('__relations', () => getRelations(this))
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
get _foreignKey4() {
|
|
25
|
-
return this.own('__foreignKey4')
|
|
24
|
+
return this.own('__foreignKey4', () => foreignKey4(this))
|
|
26
25
|
}
|
|
27
26
|
}
|
|
27
|
+
|
|
28
|
+
const Relation = require('./relation')
|
|
29
|
+
const _exposeRelation = relation => Object.defineProperty({}, '_', { get: () => relation })
|
|
30
|
+
|
|
31
|
+
const _relationHandler = relation => ({
|
|
32
|
+
get: (target, name) => {
|
|
33
|
+
const path = name.split(',')
|
|
34
|
+
const prop = path.join('_')
|
|
35
|
+
if (!target[prop]) {
|
|
36
|
+
if (path.length === 1) {
|
|
37
|
+
// REVISIT: property 'join' must not be used in CSN to make this working
|
|
38
|
+
if (relation._has(prop)) return relation[prop]
|
|
39
|
+
const newRelation = Relation.to(relation, prop)
|
|
40
|
+
if (newRelation) {
|
|
41
|
+
target[prop] = new Proxy(_exposeRelation(newRelation), _relationHandler(newRelation))
|
|
42
|
+
}
|
|
43
|
+
return target[prop]
|
|
44
|
+
}
|
|
45
|
+
target[prop] = path.reduce((r, p) => r[p] || r.csn._relations[p], relation)
|
|
46
|
+
target[prop].path = path
|
|
47
|
+
}
|
|
48
|
+
return target[prop]
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const getRelations = e => {
|
|
53
|
+
const newRelation = Relation.to(e)
|
|
54
|
+
return new Proxy(_exposeRelation(newRelation), _relationHandler(newRelation))
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const CommonFieldControl = e => {
|
|
58
|
+
const cfr = e['@Common.FieldControl']
|
|
59
|
+
return cfr && cfr['#']
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const isMandatory = e => {
|
|
63
|
+
return (
|
|
64
|
+
e['@assert.mandatory'] !== false &&
|
|
65
|
+
(e['@mandatory'] ||
|
|
66
|
+
e['@Common.FieldControl.Mandatory'] ||
|
|
67
|
+
e['@FieldControl.Mandatory'] ||
|
|
68
|
+
CommonFieldControl(e) === 'Mandatory')
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const isReadOnly = e => {
|
|
73
|
+
return (
|
|
74
|
+
e['@readonly'] ||
|
|
75
|
+
e['@cds.on.update'] ||
|
|
76
|
+
e['@cds.on.insert'] ||
|
|
77
|
+
e['@Core.Computed'] ||
|
|
78
|
+
e['@Common.FieldControl.ReadOnly'] ||
|
|
79
|
+
e['@FieldControl.ReadOnly'] ||
|
|
80
|
+
CommonFieldControl(e) === 'ReadOnly'
|
|
81
|
+
)
|
|
82
|
+
}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
// global.cds is used on purpose here!
|
|
3
|
-
const cds = global.cds
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { getETag, hasPersonalData, hasSensitiveData } = require('./utils')
|
|
7
|
-
|
|
8
|
-
let getSearchableColumns
|
|
9
|
-
|
|
10
1
|
const _flat2struct = (def, prefix = '') => {
|
|
11
2
|
const map = {}
|
|
12
3
|
for (const ele in def.elements) {
|
|
@@ -19,90 +10,39 @@ const _flat2struct = (def, prefix = '') => {
|
|
|
19
10
|
|
|
20
11
|
module.exports = class {
|
|
21
12
|
get _isSingleton() {
|
|
22
|
-
return (
|
|
23
|
-
|
|
24
|
-
this.
|
|
25
|
-
'__isSingleton',
|
|
26
|
-
!!(this['@odata.singleton'] || (this['@odata.singleton.nullable'] && this['@odata.singleton'] !== false))
|
|
27
|
-
)
|
|
13
|
+
return this.own(
|
|
14
|
+
'__isSingleton',
|
|
15
|
+
() => this['@odata.singleton'] || (this['@odata.singleton.nullable'] && this['@odata.singleton'] !== false)
|
|
28
16
|
)
|
|
29
17
|
}
|
|
30
18
|
|
|
31
19
|
get _hasPersistenceSkip() {
|
|
32
|
-
return (
|
|
33
|
-
|
|
34
|
-
this.
|
|
35
|
-
'__hasPersistenceSkip',
|
|
36
|
-
!!(this.own('@cds.persistence.skip') && this.own('@cds.persistence.skip') !== 'if-unused')
|
|
37
|
-
)
|
|
20
|
+
return this.own(
|
|
21
|
+
'__hasPersistenceSkip',
|
|
22
|
+
() => this.own('@cds.persistence.skip') && this.own('@cds.persistence.skip') !== 'if-unused'
|
|
38
23
|
)
|
|
39
24
|
}
|
|
40
25
|
|
|
41
26
|
get _isDraftEnabled() {
|
|
42
|
-
return (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
(this.associations && this.associations.DraftAdministrativeData) ||
|
|
48
|
-
this.name.match(/\.DraftAdministrativeData$/) ||
|
|
49
|
-
(this.own('@odata.draft.enabled') && this.own('@Common.DraftRoot.ActivationAction'))
|
|
50
|
-
)
|
|
27
|
+
return this.own('__isDraftEnabled', () => {
|
|
28
|
+
return (
|
|
29
|
+
(this.associations && this.associations.DraftAdministrativeData) ||
|
|
30
|
+
this.name.match(/\.DraftAdministrativeData$/) ||
|
|
31
|
+
(this.own('@odata.draft.enabled') && this.own('@Common.DraftRoot.ActivationAction'))
|
|
51
32
|
)
|
|
52
|
-
)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
get _searchableColumns() {
|
|
56
|
-
// lazily require on first use
|
|
57
|
-
getSearchableColumns =
|
|
58
|
-
getSearchableColumns || require('../../cds-services/services/utils/columns').getSearchableColumns
|
|
59
|
-
return this.own('__searchableColumns') || this.set('__searchableColumns', getSearchableColumns(this))
|
|
33
|
+
})
|
|
60
34
|
}
|
|
61
35
|
|
|
62
36
|
get _etag() {
|
|
63
|
-
return this.own('__etag'
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
get _hasPersonalData() {
|
|
71
|
-
return this.own('__hasPersonalData') || this.set('__hasPersonalData', hasPersonalData(this))
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
get _hasSensitiveData() {
|
|
75
|
-
return this.own('__hasSensitiveData') || this.set('__hasSensitiveData', hasSensitiveData(this))
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
get _auditCreate() {
|
|
79
|
-
return (
|
|
80
|
-
this.own('__auditCreate') ||
|
|
81
|
-
this.set('__auditCreate', !!(this._hasPersonalData && this['@AuditLog.Operation.Insert']))
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
get _auditRead() {
|
|
86
|
-
return (
|
|
87
|
-
this.own('__auditRead') || this.set('__auditRead', !!(this._hasPersonalData && this['@AuditLog.Operation.Read']))
|
|
88
|
-
)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
get _auditUpdate() {
|
|
92
|
-
return (
|
|
93
|
-
this.own('__auditUpdate') ||
|
|
94
|
-
this.set('__auditUpdate', !!(this._hasPersonalData && this['@AuditLog.Operation.Update']))
|
|
95
|
-
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
get _auditDelete() {
|
|
99
|
-
return (
|
|
100
|
-
this.own('__auditDelete') ||
|
|
101
|
-
this.set('__auditDelete', !!(this._hasPersonalData && this['@AuditLog.Operation.Delete']))
|
|
102
|
-
)
|
|
37
|
+
return this.own('__etag', () => {
|
|
38
|
+
for (const el in this.elements) {
|
|
39
|
+
const element = this.elements[el]
|
|
40
|
+
if (element['@odata.etag']) return element
|
|
41
|
+
}
|
|
42
|
+
})
|
|
103
43
|
}
|
|
104
44
|
|
|
105
45
|
get _flat2struct() {
|
|
106
|
-
return this.own('_flat2struct')
|
|
46
|
+
return this.own('_flat2struct', () => _flat2struct(this))
|
|
107
47
|
}
|
|
108
48
|
}
|
|
@@ -66,7 +66,7 @@ const _whereKeys = keys => {
|
|
|
66
66
|
const where = []
|
|
67
67
|
keys.forEach(key => {
|
|
68
68
|
if (where.length) where.push('or')
|
|
69
|
-
where.push(
|
|
69
|
+
where.push({ xpr: [...ctUtils.whereKey(key)] })
|
|
70
70
|
})
|
|
71
71
|
return where
|
|
72
72
|
}
|
|
@@ -137,7 +137,7 @@ const _subWhere = (result, element) => {
|
|
|
137
137
|
const whereCQN = ctUtils.whereKey(whereObj)
|
|
138
138
|
if (whereCQN.length) {
|
|
139
139
|
if (where.length > 0) where.push('or')
|
|
140
|
-
where.push(
|
|
140
|
+
where.push({ xpr: [...whereCQN] })
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
}
|
|
@@ -84,16 +84,16 @@ function _getSubWhereAndEntities(element, parentWhere, draft, level = 0, composi
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
if (whereKeys.length > 0) {
|
|
87
|
-
where.push(
|
|
87
|
+
where.push({ xpr: [...whereKeys] }, 'and')
|
|
88
88
|
}
|
|
89
89
|
if (staticWhereValues.length > 0) {
|
|
90
|
-
where.push(
|
|
90
|
+
where.push({ xpr: [...staticWhereValues] }, 'and')
|
|
91
91
|
}
|
|
92
92
|
where.push('exists', {
|
|
93
93
|
SELECT: {
|
|
94
94
|
columns: [{ val: 1, as: '_exists' }],
|
|
95
95
|
from: { ref: [entity2.entityName], as: entity2.alias },
|
|
96
|
-
where: parentWhere && parentWhere.length ? [
|
|
96
|
+
where: parentWhere && parentWhere.length ? [{ xpr: [...parentWhere] }, 'and', { xpr: [...subWhere] }] : subWhere
|
|
97
97
|
}
|
|
98
98
|
})
|
|
99
99
|
|
|
@@ -137,7 +137,7 @@ function _getStaticWhere(allBackLinks, entity1) {
|
|
|
137
137
|
|
|
138
138
|
const _addToCQNs = (cqns, subCQN, element, model, level) => {
|
|
139
139
|
// REVISIT:
|
|
140
|
-
// The compiler generates foreign-key constraints (
|
|
140
|
+
// The compiler generates foreign-key constraints (if features.assert_integrity_type = 'DB')
|
|
141
141
|
// and enables DELETE CASCADE. For these cases, the runtime doesn't need to delete compositions
|
|
142
142
|
// manually, it's done by the database itself.
|
|
143
143
|
// However, there are cases (unmanaged compositions), where this doesn't happen.
|
|
@@ -197,7 +197,7 @@ const hasDeepDelete = (model, cqn) => {
|
|
|
197
197
|
|
|
198
198
|
const entity = model.definitions[ensureNoDraftsSuffix(from)]
|
|
199
199
|
|
|
200
|
-
if (entity) return !!Object.keys(entity.elements || {}).find(k => entity.elements[k].
|
|
200
|
+
if (entity) return !!Object.keys(entity.elements || {}).find(k => entity.elements[k].isComposition)
|
|
201
201
|
|
|
202
202
|
return false
|
|
203
203
|
}
|
|
@@ -229,14 +229,15 @@ const _getDataFromOncond = (onCond, parent) => {
|
|
|
229
229
|
const getSetNullParentForeignKeyCQNs = async (model, req, dbQuery) => {
|
|
230
230
|
const cqns = []
|
|
231
231
|
const query = dbQuery || req.query
|
|
232
|
-
|
|
232
|
+
// REVISIT: req._tx should not be used like that!
|
|
233
|
+
const origQuery = (req.tx instanceof cds.DatabaseService && req._ && req._.query) || req.query
|
|
233
234
|
if (!dbQuery && origQuery && origQuery.DELETE && origQuery.DELETE.from.ref && origQuery.DELETE.from.ref.length > 1) {
|
|
234
235
|
// delete via 2one navigation => parent is known => no need to SELECT
|
|
235
236
|
const ref = origQuery.DELETE.from.ref
|
|
236
237
|
const cqn = cqn2cqn4sql(UPDATE.entity({ ref: ref.slice(0, ref.length - 1) }), model)
|
|
237
238
|
const { target: parent, elementName } = resolveNavigationTarget(cqn, ref, model)
|
|
238
239
|
const element = parent.elements[elementName]
|
|
239
|
-
if (element && element.
|
|
240
|
+
if (element && element.isComposition && element.is2one) {
|
|
240
241
|
const onCond = element && parent._relations[element.name].join('$$whatever', '$$parent')
|
|
241
242
|
const data = _getDataFromOncond(onCond, parent)
|
|
242
243
|
cqn.data(data)
|
|
@@ -32,7 +32,7 @@ const _foreignKeysToLinks = (element, inverse) =>
|
|
|
32
32
|
const _resolvedElement = (element, service) => {
|
|
33
33
|
if (!element.target) return element
|
|
34
34
|
// skip forbidden view check if association to view with foreign key in target
|
|
35
|
-
const skipForbiddenViewCheck = element._isAssociationStrict
|
|
35
|
+
const skipForbiddenViewCheck = element._isAssociationStrict
|
|
36
36
|
const { target, mapping } = getTransition(element._target, service, skipForbiddenViewCheck)
|
|
37
37
|
const newElement = { target: target.name, _target: target }
|
|
38
38
|
Object.setPrototypeOf(newElement, element)
|
|
@@ -49,12 +49,12 @@ const _resolvedElement = (element, service) => {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const _navigationExistsInCompositionMap = (element, compositionMap) =>
|
|
52
|
-
compositionMap.has(element.target) && element.
|
|
52
|
+
compositionMap.has(element.target) && element.isComposition
|
|
53
53
|
|
|
54
54
|
const _isUnManaged = element => element.on && !element._isSelfManaged
|
|
55
55
|
|
|
56
56
|
const _isNonRecursiveNavigation = (element, rootEntityName) =>
|
|
57
|
-
rootEntityName !== element.target && element.
|
|
57
|
+
rootEntityName !== element.target && element.isComposition
|
|
58
58
|
|
|
59
59
|
const _skipPersistence = (element, definitions) => definitions[element.target]._hasPersistenceSkip
|
|
60
60
|
|
|
@@ -111,7 +111,7 @@ const _getCompositionTreeRec = ({
|
|
|
111
111
|
const targetEntity = definitions[element.target]
|
|
112
112
|
for (const backLinkName in targetEntity.elements) {
|
|
113
113
|
const _backLink = targetEntity.elements[backLinkName]
|
|
114
|
-
if (!_backLink.
|
|
114
|
+
if (!_backLink._isAssociationStrict) continue
|
|
115
115
|
if (
|
|
116
116
|
_backLink._isCompositionBacklink &&
|
|
117
117
|
_backLink.target === compositionElement.target &&
|
|
@@ -148,7 +148,7 @@ const _getCompositionTreeRec = ({
|
|
|
148
148
|
service
|
|
149
149
|
})
|
|
150
150
|
} else if (
|
|
151
|
-
element.
|
|
151
|
+
element._isAssociationStrict &&
|
|
152
152
|
element._isCompositionBacklink &&
|
|
153
153
|
element.target === compositionTree.target &&
|
|
154
154
|
compositionMap.has(element.target)
|
|
@@ -190,7 +190,7 @@ const _getCompositionTree = ({ definitions, rootEntityName, checkRoot = true, re
|
|
|
190
190
|
const rootName = resolveViews ? _resolvedEntityName(rootEntityName, definitions) : rootEntityName
|
|
191
191
|
|
|
192
192
|
if (checkRoot && !isRootEntity(definitions, rootEntityName)) {
|
|
193
|
-
throw getError(`Entity "${rootEntityName}" is not root entity`)
|
|
193
|
+
throw getError(400, `Entity "${rootEntityName}" is not root entity`)
|
|
194
194
|
}
|
|
195
195
|
const compositionTree = {}
|
|
196
196
|
_getCompositionTreeRec({
|
|
@@ -217,7 +217,7 @@ const _cacheCompositionParentsOfOne = ({ definitions }) => {
|
|
|
217
217
|
if (!parent.kind === 'entity' || !parent.elements) continue
|
|
218
218
|
for (const elementName in parent.elements) {
|
|
219
219
|
const element = parent.elements[elementName]
|
|
220
|
-
if (element.
|
|
220
|
+
if (element.isComposition && element.is2one && !element._isSelfManaged) {
|
|
221
221
|
const targetName = element.target
|
|
222
222
|
const target = definitions[targetName]
|
|
223
223
|
if (!target) continue
|
|
@@ -243,7 +243,7 @@ const _memoizeGetCompositionTree = fn => {
|
|
|
243
243
|
|
|
244
244
|
// use ApplicationService as cache key for extensibility
|
|
245
245
|
// REVISIT: context._tx is not a stable API -> pls do not rely on that
|
|
246
|
-
const cacheKey = (cds.context && cds.context.
|
|
246
|
+
const cacheKey = (cds.context && cds.context.tx && Object.getPrototypeOf(cds.context.tx)) || definitions
|
|
247
247
|
|
|
248
248
|
const map = cache.get(cacheKey)
|
|
249
249
|
const cachedResult = map && map.get(key)
|
|
@@ -266,14 +266,14 @@ const _memoizeGetCompositionTree = fn => {
|
|
|
266
266
|
const getCompositionRoot = (definitions, entity) => {
|
|
267
267
|
const associationElements = Object.keys(entity.elements)
|
|
268
268
|
.map(key => entity.elements[key])
|
|
269
|
-
.filter(element => element.
|
|
269
|
+
.filter(element => element._isAssociationStrict)
|
|
270
270
|
|
|
271
271
|
for (const { target } of associationElements) {
|
|
272
272
|
const parentEntity = definitions[target]
|
|
273
273
|
for (const parentElementName in parentEntity.elements) {
|
|
274
274
|
const parentElement = parentEntity.elements[parentElementName]
|
|
275
275
|
if (
|
|
276
|
-
parentElement.
|
|
276
|
+
parentElement.isComposition &&
|
|
277
277
|
parentElement.target === entity.name &&
|
|
278
278
|
parentElement.target !== ensureNoDraftsSuffix(parentElement.parent.name)
|
|
279
279
|
) {
|
|
@@ -43,7 +43,7 @@ function _addSubDeepUpdateCQNForDelete({ entity, data, selectData, deleteCQN })
|
|
|
43
43
|
if (deleteCQN.DELETE.where.length > 0) {
|
|
44
44
|
deleteCQN.DELETE.where.push('or')
|
|
45
45
|
}
|
|
46
|
-
deleteCQN.DELETE.where.push(
|
|
46
|
+
deleteCQN.DELETE.where.push({ xpr: [...ctUtils.whereKey(ctUtils.key(entity, selectEntry))] })
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -254,7 +254,8 @@ const _addSubDeepUpdateCQN = async ({ model, compositionTree, data, selectData,
|
|
|
254
254
|
const hasDeepUpdate = (model, cqn) => {
|
|
255
255
|
if (cqn && cqn.UPDATE && cqn.UPDATE.entity && (cqn.UPDATE.data || cqn.UPDATE.with)) {
|
|
256
256
|
const updateEntity = cqn.UPDATE.entity
|
|
257
|
-
const entityName =
|
|
257
|
+
const entityName =
|
|
258
|
+
(updateEntity.ref && (updateEntity.ref[0].id || updateEntity.ref[0])) || updateEntity.name || updateEntity
|
|
258
259
|
const entity = model.definitions[ensureNoDraftsSuffix(entityName)]
|
|
259
260
|
|
|
260
261
|
if (entity) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const MOD_EVENTS = { UPDATE: 1, DELETE: 1, EDIT: 1 }
|
|
2
|
+
const WRITE_EVENTS = Object.assign({ CREATE: 1, NEW: 1, PATCH: 1, CANCEL: 1 }, MOD_EVENTS)
|
|
3
|
+
const CRUD_EVENTS = Object.assign({ READ: 1 }, WRITE_EVENTS)
|
|
4
|
+
const DRAFT_EVENTS = { PATCH: 1, CANCEL: 1, draftActivate: 1, draftPrepare: 1 }
|
|
5
|
+
const DRAFT_MOD_EVENTS = { draftActivate: 1, EDIT: 1 }
|
|
6
|
+
const CDS_EVENTS = Object.assign({}, CRUD_EVENTS, DRAFT_EVENTS)
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
MOD_EVENTS,
|
|
10
|
+
WRITE_EVENTS,
|
|
11
|
+
CRUD_EVENTS,
|
|
12
|
+
DRAFT_EVENTS,
|
|
13
|
+
CDS_EVENTS,
|
|
14
|
+
DRAFT_MOD_EVENTS
|
|
15
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @param {number} [code] - The numeric code. Only if typeof msg === 'string'.
|
|
2
|
+
* @param {number|object} [code] - The numeric code. Only if typeof msg === 'string'.
|
|
3
3
|
* @param {string|object} msg - The message or text key (string), or entry object (if more details are needed)
|
|
4
4
|
* @param {number|string} [msg.code] - The numeric or text code.
|
|
5
5
|
* @param {string} [msg.message] - The message or text key.
|
|
6
6
|
* @param {string} [msg.target] - The target of the message.
|
|
7
7
|
* @param {Array|object} [msg.args] - The placeholder values for messages with placeholders.
|
|
8
|
-
* @param {any} [msg.<key>] -
|
|
8
|
+
* @param {any} [msg.<key>] - Additional properties, e.g., for processing in custom logging (will not reach client).
|
|
9
9
|
* @param {string} [target] - The target of the message. Only if typeof msg === 'string'.
|
|
10
10
|
* @param {Array|object} [args] - The placeholder values for messages with placeholders. Only if typeof msg === 'string'.
|
|
11
11
|
* @returns {object} - The normalized entry
|
|
@@ -21,10 +21,16 @@ module.exports = (code, msg, target, args) => {
|
|
|
21
21
|
// > params: msg, target?, args?
|
|
22
22
|
;[code, msg, target, args] = [undefined, code, msg, target]
|
|
23
23
|
}
|
|
24
|
+
|
|
24
25
|
if (target && typeof target === 'object') {
|
|
25
26
|
// > params: code?, msg, args?
|
|
26
27
|
;[args, target] = [target]
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
return {
|
|
30
|
+
return {
|
|
31
|
+
code,
|
|
32
|
+
message: msg || (code && String(code)),
|
|
33
|
+
target,
|
|
34
|
+
args
|
|
35
|
+
}
|
|
30
36
|
}
|
|
@@ -5,10 +5,8 @@
|
|
|
5
5
|
* [...]
|
|
6
6
|
* Error responses MAY contain annotations in any of its JSON objects.
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
8
|
const localeFrom = require('../../../../lib/req/locale')
|
|
10
9
|
const { getErrorMessage } = require('./utils')
|
|
11
|
-
|
|
12
10
|
let _i18n
|
|
13
11
|
const i18n = (...args) => {
|
|
14
12
|
if (!_i18n) _i18n = require('../i18n')
|
|
@@ -24,16 +22,12 @@ const {
|
|
|
24
22
|
} = require('./constants')
|
|
25
23
|
const ADDITIONAL_MSG_PROPERTIES = Object.keys(ADDITIONAL_MSG_PROPERTIES_MAP)
|
|
26
24
|
|
|
27
|
-
const SKIP_SANITIZATION = '@cds.skip_sanitization'
|
|
28
|
-
|
|
29
25
|
const _getFiltered = err => {
|
|
30
26
|
const error = {}
|
|
31
27
|
|
|
32
28
|
Object.keys(err)
|
|
33
29
|
.concat(['message'])
|
|
34
30
|
.forEach(k => {
|
|
35
|
-
// REVISIT: do not remove innererror with cds^6
|
|
36
|
-
if (k === 'innererror' && process.env.NODE_ENV === 'production' && !err[SKIP_SANITIZATION]) return
|
|
37
31
|
if (k in ALLOWED_PROPERTIES_MAP || k.startsWith('@')) {
|
|
38
32
|
error[k] = err[k]
|
|
39
33
|
} else if (k === 'numericSeverity') {
|
|
@@ -44,10 +38,10 @@ const _getFiltered = err => {
|
|
|
44
38
|
return error
|
|
45
39
|
}
|
|
46
40
|
|
|
47
|
-
const
|
|
41
|
+
const _rewriteDBError = error => {
|
|
48
42
|
// REVISIT: db stuff probably shouldn't be here
|
|
49
43
|
if (error.code === 'SQLITE_ERROR') {
|
|
50
|
-
error.code = '
|
|
44
|
+
error.code = 'null'
|
|
51
45
|
} else if (
|
|
52
46
|
(error.code.startsWith('SQLITE_CONSTRAINT') && error.message.match(/COMMIT/)) ||
|
|
53
47
|
(error.code.startsWith('SQLITE_CONSTRAINT') && error.message.match(/FOREIGN KEY/)) ||
|
|
@@ -72,7 +66,7 @@ const _normalize = (err, locale, inner = false) => {
|
|
|
72
66
|
error.code = String(error.code || 'null')
|
|
73
67
|
|
|
74
68
|
// REVISIT: code and message rewriting
|
|
75
|
-
|
|
69
|
+
_rewriteDBError(error)
|
|
76
70
|
|
|
77
71
|
let statusCode = err.status || err.statusCode || (_isAllowedError(error.code) && error.code)
|
|
78
72
|
|
|
@@ -87,8 +81,8 @@ const _normalize = (err, locale, inner = false) => {
|
|
|
87
81
|
statusCode = statusCode || _statusCodeFromDetails(childErrorCodes)
|
|
88
82
|
}
|
|
89
83
|
|
|
90
|
-
// make sure it's a number
|
|
91
|
-
statusCode = statusCode ? Number(statusCode) :
|
|
84
|
+
// make sure it's a number if set, otherwise will be assigned as 500 in normalizeError
|
|
85
|
+
statusCode = statusCode ? Number(statusCode) : undefined
|
|
92
86
|
|
|
93
87
|
return { error, statusCode }
|
|
94
88
|
}
|
|
@@ -100,25 +94,25 @@ const _isAllowedError = errorCode => {
|
|
|
100
94
|
// - for one unique value, we use it
|
|
101
95
|
// - if at least one 5xx exists, we use 500
|
|
102
96
|
// - else if at least one 4xx exists, we use 400
|
|
103
|
-
// - else we use 500
|
|
104
97
|
const _statusCodeFromDetails = uniqueStatusCodes => {
|
|
105
98
|
if (uniqueStatusCodes.size === 1) return uniqueStatusCodes.values().next().value
|
|
106
99
|
if ([...uniqueStatusCodes].some(s => s >= 500)) return 500
|
|
107
100
|
if ([...uniqueStatusCodes].some(s => s >= 400)) return 400
|
|
108
|
-
return 500
|
|
109
101
|
}
|
|
110
102
|
|
|
111
103
|
const normalizeError = (err, req) => {
|
|
112
104
|
const locale = req.locale || (req.locale = localeFrom(req))
|
|
113
|
-
|
|
105
|
+
let { error, statusCode } = _normalize(err, locale)
|
|
114
106
|
|
|
115
|
-
|
|
116
|
-
// error[SKIP_SANITIZATION] is not an official API!!!
|
|
117
|
-
if (statusCode >= 500 && process.env.NODE_ENV === 'production' && !error[SKIP_SANITIZATION]) {
|
|
107
|
+
if ((!statusCode || (statusCode >= 500 && err._thrownByFramework)) && process.env.NODE_ENV === 'production') {
|
|
118
108
|
// > return sanitized error to client
|
|
119
|
-
return {
|
|
109
|
+
return {
|
|
110
|
+
error: { code: statusCode ? `${statusCode}` : '500', message: i18n(statusCode || 500, locale) },
|
|
111
|
+
statusCode: Number(statusCode) || 500
|
|
112
|
+
}
|
|
120
113
|
}
|
|
121
|
-
|
|
114
|
+
|
|
115
|
+
if (!statusCode) statusCode = 500
|
|
122
116
|
|
|
123
117
|
// no top level null codes
|
|
124
118
|
if (error.code === 'null') {
|