@sap/cds 5.5.4 → 5.6.2
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 +138 -1
- package/apis/services.d.ts +27 -1
- package/app/index.js +22 -11
- package/bin/build/buildTaskFactory.js +1 -1
- package/bin/build/provider/buildTaskProviderInternal.js +1 -1
- package/bin/build/provider/fiori/index.js +1 -1
- package/bin/build/provider/hana/2migration.js +8 -7
- package/bin/build/provider/java-cf/index.js +1 -1
- package/bin/deploy/to-hana/hana.js +1 -17
- package/common.cds +8 -0
- package/lib/compile/to/sql.js +22 -2
- package/lib/connect/bindings.js +2 -1
- package/lib/core/reflect.js +4 -1
- package/lib/env/index.js +175 -41
- package/lib/env/requires.js +16 -1
- package/lib/i18n/localize.js +33 -5
- package/lib/index.js +3 -3
- package/lib/log/format/kibana.js +6 -2
- package/lib/ql/Query.js +1 -0
- package/lib/ql/SELECT.js +15 -8
- package/lib/ql/Whereable.js +5 -0
- package/lib/req/context.js +13 -5
- package/lib/serve/Service-dispatch.js +8 -1
- package/lib/serve/Service-methods.js +1 -1
- package/lib/utils/axios.js +7 -0
- package/lib/utils/data.js +1 -1
- package/lib/utils/tests.js +1 -1
- package/libx/_runtime/audit/Service.js +18 -18
- package/libx/_runtime/audit/generic/personal/access.js +1 -1
- package/libx/_runtime/audit/generic/personal/modification.js +3 -2
- package/libx/_runtime/audit/generic/personal/utils.js +23 -63
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +4 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +37 -35
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +3 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +5 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +13 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +84 -34
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +10 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +9 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +8 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectHelper.js +11 -95
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/ResourcePathParser.js +17 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriParser.js +2 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +6 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +3 -34
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +3 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +64 -31
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +10 -5
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +1 -1
- package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +1 -1
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +1 -3
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +20 -21
- package/libx/_runtime/cds-services/services/utils/columns.js +6 -1
- package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -8
- package/libx/_runtime/cds-services/services/utils/differ.js +7 -26
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +2 -4
- package/libx/_runtime/cds-services/util/assert.js +29 -13
- package/libx/_runtime/cds.js +2 -1
- package/libx/_runtime/common/aspects/Association.js +72 -0
- package/libx/_runtime/common/aspects/any.js +8 -45
- package/libx/_runtime/common/aspects/entity.js +0 -1
- package/libx/_runtime/common/aspects/relation.js +40 -0
- package/libx/_runtime/common/aspects/utils.js +73 -1
- package/libx/_runtime/common/auth/strategies/utils/uaa.js +10 -14
- package/libx/_runtime/common/composition/data.js +3 -2
- package/libx/_runtime/common/composition/delete.js +3 -1
- package/libx/_runtime/common/composition/tree.js +23 -18
- package/libx/_runtime/common/composition/update.js +6 -1
- package/libx/_runtime/common/composition/utils.js +34 -8
- package/libx/_runtime/common/error/frontend.js +6 -1
- package/libx/_runtime/common/generic/auth.js +15 -13
- package/libx/_runtime/common/generic/crud.js +2 -2
- package/libx/_runtime/common/generic/etag.js +11 -8
- package/libx/_runtime/common/generic/input.js +3 -3
- package/libx/_runtime/common/generic/paging.js +9 -5
- package/libx/_runtime/common/generic/put.js +3 -2
- package/libx/_runtime/common/generic/sorting.js +3 -3
- package/libx/_runtime/common/generic/temporal.js +3 -3
- package/libx/_runtime/common/utils/cqn.js +20 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +125 -139
- package/libx/_runtime/common/utils/csn.js +50 -52
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +41 -176
- package/libx/_runtime/common/utils/generateOnCond.js +40 -70
- package/libx/_runtime/common/utils/{enrichWithKeysFromWhere.js → keys.js} +29 -28
- package/libx/_runtime/common/utils/postProcessing.js +3 -0
- package/libx/_runtime/common/utils/propagateForeignKeys.js +84 -0
- package/libx/_runtime/common/utils/resolveStructured.js +1 -1
- package/libx/_runtime/common/utils/resolveView.js +7 -5
- package/libx/_runtime/common/utils/rewriteAsterisks.js +94 -0
- package/libx/_runtime/common/utils/search2cqn4sql.js +9 -8
- package/libx/_runtime/common/utils/template.js +54 -46
- package/libx/_runtime/db/Service.js +9 -2
- package/libx/_runtime/db/expand/expandCQNToJoin.js +54 -33
- package/libx/_runtime/db/expand/rawToExpanded.js +2 -1
- package/libx/_runtime/db/generic/arrayed.js +13 -28
- package/libx/_runtime/db/generic/create.js +1 -0
- package/libx/_runtime/db/generic/input.js +7 -11
- package/libx/_runtime/db/generic/integrity.js +2 -2
- package/libx/_runtime/db/generic/rewrite.js +2 -5
- package/libx/_runtime/db/generic/update.js +1 -0
- package/libx/_runtime/db/query/read.js +9 -4
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +6 -0
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +7 -2
- package/libx/_runtime/db/sql-builder/annotations.js +1 -0
- package/libx/_runtime/db/utils/columns.js +14 -43
- package/libx/_runtime/db/utils/deep.js +5 -7
- package/libx/_runtime/fiori/generic/activate.js +3 -2
- package/libx/_runtime/fiori/generic/before.js +2 -2
- package/libx/_runtime/fiori/generic/cancel.js +3 -2
- package/libx/_runtime/fiori/generic/delete.js +3 -2
- package/libx/_runtime/fiori/generic/edit.js +3 -3
- package/libx/_runtime/fiori/generic/new.js +2 -2
- package/libx/_runtime/fiori/generic/patch.js +2 -2
- package/libx/_runtime/fiori/generic/prepare.js +2 -2
- package/libx/_runtime/fiori/generic/read.js +17 -63
- package/libx/_runtime/fiori/generic/readOverDraft.js +4 -4
- package/libx/_runtime/fiori/uiflex/extensibility/index.cds +15 -0
- package/libx/_runtime/fiori/uiflex/extensibility/index.js +148 -0
- package/libx/_runtime/fiori/uiflex/handler/transformREAD.js +119 -0
- package/libx/_runtime/fiori/uiflex/handler/transformRESULT.js +43 -0
- package/libx/_runtime/fiori/uiflex/handler/transformWRITE.js +62 -0
- package/libx/_runtime/fiori/uiflex/index.js +35 -0
- package/libx/_runtime/fiori/uiflex/utils.js +78 -0
- package/libx/_runtime/fiori/utils/handler.js +3 -13
- package/libx/_runtime/fiori/utils/where.js +6 -1
- package/libx/_runtime/hana/pool.js +12 -11
- package/libx/_runtime/hana/search2cqn4sql.js +34 -43
- package/libx/_runtime/hana/searchToContains.js +3 -3
- package/libx/_runtime/index.js +5 -2
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +1 -1
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +16 -3
- package/libx/_runtime/messaging/common-utils/connections.js +11 -14
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -1
- package/libx/_runtime/messaging/message-queuing.js +18 -0
- package/libx/_runtime/remote/Service.js +20 -4
- package/libx/_runtime/remote/utils/client-types.d.ts +7 -0
- package/libx/_runtime/remote/utils/client.js +117 -23
- package/libx/_runtime/sqlite/Service.js +2 -2
- package/libx/_runtime/sqlite/convertAssocToOneManaged.js +1 -3
- package/libx/gql/GraphQLAdapter.js +33 -0
- package/libx/gql/constants/adapter.js +69 -0
- package/libx/gql/constants/cds.js +18 -0
- package/libx/gql/constants/graphql.js +33 -0
- package/libx/gql/resolvers/crud/create.js +15 -0
- package/libx/gql/resolvers/crud/delete.js +24 -0
- package/libx/gql/resolvers/crud/index.js +6 -0
- package/libx/gql/resolvers/crud/read.js +25 -0
- package/libx/gql/resolvers/crud/update.js +31 -0
- package/libx/gql/resolvers/crud/utils/index.js +36 -0
- package/libx/gql/resolvers/field.js +5 -0
- package/libx/gql/resolvers/index.js +7 -0
- package/libx/gql/resolvers/mutation.js +23 -0
- package/libx/gql/resolvers/parse/ast/enrich.js +51 -0
- package/libx/gql/resolvers/parse/ast/fragment.js +11 -0
- package/libx/gql/resolvers/parse/ast/fromObject.js +39 -0
- package/libx/gql/resolvers/parse/ast/index.js +3 -0
- package/libx/gql/resolvers/parse/ast/meta.js +4 -0
- package/libx/gql/resolvers/parse/ast/variable.js +7 -0
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +42 -0
- package/libx/gql/resolvers/parse/ast2cqn/entries.js +31 -0
- package/libx/gql/resolvers/parse/ast2cqn/index.js +8 -0
- package/libx/gql/resolvers/parse/ast2cqn/limit.js +6 -0
- package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +24 -0
- package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +3 -0
- package/libx/gql/resolvers/parse/ast2cqn/where.js +70 -0
- package/libx/gql/resolvers/parse/utils/index.js +8 -0
- package/libx/gql/resolvers/query.js +13 -0
- package/libx/gql/resolvers/root.js +34 -0
- package/libx/gql/schema/generate.js +18 -0
- package/libx/gql/schema/index.js +5 -0
- package/libx/gql/schema/mutation.js +76 -0
- package/libx/gql/schema/query.js +108 -0
- package/libx/gql/schema/typeDefMap.js +45 -0
- package/libx/gql/schema/utils/index.js +54 -0
- package/libx/gql/utils/index.js +12 -0
- package/libx/{_runtime/odata/cqn2odata.js → odata/cqn2odata/index.js} +39 -100
- package/libx/odata/index.js +80 -0
- package/libx/odata/odata2cqn/afterburner.js +170 -0
- package/libx/{_runtime/odata/odata2cqn.pegjs → odata/odata2cqn/grammar.pegjs} +102 -123
- package/libx/odata/odata2cqn/index.js +3 -0
- package/libx/odata/odata2cqn/parser.js +1 -0
- package/libx/odata/utils/index.js +64 -0
- package/libx/rest/RestAdapter.js +101 -0
- package/libx/rest/RestRequest.js +30 -0
- package/libx/rest/index.js +3 -0
- package/libx/rest/middleware/auth.js +22 -0
- package/libx/rest/middleware/content.js +15 -0
- package/libx/rest/middleware/create.js +40 -0
- package/libx/rest/middleware/delete.js +20 -0
- package/libx/rest/middleware/error.js +56 -0
- package/libx/rest/middleware/operation.js +39 -0
- package/libx/rest/middleware/parse.js +90 -0
- package/libx/rest/middleware/read.js +29 -0
- package/libx/rest/middleware/update.js +42 -0
- package/libx/rest/utils/data.js +65 -0
- package/package.json +4 -1
- package/server.js +29 -7
- package/libx/_runtime/cds-services/services/utils/diff.js +0 -53
- package/libx/_runtime/cds-services/util/auditlog.js +0 -247
- package/libx/_runtime/cds-services/util/xsenv.js +0 -51
- package/libx/_runtime/common/utils/backlinks.js +0 -83
- package/libx/_runtime/common/utils/rewriteAsterisk.js +0 -72
- package/libx/_runtime/odata/index.js +0 -55
- package/libx/_runtime/odata/odata2cqn.js +0 -1
- package/libx/_runtime/odata/readToCqn.js +0 -129
- package/libx/_runtime/remote/cqn2odata/index.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,142 @@
|
|
|
4
4
|
- The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
5
5
|
- This project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
|
+
## Version 5.6.2 - 2021-11-08
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Handle arrayed elements using templating mechanism
|
|
12
|
+
- OData requests to `$count` endpoint of ETag enabled entity
|
|
13
|
+
- `cds.test` does no longer crash if executed in `cds repl` on a remote service call
|
|
14
|
+
- Crash on draft activate after draft edit for not existing composition of one
|
|
15
|
+
- Ensure request correlation (with default server)
|
|
16
|
+
- `<entity>.texts` points to real text entity
|
|
17
|
+
- Draft union with expand to to-one and to-many
|
|
18
|
+
- No columns in draft lock statement (i.e., use `SELECT 1`)
|
|
19
|
+
|
|
20
|
+
## Version 5.6.1 - 2021-11-02
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- UAA credentials lookup
|
|
25
|
+
- Revert return type validation for `cds.String` for compatibility with older `@sap/cds-mtx` versions
|
|
26
|
+
- Messaging: Ill-defined incoming AMQP messages will not crash the app
|
|
27
|
+
- `cds compile -l` does no longer crash if called without `--to` option
|
|
28
|
+
|
|
29
|
+
## Version 5.6.0 - 2021-10-29
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- New REST protocol adapter (beta)
|
|
34
|
+
+ Makes use of the beta OData URL to CQN parser. Hence, almost all OData requests are supported (see limitations below).
|
|
35
|
+
+ Activate via `cds.env.features.rest_new_adapter = true`
|
|
36
|
+
+ Out of scope (compared to OData protocol adapter):
|
|
37
|
+
+ OData query option `$apply`
|
|
38
|
+
+ Batch requests (with or without atomicity groups)
|
|
39
|
+
+ Draft handling
|
|
40
|
+
- New GraphQL protocol adapter (alpha)
|
|
41
|
+
+ Serves single endpoint for all services based on `served` event at `/graphql` (subject to change).
|
|
42
|
+
+ Activate via `cds.env.features.graphql = true`
|
|
43
|
+
+ Required additional dependencies: `@graphql-tools/schema`, `express-graphql`, and `graphql`
|
|
44
|
+
+ Not meant for productive use! For example, authentication and authorization are out of scope.
|
|
45
|
+
- Support of the following features when using beta OData URL to CQN parser (`cds.env.features.odata_new_parser`):
|
|
46
|
+
+ REST-style URLs (example: `GET /Foo/1`)
|
|
47
|
+
+ `$expand=*` query option on different nested expand levels (`$levels` is not yet supported)
|
|
48
|
+
+ draft handling
|
|
49
|
+
+ structured keys
|
|
50
|
+
+ streaming
|
|
51
|
+
+ navigation to primitive properties without `$value` query option
|
|
52
|
+
- Optimized Search: Support `$filter` query option in combination with optimize `$search` and localized data (when the environment variable `cds.env.features.optimized_search` is set to `true`)
|
|
53
|
+
- `GET` requests support static values in ON-conditions of composition parents when using unmanaged backlinks
|
|
54
|
+
- `destinationOptions` can be configured for Remote Services
|
|
55
|
+
+ Example:
|
|
56
|
+
```json
|
|
57
|
+
{"cds":{"requires":{
|
|
58
|
+
"S4": {
|
|
59
|
+
"destinationOptions": {
|
|
60
|
+
"selectionStrategy": "subscriberFirst",
|
|
61
|
+
...
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}}}
|
|
65
|
+
```
|
|
66
|
+
- `forwardAuthToken` can be configured for Remote Services
|
|
67
|
+
+ Example:
|
|
68
|
+
```json
|
|
69
|
+
{"cds":{"requires":{
|
|
70
|
+
"credentials": {
|
|
71
|
+
"url": "...",
|
|
72
|
+
"forwardAuthToken": true
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}}}
|
|
76
|
+
```
|
|
77
|
+
- File to store private project settings `.cdsrc-private.json` (should not be checked in source code management)
|
|
78
|
+
- Read additional configuration from JSON files or directory structures using `CDS_CONFIG` env variable
|
|
79
|
+
- Missing typescript definitions for services' `.send` shortcuts `get`, `put`, `post`, `patch`, and `delete`
|
|
80
|
+
- Build VCAP_SERVICES env variable dynamically for compatibility (`cds.env.features.emulate_vcap_services`)
|
|
81
|
+
- GET requests to Remote OData Service are automatically sent as `$batch` if the generated URL is too long
|
|
82
|
+
+ Can be configured via `cds.env.remote.max_get_url_length` (beta, default: 1028).
|
|
83
|
+
- Provide ETag in response headers in case of `prefer: return=minimal`
|
|
84
|
+
- Kibana formatter: log the user's id via `cds.env.log.user = true` (beta)
|
|
85
|
+
+ Consider the data privacy implications!
|
|
86
|
+
- Experimental support for uiflex running locally on sqlite by setting `cds.requires.extensibility.kind = uiflex`
|
|
87
|
+
- Minified `cds.model` (deactivate via `cds.env.features.skip_unused = false`)
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
|
|
91
|
+
- Query API: Specified keys are now part of the target path, e.g. `SELECT.from('Books', 1)` will move the key condition into `SELECT.from.ref`.
|
|
92
|
+
+ Deactivate during two month grace period via compat feature flag `cds.env.features.keys_into_where = true`
|
|
93
|
+
- Removed duplicate integrity checks
|
|
94
|
+
- Optimized search: Optimize queries for non-localized elements
|
|
95
|
+
- Non-specified columns are resolved at database layer
|
|
96
|
+
- `cds deploy` no longer enforces the presence of SAP CommonCryptoLib (checked with env variable `SECUDIR`) on Windows since it uses now the built-in security libraries
|
|
97
|
+
- Target keys are not included into a body when sending `PATCH` requests to external services
|
|
98
|
+
|
|
99
|
+
### Fixed
|
|
100
|
+
|
|
101
|
+
- Audit logging of non-string values
|
|
102
|
+
- Query API compilation error when keys start with `{`
|
|
103
|
+
- Handling of wrong Edm.DateTimeOffset values
|
|
104
|
+
- Using UUIDs in search with beta OData URL to CQN parser (`cds.env.features.odata_new_parser`)
|
|
105
|
+
- Runtime exception for READ requests with deeply nested navigation and structured keys, for example:
|
|
106
|
+
`GET foo/Bar/b708ad6c-2dd4-40d5-91c0-2e3eacf306d2/Info/sales(a='1010',b='10',c='00')/functions(functionName='error')`
|
|
107
|
+
- The check for the minimum Node.js version now properly enforces version 12.18, i.e. aborts server startup.
|
|
108
|
+
- `cds.test` fails with a clearer error message if the server wasn't started at all
|
|
109
|
+
- Audit logging for modification of personal or sensitive data when using same entity as a composition child in different parent entities
|
|
110
|
+
- Deleting an entity defined with managed composition of one, whereas a dependent entity is defined having an independent managed association to its composition parent no longer crashes the application
|
|
111
|
+
- Audit logging for entities having arrayed elements
|
|
112
|
+
- Filtering for `cds.Date` on Remote OData V2 services
|
|
113
|
+
- Crash when `rollup` function was used in groupBy in odata requests
|
|
114
|
+
- Or for $filter with IsActiveEntity=true for access to active entities
|
|
115
|
+
- Reading draft-enabled entity with `$expand` targeting non-draft associations
|
|
116
|
+
- Delete with sub-select
|
|
117
|
+
- Runtime exception when streaming property annotated with `@Core.MediaType: 'application/json'`
|
|
118
|
+
- Reading streams via navigation when entity containing large data is a part of a draft-enabled composition tree
|
|
119
|
+
- Read draft entity with nested exists restriction
|
|
120
|
+
- Activate draft of entity having `to-one` and `to-many` compositions
|
|
121
|
+
- Caching issue that causes the OData `omit-values` preference in `Prefer` HTTP headers to misbehaves
|
|
122
|
+
- Deletion of draft instances if multiple draft enabled entities are used within one service
|
|
123
|
+
- Queries with `contains` filter targeting a remote odata v2 service
|
|
124
|
+
- Schema evolution support for nested CDS entities in `cds build`
|
|
125
|
+
- I18n texts with quotes and other special characters get escaped correctly if they appear in XML and Json documents
|
|
126
|
+
- Execution of plain SQL statements on SQLite
|
|
127
|
+
- `Content-Disposition` header is now url encoded
|
|
128
|
+
|
|
129
|
+
### Removed
|
|
130
|
+
|
|
131
|
+
- Usage of `@sap/xsenv` is superseded with `cds.env` in node.js cds-runtime
|
|
132
|
+
- `@odata.on.insert/update` and `#user/now` are deprecated and will be removed in the next major version. Use `@cds.on.insert/update` and `$user/now` instead.
|
|
133
|
+
|
|
134
|
+
## Version 5.5.5 - 2021-10-20
|
|
135
|
+
|
|
136
|
+
### Fixed
|
|
137
|
+
|
|
138
|
+
- Action parameters set to null
|
|
139
|
+
- Restrictions with "where exists" clause and filter on ambiguous fields
|
|
140
|
+
- Nulled user attribute in restrictions with "where exists" clause
|
|
141
|
+
- Wait for all queries to settle during deep operation
|
|
142
|
+
|
|
7
143
|
## Version 5.5.4 - 2021-10-12
|
|
8
144
|
|
|
9
145
|
### Fixed
|
|
@@ -49,6 +185,7 @@
|
|
|
49
185
|
### Added
|
|
50
186
|
|
|
51
187
|
- Support for minified models
|
|
188
|
+
- Messaging: Support for string payloads
|
|
52
189
|
- Messaging: Webhooks use 'application/json' as the default content type
|
|
53
190
|
- Messaging: If senders don't use `data` as a property of the payload, then the whole payload is interpreted as `data`
|
|
54
191
|
- Messaging: Support for `$namespace` placeholer in queue name
|
|
@@ -146,7 +283,7 @@
|
|
|
146
283
|
- Messaging: In multitenancy mode, messaging artifacts are only deployed to subscribers (unless the service option `deployForProvider` is set to `true`)
|
|
147
284
|
- Messaging: Incoming messages without corresponding handlers are not acknowledged
|
|
148
285
|
- If a service executes a query targeting a projection on one of its entities, the query is resolved along with projections to an entity known by the executing service. The result is post-processed to reflect the expected result of the incoming query. The reason is that no handlers of the executing service were executed as they did not know the query target.
|
|
149
|
-
+ Deactivate during two month grace period via
|
|
286
|
+
+ Deactivate during two month grace period via compat feature flag `cds.env.features.resolve_views = false`
|
|
150
287
|
- Use `@sap/cds-compiler`'s `smartId` function to determine whether a reference needs to be quoted.
|
|
151
288
|
+ Allows the use of non-word characters in column names, for example `entity Foo { ![bar/bz]: String; }`.
|
|
152
289
|
+ Support for columns with spaces with feature flag `cds.env.features.spaced_columns`.
|
package/apis/services.d.ts
CHANGED
|
@@ -140,7 +140,33 @@ export class Service extends QueryAPI {
|
|
|
140
140
|
*/
|
|
141
141
|
send (details: { event: Events, data?: object, headers?: object }) : Promise<this>
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Constructs and sends a GET request.
|
|
145
|
+
* @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
|
|
146
|
+
*/
|
|
147
|
+
get (entityOrPath: Target, data?: object) : Promise<this>
|
|
148
|
+
/**
|
|
149
|
+
* Constructs and sends a POST request.
|
|
150
|
+
* @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
|
|
151
|
+
*/
|
|
152
|
+
post (entityOrPath: Target, data?: object) : Promise<this>
|
|
153
|
+
/**
|
|
154
|
+
* Constructs and sends a PUT request.
|
|
155
|
+
* @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
|
|
156
|
+
*/
|
|
157
|
+
put (entityOrPath: Target, data?: object) : Promise<this>
|
|
158
|
+
/**
|
|
159
|
+
* Constructs and sends a PATCH request.
|
|
160
|
+
* @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
|
|
161
|
+
*/
|
|
162
|
+
patch (entityOrPath: Target, data?: object) : Promise<this>
|
|
163
|
+
/**
|
|
164
|
+
* Constructs and sends a DELETE request.
|
|
165
|
+
* @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
|
|
166
|
+
*/
|
|
167
|
+
delete (entityOrPath: Target, data?: object) : Promise<this>
|
|
168
|
+
|
|
169
|
+
// The central method to dispatch events
|
|
144
170
|
dispatch (msg: EventMessage): Promise<any>
|
|
145
171
|
|
|
146
172
|
|
package/app/index.js
CHANGED
|
@@ -6,7 +6,7 @@ module.exports = { get html(){
|
|
|
6
6
|
const odata = srv => Object.keys(srv._adapters).find (a => a.startsWith ('odata'))
|
|
7
7
|
const metadata = srv => odata(srv) ? ` / <a href="${srv.path}/$metadata">$metadata</a>` : ``
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
let html = fs.readFileSync(path.join(__dirname,'index.html'),'utf-8')
|
|
10
10
|
// .replace ('{{subtitle}}', 'Version ' + cds.version)
|
|
11
11
|
.replace (/{{package}}/g, _project())
|
|
12
12
|
.replace (/{{app}}/g, cds.env.folders.app.replace(/*trailing slash*/ /\/$/, ''))
|
|
@@ -15,16 +15,27 @@ module.exports = { get html(){
|
|
|
15
15
|
).join('\n') || '— none —'
|
|
16
16
|
)
|
|
17
17
|
.replace ('{{services}}', cds.service.providers.map (srv => `
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
`)
|
|
18
|
+
<h3>
|
|
19
|
+
<a href="${srv.path}">${srv.path}</a>${metadata(srv)} ${_moreLinks(srv)}
|
|
20
|
+
</h3>
|
|
21
|
+
<ul>${_entities_in(srv).map (e => {
|
|
22
|
+
return `
|
|
23
|
+
<li>
|
|
24
|
+
<a href="${srv.path}/${e.replace(/\./g, '_')}">${e}</a> ${_moreLinks(srv, e)}
|
|
25
|
+
</li>`}).join('')}
|
|
26
|
+
</ul>
|
|
27
|
+
`).join(''))
|
|
28
|
+
|
|
29
|
+
// add /graphql
|
|
30
|
+
if (cds.env.features.graphql) {
|
|
31
|
+
html = html.replace(/\n\s*<footer>/, `
|
|
32
|
+
|
|
33
|
+
<h3>
|
|
34
|
+
<a href="/graphql">/graphql</a>
|
|
35
|
+
</h3>
|
|
36
|
+
|
|
37
|
+
<footer>`)
|
|
38
|
+
}
|
|
28
39
|
|
|
29
40
|
Object.defineProperty (this,'html',{value:html})
|
|
30
41
|
return html
|
|
@@ -150,7 +150,7 @@ class BuildTaskFactory {
|
|
|
150
150
|
_adaptBuildTargetSettingForJava(projectPath) {
|
|
151
151
|
if (this.env.build.target !== ".") {
|
|
152
152
|
// filter user settings of cds.env
|
|
153
|
-
const userEnv = this.env.for("cds", projectPath, false
|
|
153
|
+
const userEnv = this.env.for("cds", projectPath, false)
|
|
154
154
|
|
|
155
155
|
// use helper as env.build might be undefined
|
|
156
156
|
if (!getProperty(userEnv, "build.target")) {
|
|
@@ -174,7 +174,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
174
174
|
}
|
|
175
175
|
// check whether cds config represents a legacy build system config for which requires.db was not configured
|
|
176
176
|
// Note: compat layer sets requires.db: {}
|
|
177
|
-
const userEnv = this.cds.env.for("cds", projectPath, false
|
|
177
|
+
const userEnv = this.cds.env.for("cds", projectPath, false)
|
|
178
178
|
return userEnv && (userEnv.get("data.model") || userEnv.get("service.model"))
|
|
179
179
|
}
|
|
180
180
|
|
|
@@ -51,7 +51,7 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
51
51
|
|
|
52
52
|
if (javaTask
|
|
53
53
|
&& await isOldJavaStack([javaTask.src, this.buildOptions.root])
|
|
54
|
-
&& !this.env.for("cds", this.buildOptions.root, false
|
|
54
|
+
&& !this.env.for("cds", this.buildOptions.root, false).get(ODATA_VERSION)) {
|
|
55
55
|
|
|
56
56
|
// old java stack
|
|
57
57
|
// default is now v4 and not v2 anymore, so overwrite with v2 if using default
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const parser = require('./migrationtable')
|
|
3
3
|
const { getProperty, BuildError } = require('../../util')
|
|
4
|
+
const { getArtifactCdsPersistenceName } = require('@sap/cds-compiler')
|
|
4
5
|
const { LOG_MODULE_NAMES } = require('../../constants')
|
|
5
6
|
const cdscVersion = `-- generated by cds-compiler version ${require('@sap/cds-compiler/package.json').version}`
|
|
6
7
|
const cds = require('../../cds'), minified = csn => cds.linked(csn).minified()
|
|
@@ -12,15 +13,15 @@ module.exports = async (model, lastDevVersion, srcPath, options = {}) => {
|
|
|
12
13
|
logger = options.logger
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
const
|
|
16
|
-
const { definitions, deletions, migrations, afterImage } = _toHdiMigration(model, lastDevVersion,
|
|
16
|
+
const journalFileNames = _getJournalFileNames(model)
|
|
17
|
+
const { definitions, deletions, migrations, afterImage } = _toHdiMigration(model, lastDevVersion, journalFileNames, options)
|
|
17
18
|
const definitionResult = []
|
|
18
19
|
|
|
19
20
|
for (const { name, suffix, sql } of definitions) {
|
|
20
21
|
let definitionEntry = { name, suffix, content: sql }
|
|
21
22
|
|
|
22
23
|
if (suffix === '.hdbtable') {
|
|
23
|
-
if (
|
|
24
|
+
if (journalFileNames.has(name)) {
|
|
24
25
|
const migration = migrations.find(migration => migration.name === name)
|
|
25
26
|
definitionEntry = await _2migrationtable(srcPath, migration || _emptyMigration(name), sql, options)
|
|
26
27
|
}
|
|
@@ -32,14 +33,14 @@ module.exports = async (model, lastDevVersion, srcPath, options = {}) => {
|
|
|
32
33
|
return { definitions: definitionResult, deletions, afterImage }
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
function _toHdiMigration(model, lastDevVersion,
|
|
36
|
+
function _toHdiMigration(model, lastDevVersion, journalFileNames, options) {
|
|
36
37
|
options.sqlChangeMode = getProperty(options, 'hana.journal.change-mode')
|
|
37
38
|
const result = cdsc.to.hdi.migration(minified(model), options, lastDevVersion);
|
|
38
39
|
if (logger._debug) {
|
|
39
40
|
logger.debug('cdsc.to.hdi.migration returned')
|
|
40
41
|
for (const { name, suffix, sql } of result.definitions) {
|
|
41
42
|
if (suffix === '.hdbtable' || suffix === '.hdbmigrationtable') {
|
|
42
|
-
if (
|
|
43
|
+
if (journalFileNames.has(name)) {
|
|
43
44
|
const migration = result.migrations.find(migration => migration.name === name)
|
|
44
45
|
logger.debug(`
|
|
45
46
|
File ${name + '.hdbmigrationtable'} - ${migration ? migration.changeset.length : 0} new changes
|
|
@@ -132,7 +133,7 @@ function _emptyMigration(name) {
|
|
|
132
133
|
return { name, suffix: ".hdbmigrationtable", changeset: [] }
|
|
133
134
|
}
|
|
134
135
|
|
|
135
|
-
function
|
|
136
|
+
function _getJournalFileNames(model) {
|
|
136
137
|
const journalNames = new Set(cds.reflect(model).all(item => {
|
|
137
138
|
if (item.kind === 'entity' && item['@cds.persistence.journal'] === true) {
|
|
138
139
|
if (item['@cds.persistence.skip'] === true || item['@cds.persistence.exists'] === true) {
|
|
@@ -141,7 +142,7 @@ function _getJournalEntityNames(model) {
|
|
|
141
142
|
return true
|
|
142
143
|
}
|
|
143
144
|
return false
|
|
144
|
-
}).map(entity => entity.name))
|
|
145
|
+
}).map(entity => getArtifactCdsPersistenceName(entity.name, 'quoted', model)))
|
|
145
146
|
|
|
146
147
|
logger._debug && logger.debug(`\n[hdbmigrationtable] found ${journalNames.size} model entities annotated with '@cds.persistence.journal`)
|
|
147
148
|
logger._debug && logger.debug(`[hdbmigrationtable] ${[...journalNames].join(', ')}\n`)
|
|
@@ -27,7 +27,7 @@ class JavaCfModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
27
27
|
throw new BuildError('CDS compiler version 2 does no longer support the classic CAP Java runtime. It is recommended to migrate to the current CAP Java runtime SDK. See https://cap.cloud.sap/docs/java/migration for more.')
|
|
28
28
|
}
|
|
29
29
|
// default is now v4 and not v2 anymore, so warn and overwrite with v2 if using default
|
|
30
|
-
if (!this.env.for('cds', this.buildOptions.root, false
|
|
30
|
+
if (!this.env.for('cds', this.buildOptions.root, false).get(ODATA_VERSION)) {
|
|
31
31
|
odataOptions.version = ODATA_VERSION_V2
|
|
32
32
|
this.pushMessage('Forcing OData v2 for building though the default is v4. Make sure to define OData v2 in cds configuration.', INFO)
|
|
33
33
|
}
|
|
@@ -11,7 +11,7 @@ const { defaultLogger, nullLogger } = require('./logger');
|
|
|
11
11
|
const hdiDeployUtil = require('./hdiDeployUtil');
|
|
12
12
|
const mtaUtil = require('../../build/mtaUtil');
|
|
13
13
|
const runCommand = require('./runCommand');
|
|
14
|
-
const { bold,
|
|
14
|
+
const { bold, info } = require('../../utils/term');
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
const IS_WIN = (os.platform() === 'win32');
|
|
@@ -27,8 +27,6 @@ class HanaDeployer {
|
|
|
27
27
|
logger.log(`[cds.deploy] - ${bold('Starting deploy to SAP HANA ...')}`);
|
|
28
28
|
logger.log();
|
|
29
29
|
|
|
30
|
-
this._validateEnvironment(logger);
|
|
31
|
-
|
|
32
30
|
const projectPath = path.resolve(process.env._TEST_CWD || process.cwd());
|
|
33
31
|
|
|
34
32
|
const { buildResults } = await this._build(buildTaskOptions, model, logger);
|
|
@@ -276,20 +274,6 @@ ${entry}
|
|
|
276
274
|
}
|
|
277
275
|
}
|
|
278
276
|
|
|
279
|
-
|
|
280
|
-
_validateEnvironment(logger) {
|
|
281
|
-
if (IS_WIN && !process.env.SECUDIR) {
|
|
282
|
-
const helpUrl = info('https://help.sap.com/viewer/e54136ab6a4a43e6a370265bf0a2d744/latest/en-US/c049e28431ee4e8280cd6f5d1a8937d8.html');
|
|
283
|
-
const errMessage = error('[ERROR]') + ` [cds.deploy] - In order to use the hdi deployer on ${bold("Windows")} you require the ${bold("SAP CommonCryptoLib")}.
|
|
284
|
-
Please follow ${helpUrl}
|
|
285
|
-
for further information on how to obtain ${bold("SAP CommonCryptoLib")}.
|
|
286
|
-
`;
|
|
287
|
-
logger.error(errMessage);
|
|
288
|
-
throw new Error(`[cds.deploy] - Missing SAP CommonCryptoLib`);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
277
|
_getVCAPServicesEntry(serviceInstanceName, serviceKey) {
|
|
294
278
|
return {
|
|
295
279
|
hana: [
|
package/common.cds
CHANGED
|
@@ -65,6 +65,13 @@ aspect temporal {
|
|
|
65
65
|
type User : String(255);
|
|
66
66
|
|
|
67
67
|
|
|
68
|
+
/*
|
|
69
|
+
* Aspects for extensible entities.
|
|
70
|
+
*/
|
|
71
|
+
aspect extensible {
|
|
72
|
+
@cds.api.ignore extensions__ : String
|
|
73
|
+
};
|
|
74
|
+
|
|
68
75
|
//---------------------------------------------------------------------------
|
|
69
76
|
// Annotations for Fiori UIs...
|
|
70
77
|
|
|
@@ -122,6 +129,7 @@ annotate managed with {
|
|
|
122
129
|
//---------------------------------------------------------------------------
|
|
123
130
|
// Temporary Workarounds...
|
|
124
131
|
|
|
132
|
+
// REVISIT: Remove support for @odata.on... and #... with @sap/cds ^6
|
|
125
133
|
// REVISIT: change @odata.on... to @cds.on...
|
|
126
134
|
// REVISIT: @cds.on... should automatically result in @readonly @Core.Computed
|
|
127
135
|
|
package/lib/compile/to/sql.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const cds = require ('../..'), minified = csn => cds.linked(csn).minified()
|
|
2
2
|
const cdsc = require ('../cdsc')
|
|
3
3
|
const {unfold_ddl} = cds.alpha_localized
|
|
4
|
+
const EXT_BACK_PACK = 'extensions__'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
function cds_compile_to_sql (csn,_o) {
|
|
6
|
+
function cds_compile_to_sql_ (csn,_o) {
|
|
7
7
|
const o = cdsc._options.for.sql(_o) //> used twice below...
|
|
8
8
|
const all = cdsc.to.sql (minified(csn),o)
|
|
9
9
|
const sql = unfold_ddl (all.map (each => each
|
|
@@ -13,6 +13,26 @@ function cds_compile_to_sql (csn,_o) {
|
|
|
13
13
|
return sql
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
function cds_compile_to_sql (csn,_o) {
|
|
17
|
+
const defs = cds.linked(csn).definitions
|
|
18
|
+
for (let each in defs) {
|
|
19
|
+
const d = defs[each], q = d.query
|
|
20
|
+
// q may have SET instead of SELECT
|
|
21
|
+
if (q && q.SELECT && q.SELECT.columns && _is_extensible(d)) _add_extensions2 (q.SELECT.columns)
|
|
22
|
+
}
|
|
23
|
+
function _is_extensible (d) {
|
|
24
|
+
if(!d || !d.elements) return false
|
|
25
|
+
if (EXT_BACK_PACK in d.elements) return true
|
|
26
|
+
else return _is_extensible (d.__proto__)
|
|
27
|
+
}
|
|
28
|
+
function _add_extensions2 (cols) {
|
|
29
|
+
if (cols.some(({ref}) => ref && ref[0] === EXT_BACK_PACK)) return
|
|
30
|
+
cols.push({ref:[EXT_BACK_PACK]})
|
|
31
|
+
}
|
|
32
|
+
const ddl = cds_compile_to_sql_ (csn,_o)
|
|
33
|
+
return ddl
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
|
|
17
37
|
function cds_compile_to_hdbtable (csn,o) {
|
|
18
38
|
const all = cdsc.to.hdi (minified(csn),o)
|
package/lib/connect/bindings.js
CHANGED
|
@@ -19,9 +19,10 @@ module.exports = class Bindings {
|
|
|
19
19
|
return bindings.import() .then (r,e)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
constructor() {
|
|
22
|
+
constructor(url) {
|
|
23
23
|
this._source = require ('path') .resolve (cds.root, registry.replace(/^~/, require('os').homedir()))
|
|
24
24
|
this.cds = {provides:{}}
|
|
25
|
+
this.url = url
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
async load (sync) {
|
package/lib/core/reflect.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const { types, classes:{ service, entity, action, event, any, struct, array, context, annotation } } = require('.')
|
|
2
2
|
const _kinds = { annotation, context, service, action, event, entity, view:entity }
|
|
3
|
+
const _minified = Symbol('minified')
|
|
3
4
|
|
|
4
5
|
class LinkedCSN extends any {
|
|
5
6
|
|
|
@@ -25,6 +26,7 @@ class LinkedCSN extends any {
|
|
|
25
26
|
/* else: */ any.prototype
|
|
26
27
|
)
|
|
27
28
|
if (p.key && !d.key && d.kind === 'element') Object.defineProperty (d,'key',{value:undefined}) //> don't propagate .key
|
|
29
|
+
if (d.elements && d.elements.localized) Object.defineProperty (d,'texts',{value: defs [d.elements.localized.target] })
|
|
28
30
|
try { return Object.setPrototypeOf(d,p) } //> link d to resolved proto
|
|
29
31
|
catch(e) { //> cyclic proto error
|
|
30
32
|
let msg = d.name; for (; p && p.name; p = p.__proto__) msg += ' > '+p.name
|
|
@@ -48,6 +50,7 @@ class LinkedCSN extends any {
|
|
|
48
50
|
|
|
49
51
|
minified (skip = global.cds.env.features.skip_unused) {
|
|
50
52
|
if (!skip) return this
|
|
53
|
+
if (this[_minified]) return this; else _set (this,_minified,true)
|
|
51
54
|
const csn = this, all = csn.definitions, reached = new Set
|
|
52
55
|
const roots = skip === 'all' ? this.services : this.each(_root)
|
|
53
56
|
for (let each of roots) _visit (each)
|
|
@@ -74,7 +77,7 @@ class LinkedCSN extends any {
|
|
|
74
77
|
if (n.endsWith('.texts')) delete all[n.replace('.texts','_texts')]
|
|
75
78
|
}
|
|
76
79
|
}
|
|
77
|
-
return
|
|
80
|
+
return this
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
*each (x, defs=this.definitions) {
|