@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
|
@@ -3,12 +3,14 @@ const waitingTime = require('../common-utils/waitingTime')
|
|
|
3
3
|
const OutboxRunner = require('./OutboxRunner')
|
|
4
4
|
const { isStandardError } = require('../../common/error/standardError')
|
|
5
5
|
const LOG = cds.log('persistent-outbox')
|
|
6
|
+
const util = require('util')
|
|
6
7
|
const _safeJSONParse = string => {
|
|
7
8
|
try {
|
|
8
9
|
return string && JSON.parse(string)
|
|
9
|
-
} catch (
|
|
10
|
+
} catch (_e) {
|
|
11
|
+
// Don't throw
|
|
12
|
+
}
|
|
10
13
|
}
|
|
11
|
-
|
|
12
14
|
const outboxRunner = new OutboxRunner()
|
|
13
15
|
const cdsUser = 'cds.internal.user'
|
|
14
16
|
const messageProcessorRegistered = Symbol('message processor registered')
|
|
@@ -30,7 +32,7 @@ const hasPersistentOutbox = (srv, tenant) => {
|
|
|
30
32
|
if (!cds.requires.outbox || cds.requires.outbox.kind !== 'persistent-outbox') return false
|
|
31
33
|
if (srv.options && srv.options.outbox && srv.options.outbox.kind && srv.options.outbox.kind !== 'persistent-outbox')
|
|
32
34
|
return false
|
|
33
|
-
if (cds.
|
|
35
|
+
if (cds.mtx && tenant && _isProviderTenant(tenant)) return false // no persistence for provider account
|
|
34
36
|
return true
|
|
35
37
|
}
|
|
36
38
|
|
|
@@ -42,9 +44,9 @@ const isUnrecoverable = (service, error) => {
|
|
|
42
44
|
|
|
43
45
|
const _processSingleMessage = async (service, message, succeededMessages) => {
|
|
44
46
|
const msg = _safeJSONParse(message.msg)
|
|
47
|
+
if (!msg) return
|
|
45
48
|
const userId = msg[cdsUser]
|
|
46
49
|
delete msg[cdsUser]
|
|
47
|
-
if (!msg) return message.ID
|
|
48
50
|
// Promise resolve is necessary because we want to set `cds.context` only
|
|
49
51
|
// inside this call
|
|
50
52
|
return Promise.resolve().then(async () => {
|
|
@@ -128,9 +130,13 @@ const processMessages = async (service, tenant, _opts = {}) => {
|
|
|
128
130
|
const info = { service: name, event: error.failedMessage.event }
|
|
129
131
|
if (error.failedMessage.attempts > 0) info.cause = error.failedMessage.error
|
|
130
132
|
LOG.error('Emit failed', info, `Retrying in ${Math.round(_waitingTime / 1000)} s`)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
const data = {
|
|
134
|
+
attempts: { '+=': 1 }
|
|
135
|
+
}
|
|
136
|
+
if (opts.storeLastError) {
|
|
137
|
+
data.lastError = util.inspect(error.failedMessage.error)
|
|
138
|
+
}
|
|
139
|
+
await UPDATE(messagesEntity).where({ ID: error.failedMessage.ID }).set(data)
|
|
134
140
|
outboxRunner.schedule(
|
|
135
141
|
{
|
|
136
142
|
name,
|
|
@@ -2,6 +2,8 @@ const cds = require('../cds')
|
|
|
2
2
|
const queued = require('./common-utils/queued')
|
|
3
3
|
const OutboxService = require('./Outbox')
|
|
4
4
|
|
|
5
|
+
const appId = require('./common-utils/appId')
|
|
6
|
+
|
|
5
7
|
const _topic = declared => declared['@topic'] || declared.name
|
|
6
8
|
|
|
7
9
|
let usedTopicOnce = false
|
|
@@ -93,6 +95,7 @@ class MessagingService extends OutboxService {
|
|
|
93
95
|
let res = topic
|
|
94
96
|
if (!_inbound && this.options.publishPrefix) res = this.options.publishPrefix + res
|
|
95
97
|
if (_inbound && this.options.subscribePrefix) res = this.options.subscribePrefix + res
|
|
98
|
+
res = res.replace(/\$appId/g, appId())
|
|
96
99
|
return res
|
|
97
100
|
}
|
|
98
101
|
|
|
@@ -111,7 +114,7 @@ class MessagingService extends OutboxService {
|
|
|
111
114
|
const _msg = { ...msg }
|
|
112
115
|
if (msg.inbound && !cds.context) {
|
|
113
116
|
// REVISIT: why are all inbound messages executed with privileged user?
|
|
114
|
-
cds.context = { tenant: msg.tenant, user:
|
|
117
|
+
cds.context = { tenant: msg.tenant, user: cds.User.privileged }
|
|
115
118
|
}
|
|
116
119
|
_msg.event = _warnAndStripTopicPrefix(_msg.event, this.LOG)
|
|
117
120
|
if (!_msg.headers) _msg.headers = {}
|
|
@@ -17,6 +17,7 @@ const { resolveView, getTransition, restoreLink, findQueryTarget } = require('..
|
|
|
17
17
|
const { postProcess } = require('../common/utils/postProcessing')
|
|
18
18
|
const { getKind, run, getDestination, getAdditionalOptions, getReqOptions } = require('./utils/client')
|
|
19
19
|
const { formatVal } = require('../../odata/utils')
|
|
20
|
+
const { hasAliasedColumns } = require('./utils/data')
|
|
20
21
|
|
|
21
22
|
const _isSimpleCqnQuery = q => typeof q === 'object' && q !== null && !Array.isArray(q) && Object.keys(q).length > 0
|
|
22
23
|
|
|
@@ -108,10 +109,16 @@ const _handleUnboundActionFunction = (srv, def, req, event) => {
|
|
|
108
109
|
return srv.get(url)
|
|
109
110
|
}
|
|
110
111
|
|
|
112
|
+
const _sendV2RequestActionFunction = (srv, def, url) => {
|
|
113
|
+
return def.kind === 'function'
|
|
114
|
+
? srv.send({ method: 'GET', path: url, _returnType: def.returns })
|
|
115
|
+
: srv.send({ method: 'POST', path: url, data: {}, _returnType: def.returns })
|
|
116
|
+
}
|
|
117
|
+
|
|
111
118
|
const _handleV2ActionFunction = (srv, def, req, event, kind) => {
|
|
112
119
|
const url =
|
|
113
120
|
Object.keys(req.data).length > 0 ? _buildPartialUrlFunctions(`/${event}`, req.data, def.params, kind) : `/${event}`
|
|
114
|
-
return
|
|
121
|
+
return _sendV2RequestActionFunction(srv, def, url)
|
|
115
122
|
}
|
|
116
123
|
|
|
117
124
|
const _handleV2BoundActionFunction = (srv, def, req, event, kind) => {
|
|
@@ -128,7 +135,7 @@ const _handleV2BoundActionFunction = (srv, def, req, event, kind) => {
|
|
|
128
135
|
params.push(...keys)
|
|
129
136
|
}
|
|
130
137
|
const url = `${`/${event}`}?${params.join('&')}`
|
|
131
|
-
return
|
|
138
|
+
return _sendV2RequestActionFunction(srv, def, url)
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
const _addHandlerActionFunction = (srv, def, target) => {
|
|
@@ -150,7 +157,7 @@ const _addHandlerActionFunction = (srv, def, target) => {
|
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
const _selectOnlyWithAlias = q => {
|
|
153
|
-
return q && q.SELECT && !q.SELECT._transitions && q.SELECT.columns && q.SELECT.columns.some(
|
|
160
|
+
return q && q.SELECT && !q.SELECT._transitions && q.SELECT.columns && q.SELECT.columns.some(hasAliasedColumns)
|
|
154
161
|
}
|
|
155
162
|
|
|
156
163
|
const resolvedTargetOfQuery = q => {
|
|
@@ -190,20 +197,19 @@ class RemoteService extends cds.Service {
|
|
|
190
197
|
}
|
|
191
198
|
|
|
192
199
|
this.on('*', async (req, next) => {
|
|
193
|
-
|
|
200
|
+
const { query } = req
|
|
194
201
|
if (!query && !(typeof req.path === 'string')) return next()
|
|
195
|
-
if (cds.env.features.resolve_views === false && typeof query === 'object' && this.model) {
|
|
196
|
-
query = resolveView(query, this.model, this)
|
|
197
|
-
}
|
|
198
202
|
|
|
199
203
|
const resolvedTarget = resolvedTargetOfQuery(query) || getTransition(req.target, this).target
|
|
200
204
|
const reqOptions = getReqOptions(req, query, this)
|
|
201
205
|
reqOptions.headers = _setHeaders(reqOptions.headers, req)
|
|
206
|
+
const returnType = req._returnType
|
|
202
207
|
const additionalOptions = getAdditionalOptions(
|
|
203
208
|
req,
|
|
204
209
|
this.destination,
|
|
205
210
|
this.kind,
|
|
206
211
|
resolvedTarget,
|
|
212
|
+
returnType,
|
|
207
213
|
this.destinationOptions
|
|
208
214
|
)
|
|
209
215
|
|
|
@@ -217,7 +223,7 @@ class RemoteService extends cds.Service {
|
|
|
217
223
|
result =
|
|
218
224
|
typeof query === 'object' && query.SELECT && query.SELECT.one && Array.isArray(result) ? result[0] : result
|
|
219
225
|
|
|
220
|
-
return
|
|
226
|
+
return result
|
|
221
227
|
})
|
|
222
228
|
}
|
|
223
229
|
|
|
@@ -226,15 +232,15 @@ class RemoteService extends cds.Service {
|
|
|
226
232
|
// - because of that tests/_runtime/remote/__tests__/integration/odata.test.js fails, which relies on the former behavoir of RemoteServices
|
|
227
233
|
// NOTE: that test would never have worked for RemoteServices bootstrapped from single cds.model, which is always cds.compiled.for.odata
|
|
228
234
|
// REVISIT: should become obsolete with Universal CSN
|
|
229
|
-
set model(m) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
235
|
+
// set model(m) {
|
|
236
|
+
// const fn = cds.compile.for.odata
|
|
237
|
+
// try {
|
|
238
|
+
// cds.compile.for.odata = m => m
|
|
239
|
+
// super.model = m
|
|
240
|
+
// } finally {
|
|
241
|
+
// cds.compile.for.odata = fn
|
|
242
|
+
// }
|
|
243
|
+
// }
|
|
238
244
|
|
|
239
245
|
// Overload .handle in order to resolve projections up to a definition that is known by the remote service instance.
|
|
240
246
|
// Result is post processed according to the inverse projection in order to reflect the correct result of the original query.
|
|
@@ -262,7 +268,7 @@ class RemoteService extends cds.Service {
|
|
|
262
268
|
restoreLink(req)
|
|
263
269
|
|
|
264
270
|
// REVISIT: We need to provide target explicitly because it's cached already within ensure_target
|
|
265
|
-
const newReq = new cds.Request({ query: q, target: t, headers: req.headers, _resolved: true })
|
|
271
|
+
const newReq = new cds.Request({ query: q, target: t, headers: req.headers, _resolved: true, method: req.method })
|
|
266
272
|
const result = await super.dispatch(newReq)
|
|
267
273
|
|
|
268
274
|
return postProcess(q, result, this, true)
|
|
@@ -5,7 +5,7 @@ const SANITIZE_VALUES = process.env.NODE_ENV === 'production' && cds.env.log.san
|
|
|
5
5
|
|
|
6
6
|
const { convertV2ResponseData, deepSanitize, convertV2PayloadData } = require('./data')
|
|
7
7
|
|
|
8
|
-
let
|
|
8
|
+
let _cloudSdk
|
|
9
9
|
|
|
10
10
|
const PPPD = {
|
|
11
11
|
POST: 1,
|
|
@@ -23,12 +23,11 @@ const _sanitizeHeaders = headers => {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const _executeHttpRequest = async ({ requestConfig, destination, destinationOptions, jwt }) => {
|
|
26
|
-
const {
|
|
26
|
+
const { executeHttpRequestWithOrigin } = cloudSdk()
|
|
27
27
|
|
|
28
28
|
const destinationName = typeof destination === 'string' && destination
|
|
29
29
|
if (destinationName) {
|
|
30
|
-
destination =
|
|
31
|
-
if (!destination) throw new Error(`Cannot resolve destination "${destinationName}"`)
|
|
30
|
+
destination = { destinationName, ...(resolveDestinationOptions(destinationOptions, jwt) || {}) }
|
|
32
31
|
} else if (destination.forwardAuthToken) {
|
|
33
32
|
destination = {
|
|
34
33
|
...destination,
|
|
@@ -44,20 +43,31 @@ const _executeHttpRequest = async ({ requestConfig, destination, destinationOpti
|
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
let requestOptions
|
|
47
|
-
if (PPPD[requestConfig.method]
|
|
48
|
-
|
|
46
|
+
if (PPPD[requestConfig.method]) {
|
|
47
|
+
// For GET requests, one doesn't need to fetch CSRF tokens.
|
|
48
|
+
// Once we support batch requests (other than autoBatched GET requests),
|
|
49
|
+
// we must check the respective subrequests.
|
|
50
|
+
const csrfRequired = requestConfig._autoBatch ? false : cds.env.features.fetch_csrf === true
|
|
51
|
+
requestOptions = { fetchCsrfToken: csrfRequired }
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
LOG._debug &&
|
|
52
|
-
LOG.debug(`${requestConfig.method} ${destination.url}${requestConfig.url}`, {
|
|
55
|
+
LOG.debug(`${requestConfig.method} ${destination.url || `<${destination.destinationName}>`}${requestConfig.url}`, {
|
|
53
56
|
headers: _sanitizeHeaders({ ...requestConfig.headers }),
|
|
54
57
|
data: requestConfig.data && SANITIZE_VALUES ? deepSanitize(requestConfig.data) : requestConfig.data
|
|
55
58
|
})
|
|
56
|
-
|
|
59
|
+
|
|
60
|
+
// cloud sdk requires a new mechanism to differentiate the priority of headers
|
|
61
|
+
// "custom" keeps the highest priority as before
|
|
62
|
+
requestConfig = { ...requestConfig, headers: { custom: { ...requestConfig.headers } } }
|
|
63
|
+
|
|
64
|
+
return executeHttpRequestWithOrigin(destination, requestConfig, requestOptions)
|
|
57
65
|
}
|
|
58
66
|
|
|
59
|
-
const
|
|
60
|
-
|
|
67
|
+
const cloudSdk = () => {
|
|
68
|
+
if (_cloudSdk) return _cloudSdk
|
|
69
|
+
_cloudSdk = require('@sap-cloud-sdk/http-client')
|
|
70
|
+
return _cloudSdk
|
|
61
71
|
}
|
|
62
72
|
|
|
63
73
|
const getDestination = (name, credentials) => {
|
|
@@ -74,20 +84,18 @@ const getDestination = (name, credentials) => {
|
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
/**
|
|
77
|
-
* @param {import('
|
|
87
|
+
* @param {import('@sap-cloud-sdk/connectivity').DestinationFetchOptions} [options]
|
|
78
88
|
* @param {string} [jwt]
|
|
79
|
-
* @returns {import('@sap-cloud-sdk/
|
|
89
|
+
* @returns {import('@sap-cloud-sdk/connectivity').DestinationFetchOptions}
|
|
80
90
|
*/
|
|
81
91
|
const resolveDestinationOptions = function (options, jwt) {
|
|
82
92
|
if (!options && !jwt) return undefined
|
|
83
93
|
|
|
84
94
|
const resolvedOptions = Object.assign({}, options || {})
|
|
85
|
-
resolvedOptions.
|
|
95
|
+
resolvedOptions.jwt = jwt
|
|
86
96
|
|
|
87
97
|
if (options && options.selectionStrategy) {
|
|
88
|
-
resolvedOptions.selectionStrategy =
|
|
89
|
-
if (!resolvedOptions.selectionStrategy)
|
|
90
|
-
throw new Error(`Unsupported destination selection strategy "${options.selectionStrategy}".`)
|
|
98
|
+
resolvedOptions.selectionStrategy = options.selectionStrategy
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
return resolvedOptions
|
|
@@ -165,15 +173,31 @@ function _normalizeMetadata(prefix, data, results) {
|
|
|
165
173
|
}
|
|
166
174
|
return target
|
|
167
175
|
}
|
|
176
|
+
const _getPurgedRespActionFunc = (data, returnType) => {
|
|
177
|
+
// return type is primitive value or inline/complex type
|
|
178
|
+
if (returnType.kind === 'type' && !returnType.items && Object.values(data).length === 1) {
|
|
179
|
+
// eslint-disable-next-line no-unreachable-loop
|
|
180
|
+
for (const key in data) {
|
|
181
|
+
return data[key]
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return data
|
|
185
|
+
}
|
|
168
186
|
|
|
169
|
-
const _purgeODataV2 = (data, target, reqHeaders) => {
|
|
187
|
+
const _purgeODataV2 = (data, target, returnType, reqHeaders) => {
|
|
170
188
|
if (typeof data !== 'object' || !data.d) return data
|
|
171
189
|
|
|
172
|
-
data = data.d
|
|
190
|
+
data = returnType ? _getPurgedRespActionFunc(data.d, returnType) : data.d
|
|
173
191
|
const ieee754Compatible = reqHeaders.accept && reqHeaders.accept.includes('IEEE754Compatible=true')
|
|
174
192
|
const exponentialDecimals = ieee754Compatible && reqHeaders.accept.includes('ExponentialDecimals=true')
|
|
175
|
-
const purgedResponse = 'results' in data ? data.results : data
|
|
176
|
-
const convertedResponse = convertV2ResponseData(
|
|
193
|
+
const purgedResponse = typeof data === 'object' && 'results' in data ? data.results : data
|
|
194
|
+
const convertedResponse = convertV2ResponseData(
|
|
195
|
+
purgedResponse,
|
|
196
|
+
target,
|
|
197
|
+
returnType,
|
|
198
|
+
ieee754Compatible,
|
|
199
|
+
exponentialDecimals
|
|
200
|
+
)
|
|
177
201
|
return _normalizeMetadata(/^__/, data, convertedResponse)
|
|
178
202
|
}
|
|
179
203
|
|
|
@@ -187,12 +211,15 @@ const _purgeODataV4 = data => {
|
|
|
187
211
|
const TYPES_TO_REMOVE = { function: 1, object: 1 }
|
|
188
212
|
const PROPS_TO_IGNORE = { cause: 1, name: 1 }
|
|
189
213
|
|
|
190
|
-
const _getSanitizedError = (e, reqOptions, suppressRemoteResponseBody) => {
|
|
214
|
+
const _getSanitizedError = (e, reqOptions, options = { suppressRemoteResponseBody: false, batchRequest: false }) => {
|
|
191
215
|
e.request = {
|
|
192
216
|
method: reqOptions.method,
|
|
193
217
|
url: e.config ? e.config.baseURL + e.config.url : reqOptions.url,
|
|
194
218
|
headers: e.config ? e.config.headers : reqOptions.headers
|
|
195
219
|
}
|
|
220
|
+
if (options.batchRequest) {
|
|
221
|
+
e.request.body = reqOptions.data
|
|
222
|
+
}
|
|
196
223
|
|
|
197
224
|
if (e.response) {
|
|
198
225
|
const response = {
|
|
@@ -200,7 +227,7 @@ const _getSanitizedError = (e, reqOptions, suppressRemoteResponseBody) => {
|
|
|
200
227
|
statusText: e.response.statusText,
|
|
201
228
|
headers: e.response.headers
|
|
202
229
|
}
|
|
203
|
-
if (e.response.data && !suppressRemoteResponseBody) {
|
|
230
|
+
if (e.response.data && !options.suppressRemoteResponseBody) {
|
|
204
231
|
response.body = e.response.data
|
|
205
232
|
}
|
|
206
233
|
e.response = response
|
|
@@ -236,19 +263,26 @@ const _getSanitizedError = (e, reqOptions, suppressRemoteResponseBody) => {
|
|
|
236
263
|
// eslint-disable-next-line complexity
|
|
237
264
|
const run = async (
|
|
238
265
|
requestConfig,
|
|
239
|
-
{ destination, jwt, kind, resolvedTarget, suppressRemoteResponseBody, destinationOptions }
|
|
266
|
+
{ destination, jwt, kind, resolvedTarget, returnType, suppressRemoteResponseBody, destinationOptions }
|
|
240
267
|
) => {
|
|
241
268
|
let response
|
|
242
269
|
try {
|
|
243
270
|
response = await _executeHttpRequest({ requestConfig, destination, destinationOptions, jwt })
|
|
244
271
|
} catch (e) {
|
|
245
272
|
// > axios received status >= 400 -> gateway error
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
273
|
+
const msg =
|
|
274
|
+
(e.response &&
|
|
275
|
+
e.response.data &&
|
|
276
|
+
e.response.data.error &&
|
|
277
|
+
((e.response.data.error.message && e.response.data.error.message.value) || e.response.data.error.message)) ||
|
|
278
|
+
e.message
|
|
279
|
+
e.message = msg ? 'Error during request to remote service: \n' + msg : 'Request to remote service failed.'
|
|
280
|
+
|
|
281
|
+
const sanitizedError = _getSanitizedError(e, requestConfig, {
|
|
282
|
+
suppressRemoteResponseBody: suppressRemoteResponseBody
|
|
283
|
+
})
|
|
249
284
|
|
|
250
|
-
|
|
251
|
-
const err = Object.assign(new Error(e.message), { statusCode: 502, innererror: sanitizedError })
|
|
285
|
+
const err = Object.assign(new Error(e.message), { statusCode: 502, reason: sanitizedError })
|
|
252
286
|
LOG._warn && LOG.warn(err)
|
|
253
287
|
|
|
254
288
|
throw err
|
|
@@ -268,12 +302,13 @@ const run = async (
|
|
|
268
302
|
const e = new Error("Received content-type 'text/html' which is not part of accepted content types")
|
|
269
303
|
e.response = response
|
|
270
304
|
|
|
271
|
-
const sanitizedError = _getSanitizedError(e, requestConfig,
|
|
305
|
+
const sanitizedError = _getSanitizedError(e, requestConfig, {
|
|
306
|
+
suppressRemoteResponseBody: suppressRemoteResponseBody
|
|
307
|
+
})
|
|
272
308
|
|
|
273
|
-
// REVISIT: switch from innererror to reason in cds^6
|
|
274
309
|
const err = Object.assign(new Error(`Error during request to remote service: ${e.message}`), {
|
|
275
310
|
statusCode: 502,
|
|
276
|
-
|
|
311
|
+
reason: sanitizedError
|
|
277
312
|
})
|
|
278
313
|
|
|
279
314
|
LOG._warn && LOG.warn(err)
|
|
@@ -297,27 +332,28 @@ const run = async (
|
|
|
297
332
|
response.data = contentJSON
|
|
298
333
|
}
|
|
299
334
|
if (responseDataSplitted[1].startsWith('HTTP/1.1 4') || responseDataSplitted[1].startsWith('HTTP/1.1 5')) {
|
|
300
|
-
contentJSON.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
const sanitizedError = _getSanitizedError(
|
|
304
|
-
|
|
305
|
-
|
|
335
|
+
const innerError = contentJSON.error || contentJSON
|
|
336
|
+
innerError.status = Number(responseDataSplitted[1].match(/HTTP.*(\d{3})/m)[1])
|
|
337
|
+
innerError.response = response
|
|
338
|
+
const sanitizedError = _getSanitizedError(innerError, requestConfig, { batchRequest: true })
|
|
339
|
+
const err = Object.assign(new Error('Request to remote service failed.'), {
|
|
340
|
+
statusCode: 502,
|
|
341
|
+
reason: sanitizedError
|
|
342
|
+
})
|
|
306
343
|
|
|
307
344
|
LOG._warn && LOG.warn(err)
|
|
308
345
|
|
|
309
|
-
// REVISIT: switch from innererror to reason in cds^6
|
|
310
346
|
throw err
|
|
311
347
|
}
|
|
312
348
|
}
|
|
313
349
|
|
|
314
350
|
if (kind === 'odata-v4') return _purgeODataV4(response.data)
|
|
315
|
-
if (kind === 'odata-v2') return _purgeODataV2(response.data, resolvedTarget, requestConfig.headers)
|
|
351
|
+
if (kind === 'odata-v2') return _purgeODataV2(response.data, resolvedTarget, returnType, requestConfig.headers)
|
|
316
352
|
if (kind === 'odata') {
|
|
317
353
|
if (typeof response.data !== 'object') return response.data
|
|
318
354
|
// try to guess if we need to purge v2 or v4
|
|
319
355
|
if (response.data.d) {
|
|
320
|
-
return _purgeODataV2(response.data, resolvedTarget, requestConfig.headers)
|
|
356
|
+
return _purgeODataV2(response.data, resolvedTarget, returnType, requestConfig.headers)
|
|
321
357
|
}
|
|
322
358
|
return _purgeODataV4(response.data)
|
|
323
359
|
}
|
|
@@ -335,8 +371,10 @@ const getJwt = req => {
|
|
|
335
371
|
return null
|
|
336
372
|
}
|
|
337
373
|
|
|
338
|
-
const _cqnToReqOptions = (query,
|
|
339
|
-
const
|
|
374
|
+
const _cqnToReqOptions = (query, service, req) => {
|
|
375
|
+
const { kind, model } = service
|
|
376
|
+
const method = req.method
|
|
377
|
+
const queryObject = cds.odata.urlify(query, { kind, model, method })
|
|
340
378
|
const reqOptions = {
|
|
341
379
|
method: queryObject.method,
|
|
342
380
|
url: queryObject.path
|
|
@@ -345,7 +383,7 @@ const _cqnToReqOptions = (query, kind, model, target) => {
|
|
|
345
383
|
.replace(/ \)/g, ')')
|
|
346
384
|
}
|
|
347
385
|
if (queryObject.method !== 'GET' && queryObject.method !== 'HEAD') {
|
|
348
|
-
reqOptions.data = kind === 'odata-v2' ? convertV2PayloadData(queryObject.body, target) : queryObject.body
|
|
386
|
+
reqOptions.data = kind === 'odata-v2' ? convertV2PayloadData(queryObject.body, req.target) : queryObject.body
|
|
349
387
|
}
|
|
350
388
|
return reqOptions
|
|
351
389
|
}
|
|
@@ -390,7 +428,7 @@ const _hasHeader = (headers, header) =>
|
|
|
390
428
|
const getReqOptions = (req, query, service) => {
|
|
391
429
|
const reqOptions =
|
|
392
430
|
typeof query === 'object'
|
|
393
|
-
? _cqnToReqOptions(query, service
|
|
431
|
+
? _cqnToReqOptions(query, service, req)
|
|
394
432
|
: typeof query === 'string'
|
|
395
433
|
? _stringToReqOptions(query, req.data, req.target)
|
|
396
434
|
: _pathToReqOptions(req.method, req.path, req.data, req.target)
|
|
@@ -450,9 +488,9 @@ const getReqOptions = (req, query, service) => {
|
|
|
450
488
|
return reqOptions
|
|
451
489
|
}
|
|
452
490
|
|
|
453
|
-
const getAdditionalOptions = (req, destination, kind, resolvedTarget, destinationOptions) => {
|
|
491
|
+
const getAdditionalOptions = (req, destination, kind, resolvedTarget, returnType, destinationOptions) => {
|
|
454
492
|
const jwt = getJwt(req)
|
|
455
|
-
const additionalOptions = { destination, kind, resolvedTarget, destinationOptions }
|
|
493
|
+
const additionalOptions = { destination, kind, resolvedTarget, returnType, destinationOptions }
|
|
456
494
|
if (jwt) additionalOptions.jwt = jwt
|
|
457
495
|
return additionalOptions
|
|
458
496
|
}
|
|
@@ -22,8 +22,10 @@ const DataTypeOData = {
|
|
|
22
22
|
Time: 'cds.TimeOfDay'
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const _convertData = (data, target, convertValueFn) => {
|
|
26
|
-
const _convertRecordFn =
|
|
25
|
+
const _convertData = (data, target, convertValueFn, returnType) => {
|
|
26
|
+
const _convertRecordFn = returnType
|
|
27
|
+
? _convertActionFuncResponse(returnType, convertValueFn)
|
|
28
|
+
: _getConvertRecordFn(target, convertValueFn)
|
|
27
29
|
if (Array.isArray(data)) {
|
|
28
30
|
return data.map(_convertRecordFn)
|
|
29
31
|
}
|
|
@@ -52,6 +54,16 @@ const _getConvertRecordFn = (target, convertValueFn) => record => {
|
|
|
52
54
|
return record
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
const _convertActionFuncResponse = (returnType, convertValueFn) => data => {
|
|
58
|
+
// return type is entity/complex type or array of entities/complex types
|
|
59
|
+
if (returnType.elements || (returnType.items && returnType.items.elements)) {
|
|
60
|
+
const _convertRecordFn = _getConvertRecordFn(returnType.items || returnType, convertValueFn)
|
|
61
|
+
return _convertRecordFn(data)
|
|
62
|
+
}
|
|
63
|
+
// return type is primitive type/array of primitive types
|
|
64
|
+
return convertValueFn(data, returnType.items || returnType)
|
|
65
|
+
}
|
|
66
|
+
|
|
55
67
|
// eslint-disable-next-line complexity
|
|
56
68
|
const _convertValue = (ieee754Compatible, exponentialDecimals) => (value, element) => {
|
|
57
69
|
if (value == null) {
|
|
@@ -151,9 +163,9 @@ const _elementType = element => {
|
|
|
151
163
|
return type
|
|
152
164
|
}
|
|
153
165
|
|
|
154
|
-
const convertV2ResponseData = (data, target, ieee754Compatible, exponentialDecimals) => {
|
|
155
|
-
if (!target
|
|
156
|
-
return _convertData(data, target, _convertValue(ieee754Compatible, exponentialDecimals))
|
|
166
|
+
const convertV2ResponseData = (data, target, returnType, ieee754Compatible, exponentialDecimals) => {
|
|
167
|
+
if (!((target && target.elements) || returnType)) return data
|
|
168
|
+
return _convertData(data, target, _convertValue(ieee754Compatible, exponentialDecimals), returnType)
|
|
157
169
|
}
|
|
158
170
|
|
|
159
171
|
const convertV2PayloadData = (data, target) => {
|
|
@@ -171,8 +183,13 @@ const deepSanitize = arg => {
|
|
|
171
183
|
return '***'
|
|
172
184
|
}
|
|
173
185
|
|
|
186
|
+
const hasAliasedColumns = (column = {}) => {
|
|
187
|
+
return column.as || (column.expand && column.expand.some(hasAliasedColumns))
|
|
188
|
+
}
|
|
189
|
+
|
|
174
190
|
module.exports = {
|
|
175
191
|
convertV2ResponseData,
|
|
176
192
|
convertV2PayloadData,
|
|
177
|
-
deepSanitize
|
|
193
|
+
deepSanitize,
|
|
194
|
+
hasAliasedColumns
|
|
178
195
|
}
|
|
@@ -99,33 +99,34 @@ module.exports = class SQLiteDatabase extends DatabaseService {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
getDbUrl(tenant) {
|
|
103
|
+
const credentials = this.options.credentials || this.options || {}
|
|
104
|
+
let dbUrl = credentials.database || credentials.url || credentials.host || ':memory:'
|
|
105
|
+
|
|
106
|
+
if (tenant && dbUrl.endsWith('.db')) {
|
|
107
|
+
dbUrl = dbUrl.split('.db')[0] + '_' + tenant + '.db'
|
|
108
|
+
}
|
|
109
|
+
return dbUrl
|
|
110
|
+
}
|
|
111
|
+
|
|
102
112
|
/*
|
|
103
113
|
* connection
|
|
104
114
|
*/
|
|
105
115
|
async acquire(arg) {
|
|
106
116
|
// in non-multi-tenant scenarios, the default db should be returned regardless of arg
|
|
107
|
-
let tenant = 'anonymous'
|
|
108
117
|
const isMultitenant = 'multiTenant' in this.options ? this.options.multiTenant : cds.env.requires.multitenancy
|
|
109
118
|
// REVISIT: there should already be compat for the multitenancy flag, why is it not working here?
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
else tenant = arg.tenant || (arg.user && arg.user.tenant) || tenant // > REVISIT: remove fallback arg.user.tenant with cds^6
|
|
113
|
-
}
|
|
114
|
-
|
|
119
|
+
// REVISIT: remove fallback arg.user.tenant with cds^6
|
|
120
|
+
const tenant = isMultitenant && arg && (typeof arg === 'string' ? arg : arg.tenant || (arg.user && arg.user.tenant))
|
|
115
121
|
let dbc = this.dbcs.get(tenant)
|
|
116
122
|
if (!dbc) {
|
|
117
|
-
const
|
|
118
|
-
let dbUrl = credentials.database || credentials.url || credentials.host || ':memory:'
|
|
119
|
-
|
|
120
|
-
if (isMultitenant && dbUrl.endsWith('.db')) {
|
|
121
|
-
dbUrl = dbUrl.split('.db')[0] + '_' + tenant + '.db'
|
|
122
|
-
}
|
|
123
|
+
const dbUrl = this.getDbUrl(tenant)
|
|
123
124
|
|
|
124
125
|
dbc = await _new(dbUrl)
|
|
125
126
|
|
|
126
127
|
dbc._queued = []
|
|
127
128
|
|
|
128
|
-
if (cds.env.features.
|
|
129
|
+
if (cds.env.features.assert_integrity && cds.env.features.assert_integrity_type == 'DB') {
|
|
129
130
|
await new Promise((resolve, reject) => {
|
|
130
131
|
dbc.exec('PRAGMA foreign_keys = ON', err => {
|
|
131
132
|
if (err) reject(err)
|
|
@@ -28,8 +28,10 @@ const _convert = (refEntries, req) => {
|
|
|
28
28
|
// only check refs in format {ref: ['assoc', 'id']}
|
|
29
29
|
continue
|
|
30
30
|
}
|
|
31
|
+
|
|
31
32
|
const element = req.target.elements[refEntry.ref[0]]
|
|
32
33
|
if (!element || !element.is2one) return
|
|
34
|
+
|
|
33
35
|
_convertRefForAssocToOneManaged(element, refEntry)
|
|
34
36
|
}
|
|
35
37
|
}
|
|
@@ -8,6 +8,7 @@ const { Readable } = require('stream')
|
|
|
8
8
|
const cds = require('../cds')
|
|
9
9
|
const LOG = cds.log('sqlite|db|sql')
|
|
10
10
|
// && {_debug:true, debug(sql){ cds._debug && console.log(sql+';\n') }} //> please keep that for debugging stakeholder tests
|
|
11
|
+
const coloredTxCommands = require('../db/utils/coloredTxCommands')
|
|
11
12
|
const { inspect } = require('util')
|
|
12
13
|
|
|
13
14
|
const SANITIZE_VALUES = process.env.NODE_ENV === 'production' && cds.env.log.sanitize_values !== false
|
|
@@ -26,14 +27,6 @@ const _captureStack = DEBUG
|
|
|
26
27
|
}
|
|
27
28
|
: () => undefined
|
|
28
29
|
|
|
29
|
-
/*
|
|
30
|
-
* helpers
|
|
31
|
-
*/
|
|
32
|
-
const _colored = {
|
|
33
|
-
BEGIN: '\x1b[1m\x1b[33mBEGIN\x1b[0m',
|
|
34
|
-
COMMIT: '\x1b[1m\x1b[32mCOMMIT\x1b[0m',
|
|
35
|
-
ROLLBACK: '\x1b[1m\x1b[91mROLLBACK\x1b[0m'
|
|
36
|
-
}
|
|
37
30
|
const _augmented = (err, sql, values, o) => {
|
|
38
31
|
err.query = sql
|
|
39
32
|
if (values) err.values = SANITIZE_VALUES ? ['***'] : values
|
|
@@ -43,7 +36,8 @@ const _augmented = (err, sql, values, o) => {
|
|
|
43
36
|
}
|
|
44
37
|
|
|
45
38
|
function _executeSimpleSQL(dbc, sql, values) {
|
|
46
|
-
LOG._debug &&
|
|
39
|
+
LOG._debug &&
|
|
40
|
+
LOG.debug(coloredTxCommands[sql] || sql, Array.isArray(values) ? (SANITIZE_VALUES ? ['***'] : values) : '')
|
|
47
41
|
|
|
48
42
|
return new Promise((resolve, reject) => {
|
|
49
43
|
const o = _captureStack()
|