@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
package/libx/odata/grammar.pegjs
CHANGED
|
@@ -32,19 +32,21 @@
|
|
|
32
32
|
const stack = []
|
|
33
33
|
let SELECT, count
|
|
34
34
|
const TECHNICAL_OPTS = ['$value'] // odata parts to be handled somewhere else
|
|
35
|
-
|
|
36
35
|
// we keep that here to allow for usage in https://pegjs.org/online
|
|
37
|
-
const safeNumber =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
const safeNumber =
|
|
37
|
+
options.safeNumber ||
|
|
38
|
+
function (str) {
|
|
39
|
+
const n = Number(str)
|
|
40
|
+
return Number.isSafeInteger(n) ? n : str
|
|
41
|
+
}
|
|
42
|
+
const standardBase64 =
|
|
43
|
+
options.standardBase64 ||
|
|
44
|
+
function (str) {
|
|
45
|
+
// convert url-safe to standard base64 (with padding, if necessary)
|
|
46
|
+
return Buffer.from(str, 'base64').toString('base64')
|
|
47
|
+
}
|
|
48
|
+
const _compareRefs = col => exp =>
|
|
49
|
+
col === exp ||
|
|
48
50
|
(col.as && exp.as && col.as === exp.as) ||
|
|
49
51
|
(exp.as && col.ref && exp.as === col.ref[col.ref.length - 1]) ||
|
|
50
52
|
(col.ref && exp.ref && col.ref.join('') === exp.ref.join(''))
|
|
@@ -78,35 +80,80 @@
|
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
const _handleApply = (cqn, apply, onlyColumnsFromExpand = false) => {
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
if (apply.where) {
|
|
87
|
-
if (cqn.where) cqn.from.SELECT.where = apply.where
|
|
88
|
-
else cqn.where = apply.where
|
|
89
|
-
}
|
|
90
|
-
if (apply.search) {
|
|
91
|
-
if (cqn.search) cqn.from.SELECT.search = apply.search
|
|
92
|
-
else cqn.search = apply.search
|
|
93
|
-
}
|
|
94
|
-
if (apply.groupBy) {
|
|
95
|
-
cqn.groupBy = []
|
|
96
|
-
for (const col of apply.groupBy) {
|
|
97
|
-
if (!cqn.groupBy.find(_compareRefs(col))) cqn.groupBy.push(col)
|
|
83
|
+
let newCqn = _convertApply({ from: cqn.from }, apply, onlyColumnsFromExpand)
|
|
84
|
+
if (Array.isArray(newCqn)) {
|
|
85
|
+
for (let i = 0; i < newCqn.length; i++) {
|
|
86
|
+
newCqn[i] = _addNormalQueryOptions(newCqn[i], cqn, onlyColumnsFromExpand)
|
|
98
87
|
}
|
|
88
|
+
} else newCqn = _addNormalQueryOptions(newCqn, cqn, onlyColumnsFromExpand)
|
|
89
|
+
|
|
90
|
+
return newCqn
|
|
91
|
+
}
|
|
92
|
+
const _addNormalQueryOptions = (cqn, topCqn, onlyColumnsFromExpand) => {
|
|
93
|
+
if (!topCqn) return cqn
|
|
94
|
+
if (topCqn.apply) delete topCqn.apply
|
|
95
|
+
let newCqn = {}
|
|
96
|
+
if (
|
|
97
|
+
(topCqn.columns && topCqn.columns[0].as === '$count') ||
|
|
98
|
+
(cqn.SELECT.where && topCqn.where) ||
|
|
99
|
+
(cqn.SELECT.limit && topCqn.limit) ||
|
|
100
|
+
(cqn.SELECT.orderBy && topCqn.orderBy) ||
|
|
101
|
+
(cqn.SELECT.search && topCqn.search)
|
|
102
|
+
) {
|
|
103
|
+
newCqn.from = cqn
|
|
104
|
+
} else newCqn = cqn.SELECT
|
|
105
|
+
for (const queryOption in topCqn) {
|
|
106
|
+
if (queryOption === 'columns') {
|
|
107
|
+
topCqn.columns = topCqn.columns.map(topCol => {
|
|
108
|
+
if (newCqn.columns)
|
|
109
|
+
return (
|
|
110
|
+
newCqn.columns.find(
|
|
111
|
+
col =>
|
|
112
|
+
(topCol.ref && topCol.ref[0] === col.as) ||
|
|
113
|
+
(col.ref && topCol.ref && topCol.ref[0] === col.ref[0] && !topCol.expand)
|
|
114
|
+
) || topCol
|
|
115
|
+
)
|
|
116
|
+
return topCol
|
|
117
|
+
})
|
|
118
|
+
if (newCqn.columns && newCqn.groupBy)
|
|
119
|
+
topCqn.columns.push(
|
|
120
|
+
...(newCqn.columns.filter(
|
|
121
|
+
col =>
|
|
122
|
+
onlyColumnsFromExpand &&
|
|
123
|
+
newCqn.groupBy.find(group => col.ref && col.ref[0] === group.ref[0]) &&
|
|
124
|
+
!topCqn.columns.some(
|
|
125
|
+
topCol =>
|
|
126
|
+
(topCol.ref && topCol.ref[0] === col.as) ||
|
|
127
|
+
(topCol.ref && col.ref && topCol.ref[0] === col.ref[0]) ||
|
|
128
|
+
(topCol.as && topCol.as === col.as)
|
|
129
|
+
)
|
|
130
|
+
) || [])
|
|
131
|
+
)
|
|
132
|
+
newCqn.columns = topCqn.columns
|
|
133
|
+
} else if (queryOption !== 'from') newCqn[queryOption] = topCqn[queryOption]
|
|
99
134
|
}
|
|
100
|
-
const aggregatedColumns = [
|
|
135
|
+
const aggregatedColumns = [
|
|
136
|
+
...((newCqn.columns &&
|
|
137
|
+
newCqn.columns.filter(
|
|
138
|
+
col => newCqn.groupBy && newCqn.groupBy.find(group => col.ref && col.ref[0] === group.ref[0])
|
|
139
|
+
)) ||
|
|
140
|
+
[]),
|
|
141
|
+
...((newCqn.columns && newCqn.columns.filter(col => col && typeof col === 'object' && 'func' in col)) || [])
|
|
142
|
+
]
|
|
143
|
+
_handleAggregatedColumns(newCqn, aggregatedColumns, onlyColumnsFromExpand)
|
|
144
|
+
return { SELECT: newCqn }
|
|
145
|
+
}
|
|
146
|
+
const _handleAggregatedColumns = (cqn, aggregatedColumns, onlyColumnsFromExpand) => {
|
|
101
147
|
if (aggregatedColumns.length) {
|
|
102
|
-
cqn.columns =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
148
|
+
cqn.columns =
|
|
149
|
+
cqn.columns && !onlyColumnsFromExpand
|
|
150
|
+
? // using .reduce instead of .filter since columns order might be important
|
|
151
|
+
cqn.columns.reduce((columns, col) => {
|
|
152
|
+
const aggregatedColumn = aggregatedColumns.find(_compareRefs(col))
|
|
153
|
+
if (aggregatedColumn) columns.push(aggregatedColumn)
|
|
154
|
+
return columns
|
|
155
|
+
}, [])
|
|
156
|
+
: aggregatedColumns
|
|
110
157
|
if (cqn.where) {
|
|
111
158
|
cqn.where = cqn.where.map(_remapFunc(cqn.columns))
|
|
112
159
|
if (cqn.groupBy) {
|
|
@@ -122,22 +169,72 @@
|
|
|
122
169
|
return columns
|
|
123
170
|
}, [])
|
|
124
171
|
}
|
|
125
|
-
|
|
172
|
+
}
|
|
173
|
+
const _convertApply = (cqn, apply, onlyColumnsFromExpand) => {
|
|
174
|
+
if (!apply) return
|
|
175
|
+
if (cqn.apply) delete cqn.apply
|
|
176
|
+
if (apply.identity && cqn.from.SELECT) cqn = cqn.from.SELECT
|
|
177
|
+
if (
|
|
178
|
+
apply.apply ||
|
|
179
|
+
(apply.where && cqn.where) ||
|
|
180
|
+
(apply.search && cqn.search) ||
|
|
181
|
+
(apply.limit && cqn.limit) ||
|
|
182
|
+
(apply.orderBy && cqn.orderBy)
|
|
183
|
+
) {
|
|
184
|
+
cqn.from = { SELECT: { ...cqn } }
|
|
185
|
+
}
|
|
186
|
+
if (apply.where) cqn.where = apply.where
|
|
187
|
+
if (apply.search) cqn.search = apply.search
|
|
188
|
+
if (apply.groupBy) {
|
|
189
|
+
cqn.groupBy = []
|
|
190
|
+
for (const col of apply.groupBy) {
|
|
191
|
+
if (!cqn.groupBy.find(_compareRefs(col))) cqn.groupBy.push(col)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (apply.limit) cqn.limit = apply.limit
|
|
195
|
+
if (apply.orderBy) cqn.orderBy = apply.orderBy
|
|
196
|
+
const aggregatedColumns = [...(cqn.groupBy || []), ...(apply.aggregate || [])]
|
|
197
|
+
_handleAggregatedColumns(cqn, aggregatedColumns, onlyColumnsFromExpand)
|
|
198
|
+
|
|
199
|
+
if (apply.apply && cqn.from) _convertApply(cqn.from.SELECT, apply.apply)
|
|
200
|
+
|
|
201
|
+
if (apply.concat && Array.isArray(apply.concat)) {
|
|
202
|
+
const additionalQueries = []
|
|
203
|
+
for (let select of apply.concat) {
|
|
204
|
+
select.from =
|
|
205
|
+
Object.keys(cqn).length === 1
|
|
206
|
+
? cqn.from
|
|
207
|
+
: { SELECT: cqn }
|
|
208
|
+
const nextCqn = _convertApply(select, select.apply)
|
|
209
|
+
if (Array.isArray(nextCqn)) additionalQueries.push(...nextCqn)
|
|
210
|
+
else additionalQueries.push(nextCqn)
|
|
211
|
+
}
|
|
212
|
+
cqn = additionalQueries
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (Array.isArray(cqn)) return cqn
|
|
216
|
+
return { SELECT: cqn }
|
|
126
217
|
}
|
|
127
218
|
const _setLimitOffset = val => {
|
|
128
219
|
if (SELECT.limit && SELECT.limit.offset && SELECT.limit.offset.val) {
|
|
129
220
|
val += SELECT.limit.offset.val
|
|
130
221
|
}
|
|
131
|
-
(SELECT.limit || (SELECT.limit={})).offset = {val}
|
|
222
|
+
;(SELECT.limit || (SELECT.limit = {})).offset = { val }
|
|
223
|
+
}
|
|
224
|
+
//Second parameter needed, to assure that order is correct
|
|
225
|
+
const _setOrderBy = (appendObj, first = false) => {
|
|
226
|
+
SELECT.orderBy = SELECT.orderBy
|
|
227
|
+
? first
|
|
228
|
+
? [appendObj, ...SELECT.orderBy]
|
|
229
|
+
: [...SELECT.orderBy, appendObj]
|
|
230
|
+
: [appendObj]
|
|
132
231
|
}
|
|
133
|
-
|
|
134
232
|
const _removeLambdaPrefix = (prefix, elements) => {
|
|
135
233
|
for (const e of elements) {
|
|
136
234
|
// remove the prefix identifier
|
|
137
235
|
if (e.ref && e.ref[0] === prefix) e.ref.shift()
|
|
138
236
|
if (e.func) _removeLambdaPrefix(prefix, e.args)
|
|
139
237
|
}
|
|
140
|
-
|
|
141
238
|
return elements
|
|
142
239
|
}
|
|
143
240
|
}
|
|
@@ -146,7 +243,7 @@
|
|
|
146
243
|
|
|
147
244
|
ODataRelativeURI // Note: case-sensitive!
|
|
148
245
|
= '/'? (p:path { SELECT = p })
|
|
149
|
-
( o"?"o QueryOption ( o'&'o QueryOption )* )? o {
|
|
246
|
+
( o"?"o QueryOption ( o'&'o QueryOption )* )? o "?"? o {
|
|
150
247
|
if (count) {
|
|
151
248
|
// columns set because of $count: ignore $select, $expand, $top, $skip, $orderby
|
|
152
249
|
// REVISIT: don't ignore query options but throw bad request (as okra did)?
|
|
@@ -154,10 +251,8 @@
|
|
|
154
251
|
delete SELECT.expand
|
|
155
252
|
delete SELECT.limit
|
|
156
253
|
delete SELECT.orderBy
|
|
157
|
-
if (SELECT.apply)
|
|
158
|
-
SELECT
|
|
159
|
-
_handleApply(SELECT, SELECT.apply)
|
|
160
|
-
}
|
|
254
|
+
if (SELECT.apply)
|
|
255
|
+
return _handleApply(SELECT, SELECT.apply)
|
|
161
256
|
return { SELECT }
|
|
162
257
|
}
|
|
163
258
|
let onlyColumnsFromExpand
|
|
@@ -174,8 +269,10 @@
|
|
|
174
269
|
}
|
|
175
270
|
delete SELECT.expand
|
|
176
271
|
}
|
|
177
|
-
if (SELECT.count && SELECT.apply)
|
|
178
|
-
|
|
272
|
+
if (SELECT.count && SELECT.apply)
|
|
273
|
+
SELECT.__countAggregated = true
|
|
274
|
+
if(SELECT.apply)
|
|
275
|
+
return _handleApply(SELECT, SELECT.apply, onlyColumnsFromExpand)
|
|
179
276
|
return { SELECT }
|
|
180
277
|
}
|
|
181
278
|
|
|
@@ -192,7 +289,6 @@
|
|
|
192
289
|
tail.from.ref.unshift('')
|
|
193
290
|
return tail
|
|
194
291
|
}
|
|
195
|
-
|
|
196
292
|
const [id, filter] = head
|
|
197
293
|
// minimal: val also as path segment
|
|
198
294
|
const ref = []
|
|
@@ -235,23 +331,22 @@
|
|
|
235
331
|
//
|
|
236
332
|
// ---------- Query Options ------------
|
|
237
333
|
|
|
238
|
-
QueryOption = ExpandOption /
|
|
334
|
+
QueryOption = option:ExpandOption { if(option && option.apply) SELECT.apply = option.apply} /
|
|
239
335
|
"$skiptoken=" o skiptoken /
|
|
240
|
-
|
|
241
|
-
SELECT.apply = {}
|
|
242
|
-
}) apply /
|
|
336
|
+
format /
|
|
243
337
|
custom
|
|
244
338
|
// @OData spec for $expand:
|
|
245
|
-
// "Allowed system query options are $filter, $select, $orderby, $skip, $top, $count, $search, and $
|
|
339
|
+
// "Allowed system query options are $filter, $select, $orderby, $skip, $top, $count, $search, $expand and $apply (http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/cs02/odata-data-aggregation-ext-v4.0-cs02.html#_The_expand_Transformation)."
|
|
246
340
|
ExpandOption =
|
|
247
341
|
"$select=" o select ( COMMA select )* /
|
|
248
342
|
"$expand=" o expand ( COMMA expand )* /
|
|
249
343
|
"$filter=" o f:filter{SELECT.where = f} /
|
|
250
|
-
"$orderby=" o orderby ( COMMA orderby )* /
|
|
251
|
-
"$top=" o top /
|
|
252
|
-
"$skip=" o skip /
|
|
344
|
+
"$orderby=" o o:orderby ( COMMA o2:orderby{_setOrderBy(o2)} )* {_setOrderBy(o,true)} /
|
|
345
|
+
"$top=" o val:top{(SELECT.limit || (SELECT.limit={})).rows = {val}} /
|
|
346
|
+
"$skip=" o val:skip{_setLimitOffset(val)} /
|
|
253
347
|
"$search=" o s:search {if (s) SELECT.search = s} /
|
|
254
|
-
"$count=" o count
|
|
348
|
+
"$count=" o count /
|
|
349
|
+
"$apply=" o trafos:transformations {return trafos}
|
|
255
350
|
|
|
256
351
|
|
|
257
352
|
select
|
|
@@ -261,6 +356,7 @@
|
|
|
261
356
|
return col
|
|
262
357
|
}
|
|
263
358
|
|
|
359
|
+
//REVISIT: per OData spec $apply should be also supported inside of $expand
|
|
264
360
|
expand =
|
|
265
361
|
(
|
|
266
362
|
c:('*'/ref) {
|
|
@@ -277,8 +373,13 @@
|
|
|
277
373
|
SELECT = SELECT.expand[SELECT.expand.length-1]
|
|
278
374
|
SELECT.expand = '*' // by default expand everything
|
|
279
375
|
})(
|
|
280
|
-
expandOptions:( o ";"? o ExpandOption)*
|
|
376
|
+
expandOptions:( o ";"? o option:ExpandOption{return option})*
|
|
281
377
|
{
|
|
378
|
+
if (expandOptions.find(option => option && option.apply !== undefined)) {
|
|
379
|
+
const err = new Error("EXPAND_APPLY_UNSUPPORTED");
|
|
380
|
+
err.statusCode=501;
|
|
381
|
+
throw err;
|
|
382
|
+
}
|
|
282
383
|
if (SELECT.columns) {
|
|
283
384
|
if (SELECT.expand === '*') SELECT.expand = []
|
|
284
385
|
for (const col of SELECT.columns) {
|
|
@@ -299,28 +400,19 @@
|
|
|
299
400
|
err.statusCode=501;
|
|
300
401
|
throw err;
|
|
301
402
|
})?
|
|
302
|
-
|
|
303
403
|
top
|
|
304
|
-
= val:integer {
|
|
305
|
-
(SELECT.limit || (SELECT.limit={})).rows = {val}
|
|
306
|
-
}
|
|
307
|
-
|
|
404
|
+
= val:integer {return val}
|
|
308
405
|
skiptoken
|
|
309
406
|
= val:integer? skiptoken:skiptokenChars? {
|
|
310
407
|
// REVISIT ignore non-numeric $skiptoken as not supported by CQN
|
|
311
408
|
if (skiptoken) return
|
|
312
409
|
_setLimitOffset(val)
|
|
313
410
|
}
|
|
314
|
-
|
|
315
411
|
skip
|
|
316
|
-
= val:integer {
|
|
317
|
-
_setLimitOffset(val)
|
|
318
|
-
}
|
|
319
|
-
|
|
412
|
+
= val:integer {return val}
|
|
320
413
|
search
|
|
321
414
|
= p:search_clause {return p}
|
|
322
415
|
/ o // Do not add search property for space only
|
|
323
|
-
|
|
324
416
|
search_clause
|
|
325
417
|
= p:( n:NOT? {return n?[n]:[]} )(
|
|
326
418
|
OPEN xpr:search_clause CLOSE {p.push({xpr})}
|
|
@@ -331,10 +423,8 @@
|
|
|
331
423
|
)
|
|
332
424
|
)( ao:(AND/OR/AND_SPACE) more:search_clause {p.push(ao,...more)} )*
|
|
333
425
|
{return p}
|
|
334
|
-
|
|
335
426
|
filter
|
|
336
427
|
= p:where_clause { return p }
|
|
337
|
-
|
|
338
428
|
where_clause = p:( n:NOT? {return n?[n]:[]} )(
|
|
339
429
|
OPEN xpr:where_clause CLOSE {p.push({xpr})}
|
|
340
430
|
/ comp:comparison {p.push(...comp)}
|
|
@@ -349,7 +439,6 @@
|
|
|
349
439
|
/ val:bool {p.push({val})}
|
|
350
440
|
)( ao:(AND/OR) more:where_clause {p.push(ao,...more)} )*
|
|
351
441
|
{return p}
|
|
352
|
-
|
|
353
442
|
lambda =
|
|
354
443
|
nav:( n:identifier {return[n]} ) '/' ( n:identifier '/' {nav.push(n)} )*
|
|
355
444
|
xpr:(
|
|
@@ -365,7 +454,6 @@
|
|
|
365
454
|
xpr[k++] = each
|
|
366
455
|
}
|
|
367
456
|
}
|
|
368
|
-
|
|
369
457
|
if (xpr.length < any.length) {
|
|
370
458
|
id = nav.pop()
|
|
371
459
|
return ['exists', { ref: [...nav, { id, where: xpr }] }]
|
|
@@ -379,7 +467,6 @@
|
|
|
379
467
|
}
|
|
380
468
|
)
|
|
381
469
|
{ return xpr }
|
|
382
|
-
|
|
383
470
|
inner_lambda =
|
|
384
471
|
p:( n:NOT? { return n ? [n] : [] } )(
|
|
385
472
|
OPEN xpr:inner_lambda CLOSE { p.push('(', ...xpr, ')') }
|
|
@@ -389,48 +476,69 @@
|
|
|
389
476
|
)
|
|
390
477
|
( ao:(AND/OR) more:inner_lambda { p.push(ao, ...more) } )*
|
|
391
478
|
{ return p }
|
|
392
|
-
|
|
393
479
|
lambda_clause = prefix:identifier ":" inner:inner_lambda {
|
|
394
480
|
return _removeLambdaPrefix(prefix, inner)
|
|
395
481
|
}
|
|
396
|
-
|
|
397
482
|
any = "any" OPEN p:lambda_clause? CLOSE { return p }
|
|
398
|
-
|
|
399
483
|
all = "all" OPEN p:lambda_clause CLOSE { return p }
|
|
400
|
-
|
|
401
484
|
orderby
|
|
402
485
|
= ref:(lambda{const err = new Error("ORDERBY_LAMBDA_UNSUPPORTED");err.statusCode=501;throw err;}/function/ref) sort:( _ s:$("asc"/"desc") {return s})? {
|
|
403
486
|
// TODO: Lambda support
|
|
404
487
|
const appendObj = $(ref, sort && {sort});
|
|
405
|
-
|
|
406
|
-
[...SELECT.orderBy, appendObj] :
|
|
407
|
-
[appendObj]
|
|
488
|
+
return appendObj;
|
|
408
489
|
}
|
|
409
|
-
|
|
410
490
|
count
|
|
411
491
|
= val:bool { if(val) SELECT.count = true }
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
492
|
+
transformations
|
|
493
|
+
= mainTransformation:trafo additionalTransformation:("/" t2:trafo {
|
|
494
|
+
return t2
|
|
495
|
+
})* {
|
|
496
|
+
if(mainTransformation === undefined) return
|
|
497
|
+
additionalTransformation = (Array.isArray(additionalTransformation)) ? additionalTransformation : [additionalTransformation]
|
|
498
|
+
//Loop through additionalTransformation
|
|
499
|
+
//Loop through each element, add it to current level, if element is already part of result, increase level
|
|
500
|
+
for(let trafos of additionalTransformation) {
|
|
501
|
+
for(const trafo in trafos) {
|
|
502
|
+
if (trafo === 'limit' && trafos.limit && mainTransformation.limit && mainTransformation.limit.offset && trafos.limit.rows)
|
|
503
|
+
mainTransformation.limit.rows = trafos.limit.rows
|
|
504
|
+
else if(
|
|
505
|
+
mainTransformation[trafo] ||
|
|
506
|
+
(trafo === 'groupBy' && (mainTransformation.where || mainTransformation.search)) ||
|
|
507
|
+
(trafo === 'aggregate' && 'groupBy' in mainTransformation && !('groupBy' in trafos))
|
|
508
|
+
) {
|
|
509
|
+
let _apply = mainTransformation
|
|
510
|
+
mainTransformation = { apply: _apply }
|
|
511
|
+
if (trafo === 'limit' && trafos[trafo].offset && _apply.limit && _apply.limit.offset && _apply.limit.offset.val)
|
|
512
|
+
trafos[trafo].offset += _apply.limit.offset.val
|
|
513
|
+
|
|
514
|
+
_apply = mainTransformation
|
|
515
|
+
_apply[trafo] = trafos[trafo]
|
|
516
|
+
} else {
|
|
517
|
+
mainTransformation[trafo] = trafos[trafo]
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return {apply: mainTransformation}
|
|
522
|
+
}
|
|
416
523
|
custom = [a-zA-Z] [a-zA-Z0-9-]* "=" [^&]*
|
|
417
|
-
|
|
524
|
+
format = "$format=" f:$([^&]*) {
|
|
525
|
+
if (f.toLowerCase() !== "json") {
|
|
526
|
+
const err = new Error("ONLY_QUERY_PARAM_FORMAT_JSON_ALLOWED")
|
|
527
|
+
err.statusCode = 501
|
|
528
|
+
throw err;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
418
531
|
//
|
|
419
532
|
// ---------- Expressions ------------
|
|
420
|
-
|
|
421
|
-
|
|
422
533
|
comparison "a comparison"
|
|
423
534
|
= a:operand _ o:$("eq"/"ne"/"lt"/"gt"/"le"/"ge") _ b:operand {
|
|
424
535
|
const op = { eq:'=', ne:'!=', lt:'<', gt:'>', le:'<=', ge:'>=' }[o]||o
|
|
425
536
|
return [ a, op, b ]
|
|
426
537
|
}
|
|
427
|
-
|
|
428
538
|
mathCalc
|
|
429
539
|
= operand (_ ("add" / "sub" / "mul" / "div" / "mod") _ operand)*
|
|
430
|
-
|
|
431
540
|
operand "an operand"
|
|
432
541
|
= navigationCount / function / val / ref / jsonObject / jsonArray / list
|
|
433
|
-
|
|
434
542
|
navigationCount "navigation with $count"
|
|
435
543
|
= navigationPath:(head:identifier key:(OPEN keyArgs:args CLOSE {return keyArgs;})? '/' {
|
|
436
544
|
if (key) {
|
|
@@ -440,26 +548,21 @@
|
|
|
440
548
|
return head;
|
|
441
549
|
})+ count: '$count'
|
|
442
550
|
{ return {func: 'count', as: '$count', args: [{ref: navigationPath}]} }
|
|
443
|
-
|
|
444
551
|
ref "a reference"
|
|
445
552
|
= head:identifier tail:( '/' n:identifier {return n})*
|
|
446
553
|
{
|
|
447
554
|
if (head === "null") {
|
|
448
555
|
return { val: null }
|
|
449
556
|
}
|
|
450
|
-
|
|
451
557
|
return { ref:[ head, ...tail ] }
|
|
452
558
|
}
|
|
453
|
-
|
|
454
559
|
val
|
|
455
560
|
= val:(bool / date) {return {val}}
|
|
456
561
|
/ val:guid {return {val}}
|
|
457
562
|
/ val:number {return typeof val === 'number' ? {val} : { val, literal:'number' }}
|
|
458
563
|
/ val:string {return {val}}
|
|
459
564
|
/ val:binary {return {val}}
|
|
460
|
-
|
|
461
565
|
jsonObject = val:$("{" (jsonObject / [^}])* "}") {return {val}}
|
|
462
|
-
|
|
463
566
|
jsonArray = val:$("[" o "]" / "[" o "{" (jsonArray / [^\]])* "]") {return {val}}
|
|
464
567
|
|
|
465
568
|
list
|
|
@@ -486,19 +589,21 @@
|
|
|
486
589
|
|
|
487
590
|
//
|
|
488
591
|
// ---------- Transformations ------------
|
|
592
|
+
// Odata spec: http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/odata-data-aggregation-ext-v4.0.html
|
|
489
593
|
|
|
490
|
-
|
|
594
|
+
trafo
|
|
491
595
|
= (
|
|
492
|
-
"aggregate" aggregateTrafo /
|
|
493
|
-
"groupby" groupbyTrafo /
|
|
494
|
-
"filter" filterTrafo /
|
|
596
|
+
"aggregate" agg:aggregateTrafo{return agg} /
|
|
597
|
+
"groupby" group:groupbyTrafo{return group} /
|
|
598
|
+
"filter" filter:filterTrafo{return filter} /
|
|
495
599
|
|
|
496
600
|
// REVISIT: All transformations below need improvment
|
|
497
|
-
|
|
498
|
-
"
|
|
499
|
-
"
|
|
500
|
-
"
|
|
501
|
-
"
|
|
601
|
+
"search" search:searchTrafo{return search} /
|
|
602
|
+
"concat" con:concatTrafo{return con} / //Return con so that concat string is not returned
|
|
603
|
+
"compute" compute:computeTrafo{return compute} /
|
|
604
|
+
"top" top:topTrafo{return top} /
|
|
605
|
+
"skip" skip:skipTrafo{return skip} /
|
|
606
|
+
"orderby" order:orderbyTrafo{return order} /
|
|
502
607
|
func:("topcount"i/"bottomcount"i/"topsum"i/"bottomsum"i/"toppercent"i/"bottompercent"i) args:commonFuncTrafo {
|
|
503
608
|
const SUPPORTED_APPLY_TRANSFORMATIONS = {
|
|
504
609
|
"topcount": true,
|
|
@@ -510,23 +615,18 @@
|
|
|
510
615
|
}
|
|
511
616
|
func = func.toLowerCase()
|
|
512
617
|
if (!SUPPORTED_APPLY_TRANSFORMATIONS[func]) {
|
|
513
|
-
throw Object.assign(new Error(`Transformation "${func}" in $apply is not supported
|
|
514
|
-
}
|
|
515
|
-
|
|
618
|
+
throw Object.assign(new Error(`Transformation "${func}" in $apply is not yet supported.`), { statusCode: 501 })
|
|
619
|
+
}
|
|
620
|
+
return {aggregate: [{ func, args }]}
|
|
516
621
|
} /
|
|
517
|
-
identityTrafo
|
|
622
|
+
identity: identityTrafo{return identity}
|
|
518
623
|
// customFunction
|
|
519
624
|
)
|
|
520
625
|
|
|
521
626
|
aggregateTrafo
|
|
522
627
|
= OPEN o head:aggregateItem tail:(o COMMA o p:aggregateItem {return p})* o CLOSE {
|
|
523
|
-
let
|
|
524
|
-
|
|
525
|
-
SELECT.apply = { apply: _apply }
|
|
526
|
-
if (_apply.groupBy) SELECT.apply.groupBy = _apply.groupBy
|
|
527
|
-
_apply = SELECT.apply
|
|
528
|
-
}
|
|
529
|
-
_apply.aggregate = [head, ...tail]
|
|
628
|
+
let response = {aggregate: [head,...tail]}
|
|
629
|
+
return response
|
|
530
630
|
}
|
|
531
631
|
aggregateItem
|
|
532
632
|
= res:("$count" as:asAlias { return { func: 'count', args: [{ val: 1 }], as } }
|
|
@@ -537,7 +637,7 @@
|
|
|
537
637
|
ref
|
|
538
638
|
// / mathCalc - needs CAP support
|
|
539
639
|
)
|
|
540
|
-
func:aggregateWith aggregateFrom? as:asAlias
|
|
640
|
+
func:aggregateWith? aggregateFrom? as:asAlias?
|
|
541
641
|
{ return { func, args: [ path ], as } }
|
|
542
642
|
/ identifier OPEN aggregateExpr CLOSE // needs CAP support
|
|
543
643
|
// / customAggregate // needs CAP support
|
|
@@ -550,57 +650,57 @@
|
|
|
550
650
|
|
|
551
651
|
groupbyTrafo
|
|
552
652
|
= OPEN OPEN head:groupByElem tail:(COMMA p:groupByElem {return p})* (CLOSE {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
}
|
|
653
|
+
|
|
654
|
+
return { groupBy: [head, ...tail] }
|
|
655
|
+
}) trafos:(COMMA t:transformations {return t})? CLOSE {
|
|
656
|
+
let apply = {}
|
|
657
|
+
apply = (trafos) ? {groupBy: [head, ...tail], ...trafos.apply} : {groupBy: [head, ...tail]}
|
|
658
|
+
return apply
|
|
659
|
+
}
|
|
560
660
|
groupByElem
|
|
561
661
|
= c:(rollupSpec / ref) { return c }
|
|
562
662
|
rollupSpec // TODO fix this + add CAP support
|
|
563
663
|
= rollup:("rollup" OPEN o ('$all' / ref) (o COMMA ref)+ o CLOSE) {const err = new Error("Rollup in groupby is not supported yet.");err.statusCode=501;throw err;}
|
|
564
664
|
|
|
565
|
-
filterTrafo = OPEN o (where:filter{
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
571
|
-
_apply.where = where
|
|
572
|
-
}) o CLOSE
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
// All transformations below need improvment
|
|
576
|
-
// and should supported by CAP
|
|
577
|
-
expandTrafo
|
|
578
|
-
= OPEN o ref o COMMA o
|
|
579
|
-
( expandTrafo (o COMMA expandTrafo)*
|
|
580
|
-
/ filterTrafo (o COMMA expandTrafo)*
|
|
581
|
-
) o CLOSE
|
|
665
|
+
filterTrafo = OPEN o where:(where:filter{
|
|
666
|
+
return where
|
|
667
|
+
}) o CLOSE {
|
|
668
|
+
return {where: where}
|
|
669
|
+
}
|
|
582
670
|
|
|
583
|
-
searchTrafo = OPEN o (search:search{
|
|
671
|
+
searchTrafo = OPEN o search:(search:search{
|
|
584
672
|
if (!search) return
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
}
|
|
590
|
-
_apply.search = search
|
|
591
|
-
}) o CLOSE
|
|
673
|
+
return search
|
|
674
|
+
}) o CLOSE {
|
|
675
|
+
return {search: search}
|
|
676
|
+
}
|
|
592
677
|
|
|
593
|
-
concatTrafo = OPEN o
|
|
678
|
+
concatTrafo = OPEN o trafo1:transformations trafo2:(o COMMA o trafos:transformations{ return trafos })+ o CLOSE {
|
|
679
|
+
return {concat: [trafo1, ...trafo2]}
|
|
680
|
+
}
|
|
594
681
|
|
|
595
|
-
computeTrafo = OPEN o computeExpr (o COMMA o computeExpr)* o CLOSE
|
|
682
|
+
computeTrafo = OPEN o computeExpr (o COMMA o computeExpr)* o CLOSE //REVISIT: support compute - current implementation is deviating from odata
|
|
596
683
|
|
|
597
684
|
computeExpr = where_clause asAlias
|
|
598
685
|
|
|
599
686
|
commonFuncTrafo = OPEN o first:operand o COMMA o second:operand o CLOSE { return [first, second] }
|
|
600
687
|
|
|
601
|
-
identityTrafo = "identity"
|
|
688
|
+
identityTrafo = "identity" {return {identity: true }} //REVISIT: support identity
|
|
602
689
|
|
|
690
|
+
topTrafo
|
|
691
|
+
= OPEN o val:top o CLOSE {
|
|
692
|
+
return {limit: {rows: {val}}}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
skipTrafo
|
|
696
|
+
= OPEN o val:skip o CLOSE {
|
|
697
|
+
return {limit: {offset: {val}}}
|
|
698
|
+
}
|
|
603
699
|
|
|
700
|
+
orderbyTrafo
|
|
701
|
+
= OPEN o o:orderby o2:( COMMA o2:orderby{return o2} )* o CLOSE {
|
|
702
|
+
return {orderBy: [o,...o2]}
|
|
703
|
+
}
|
|
604
704
|
//
|
|
605
705
|
// ---------- Literals -----------
|
|
606
706
|
|
|
@@ -621,7 +721,11 @@
|
|
|
621
721
|
= s:$( [0-9]+"-"[0-9][0-9]"-"[0-9][0-9] // date
|
|
622
722
|
( "T"[0-9][0-9]":"[0-9][0-9](":"[0-9][0-9]("."[0-9]+)?)? // time
|
|
623
723
|
( "Z" / (("+" / "-")[0-9][0-9]":"[0-9][0-9]) )? // timezone (Z or +-hh:mm)
|
|
624
|
-
)?)
|
|
724
|
+
)?) {
|
|
725
|
+
if (s.split('-')[0].length > 4)
|
|
726
|
+
throw Object.assign(new Error(`The type 'Edm.DateTimeOffset' is not compatible with '${s}'`), { statusCode: 400 })
|
|
727
|
+
return s
|
|
728
|
+
}
|
|
625
729
|
|
|
626
730
|
number
|
|
627
731
|
= s:$( [+-]? [0-9]+ ("."[0-9]+)? ("e"[0-9]+)? ) { return safeNumber(s) }
|
|
@@ -663,4 +767,4 @@
|
|
|
663
767
|
_ "mandatory whitespaces" = $[ \t\n]+
|
|
664
768
|
|
|
665
769
|
//
|
|
666
|
-
// ------------------------------------
|
|
770
|
+
// ------------------------------------
|