@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
|
@@ -51,15 +51,6 @@ class ReferenceBuilder extends BaseBuilder {
|
|
|
51
51
|
this._outputObj.sql.push('CAST', '(')
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
// REVISIT: compat for legacy ref: "['foo as bar']" -> remove with cds^6
|
|
55
|
-
if (this._obj.ref.length === 1 && typeof this._obj.ref[0] === 'string') {
|
|
56
|
-
const matched = this._obj.ref[0].match(/(\S*)\s{1,}as\s{1,}(\S*)/i)
|
|
57
|
-
if (matched) {
|
|
58
|
-
this._obj.ref = [matched[1]]
|
|
59
|
-
this._obj.as = matched[2].replace(/^"/, '').replace(/"$/, '')
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
54
|
if (this._obj.param) {
|
|
64
55
|
this._parseParamReference(this._obj.ref)
|
|
65
56
|
} else {
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const cds = require('../../cds')
|
|
2
|
-
|
|
3
1
|
const BaseBuilder = require('./BaseBuilder')
|
|
4
2
|
const { DRAFT_COLUMNS_MAP } = require('../../common/constants/draft')
|
|
5
3
|
|
|
@@ -108,6 +106,10 @@ class SelectBuilder extends BaseBuilder {
|
|
|
108
106
|
this._forUpdate()
|
|
109
107
|
}
|
|
110
108
|
|
|
109
|
+
if (this._obj.SELECT.forShareLock) {
|
|
110
|
+
this._forShareLock()
|
|
111
|
+
}
|
|
112
|
+
|
|
111
113
|
this._parameters()
|
|
112
114
|
this._outputObj.sql = /** @type {string} */ this._outputObj.sql.join(' ')
|
|
113
115
|
return this._outputObj
|
|
@@ -133,6 +135,10 @@ class SelectBuilder extends BaseBuilder {
|
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
137
|
|
|
138
|
+
_forShareLock() {
|
|
139
|
+
this._outputObj.sql.push('FOR SHARE LOCK')
|
|
140
|
+
}
|
|
141
|
+
|
|
136
142
|
_distinct() {
|
|
137
143
|
this._outputObj.sql.push('DISTINCT')
|
|
138
144
|
}
|
|
@@ -268,7 +274,7 @@ class SelectBuilder extends BaseBuilder {
|
|
|
268
274
|
}
|
|
269
275
|
|
|
270
276
|
// this function is overridden in hana in CustomSelectBuilder
|
|
271
|
-
_buildRefElement(col, res
|
|
277
|
+
_buildRefElement(col, res) {
|
|
272
278
|
res = new this.ReferenceBuilder(col, this._options, this._csn).build()
|
|
273
279
|
return res
|
|
274
280
|
}
|
|
@@ -281,7 +287,7 @@ class SelectBuilder extends BaseBuilder {
|
|
|
281
287
|
) {
|
|
282
288
|
// REVISIT: db cleanup
|
|
283
289
|
// slugify is needed for a unit test. Really required in production?
|
|
284
|
-
const slugifiedAlias = col.as.replace(/\./g, '_')
|
|
290
|
+
const slugifiedAlias = col.as.includes('@odata.') ? col.as : col.as.replace(/\./g, '_')
|
|
285
291
|
return ` AS ${this._quote(slugifiedAlias)}`
|
|
286
292
|
}
|
|
287
293
|
|
|
@@ -439,13 +445,8 @@ class SelectBuilder extends BaseBuilder {
|
|
|
439
445
|
}
|
|
440
446
|
|
|
441
447
|
_val(obj) {
|
|
442
|
-
|
|
448
|
+
const _val = obj.val
|
|
443
449
|
if (typeof _val === 'number' || _val === null) return { sql: _val, values: [] }
|
|
444
|
-
// REVISIT: remove with cds^6
|
|
445
|
-
if (typeof _val === 'string' && cds.env.features.extract_vals !== false) {
|
|
446
|
-
const match = _val.match(/^'(.*)'$/)
|
|
447
|
-
if (match) _val = match[1]
|
|
448
|
-
}
|
|
449
450
|
return { sql: '?', values: [_val] }
|
|
450
451
|
}
|
|
451
452
|
|
|
@@ -119,7 +119,7 @@ class UpdateBuilder extends BaseBuilder {
|
|
|
119
119
|
})
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
resMap.forEach((value, key
|
|
122
|
+
resMap.forEach((value, key) => {
|
|
123
123
|
if (value && value.sql) {
|
|
124
124
|
sql.push(`${this._quoteElement(key)} = ${value.sql}`)
|
|
125
125
|
this._outputObj.values.push(...value.values)
|
|
@@ -192,7 +192,7 @@ class UpdateBuilder extends BaseBuilder {
|
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
_where(
|
|
195
|
+
_where() {
|
|
196
196
|
const where = new this.ExpressionBuilder(this._obj.UPDATE.where, this._options, this._csn).build()
|
|
197
197
|
this._outputObj.sql.push('WHERE', where.sql)
|
|
198
198
|
this._outputObj.values = this._outputObj.values.concat(where.values)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const getColumns = require('../utils/columns')
|
|
2
|
-
|
|
3
|
-
const ANNOTATIONS = ['@cds.on.insert', '@odata.on.insert', '@cds.on.update', '@odata.on.update']
|
|
2
|
+
const ANNOTATIONS = ['@cds.on.insert', '@cds.on.update']
|
|
4
3
|
const { ensureNoDraftsSuffix } = require('../../common/utils/draft')
|
|
5
4
|
|
|
6
5
|
const _getAnnotationNames = column => {
|
|
@@ -23,7 +23,7 @@ const getColumns = (entity, { _4db, onlyKeys } = { _4db: true, onlyKeys: false }
|
|
|
23
23
|
if (element.isAssociation) continue
|
|
24
24
|
if (_4db && entity._isDraftEnabled && elementName in DRAFT_COLUMNS_MAP) continue
|
|
25
25
|
if ((cds.env.effective.odata.structs || cds.env.features.ucsn_struct_conversion) && element.elements) {
|
|
26
|
-
columnNames.push(...resolveStructured({
|
|
26
|
+
columnNames.push(...resolveStructured({ element, structProperties: [] }, false))
|
|
27
27
|
continue
|
|
28
28
|
}
|
|
29
29
|
columnNames.push(elementName)
|
|
@@ -62,6 +62,14 @@ const _propagateToParent = ({ parentElement, childElement, deep }, childRow, row
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
module.exports = (tKey, row, foreignKeyPropagations, isCompositionEffective) => {
|
|
65
|
+
if (row[tKey] === null) {
|
|
66
|
+
for (const foreignKeyPropagation of foreignKeyPropagations) {
|
|
67
|
+
if (!foreignKeyPropagation.fillChild) row[foreignKeyPropagation.parentElement.name] = null
|
|
68
|
+
}
|
|
69
|
+
if (!isCompositionEffective) delete row[tKey]
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
65
73
|
const childRows = Array.isArray(row[tKey]) ? row[tKey] : [row[tKey]]
|
|
66
74
|
|
|
67
75
|
for (const childRow of childRows) {
|
|
@@ -74,12 +82,12 @@ module.exports = (tKey, row, foreignKeyPropagations, isCompositionEffective) =>
|
|
|
74
82
|
if (pk && !(pk in row)) _propagateToParent(foreignKeyPropagation, childRow, row)
|
|
75
83
|
if (!(pk in row)) _generateParentField(foreignKeyPropagation, row)
|
|
76
84
|
|
|
77
|
-
if (
|
|
78
|
-
else _propagateToChid(foreignKeyPropagation, row, childRow)
|
|
85
|
+
if (isCompositionEffective) _propagateToChid(foreignKeyPropagation, row, childRow)
|
|
79
86
|
} else {
|
|
80
87
|
_generateChildField(foreignKeyPropagation, childRow)
|
|
81
88
|
_propagateToParent(foreignKeyPropagation, childRow, row)
|
|
82
89
|
}
|
|
83
90
|
}
|
|
84
91
|
}
|
|
92
|
+
if (!isCompositionEffective) delete row[tKey]
|
|
85
93
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const cds = require('../cds')
|
|
2
|
+
|
|
3
|
+
const handleDefaults = require('./defaults')
|
|
4
|
+
|
|
5
|
+
const _calculateExtensions = async function (ID, tag, tenant) {
|
|
6
|
+
let active, inactive
|
|
7
|
+
await cds.tx({ tenant }, async tx => {
|
|
8
|
+
if (tag || ID) {
|
|
9
|
+
const inactiveCqn = SELECT.from('cds.xt.Extensions').where({ activated: 'propertyBag' })
|
|
10
|
+
if (ID) {
|
|
11
|
+
inactiveCqn.where('ID !=', ID)
|
|
12
|
+
} else {
|
|
13
|
+
inactiveCqn.where('tag !=', tag)
|
|
14
|
+
}
|
|
15
|
+
inactive = await tx.run(inactiveCqn)
|
|
16
|
+
const activeCqn = SELECT.from('cds.xt.Extensions').where({ activated: 'database' })
|
|
17
|
+
if (ID) {
|
|
18
|
+
activeCqn.or({ ID })
|
|
19
|
+
} else {
|
|
20
|
+
if (tag) activeCqn.or({ tag })
|
|
21
|
+
}
|
|
22
|
+
active = await tx.run(activeCqn)
|
|
23
|
+
if (inactive.length) {
|
|
24
|
+
const deleteCqn = DELETE.from('cds.xt.Extensions').where(inactiveCqn.SELECT.where)
|
|
25
|
+
await tx.run(deleteCqn)
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
// activate all
|
|
29
|
+
inactive = []
|
|
30
|
+
active = await tx.run(SELECT.from('cds.xt.Extensions'))
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
return { active, inactive }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const _restoreExtensions = async function (tenant, active, inactive) {
|
|
38
|
+
await cds.tx({ tenant }, async tx => {
|
|
39
|
+
// delete all extensions
|
|
40
|
+
await tx.run(DELETE.from('cds.xt.Extensions'))
|
|
41
|
+
// active
|
|
42
|
+
active.forEach(row => {
|
|
43
|
+
row.csn = row.csn.replace(/,"@cds.extension":true/g, '')
|
|
44
|
+
row.activated = 'database'
|
|
45
|
+
row.timestamp = '$now'
|
|
46
|
+
})
|
|
47
|
+
await tx.run(INSERT.into('cds.xt.Extensions').entries(active))
|
|
48
|
+
// inactive
|
|
49
|
+
if (inactive.length) {
|
|
50
|
+
for (const na of inactive) {
|
|
51
|
+
for (const extension of JSON.parse(na.csn).extensions) {
|
|
52
|
+
await handleDefaults(extension, tx)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
await tx.run(INSERT.into('cds.xt.Extensions').entries(inactive))
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const activate = async function (ID, tag, tenant) {
|
|
61
|
+
const { active, inactive } = await _calculateExtensions(ID, tag, tenant)
|
|
62
|
+
|
|
63
|
+
const { 'cds.xt.DeploymentService': ds } = cds.services
|
|
64
|
+
await ds.extend(tenant)
|
|
65
|
+
|
|
66
|
+
await _restoreExtensions(tenant, active, inactive)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = activate
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const cds = require('../cds')
|
|
2
|
+
|
|
3
|
+
const { validateExtension } = require('./validation')
|
|
4
|
+
const handleDefaults = require('./defaults')
|
|
5
|
+
const activateExt = require('./activate')
|
|
6
|
+
|
|
7
|
+
const _isCSN = str => str.substring(0, 1) === '{'
|
|
8
|
+
|
|
9
|
+
const add = async function (req) {
|
|
10
|
+
let { extension, tag, activate } = req.data
|
|
11
|
+
if (!extension || !extension.length) req.reject(400, 'Missing extension')
|
|
12
|
+
if (!activate) activate = 'database'
|
|
13
|
+
if (!tag) tag = null
|
|
14
|
+
const tenant = req.tenant || (req.user.is('internal-user') && req.data.tenant)
|
|
15
|
+
|
|
16
|
+
const csn = _isCSN(extension) ? JSON.parse(extension) : cds.parse.cdl(extension)
|
|
17
|
+
if (csn.requires) delete csn.requires
|
|
18
|
+
await validateExtension(csn, tenant, req)
|
|
19
|
+
|
|
20
|
+
const ID = cds.utils.uuid()
|
|
21
|
+
await cds.tx({ tenant }, async tx => {
|
|
22
|
+
await tx.run(INSERT.into('cds.xt.Extensions').entries([{ ID, tag, csn: JSON.stringify(csn), activated: activate }]))
|
|
23
|
+
if (activate === 'propertyBag' && csn.extensions) csn.extensions.forEach(async ext => await handleDefaults(ext, tx))
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
if (activate === 'database') {
|
|
27
|
+
await activateExt(ID, tag, tenant)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const promote = async function (req) {
|
|
32
|
+
let { tag, activate } = req.data
|
|
33
|
+
if (!activate) activate = 'database'
|
|
34
|
+
if (!tag) tag = null
|
|
35
|
+
const tenant = req.tenant || (req.user.is('internal-user') && req.data.tenant) || ''
|
|
36
|
+
if (activate !== 'database') req.reject(400, 'Promote to propertyBag is not supported')
|
|
37
|
+
|
|
38
|
+
await activateExt(null, tag, tenant)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = { add, promote }
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const cds = require('../cds')
|
|
2
|
+
|
|
3
|
+
const { validateCsn, validateExtensionFields, validateExtension } = require('./validation')
|
|
4
|
+
const handleDefaults = require('./defaults')
|
|
5
|
+
const resolveViews = require('./views')
|
|
6
|
+
|
|
7
|
+
const _getCsn = req => {
|
|
8
|
+
const csn = {
|
|
9
|
+
extensions: req.data.extensions.map(ext => JSON.parse(ext))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return csn
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const _addAnnotation = extension => {
|
|
16
|
+
Object.values(extension.elements).forEach(el => {
|
|
17
|
+
el['@cds.extension'] = true
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const _addViews = csn => {
|
|
22
|
+
csn.extensions.forEach(extension => {
|
|
23
|
+
const target = cds.model.definitions[extension.extend]
|
|
24
|
+
const views_ = []
|
|
25
|
+
const view = resolveViews(target, views_)
|
|
26
|
+
extension.extend = view && view.name
|
|
27
|
+
_addAnnotation(extension)
|
|
28
|
+
|
|
29
|
+
// All projection views leading to the db entity are extended with back pack in case view columns are explicitly listed.
|
|
30
|
+
// The views using projections with '*' obtain the back pack automatically.
|
|
31
|
+
views_.forEach(view => {
|
|
32
|
+
if (!view.projection || (view.projection.columns && !view.projection.columns.some(col => col === '*'))) {
|
|
33
|
+
csn.extensions.push({
|
|
34
|
+
extend: view.name,
|
|
35
|
+
columns: Object.keys(extension.elements).map(key => {
|
|
36
|
+
return { ref: [key] }
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const _addExtension = async function (csn, req) {
|
|
45
|
+
const tx = cds.tx(req)
|
|
46
|
+
await tx.run(
|
|
47
|
+
INSERT.into('cds.xt.Extensions').entries([
|
|
48
|
+
{ ID: cds.utils.uuid(), tag: 'uiflex', csn: JSON.stringify(csn), activated: 'propertyBag' }
|
|
49
|
+
])
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
// defaults
|
|
53
|
+
for (const ext of req.data.extensions) {
|
|
54
|
+
const extension = JSON.parse(ext)
|
|
55
|
+
await handleDefaults(extension, tx, false)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const addExtension = async function (req) {
|
|
60
|
+
const csn = _getCsn(req)
|
|
61
|
+
validateCsn(csn, req)
|
|
62
|
+
validateExtensionFields(csn, req)
|
|
63
|
+
_addViews(csn, cds)
|
|
64
|
+
await validateExtension(csn, req.tenant, req)
|
|
65
|
+
await _addExtension(csn, req)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = addExtension
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const cds = require('../cds')
|
|
2
|
+
|
|
3
|
+
const { ensureDraftsSuffix } = require('../common/utils/draft')
|
|
4
|
+
const resolveViews = require('./views')
|
|
5
|
+
const { EXT_BACK_PACK } = require('./utils')
|
|
6
|
+
|
|
7
|
+
const _needsQuotations = t => t instanceof cds.builtin.classes.string || t instanceof cds.builtin.classes.date
|
|
8
|
+
|
|
9
|
+
const _getDraftTable = view => {
|
|
10
|
+
return cds.model.definitions[view]._isDraftEnabled ? ensureDraftsSuffix(view) : undefined
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const handleDefaults = async (extension, tx, checkDb = true) => {
|
|
14
|
+
const target = cds.model.definitions[extension.extend]
|
|
15
|
+
const dbEntity = resolveViews(target).name
|
|
16
|
+
|
|
17
|
+
if (checkDb && target.name !== dbEntity) return // only db entities
|
|
18
|
+
|
|
19
|
+
const draft = _getDraftTable(extension.extend)
|
|
20
|
+
const ext = Object.keys(extension.elements)
|
|
21
|
+
.filter(key => extension.elements[key].default)
|
|
22
|
+
.map(key => {
|
|
23
|
+
const element = extension.elements[key]
|
|
24
|
+
// .type as ui flex extensions are not linked
|
|
25
|
+
const t = cds.model.definitions[element.type] || cds.builtin.types[element.type]
|
|
26
|
+
const value = t && _needsQuotations(t) ? `"${element.default.val}"` : element.default.val
|
|
27
|
+
return `"${key}":${value}`
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
if (ext.length !== 0) {
|
|
31
|
+
const extStr = ext.join(',')
|
|
32
|
+
const changed = `'{${extStr},' || substr(${EXT_BACK_PACK}, 2, length(${EXT_BACK_PACK})-1)`
|
|
33
|
+
const assign = `${EXT_BACK_PACK} = CASE WHEN ${EXT_BACK_PACK} IS NULL THEN '{${extStr}}' ELSE ${changed} END`
|
|
34
|
+
await tx.run(UPDATE(dbEntity).with(assign))
|
|
35
|
+
if (draft) await tx.run(UPDATE(draft).with(assign))
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = handleDefaults
|
|
File without changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { EXT_BACK_PACK, hasExtendedEntity, getTargetRead } = require('../utils')
|
|
2
2
|
|
|
3
|
-
const getTemplate = require('
|
|
4
|
-
const templateProcessor = require('
|
|
3
|
+
const getTemplate = require('../../common/utils/template')
|
|
4
|
+
const templateProcessor = require('../../common/utils/templateProcessor')
|
|
5
5
|
|
|
6
6
|
const _pick = element => {
|
|
7
7
|
return element['@cds.extension']
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { EXT_BACK_PACK, getTargetWrite, isExtendedEntity } = require('../utils')
|
|
2
2
|
|
|
3
|
-
const getTemplate = require('
|
|
4
|
-
const templateProcessor = require('
|
|
3
|
+
const getTemplate = require('../../common/utils/template')
|
|
4
|
+
const templateProcessor = require('../../common/utils/templateProcessor')
|
|
5
5
|
|
|
6
6
|
const _pick = element => {
|
|
7
7
|
return element['@cds.extension']
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const cds = require('../cds')
|
|
4
|
+
|
|
5
|
+
const activate = require('./activate')
|
|
6
|
+
const { validateExtension } = require('./validation')
|
|
7
|
+
const { collectFiles, getCompilerError, exists } = require('./utils')
|
|
8
|
+
const { packTarArchive, unpackTarArchive } = require('../../../lib/utils/resources')
|
|
9
|
+
|
|
10
|
+
const TEMP_DIR = fs.realpathSync(require('os').tmpdir())
|
|
11
|
+
|
|
12
|
+
const _compileProject = async function (extension, req) {
|
|
13
|
+
let csn, root
|
|
14
|
+
try {
|
|
15
|
+
root = await fs.promises.mkdtemp(`${TEMP_DIR}${path.sep}extension-`)
|
|
16
|
+
await unpackTarArchive(extension, root)
|
|
17
|
+
csn = await cds.compile(collectFiles(root, ['.cds', '.json']), { flavor: 'parsed' })
|
|
18
|
+
if (csn.requires) delete csn.requires
|
|
19
|
+
} catch (err) {
|
|
20
|
+
if (err.messages) req.reject(400, getCompilerError(err.messages))
|
|
21
|
+
else throw err
|
|
22
|
+
} finally {
|
|
23
|
+
if (await exists(root)) {
|
|
24
|
+
await (fs.promises.rm || fs.promises.rmdir)(root, { recursive: true, force: true })
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return csn
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const base = async function (req) {
|
|
32
|
+
const cdsFiles = cds.resolve('*').filter(f => f.startsWith(cds.root) && !f.includes('node_modules'))
|
|
33
|
+
const csvObj = await cds.deploy.resources()
|
|
34
|
+
const csvFiles = Object.keys(csvObj).filter(f => f.startsWith(cds.root) && !f.includes('node_modules'))
|
|
35
|
+
const i18nFiles = collectFiles(cds.root, ['.properties'])
|
|
36
|
+
if (req._.res) req._.res.set('content-type', 'application/octet-stream; charset=binary')
|
|
37
|
+
|
|
38
|
+
return packTarArchive([...cdsFiles, ...csvFiles, ...i18nFiles], cds.root)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const push = async function (req) {
|
|
42
|
+
let { extension } = req.data
|
|
43
|
+
if (!extension || !extension.data) req.reject(400, 'Missing extension')
|
|
44
|
+
const csn = await _compileProject(extension.data, req)
|
|
45
|
+
if (!csn) req.reject(400, 'Missing or bad extension')
|
|
46
|
+
const tenant = req.tenant
|
|
47
|
+
await validateExtension(csn, tenant, req)
|
|
48
|
+
|
|
49
|
+
const ID = cds.utils.uuid()
|
|
50
|
+
await cds.tx({ tenant }, async tx => {
|
|
51
|
+
await tx.run(
|
|
52
|
+
INSERT.into('cds.xt.Extensions').entries([
|
|
53
|
+
{ ID, csn: JSON.stringify(csn), sources: extension.data, activated: 'database' }
|
|
54
|
+
])
|
|
55
|
+
)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
await activate(ID, null, tenant)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = { base, push }
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const cds = require('../cds')
|
|
2
|
+
|
|
3
|
+
const addExtension = require('./addExtension')
|
|
4
|
+
const { add, promote } = require('./add')
|
|
5
|
+
const { base, push } = require('./push')
|
|
6
|
+
const { transformExtendedFieldsCREATE, transformExtendedFieldsUPDATE } = require('./handler/transformWRITE')
|
|
7
|
+
const { transformExtendedFieldsREAD } = require('./handler/transformREAD')
|
|
8
|
+
const { transformExtendedFieldsRESULT } = require('./handler/transformRESULT')
|
|
9
|
+
|
|
10
|
+
module.exports = async function () {
|
|
11
|
+
this.on('addExtension', addExtension)
|
|
12
|
+
this.on('add', add)
|
|
13
|
+
this.on('promote', promote)
|
|
14
|
+
this.on('base', base)
|
|
15
|
+
this.on('push', push)
|
|
16
|
+
cds.db
|
|
17
|
+
.before('CREATE', transformExtendedFieldsCREATE)
|
|
18
|
+
.before('UPDATE', transformExtendedFieldsUPDATE)
|
|
19
|
+
.before('READ', transformExtendedFieldsREAD)
|
|
20
|
+
.after('READ', transformExtendedFieldsRESULT)
|
|
21
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
|
|
4
|
+
const { ensureNoDraftsSuffix } = require('../common/utils/draft')
|
|
5
|
+
const { ensureUnlocalized } = require('../fiori/utils/handler')
|
|
3
6
|
|
|
4
7
|
const EXT_BACK_PACK = 'extensions__'
|
|
5
8
|
|
|
@@ -83,11 +86,44 @@ const getExtendedFields = (entityName, model) => {
|
|
|
83
86
|
})
|
|
84
87
|
}
|
|
85
88
|
|
|
89
|
+
const getCompilerError = messages => {
|
|
90
|
+
const defaultMsg = 'Error while compiling extension'
|
|
91
|
+
if (!messages) return defaultMsg
|
|
92
|
+
|
|
93
|
+
for (const msg of messages) {
|
|
94
|
+
if (msg.severity === 'Error') return msg.message
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return defaultMsg
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const collectFiles = (dir, extensions) => {
|
|
101
|
+
const files = []
|
|
102
|
+
fs.readdirSync(dir).forEach(file => {
|
|
103
|
+
const abs = path.join(dir, file)
|
|
104
|
+
if (fs.statSync(abs).isDirectory() && !abs.includes('node_modules')) files.push(...collectFiles(abs, extensions))
|
|
105
|
+
else if (!extensions || extensions.includes(path.extname(abs))) files.push(abs)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
return files
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const exists = async fileOrDir => {
|
|
112
|
+
try {
|
|
113
|
+
return await fs.promises.stat(fileOrDir)
|
|
114
|
+
} catch (_) {
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
86
119
|
module.exports = {
|
|
87
120
|
EXT_BACK_PACK,
|
|
88
121
|
getTargetRead,
|
|
89
122
|
getTargetWrite,
|
|
90
123
|
isExtendedEntity,
|
|
91
124
|
hasExtendedEntity,
|
|
92
|
-
getExtendedFields
|
|
125
|
+
getExtendedFields,
|
|
126
|
+
getCompilerError,
|
|
127
|
+
collectFiles,
|
|
128
|
+
exists
|
|
93
129
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const cds = require('../cds')
|
|
2
|
+
|
|
3
|
+
const { getCompilerError } = require('./utils')
|
|
4
|
+
|
|
5
|
+
const validateCsn = (csn, req) => {
|
|
6
|
+
if (!csn) req.reject(400, 'Missing extension')
|
|
7
|
+
if (!csn.extensions) return
|
|
8
|
+
|
|
9
|
+
csn.extensions.forEach(extension => {
|
|
10
|
+
if (!extension.extend || !cds.model.definitions[extension.extend]) {
|
|
11
|
+
req.reject(400, 'Invalid extension. Parameter "extend" missing or malformed')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (!extension.elements) {
|
|
15
|
+
req.reject(400, 'Invalid extension. Missing parameter "elements"')
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const validateExtensionFields = (csn, req) => {
|
|
21
|
+
if (!csn.extensions) return
|
|
22
|
+
|
|
23
|
+
csn.extensions.forEach(extension => {
|
|
24
|
+
if (extension.elements) {
|
|
25
|
+
Object.keys(extension.elements).forEach(name => {
|
|
26
|
+
if (!/^[A-Za-z]\w*$/.test(name)) {
|
|
27
|
+
req.reject(400, `Invalid extension. Bad element name "${name}"`)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (Object.keys(cds.model.definitions[extension.extend].elements).includes(name)) {
|
|
31
|
+
req.reject(400, `Invalid extension. Element "${name}" already exists`)
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const validateExtension = async (ext, tenant, req) => {
|
|
39
|
+
try {
|
|
40
|
+
const { 'cds.xt.ModelProviderService': mps } = cds.services
|
|
41
|
+
const csn = await mps.getCsn(tenant, ['*'])
|
|
42
|
+
const extCsn = cds.compile.to.json(ext)
|
|
43
|
+
await cds.compile.to.csn({ 'base.csn': JSON.stringify(csn), 'ext.csn': extCsn })
|
|
44
|
+
} catch (err) {
|
|
45
|
+
req.reject(400, getCompilerError(err.messages))
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = {
|
|
50
|
+
validateCsn,
|
|
51
|
+
validateExtensionFields,
|
|
52
|
+
validateExtension
|
|
53
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const _isProjection = target => target && target.query && target.query._target
|
|
2
|
+
|
|
3
|
+
const resolveViews = (target, views_ = []) => {
|
|
4
|
+
if (_isProjection(target)) {
|
|
5
|
+
views_.push(target)
|
|
6
|
+
return resolveViews(target.query._target, views_)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
return target
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = resolveViews
|
|
@@ -177,8 +177,6 @@ const _handler = async function (req) {
|
|
|
177
177
|
return result
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
module.exports = cds.service.impl(function () {
|
|
181
|
-
|
|
182
|
-
this.on('draftActivate', entity, _handler)
|
|
183
|
-
}
|
|
180
|
+
module.exports = cds.service.impl(function (srv, entity) {
|
|
181
|
+
srv.on('draftActivate', entity, _handler)
|
|
184
182
|
})
|