@sap/cds 7.5.0 → 7.5.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 +14 -0
- package/lib/auth/index.js +2 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +5 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/OdataRequest.js +4 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/handler/MetadataHandler.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/handler/ServiceHandler.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DispatcherCommand.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +1 -0
- package/libx/odata/metadata.js +5 -1
- package/libx/odata/read.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@
|
|
|
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 7.5.2 - 2024-01-05
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Service-level ETag handling in legacy OData server
|
|
12
|
+
- Only provide model to ModelProvider if extensibility or feature toggles are active
|
|
13
|
+
- OData server driven paging when using feature flags `cds.env.features.odata_new_parser` and `cds.env.features.okra_skip_query_options`
|
|
14
|
+
|
|
15
|
+
## Version 7.5.1 - 2023-12-21
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Resolving custom authentication implementation pointer
|
|
20
|
+
|
|
7
21
|
## Version 7.5.0 - 2023-12-14
|
|
8
22
|
|
|
9
23
|
### Added
|
package/lib/auth/index.js
CHANGED
|
@@ -30,7 +30,8 @@ module.exports = function auth_factory (o) {
|
|
|
30
30
|
|
|
31
31
|
// try resolving the impl, throw if not found
|
|
32
32
|
const config = { kind, impl: cds.utils.local(impl) }
|
|
33
|
-
|
|
33
|
+
// use cds.resolve() to allow './srv/auth.js' and 'srv/auth.js'
|
|
34
|
+
try { impl = require.resolve (cds.resolve (impl)?.[0], {paths:[cds.root]}) } catch {
|
|
34
35
|
throw cds.error `Didn't find auth implementation for ${config}`
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -31,7 +31,11 @@ const metadata = service => {
|
|
|
31
31
|
if (mps) {
|
|
32
32
|
// REVISIT: remove check later
|
|
33
33
|
if (mpSupportsEmptyLocale()) {
|
|
34
|
-
|
|
34
|
+
// If no extensibility nor fts, do not provide model to mtxs
|
|
35
|
+
const modelNeeded =
|
|
36
|
+
cds.env.requires.extensibility ||
|
|
37
|
+
(cds.env.requires.toggles && Object.keys(cds.context.features || {}).length)
|
|
38
|
+
edmx = await mps.getEdmx({ tenant, model: modelNeeded && service.model, service: service.definition.name })
|
|
35
39
|
const extBundle = cds.env.requires.extensibility && (await mps.getI18n({ tenant, locale }))
|
|
36
40
|
edmx = cds.localize(service.model, locale, edmx, extBundle)
|
|
37
41
|
} else {
|
|
@@ -273,9 +273,9 @@ const _readCollection = async (tx, req, odataReq) => {
|
|
|
273
273
|
const limit = Array.isArray(req.query)
|
|
274
274
|
? getPageSize(req.query[0]._target).max
|
|
275
275
|
: req.query.SELECT.limit && req.query.SELECT.limit.rows && req.query.SELECT.limit.rows.val
|
|
276
|
-
const top = odataReq.getUriInfo().getQueryOption(QueryOptions.TOP)
|
|
276
|
+
const top = odataReq.getUriInfo().getQueryOption(QueryOptions.TOP) || parseInt(odataReq._queryOptions?.$top)
|
|
277
277
|
if (limit && limit === result.length && limit !== top && !('$nextLink' in result)) {
|
|
278
|
-
const token = odataReq.getUriInfo().getQueryOption(QueryOptions.SKIPTOKEN)
|
|
278
|
+
const token = odataReq.getUriInfo().getQueryOption(QueryOptions.SKIPTOKEN) || odataReq._queryOptions?.$skiptoken
|
|
279
279
|
if (cds.env.query.limit.reliablePaging && _reliablePagingPossible(req)) {
|
|
280
280
|
const decoded = token && JSON.parse(Buffer.from(token, 'base64').toString())
|
|
281
281
|
const skipToken = {
|
|
@@ -283,7 +283,10 @@ class OdataRequest {
|
|
|
283
283
|
* @throws {PreconditionFailedError} if the validations failed
|
|
284
284
|
*/
|
|
285
285
|
validateEtag (etag) {
|
|
286
|
-
|
|
286
|
+
const url = this.getIncomingRequest().url
|
|
287
|
+
if (!url.match(/\/(\$metadata)?(\?.*)?$/) && !process.env.TEST_OKRA) //> keep etag handling for okra tests
|
|
288
|
+
throw new Error(`etag validation not supported for url "${url}"`)
|
|
289
|
+
|
|
287
290
|
this._logger.debug('Provided etag:', etag)
|
|
288
291
|
|
|
289
292
|
this._validateEtagHasBeenCalled = true
|
package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/handler/MetadataHandler.js
CHANGED
|
@@ -12,7 +12,7 @@ class MetadataHandler {
|
|
|
12
12
|
*/
|
|
13
13
|
static read (request, response, next) {
|
|
14
14
|
const metadataETag = request.getService().getMetadataEtag()
|
|
15
|
-
|
|
15
|
+
if (metadataETag) request.validateEtag(metadataETag)
|
|
16
16
|
|
|
17
17
|
next(null, { [MetaProperties.ETAG]: metadataETag })
|
|
18
18
|
}
|
package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/handler/ServiceHandler.js
CHANGED
|
@@ -16,7 +16,7 @@ class ServiceHandler {
|
|
|
16
16
|
*/
|
|
17
17
|
static read (request, response, next) {
|
|
18
18
|
const metadataETag = request.getService().getMetadataEtag()
|
|
19
|
-
|
|
19
|
+
if (metadataETag) request.validateEtag(metadataETag)
|
|
20
20
|
next(null, { [MetaProperties.ETAG]: metadataETag })
|
|
21
21
|
// TODO this method may be replaced by a custom service handler, so we need a scenario test that ensures that this method is called...
|
|
22
22
|
}
|
|
@@ -56,7 +56,7 @@ class DispatcherCommand extends Command {
|
|
|
56
56
|
|
|
57
57
|
if (cachedMetadata) {
|
|
58
58
|
this._response.setBody({ value: cachedMetadata.metadata, [MetaProperties.ETAG]: cachedMetadata.etag })
|
|
59
|
-
|
|
59
|
+
this._request.validateEtag(cachedMetadata.etag)
|
|
60
60
|
next()
|
|
61
61
|
} else {
|
|
62
62
|
this._dispatcher
|
|
@@ -79,7 +79,7 @@ class DispatcherCommand extends Command {
|
|
|
79
79
|
'Metadata size exceeds cache boundary. Use cds option odata.metadataCacheLimit to increase the cache size.'
|
|
80
80
|
)
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
this._request.validateEtag(metadataEtag)
|
|
83
83
|
let data = result.data
|
|
84
84
|
data[MetaProperties.ETAG] = metadataEtag
|
|
85
85
|
}
|
package/libx/odata/metadata.js
CHANGED
|
@@ -92,7 +92,11 @@ module.exports = srv =>
|
|
|
92
92
|
let edmx
|
|
93
93
|
// REVISIT: remove check later
|
|
94
94
|
if (mpSupportsEmptyLocale()) {
|
|
95
|
-
|
|
95
|
+
// If no extensibility nor fts, do not provide model to mtxs
|
|
96
|
+
const modelNeeded =
|
|
97
|
+
cds.env.requires.extensibility ||
|
|
98
|
+
(cds.env.requires.toggles && Object.keys(cds.context.features || {}).length)
|
|
99
|
+
edmx = metadataCache.edm || (await mps.getEdmx({ tenant, model: modelNeeded && srv.model, service: srv.definition.name }))
|
|
96
100
|
metadataCache.edm = edmx
|
|
97
101
|
const extBundle = cds.env.requires.extensibility && (await mps.getI18n({ tenant, locale }))
|
|
98
102
|
edmx = cds.localize(srv.model, locale, edmx, extBundle)
|
package/libx/odata/read.js
CHANGED
|
@@ -27,9 +27,9 @@ const _calculateSkiptoken = (req, result) => {
|
|
|
27
27
|
const limit = Array.isArray(req.query)
|
|
28
28
|
? getPageSize(req.query[0]._target).max
|
|
29
29
|
: req.query.SELECT.limit?.rows?.val
|
|
30
|
-
const top = parseInt(req.http.req.query
|
|
30
|
+
const top = parseInt(req.http.req.query.$top)
|
|
31
31
|
if (limit === result.length && limit !== top) {
|
|
32
|
-
const token = req.http.req.query
|
|
32
|
+
const token = req.http.req.query.$skiptoken
|
|
33
33
|
if (cds.env.query.limit.reliablePaging && _reliablePagingPossible(req)) {
|
|
34
34
|
const decoded = token && JSON.parse(Buffer.from(token, 'base64').toString())
|
|
35
35
|
const skipToken = {
|