@sap/cds 5.9.8 → 6.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +277 -20
- package/apis/services.d.ts +1 -1
- package/app/fiori/preview.js +2 -6
- package/app/index.js +3 -3
- package/bin/build/buildTaskEngine.js +17 -15
- package/bin/build/buildTaskFactory.js +29 -19
- package/bin/build/buildTaskHandler.js +27 -11
- package/bin/build/buildTaskProvider.js +2 -4
- package/bin/build/buildTaskProviderFactory.js +11 -16
- package/bin/build/constants.js +14 -6
- package/bin/build/csv-reader.js +2 -1
- package/bin/build/index.js +12 -18
- package/bin/build/provider/buildTaskHandlerEdmx.js +3 -39
- package/bin/build/provider/buildTaskHandlerFeatureToggles.js +149 -0
- package/bin/build/provider/buildTaskHandlerInternal.js +2 -3
- package/bin/build/provider/buildTaskProviderInternal.js +108 -239
- package/bin/build/provider/fiori/index.js +2 -2
- package/bin/build/provider/hana/2migration.js +11 -11
- package/bin/build/provider/hana/2tabledata.js +3 -3
- package/bin/build/provider/hana/index.js +89 -99
- package/bin/build/provider/hana/migrationtable.js +4 -3
- package/bin/build/provider/java/index.js +101 -0
- package/bin/build/provider/java-cf/index.js +1 -101
- package/bin/build/provider/mtx/index.js +83 -41
- package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
- package/bin/build/provider/mtx-sidecar/index.js +110 -0
- package/bin/build/provider/node-cf/index.js +1 -308
- package/bin/build/provider/nodejs/index.js +189 -0
- package/bin/build/util.js +21 -31
- package/bin/cds.js +5 -3
- package/bin/deploy/to-hana/cfUtil.js +31 -6
- package/bin/deploy/to-hana/gitUtil.js +5 -3
- package/bin/deploy/to-hana/hana.js +15 -13
- package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
- package/bin/mtx/in-cds.js +19 -7
- package/bin/serve.js +49 -22
- package/bin/utils/log.js +13 -30
- package/bin/version.js +4 -3
- package/common.cds +61 -16
- package/lib/compile/cdsc.js +3 -2
- package/lib/compile/etc/_localized.js +15 -14
- package/lib/compile/for/drafts.js +3 -4
- package/lib/compile/for/java.js +13 -10
- package/lib/compile/for/nodejs.js +8 -8
- package/lib/compile/for/odata.js +7 -12
- package/lib/compile/for/sql.js +5 -6
- package/lib/compile/index.js +5 -4
- package/lib/compile/load.js +9 -11
- package/lib/compile/minify.js +8 -5
- package/lib/compile/parse.js +4 -2
- package/lib/compile/resolve.js +18 -15
- package/lib/compile/to/edm.js +0 -1
- package/lib/compile/to/gql.js +3 -2
- package/lib/compile/to/json.js +24 -17
- package/lib/connect/bindings.js +3 -2
- package/lib/connect/index.js +5 -5
- package/lib/core/classes.js +74 -2
- package/lib/core/entities.js +52 -3
- package/lib/core/reflect.js +2 -1
- package/lib/deploy.js +10 -8
- package/lib/env/defaults.js +4 -3
- package/lib/env/index.js +71 -31
- package/lib/env/presets.js +1 -14
- package/lib/env/requires.js +71 -20
- package/lib/env/serviceBindings.js +147 -0
- package/lib/i18n/localize.js +22 -23
- package/lib/index.js +148 -144
- package/lib/log/errors.js +55 -12
- package/lib/log/format/kibana.js +1 -1
- package/lib/log/index.js +4 -0
- package/lib/ql/SELECT.js +7 -2
- package/lib/ql/Whereable.js +8 -2
- package/lib/ql/index.js +2 -2
- package/lib/req/assert.js +71 -0
- package/lib/req/cds-context.js +38 -70
- package/lib/req/context.js +34 -21
- package/lib/req/request.js +12 -18
- package/lib/req/response.js +6 -2
- package/lib/req/user.js +30 -22
- package/lib/serve/Service-api.js +17 -12
- package/lib/serve/Service-dispatch.js +5 -9
- package/lib/serve/Service-methods.js +4 -3
- package/lib/serve/Transaction.js +24 -21
- package/lib/serve/adapters.js +15 -5
- package/lib/serve/factory.js +22 -20
- package/lib/serve/index.js +51 -54
- package/lib/utils/axios.js +8 -12
- package/lib/utils/index.js +13 -4
- package/lib/utils/resources/index.js +1 -44
- package/lib/utils/resources/tar.js +2 -1
- package/lib/utils/tests.js +13 -15
- package/libx/_runtime/.eslintrc +1 -1
- package/libx/_runtime/audit/Service.js +6 -4
- package/libx/_runtime/audit/generic/personal/access.js +19 -43
- package/libx/_runtime/audit/generic/personal/index.js +40 -34
- package/libx/_runtime/audit/generic/personal/modification.js +11 -9
- package/libx/_runtime/audit/generic/personal/utils.js +13 -6
- package/libx/_runtime/audit/utils/v2.js +6 -3
- package/libx/_runtime/auth/index.js +71 -66
- package/libx/_runtime/auth/strategies/JWT.js +3 -2
- package/libx/_runtime/auth/strategies/mock.js +54 -53
- package/libx/_runtime/auth/strategies/xssecUtils.js +3 -4
- package/libx/_runtime/auth/strategies/xsuaa.js +3 -2
- package/libx/_runtime/auth/utils.js +2 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +127 -41
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +9 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +93 -73
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +25 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +10 -14
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +9 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +60 -53
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +21 -26
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +8 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +29 -41
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -13
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectToCQN.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +24 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityContainer.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/PrimitiveValueDecoder.js +4 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/validator/ValueValidator.js +5 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/ResponseHeaderSetter.js +2 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DebugSerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/PresetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ContextURLFactory.js +3 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ErrorJsonSerializer.js +3 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/TrustedResourceJsonSerializer.js +3 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +36 -25
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +97 -92
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +382 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +5 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +82 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +3 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +91 -69
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +27 -6
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +7 -17
- package/libx/_runtime/cds-services/services/Service.js +17 -76
- package/libx/_runtime/cds-services/services/utils/columns.js +6 -4
- package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -53
- package/libx/_runtime/cds-services/services/utils/differ.js +15 -19
- package/libx/_runtime/cds-services/util/assert.js +107 -34
- package/libx/_runtime/cds.js +1 -31
- package/libx/_runtime/common/aspects/Association.js +40 -54
- package/libx/_runtime/common/aspects/any.js +61 -6
- package/libx/_runtime/common/aspects/entity.js +19 -79
- package/libx/_runtime/common/composition/data.js +2 -2
- package/libx/_runtime/common/composition/delete.js +8 -7
- package/libx/_runtime/common/composition/tree.js +10 -10
- package/libx/_runtime/common/composition/update.js +3 -2
- package/libx/_runtime/common/constants/events.js +13 -0
- package/libx/_runtime/common/error/entry.js +9 -3
- package/libx/_runtime/common/error/frontend.js +13 -19
- package/libx/_runtime/common/error/index.js +8 -3
- package/libx/_runtime/common/generic/auth/capabilities.js +2 -1
- package/libx/_runtime/common/generic/auth/constants.js +1 -4
- package/libx/_runtime/common/generic/auth/requires.js +1 -1
- package/libx/_runtime/common/generic/auth/restrict.js +12 -28
- package/libx/_runtime/common/generic/auth/restrictions.js +12 -4
- package/libx/_runtime/common/generic/auth/utils.js +2 -1
- package/libx/_runtime/common/generic/crud.js +9 -60
- package/libx/_runtime/common/generic/etag.js +41 -7
- package/libx/_runtime/common/generic/input.js +128 -66
- package/libx/_runtime/common/generic/paging.js +9 -3
- package/libx/_runtime/common/generic/put.js +2 -2
- package/libx/_runtime/common/generic/sorting.js +7 -3
- package/libx/_runtime/common/generic/temporal.js +0 -5
- package/libx/_runtime/common/i18n/messages.properties +2 -1
- package/libx/_runtime/common/utils/binary.js +69 -0
- package/libx/_runtime/common/utils/cqn.js +39 -14
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +93 -59
- package/libx/_runtime/common/utils/csn.js +87 -85
- package/libx/_runtime/common/utils/dollar.js +8 -7
- package/libx/_runtime/common/utils/draft.js +1 -1
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +23 -7
- package/libx/_runtime/common/utils/generateOnCond.js +2 -1
- package/libx/_runtime/common/utils/keys.js +30 -13
- package/libx/_runtime/common/utils/postProcessing.js +6 -1
- package/libx/_runtime/common/utils/quotingStyles.js +0 -23
- package/libx/_runtime/common/utils/resolveStructured.js +23 -26
- package/libx/_runtime/common/utils/resolveView.js +4 -1
- package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -0
- package/libx/_runtime/common/utils/search2cqn4sql.js +4 -13
- package/libx/_runtime/common/utils/searchToLike.js +9 -13
- package/libx/_runtime/common/utils/streamProp.js +35 -0
- package/libx/_runtime/common/utils/structured.js +12 -18
- package/libx/_runtime/common/utils/template.js +3 -5
- package/libx/_runtime/common/utils/templateProcessor.js +22 -14
- package/libx/_runtime/common/utils/unionCqnTemplate.js +4 -14
- package/libx/_runtime/db/Service.js +2 -1
- package/libx/_runtime/db/expand/expand-v2.js +2 -2
- package/libx/_runtime/db/expand/expandCQNToJoin.js +7 -6
- package/libx/_runtime/db/generic/input.js +14 -17
- package/libx/_runtime/db/generic/integrity.js +1 -2
- package/libx/_runtime/db/generic/update.js +14 -1
- package/libx/_runtime/db/query/read.js +0 -1
- package/libx/_runtime/db/query/update.js +1 -1
- package/libx/_runtime/db/sql-builder/BaseBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +5 -31
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +0 -9
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +11 -10
- package/libx/_runtime/db/sql-builder/UpdateBuilder.js +2 -2
- package/libx/_runtime/db/sql-builder/annotations.js +1 -2
- package/libx/_runtime/db/utils/coloredTxCommands.js +5 -0
- package/libx/_runtime/db/utils/columns.js +1 -1
- package/libx/_runtime/db/utils/propagateForeignKeys.js +10 -2
- package/libx/_runtime/extensibility/activate.js +69 -0
- package/libx/_runtime/extensibility/add.js +41 -0
- package/libx/_runtime/extensibility/addExtension.js +68 -0
- package/libx/_runtime/extensibility/defaults.js +39 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformREAD.js +0 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformRESULT.js +2 -2
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformWRITE.js +2 -2
- package/libx/_runtime/extensibility/push.js +61 -0
- package/libx/_runtime/extensibility/service.js +21 -0
- package/libx/_runtime/extensibility/{uiflex/utils.js → utils.js} +39 -3
- package/libx/_runtime/extensibility/validation.js +53 -0
- package/libx/_runtime/extensibility/views.js +12 -0
- package/libx/_runtime/fiori/generic/activate.js +2 -4
- package/libx/_runtime/fiori/generic/before.js +17 -29
- package/libx/_runtime/fiori/generic/cancel.js +2 -4
- package/libx/_runtime/fiori/generic/delete.js +2 -4
- package/libx/_runtime/fiori/generic/edit.js +4 -16
- package/libx/_runtime/fiori/generic/index.js +31 -0
- package/libx/_runtime/fiori/generic/new.js +5 -21
- package/libx/_runtime/fiori/generic/patch.js +10 -15
- package/libx/_runtime/fiori/generic/prepare.js +13 -22
- package/libx/_runtime/fiori/generic/read.js +148 -163
- package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
- package/libx/_runtime/fiori/utils/handler.js +10 -22
- package/libx/_runtime/fiori/utils/where.js +1 -4
- package/libx/_runtime/hana/Service.js +14 -7
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +1 -1
- package/libx/_runtime/hana/dynatrace.js +2 -2
- package/libx/_runtime/hana/localized.js +7 -6
- package/libx/_runtime/hana/pool.js +9 -6
- package/libx/_runtime/hana/search.js +2 -3
- package/libx/_runtime/hana/{searchToContains.js → search2Contains.js} +5 -2
- package/libx/_runtime/hana/search2cqn4sql.js +20 -17
- package/libx/_runtime/index.js +2 -6
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +30 -22
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -3
- package/libx/_runtime/messaging/common-utils/appId.js +9 -0
- package/libx/_runtime/messaging/common-utils/authorizedRequest.js +2 -18
- package/libx/_runtime/messaging/common-utils/connections.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +305 -231
- package/libx/_runtime/messaging/enterprise-messaging-utils/cloudEvents.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-management.js +15 -8
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-messaging.js +57 -14
- package/libx/_runtime/messaging/enterprise-messaging.js +14 -19
- package/libx/_runtime/messaging/file-based.js +3 -1
- package/libx/_runtime/messaging/http-utils/token.js +18 -6
- package/libx/_runtime/messaging/message-queuing-utils/options-management.js +22 -12
- package/libx/_runtime/messaging/message-queuing-utils/options-messaging.js +27 -14
- package/libx/_runtime/messaging/message-queuing.js +138 -85
- package/libx/_runtime/messaging/outbox/utils.js +13 -7
- package/libx/_runtime/messaging/redis-messaging.js +0 -1
- package/libx/_runtime/messaging/service.js +4 -1
- package/libx/_runtime/remote/Service.js +24 -18
- package/libx/_runtime/remote/utils/client.js +90 -48
- package/libx/_runtime/remote/utils/data.js +23 -6
- package/libx/_runtime/sqlite/Service.js +14 -13
- package/libx/_runtime/sqlite/convertAssocToOneManaged.js +2 -0
- package/libx/_runtime/sqlite/customBuilder/CustomSelectBuilder.js +1 -0
- package/libx/_runtime/sqlite/execute.js +3 -9
- package/libx/_runtime/types/api.js +23 -11
- package/libx/common/utils/ucsn.js +15 -9
- package/libx/odata/afterburner.js +109 -29
- package/libx/odata/cqn2odata.js +48 -9
- package/libx/odata/grammar.pegjs +263 -156
- package/libx/odata/index.js +21 -9
- package/libx/odata/parseToCqn.js +8 -5
- package/libx/odata/parser.js +1 -1
- package/libx/odata/utils.js +13 -3
- package/libx/rest/RestAdapter.js +173 -113
- package/libx/rest/RestRequest.js +3 -2
- package/libx/rest/middleware/create.js +8 -6
- package/libx/rest/middleware/delete.js +6 -13
- package/libx/rest/middleware/error.js +1 -1
- package/libx/rest/middleware/input.js +6 -6
- package/libx/rest/middleware/operation.js +8 -3
- package/libx/rest/middleware/parse.js +3 -3
- package/libx/rest/middleware/payload.js +12 -0
- package/libx/rest/middleware/read.js +12 -2
- package/libx/rest/middleware/update.js +3 -3
- package/package.json +4 -6
- package/server.js +3 -44
- package/srv/extensibility-service.cds +56 -0
- package/srv/extensibility-service.js +1 -0
- package/srv/extensions.cds +8 -0
- package/srv/model-provider.cds +59 -0
- package/srv/model-provider.js +163 -0
- package/srv/mtx.cds +2 -0
- package/srv/mtx.js +22 -0
- package/srv/outbox.cds +2 -0
- package/tasks/enterprise-messaging-deploy.js +19 -12
- package/lib/serve/Service-compat.js +0 -36
- package/libx/_runtime/audit/generic/personal/constants.js +0 -4
- package/libx/_runtime/auth/strategies/dwc.js +0 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/Rest.js +0 -183
- package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -67
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -82
- package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +0 -39
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +0 -63
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +0 -52
- package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +0 -81
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +0 -33
- package/libx/_runtime/cds-services/adapter/rest/to.js +0 -8
- package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +0 -50
- package/libx/_runtime/cds-services/adapter/rest/utils/data.js +0 -117
- package/libx/_runtime/cds-services/adapter/rest/utils/header-checks.js +0 -14
- package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +0 -30
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +0 -250
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +0 -26
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +0 -200
- package/libx/_runtime/common/aspects/utils.js +0 -152
- package/libx/_runtime/common/toggles/handler.js +0 -21
- package/libx/_runtime/common/utils/extensibilityUtils.js +0 -18
- package/libx/_runtime/extensibility/mps/index.js +0 -5
- package/libx/_runtime/extensibility/mps/service.js +0 -111
- package/libx/_runtime/extensibility/mps/tar.js +0 -42
- package/libx/_runtime/extensibility/mps/utils.js +0 -11
- package/libx/_runtime/extensibility/uiflex/index.js +0 -54
- package/libx/_runtime/extensibility/uiflex/service.js +0 -276
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +0 -20
- package/libx/_runtime/remote/utils/client-types.d.ts +0 -7
- package/libx/gql/GraphQLAdapter.js +0 -33
- package/libx/gql/constants/adapter.js +0 -69
- package/libx/gql/constants/cds.js +0 -18
- package/libx/gql/constants/graphql.js +0 -33
- package/libx/gql/readme.md +0 -1
- package/libx/gql/resolvers/crud/create.js +0 -20
- package/libx/gql/resolvers/crud/delete.js +0 -29
- package/libx/gql/resolvers/crud/index.js +0 -6
- package/libx/gql/resolvers/crud/read.js +0 -30
- package/libx/gql/resolvers/crud/update.js +0 -42
- package/libx/gql/resolvers/crud/utils/index.js +0 -36
- package/libx/gql/resolvers/field.js +0 -5
- package/libx/gql/resolvers/index.js +0 -7
- package/libx/gql/resolvers/mutation.js +0 -23
- package/libx/gql/resolvers/parse/ast/enrich.js +0 -52
- package/libx/gql/resolvers/parse/ast/fragment.js +0 -11
- package/libx/gql/resolvers/parse/ast/fromObject.js +0 -39
- package/libx/gql/resolvers/parse/ast/index.js +0 -3
- package/libx/gql/resolvers/parse/ast/meta.js +0 -4
- package/libx/gql/resolvers/parse/ast/variable.js +0 -7
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +0 -44
- package/libx/gql/resolvers/parse/ast2cqn/entries.js +0 -31
- package/libx/gql/resolvers/parse/ast2cqn/index.js +0 -8
- package/libx/gql/resolvers/parse/ast2cqn/limit.js +0 -6
- package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +0 -24
- package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +0 -3
- package/libx/gql/resolvers/parse/ast2cqn/where.js +0 -70
- package/libx/gql/resolvers/parse/utils/index.js +0 -8
- package/libx/gql/resolvers/query.js +0 -13
- package/libx/gql/resolvers/root.js +0 -34
- package/libx/gql/schema/generate.js +0 -18
- package/libx/gql/schema/index.js +0 -5
- package/libx/gql/schema/mutation.js +0 -76
- package/libx/gql/schema/query.js +0 -108
- package/libx/gql/schema/typeDefMap.js +0 -45
- package/libx/gql/schema/utils/index.js +0 -54
- package/libx/gql/utils/index.js +0 -12
- package/libx/rest/middleware/auth.js +0 -20
- package/libx/rest/middleware/content.js +0 -19
- package/srv/flex.cds +0 -21
- package/srv/flex.js +0 -1
- package/srv/mps.cds +0 -23
- package/srv/mps.js +0 -1
- package/srv/outbox.js +0 -0
|
@@ -76,9 +76,7 @@ const _getColumnsFromTargetType = (targetType, relatedEntity, all = false) => {
|
|
|
76
76
|
}))
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
const columnNames =
|
|
80
|
-
.filter(element => element['@odata.etag'])
|
|
81
|
-
.map(element => element.name)
|
|
79
|
+
const columnNames = []
|
|
82
80
|
|
|
83
81
|
const keyNames = Object.keys(relatedEntity.keys).filter(keyName => {
|
|
84
82
|
const key = relatedEntity.keys[keyName]
|
|
@@ -94,6 +92,17 @@ const _getInnerSelect = expandItem => {
|
|
|
94
92
|
return expandItem.getOption(QueryOptions.SELECT) || []
|
|
95
93
|
}
|
|
96
94
|
|
|
95
|
+
const _isProxy = (service, targetType, relatedEntity) => {
|
|
96
|
+
// REVISIT still not perfect solution
|
|
97
|
+
if (!cds.env.effective.odata.proxies && !cds.env.effective.odata.xrefs) return
|
|
98
|
+
// proxy => target entity not exposed in service (model.namespace)
|
|
99
|
+
if (targetType.getName() in service.entities()) return
|
|
100
|
+
for (const key of targetType.getProperties().keys()) {
|
|
101
|
+
if (!relatedEntity.keys[key]) return
|
|
102
|
+
}
|
|
103
|
+
return true
|
|
104
|
+
}
|
|
105
|
+
|
|
97
106
|
/**
|
|
98
107
|
* Get the selected columns and navigation paths.
|
|
99
108
|
*
|
|
@@ -103,17 +112,14 @@ const _getInnerSelect = expandItem => {
|
|
|
103
112
|
* @returns {Array}
|
|
104
113
|
* @private
|
|
105
114
|
*/
|
|
106
|
-
const _getSelectedElements = (expandItem, targetType,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (proxy) {
|
|
115
|
-
return _getColumnsFromTargetType(targetType, relatedEntity)
|
|
116
|
-
}
|
|
115
|
+
const _getSelectedElements = (expandItem, targetType, service, options) => {
|
|
116
|
+
const { name: entityName, namespace } = targetType.getFullQualifiedName()
|
|
117
|
+
|
|
118
|
+
// autoexposed entities now used . in csn and _ in edm
|
|
119
|
+
const relatedEntity = findCsnTargetFor(entityName, service.model, namespace)
|
|
120
|
+
// proxy target?
|
|
121
|
+
if (_isProxy(service, targetType, relatedEntity)) {
|
|
122
|
+
return _getColumnsFromTargetType(targetType, relatedEntity)
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
let innerSelectItems = _getInnerSelect(expandItem)
|
|
@@ -151,50 +157,30 @@ const _getSelectedElements = (expandItem, targetType, relatedEntity, options) =>
|
|
|
151
157
|
return selectedPaths
|
|
152
158
|
}
|
|
153
159
|
|
|
154
|
-
/**
|
|
155
|
-
* Nested expands are inner expand items.
|
|
156
|
-
*
|
|
157
|
-
* @param model
|
|
158
|
-
* @param expandItem
|
|
159
|
-
* @param targetType
|
|
160
|
-
* @returns {Array}
|
|
161
|
-
* @private
|
|
162
|
-
*/
|
|
163
|
-
const _getInnerExpandItems = (model, expandItem, targetType) => {
|
|
164
|
-
if (!expandItem || !expandItem.getOption(QueryOptions.EXPAND)) {
|
|
165
|
-
return []
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return expandToCQN(model, expandItem.getOption(QueryOptions.EXPAND), targetType)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
160
|
const _filter = (item, expression) => {
|
|
172
161
|
if (!expression) return
|
|
173
162
|
const expressionToCQN = new ExpressionToCQN()
|
|
174
163
|
item.where = SELECT.from('a').where(expressionToCQN.parse(expression)).SELECT.where
|
|
175
164
|
}
|
|
176
165
|
|
|
177
|
-
const _getItemCQN = (
|
|
166
|
+
const _getItemCQN = (service, name, navigationProperty, expandItem, options) => {
|
|
178
167
|
_notSupported(expandItem)
|
|
179
168
|
|
|
180
169
|
const targetType = navigationProperty.getEntityType()
|
|
181
|
-
const { name: entityName, namespace } = navigationProperty.getEntityType().getFullQualifiedName()
|
|
182
170
|
|
|
183
|
-
|
|
184
|
-
const relatedEntity = findCsnTargetFor(entityName, model, namespace)
|
|
185
|
-
const expand = _getSelectedElements(expandItem, targetType, relatedEntity, options)
|
|
171
|
+
const expand = _getSelectedElements(expandItem, targetType, service, options)
|
|
186
172
|
const item = {
|
|
187
173
|
ref: name, // ['structured', 'nested_', nestedAssocToOne] if expand on structured
|
|
188
174
|
expand
|
|
189
175
|
}
|
|
190
176
|
|
|
191
|
-
item.expand.push(..._getInnerExpandItems(model, expandItem, targetType))
|
|
192
|
-
|
|
193
177
|
if (!expandItem) {
|
|
194
178
|
// $expand=* can't have own query options -> no limit, orderBy, etc. needed
|
|
195
179
|
return item
|
|
196
180
|
}
|
|
197
181
|
|
|
182
|
+
item.expand.push(...expandToCQN(expandItem.getOption(QueryOptions.EXPAND), targetType, service, options))
|
|
183
|
+
|
|
198
184
|
const orderBy = expandItem.getOption(QueryOptions.ORDERBY)
|
|
199
185
|
if (orderBy) {
|
|
200
186
|
orderByToCQN(item, orderBy)
|
|
@@ -230,7 +216,9 @@ const _name = expandItem =>
|
|
|
230
216
|
* @param type
|
|
231
217
|
* @returns {Array}
|
|
232
218
|
*/
|
|
233
|
-
const expandToCQN = (
|
|
219
|
+
const expandToCQN = (expandItems, type, service, options) => {
|
|
220
|
+
if (!expandItems || !expandItems.length) return []
|
|
221
|
+
|
|
234
222
|
const allElements = []
|
|
235
223
|
const isAll = expandItems.some(item => item.isAll())
|
|
236
224
|
|
|
@@ -238,7 +226,7 @@ const expandToCQN = (model, expandItems, type, options) => {
|
|
|
238
226
|
const expandItem = _getExpandItem(isAll, expandItems, name)
|
|
239
227
|
|
|
240
228
|
if (isAll || expandItem) {
|
|
241
|
-
const itemCQN = _getItemCQN(
|
|
229
|
+
const itemCQN = _getItemCQN(service, [name], navigationProperty, expandItem, options)
|
|
242
230
|
allElements.push(itemCQN)
|
|
243
231
|
}
|
|
244
232
|
}
|
|
@@ -251,7 +239,7 @@ const expandToCQN = (model, expandItems, type, options) => {
|
|
|
251
239
|
const navigationProperty = _getNavigationProperty(pathSegments)
|
|
252
240
|
|
|
253
241
|
if (isAll || expandItem) {
|
|
254
|
-
allElements.push(_getItemCQN(
|
|
242
|
+
allElements.push(_getItemCQN(service, _name(expandItem), navigationProperty, expandItem))
|
|
255
243
|
}
|
|
256
244
|
}
|
|
257
245
|
}
|
|
@@ -23,10 +23,7 @@ const parseToCqn = require('../../../../../odata/parseToCqn')
|
|
|
23
23
|
* @returns {object} - The CQN object
|
|
24
24
|
*/
|
|
25
25
|
module.exports = (component, service, target, data, odataReq, upsert) => {
|
|
26
|
-
if (
|
|
27
|
-
cds.env.features.odata_new_parser &&
|
|
28
|
-
!(component in { 'BOUND.ACTION': 1, 'BOUND.FUNCTION': 1, 'FUNCTION.IMPORT': 1, 'ACTION.IMPORT': 1 })
|
|
29
|
-
) {
|
|
26
|
+
if (cds.env.features.odata_new_parser) {
|
|
30
27
|
return parseToCqn(component, service, target, data, odataReq, upsert)
|
|
31
28
|
}
|
|
32
29
|
|
|
@@ -6,7 +6,7 @@ const orderByToCQN = require('./orderByToCQN')
|
|
|
6
6
|
const selectToCQN = require('./selectToCQN')
|
|
7
7
|
const searchToCQN = require('./searchToCQN')
|
|
8
8
|
const applyToCQN = require('./applyToCQN')
|
|
9
|
-
const { convertUrlPathToCqn, getAllKeys, isPathSupported } = require('./utils')
|
|
9
|
+
const { convertUrlPathToCqn, getAllKeys, isPathSupported, getSegmentKeyValue } = require('./utils')
|
|
10
10
|
|
|
11
11
|
const QueryOptions = require('../okra/odata-server').QueryOptions
|
|
12
12
|
const {
|
|
@@ -32,7 +32,7 @@ const SUPPORTED_SEGMENT_KINDS = {
|
|
|
32
32
|
[SINGLETON]: 1
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
const
|
|
35
|
+
const expandToCQN = require('./expandToCQN')
|
|
36
36
|
const { resolveStructuredName } = require('../utils/handlerUtils')
|
|
37
37
|
const { isStreaming } = require('../utils/stream')
|
|
38
38
|
|
|
@@ -249,7 +249,8 @@ const _addKeysToSelectIfNoStreaming = (entity, select, streaming) => {
|
|
|
249
249
|
|
|
250
250
|
const _convertUrlPathToViewCqn = segments => {
|
|
251
251
|
const args = segments[0].getKeyPredicates().reduce((prev, curr) => {
|
|
252
|
-
|
|
252
|
+
const { keyName, val } = getSegmentKeyValue(curr)
|
|
253
|
+
prev[keyName.replace(/\//g, '_')] = { val }
|
|
253
254
|
return prev
|
|
254
255
|
}, {})
|
|
255
256
|
|
|
@@ -342,7 +343,7 @@ const readToCQN = (service, target, odataReq) => {
|
|
|
342
343
|
const propertyParam = _getPropertyParam(segments)
|
|
343
344
|
const apply = _apply(uriInfo, queryOptions, entity, service.model)
|
|
344
345
|
const select = _select(queryOptions, entity)
|
|
345
|
-
const expand =
|
|
346
|
+
const expand = expandToCQN(uriInfo.getQueryOption(QueryOptions.EXPAND), uriInfo.getFinalEdmType(), service)
|
|
346
347
|
|
|
347
348
|
if (Object.keys(apply).length) {
|
|
348
349
|
_handleApply(apply, select)
|
|
@@ -351,14 +352,6 @@ const readToCQN = (service, target, odataReq) => {
|
|
|
351
352
|
if (propertyParam) {
|
|
352
353
|
select.push(propertyParam)
|
|
353
354
|
|
|
354
|
-
// add etag property if necessary
|
|
355
|
-
if (
|
|
356
|
-
entity._etag &&
|
|
357
|
-
!(propertyParam.ref && propertyParam.ref.length === 1 && propertyParam.ref[0] === entity._etag)
|
|
358
|
-
) {
|
|
359
|
-
select.push({ ref: [entity._etag] })
|
|
360
|
-
}
|
|
361
|
-
|
|
362
355
|
// add keys if no streaming, TODO: what if streaming via to-one
|
|
363
356
|
_addKeysToSelectIfNoStreaming(entity, select, isStreaming(segments))
|
|
364
357
|
}
|
|
@@ -381,7 +374,14 @@ const readToCQN = (service, target, odataReq) => {
|
|
|
381
374
|
// keep target as input because of localized view
|
|
382
375
|
const cqn = SELECT.from(isView ? _convertUrlPathToViewCqn(segments) : convertUrlPathToCqn(segments, service), select)
|
|
383
376
|
|
|
384
|
-
|
|
377
|
+
const isCount =
|
|
378
|
+
isCollectionOrToMany &&
|
|
379
|
+
queryOptions &&
|
|
380
|
+
queryOptions[QueryOptions.COUNT] &&
|
|
381
|
+
queryOptions[QueryOptions.COUNT].toUpperCase() === 'TRUE'
|
|
382
|
+
if (isCount) {
|
|
383
|
+
cqn.SELECT.count = true
|
|
384
|
+
}
|
|
385
385
|
|
|
386
386
|
if (Object.keys(apply).length) _extendCqnWithApply(cqn, apply, entity)
|
|
387
387
|
|
|
@@ -29,13 +29,6 @@ const selectToCQN = (select, keys, entity) => {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
for (const col in entity.elements) {
|
|
33
|
-
const newRef = { ref: [col] }
|
|
34
|
-
if (entity.elements[col]['@odata.etag'] && !elements.some(ref => isSameArray(ref.ref, newRef.ref))) {
|
|
35
|
-
elements.push(newRef)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
32
|
return Array.from(elements)
|
|
40
33
|
}
|
|
41
34
|
|
|
@@ -118,10 +118,33 @@ const isPathSupported = (supported, pathSegments) => {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
const _parsePrimitiveValue = (edmRef, value) => {
|
|
122
|
+
const typeName = edmRef.getProperty ? edmRef.getProperty().getType().getName() : edmRef.getType().getName()
|
|
123
|
+
return typeName.startsWith('Int') ? Number(value) : typeName === 'Boolean' ? value === 'true' : value
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const getSegmentKeyValue = segmentParam => {
|
|
127
|
+
const edmRef = segmentParam.getEdmRef()
|
|
128
|
+
const keyName = edmRef.getName()
|
|
129
|
+
if (segmentParam.getAliasValue()) {
|
|
130
|
+
const value = segmentParam.getAliasValue()
|
|
131
|
+
// must be JSON or a string according to
|
|
132
|
+
// https://docs.oasis-open.org/odata/odata/v4.01/os/part2-url-conventions/odata-v4.01-os-part2-url-conventions.html#sec_ComplexandCollectionLiterals
|
|
133
|
+
try {
|
|
134
|
+
return { keyName, val: JSON.parse(value) }
|
|
135
|
+
} catch (e) {
|
|
136
|
+
// plain string
|
|
137
|
+
}
|
|
138
|
+
return { keyName, val: _parsePrimitiveValue(edmRef, value) }
|
|
139
|
+
}
|
|
140
|
+
return { keyName, val: _parsePrimitiveValue(edmRef, segmentParam.getText()) }
|
|
141
|
+
}
|
|
142
|
+
|
|
121
143
|
module.exports = {
|
|
122
144
|
addLimit,
|
|
123
145
|
convertUrlPathToCqn,
|
|
124
146
|
isSameArray,
|
|
125
147
|
getAllKeys,
|
|
126
|
-
isPathSupported
|
|
148
|
+
isPathSupported,
|
|
149
|
+
getSegmentKeyValue
|
|
127
150
|
}
|
package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityContainer.js
CHANGED
|
@@ -343,7 +343,7 @@ class EdmEntityContainer {
|
|
|
343
343
|
for (const csdlEntitySet of providerEntitySets) {
|
|
344
344
|
const config = this._getArtifactConfiguration(this.getNamespace(), csdlEntitySet.name)
|
|
345
345
|
const entitySet = new EdmEntitySet(this._edm, this, csdlEntitySet, config)
|
|
346
|
-
this._entitySetCache
|
|
346
|
+
this._entitySetCache.set(entitySet.getName(), entitySet)
|
|
347
347
|
this._entitySets.push(entitySet)
|
|
348
348
|
}
|
|
349
349
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const EdmTypeKind = require('../edm/EdmType').TypeKind
|
|
4
4
|
const EdmPrimitiveTypeKind = require('../edm/EdmPrimitiveTypeKind')
|
|
5
|
+
const { toBase64url } = require('../../../../../../common/utils/binary')
|
|
5
6
|
|
|
6
7
|
const REGEXP_SINGLE_QUOTE = new RegExp("'", 'g')
|
|
7
8
|
const REGEXP_TWO_SINGLE_QUOTES = new RegExp("''", 'g')
|
|
@@ -24,8 +25,8 @@ class UriHelper {
|
|
|
24
25
|
|
|
25
26
|
if (edmType === EdmPrimitiveTypeKind.Binary) {
|
|
26
27
|
// convert the URL-safe base64 encoding to the standard variant (with padding, if necessary)
|
|
27
|
-
|
|
28
|
-
return
|
|
28
|
+
const val = uriLiteral.substring(uriLiteral.indexOf("'") + 1, uriLiteral.length - 1)
|
|
29
|
+
return Buffer.from(val, 'base64').toString('base64')
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
if (edmType === EdmPrimitiveTypeKind.Duration || edmType.getKind() === EdmTypeKind.ENUM || edmType.getName().startsWith('Geo')) {
|
|
@@ -50,7 +51,7 @@ class UriHelper {
|
|
|
50
51
|
if (value === null) return 'null'
|
|
51
52
|
if (edmType === EdmPrimitiveTypeKind.String) return "'" + value.replace(REGEXP_SINGLE_QUOTE, "''") + "'"
|
|
52
53
|
if (edmType === EdmPrimitiveTypeKind.Duration) return "duration'" + value + "'"
|
|
53
|
-
if (edmType === EdmPrimitiveTypeKind.Binary) return "binary'" + value
|
|
54
|
+
if (edmType === EdmPrimitiveTypeKind.Binary) return "binary'" + toBase64url(value) + "'"
|
|
54
55
|
if (edmType.getKind() === EdmTypeKind.DEFINITION) {
|
|
55
56
|
return UriHelper.toUriLiteral(value, edmType.getUnderlyingType())
|
|
56
57
|
}
|
|
@@ -8,6 +8,7 @@ const ValueConverter = require('./ValueConverter')
|
|
|
8
8
|
const ValueValidator = require('../validator/ValueValidator')
|
|
9
9
|
const JsonContentTypeInfo = require('../format/JsonContentTypeInfo')
|
|
10
10
|
const IllegalArgumentError = require('../errors/IllegalArgumentError')
|
|
11
|
+
const { isInvalidBase64string } = require('../../../../../../common/utils/binary')
|
|
11
12
|
|
|
12
13
|
const V2_DATE_TIME_OFFSET_REGEXP = new RegExp('^/Date\\((-?\\d{1,15})(?:(\\+|-)(\\d{4}))?\\)/$')
|
|
13
14
|
const V2_TIME_OF_DAY_REGEXP = new RegExp('^PT(?:(\\d{1,2})H)?(?:(\\d{1,4})M)?(?:(\\d{1,5})(\\.\\d+)?S)?$')
|
|
@@ -70,11 +71,9 @@ const COLLECTION_VALIDATION = new RegExp('^' + SRID + 'Collection\\((' + MULTI_G
|
|
|
70
71
|
const BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}={2})$/
|
|
71
72
|
|
|
72
73
|
function _getBase64(val) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (!val.match(BASE64)) return
|
|
77
|
-
return val
|
|
74
|
+
if (isInvalidBase64string(val)) return
|
|
75
|
+
// convert url-safe to standard base64
|
|
76
|
+
return Buffer.from(val, 'base64').toString('base64')
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
/**
|
package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js
CHANGED
|
@@ -6,6 +6,7 @@ const EdmTypeKind = require('../edm/EdmType').TypeKind
|
|
|
6
6
|
const EdmPrimitiveTypeKind = require('../edm/EdmPrimitiveTypeKind')
|
|
7
7
|
const JsonContentTypeInfo = require('../format/JsonContentTypeInfo')
|
|
8
8
|
const IllegalArgumentError = require('../errors/IllegalArgumentError')
|
|
9
|
+
const { toBase64url } = require('../../../../../../common/utils/binary')
|
|
9
10
|
|
|
10
11
|
const PLUS_REGEXP = new RegExp('\\+', 'g')
|
|
11
12
|
const SLASH_REGEXP = new RegExp('/', 'g')
|
|
@@ -189,9 +190,9 @@ class ValueConverter {
|
|
|
189
190
|
* @param {Buffer|string} value - value, which should be converted
|
|
190
191
|
* @returns {string} Base64 string
|
|
191
192
|
*/
|
|
192
|
-
convertBinary (value) {
|
|
193
|
-
|
|
194
|
-
return (
|
|
193
|
+
convertBinary (value, maxLength) {
|
|
194
|
+
this._valueValidator.validateBinary(value, maxLength)
|
|
195
|
+
return toBase64url(value)
|
|
195
196
|
}
|
|
196
197
|
|
|
197
198
|
/**
|
package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/validator/ValueValidator.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { big } = require('@sap/cds-foss')
|
|
4
|
+
const { isInvalidBase64string } = require('../../../../../../common/utils/binary')
|
|
4
5
|
const IllegalArgumentError = require('../errors/IllegalArgumentError')
|
|
5
6
|
|
|
6
7
|
const YEAR_RE = '(?:-?(?:(?:(?:0\\d{3})|(?:[1-9]\\d{3,}))))'
|
|
@@ -86,12 +87,13 @@ class ValueValidator {
|
|
|
86
87
|
|
|
87
88
|
/**
|
|
88
89
|
* Validates value of Edm.Binary type.
|
|
89
|
-
* @param {Buffer} value - Edm.Binary value
|
|
90
|
+
* @param {Buffer} value - Edm.Binary value as base64 or base64url string
|
|
90
91
|
* @param {number} maxLength - value of MaxLength facet
|
|
91
92
|
*/
|
|
92
93
|
validateBinary (value, maxLength) {
|
|
93
|
-
if
|
|
94
|
-
this.
|
|
94
|
+
// if it's a Buffer instance, just let it go. Otherwise MUST be base64 or base64url string as per OData spec for edm.Binary
|
|
95
|
+
if (isInvalidBase64string(value)) throw this._valueError(value, 'Edm.Binary', 'Buffer instance or base64/base64url string')
|
|
96
|
+
this._checkMaxLength(Buffer.isBuffer(value) ? value : Buffer.from(value, 'base64'), maxLength, 'Edm.Binary')
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
/**
|
package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/ResponseHeaderSetter.js
CHANGED
|
@@ -89,6 +89,8 @@ class ResponseHeaderSetter {
|
|
|
89
89
|
* @returns {ResponseHeaderSetter} this instance of ResponseHeaderSetter
|
|
90
90
|
*/
|
|
91
91
|
setLocationHeader (overwrite = false) {
|
|
92
|
+
// to prevent reading empty body in case of e.g. no auth by readAfterWrite
|
|
93
|
+
if (this._response.getHeader(HeaderNames.LOCATION)) return this
|
|
92
94
|
const uriInfo = this._request.getUriInfo()
|
|
93
95
|
const data = this._response.getBody()
|
|
94
96
|
const primitiveValueEncoder = this._request
|
|
@@ -29,7 +29,7 @@ class DebugSerializingCommand extends Command {
|
|
|
29
29
|
const response = this.getContext().getResponse()
|
|
30
30
|
|
|
31
31
|
if (response.isHeadersSent()) {
|
|
32
|
-
logger.
|
|
32
|
+
logger.debug('Headers already sent')
|
|
33
33
|
next()
|
|
34
34
|
} else {
|
|
35
35
|
// The runtime measurement must be stopped before serializing its output,
|
|
@@ -35,7 +35,7 @@ class PresetResponseHeadersCommand extends Command {
|
|
|
35
35
|
*/
|
|
36
36
|
execute (next) {
|
|
37
37
|
if (this._response.isHeadersSent()) {
|
|
38
|
-
this._logger.
|
|
38
|
+
this._logger.debug('Headers already sent')
|
|
39
39
|
} else {
|
|
40
40
|
new ResponseHeaderSetter(this._request, this._response, this._version, this._logger).setHeaders(true)
|
|
41
41
|
}
|
|
@@ -35,7 +35,7 @@ class SetResponseHeadersCommand extends Command {
|
|
|
35
35
|
*/
|
|
36
36
|
execute (next) {
|
|
37
37
|
if (this._response.isHeadersSent()) {
|
|
38
|
-
this._logger.
|
|
38
|
+
this._logger.debug('Headers already sent')
|
|
39
39
|
} else {
|
|
40
40
|
const responseHeaderSetter = new ResponseHeaderSetter(this._request, this._response, null, this._logger)
|
|
41
41
|
const responseContract = this._response.getContract()
|
|
@@ -8,6 +8,7 @@ const RepresentationKind = commons.format.RepresentationKind.Kinds
|
|
|
8
8
|
const UriHelper = require('../utils/UriHelper')
|
|
9
9
|
const SerializationError = require('../errors/SerializationError')
|
|
10
10
|
const { appURL } = require('../../../../../../common/utils/vcap')
|
|
11
|
+
const cds = require('../../../../../../../../lib')
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Context URL construction.
|
|
@@ -30,10 +31,10 @@ class ContextURLFactory {
|
|
|
30
31
|
const lastSegment = pathSegments[pathSegments.length - 1]
|
|
31
32
|
const contextUrlInfo = this._parseSegments(pathSegments, providedKeyMap, edm)
|
|
32
33
|
const contextUrlPrefix = this._buildContextUrlPrefix(contextUrlInfo, pathSegments, request, logger)
|
|
33
|
-
|
|
34
|
+
|
|
34
35
|
if (lastSegment.getKind() === ResourceKind.SERVICE) return `${contextUrlPrefix}$metadata`
|
|
35
36
|
if (lastSegment.getKind() === ResourceKind.METADATA) return ''
|
|
36
|
-
|
|
37
|
+
|
|
37
38
|
const finalEdmType = uriInfo.getFinalEdmType()
|
|
38
39
|
const structuredType =
|
|
39
40
|
finalEdmType && (finalEdmType.getKind() === EdmTypeKind.ENTITY || finalEdmType.getKind() === EdmTypeKind.COMPLEX)
|
|
@@ -19,8 +19,10 @@ class ErrorJsonSerializer extends ErrorSerializer {
|
|
|
19
19
|
let result = {
|
|
20
20
|
code: this._error.code || 'null',
|
|
21
21
|
message: this._error.message,
|
|
22
|
-
target: this._error.target
|
|
22
|
+
target: this._error.target,
|
|
23
23
|
}
|
|
24
|
+
// REVISIT: We should also pass stack traces in development
|
|
25
|
+
// if (!cds.env.production) result.stack = this._error.stack
|
|
24
26
|
|
|
25
27
|
if (this._error.details) {
|
|
26
28
|
result.details = this._error.details.map(d => {
|
|
@@ -446,6 +446,7 @@ class SerializerFactory {
|
|
|
446
446
|
if (!propertyOrReturnType.isNullable()) throw new SerializationError('Not nullable value must not be null')
|
|
447
447
|
} else if (type === EdmPrimitiveTypeKind.Binary) {
|
|
448
448
|
new ValueValidator().validateBinary(value, propertyOrReturnType.getMaxLength())
|
|
449
|
+
value = Buffer.isBuffer(value) ? value : Buffer.from(value, 'base64')
|
|
449
450
|
response.setHeader(HeaderNames.CONTENT_TYPE, data[MetaProperties.MEDIA_CONTENT_TYPE] || ContentTypes.BINARY)
|
|
450
451
|
} else if (type === EdmPrimitiveTypeKind.Stream) {
|
|
451
452
|
if (!value.pipe || typeof value.pipe !== 'function') {
|
|
@@ -12,6 +12,7 @@ const QueryOptions = commons.uri.UriInfo.QueryOptions
|
|
|
12
12
|
const UriHelper = require('../utils/UriHelper')
|
|
13
13
|
const NextLinkSerializer = require('./NextLinkSerializer')
|
|
14
14
|
const SerializationError = require('../errors/SerializationError')
|
|
15
|
+
const { toBase64url } = require('../../../../../../common/utils/binary')
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* JSON serializer for trusted OData resources, i.e., there is no validation.
|
|
@@ -209,7 +210,7 @@ class TrustedResourceJsonSerializer {
|
|
|
209
210
|
* @private
|
|
210
211
|
*/
|
|
211
212
|
_serializeEntity (result, entityType, data, expandItems, odataPath, structurePath) {
|
|
212
|
-
this._serializeAnnotations(result, data, MetaProperties.ETAG)
|
|
213
|
+
this._serializeAnnotations(result, data, MetaProperties.ETAG, MetaProperties.CONTEXT)
|
|
213
214
|
|
|
214
215
|
this._serializeStructure(result, entityType, data, expandItems, odataPath, structurePath || [])
|
|
215
216
|
|
|
@@ -472,8 +473,7 @@ class TrustedResourceJsonSerializer {
|
|
|
472
473
|
if (type === EdmPrimitiveTypeKind.Decimal || type === EdmPrimitiveTypeKind.Int64) {
|
|
473
474
|
result = this._formatParams.getIEEE754Setting() ? String(propertyValue) : Number(propertyValue)
|
|
474
475
|
} else if (type === EdmPrimitiveTypeKind.Binary) {
|
|
475
|
-
|
|
476
|
-
result = (Buffer.isBuffer(propertyValue) ? propertyValue.toString('base64') : propertyValue).replace(/\+/g, '-').replace(/\//g, '_')
|
|
476
|
+
result = toBase64url(propertyValue)
|
|
477
477
|
}
|
|
478
478
|
break
|
|
479
479
|
case EdmTypeKind.COMPLEX:
|
|
@@ -6,13 +6,11 @@ const { findCsnTargetFor } = require('../../../../common/utils/csn')
|
|
|
6
6
|
const { isStreaming } = require('./stream')
|
|
7
7
|
const { convertStructured } = require('../../../../../common/utils/ucsn')
|
|
8
8
|
const { deepCopy } = require('../../../../common/utils/copy')
|
|
9
|
+
const { getSegmentKeyValue } = require('../odata-to-cqn/utils')
|
|
9
10
|
|
|
10
11
|
const _isFunctionInvocation = req =>
|
|
11
12
|
req.getUriInfo().getLastSegment().getFunction || req.getUriInfo().getLastSegment().getFunctionImport
|
|
12
13
|
|
|
13
|
-
const _getTypeName = edmRef =>
|
|
14
|
-
edmRef.getProperty ? edmRef.getProperty().getType().getName() : edmRef.getType().getName()
|
|
15
|
-
|
|
16
14
|
const _addStructuredProperties = ([structName, property, ...nestedProperties], paramData, value) => {
|
|
17
15
|
paramData[structName] = paramData[structName] || {}
|
|
18
16
|
if (nestedProperties.length) {
|
|
@@ -23,25 +21,6 @@ const _addStructuredProperties = ([structName, property, ...nestedProperties], p
|
|
|
23
21
|
paramData[structName][property] = value
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
const _getParamKeyValue = segmentParam => {
|
|
27
|
-
const edmRef = segmentParam.getEdmRef()
|
|
28
|
-
const typeName = _getTypeName(edmRef)
|
|
29
|
-
if (segmentParam.getAliasValue())
|
|
30
|
-
// must be JSON or a string according to
|
|
31
|
-
// https://docs.oasis-open.org/odata/odata/v4.01/os/part2-url-conventions/odata-v4.01-os-part2-url-conventions.html#sec_ComplexandCollectionLiterals
|
|
32
|
-
try {
|
|
33
|
-
return { keyName: edmRef.getName(), value: JSON.parse(segmentParam.getAliasValue()) }
|
|
34
|
-
} catch (e) {
|
|
35
|
-
return { keyName: edmRef.getName(), value: segmentParam.getAliasValue() }
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
keyName: edmRef.getName(),
|
|
40
|
-
// Convert any integer type into numeric values.
|
|
41
|
-
value: typeName.startsWith('Int') ? Number(segmentParam.getText()) : segmentParam.getText()
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
24
|
/**
|
|
46
25
|
* The key predicates or function parameters will contain the keys and values for this request.
|
|
47
26
|
* Combine all key value pairs into one object.
|
|
@@ -54,14 +33,14 @@ const _getParamData = parameters => {
|
|
|
54
33
|
const paramData = {}
|
|
55
34
|
|
|
56
35
|
for (const segmentParam of parameters) {
|
|
57
|
-
const { keyName,
|
|
36
|
+
const { keyName, val } = getSegmentKeyValue(segmentParam)
|
|
58
37
|
|
|
59
38
|
if (keyName.includes('/')) {
|
|
60
|
-
_addStructuredProperties(keyName.split('/'), paramData,
|
|
39
|
+
_addStructuredProperties(keyName.split('/'), paramData, val)
|
|
61
40
|
continue
|
|
62
41
|
}
|
|
63
42
|
|
|
64
|
-
paramData[keyName] =
|
|
43
|
+
paramData[keyName] = val
|
|
65
44
|
}
|
|
66
45
|
|
|
67
46
|
return paramData
|
|
@@ -83,6 +62,11 @@ const _flattenStructureKeys = structureData => {
|
|
|
83
62
|
// works only for custom on condition working on keys with '=' operator
|
|
84
63
|
// and combination of multiple conditions connected with 'and'
|
|
85
64
|
const _addKeysToData = (navSourceKeyValues, onCondition, data) => {
|
|
65
|
+
if (onCondition[0].xpr) {
|
|
66
|
+
// REVISIT support for nested xpr?
|
|
67
|
+
return _addKeysToData(navSourceKeyValues, onCondition[0].xpr, data)
|
|
68
|
+
}
|
|
69
|
+
|
|
86
70
|
const flattenKeys = _flattenStructureKeys(navSourceKeyValues)
|
|
87
71
|
for (const key in flattenKeys) {
|
|
88
72
|
// find index of source column
|
|
@@ -100,6 +84,33 @@ const _addKeysToData = (navSourceKeyValues, onCondition, data) => {
|
|
|
100
84
|
data[target] = flattenKeys[key]
|
|
101
85
|
}
|
|
102
86
|
}
|
|
87
|
+
|
|
88
|
+
// get static values from onCond
|
|
89
|
+
for (let i = 0; i < onCondition.length; i++) {
|
|
90
|
+
const first = onCondition[i]
|
|
91
|
+
const compare = onCondition[i + 1]
|
|
92
|
+
const second = onCondition[i + 2]
|
|
93
|
+
|
|
94
|
+
if (compare !== '=') continue
|
|
95
|
+
|
|
96
|
+
if (first && first.ref && second && 'val' in second) {
|
|
97
|
+
// ref = val
|
|
98
|
+
_staticOnCond(data, first, second)
|
|
99
|
+
i += 2
|
|
100
|
+
} else if (second && second.ref && first && 'val' in first) {
|
|
101
|
+
// val = ref
|
|
102
|
+
_staticOnCond(data, second, first)
|
|
103
|
+
i += 2
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const _staticOnCond = (data, ref, val) => {
|
|
109
|
+
const {
|
|
110
|
+
ref: [alias, target]
|
|
111
|
+
} = ref
|
|
112
|
+
if (alias != 'target') return
|
|
113
|
+
data[target] = val.val
|
|
103
114
|
}
|
|
104
115
|
|
|
105
116
|
function _entityOrTypeName(navSourceSegment) {
|