@sap/cds 7.9.3 → 8.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 +126 -3655
- package/_i18n/i18n_en_US_saptrc.properties +113 -0
- package/_i18n/i18n_zh_CN.properties +7 -4
- package/app/index.css +129 -0
- package/app/index.html +16 -64
- package/app/index.js +14 -9
- package/bin/args.js +34 -0
- package/bin/serve.js +18 -24
- package/bin/test.js +97 -0
- package/common.cds +5 -12
- package/eslint.config.mjs +133 -0
- package/lib/auth/basic-auth.js +16 -20
- package/lib/auth/dummy-auth.js +1 -1
- package/lib/auth/ias-auth.js +9 -41
- package/lib/auth/index.js +1 -14
- package/lib/auth/jwt-auth.js +10 -40
- package/lib/compile/cds-compile.js +1 -2
- package/lib/compile/cdsc.js +21 -26
- package/lib/compile/etc/_localized.js +1 -6
- package/lib/compile/etc/csv.js +1 -1
- package/lib/compile/etc/properties.js +1 -1
- package/lib/compile/for/java.js +1 -1
- package/lib/compile/for/lean_drafts.js +4 -6
- package/lib/compile/for/nodejs.js +1 -1
- package/lib/compile/parse.js +4 -0
- package/lib/compile/resolve.js +4 -4
- package/lib/compile/to/edm-files.js +16 -23
- package/lib/compile/to/hana.js +27 -0
- package/lib/compile/to/json.js +1 -1
- package/lib/compile/to/sql.js +5 -1
- package/lib/compile/to/yaml.js +3 -3
- package/lib/dbs/cds-deploy.js +4 -2
- package/lib/env/cds-env.js +10 -14
- package/lib/env/cds-requires.js +29 -13
- package/lib/env/defaults.js +46 -16
- package/lib/env/plugins.js +1 -1
- package/lib/env/schemas/cds-rc.js +8 -4
- package/lib/env/schemas/index.js +7 -7
- package/lib/env/serviceBindings.js +1 -1
- package/lib/index.js +12 -10
- package/lib/lazy.js +1 -1
- package/lib/linked/classes.js +36 -8
- package/lib/linked/entities.js +2 -10
- package/lib/linked/models.js +2 -1
- package/lib/linked/validate.js +292 -0
- package/lib/log/cds-error.js +0 -6
- package/lib/log/cds-log.js +3 -3
- package/lib/log/format/json.js +1 -1
- package/lib/log/service/index.js +0 -1
- package/lib/plugins.js +2 -2
- package/lib/ql/Query.js +2 -10
- package/lib/ql/SELECT.js +1 -1
- package/lib/ql/Whereable.js +3 -2
- package/lib/req/cds-context.js +14 -25
- package/lib/req/context.js +23 -25
- package/lib/req/request.js +1 -34
- package/lib/req/user.js +47 -35
- package/lib/srv/bindings.js +1 -1
- package/lib/srv/cds-connect.js +4 -4
- package/lib/srv/cds-serve.js +2 -2
- package/lib/srv/factory.js +1 -1
- package/lib/srv/middlewares/cds-context.js +11 -22
- package/lib/srv/middlewares/ctx-model.js +2 -3
- package/lib/srv/middlewares/errors.js +41 -8
- package/lib/srv/middlewares/index.js +3 -3
- package/lib/srv/middlewares/trace.js +0 -2
- package/lib/srv/protocols/hcql.js +15 -10
- package/lib/srv/protocols/http.js +44 -49
- package/lib/srv/protocols/index.js +1 -23
- package/lib/srv/protocols/odata-v4.js +12 -74
- package/lib/srv/protocols/rest.js +1 -13
- package/lib/srv/srv-api.js +0 -20
- package/lib/srv/srv-dispatch.js +3 -2
- package/lib/srv/srv-handlers.js +22 -11
- package/lib/srv/srv-methods.js +2 -2
- package/lib/srv/srv-models.js +3 -36
- package/lib/test/expect.js +343 -0
- package/lib/test/index.js +2 -0
- package/lib/test/reporter.js +176 -0
- package/lib/utils/axios.js +10 -9
- package/lib/utils/cds-test.js +85 -36
- package/lib/utils/cds-utils.js +54 -7
- package/lib/utils/check-version.js +0 -4
- package/lib/utils/colors.js +49 -0
- package/lib/utils/data.js +5 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +2 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +3 -30
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +6 -12
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +1 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +0 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +4 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +12 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +2 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +0 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +1 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/AbstractEdmStructuredType.js +1 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/ResourceJsonDeserializer.js +5 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ContextURLFactory.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +9 -43
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +0 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +8 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +4 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +1 -3
- package/libx/_runtime/cds-services/util/assert.js +1 -1
- package/libx/_runtime/cds.js +10 -3
- package/libx/_runtime/common/Service.js +12 -32
- package/libx/_runtime/common/aspects/any.js +1 -0
- package/libx/_runtime/common/code-ext/execute.js +1 -1
- package/libx/_runtime/common/code-ext/worker.js +0 -1
- package/libx/_runtime/common/composition/data.js +0 -1
- package/libx/_runtime/common/composition/delete.js +0 -1
- package/libx/_runtime/common/composition/insert.js +2 -2
- package/libx/_runtime/common/composition/tree.js +0 -1
- package/libx/_runtime/common/composition/update.js +3 -3
- package/libx/_runtime/common/error/frontend.js +21 -12
- package/libx/_runtime/common/error/log.js +36 -0
- package/libx/_runtime/common/error/utils.js +2 -5
- package/libx/_runtime/common/generic/auth/autoexpose.js +18 -17
- package/libx/_runtime/common/generic/auth/expand.js +1 -1
- package/libx/_runtime/common/generic/auth/readOnly.js +1 -2
- package/libx/_runtime/common/generic/auth/restrict.js +23 -42
- package/libx/_runtime/common/generic/auth/restrictions.js +2 -7
- package/libx/_runtime/common/generic/auth/utils.js +91 -88
- package/libx/_runtime/common/generic/crud.js +6 -5
- package/libx/_runtime/common/generic/etag.js +7 -12
- package/libx/_runtime/common/generic/input.js +70 -68
- package/libx/_runtime/common/generic/paging.js +1 -0
- package/libx/_runtime/common/generic/sorting.js +1 -0
- package/libx/_runtime/common/generic/temporal.js +8 -2
- package/libx/_runtime/common/i18n/index.js +1 -1
- package/libx/_runtime/common/i18n/messages.properties +3 -1
- package/libx/_runtime/common/utils/binary.js +8 -2
- package/libx/_runtime/common/utils/compareJson.js +5 -1
- package/libx/_runtime/common/utils/copy.js +6 -11
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +16 -14
- package/libx/_runtime/common/utils/differ.js +3 -6
- package/libx/_runtime/common/utils/keys.js +77 -18
- package/libx/_runtime/common/utils/postProcess.js +12 -15
- package/libx/_runtime/common/utils/propagateForeignKeys.js +0 -1
- package/libx/_runtime/common/utils/resolveView.js +2 -3
- package/libx/_runtime/common/utils/restrictions.js +45 -17
- package/libx/_runtime/common/utils/rewriteAsterisks.js +1 -8
- package/libx/_runtime/common/utils/stream.js +3 -16
- package/libx/_runtime/common/utils/streamProp.js +8 -18
- package/libx/_runtime/common/utils/structured.js +1 -1
- package/libx/_runtime/common/utils/ucsn.js +0 -2
- package/libx/_runtime/db/Service.js +0 -72
- package/libx/_runtime/db/data-conversion/post-processing.js +0 -1
- package/libx/_runtime/db/expand/expandCQNToJoin.js +9 -9
- package/libx/_runtime/db/expand/rawToExpanded.js +0 -8
- package/libx/_runtime/db/generic/input.js +3 -8
- package/libx/_runtime/db/generic/rewrite.js +1 -0
- package/libx/_runtime/db/query/read.js +2 -2
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +0 -1
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
- package/libx/_runtime/db/utils/columns.js +2 -6
- package/libx/_runtime/fiori/lean-draft.js +138 -56
- package/libx/_runtime/hana/Service.js +0 -1
- package/libx/_runtime/hana/driver.js +1 -1
- package/libx/_runtime/hana/dynatrace.js +1 -2
- package/libx/_runtime/hana/pool.js +11 -21
- package/libx/_runtime/hana/streaming.js +0 -1
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +0 -1
- package/libx/_runtime/messaging/common-utils/authorizedRequest.js +1 -1
- package/libx/_runtime/messaging/common-utils/normalizeIncomingMessage.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/getTenantInfo.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +19 -33
- package/libx/_runtime/messaging/event-broker.js +0 -12
- package/libx/_runtime/messaging/file-based.js +3 -3
- package/libx/_runtime/messaging/http-utils/token.js +1 -1
- package/libx/_runtime/messaging/kafka.js +2 -2
- package/libx/_runtime/messaging/redis-messaging.js +0 -1
- package/libx/_runtime/remote/Service.js +25 -25
- package/libx/_runtime/remote/utils/client.js +4 -5
- package/libx/_runtime/remote/utils/cloudSdkProvider.js +0 -3
- package/libx/_runtime/remote/utils/data.js +0 -1
- package/libx/_runtime/sqlite/Service.js +1 -2
- package/libx/_runtime/ucl/Service.js +37 -78
- package/libx/common/assert/index.js +22 -21
- package/libx/common/assert/type-relaxed.js +39 -0
- package/libx/common/assert/utils.js +3 -2
- package/libx/common/assert/validation.js +3 -8
- package/libx/common/utils/index.js +5 -0
- package/libx/common/utils/path.js +51 -0
- package/libx/odata/ODataAdapter.js +126 -0
- package/libx/odata/index.js +15 -2
- package/libx/odata/middleware/batch.js +261 -72
- package/libx/odata/middleware/body-parser.js +33 -0
- package/libx/odata/middleware/create.js +44 -59
- package/libx/odata/middleware/delete.js +23 -12
- package/libx/odata/middleware/error.js +30 -6
- package/libx/odata/middleware/metadata.js +38 -26
- package/libx/odata/middleware/operation.js +93 -69
- package/libx/odata/middleware/parse.js +6 -8
- package/libx/odata/middleware/read.js +117 -93
- package/libx/odata/middleware/service-document.js +22 -19
- package/libx/odata/middleware/stream.js +54 -56
- package/libx/odata/middleware/update.js +79 -87
- package/libx/odata/parse/afterburner.js +191 -175
- package/libx/odata/parse/cqn2odata.js +8 -8
- package/libx/odata/parse/grammar.peggy +27 -20
- package/libx/odata/parse/multipartToJson.js +17 -9
- package/libx/odata/parse/parser.js +1 -1
- package/libx/odata/utils/etag.js +14 -6
- package/libx/odata/utils/index.js +84 -12
- package/libx/odata/utils/metadata.js +161 -0
- package/libx/odata/utils/postProcess.js +89 -0
- package/libx/odata/utils/readAfterWrite.js +134 -17
- package/libx/odata/utils/result.js +36 -142
- package/libx/outbox/index.js +4 -3
- package/libx/rest/RestAdapter.js +115 -182
- package/libx/rest/middleware/create.js +28 -24
- package/libx/rest/middleware/delete.js +7 -10
- package/libx/rest/middleware/error.js +19 -16
- package/libx/rest/middleware/operation.js +48 -41
- package/libx/rest/middleware/parse.js +128 -126
- package/libx/rest/middleware/read.js +20 -27
- package/libx/rest/middleware/update.js +26 -31
- package/package.json +17 -8
- package/server.js +4 -2
- package/tasks/enterprise-messaging-deploy.js +1 -1
- package/apis/cds.d.ts +0 -3
- package/apis/core.d.ts +0 -21
- package/apis/cqn.d.ts +0 -18
- package/apis/csn.d.ts +0 -21
- package/apis/events.d.ts +0 -18
- package/apis/internal/inference.d.ts +0 -18
- package/apis/linked.d.ts +0 -18
- package/apis/log.d.ts +0 -20
- package/apis/models.d.ts +0 -18
- package/apis/ql.d.ts +0 -18
- package/apis/reflect.d.ts +0 -32
- package/apis/server.d.ts +0 -18
- package/apis/services.d.ts +0 -22
- package/bin/cds-serve.js +0 -56
- package/lib/compile/to/gql.js +0 -15
- package/lib/srv/protocols/_legacy.js +0 -44
- package/lib/utils/jest.js +0 -43
- package/libx/_runtime/auth/index.js +0 -193
- package/libx/_runtime/auth/strategies/JWT.js +0 -37
- package/libx/_runtime/auth/strategies/basic.js +0 -20
- package/libx/_runtime/auth/strategies/dummy.js +0 -14
- package/libx/_runtime/auth/strategies/ias-auth.js +0 -1
- package/libx/_runtime/auth/strategies/mock.js +0 -77
- package/libx/_runtime/auth/strategies/xssecUtils.js +0 -93
- package/libx/_runtime/auth/strategies/xsuaa.js +0 -38
- package/libx/_runtime/common/perf/index.js +0 -19
- package/libx/_runtime/common/utils/ensureIEEE754.js +0 -29
- package/libx/_runtime/fiori/draft.js +0 -2
- package/libx/_runtime/fiori/generic/activate.js +0 -190
- package/libx/_runtime/fiori/generic/before.js +0 -201
- package/libx/_runtime/fiori/generic/cancel.js +0 -19
- package/libx/_runtime/fiori/generic/delete.js +0 -21
- package/libx/_runtime/fiori/generic/edit.js +0 -157
- package/libx/_runtime/fiori/generic/index.js +0 -25
- package/libx/_runtime/fiori/generic/new.js +0 -82
- package/libx/_runtime/fiori/generic/patch.js +0 -101
- package/libx/_runtime/fiori/generic/prepare.js +0 -57
- package/libx/_runtime/fiori/generic/read.js +0 -1340
- package/libx/_runtime/fiori/generic/readOverDraft.js +0 -146
- package/libx/_runtime/fiori/utils/csn.js +0 -13
- package/libx/_runtime/fiori/utils/delete.js +0 -114
- package/libx/_runtime/fiori/utils/handler.js +0 -264
- package/libx/_runtime/fiori/utils/lockInfo.js +0 -27
- package/libx/_runtime/fiori/utils/req.js +0 -23
- package/libx/_runtime/fiori/utils/stream.js +0 -36
- package/libx/_runtime/fiori/utils/where.js +0 -254
- package/libx/_runtime/index.js +0 -22
- package/libx/odata/utils/handler.js +0 -120
- package/libx/odata/utils/metaInfo.js +0 -410
- package/libx/odata/utils/path.js +0 -75
- package/libx/rest/RestRequest.js +0 -32
- package/libx/rest/index.js +0 -3
- package/libx/rest/readme.md +0 -1
- /package/libx/common/assert/{type.js → type-strict.js} +0 -0
package/lib/req/user.js
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Users factory function which can be used as follows:
|
|
3
|
+
* - `User(<string>)` - returns a new user instance with the given string as id
|
|
4
|
+
* - `User(<object>)` - returns a new user instance with the given properties
|
|
5
|
+
* - `User(<none>)` - returns the default user if the argument is undefined
|
|
6
|
+
* - `User(<user>)` - returns the given user if it's an instance of `User`
|
|
7
|
+
* - `new User(...)` - always constructs a new instance of User
|
|
8
|
+
*/
|
|
9
|
+
module.exports = exports = function (u) {
|
|
10
|
+
return new.target ? new User(u) :
|
|
11
|
+
u === undefined ? exports.default :
|
|
12
|
+
u instanceof User ? u :
|
|
13
|
+
new User(u)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Class representing users */
|
|
1
17
|
class User {
|
|
2
18
|
|
|
3
19
|
constructor (_) {
|
|
4
|
-
if (_ ===
|
|
5
|
-
if (new.target === Privileged) return
|
|
6
|
-
if (new.target === Anonymous) return
|
|
7
|
-
else return new User.default
|
|
8
|
-
}
|
|
9
|
-
else if (typeof _ === 'string') this.id = _
|
|
20
|
+
if (typeof _ === 'string') this.id = _
|
|
10
21
|
else Object.assign(this,_)
|
|
11
22
|
}
|
|
12
23
|
|
|
@@ -15,50 +26,51 @@ class User {
|
|
|
15
26
|
|
|
16
27
|
get roles() { return super.roles = {} }
|
|
17
28
|
set roles(r) {
|
|
18
|
-
super.roles = Array.isArray(r) ? r.reduce((p,
|
|
29
|
+
super.roles = Array.isArray(r) ? r.reduce((p,n) => (p[n]=1, p), {}) : r
|
|
19
30
|
}
|
|
20
31
|
|
|
32
|
+
has (role) { return this.is(role) }
|
|
21
33
|
is (role) {
|
|
22
34
|
return (
|
|
23
35
|
role === 'authenticated-user' ||
|
|
24
36
|
role === 'identified-user' ||
|
|
25
37
|
role === 'any' ||
|
|
26
|
-
|
|
38
|
+
role in this.roles // REVISIT: This may break something, did in the past, but we don't know anymore. we should know.
|
|
27
39
|
)
|
|
28
40
|
}
|
|
29
41
|
valueOf() { return this.id }
|
|
30
|
-
|
|
31
|
-
// compatibility
|
|
32
|
-
get _roles(){ return this.roles }
|
|
33
|
-
set _roles(r){ this.roles = r }
|
|
34
42
|
}
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
|
|
45
|
+
/** Subclass representing unauthenticated users. */
|
|
46
|
+
class Anonymous extends User {}
|
|
47
|
+
Object.assign (Anonymous.prototype, {
|
|
48
|
+
is: role => role === 'any',
|
|
49
|
+
_is_anonymous: true,
|
|
50
|
+
id: 'anonymous',
|
|
51
|
+
roles: {},
|
|
52
|
+
attr: {},
|
|
45
53
|
})
|
|
54
|
+
exports.anonymous = exports.default = Object.seal (new Anonymous)
|
|
55
|
+
exports.Anonymous = Anonymous
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
|
|
58
|
+
/** Subclass for executing code with superuser privileges. */
|
|
59
|
+
class Privileged extends User {}
|
|
60
|
+
Object.assign (Privileged.prototype, {
|
|
61
|
+
is: () => true,
|
|
62
|
+
_is_privileged: true,
|
|
63
|
+
id: 'privileged',
|
|
64
|
+
roles: {},
|
|
65
|
+
attr: {},
|
|
56
66
|
})
|
|
67
|
+
exports.privileged = Object.seal (new Privileged)
|
|
68
|
+
exports.Privileged = Privileged
|
|
57
69
|
|
|
58
70
|
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
default: Anonymous,
|
|
71
|
+
// Allow setting default user by class for compatibility, e.g.: User.default = User.Privileged
|
|
72
|
+
Object.defineProperty (exports, 'default', {
|
|
73
|
+
set(v) { this._default = typeof v === 'function' ? new v : v },
|
|
74
|
+
get() { return this._default },
|
|
64
75
|
})
|
|
76
|
+
exports._default = exports.anonymous
|
package/lib/srv/bindings.js
CHANGED
|
@@ -26,7 +26,7 @@ module.exports = class Bindings {
|
|
|
26
26
|
async load (sync) {
|
|
27
27
|
DEBUG?.('reading bindings from:', this._source)
|
|
28
28
|
try { Object.assign (this, JSON.parse (sync ? readFileSync (this._source) : await read (this._source))) }
|
|
29
|
-
catch
|
|
29
|
+
catch { /* ignored */ }
|
|
30
30
|
return this
|
|
31
31
|
}
|
|
32
32
|
async store (sync) {
|
package/lib/srv/cds-connect.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const cds = require('..'),
|
|
1
|
+
const cds = require('..'), LOG = cds.log('cds.connect')
|
|
2
2
|
const _pending = cds.services._pending || {} // used below to chain parallel connect.to(<same>)
|
|
3
3
|
const TRACE = cds.debug('trace')
|
|
4
4
|
|
|
@@ -72,7 +72,7 @@ function options4 (name, _o) {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
function model4 (o) {
|
|
75
|
-
if (o.model
|
|
76
|
-
if (
|
|
77
|
-
|
|
75
|
+
if (o.model?.definitions) return o.model // got a CSN already? -> use it
|
|
76
|
+
if (cds.model) return cds.model // use global model if available
|
|
77
|
+
if (o.model) return cds.load (o.model) // load specified model from file
|
|
78
78
|
}
|
package/lib/srv/cds-serve.js
CHANGED
|
@@ -3,7 +3,7 @@ const { Service } = cds.service.factory
|
|
|
3
3
|
const { serve } = cds.service.protocols
|
|
4
4
|
const _ready = Symbol(), _pending = cds.services._pending || {}
|
|
5
5
|
const TRACE = cds.debug('trace')
|
|
6
|
-
if (TRACE && !cds.env.features.odata_new_adapter) require('./../../libx/_runtime')
|
|
6
|
+
if (TRACE && !cds.env.features.odata_new_adapter) require('./../../libx/_runtime/cds-services/adapter/odata-v4/to')
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
/** @param som - a service name or a model (name or csn) */
|
|
@@ -36,7 +36,7 @@ module.exports = function cds_serve (som, _options) { // NOSONAR
|
|
|
36
36
|
const loaded = options.then (async ({from}=o) => {
|
|
37
37
|
if (!from || from === 'all' || from === '*') from = cds.model || '*'
|
|
38
38
|
if (from.definitions) return from
|
|
39
|
-
if (from === '?') try { return await cds.load('*',o) } catch
|
|
39
|
+
if (from === '?') try { return await cds.load('*',o) } catch { return }
|
|
40
40
|
return cds.load(from, {...o, silent:true })
|
|
41
41
|
})
|
|
42
42
|
|
package/lib/srv/factory.js
CHANGED
|
@@ -41,7 +41,7 @@ const _require = (it,d) => {
|
|
|
41
41
|
DEBUG && d && DEBUG ('requires',{ service: d.name, source:_source(d), impl:it })
|
|
42
42
|
if (it.startsWith('@sap/cds/')) it = cds.home + it.slice(8) //> for local tests in @sap/cds dev
|
|
43
43
|
if (it.startsWith('./')) it = _relative (d,it.slice(2)) //> relative to <service>.cds
|
|
44
|
-
try { var resolved = require.resolve(it,{paths}) } catch
|
|
44
|
+
try { var resolved = require.resolve(it,{paths}) } catch {
|
|
45
45
|
try { resolved = require.resolve(path.join(cds.root,it)) } catch(e) { // compatibility
|
|
46
46
|
throw cds.error `Failed loading service implementation from '${it}' ${{ Reason:e, paths, 'cds.root':cds.root }}`
|
|
47
47
|
}
|
|
@@ -1,27 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
const cds = require ('../../index')
|
|
2
|
+
const corr_id = 'x-correlation-id'
|
|
3
|
+
const req_id = 'x-request-id'
|
|
4
|
+
const vr_id = 'x-vcap-request-id'
|
|
5
|
+
const { uuid } = cds.utils
|
|
6
|
+
const { EventContext } = cds
|
|
4
7
|
|
|
8
|
+
module.exports = () => {
|
|
5
9
|
/** @type { import('express').Handler } */
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
ctx
|
|
9
|
-
|
|
10
|
+
return function cds_context (req, res, next) {
|
|
11
|
+
const id = req.headers[corr_id] ??= req.headers[req_id] || req.headers[vr_id] || uuid()
|
|
12
|
+
const ctx = EventContext.for ({ id, http: { req, res } })
|
|
13
|
+
res.set ('X-Correlation-ID', id) // Note: we use capitalized style here as that's common standard in HTTP world
|
|
10
14
|
cds._context.run (ctx, next)
|
|
11
15
|
}
|
|
12
|
-
|
|
13
|
-
const { uuid } = cds.utils
|
|
14
|
-
const _id4 = (req) => {
|
|
15
|
-
let id = req.headers['x-correlation-id'] = (
|
|
16
|
-
req.headers['x-correlation-id'] ||
|
|
17
|
-
req.headers['x-correlationid'] ||
|
|
18
|
-
req.headers['x-request-id'] ||
|
|
19
|
-
req.headers['x-vcap-request-id'] ||
|
|
20
|
-
uuid()
|
|
21
|
-
)
|
|
22
|
-
req.res.set('x-correlation-id', id)
|
|
23
|
-
return id
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return cds_context_provider
|
|
27
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module.exports = ()=> {
|
|
2
2
|
|
|
3
|
-
const cds = require ('../../index')
|
|
3
|
+
const cds = require ('../../index'), LOG = cds.log()
|
|
4
4
|
const context_model_required = cds.requires.extensibility || cds.requires.toggles
|
|
5
5
|
if (!context_model_required) return []
|
|
6
6
|
|
|
@@ -9,10 +9,9 @@ module.exports = ()=> {
|
|
|
9
9
|
if (req.baseUrl.startsWith('/-/')) return next() //> our own tech services cannot be extended
|
|
10
10
|
const ctx = cds.context
|
|
11
11
|
if (ctx.tenant || ctx.features?.given) try {
|
|
12
|
-
// if (req.headers.features) ctx.user.features = req.headers.features //> currently done in basic-auth only
|
|
13
12
|
ctx.model = req.__model = await model4 (ctx.tenant, ctx.features) // REVISIT: req.__model is because of Okra
|
|
14
13
|
} catch (e) {
|
|
15
|
-
|
|
14
|
+
LOG.error(e)
|
|
16
15
|
return res.status(503) .json ({ // REVISIT: we should throw a simple error, nothing else! -> this is overly OData-specific!
|
|
17
16
|
error: { code: '503', message:
|
|
18
17
|
process.env.NODE_ENV === 'production' ? 'Service Unavailable' :
|
|
@@ -1,9 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
const production = process.env.NODE_ENV === 'production'
|
|
2
|
+
const cds = require ('../..'), LOG = cds.log('error')
|
|
3
|
+
|
|
4
|
+
module.exports = () => {
|
|
5
|
+
return function http_error (error, req, res, _next) { // eslint-disable-line no-unused-vars
|
|
6
|
+
|
|
7
|
+
// In case of 401 require login if available by auth strategy
|
|
8
|
+
if (typeof error === 'number') error = { code: error }
|
|
9
|
+
if (error.code == 401 && req._login) return req._login()
|
|
10
|
+
|
|
11
|
+
// Prepare and log the error object
|
|
12
|
+
const status = error.statusCode || error.status || Number(error.code) || 500
|
|
13
|
+
delete error.statusCode
|
|
14
|
+
delete error.status
|
|
15
|
+
if (!production && error.stack) error.stack = error.stack.replace(/\n {4}at .*(?:node_modules\/express|node:internal).*/g,'')
|
|
16
|
+
|
|
17
|
+
if (400 <= status && status < 500) {
|
|
18
|
+
LOG.warn (status, '>', error)
|
|
19
|
+
} else {
|
|
20
|
+
LOG.error (status, '>', error)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Expose as little information as possible in production, and as much as possible in development
|
|
24
|
+
if (production) {
|
|
25
|
+
Object.defineProperties (error, {
|
|
26
|
+
message: { enumerable: true },
|
|
27
|
+
user: { enumerable: false },
|
|
28
|
+
})
|
|
29
|
+
} else {
|
|
30
|
+
Object.defineProperties (error, {
|
|
31
|
+
message: { enumerable: true },
|
|
32
|
+
stack: { enumerable: true },
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Send the error response
|
|
37
|
+
return res.status(status).json({error})
|
|
38
|
+
|
|
39
|
+
// Note: express returns errors as XML, we prefer JSON
|
|
40
|
+
// _next (error)
|
|
41
|
+
}
|
|
9
42
|
}
|
|
@@ -8,14 +8,14 @@ const trace = exports.trace = require('./trace')
|
|
|
8
8
|
exports.before = [
|
|
9
9
|
context, // provides cds.context
|
|
10
10
|
trace, // provides detailed trace logs when DEBUG=trace
|
|
11
|
-
auth, // provides
|
|
11
|
+
auth, // provides cds.context.user & .tenant
|
|
12
12
|
ctx_model, // fills in cds.context.model, in case of extensibility
|
|
13
13
|
].map(mw => _instantiate(mw))
|
|
14
14
|
|
|
15
15
|
// middlewares running after protocol adapters -> usually error middlewares
|
|
16
16
|
exports.after = [
|
|
17
|
-
errors
|
|
18
|
-
]
|
|
17
|
+
errors, // provides final error handling
|
|
18
|
+
].map(mw => _instantiate(mw))
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Convenience method to add custom middlewares like so:
|
|
@@ -65,7 +65,6 @@ let sqlite
|
|
|
65
65
|
function _instrument_sqlite (_get_perf) {
|
|
66
66
|
const me = _instrument_sqlite; if (me.done) return; else me.done = true
|
|
67
67
|
try { require.resolve('sqlite3') } catch { return }
|
|
68
|
-
// eslint-disable-next-line cds/no-missing-dependencies
|
|
69
68
|
sqlite = require('sqlite3').Database.prototype
|
|
70
69
|
for (let each of ['all', 'get', 'run', 'prepare']) _wrap(each,sqlite)
|
|
71
70
|
function _wrap (op,sqlite) {
|
|
@@ -93,7 +92,6 @@ function _instrument_sqlite (_get_perf) {
|
|
|
93
92
|
function _instrument_better_sqlite (_get_perf) {
|
|
94
93
|
const me = _instrument_better_sqlite; if (me.done) return; else me.done = true
|
|
95
94
|
try { require.resolve('better-sqlite3') } catch { return }
|
|
96
|
-
// eslint-disable-next-line cds/no-missing-dependencies
|
|
97
95
|
const sqlite = require('better-sqlite3').prototype
|
|
98
96
|
for (let each of ['exec', 'prepare']) _wrap(each,sqlite)
|
|
99
97
|
function _wrap (op,sqlite) {
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
const express = require('express')
|
|
1
|
+
const express = require('express')
|
|
2
2
|
const cds = require('../../index')
|
|
3
|
+
const LOG = cds.log('hcql')
|
|
3
4
|
const { inspect } = require('util')
|
|
4
5
|
|
|
5
6
|
class HCQLAdapter extends require('./http') {
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
router4 (srv) { return super.router4 (srv)
|
|
8
|
+
get router() {
|
|
9
|
+
const srv = this.service
|
|
10
|
+
return super.router
|
|
12
11
|
|
|
13
|
-
/**
|
|
14
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Return CSN schema in response to /<srv>/$csn requests
|
|
14
|
+
*/
|
|
15
|
+
.get('/\\$csn', (_, res) => res.json(this.schema))
|
|
15
16
|
|
|
16
17
|
.use(express.json()) //> for application/json -> cqn
|
|
17
18
|
.use(express.text()) //> for text/plain -> cql -> cqn
|
|
@@ -35,13 +36,17 @@ class HCQLAdapter extends require('./http') {
|
|
|
35
36
|
*/
|
|
36
37
|
.use((req, res, next) => {
|
|
37
38
|
let q = this.query4(req)
|
|
38
|
-
|
|
39
|
+
LOG._info && LOG.info(req.method, decodeURIComponent(req.originalUrl), inspect(q, { colors: true, depth: 11 }))
|
|
39
40
|
return srv.run(q).then(r => res.json(r)).catch(next)
|
|
40
41
|
})
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
get schema() {
|
|
45
|
+
return cds.minify (cds.model, { service: this.service.name })
|
|
46
|
+
}
|
|
47
|
+
|
|
43
48
|
query4 (req) {
|
|
44
|
-
if (typeof req.body === 'string') return cds.parse.cql
|
|
49
|
+
if (typeof req.body === 'string') return cds.parse.cql(req.body)
|
|
45
50
|
return req.body //> a plain CQN object
|
|
46
51
|
}
|
|
47
52
|
}
|
|
@@ -1,60 +1,55 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
1
|
+
const cds = require('../../index'), { decodeURI } = cds.utils
|
|
2
|
+
const express = require('express')
|
|
3
|
+
const production = process.env.NODE_ENV === 'production'
|
|
4
|
+
const restrict_all = cds.env.requires.auth?.restrict_all_services !== false
|
|
5
|
+
const restricted_by_default = production && restrict_all ? ['authenticated-user'] : false
|
|
3
6
|
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
class HttpAdapter {
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.
|
|
10
|
-
|
|
10
|
+
/** Constructs and returns a new express.Router */
|
|
11
|
+
constructor (srv,o={}) {
|
|
12
|
+
this.kind = o.kind || this.constructor.name.replace(/Adapter$/,'').toLowerCase()
|
|
13
|
+
this.service = srv
|
|
14
|
+
this.options = o
|
|
15
|
+
return this.router //> constructed by getter
|
|
11
16
|
}
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}.bind(this))
|
|
20
|
-
.use(this.early_access_check4(srv))
|
|
18
|
+
/** The actual Router factory. Subclasses override this to add specific handlers. */
|
|
19
|
+
get router() {
|
|
20
|
+
let router = super.router = (new express.Router) .use (this.http_log.bind(this))
|
|
21
|
+
let assert_roles = this.requires_check()
|
|
22
|
+
if (assert_roles) router.use (assert_roles)
|
|
23
|
+
return router
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const roles = d['@requires'] || d['@restrict']?.map(r => r.to).flat()
|
|
29
|
-
|| cds.env.requires.auth?.restrict_all_services !== false && process.env.NODE_ENV === 'production' && ['authenticated-user']
|
|
30
|
-
|
|
31
|
-
// ... and return a handler function accordingly -> PROBLEM: Extensibility
|
|
32
|
-
if (!roles) return (req, res, next) => next() //> no handlers required
|
|
33
|
-
|
|
34
|
-
const required_roles = Array.isArray(roles) ? roles : [roles]
|
|
35
|
-
return function early_access_check (req, res, next) {
|
|
36
|
-
let u = req.user; if (!u?.is) u = new cds.User(u) // revisit
|
|
37
|
-
if (required_roles.some(r => u.is(r))) return next()
|
|
38
|
-
// Following demonstrates how to directly send responses from here...
|
|
39
|
-
// However, in order to allow others to plug in error handlers throwing errors is better.
|
|
40
|
-
// For example, also for ourselves to obfucscate error details in production mode.
|
|
41
|
-
// throw cds.error ({ status: 403, code: 'REQUIRES_AUTH_USER', details: `Requires any of [ ${roles} ]` })
|
|
42
|
-
if (!u._is_anonymous) return res.status(403).send(`User '${u.id}' is lacking required roles: [ ${roles} ]`)
|
|
43
|
-
else if (!req._login) return res.status(401).send('Requires authenticated user')
|
|
44
|
-
else return req._login()
|
|
45
|
-
}
|
|
26
|
+
/** Handler to log all incoming requests */
|
|
27
|
+
http_log (r,_,next) {
|
|
28
|
+
this.logger = cds.log(this.kind)
|
|
29
|
+
this.log(r)
|
|
30
|
+
next()
|
|
46
31
|
}
|
|
47
|
-
}
|
|
48
32
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
33
|
+
/** Subclasses may override this method to log incoming requests. */
|
|
34
|
+
log (req, LOG = this.logger) { LOG._info && LOG.info (
|
|
35
|
+
req.method,
|
|
36
|
+
decodeURI (req.baseUrl + req.path),
|
|
37
|
+
Object.keys (req.query).length ? { ...req.query } : ''
|
|
38
|
+
)}
|
|
39
|
+
|
|
40
|
+
/** Returns a handler to check required roles, or null if no check required. */
|
|
41
|
+
requires_check() {
|
|
42
|
+
const d = this.service.definition
|
|
43
|
+
const roles = d['@requires'] || d['@restrict']?.map(r => r.to).flat().filter(r => r)
|
|
44
|
+
const required = !roles?.length ? restricted_by_default : Array.isArray(roles) ? roles : [roles]
|
|
45
|
+
if (required) return function requires_check (req, res, next) {
|
|
46
|
+
const user = cds.context.user
|
|
47
|
+
if (required.some(role => user.has(role))) return next()
|
|
48
|
+
else if (user._is_anonymous) return next(401) // request login
|
|
49
|
+
else throw Object.assign(new Error, { code: 403, reason: `User '${user.id}' is lacking required roles: [${required}]`, user, required })
|
|
50
|
+
}
|
|
55
51
|
}
|
|
56
|
-
return express.Router().use((req,res,next) => {
|
|
57
|
-
return this.routers[req.tenant].handle(req,res,next)
|
|
58
|
-
})
|
|
59
52
|
}
|
|
60
|
-
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
module.exports = HttpAdapter
|
|
@@ -80,20 +80,6 @@ class Protocols {
|
|
|
80
80
|
// to lots of "UriSemanticError: 'webapp' is not an entity set, ..." errors, if the
|
|
81
81
|
// service path and static app root path are the same, e.g. /browse in bookshop.
|
|
82
82
|
if (!path.match(/^\/.+\/.+/)) app.use (`${path}/webapp/`, (_,res) => res.sendStatus(404))
|
|
83
|
-
|
|
84
|
-
// Add a reject-all handler for access to /old/$metadata if new scheme is used
|
|
85
|
-
if (!cds.env.features.serve_on_root && path.startsWith(this[kind].path)) {
|
|
86
|
-
let LOG = cds.log(kind), msg = `PLEASE NOTE:\n
|
|
87
|
-
With @sap/cds version 7, default service paths have changed to '${this[kind].path}/<srv>'.
|
|
88
|
-
If you use SAP Fiori Elements, make sure to adapt the 'dataSources.uri' paths
|
|
89
|
-
in 'manifest.json' files accordingly. For more information see release notes at
|
|
90
|
-
https://cap.cloud.sap/docs/releases/jun23#changed-default-service-path.
|
|
91
|
-
`.replace(/ {9}/g,'')
|
|
92
|
-
app.use(`${path.slice(this[kind].path.length)}/\\$metadata`, (_,res) => {
|
|
93
|
-
res.status(404).send(`<pre>${msg}</pre>`)
|
|
94
|
-
LOG?.warn(msg); LOG = undefined
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
83
|
}
|
|
98
84
|
|
|
99
85
|
// mount adapter to express app
|
|
@@ -129,21 +115,14 @@ class Protocols {
|
|
|
129
115
|
if (!annos.length) annos.push ({ kind: this.default })
|
|
130
116
|
|
|
131
117
|
// canonicalize to { kind, path } objects
|
|
132
|
-
const no_mws = cds.requires.middlewares === false
|
|
133
118
|
const endpoints = annos.map (each => {
|
|
134
119
|
let { kind = each['='] || each, path } = each
|
|
135
120
|
let { path: prefix } = this[kind] || cds.error `Unknown protocol: ${kind}`
|
|
136
121
|
if (typeof path !== 'string') path = o?.at || o?.path || def['@path'] || _slugified(srv.name)
|
|
137
|
-
if (path[0] !== '/') path =
|
|
122
|
+
if (path[0] !== '/') path = prefix+'/'+path
|
|
138
123
|
return { kind, path }
|
|
139
124
|
})
|
|
140
125
|
|
|
141
|
-
// add serve-on-root endpoint if enabled
|
|
142
|
-
if (!no_mws && endpoints.length === 1 && cds.env.features.serve_on_root) {
|
|
143
|
-
let [{ kind, path }] = endpoints, prefix = this[kind].path
|
|
144
|
-
if (prefix && path.startsWith(prefix)) endpoints.unshift ({ kind, path: path.slice(prefix.length) })
|
|
145
|
-
}
|
|
146
|
-
|
|
147
126
|
return endpoints.length && endpoints
|
|
148
127
|
}
|
|
149
128
|
|
|
@@ -204,4 +183,3 @@ const _slugified = name => (
|
|
|
204
183
|
|
|
205
184
|
|
|
206
185
|
module.exports = new Protocols
|
|
207
|
-
if (!cds.requires.middlewares) require('./_legacy')
|
|
@@ -1,93 +1,31 @@
|
|
|
1
|
-
const cds = require('../../index'),
|
|
2
|
-
{ User } = cds,
|
|
3
|
-
{ decodeURI } = cds.utils
|
|
4
|
-
const express = require('express') // eslint-disable-line cds/no-missing-dependencies
|
|
1
|
+
const cds = require('../../index'), { decodeURI } = cds.utils
|
|
5
2
|
|
|
6
3
|
if (cds.env.features.odata_new_adapter) {
|
|
7
4
|
cds.log().info('using new OData adapter')
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
const BaseProtocolAdapter = require('./http')
|
|
11
|
-
|
|
12
|
-
module.exports = class ODataAdapter extends BaseProtocolAdapter {
|
|
13
|
-
log(req) {
|
|
14
|
-
let u = req.user
|
|
15
|
-
req.user = u instanceof User ? u : new User(u)
|
|
16
|
-
|
|
17
|
-
// REVISIT: how to handle logging of batch subrequests? (note: service is missing from path)
|
|
18
|
-
let url = decodeURI(req.originalUrl)
|
|
19
|
-
this.logger.info(req.method, url, req.body || '')
|
|
20
|
-
if (/\$batch/.test(req.url))
|
|
21
|
-
req.on('dispatch', req => {
|
|
22
|
-
let path = decodeURI(req._path)
|
|
23
|
-
this.logger.info('>', req.event, path, req._query || '')
|
|
24
|
-
if (this.logger._debug && req.query) this.logger.debug(req.query)
|
|
25
|
-
})
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
router4(srv) {
|
|
29
|
-
const router = super.router4(srv)
|
|
30
|
-
const jsonBodyParser = express.json()
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
router
|
|
34
|
-
// REVISIT: add middleware for negative cases?
|
|
35
|
-
// service root
|
|
36
|
-
.use(/^\/$/, require('../../../libx/odata/middleware/service-document')(srv))
|
|
37
|
-
.use('/\\$metadata', require('../../../libx/odata/middleware/metadata')(srv))
|
|
38
|
-
// parse
|
|
39
|
-
.use(require('../../../libx/odata/middleware/parse')(srv))
|
|
40
|
-
// REVISIT do we want to build our own body parser logic?
|
|
41
|
-
.use((req, res, next) => {
|
|
42
|
-
// REVISIT: body of batch subrequests are already deserialized
|
|
43
|
-
if (typeof req.body === 'object') return next()
|
|
44
|
-
if (req.method === 'PUT' && isStream(req._query)) {
|
|
45
|
-
req.body = { value: req }
|
|
46
|
-
return next()
|
|
47
|
-
}
|
|
48
|
-
// TODO: check if the raw body still exists, then we can remove deepCopy() in the handlers
|
|
49
|
-
return jsonBodyParser(req, res, next)
|
|
50
|
-
})
|
|
51
|
-
// batch
|
|
52
|
-
.post('/\\$batch', require('../../../libx/odata/middleware/batch')(srv, router))
|
|
53
|
-
// handle
|
|
54
|
-
// REVISIT: with old adapter, we return 405 for HEAD requests -> check OData spec
|
|
55
|
-
.head('*', (_, res) => res.sendStatus(405))
|
|
56
|
-
.post('*', require('../../../libx/odata/middleware/operation')(srv)) //> action
|
|
57
|
-
.get('*', require('../../../libx/odata/middleware/operation')(srv)) //> function
|
|
58
|
-
.post('*', require('../../../libx/odata/middleware/create')(srv))
|
|
59
|
-
.get('*', stream(srv))
|
|
60
|
-
.get('*', require('../../../libx/odata/middleware/read')(srv))
|
|
61
|
-
.put('*', require('../../../libx/odata/middleware/update')(srv, router))
|
|
62
|
-
.patch('*', require('../../../libx/odata/middleware/update')(srv, router))
|
|
63
|
-
.delete('*', require('../../../libx/odata/middleware/delete')(srv))
|
|
64
|
-
// error
|
|
65
|
-
.use(require('../../../libx/odata/middleware/error')(srv))
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
6
|
+
module.exports = require('../../../libx/odata/ODataAdapter')
|
|
69
7
|
} else {
|
|
70
|
-
|
|
8
|
+
cds.log().info('using legacy OData adapter')
|
|
9
|
+
|
|
10
|
+
const legacy_adapter_factory = require('../../../libx/_runtime/cds-services/adapter/odata-v4/to')
|
|
71
11
|
const LOG = cds.log('odata')
|
|
72
|
-
module.exports = function ODataAdapter(srv) {
|
|
73
|
-
const router = express.Router()
|
|
74
12
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
req.user = u instanceof User ? u : new User(u)
|
|
13
|
+
module.exports = function ODataAdapter(srv) {
|
|
14
|
+
const router = require('express').Router()
|
|
78
15
|
|
|
16
|
+
router.use(function odata_log(req, _, next) {
|
|
79
17
|
let url = decodeURI(req.originalUrl)
|
|
80
18
|
LOG && LOG(req.method, url, req.body || '')
|
|
81
19
|
if (/\$batch/.test(req.url))
|
|
82
20
|
req.on('dispatch', req => {
|
|
83
|
-
let path = decodeURI(req.
|
|
84
|
-
LOG && LOG('>', req.event, path, req.
|
|
85
|
-
if (LOG._debug && req.query) LOG.debug(req.query)
|
|
21
|
+
let path = decodeURI(req._.odataReq?._rawODataPath || '')
|
|
22
|
+
LOG && LOG('>', req.event, path, req._queryOptions || '')
|
|
23
|
+
if (LOG._debug && req.query) LOG.debug(req.query) //> why only for batch subrequests?
|
|
86
24
|
})
|
|
87
25
|
|
|
88
26
|
next()
|
|
89
27
|
})
|
|
90
|
-
router.use(
|
|
28
|
+
router.use(legacy_adapter_factory(srv))
|
|
91
29
|
return router
|
|
92
30
|
}
|
|
93
31
|
}
|
|
@@ -1,13 +1 @@
|
|
|
1
|
-
|
|
2
|
-
const libx = require('../../../libx/_runtime')
|
|
3
|
-
const LOG = cds.log('rest')
|
|
4
|
-
|
|
5
|
-
module.exports = function RestAdapter (srv) { return [
|
|
6
|
-
(req, _, next) => {
|
|
7
|
-
let u = req.user
|
|
8
|
-
req.user = u instanceof User ? u : new User(u)
|
|
9
|
-
LOG (req.method, decodeURIComponent(req.originalUrl), req.body||'')
|
|
10
|
-
next()
|
|
11
|
-
},
|
|
12
|
-
libx.to.rest (srv)
|
|
13
|
-
]}
|
|
1
|
+
module.exports = require('../../../libx/rest/RestAdapter')
|