@sap/cds 5.9.8 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +252 -20
- package/apis/services.d.ts +1 -1
- package/app/fiori/preview.js +2 -6
- package/app/index.js +3 -3
- package/bin/build/buildTaskEngine.js +17 -15
- package/bin/build/buildTaskFactory.js +29 -19
- package/bin/build/buildTaskHandler.js +27 -11
- package/bin/build/buildTaskProvider.js +2 -4
- package/bin/build/buildTaskProviderFactory.js +11 -16
- package/bin/build/constants.js +14 -6
- package/bin/build/csv-reader.js +2 -1
- package/bin/build/index.js +12 -18
- package/bin/build/provider/buildTaskHandlerEdmx.js +3 -39
- package/bin/build/provider/buildTaskHandlerFeatureToggles.js +149 -0
- package/bin/build/provider/buildTaskHandlerInternal.js +2 -3
- package/bin/build/provider/buildTaskProviderInternal.js +108 -239
- package/bin/build/provider/fiori/index.js +2 -2
- package/bin/build/provider/hana/2migration.js +11 -11
- package/bin/build/provider/hana/2tabledata.js +3 -3
- package/bin/build/provider/hana/index.js +89 -99
- package/bin/build/provider/hana/migrationtable.js +4 -3
- package/bin/build/provider/java/index.js +101 -0
- package/bin/build/provider/java-cf/index.js +1 -101
- package/bin/build/provider/mtx/index.js +83 -41
- package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
- package/bin/build/provider/mtx-sidecar/index.js +80 -0
- package/bin/build/provider/node-cf/index.js +1 -308
- package/bin/build/provider/nodejs/index.js +189 -0
- package/bin/build/util.js +19 -31
- package/bin/cds.js +5 -3
- package/bin/deploy/to-hana/cfUtil.js +31 -6
- package/bin/deploy/to-hana/gitUtil.js +5 -3
- package/bin/deploy/to-hana/hana.js +9 -10
- package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
- package/bin/mtx/in-cds.js +19 -7
- package/bin/serve.js +56 -21
- package/bin/utils/log.js +13 -30
- package/bin/version.js +4 -3
- package/common.cds +61 -16
- package/lib/compile/cdsc.js +3 -2
- package/lib/compile/etc/_localized.js +15 -14
- package/lib/compile/for/drafts.js +3 -4
- package/lib/compile/for/java.js +13 -10
- package/lib/compile/for/nodejs.js +8 -8
- package/lib/compile/for/odata.js +7 -12
- package/lib/compile/for/sql.js +5 -6
- package/lib/compile/index.js +5 -4
- package/lib/compile/load.js +9 -11
- package/lib/compile/minify.js +8 -5
- package/lib/compile/parse.js +4 -2
- package/lib/compile/resolve.js +18 -15
- package/lib/compile/to/edm.js +0 -1
- package/lib/compile/to/gql.js +3 -2
- package/lib/compile/to/json.js +24 -17
- package/lib/connect/bindings.js +3 -2
- package/lib/connect/index.js +5 -5
- package/lib/core/classes.js +74 -2
- package/lib/core/entities.js +52 -3
- package/lib/core/reflect.js +2 -1
- package/lib/deploy.js +11 -8
- package/lib/env/defaults.js +4 -3
- package/lib/env/index.js +71 -31
- package/lib/env/presets.js +1 -14
- package/lib/env/requires.js +70 -20
- package/lib/env/serviceBindings.js +147 -0
- package/lib/i18n/localize.js +22 -23
- package/lib/index.js +148 -144
- package/lib/log/errors.js +55 -12
- package/lib/log/format/kibana.js +1 -1
- package/lib/log/index.js +4 -0
- package/lib/ql/SELECT.js +7 -2
- package/lib/ql/Whereable.js +8 -2
- package/lib/ql/index.js +2 -2
- package/lib/req/assert.js +71 -0
- package/lib/req/cds-context.js +38 -70
- package/lib/req/context.js +34 -21
- package/lib/req/request.js +12 -18
- package/lib/req/response.js +6 -2
- package/lib/req/user.js +30 -22
- package/lib/serve/Service-api.js +17 -12
- package/lib/serve/Service-dispatch.js +5 -9
- package/lib/serve/Service-methods.js +4 -3
- package/lib/serve/Transaction.js +24 -21
- package/lib/serve/adapters.js +15 -5
- package/lib/serve/factory.js +23 -20
- package/lib/serve/index.js +51 -54
- package/lib/utils/axios.js +8 -12
- package/lib/utils/index.js +3 -3
- package/lib/utils/resources/index.js +1 -44
- package/lib/utils/resources/tar.js +2 -1
- package/lib/utils/tests.js +13 -15
- package/libx/_runtime/.eslintrc +1 -1
- package/libx/_runtime/audit/Service.js +6 -4
- package/libx/_runtime/audit/generic/personal/access.js +19 -43
- package/libx/_runtime/audit/generic/personal/index.js +40 -34
- package/libx/_runtime/audit/generic/personal/modification.js +11 -9
- package/libx/_runtime/audit/generic/personal/utils.js +13 -6
- package/libx/_runtime/audit/utils/v2.js +6 -3
- package/libx/_runtime/auth/index.js +71 -66
- package/libx/_runtime/auth/strategies/JWT.js +3 -2
- package/libx/_runtime/auth/strategies/mock.js +54 -53
- package/libx/_runtime/auth/strategies/xssecUtils.js +3 -4
- package/libx/_runtime/auth/strategies/xsuaa.js +3 -2
- package/libx/_runtime/auth/utils.js +2 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +127 -41
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +93 -73
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +10 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -9
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +9 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +60 -53
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +8 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +29 -41
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -13
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectToCQN.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +24 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityContainer.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/PrimitiveValueDecoder.js +4 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/validator/ValueValidator.js +5 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/ResponseHeaderSetter.js +2 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DebugSerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/PresetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ContextURLFactory.js +3 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ErrorJsonSerializer.js +3 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/TrustedResourceJsonSerializer.js +3 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +36 -25
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +100 -91
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +382 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +5 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +77 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +3 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +91 -69
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +27 -6
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +7 -17
- package/libx/_runtime/cds-services/services/Service.js +17 -76
- package/libx/_runtime/cds-services/services/utils/columns.js +6 -4
- package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -53
- package/libx/_runtime/cds-services/services/utils/differ.js +15 -19
- package/libx/_runtime/cds-services/util/assert.js +107 -34
- package/libx/_runtime/cds.js +1 -31
- package/libx/_runtime/common/aspects/Association.js +40 -54
- package/libx/_runtime/common/aspects/any.js +61 -6
- package/libx/_runtime/common/aspects/entity.js +19 -79
- package/libx/_runtime/common/composition/data.js +2 -2
- package/libx/_runtime/common/composition/delete.js +8 -7
- package/libx/_runtime/common/composition/tree.js +10 -10
- package/libx/_runtime/common/composition/update.js +3 -2
- package/libx/_runtime/common/constants/events.js +15 -0
- package/libx/_runtime/common/error/entry.js +9 -3
- package/libx/_runtime/common/error/frontend.js +13 -19
- package/libx/_runtime/common/error/index.js +8 -3
- package/libx/_runtime/common/generic/auth/capabilities.js +2 -1
- package/libx/_runtime/common/generic/auth/constants.js +1 -4
- package/libx/_runtime/common/generic/auth/requires.js +1 -1
- package/libx/_runtime/common/generic/auth/restrict.js +12 -28
- package/libx/_runtime/common/generic/auth/restrictions.js +12 -4
- package/libx/_runtime/common/generic/auth/utils.js +2 -1
- package/libx/_runtime/common/generic/crud.js +9 -60
- package/libx/_runtime/common/generic/etag.js +41 -7
- package/libx/_runtime/common/generic/input.js +128 -66
- package/libx/_runtime/common/generic/paging.js +9 -3
- package/libx/_runtime/common/generic/put.js +2 -2
- package/libx/_runtime/common/generic/sorting.js +7 -3
- package/libx/_runtime/common/generic/temporal.js +0 -5
- package/libx/_runtime/common/i18n/messages.properties +2 -1
- package/libx/_runtime/common/utils/binary.js +69 -0
- package/libx/_runtime/common/utils/cqn.js +39 -14
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +93 -59
- package/libx/_runtime/common/utils/csn.js +87 -85
- package/libx/_runtime/common/utils/dollar.js +8 -7
- package/libx/_runtime/common/utils/draft.js +1 -1
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +23 -7
- package/libx/_runtime/common/utils/generateOnCond.js +2 -1
- package/libx/_runtime/common/utils/keys.js +30 -13
- package/libx/_runtime/common/utils/postProcessing.js +6 -1
- package/libx/_runtime/common/utils/quotingStyles.js +0 -23
- package/libx/_runtime/common/utils/resolveStructured.js +23 -26
- package/libx/_runtime/common/utils/resolveView.js +4 -1
- package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -0
- package/libx/_runtime/common/utils/search2cqn4sql.js +4 -13
- package/libx/_runtime/common/utils/searchToLike.js +9 -13
- package/libx/_runtime/common/utils/streamProp.js +35 -0
- package/libx/_runtime/common/utils/structured.js +12 -18
- package/libx/_runtime/common/utils/template.js +3 -5
- package/libx/_runtime/common/utils/templateProcessor.js +22 -14
- package/libx/_runtime/common/utils/unionCqnTemplate.js +4 -14
- package/libx/_runtime/db/Service.js +2 -1
- package/libx/_runtime/db/expand/expand-v2.js +2 -2
- package/libx/_runtime/db/expand/expandCQNToJoin.js +7 -6
- package/libx/_runtime/db/generic/input.js +14 -17
- package/libx/_runtime/db/generic/integrity.js +1 -2
- package/libx/_runtime/db/generic/update.js +14 -1
- package/libx/_runtime/db/query/read.js +0 -1
- package/libx/_runtime/db/query/update.js +1 -1
- package/libx/_runtime/db/sql-builder/BaseBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +5 -31
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +0 -9
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +11 -10
- package/libx/_runtime/db/sql-builder/UpdateBuilder.js +2 -2
- package/libx/_runtime/db/sql-builder/annotations.js +1 -2
- package/libx/_runtime/db/utils/coloredTxCommands.js +5 -0
- package/libx/_runtime/db/utils/columns.js +1 -1
- package/libx/_runtime/db/utils/propagateForeignKeys.js +10 -2
- package/libx/_runtime/extensibility/activate.js +69 -0
- package/libx/_runtime/extensibility/add.js +41 -0
- package/libx/_runtime/extensibility/addExtension.js +68 -0
- package/libx/_runtime/extensibility/defaults.js +39 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformREAD.js +0 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformRESULT.js +2 -2
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformWRITE.js +2 -2
- package/libx/_runtime/extensibility/push.js +61 -0
- package/libx/_runtime/extensibility/service.js +21 -0
- package/libx/_runtime/extensibility/{uiflex/utils.js → utils.js} +39 -3
- package/libx/_runtime/extensibility/validation.js +53 -0
- package/libx/_runtime/extensibility/views.js +12 -0
- package/libx/_runtime/fiori/generic/activate.js +6 -4
- package/libx/_runtime/fiori/generic/before.js +17 -29
- package/libx/_runtime/fiori/generic/cancel.js +2 -4
- package/libx/_runtime/fiori/generic/delete.js +2 -4
- package/libx/_runtime/fiori/generic/edit.js +3 -7
- package/libx/_runtime/fiori/generic/index.js +31 -0
- package/libx/_runtime/fiori/generic/new.js +2 -4
- package/libx/_runtime/fiori/generic/patch.js +4 -8
- package/libx/_runtime/fiori/generic/prepare.js +2 -4
- package/libx/_runtime/fiori/generic/read.js +137 -162
- package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
- package/libx/_runtime/fiori/utils/handler.js +10 -5
- package/libx/_runtime/fiori/utils/where.js +1 -4
- package/libx/_runtime/hana/Service.js +14 -7
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +1 -1
- package/libx/_runtime/hana/dynatrace.js +2 -2
- package/libx/_runtime/hana/localized.js +7 -6
- package/libx/_runtime/hana/pool.js +9 -6
- package/libx/_runtime/hana/search.js +2 -3
- package/libx/_runtime/hana/{searchToContains.js → search2Contains.js} +5 -2
- package/libx/_runtime/hana/search2cqn4sql.js +20 -17
- package/libx/_runtime/index.js +2 -6
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +11 -2
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -3
- package/libx/_runtime/messaging/common-utils/appId.js +9 -0
- package/libx/_runtime/messaging/common-utils/authorizedRequest.js +2 -18
- package/libx/_runtime/messaging/common-utils/connections.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +305 -231
- package/libx/_runtime/messaging/enterprise-messaging-utils/cloudEvents.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-management.js +15 -8
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-messaging.js +57 -14
- package/libx/_runtime/messaging/enterprise-messaging.js +14 -19
- package/libx/_runtime/messaging/file-based.js +2 -1
- package/libx/_runtime/messaging/http-utils/token.js +18 -6
- package/libx/_runtime/messaging/message-queuing-utils/options-management.js +22 -12
- package/libx/_runtime/messaging/message-queuing-utils/options-messaging.js +27 -14
- package/libx/_runtime/messaging/message-queuing.js +138 -85
- package/libx/_runtime/messaging/outbox/utils.js +13 -7
- package/libx/_runtime/messaging/redis-messaging.js +0 -1
- package/libx/_runtime/messaging/service.js +4 -1
- package/libx/_runtime/remote/Service.js +24 -18
- package/libx/_runtime/remote/utils/client.js +84 -46
- package/libx/_runtime/remote/utils/data.js +23 -6
- package/libx/_runtime/sqlite/Service.js +14 -13
- package/libx/_runtime/sqlite/convertAssocToOneManaged.js +2 -0
- package/libx/_runtime/sqlite/customBuilder/CustomSelectBuilder.js +1 -0
- package/libx/_runtime/sqlite/execute.js +3 -9
- package/libx/_runtime/types/api.js +23 -11
- package/libx/common/utils/ucsn.js +15 -9
- package/libx/odata/afterburner.js +109 -29
- package/libx/odata/cqn2odata.js +48 -9
- package/libx/odata/grammar.pegjs +261 -157
- package/libx/odata/index.js +21 -9
- package/libx/odata/parseToCqn.js +8 -5
- package/libx/odata/parser.js +1 -1
- package/libx/odata/utils.js +13 -3
- package/libx/rest/RestAdapter.js +173 -113
- package/libx/rest/RestRequest.js +3 -2
- package/libx/rest/middleware/create.js +8 -6
- package/libx/rest/middleware/delete.js +6 -13
- package/libx/rest/middleware/error.js +1 -1
- package/libx/rest/middleware/input.js +6 -6
- package/libx/rest/middleware/operation.js +8 -3
- package/libx/rest/middleware/parse.js +3 -3
- package/libx/rest/middleware/payload.js +12 -0
- package/libx/rest/middleware/read.js +12 -2
- package/libx/rest/middleware/update.js +3 -3
- package/package.json +4 -6
- package/server.js +3 -44
- package/srv/extensibility-service.cds +56 -0
- package/srv/extensibility-service.js +1 -0
- package/srv/extensions.cds +8 -0
- package/srv/model-provider.cds +59 -0
- package/srv/model-provider.js +163 -0
- package/srv/mtx.cds +2 -0
- package/srv/mtx.js +22 -0
- package/srv/outbox.cds +2 -0
- package/tasks/enterprise-messaging-deploy.js +19 -12
- package/lib/serve/Service-compat.js +0 -36
- package/libx/_runtime/audit/generic/personal/constants.js +0 -4
- package/libx/_runtime/auth/strategies/dwc.js +0 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/Rest.js +0 -183
- package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -67
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -82
- package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +0 -39
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +0 -63
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +0 -52
- package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +0 -81
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +0 -33
- package/libx/_runtime/cds-services/adapter/rest/to.js +0 -8
- package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +0 -50
- package/libx/_runtime/cds-services/adapter/rest/utils/data.js +0 -117
- package/libx/_runtime/cds-services/adapter/rest/utils/header-checks.js +0 -14
- package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +0 -30
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +0 -250
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +0 -26
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +0 -200
- package/libx/_runtime/common/aspects/utils.js +0 -152
- package/libx/_runtime/common/toggles/handler.js +0 -21
- package/libx/_runtime/common/utils/extensibilityUtils.js +0 -18
- package/libx/_runtime/extensibility/mps/index.js +0 -5
- package/libx/_runtime/extensibility/mps/service.js +0 -111
- package/libx/_runtime/extensibility/mps/tar.js +0 -42
- package/libx/_runtime/extensibility/mps/utils.js +0 -11
- package/libx/_runtime/extensibility/uiflex/index.js +0 -54
- package/libx/_runtime/extensibility/uiflex/service.js +0 -276
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +0 -20
- package/libx/_runtime/remote/utils/client-types.d.ts +0 -7
- package/libx/gql/GraphQLAdapter.js +0 -33
- package/libx/gql/constants/adapter.js +0 -69
- package/libx/gql/constants/cds.js +0 -18
- package/libx/gql/constants/graphql.js +0 -33
- package/libx/gql/readme.md +0 -1
- package/libx/gql/resolvers/crud/create.js +0 -20
- package/libx/gql/resolvers/crud/delete.js +0 -29
- package/libx/gql/resolvers/crud/index.js +0 -6
- package/libx/gql/resolvers/crud/read.js +0 -30
- package/libx/gql/resolvers/crud/update.js +0 -42
- package/libx/gql/resolvers/crud/utils/index.js +0 -36
- package/libx/gql/resolvers/field.js +0 -5
- package/libx/gql/resolvers/index.js +0 -7
- package/libx/gql/resolvers/mutation.js +0 -23
- package/libx/gql/resolvers/parse/ast/enrich.js +0 -52
- package/libx/gql/resolvers/parse/ast/fragment.js +0 -11
- package/libx/gql/resolvers/parse/ast/fromObject.js +0 -39
- package/libx/gql/resolvers/parse/ast/index.js +0 -3
- package/libx/gql/resolvers/parse/ast/meta.js +0 -4
- package/libx/gql/resolvers/parse/ast/variable.js +0 -7
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +0 -44
- package/libx/gql/resolvers/parse/ast2cqn/entries.js +0 -31
- package/libx/gql/resolvers/parse/ast2cqn/index.js +0 -8
- package/libx/gql/resolvers/parse/ast2cqn/limit.js +0 -6
- package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +0 -24
- package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +0 -3
- package/libx/gql/resolvers/parse/ast2cqn/where.js +0 -70
- package/libx/gql/resolvers/parse/utils/index.js +0 -8
- package/libx/gql/resolvers/query.js +0 -13
- package/libx/gql/resolvers/root.js +0 -34
- package/libx/gql/schema/generate.js +0 -18
- package/libx/gql/schema/index.js +0 -5
- package/libx/gql/schema/mutation.js +0 -76
- package/libx/gql/schema/query.js +0 -108
- package/libx/gql/schema/typeDefMap.js +0 -45
- package/libx/gql/schema/utils/index.js +0 -54
- package/libx/gql/utils/index.js +0 -12
- package/libx/rest/middleware/auth.js +0 -20
- package/libx/rest/middleware/content.js +0 -19
- package/srv/flex.cds +0 -21
- package/srv/flex.js +0 -1
- package/srv/mps.cds +0 -23
- package/srv/mps.js +0 -1
- package/srv/outbox.js +0 -0
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @typedef {object} ColumnRef
|
|
5
5
|
* @property {Array<string>} ref
|
|
6
|
+
* @property {function} func
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
* @property {*} value
|
|
18
19
|
* @property {Array} errors
|
|
19
20
|
* @property {string} [key]
|
|
20
|
-
* @property {
|
|
21
|
+
* @property {pathSegment[]} [pathSegments]
|
|
21
22
|
* @property {string} event
|
|
22
23
|
*/
|
|
23
24
|
|
|
@@ -49,7 +50,7 @@
|
|
|
49
50
|
* @typedef {object} TemplateProcessorPathOptions
|
|
50
51
|
* @property {object} [extraKeys]
|
|
51
52
|
* @property {function} [rowKeysGenerator]
|
|
52
|
-
* @property {
|
|
53
|
+
* @property {string[]} [segments=[]] - Path segments to relate the error message.
|
|
53
54
|
* @property {boolean} [includeKeyValues=false] Indicates whether the key values are included in the path segments
|
|
54
55
|
* The path segments are used to build the error target (a relative resource path)
|
|
55
56
|
*/
|
|
@@ -64,20 +65,14 @@
|
|
|
64
65
|
*/
|
|
65
66
|
|
|
66
67
|
/**
|
|
67
|
-
* @typedef {object}
|
|
68
|
+
* @typedef {object} templateElementInfo
|
|
68
69
|
* @property {object} row
|
|
69
70
|
* @property {string} key
|
|
70
71
|
* @property {object} element
|
|
71
72
|
* @property {boolean} plain
|
|
73
|
+
* @property {entity} target
|
|
72
74
|
* @property {boolean} isRoot
|
|
73
|
-
* @property {Array<
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @typedef {object} pathSegment
|
|
78
|
-
* @property {string} key
|
|
79
|
-
* @property {number} idx
|
|
80
|
-
* @property {string} url
|
|
75
|
+
* @property {Array<String>} [pathSegments]
|
|
81
76
|
*/
|
|
82
77
|
|
|
83
78
|
// Search
|
|
@@ -113,4 +108,21 @@
|
|
|
113
108
|
* @property {import('../db/Service')} [service]
|
|
114
109
|
*/
|
|
115
110
|
|
|
111
|
+
// Assert targets map
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @typedef {object} assertTargetMap
|
|
115
|
+
* @property {Map<string, targetMaps>} targets
|
|
116
|
+
* @property {targetMaps[]} allTargets
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @typedef {object} targetMaps
|
|
121
|
+
* @property {string} key
|
|
122
|
+
* @property {entity} entity
|
|
123
|
+
* @property {object} keys
|
|
124
|
+
* @property {object} foreignKey
|
|
125
|
+
* @property {templateElementInfo} assocInfo
|
|
126
|
+
*/
|
|
127
|
+
|
|
116
128
|
module.exports = {}
|
|
@@ -61,32 +61,38 @@ const _processor = ({ row, key, plain: { category }, element }) => {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
const _cleanup = (row, definition, cleanupNull) => {
|
|
64
|
+
const _cleanup = (row, definition, cleanupNull, cleanupStruct, prefix = []) => {
|
|
65
65
|
if (!row || !definition) return
|
|
66
66
|
const elements = definition.elements || definition.params
|
|
67
67
|
for (const key of Object.keys(row)) {
|
|
68
|
-
|
|
68
|
+
if (definition['@open']) continue
|
|
69
|
+
const element = elements[key] || (cleanupStruct && elements[`${prefix.join('_')}_${key}`])
|
|
69
70
|
if (!element) {
|
|
70
|
-
if (
|
|
71
|
+
if (cleanupStruct && typeof row[key] === 'object' && !Array.isArray(row[key])) {
|
|
72
|
+
_cleanup( row[key], definition, cleanupNull, cleanupStruct, [...prefix, key])
|
|
73
|
+
} else {
|
|
74
|
+
delete row[key]
|
|
75
|
+
}
|
|
71
76
|
continue
|
|
72
77
|
}
|
|
73
78
|
if (!row[key]) continue
|
|
74
79
|
if (element.isAssociation) {
|
|
75
80
|
if (element.is2many) {
|
|
76
81
|
for (const r of row[key]) {
|
|
77
|
-
_cleanup(r, element._target, cleanupNull)
|
|
82
|
+
_cleanup(r, element._target, cleanupNull, cleanupStruct, [])
|
|
78
83
|
}
|
|
79
84
|
} else {
|
|
80
|
-
_cleanup(row[key], element._target, cleanupNull)
|
|
85
|
+
_cleanup(row[key], element._target, cleanupNull, cleanupStruct, [])
|
|
81
86
|
}
|
|
82
87
|
} else if (element.elements) {
|
|
83
|
-
_cleanup(row[key], element, cleanupNull)
|
|
88
|
+
_cleanup(row[key], element, cleanupNull, cleanupStruct, prefix)
|
|
89
|
+
if (!Object.keys(row).length) delete row[key]
|
|
84
90
|
if (cleanupNull && Object.values(row[key]).every(v => v == null)) row[key] = null
|
|
85
91
|
}
|
|
86
92
|
}
|
|
87
93
|
}
|
|
88
94
|
|
|
89
|
-
function convertStructured(service, definition, data, { cleanupNull = false } = {}) {
|
|
95
|
+
function convertStructured(service, definition, data, { cleanupNull = false, cleanupStruct = false } = {}) {
|
|
90
96
|
if (!definition) return
|
|
91
97
|
// REVISIT check `structs` mode only for now as uCSN is not yet available
|
|
92
98
|
const flatAccess = cds.env.features.compat_flat_access
|
|
@@ -95,11 +101,11 @@ function convertStructured(service, definition, data, { cleanupNull = false } =
|
|
|
95
101
|
if (template && template.elements.size) {
|
|
96
102
|
for (let i = 0; i < arrayData.length; i++) {
|
|
97
103
|
const row = proxifyIfFlattened(definition, arrayData[i])
|
|
98
|
-
templateProcessor({ processFn: _processor, row, template
|
|
104
|
+
templateProcessor({ processFn: _processor, row, template })
|
|
99
105
|
}
|
|
100
106
|
}
|
|
101
107
|
for (const row of arrayData) {
|
|
102
|
-
_cleanup(row, definition, cleanupNull)
|
|
108
|
+
_cleanup(row, definition, cleanupNull, cleanupStruct)
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
111
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const cds = require('../_runtime/cds')
|
|
2
2
|
|
|
3
|
-
const { where2obj } = require('../_runtime/common/utils/cqn')
|
|
3
|
+
const { where2obj, resolveFromSelect } = require('../_runtime/common/utils/cqn')
|
|
4
4
|
const { findCsnTargetFor } = require('../_runtime/common/utils/csn')
|
|
5
5
|
|
|
6
6
|
const _addKeysDeep = (keys, keysCollector, ignoreManagedBacklinks) => {
|
|
@@ -52,14 +52,38 @@ function _resolveAliasInParams(params, entity) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
function
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
if (
|
|
59
|
-
|
|
55
|
+
function _resolveAliasesInRef(ref, target) {
|
|
56
|
+
if (ref.length === 1) {
|
|
57
|
+
if (target.keys[ref[0]]) return ref
|
|
58
|
+
if (target._alias2ref && target._alias2ref[ref[0]]) return [...target._alias2ref[ref[0]]]
|
|
59
|
+
}
|
|
60
|
+
for (const seg of ref) {
|
|
61
|
+
target = target.elements[seg.id || seg]
|
|
62
|
+
if (!target) return ref
|
|
63
|
+
if (target.isAssociation) {
|
|
64
|
+
target = target._target
|
|
65
|
+
if (seg.where) _resolveAliasesInXpr(seg.where, target)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return ref
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function _resolveAliasesInXpr(xpr, target) {
|
|
72
|
+
if (!target || !xpr) return
|
|
73
|
+
for (const el of xpr) {
|
|
74
|
+
if (el.xpr) _resolveAliasesInXpr(el.xpr, target)
|
|
75
|
+
if (el.args) _resolveAliasesInXpr(el.args, target)
|
|
76
|
+
if (el.ref) el.ref = _resolveAliasesInRef(el.ref, target)
|
|
60
77
|
}
|
|
61
78
|
}
|
|
62
79
|
|
|
80
|
+
function _resolveAliasesInNavigation(cqn, target) {
|
|
81
|
+
if (!target || !cqn) return
|
|
82
|
+
if (cqn.SELECT.from.SELECT) _resolveAliasesInNavigation(cqn.SELECT.from, target)
|
|
83
|
+
if (cqn.SELECT.where) _resolveAliasesInXpr(cqn.SELECT.where, target)
|
|
84
|
+
if (cqn.SELECT.having) _resolveAliasesInXpr(cqn.SELECT.having, target)
|
|
85
|
+
}
|
|
86
|
+
|
|
63
87
|
function _addDefaultParams(ref, view) {
|
|
64
88
|
const params = view.params
|
|
65
89
|
const defaults = params && Object.values(params).filter(p => p.default)
|
|
@@ -87,9 +111,8 @@ function addRefToWhereIfNecessary(where, entity) {
|
|
|
87
111
|
return 1
|
|
88
112
|
}
|
|
89
113
|
|
|
90
|
-
function _processSegments(
|
|
91
|
-
const
|
|
92
|
-
const ref = from.ref
|
|
114
|
+
function _processSegments(from, model, namespace) {
|
|
115
|
+
const { ref } = from
|
|
93
116
|
|
|
94
117
|
let current = model
|
|
95
118
|
let path
|
|
@@ -97,13 +120,14 @@ function _processSegments(cqn, model, namespace) {
|
|
|
97
120
|
let keyCount = 0
|
|
98
121
|
let incompleteKeys
|
|
99
122
|
let one
|
|
123
|
+
let target
|
|
100
124
|
for (let i = 0; i < ref.length; i++) {
|
|
101
125
|
const seg = ref[i].id || ref[i]
|
|
102
126
|
let params = ref[i].where && where2obj(ref[i].where)
|
|
103
127
|
|
|
104
128
|
if (incompleteKeys) {
|
|
105
129
|
// > key
|
|
106
|
-
keys = keys || _keysOf(current,
|
|
130
|
+
keys = keys || _keysOf(current, cds.env.features.odata_new_parser) // if odata, skip backlinks as key as they are used from structure
|
|
107
131
|
let key = keys[keyCount++]
|
|
108
132
|
one = true
|
|
109
133
|
const element = current.elements[key]
|
|
@@ -118,7 +142,9 @@ function _processSegments(cqn, model, namespace) {
|
|
|
118
142
|
.join(',')})`
|
|
119
143
|
base.where.push({ ref: [key] }, '=', { val })
|
|
120
144
|
} else {
|
|
121
|
-
|
|
145
|
+
const val =
|
|
146
|
+
element._type === 'cds.Integer' ? Number(seg) : element._type === 'cds.Boolean' ? seg === 'true' : seg
|
|
147
|
+
base.where.push({ ref: [key] }, '=', { val })
|
|
122
148
|
}
|
|
123
149
|
ref[i] = null
|
|
124
150
|
ref[i - keyCount] = base
|
|
@@ -137,9 +163,10 @@ function _processSegments(cqn, model, namespace) {
|
|
|
137
163
|
|
|
138
164
|
if (current.params && current.kind === 'entity') {
|
|
139
165
|
// > View with params
|
|
166
|
+
target = current
|
|
140
167
|
if (ref[i].where) {
|
|
141
168
|
keyCount += addRefToWhereIfNecessary(ref[i].where, current)
|
|
142
|
-
|
|
169
|
+
_resolveAliasesInXpr(ref[i].where, current)
|
|
143
170
|
_resolveAliasInParams(params, current)
|
|
144
171
|
}
|
|
145
172
|
|
|
@@ -149,10 +176,12 @@ function _processSegments(cqn, model, namespace) {
|
|
|
149
176
|
_checkAllKeysProvided(params, current)
|
|
150
177
|
|
|
151
178
|
ref[i].args = {}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
179
|
+
|
|
180
|
+
const where = ref[i].where
|
|
181
|
+
for (let j = 0; j < where.length; j++) {
|
|
182
|
+
const whereElement = where[j]
|
|
183
|
+
if (whereElement === 'and' || !whereElement.ref) continue
|
|
184
|
+
ref[i].args[whereElement.ref[0]] = where[j + 2]
|
|
156
185
|
j += 2
|
|
157
186
|
}
|
|
158
187
|
ref[i].where = undefined
|
|
@@ -163,11 +192,12 @@ function _processSegments(cqn, model, namespace) {
|
|
|
163
192
|
ref[++i] = null
|
|
164
193
|
} else if (current.kind === 'entity') {
|
|
165
194
|
// > entity
|
|
195
|
+
target = current
|
|
166
196
|
one = !!(ref[i].where || current._isSingleton)
|
|
167
197
|
incompleteKeys = ref[i].where ? false : i === ref.length - 1 || one ? false : true
|
|
168
198
|
if (ref[i].where) {
|
|
169
199
|
keyCount += addRefToWhereIfNecessary(ref[i].where, current)
|
|
170
|
-
|
|
200
|
+
_resolveAliasesInXpr(ref[i].where, current)
|
|
171
201
|
_resolveAliasInParams(params, current)
|
|
172
202
|
// in case of Foo(1), params will be {} (before addRefToWhereIfNecessary was called)
|
|
173
203
|
if (!Object.keys(params).length) params = where2obj(ref[i].where)
|
|
@@ -187,14 +217,14 @@ function _processSegments(cqn, model, namespace) {
|
|
|
187
217
|
one = !!(current.is2one || ref[i].where)
|
|
188
218
|
incompleteKeys = one || i === ref.length - 1 ? false : true
|
|
189
219
|
current = model.definitions[current.target]
|
|
220
|
+
target = current
|
|
190
221
|
if (ref[i].where) {
|
|
191
222
|
keyCount += addRefToWhereIfNecessary(ref[i].where, current)
|
|
192
|
-
|
|
223
|
+
_resolveAliasesInXpr(ref[i].where, current)
|
|
193
224
|
}
|
|
194
225
|
} else if (current._isStructured) {
|
|
195
226
|
// > nested property
|
|
196
227
|
one = true
|
|
197
|
-
current = current.elements
|
|
198
228
|
} else {
|
|
199
229
|
// > property
|
|
200
230
|
one = true
|
|
@@ -217,15 +247,42 @@ function _processSegments(cqn, model, namespace) {
|
|
|
217
247
|
// remove all nulled refs
|
|
218
248
|
from.ref = ref.filter(r => r)
|
|
219
249
|
|
|
220
|
-
|
|
221
|
-
if (one) cqn.SELECT.one = true
|
|
222
|
-
|
|
223
|
-
// REVISIT: better
|
|
224
|
-
// set target (csn definition) for later retrieval
|
|
225
|
-
cqn.__target = current
|
|
250
|
+
return { one, current, target }
|
|
226
251
|
}
|
|
227
252
|
|
|
228
|
-
const
|
|
253
|
+
const AGGREGATION_DEFAULT = '@Aggregation.default'
|
|
254
|
+
|
|
255
|
+
function _processColumns(cqn, target) {
|
|
256
|
+
if (cqn.SELECT.from.SELECT) _processColumns(cqn.SELECT.from, target)
|
|
257
|
+
|
|
258
|
+
const columns = cqn.SELECT.columns
|
|
259
|
+
|
|
260
|
+
if (!Array.isArray(columns)) return
|
|
261
|
+
|
|
262
|
+
let aggrProp, aggrElem
|
|
263
|
+
for (let i = 0; i < columns.length; i++) {
|
|
264
|
+
if (
|
|
265
|
+
columns[i].func === null &&
|
|
266
|
+
columns[i].args &&
|
|
267
|
+
columns[i].args.length &&
|
|
268
|
+
columns[i].args[0].ref &&
|
|
269
|
+
columns[i].args[0].ref.length
|
|
270
|
+
) {
|
|
271
|
+
// REVISIT: also support aggregate(Sales/Amount)?
|
|
272
|
+
aggrProp = columns[i].args[0].ref[0]
|
|
273
|
+
aggrElem = target.elements[aggrProp]
|
|
274
|
+
if (
|
|
275
|
+
aggrElem &&
|
|
276
|
+
target[`@Aggregation.CustomAggregate#${aggrProp}`] &&
|
|
277
|
+
aggrElem[AGGREGATION_DEFAULT] &&
|
|
278
|
+
aggrElem[AGGREGATION_DEFAULT]['#']
|
|
279
|
+
) {
|
|
280
|
+
columns[i].func = aggrElem[AGGREGATION_DEFAULT]['#'].toLowerCase()
|
|
281
|
+
columns[i].as = columns[i].as || aggrProp
|
|
282
|
+
} else throw new Error(`Default aggregation for property '${aggrProp}' not found.`)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
229
286
|
|
|
230
287
|
const _checkAllKeysProvided = (params, entity) => {
|
|
231
288
|
let keysOfEntity
|
|
@@ -267,13 +324,21 @@ function _4service(service) {
|
|
|
267
324
|
const { namespace, model } = service
|
|
268
325
|
|
|
269
326
|
return cqn => {
|
|
270
|
-
const
|
|
327
|
+
const from = resolveFromSelect(cqn)
|
|
328
|
+
const { ref } = from
|
|
271
329
|
|
|
272
330
|
// REVISIT: shouldn't be necessary
|
|
331
|
+
//Second findCsnTargetFor is required for concat query, where the root is already identified with the first query and subsequent queries already have correct root
|
|
273
332
|
/*
|
|
274
333
|
* make first path segment fully qualified
|
|
275
334
|
*/
|
|
276
|
-
const root =
|
|
335
|
+
const root =
|
|
336
|
+
findCsnTargetFor(ref[0].id || ref[0], model, namespace) ||
|
|
337
|
+
findCsnTargetFor(
|
|
338
|
+
ref[0].id?.split('.')[ref[0].id?.split('.').length - 1] || ref[0].split('.')[ref[0].split('.').length - 1],
|
|
339
|
+
model,
|
|
340
|
+
namespace
|
|
341
|
+
)
|
|
277
342
|
// REVISIT: 404 or 400?
|
|
278
343
|
if (!root) cds.error(`Invalid resource path "${namespace}.${ref[0].id || ref[0]}"`, { code: 404 })
|
|
279
344
|
if (ref[0].id) ref[0].id = root.name
|
|
@@ -282,7 +347,22 @@ function _4service(service) {
|
|
|
282
347
|
/*
|
|
283
348
|
* key vs. path segments (/Books/1/author/books/2/...) and more
|
|
284
349
|
*/
|
|
285
|
-
_processSegments(
|
|
350
|
+
const { one, current, target } = _processSegments(from, model, namespace)
|
|
351
|
+
|
|
352
|
+
// one?
|
|
353
|
+
if (one) cqn.SELECT.one = true
|
|
354
|
+
|
|
355
|
+
// REVISIT: better
|
|
356
|
+
// set target (csn definition) for later retrieval
|
|
357
|
+
cqn.__target = current
|
|
358
|
+
|
|
359
|
+
// target <=> endpoint entity, all navigation refs must be resolvable accordingly
|
|
360
|
+
if (cds.env.effective.odata.structs) _resolveAliasesInNavigation(cqn, target)
|
|
361
|
+
|
|
362
|
+
/*
|
|
363
|
+
* add default aggregation function (and alias)
|
|
364
|
+
*/
|
|
365
|
+
_processColumns(cqn, cqn.__target)
|
|
286
366
|
|
|
287
367
|
return cqn
|
|
288
368
|
}
|
package/libx/odata/cqn2odata.js
CHANGED
|
@@ -95,8 +95,8 @@ function _args(args) {
|
|
|
95
95
|
|
|
96
96
|
const _in = (column, /* in */ collection, target, kind, isLambda) => {
|
|
97
97
|
const ref = _format(column, null, target, kind, isLambda)
|
|
98
|
-
// {
|
|
99
|
-
const values = collection.
|
|
98
|
+
// { list: [ { val: 1}, { val: 2}, { val: 3} ] }
|
|
99
|
+
const values = collection.list
|
|
100
100
|
if (values && values.length) {
|
|
101
101
|
// REVISIT: what about OData `in` operator?
|
|
102
102
|
const expressions = values.map(value => `${ref}%20eq%20${_format(value, ref, target, kind, isLambda)}`)
|
|
@@ -117,7 +117,7 @@ const _odataV2Func = (func, args) => {
|
|
|
117
117
|
const _format = (cur, element, target, kind, isLambda) => {
|
|
118
118
|
if (typeof cur !== 'object') return encodeURIComponent(formatVal(cur, element, target, kind))
|
|
119
119
|
if (hasValidProps(cur, 'ref'))
|
|
120
|
-
return encodeURIComponent(isLambda ? [LAMBDA_VARIABLE, ...cur.ref].join('/') : cur.ref.join('/'))
|
|
120
|
+
return encodeURIComponent(isLambda ? [LAMBDA_VARIABLE, ...cur.ref].join('/') : cur.ref[0].id || cur.ref.join('/'))
|
|
121
121
|
if (hasValidProps(cur, 'val')) return encodeURIComponent(formatVal(cur.val, element, target, kind))
|
|
122
122
|
if (hasValidProps(cur, 'xpr')) return `(${_xpr(cur.xpr, target, kind, isLambda)})`
|
|
123
123
|
// REVISIT: How to detect the types for all functions?
|
|
@@ -196,9 +196,24 @@ const _keysOfWhere = (where, kind, target) => {
|
|
|
196
196
|
return `/${keys}`
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
if (where.length === 3) {
|
|
200
|
+
const [left, op, right] = where
|
|
201
|
+
if (op === '=' && (('val' in left && right.ref) || (left.ref && 'val' in right))) {
|
|
202
|
+
if ('val' in left) return `(${formatVal(left.val, right.ref.join('/'), target, kind)})`
|
|
203
|
+
return `(${formatVal(right.val, left.ref.join('/'), target, kind)})`
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
199
207
|
const res = []
|
|
200
208
|
for (const cur of where) {
|
|
201
209
|
if (hasValidProps(cur, 'ref')) {
|
|
210
|
+
if (target && target._alias2ref) {
|
|
211
|
+
const alias = target._alias2ref.__2alias[cur.ref.join('/')]
|
|
212
|
+
if (alias) {
|
|
213
|
+
res.push(_format({ ref: [alias] }))
|
|
214
|
+
continue
|
|
215
|
+
}
|
|
216
|
+
}
|
|
202
217
|
res.push(_format(cur))
|
|
203
218
|
} else if (hasValidProps(cur, 'val')) {
|
|
204
219
|
// find previous ref
|
|
@@ -228,6 +243,24 @@ function _getQueryTarget(entity, propOrEntity, model) {
|
|
|
228
243
|
}
|
|
229
244
|
}
|
|
230
245
|
|
|
246
|
+
const _params = (args, kind, target) => {
|
|
247
|
+
if (!args) {
|
|
248
|
+
throw new Error(`Incorrect call to a view with parameter "${target.name}"`)
|
|
249
|
+
}
|
|
250
|
+
const params = Object.keys(args)
|
|
251
|
+
if (params.length !== Object.keys(target.params).length) {
|
|
252
|
+
throw new Error('KEY_EXPECTED')
|
|
253
|
+
}
|
|
254
|
+
if (params.length === 1) {
|
|
255
|
+
return `(${formatVal(args[params[0]].val, params[0], target, kind)})`
|
|
256
|
+
}
|
|
257
|
+
const _params = []
|
|
258
|
+
for (const p of params) {
|
|
259
|
+
_params.push(`${_format({ ref: [p] })}=${formatVal(args[p].val, p, target, kind)}`)
|
|
260
|
+
}
|
|
261
|
+
return `(${_params.join(',')})`
|
|
262
|
+
}
|
|
263
|
+
|
|
231
264
|
function _from(from, kind, model) {
|
|
232
265
|
if (typeof from === 'string') {
|
|
233
266
|
return { url: _entityUrl(from), queryTarget: model && model.definitions[from] }
|
|
@@ -245,6 +278,11 @@ function _from(from, kind, model) {
|
|
|
245
278
|
queryTarget = model && _getQueryTarget(queryTarget, id, model)
|
|
246
279
|
const keys = _keysOfWhere(where, kind, queryTarget)
|
|
247
280
|
path.push(`${id}${keys}`)
|
|
281
|
+
} else if (hasValidProps(curRef, 'id') && 'args' in curRef) {
|
|
282
|
+
const { args, id } = curRef
|
|
283
|
+
queryTarget = model && _getQueryTarget(queryTarget, id, model)
|
|
284
|
+
const params = _params(args, kind, queryTarget)
|
|
285
|
+
path.push(`${id}${params}`)
|
|
248
286
|
} else if (typeof curRef === 'string') {
|
|
249
287
|
queryTarget = model && _getQueryTarget(queryTarget, curRef, model)
|
|
250
288
|
path.push(curRef)
|
|
@@ -288,7 +326,7 @@ const _parseColumns = columns => {
|
|
|
288
326
|
let refName = _format(column)
|
|
289
327
|
if (hasValidProps(column, 'expand')) {
|
|
290
328
|
// REVISIT: incomplete, see test Foo?$expand=invoices($count=true;$expand=item($search="some"))
|
|
291
|
-
if (!columns.some(c => !c.expand)) select.push(refName)
|
|
329
|
+
if (!columns.some(c => !c.expand) && !column.ref[0].id) select.push(refName)
|
|
292
330
|
const curOptions = getOptions(column).join(';')
|
|
293
331
|
refName += curOptions ? `(${curOptions})` : ''
|
|
294
332
|
expand.push(refName)
|
|
@@ -429,7 +467,8 @@ const parsers = {
|
|
|
429
467
|
orderBy: (cqnPart, url, kind, target, isCount) => !isCount && $orderBy(cqnPart),
|
|
430
468
|
count: (cqnPart, url, kind, target, isCount) => !isCount && $count(cqnPart, kind),
|
|
431
469
|
limit: (cqnPart, url, kind, target, isCount) => !isCount && $limit(cqnPart),
|
|
432
|
-
one: (cqnPart, url, kind, target, isCount) => !isCount && $one(cqnPart, url, kind)
|
|
470
|
+
one: (cqnPart, url, kind, target, isCount) => !isCount && $one(cqnPart, url, kind),
|
|
471
|
+
ref: (cqnPart, url, kind, target, isCount) => cqnPart[0].where && $where(cqnPart[0].where, target, kind)
|
|
433
472
|
}
|
|
434
473
|
|
|
435
474
|
function getOptions(cqnPart, url, kind, target, isCount) {
|
|
@@ -484,7 +523,7 @@ const _copyData = data => {
|
|
|
484
523
|
return copied
|
|
485
524
|
}
|
|
486
525
|
|
|
487
|
-
const _update = (cqn, kind, model) => {
|
|
526
|
+
const _update = (cqn, kind, model, method) => {
|
|
488
527
|
const UPDATE = getProp(cqn, 'UPDATE')
|
|
489
528
|
const { url, queryTarget } = _from(getProp(UPDATE, 'entity'), kind, model)
|
|
490
529
|
let keys = ''
|
|
@@ -498,7 +537,7 @@ const _update = (cqn, kind, model) => {
|
|
|
498
537
|
|
|
499
538
|
// TODO: support for .set as well
|
|
500
539
|
const body = _copyData(UPDATE.data)
|
|
501
|
-
return { method: 'PATCH', path: `${url}${keys}`, body }
|
|
540
|
+
return { method: method || 'PATCH', path: `${url}${keys}`, body }
|
|
502
541
|
}
|
|
503
542
|
|
|
504
543
|
const _delete = (cqn, kind, model) => {
|
|
@@ -517,10 +556,10 @@ const _delete = (cqn, kind, model) => {
|
|
|
517
556
|
return { method: 'DELETE', path: `${url}${keys}` }
|
|
518
557
|
}
|
|
519
558
|
|
|
520
|
-
function cqn2odata(cqn, kind, model) {
|
|
559
|
+
function cqn2odata(cqn, { kind, model, method }) {
|
|
521
560
|
if (cqn.SELECT) return _select(cqn, kind, model)
|
|
522
561
|
if (cqn.INSERT) return _insert(cqn, kind, model)
|
|
523
|
-
if (cqn.UPDATE) return _update(cqn, kind, model)
|
|
562
|
+
if (cqn.UPDATE) return _update(cqn, kind, model, method)
|
|
524
563
|
if (cqn.DELETE) return _delete(cqn, kind, model)
|
|
525
564
|
|
|
526
565
|
throw new Error('Unknown CQN object cannot be translated to URL: ' + JSON.stringify(cqn))
|