@sap/cds 5.9.8 → 6.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +277 -20
- package/apis/services.d.ts +1 -1
- package/app/fiori/preview.js +2 -6
- package/app/index.js +3 -3
- package/bin/build/buildTaskEngine.js +17 -15
- package/bin/build/buildTaskFactory.js +29 -19
- package/bin/build/buildTaskHandler.js +27 -11
- package/bin/build/buildTaskProvider.js +2 -4
- package/bin/build/buildTaskProviderFactory.js +11 -16
- package/bin/build/constants.js +14 -6
- package/bin/build/csv-reader.js +2 -1
- package/bin/build/index.js +12 -18
- package/bin/build/provider/buildTaskHandlerEdmx.js +3 -39
- package/bin/build/provider/buildTaskHandlerFeatureToggles.js +149 -0
- package/bin/build/provider/buildTaskHandlerInternal.js +2 -3
- package/bin/build/provider/buildTaskProviderInternal.js +108 -239
- package/bin/build/provider/fiori/index.js +2 -2
- package/bin/build/provider/hana/2migration.js +11 -11
- package/bin/build/provider/hana/2tabledata.js +3 -3
- package/bin/build/provider/hana/index.js +89 -99
- package/bin/build/provider/hana/migrationtable.js +4 -3
- package/bin/build/provider/java/index.js +101 -0
- package/bin/build/provider/java-cf/index.js +1 -101
- package/bin/build/provider/mtx/index.js +83 -41
- package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
- package/bin/build/provider/mtx-sidecar/index.js +110 -0
- package/bin/build/provider/node-cf/index.js +1 -308
- package/bin/build/provider/nodejs/index.js +189 -0
- package/bin/build/util.js +21 -31
- package/bin/cds.js +5 -3
- package/bin/deploy/to-hana/cfUtil.js +31 -6
- package/bin/deploy/to-hana/gitUtil.js +5 -3
- package/bin/deploy/to-hana/hana.js +15 -13
- package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
- package/bin/mtx/in-cds.js +19 -7
- package/bin/serve.js +49 -22
- package/bin/utils/log.js +13 -30
- package/bin/version.js +4 -3
- package/common.cds +61 -16
- package/lib/compile/cdsc.js +3 -2
- package/lib/compile/etc/_localized.js +15 -14
- package/lib/compile/for/drafts.js +3 -4
- package/lib/compile/for/java.js +13 -10
- package/lib/compile/for/nodejs.js +8 -8
- package/lib/compile/for/odata.js +7 -12
- package/lib/compile/for/sql.js +5 -6
- package/lib/compile/index.js +5 -4
- package/lib/compile/load.js +9 -11
- package/lib/compile/minify.js +8 -5
- package/lib/compile/parse.js +4 -2
- package/lib/compile/resolve.js +18 -15
- package/lib/compile/to/edm.js +0 -1
- package/lib/compile/to/gql.js +3 -2
- package/lib/compile/to/json.js +24 -17
- package/lib/connect/bindings.js +3 -2
- package/lib/connect/index.js +5 -5
- package/lib/core/classes.js +74 -2
- package/lib/core/entities.js +52 -3
- package/lib/core/reflect.js +2 -1
- package/lib/deploy.js +10 -8
- package/lib/env/defaults.js +4 -3
- package/lib/env/index.js +71 -31
- package/lib/env/presets.js +1 -14
- package/lib/env/requires.js +71 -20
- package/lib/env/serviceBindings.js +147 -0
- package/lib/i18n/localize.js +22 -23
- package/lib/index.js +148 -144
- package/lib/log/errors.js +55 -12
- package/lib/log/format/kibana.js +1 -1
- package/lib/log/index.js +4 -0
- package/lib/ql/SELECT.js +7 -2
- package/lib/ql/Whereable.js +8 -2
- package/lib/ql/index.js +2 -2
- package/lib/req/assert.js +71 -0
- package/lib/req/cds-context.js +38 -70
- package/lib/req/context.js +34 -21
- package/lib/req/request.js +12 -18
- package/lib/req/response.js +6 -2
- package/lib/req/user.js +30 -22
- package/lib/serve/Service-api.js +17 -12
- package/lib/serve/Service-dispatch.js +5 -9
- package/lib/serve/Service-methods.js +4 -3
- package/lib/serve/Transaction.js +24 -21
- package/lib/serve/adapters.js +15 -5
- package/lib/serve/factory.js +22 -20
- package/lib/serve/index.js +51 -54
- package/lib/utils/axios.js +8 -12
- package/lib/utils/index.js +13 -4
- package/lib/utils/resources/index.js +1 -44
- package/lib/utils/resources/tar.js +2 -1
- package/lib/utils/tests.js +13 -15
- package/libx/_runtime/.eslintrc +1 -1
- package/libx/_runtime/audit/Service.js +6 -4
- package/libx/_runtime/audit/generic/personal/access.js +19 -43
- package/libx/_runtime/audit/generic/personal/index.js +40 -34
- package/libx/_runtime/audit/generic/personal/modification.js +11 -9
- package/libx/_runtime/audit/generic/personal/utils.js +13 -6
- package/libx/_runtime/audit/utils/v2.js +6 -3
- package/libx/_runtime/auth/index.js +71 -66
- package/libx/_runtime/auth/strategies/JWT.js +3 -2
- package/libx/_runtime/auth/strategies/mock.js +54 -53
- package/libx/_runtime/auth/strategies/xssecUtils.js +3 -4
- package/libx/_runtime/auth/strategies/xsuaa.js +3 -2
- package/libx/_runtime/auth/utils.js +2 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +127 -41
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +9 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +93 -73
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +25 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +10 -14
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +9 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +60 -53
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +21 -26
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +8 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +29 -41
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -13
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectToCQN.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +24 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityContainer.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/PrimitiveValueDecoder.js +4 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/validator/ValueValidator.js +5 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/ResponseHeaderSetter.js +2 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DebugSerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/PresetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ContextURLFactory.js +3 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ErrorJsonSerializer.js +3 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/TrustedResourceJsonSerializer.js +3 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +36 -25
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +97 -92
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +382 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +5 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +82 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +3 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +91 -69
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +27 -6
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +7 -17
- package/libx/_runtime/cds-services/services/Service.js +17 -76
- package/libx/_runtime/cds-services/services/utils/columns.js +6 -4
- package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -53
- package/libx/_runtime/cds-services/services/utils/differ.js +15 -19
- package/libx/_runtime/cds-services/util/assert.js +107 -34
- package/libx/_runtime/cds.js +1 -31
- package/libx/_runtime/common/aspects/Association.js +40 -54
- package/libx/_runtime/common/aspects/any.js +61 -6
- package/libx/_runtime/common/aspects/entity.js +19 -79
- package/libx/_runtime/common/composition/data.js +2 -2
- package/libx/_runtime/common/composition/delete.js +8 -7
- package/libx/_runtime/common/composition/tree.js +10 -10
- package/libx/_runtime/common/composition/update.js +3 -2
- package/libx/_runtime/common/constants/events.js +13 -0
- package/libx/_runtime/common/error/entry.js +9 -3
- package/libx/_runtime/common/error/frontend.js +13 -19
- package/libx/_runtime/common/error/index.js +8 -3
- package/libx/_runtime/common/generic/auth/capabilities.js +2 -1
- package/libx/_runtime/common/generic/auth/constants.js +1 -4
- package/libx/_runtime/common/generic/auth/requires.js +1 -1
- package/libx/_runtime/common/generic/auth/restrict.js +12 -28
- package/libx/_runtime/common/generic/auth/restrictions.js +12 -4
- package/libx/_runtime/common/generic/auth/utils.js +2 -1
- package/libx/_runtime/common/generic/crud.js +9 -60
- package/libx/_runtime/common/generic/etag.js +41 -7
- package/libx/_runtime/common/generic/input.js +128 -66
- package/libx/_runtime/common/generic/paging.js +9 -3
- package/libx/_runtime/common/generic/put.js +2 -2
- package/libx/_runtime/common/generic/sorting.js +7 -3
- package/libx/_runtime/common/generic/temporal.js +0 -5
- package/libx/_runtime/common/i18n/messages.properties +2 -1
- package/libx/_runtime/common/utils/binary.js +69 -0
- package/libx/_runtime/common/utils/cqn.js +39 -14
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +93 -59
- package/libx/_runtime/common/utils/csn.js +87 -85
- package/libx/_runtime/common/utils/dollar.js +8 -7
- package/libx/_runtime/common/utils/draft.js +1 -1
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +23 -7
- package/libx/_runtime/common/utils/generateOnCond.js +2 -1
- package/libx/_runtime/common/utils/keys.js +30 -13
- package/libx/_runtime/common/utils/postProcessing.js +6 -1
- package/libx/_runtime/common/utils/quotingStyles.js +0 -23
- package/libx/_runtime/common/utils/resolveStructured.js +23 -26
- package/libx/_runtime/common/utils/resolveView.js +4 -1
- package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -0
- package/libx/_runtime/common/utils/search2cqn4sql.js +4 -13
- package/libx/_runtime/common/utils/searchToLike.js +9 -13
- package/libx/_runtime/common/utils/streamProp.js +35 -0
- package/libx/_runtime/common/utils/structured.js +12 -18
- package/libx/_runtime/common/utils/template.js +3 -5
- package/libx/_runtime/common/utils/templateProcessor.js +22 -14
- package/libx/_runtime/common/utils/unionCqnTemplate.js +4 -14
- package/libx/_runtime/db/Service.js +2 -1
- package/libx/_runtime/db/expand/expand-v2.js +2 -2
- package/libx/_runtime/db/expand/expandCQNToJoin.js +7 -6
- package/libx/_runtime/db/generic/input.js +14 -17
- package/libx/_runtime/db/generic/integrity.js +1 -2
- package/libx/_runtime/db/generic/update.js +14 -1
- package/libx/_runtime/db/query/read.js +0 -1
- package/libx/_runtime/db/query/update.js +1 -1
- package/libx/_runtime/db/sql-builder/BaseBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +5 -31
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +0 -9
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +11 -10
- package/libx/_runtime/db/sql-builder/UpdateBuilder.js +2 -2
- package/libx/_runtime/db/sql-builder/annotations.js +1 -2
- package/libx/_runtime/db/utils/coloredTxCommands.js +5 -0
- package/libx/_runtime/db/utils/columns.js +1 -1
- package/libx/_runtime/db/utils/propagateForeignKeys.js +10 -2
- package/libx/_runtime/extensibility/activate.js +69 -0
- package/libx/_runtime/extensibility/add.js +41 -0
- package/libx/_runtime/extensibility/addExtension.js +68 -0
- package/libx/_runtime/extensibility/defaults.js +39 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformREAD.js +0 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformRESULT.js +2 -2
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformWRITE.js +2 -2
- package/libx/_runtime/extensibility/push.js +61 -0
- package/libx/_runtime/extensibility/service.js +21 -0
- package/libx/_runtime/extensibility/{uiflex/utils.js → utils.js} +39 -3
- package/libx/_runtime/extensibility/validation.js +53 -0
- package/libx/_runtime/extensibility/views.js +12 -0
- package/libx/_runtime/fiori/generic/activate.js +2 -4
- package/libx/_runtime/fiori/generic/before.js +17 -29
- package/libx/_runtime/fiori/generic/cancel.js +2 -4
- package/libx/_runtime/fiori/generic/delete.js +2 -4
- package/libx/_runtime/fiori/generic/edit.js +4 -16
- package/libx/_runtime/fiori/generic/index.js +31 -0
- package/libx/_runtime/fiori/generic/new.js +5 -21
- package/libx/_runtime/fiori/generic/patch.js +10 -15
- package/libx/_runtime/fiori/generic/prepare.js +13 -22
- package/libx/_runtime/fiori/generic/read.js +148 -163
- package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
- package/libx/_runtime/fiori/utils/handler.js +10 -22
- package/libx/_runtime/fiori/utils/where.js +1 -4
- package/libx/_runtime/hana/Service.js +14 -7
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +1 -1
- package/libx/_runtime/hana/dynatrace.js +2 -2
- package/libx/_runtime/hana/localized.js +7 -6
- package/libx/_runtime/hana/pool.js +9 -6
- package/libx/_runtime/hana/search.js +2 -3
- package/libx/_runtime/hana/{searchToContains.js → search2Contains.js} +5 -2
- package/libx/_runtime/hana/search2cqn4sql.js +20 -17
- package/libx/_runtime/index.js +2 -6
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +30 -22
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -3
- package/libx/_runtime/messaging/common-utils/appId.js +9 -0
- package/libx/_runtime/messaging/common-utils/authorizedRequest.js +2 -18
- package/libx/_runtime/messaging/common-utils/connections.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +305 -231
- package/libx/_runtime/messaging/enterprise-messaging-utils/cloudEvents.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-management.js +15 -8
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-messaging.js +57 -14
- package/libx/_runtime/messaging/enterprise-messaging.js +14 -19
- package/libx/_runtime/messaging/file-based.js +3 -1
- package/libx/_runtime/messaging/http-utils/token.js +18 -6
- package/libx/_runtime/messaging/message-queuing-utils/options-management.js +22 -12
- package/libx/_runtime/messaging/message-queuing-utils/options-messaging.js +27 -14
- package/libx/_runtime/messaging/message-queuing.js +138 -85
- package/libx/_runtime/messaging/outbox/utils.js +13 -7
- package/libx/_runtime/messaging/redis-messaging.js +0 -1
- package/libx/_runtime/messaging/service.js +4 -1
- package/libx/_runtime/remote/Service.js +24 -18
- package/libx/_runtime/remote/utils/client.js +90 -48
- package/libx/_runtime/remote/utils/data.js +23 -6
- package/libx/_runtime/sqlite/Service.js +14 -13
- package/libx/_runtime/sqlite/convertAssocToOneManaged.js +2 -0
- package/libx/_runtime/sqlite/customBuilder/CustomSelectBuilder.js +1 -0
- package/libx/_runtime/sqlite/execute.js +3 -9
- package/libx/_runtime/types/api.js +23 -11
- package/libx/common/utils/ucsn.js +15 -9
- package/libx/odata/afterburner.js +109 -29
- package/libx/odata/cqn2odata.js +48 -9
- package/libx/odata/grammar.pegjs +263 -156
- package/libx/odata/index.js +21 -9
- package/libx/odata/parseToCqn.js +8 -5
- package/libx/odata/parser.js +1 -1
- package/libx/odata/utils.js +13 -3
- package/libx/rest/RestAdapter.js +173 -113
- package/libx/rest/RestRequest.js +3 -2
- package/libx/rest/middleware/create.js +8 -6
- package/libx/rest/middleware/delete.js +6 -13
- package/libx/rest/middleware/error.js +1 -1
- package/libx/rest/middleware/input.js +6 -6
- package/libx/rest/middleware/operation.js +8 -3
- package/libx/rest/middleware/parse.js +3 -3
- package/libx/rest/middleware/payload.js +12 -0
- package/libx/rest/middleware/read.js +12 -2
- package/libx/rest/middleware/update.js +3 -3
- package/package.json +4 -6
- package/server.js +3 -44
- package/srv/extensibility-service.cds +56 -0
- package/srv/extensibility-service.js +1 -0
- package/srv/extensions.cds +8 -0
- package/srv/model-provider.cds +59 -0
- package/srv/model-provider.js +163 -0
- package/srv/mtx.cds +2 -0
- package/srv/mtx.js +22 -0
- package/srv/outbox.cds +2 -0
- package/tasks/enterprise-messaging-deploy.js +19 -12
- package/lib/serve/Service-compat.js +0 -36
- package/libx/_runtime/audit/generic/personal/constants.js +0 -4
- package/libx/_runtime/auth/strategies/dwc.js +0 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/Rest.js +0 -183
- package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -67
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -82
- package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +0 -39
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +0 -63
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +0 -52
- package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +0 -81
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +0 -33
- package/libx/_runtime/cds-services/adapter/rest/to.js +0 -8
- package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +0 -50
- package/libx/_runtime/cds-services/adapter/rest/utils/data.js +0 -117
- package/libx/_runtime/cds-services/adapter/rest/utils/header-checks.js +0 -14
- package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +0 -30
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +0 -250
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +0 -26
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +0 -200
- package/libx/_runtime/common/aspects/utils.js +0 -152
- package/libx/_runtime/common/toggles/handler.js +0 -21
- package/libx/_runtime/common/utils/extensibilityUtils.js +0 -18
- package/libx/_runtime/extensibility/mps/index.js +0 -5
- package/libx/_runtime/extensibility/mps/service.js +0 -111
- package/libx/_runtime/extensibility/mps/tar.js +0 -42
- package/libx/_runtime/extensibility/mps/utils.js +0 -11
- package/libx/_runtime/extensibility/uiflex/index.js +0 -54
- package/libx/_runtime/extensibility/uiflex/service.js +0 -276
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +0 -20
- package/libx/_runtime/remote/utils/client-types.d.ts +0 -7
- package/libx/gql/GraphQLAdapter.js +0 -33
- package/libx/gql/constants/adapter.js +0 -69
- package/libx/gql/constants/cds.js +0 -18
- package/libx/gql/constants/graphql.js +0 -33
- package/libx/gql/readme.md +0 -1
- package/libx/gql/resolvers/crud/create.js +0 -20
- package/libx/gql/resolvers/crud/delete.js +0 -29
- package/libx/gql/resolvers/crud/index.js +0 -6
- package/libx/gql/resolvers/crud/read.js +0 -30
- package/libx/gql/resolvers/crud/update.js +0 -42
- package/libx/gql/resolvers/crud/utils/index.js +0 -36
- package/libx/gql/resolvers/field.js +0 -5
- package/libx/gql/resolvers/index.js +0 -7
- package/libx/gql/resolvers/mutation.js +0 -23
- package/libx/gql/resolvers/parse/ast/enrich.js +0 -52
- package/libx/gql/resolvers/parse/ast/fragment.js +0 -11
- package/libx/gql/resolvers/parse/ast/fromObject.js +0 -39
- package/libx/gql/resolvers/parse/ast/index.js +0 -3
- package/libx/gql/resolvers/parse/ast/meta.js +0 -4
- package/libx/gql/resolvers/parse/ast/variable.js +0 -7
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +0 -44
- package/libx/gql/resolvers/parse/ast2cqn/entries.js +0 -31
- package/libx/gql/resolvers/parse/ast2cqn/index.js +0 -8
- package/libx/gql/resolvers/parse/ast2cqn/limit.js +0 -6
- package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +0 -24
- package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +0 -3
- package/libx/gql/resolvers/parse/ast2cqn/where.js +0 -70
- package/libx/gql/resolvers/parse/utils/index.js +0 -8
- package/libx/gql/resolvers/query.js +0 -13
- package/libx/gql/resolvers/root.js +0 -34
- package/libx/gql/schema/generate.js +0 -18
- package/libx/gql/schema/index.js +0 -5
- package/libx/gql/schema/mutation.js +0 -76
- package/libx/gql/schema/query.js +0 -108
- package/libx/gql/schema/typeDefMap.js +0 -45
- package/libx/gql/schema/utils/index.js +0 -54
- package/libx/gql/utils/index.js +0 -12
- package/libx/rest/middleware/auth.js +0 -20
- package/libx/rest/middleware/content.js +0 -19
- package/srv/flex.cds +0 -21
- package/srv/flex.js +0 -1
- package/srv/mps.cds +0 -23
- package/srv/mps.js +0 -1
- package/srv/outbox.js +0 -0
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,72 @@
|
|
|
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 }
|
|
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
|
+
}
|
|
412
523
|
|
|
413
|
-
|
|
414
|
-
=
|
|
415
|
-
|
|
416
|
-
custom = [a-zA-Z] [a-zA-Z0-9-]* "=" [^&]*
|
|
524
|
+
custom
|
|
525
|
+
= [a-zA-Z0-9-_.~]+ "=" [^&]*
|
|
417
526
|
|
|
527
|
+
format = "$format=" f:$([^&]*) {
|
|
528
|
+
if (f.toLowerCase() !== "json") {
|
|
529
|
+
const err = new Error("ONLY_QUERY_PARAM_FORMAT_JSON_ALLOWED")
|
|
530
|
+
err.statusCode = 501
|
|
531
|
+
throw err;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
418
534
|
//
|
|
419
535
|
// ---------- Expressions ------------
|
|
420
|
-
|
|
421
|
-
|
|
422
536
|
comparison "a comparison"
|
|
423
537
|
= a:operand _ o:$("eq"/"ne"/"lt"/"gt"/"le"/"ge") _ b:operand {
|
|
424
538
|
const op = { eq:'=', ne:'!=', lt:'<', gt:'>', le:'<=', ge:'>=' }[o]||o
|
|
425
539
|
return [ a, op, b ]
|
|
426
540
|
}
|
|
427
|
-
|
|
428
541
|
mathCalc
|
|
429
542
|
= operand (_ ("add" / "sub" / "mul" / "div" / "mod") _ operand)*
|
|
430
|
-
|
|
431
543
|
operand "an operand"
|
|
432
544
|
= navigationCount / function / val / ref / jsonObject / jsonArray / list
|
|
433
|
-
|
|
434
545
|
navigationCount "navigation with $count"
|
|
435
546
|
= navigationPath:(head:identifier key:(OPEN keyArgs:args CLOSE {return keyArgs;})? '/' {
|
|
436
547
|
if (key) {
|
|
@@ -440,26 +551,21 @@
|
|
|
440
551
|
return head;
|
|
441
552
|
})+ count: '$count'
|
|
442
553
|
{ return {func: 'count', as: '$count', args: [{ref: navigationPath}]} }
|
|
443
|
-
|
|
444
554
|
ref "a reference"
|
|
445
555
|
= head:identifier tail:( '/' n:identifier {return n})*
|
|
446
556
|
{
|
|
447
557
|
if (head === "null") {
|
|
448
558
|
return { val: null }
|
|
449
559
|
}
|
|
450
|
-
|
|
451
560
|
return { ref:[ head, ...tail ] }
|
|
452
561
|
}
|
|
453
|
-
|
|
454
562
|
val
|
|
455
563
|
= val:(bool / date) {return {val}}
|
|
456
564
|
/ val:guid {return {val}}
|
|
457
565
|
/ val:number {return typeof val === 'number' ? {val} : { val, literal:'number' }}
|
|
458
566
|
/ val:string {return {val}}
|
|
459
567
|
/ val:binary {return {val}}
|
|
460
|
-
|
|
461
568
|
jsonObject = val:$("{" (jsonObject / [^}])* "}") {return {val}}
|
|
462
|
-
|
|
463
569
|
jsonArray = val:$("[" o "]" / "[" o "{" (jsonArray / [^\]])* "]") {return {val}}
|
|
464
570
|
|
|
465
571
|
list
|
|
@@ -486,19 +592,21 @@
|
|
|
486
592
|
|
|
487
593
|
//
|
|
488
594
|
// ---------- Transformations ------------
|
|
595
|
+
// Odata spec: http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/odata-data-aggregation-ext-v4.0.html
|
|
489
596
|
|
|
490
|
-
|
|
597
|
+
trafo
|
|
491
598
|
= (
|
|
492
|
-
"aggregate" aggregateTrafo /
|
|
493
|
-
"groupby" groupbyTrafo /
|
|
494
|
-
"filter" filterTrafo /
|
|
599
|
+
"aggregate" agg:aggregateTrafo{return agg} /
|
|
600
|
+
"groupby" group:groupbyTrafo{return group} /
|
|
601
|
+
"filter" filter:filterTrafo{return filter} /
|
|
495
602
|
|
|
496
603
|
// REVISIT: All transformations below need improvment
|
|
497
|
-
|
|
498
|
-
"
|
|
499
|
-
"
|
|
500
|
-
"
|
|
501
|
-
"
|
|
604
|
+
"search" search:searchTrafo{return search} /
|
|
605
|
+
"concat" con:concatTrafo{return con} / //Return con so that concat string is not returned
|
|
606
|
+
"compute" compute:computeTrafo{return compute} /
|
|
607
|
+
"top" top:topTrafo{return top} /
|
|
608
|
+
"skip" skip:skipTrafo{return skip} /
|
|
609
|
+
"orderby" order:orderbyTrafo{return order} /
|
|
502
610
|
func:("topcount"i/"bottomcount"i/"topsum"i/"bottomsum"i/"toppercent"i/"bottompercent"i) args:commonFuncTrafo {
|
|
503
611
|
const SUPPORTED_APPLY_TRANSFORMATIONS = {
|
|
504
612
|
"topcount": true,
|
|
@@ -510,23 +618,18 @@
|
|
|
510
618
|
}
|
|
511
619
|
func = func.toLowerCase()
|
|
512
620
|
if (!SUPPORTED_APPLY_TRANSFORMATIONS[func]) {
|
|
513
|
-
throw Object.assign(new Error(`Transformation "${func}" in $apply is not supported
|
|
514
|
-
}
|
|
515
|
-
|
|
621
|
+
throw Object.assign(new Error(`Transformation "${func}" in $apply is not yet supported.`), { statusCode: 501 })
|
|
622
|
+
}
|
|
623
|
+
return {aggregate: [{ func, args }]}
|
|
516
624
|
} /
|
|
517
|
-
identityTrafo
|
|
625
|
+
identity: identityTrafo{return identity}
|
|
518
626
|
// customFunction
|
|
519
627
|
)
|
|
520
628
|
|
|
521
629
|
aggregateTrafo
|
|
522
630
|
= 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]
|
|
631
|
+
let response = {aggregate: [head,...tail]}
|
|
632
|
+
return response
|
|
530
633
|
}
|
|
531
634
|
aggregateItem
|
|
532
635
|
= res:("$count" as:asAlias { return { func: 'count', args: [{ val: 1 }], as } }
|
|
@@ -537,7 +640,7 @@
|
|
|
537
640
|
ref
|
|
538
641
|
// / mathCalc - needs CAP support
|
|
539
642
|
)
|
|
540
|
-
func:aggregateWith aggregateFrom? as:asAlias
|
|
643
|
+
func:aggregateWith? aggregateFrom? as:asAlias?
|
|
541
644
|
{ return { func, args: [ path ], as } }
|
|
542
645
|
/ identifier OPEN aggregateExpr CLOSE // needs CAP support
|
|
543
646
|
// / customAggregate // needs CAP support
|
|
@@ -550,57 +653,57 @@
|
|
|
550
653
|
|
|
551
654
|
groupbyTrafo
|
|
552
655
|
= OPEN OPEN head:groupByElem tail:(COMMA p:groupByElem {return p})* (CLOSE {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
}
|
|
656
|
+
|
|
657
|
+
return { groupBy: [head, ...tail] }
|
|
658
|
+
}) trafos:(COMMA t:transformations {return t})? CLOSE {
|
|
659
|
+
let apply = {}
|
|
660
|
+
apply = (trafos) ? {groupBy: [head, ...tail], ...trafos.apply} : {groupBy: [head, ...tail]}
|
|
661
|
+
return apply
|
|
662
|
+
}
|
|
560
663
|
groupByElem
|
|
561
664
|
= c:(rollupSpec / ref) { return c }
|
|
562
665
|
rollupSpec // TODO fix this + add CAP support
|
|
563
666
|
= 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
667
|
|
|
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
|
|
668
|
+
filterTrafo = OPEN o where:(where:filter{
|
|
669
|
+
return where
|
|
670
|
+
}) o CLOSE {
|
|
671
|
+
return {where: where}
|
|
672
|
+
}
|
|
582
673
|
|
|
583
|
-
searchTrafo = OPEN o (search:search{
|
|
674
|
+
searchTrafo = OPEN o search:(search:search{
|
|
584
675
|
if (!search) return
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
}
|
|
590
|
-
_apply.search = search
|
|
591
|
-
}) o CLOSE
|
|
676
|
+
return search
|
|
677
|
+
}) o CLOSE {
|
|
678
|
+
return {search: search}
|
|
679
|
+
}
|
|
592
680
|
|
|
593
|
-
concatTrafo = OPEN o
|
|
681
|
+
concatTrafo = OPEN o trafo1:transformations trafo2:(o COMMA o trafos:transformations{ return trafos })+ o CLOSE {
|
|
682
|
+
return {concat: [trafo1, ...trafo2]}
|
|
683
|
+
}
|
|
594
684
|
|
|
595
|
-
computeTrafo = OPEN o computeExpr (o COMMA o computeExpr)* o CLOSE
|
|
685
|
+
computeTrafo = OPEN o computeExpr (o COMMA o computeExpr)* o CLOSE //REVISIT: support compute - current implementation is deviating from odata
|
|
596
686
|
|
|
597
687
|
computeExpr = where_clause asAlias
|
|
598
688
|
|
|
599
689
|
commonFuncTrafo = OPEN o first:operand o COMMA o second:operand o CLOSE { return [first, second] }
|
|
600
690
|
|
|
601
|
-
identityTrafo = "identity"
|
|
691
|
+
identityTrafo = "identity" {return {identity: true }} //REVISIT: support identity
|
|
602
692
|
|
|
693
|
+
topTrafo
|
|
694
|
+
= OPEN o val:top o CLOSE {
|
|
695
|
+
return {limit: {rows: {val}}}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
skipTrafo
|
|
699
|
+
= OPEN o val:skip o CLOSE {
|
|
700
|
+
return {limit: {offset: {val}}}
|
|
701
|
+
}
|
|
603
702
|
|
|
703
|
+
orderbyTrafo
|
|
704
|
+
= OPEN o o:orderby o2:( COMMA o2:orderby{return o2} )* o CLOSE {
|
|
705
|
+
return {orderBy: [o,...o2]}
|
|
706
|
+
}
|
|
604
707
|
//
|
|
605
708
|
// ---------- Literals -----------
|
|
606
709
|
|
|
@@ -621,7 +724,11 @@
|
|
|
621
724
|
= s:$( [0-9]+"-"[0-9][0-9]"-"[0-9][0-9] // date
|
|
622
725
|
( "T"[0-9][0-9]":"[0-9][0-9](":"[0-9][0-9]("."[0-9]+)?)? // time
|
|
623
726
|
( "Z" / (("+" / "-")[0-9][0-9]":"[0-9][0-9]) )? // timezone (Z or +-hh:mm)
|
|
624
|
-
)?)
|
|
727
|
+
)?) {
|
|
728
|
+
if (s.split('-')[0].length > 4)
|
|
729
|
+
throw Object.assign(new Error(`The type 'Edm.DateTimeOffset' is not compatible with '${s}'`), { statusCode: 400 })
|
|
730
|
+
return s
|
|
731
|
+
}
|
|
625
732
|
|
|
626
733
|
number
|
|
627
734
|
= s:$( [+-]? [0-9]+ ("."[0-9]+)? ("e"[0-9]+)? ) { return safeNumber(s) }
|
|
@@ -663,4 +770,4 @@
|
|
|
663
770
|
_ "mandatory whitespaces" = $[ \t\n]+
|
|
664
771
|
|
|
665
772
|
//
|
|
666
|
-
// ------------------------------------
|
|
773
|
+
// ------------------------------------
|