@sap/cds 7.9.4 → 8.0.4
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 +128 -3659
- 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 +30 -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/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 +54 -27
- 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 +320 -84
- 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 +5 -5
- 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 +26 -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/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/compile/to/json.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = (csn,o={}) => {
|
|
|
15
15
|
// Note: This has moved to cds.compile.for.java meanwhile, but is kept
|
|
16
16
|
// here for compatibility, at least temporarily.
|
|
17
17
|
return {...v, _where: JSON.stringify (cds.parse.xpr(v.where)) }
|
|
18
|
-
} catch
|
|
18
|
+
} catch {/* ignored */}
|
|
19
19
|
|
|
20
20
|
else if (v.kind === "service" && !v['@source'] && v.$location?.file) {
|
|
21
21
|
// Preserve original sources for services so we can use them for finding
|
package/lib/compile/to/sql.js
CHANGED
|
@@ -16,12 +16,15 @@ function cds_compile_to_sql (csn,_o) {
|
|
|
16
16
|
return sql
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
20
19
|
function cds_compile_to_hdbtable (csn,o) {
|
|
21
20
|
const all = cdsc.to.hdi (cds.minify(csn),o)
|
|
22
21
|
return _2many(all)
|
|
23
22
|
}
|
|
24
23
|
|
|
24
|
+
function cds_compile_to_hana(csn, o, beforeCsn) {
|
|
25
|
+
return require('./hana')(cds.minify(csn), o, beforeCsn)
|
|
26
|
+
}
|
|
27
|
+
|
|
25
28
|
function cds_compile_to_deltaSql (csn, o, beforeCsn) {
|
|
26
29
|
const options = cdsc._options.for.sql(o)
|
|
27
30
|
if (typeof beforeCsn === 'string') beforeCsn = JSON.parse(beforeCsn)
|
|
@@ -53,6 +56,7 @@ function* _2many (all,_file=f=>f) {
|
|
|
53
56
|
module.exports = Object.assign (cds_compile_to_sql, {
|
|
54
57
|
hdbcds: cds_compile_to_hdbcds,
|
|
55
58
|
hdbtable: cds_compile_to_hdbtable,
|
|
59
|
+
hana: cds_compile_to_hana,
|
|
56
60
|
delta: cds_compile_to_deltaSql,
|
|
57
61
|
sqlite: { keywords: sqliteKeywords },
|
|
58
62
|
postgres: { keywords: postgresKeywords },
|
package/lib/compile/to/yaml.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// A simple YAML serializer
|
|
2
2
|
module.exports = function _2yaml (object, {limit=111}={}) {
|
|
3
|
-
return $(object,'',1)
|
|
3
|
+
return $(object,'',1)?.toString().replace(/^\n/,'')
|
|
4
4
|
function $(o, indent, count, _visited) {
|
|
5
5
|
if (o == null) return o
|
|
6
6
|
if (o.toJSON) o = o.toJSON()
|
|
@@ -11,7 +11,7 @@ module.exports = function _2yaml (object, {limit=111}={}) {
|
|
|
11
11
|
}
|
|
12
12
|
if (typeof o === 'object') {
|
|
13
13
|
const visited = new Set (_visited)
|
|
14
|
-
if (visited.has(o)) return console.error('circular reference to',o)
|
|
14
|
+
if (visited.has(o)) return console.error('circular reference to',o) // eslint-disable-line no-console
|
|
15
15
|
else visited.add(o)
|
|
16
16
|
let s = ''
|
|
17
17
|
for (let k in o) {
|
|
@@ -31,7 +31,7 @@ module.exports = function _2yaml (object, {limit=111}={}) {
|
|
|
31
31
|
let s = o.trim()
|
|
32
32
|
return !s || /^[\^@#:,=!<>*|]/.test(s) ? '"'+ o.replace(/\\/g,'\\\\') +'"' : s
|
|
33
33
|
}
|
|
34
|
-
if (typeof o === 'function') return
|
|
34
|
+
if (typeof o === 'function') return
|
|
35
35
|
else return o
|
|
36
36
|
}
|
|
37
37
|
}
|
package/lib/dbs/cds-deploy.js
CHANGED
|
@@ -6,10 +6,12 @@ const TRACE = cds.debug('trace')
|
|
|
6
6
|
|
|
7
7
|
/** Fluent API: cds.deploy(model).to(db) */
|
|
8
8
|
const deploy = module.exports = function cds_deploy (model, options, csvs) {
|
|
9
|
+
|
|
9
10
|
return { async to (/** @type {import('../../lib/srv/srv-api')} */ db, o = options||{}) {
|
|
11
|
+
/* eslint-disable no-console */
|
|
10
12
|
|
|
11
13
|
// prepare logging
|
|
12
|
-
const [ GREY, RESET ] =
|
|
14
|
+
const [ GREY, RESET ] = process.stdout.isTTY && !process.env.NO_COLOR || process.env.FORCE_COLOR ? ['\x1b[2m', '\x1b[0m' ] : ['','']
|
|
13
15
|
const LOG = !o.silent && !o.dry && cds.log('deploy')._info ? console.log : undefined
|
|
14
16
|
|
|
15
17
|
// prepare model
|
|
@@ -290,7 +292,7 @@ deploy.resources = async function (csn, opts) {
|
|
|
290
292
|
}
|
|
291
293
|
const e = _entity4(f,csn); if (!e || e['@cds.persistence.skip'] === true) continue
|
|
292
294
|
if (cds.env.features.deploy_data_onconflict === 'replace' && !/[._]texts_/.test(f)) {
|
|
293
|
-
const seenBefore = Object.entries(found).find(([
|
|
295
|
+
const seenBefore = Object.entries(found).find(([,entity]) => entity === e.name )
|
|
294
296
|
if (seenBefore) {
|
|
295
297
|
DEBUG?.(`Conflict for '${e.name}': replacing '${local(seenBefore[0])}' with '${local(path.join(subdir,fx))}'`)
|
|
296
298
|
continue
|
package/lib/env/cds-env.js
CHANGED
|
@@ -91,13 +91,6 @@ class Config {
|
|
|
91
91
|
if (this.features && this.features.emulate_vcap_services) {
|
|
92
92
|
this._emulate_vcap_services()
|
|
93
93
|
}
|
|
94
|
-
|
|
95
|
-
// new odata adapter shall include new parser, cds.assert(), and decimals as strings
|
|
96
|
-
if (this.features?.odata_new_adapter) {
|
|
97
|
-
this.features.odata_new_parser = true
|
|
98
|
-
this.features.cds_assert = true
|
|
99
|
-
this.features.string_decimals = true
|
|
100
|
-
}
|
|
101
94
|
}
|
|
102
95
|
|
|
103
96
|
/**
|
|
@@ -227,7 +220,7 @@ class Config {
|
|
|
227
220
|
if (val) try {
|
|
228
221
|
// CDS_CONFIG={ /* json */}
|
|
229
222
|
config = JSON.parse (val)
|
|
230
|
-
} catch
|
|
223
|
+
} catch {
|
|
231
224
|
// CDS_CONFIG=/path/to/config.json *OR* CDS_CONFIG=/path/to/config/dir
|
|
232
225
|
if (typeof val === "string") {
|
|
233
226
|
// Load from JSON file or directory; No profile support!
|
|
@@ -391,13 +384,16 @@ class Config {
|
|
|
391
384
|
_fetch ({ type: conf.dialect || conf.kind })
|
|
392
385
|
|
|
393
386
|
function _fetch (predicate) {
|
|
387
|
+
const filters = []
|
|
394
388
|
for (let k in predicate) {
|
|
395
389
|
const v = predicate[k]; if (!v) continue
|
|
396
390
|
const filter = k === 'tag' ? e => _array(e,'tags').includes(v) : e => e[k] === v
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
391
|
+
filters.push(filter)
|
|
392
|
+
}
|
|
393
|
+
if (filters.length === 0) return false
|
|
394
|
+
for (let stype in vcaps) {
|
|
395
|
+
const found = _array(vcaps,stype).find(e => filters.every(f => f(e)))
|
|
396
|
+
if (found) return found
|
|
401
397
|
}
|
|
402
398
|
}
|
|
403
399
|
|
|
@@ -491,8 +487,8 @@ function _merge (dst, src, _profiles) {
|
|
|
491
487
|
}
|
|
492
488
|
|
|
493
489
|
function _value4 (val) {
|
|
494
|
-
if (val && val[0] === '{') try { return JSON.parse(val) } catch
|
|
495
|
-
if (val && val[0] === '[') try { return JSON.parse(val) } catch
|
|
490
|
+
if (val && val[0] === '{') try { return JSON.parse(val) } catch {/* ignored */}
|
|
491
|
+
if (val && val[0] === '[') try { return JSON.parse(val) } catch {/* ignored */}
|
|
496
492
|
if (val === 'true') return true
|
|
497
493
|
if (val === 'false') return false
|
|
498
494
|
if (!isNaN(val)) return parseFloat(val)
|
package/lib/env/cds-requires.js
CHANGED
|
@@ -2,7 +2,7 @@ const _runtime = '@sap/cds/libx/_runtime'
|
|
|
2
2
|
|
|
3
3
|
exports = module.exports = {
|
|
4
4
|
|
|
5
|
-
middlewares: true,
|
|
5
|
+
middlewares: true, // REVISIT: odata-v2-adapter uses this
|
|
6
6
|
db: undefined, "[schevo]": { db: { schema_evolution: 'auto' }, },
|
|
7
7
|
messaging: undefined,
|
|
8
8
|
multitenancy: undefined,
|
|
@@ -23,8 +23,7 @@ exports = module.exports = {
|
|
|
23
23
|
const dict = Object.create (this)
|
|
24
24
|
for (let [name,e] of Object.entries (this)) if (e.service) {
|
|
25
25
|
if (e.service in dict && !e.override && e.service !== name) {
|
|
26
|
-
|
|
27
|
-
throw new Error (`Datasource name '${e.service}' conflicts with service definition`)
|
|
26
|
+
throw new Error (`Datasource name '${e.service}' conflicts with service definition, referred to in 'cds.requires.${name}'`)
|
|
28
27
|
}
|
|
29
28
|
else dict[e.service] = { ...e, name }
|
|
30
29
|
}
|
|
@@ -33,8 +32,8 @@ exports = module.exports = {
|
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
|
|
36
|
-
const admin = [ '
|
|
37
|
-
const builder = [ 'cds.ExtensionDeveloper'
|
|
35
|
+
const admin = [ 'admin' ]
|
|
36
|
+
const builder = [ 'cds.ExtensionDeveloper' ]
|
|
38
37
|
const _authentication_strategies = {
|
|
39
38
|
|
|
40
39
|
"basic-auth": {
|
|
@@ -81,6 +80,7 @@ const _authentication_strategies = {
|
|
|
81
80
|
|
|
82
81
|
for (let each of Object.values(_authentication_strategies)) {
|
|
83
82
|
Object.defineProperty (each, 'strategy', {get() {
|
|
83
|
+
// eslint-disable-next-line no-console
|
|
84
84
|
if (process.env.NODE_ENV !== 'production') console.trace('WARNING: auth.strategy is deprecated, use auth.kind instead')
|
|
85
85
|
return { jwt: 'JWT', mocked: 'mock' }[this.kind] || this.kind
|
|
86
86
|
}})
|
|
@@ -116,6 +116,17 @@ const _services = {
|
|
|
116
116
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
const better_sqlite = '@cap-js/sqlite'
|
|
120
|
+
const better_hana = '@cap-js/hana'
|
|
121
|
+
|
|
122
|
+
const legacy_sqlite = `${_runtime}/sqlite/Service.js`
|
|
123
|
+
const legacy_hana = `${_runtime}/hana/Service.js`
|
|
124
|
+
|
|
125
|
+
const _resolve = (preferred, fallback) => {
|
|
126
|
+
try { return require.resolve(preferred) && preferred }
|
|
127
|
+
catch { return fallback }
|
|
128
|
+
}
|
|
129
|
+
|
|
119
130
|
|
|
120
131
|
const _databases = {
|
|
121
132
|
|
|
@@ -125,9 +136,9 @@ const _databases = {
|
|
|
125
136
|
},
|
|
126
137
|
|
|
127
138
|
"sqlite": {
|
|
128
|
-
'[legacy-sqlite]': { impl:
|
|
129
|
-
'[better-sqlite]': { impl:
|
|
130
|
-
impl:
|
|
139
|
+
'[legacy-sqlite!]': { impl: legacy_sqlite },
|
|
140
|
+
'[better-sqlite!]': { impl: better_sqlite },
|
|
141
|
+
impl: _resolve (better_sqlite, legacy_sqlite),
|
|
131
142
|
credentials: { url: 'db.sqlite' },
|
|
132
143
|
},
|
|
133
144
|
"better-sqlite": {
|
|
@@ -136,21 +147,21 @@ const _databases = {
|
|
|
136
147
|
kind: 'sqlite'
|
|
137
148
|
},
|
|
138
149
|
"legacy-sqlite": {
|
|
139
|
-
impl:
|
|
150
|
+
impl: legacy_sqlite,
|
|
140
151
|
credentials: { url: 'db.sqlite' },
|
|
141
152
|
kind: 'sqlite'
|
|
142
153
|
},
|
|
143
154
|
|
|
144
155
|
"hana": {
|
|
145
|
-
'[legacy-hana]': { impl:
|
|
146
|
-
'[better-hana]': { impl:
|
|
147
|
-
impl:
|
|
156
|
+
'[legacy-hana]': { impl: legacy_hana },
|
|
157
|
+
'[better-hana]': { impl: better_hana },
|
|
158
|
+
impl: _resolve (better_hana, legacy_hana),
|
|
148
159
|
},
|
|
149
160
|
"hana-cloud": {
|
|
150
161
|
kind: 'hana', "deploy-format": "hdbtable",
|
|
151
162
|
},
|
|
152
163
|
"legacy-hana": {
|
|
153
|
-
impl:
|
|
164
|
+
impl: legacy_hana,
|
|
154
165
|
kind: 'hana'
|
|
155
166
|
},
|
|
156
167
|
|
|
@@ -222,6 +233,7 @@ const _messaging = {
|
|
|
222
233
|
},
|
|
223
234
|
"event-broker": {
|
|
224
235
|
impl: `${_runtime}/messaging/event-broker.js`,
|
|
236
|
+
format: 'cloudevents',
|
|
225
237
|
vcap: {
|
|
226
238
|
label: "eventmesh-sap2sap-internal"
|
|
227
239
|
}
|
|
@@ -268,6 +280,11 @@ const _platform_services = {
|
|
|
268
280
|
label: 'destination'
|
|
269
281
|
}
|
|
270
282
|
},
|
|
283
|
+
connectivity: {
|
|
284
|
+
vcap: {
|
|
285
|
+
label: 'connectivity'
|
|
286
|
+
}
|
|
287
|
+
},
|
|
271
288
|
|
|
272
289
|
approuter: undefined,
|
|
273
290
|
|
package/lib/env/defaults.js
CHANGED
|
@@ -2,12 +2,46 @@ const production = process.env.NODE_ENV === 'production'
|
|
|
2
2
|
|
|
3
3
|
const defaults = module.exports = {
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* For our own tests to replace hard-coded checks for CDS_ENV === 'better-sqlite'
|
|
7
|
+
* which don't work anymore with cds8 where that is the default.
|
|
8
|
+
*/
|
|
9
|
+
get _better_sqlite() {
|
|
10
|
+
if (process.env.CDS_ENV === 'better-sqlite') return true
|
|
11
|
+
let conf = this.requires.db || this.requires.kinds.sql
|
|
12
|
+
if (conf?.impl === '@cap-js/sqlite') return true
|
|
13
|
+
else return false
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
"[attic!]": {
|
|
17
|
+
features: {
|
|
18
|
+
pre_compile_edmxs: false,
|
|
19
|
+
odata_new_adapter: false,
|
|
20
|
+
odata_new_parser: false,
|
|
21
|
+
},
|
|
22
|
+
requires: {
|
|
23
|
+
kinds: {
|
|
24
|
+
sqlite: { impl: '@sap/cds/libx/_runtime/sqlite/Service.js' },
|
|
25
|
+
hana: { impl: '@sap/cds/libx/_runtime/hana/Service.js' },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
"[noa]": {
|
|
31
|
+
features: {
|
|
32
|
+
odata_new_adapter: true,
|
|
33
|
+
odata_new_parser: true,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
|
|
5
37
|
production,
|
|
6
38
|
|
|
7
39
|
requires: require('./cds-requires'),
|
|
8
40
|
|
|
9
41
|
server: {
|
|
10
42
|
force_exit_timeout: 1111,
|
|
43
|
+
cors: !production, // CORS middleware is off in production
|
|
44
|
+
index: !production, // index page is off in production
|
|
11
45
|
port: 4004,
|
|
12
46
|
},
|
|
13
47
|
|
|
@@ -20,8 +54,11 @@ const defaults = module.exports = {
|
|
|
20
54
|
|
|
21
55
|
features: {
|
|
22
56
|
folders: 'fts/*', // where to find feature toggles -> switch on by default when released
|
|
57
|
+
sql_simple_queries: 0,
|
|
23
58
|
pre_compile_edmxs: false,
|
|
24
|
-
odata_new_adapter:
|
|
59
|
+
odata_new_adapter: true,
|
|
60
|
+
odata_new_parser: true,
|
|
61
|
+
get cds_validate() { return this.odata_new_adapter },
|
|
25
62
|
live_reload: !production,
|
|
26
63
|
in_memory_db: !production,
|
|
27
64
|
test_data: !production,
|
|
@@ -31,31 +68,26 @@ const defaults = module.exports = {
|
|
|
31
68
|
// skip_unused: 'all',
|
|
32
69
|
skip_unused: true,
|
|
33
70
|
deploy_data_onconflict: 'insert',
|
|
34
|
-
one_model: true,
|
|
35
71
|
localized: true,
|
|
36
72
|
assert_integrity: false,
|
|
37
|
-
cds_tx_inheritance: true,
|
|
38
|
-
serve_on_root: false,
|
|
39
73
|
precise_timestamps: false,
|
|
40
|
-
|
|
74
|
+
ieee754compatible: undefined,
|
|
75
|
+
// compat for db
|
|
76
|
+
get string_decimals() { return this.ieee754compatible }
|
|
41
77
|
},
|
|
42
78
|
|
|
43
79
|
fiori: {
|
|
44
80
|
preview: !production,
|
|
45
81
|
routes: !production,
|
|
46
82
|
lean_draft: true,
|
|
47
|
-
wrap_multiple_errors: true,
|
|
83
|
+
wrap_multiple_errors: true,
|
|
48
84
|
draft_lock_timeout: true,
|
|
49
|
-
draft_deletion_timeout:
|
|
85
|
+
draft_deletion_timeout: true,
|
|
50
86
|
draft_compat: undefined,
|
|
51
|
-
'[better-sqlite]': { lean_draft: true },
|
|
52
|
-
'[better-hana]': { lean_draft: true },
|
|
53
|
-
'[lean-draft]': { lean_draft: true },
|
|
54
87
|
'[draft-compat]': { draft_compat: true },
|
|
55
88
|
},
|
|
56
89
|
|
|
57
90
|
ql: {
|
|
58
|
-
quirks_mode: true, // IMPORTANT: Remove that for cds^7 !!
|
|
59
91
|
},
|
|
60
92
|
|
|
61
93
|
log: {
|
|
@@ -152,13 +184,11 @@ const defaults = module.exports = {
|
|
|
152
184
|
* - `false` → always skipped.
|
|
153
185
|
* - `true` → never skipped.
|
|
154
186
|
*/
|
|
155
|
-
transitive_localized_views:
|
|
156
|
-
|
|
157
|
-
transitive_localized_views: false
|
|
158
|
-
},
|
|
159
|
-
native_hana_associations: true,
|
|
187
|
+
transitive_localized_views: undefined,
|
|
188
|
+
native_hana_associations: undefined,
|
|
160
189
|
names: 'plain', // or 'quoted', or 'hdbcds'
|
|
161
190
|
dialect: 'sqlite' // or 'plain' or 'hana'
|
|
191
|
+
// dialect: undefined, // or 'sqlite', 'hana', 'postgres', 'h2', ...
|
|
162
192
|
},
|
|
163
193
|
|
|
164
194
|
hana: {
|
package/lib/env/plugins.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// REVISIT: we should have a real modular plugin technique for cds.env
|
|
2
2
|
module.exports = function add_mtx_env (env) {
|
|
3
3
|
|
|
4
|
-
const mtx_env = require('@sap/cds-mtxs/env')
|
|
4
|
+
const mtx_env = require('@sap/cds-mtxs/env')
|
|
5
5
|
if (mtx_env) {
|
|
6
6
|
const {requires} = env, {kinds} = requires
|
|
7
7
|
Object.assign (env, mtx_env, {requires})
|
|
@@ -261,10 +261,6 @@ module.exports = {
|
|
|
261
261
|
}
|
|
262
262
|
]
|
|
263
263
|
},
|
|
264
|
-
middlewares: {
|
|
265
|
-
type: 'boolean',
|
|
266
|
-
description: 'Enables new middlewares support (experimental).'
|
|
267
|
-
},
|
|
268
264
|
multitenancy: {
|
|
269
265
|
oneOf: [
|
|
270
266
|
{
|
|
@@ -760,6 +756,14 @@ module.exports = {
|
|
|
760
756
|
description: 'Number of fields to be added at most.',
|
|
761
757
|
minimum: 1
|
|
762
758
|
},
|
|
759
|
+
'fields': {
|
|
760
|
+
type: 'array',
|
|
761
|
+
description: 'Fields that are allowed to be extended.',
|
|
762
|
+
uniqueItems: true,
|
|
763
|
+
items: {
|
|
764
|
+
type: 'string'
|
|
765
|
+
}
|
|
766
|
+
},
|
|
763
767
|
'new-entities': {
|
|
764
768
|
type: 'integer',
|
|
765
769
|
description: 'Number of entities to be added at most',
|
package/lib/env/schemas/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
const { join } = require('path')
|
|
2
2
|
|
|
3
3
|
module.exports = new class {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
4
|
+
async default4(name) {
|
|
5
|
+
const file = join(__dirname, name.replace(/\.\w+$/, ''))
|
|
6
|
+
try {
|
|
7
|
+
return structuredClone(require(file))
|
|
8
|
+
} catch {
|
|
9
|
+
throw new Error(`ENOENT: Could not load schema '${name}' from ${file}`)
|
|
11
10
|
}
|
|
11
|
+
}
|
|
12
12
|
}
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
if (process.env.CDS_STRICT_NODE_VERSION !== 'false') require ('./utils/check-version')
|
|
2
2
|
!(global.__cds_loaded_from ??= new Set).add(__filename) // track from where we loaded cds
|
|
3
3
|
|
|
4
|
-
/** @typedef { import('../apis/linked.js').LinkedCSN } Linked */
|
|
5
4
|
/** @typedef { import('./srv/srv-api') } Service */
|
|
6
5
|
|
|
7
6
|
const { EventEmitter } = require('node:events')
|
|
@@ -45,6 +44,7 @@ const cds = module.exports = global.cds = new class cds extends EventEmitter {
|
|
|
45
44
|
get linked() { return super.linked = require('./linked/models') }
|
|
46
45
|
get infer() { return super.infer = require('./ql/infer') }
|
|
47
46
|
get builtin() { return super.builtin = require('./linked/types') }
|
|
47
|
+
get validate() { return super.validate = require('./linked/validate') }
|
|
48
48
|
get Association() { return super.Association = this.builtin.classes.Association }
|
|
49
49
|
get Composition() { return super.Composition = this.builtin.classes.Composition }
|
|
50
50
|
get entity() { return super.entity = this.builtin.classes.entity }
|
|
@@ -84,16 +84,16 @@ const cds = module.exports = global.cds = new class cds extends EventEmitter {
|
|
|
84
84
|
get DatabaseService() { return super.DatabaseService = require('../libx/_runtime/db/Service.js') }
|
|
85
85
|
get RemoteService() { return super.RemoteService = require('../libx/_runtime/remote/Service.js') }
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
get
|
|
89
|
-
|
|
90
|
-
set context(_) { this._context._for(this,_) }
|
|
87
|
+
/** Contexts and Transactions @type {import('./req/context.js')} */
|
|
88
|
+
get context() { return this._context.getStore() }
|
|
89
|
+
set context(x) { this._context.enterWith(x) }
|
|
91
90
|
get spawn() { return super.spawn = this._context.spawn }
|
|
91
|
+
get _context() { return super._context = require('./req/cds-context') }
|
|
92
92
|
|
|
93
93
|
// Helpers
|
|
94
94
|
get utils() { return super.utils = require('./utils/cds-utils') }
|
|
95
95
|
get error() { return super.error = require('./log/cds-error') }
|
|
96
|
-
get exec() { return super.exec = require('../bin/
|
|
96
|
+
get exec() { return super.exec = require('../bin/serve').exec }
|
|
97
97
|
get test() { return super.test = require('./utils/cds-test') }
|
|
98
98
|
get log() { return super.log = require('./log/cds-log') }
|
|
99
99
|
get debug() { return super.debug = this.log.debug }
|
|
@@ -108,7 +108,6 @@ const cds = module.exports = global.cds = new class cds extends EventEmitter {
|
|
|
108
108
|
tx (..._) { return (this.db || this.txs).tx(..._) }
|
|
109
109
|
run (..._) { return (this.db || typeof _[0] === 'function' && this.txs || this.error._no_primary_db).run(..._) }
|
|
110
110
|
foreach (..._) { return (this.db || this.error._no_primary_db).foreach(..._) }
|
|
111
|
-
stream (..._) { return (this.db || this.error._no_primary_db).stream(..._) }
|
|
112
111
|
read (..._) { return (this.db || this.error._no_primary_db).read(..._) }
|
|
113
112
|
create (..._) { return (this.db || this.error._no_primary_db).create(..._) }
|
|
114
113
|
insert (..._) { return (this.db || this.error._no_primary_db).insert(..._) }
|
|
@@ -119,7 +118,6 @@ const cds = module.exports = global.cds = new class cds extends EventEmitter {
|
|
|
119
118
|
|
|
120
119
|
// legacy and to be moved stuff -> hidden for tools in cds.__proto__
|
|
121
120
|
/** @deprecated */ transaction (..._) { return (this.db||this.error._no_primary_db).transaction(..._) }
|
|
122
|
-
/** @deprecated */ get build() { return super.build = this.error._outdated_dk }
|
|
123
121
|
/** @deprecated */ get in() { return super.in = cwd => !cwd ? this : {__proto__:this, cwd, env: this.env.for('cds',cwd) } }
|
|
124
122
|
}
|
|
125
123
|
|
|
@@ -137,8 +135,12 @@ extend (global) .with (class {
|
|
|
137
135
|
static get CXL() { return cds.parse.CXL }
|
|
138
136
|
})
|
|
139
137
|
|
|
140
|
-
//
|
|
141
|
-
|
|
138
|
+
// ensure cds.test is loaded for running tests w/ node --test
|
|
139
|
+
'describe' in global || ['describe','before','beforeAll','afterAll'].forEach (p => {
|
|
140
|
+
Object.defineProperty (global,p, { configurable:1, set(v){Object.defineProperty(global,p,{value:v})},
|
|
141
|
+
get(){ return cds.test, global[p] }
|
|
142
|
+
})
|
|
143
|
+
})
|
|
142
144
|
|
|
143
145
|
// Allow for import cds from '@sap/cds' without esModuleInterop
|
|
144
146
|
// FIXME: remove this flag in the next release. Only serves as fallback switch if people report issues with value:cds
|
package/lib/lazy.js
CHANGED
|
@@ -42,7 +42,7 @@ const lazify_module = (module) => {
|
|
|
42
42
|
extend(module).with({ set exports(all) {
|
|
43
43
|
extend(module).with({ exports: lazify(all) })
|
|
44
44
|
}})
|
|
45
|
-
return (id) => (lazy) => module.require(id)
|
|
45
|
+
return (id) => (lazy) => module.require(id) // eslint-disable-line no-unused-vars
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
const is_lazy = (x) => typeof x === 'function' && /^(function\s?)?\(?lazy[,)\t =]/.test(x)
|
package/lib/linked/classes.js
CHANGED
|
@@ -7,7 +7,7 @@ class any { is (kind) { return this.kind === kind || kind === 'any' }
|
|
|
7
7
|
set name(n) { this.set('name', n, false) }
|
|
8
8
|
set kind(k) { this.set('kind', k, true) }
|
|
9
9
|
get kind() { return this.set('kind', this.parent ? 'element' : 'type') }
|
|
10
|
-
|
|
10
|
+
toString(){ return !this.type ? this : this.type.startsWith('cds.') ? this.type.slice(4) : this.type }
|
|
11
11
|
|
|
12
12
|
own (property, ifAbsent) {
|
|
13
13
|
const pd = Reflect.getOwnPropertyDescriptor (this, property)
|
|
@@ -40,8 +40,14 @@ class type extends any { is(kind) { return kind === 'type' || super.is(kind) }
|
|
|
40
40
|
class boolean extends scalar {}
|
|
41
41
|
class Boolean extends boolean {}
|
|
42
42
|
|
|
43
|
-
class string extends scalar {
|
|
44
|
-
|
|
43
|
+
class string extends scalar {
|
|
44
|
+
toString(){
|
|
45
|
+
return this.length ? `${super.toString()}(${this.length})` : super.toString()
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
class UUID extends string {
|
|
49
|
+
toString(){ return 'UUID' }
|
|
50
|
+
}
|
|
45
51
|
class String extends string {}
|
|
46
52
|
class LargeString extends String {}
|
|
47
53
|
class Binary extends string {}
|
|
@@ -56,7 +62,11 @@ class type extends any { is(kind) { return kind === 'type' || super.is(kind) }
|
|
|
56
62
|
class Int64 extends Integer {}
|
|
57
63
|
class Float extends number {}
|
|
58
64
|
class Double extends Float {}
|
|
59
|
-
class Decimal extends Float {
|
|
65
|
+
class Decimal extends Float {
|
|
66
|
+
toString(){
|
|
67
|
+
return this.precision ? this.scale ? `Decimal(${this.precision},${this.scale})` : `Decimal(${this.precision})` : 'Decimal'
|
|
68
|
+
}
|
|
69
|
+
}
|
|
60
70
|
|
|
61
71
|
class date extends scalar {}
|
|
62
72
|
class Date extends date {}
|
|
@@ -64,8 +74,17 @@ class type extends any { is(kind) { return kind === 'type' || super.is(kind) }
|
|
|
64
74
|
class DateTime extends date {}
|
|
65
75
|
class Timestamp extends DateTime {}
|
|
66
76
|
|
|
67
|
-
class array extends type {
|
|
68
|
-
|
|
77
|
+
class array extends type {
|
|
78
|
+
toString(){ return 'array of ' + this.items.toString() }
|
|
79
|
+
is(kind) { return kind === 'array' || super.is(kind) }
|
|
80
|
+
}
|
|
81
|
+
class struct extends type {
|
|
82
|
+
toString(){
|
|
83
|
+
const elements = []
|
|
84
|
+
for (let each in this.elements) elements.push(each)
|
|
85
|
+
return `{ ${elements.join(', ')} }`
|
|
86
|
+
}
|
|
87
|
+
is(kind) { return kind === 'struct' || super.is(kind) }
|
|
69
88
|
|
|
70
89
|
/**
|
|
71
90
|
* Gets the foreign key data for a given managed association from inbound data
|
|
@@ -167,11 +186,20 @@ class LinkedDefinitions {
|
|
|
167
186
|
*[Symbol.iterator](){ for (let e in this) yield this[e] }
|
|
168
187
|
forEach(f){ let i=0; for (let k in this) f(this[k],i++,this) }
|
|
169
188
|
filter(f){ let i=0, r=[]; for (let k in this) f(this[k],i++,this) && r.push(this[k]); return r }
|
|
189
|
+
find(f){ for (let k in this) if (f(this[k])) return this[k] }
|
|
170
190
|
map(f){ let i=0, r=[]; for (let k in this) r.push(f(this[k],i++,this)); return r }
|
|
171
191
|
some(f){ for (let k in this) if (f(this[k])) return true }
|
|
172
|
-
|
|
192
|
+
every(f){ for (let k in this) if (!f(this[k])) return false }
|
|
173
193
|
}
|
|
174
194
|
|
|
195
|
+
// Protect LinkedDefinitions methods from erroneously being used as linked definitions/elements
|
|
196
|
+
Object.entries(Object.getOwnPropertyDescriptors(LinkedDefinitions.prototype)).forEach(([p,pd]) => p === 'constructor' || Object.defineProperties(pd.value, {
|
|
197
|
+
own: {get(){ throw new Error(`'${p}' is not a linked definition but a method inherited from LinkedDefinitions`) }},
|
|
198
|
+
name: {get(){ throw new Error(`'${p}' is not a linked definition but a method inherited from LinkedDefinitions`) }},
|
|
199
|
+
kind: {get(){ throw new Error(`'${p}' is not a linked definition but a method inherited from LinkedDefinitions`) }},
|
|
200
|
+
type: {get(){ throw new Error(`'${p}' is not a linked definition but a method inherited from LinkedDefinitions`) }},
|
|
201
|
+
_type: {get(){ throw new Error(`'${p}' is not a linked definition but a method inherited from LinkedDefinitions`) }},
|
|
202
|
+
}))
|
|
175
203
|
|
|
176
204
|
module.exports = {
|
|
177
205
|
|
|
@@ -179,7 +207,7 @@ module.exports = {
|
|
|
179
207
|
|
|
180
208
|
any, type, aspect, struct, array,
|
|
181
209
|
scalar, boolean, string, number, date,
|
|
182
|
-
service, event, action,
|
|
210
|
+
service, event, action, function: action,
|
|
183
211
|
context,
|
|
184
212
|
|
|
185
213
|
UUID, Boolean, String,
|
package/lib/linked/entities.js
CHANGED
|
@@ -32,15 +32,6 @@ class entity extends struct {
|
|
|
32
32
|
return derived[kind] = any
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
get drafts() {
|
|
36
|
-
if (cds.env.fiori.lean_draft) return null
|
|
37
|
-
// Remove this getter when old draft is removed
|
|
38
|
-
return this.own('_drafts') || this.set('_drafts', this.elements?.HasDraftEntity && {
|
|
39
|
-
name: this.name + '_drafts', keys: this.keys,
|
|
40
|
-
toString(){ return this.name.replace(/\./g,'_') }
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
|
|
44
35
|
toJSON() {
|
|
45
36
|
return this.own('query') ? {...this} : super.toJSON(this)
|
|
46
37
|
}
|
|
@@ -67,7 +58,8 @@ class Association extends type {
|
|
|
67
58
|
for (const k of keys) {
|
|
68
59
|
const el = k.ref.reduce((target,n)=> target.elements[n], this._target)
|
|
69
60
|
const as = k.as || k.ref.at(-1)
|
|
70
|
-
foreignKeys[as] = Object.create (el, { name:{value:as} }) //, parent:{value:this} })
|
|
61
|
+
foreignKeys[as] = Object.create (el, { name:{value:as}, notNull: {value:true} }) //, parent:{value:this} })
|
|
62
|
+
// For structures, foreign keys must be provided, (autogenerated) UUIDs are skipped for validation
|
|
71
63
|
// REVISIT: We should change the line above to set parent correctly, as in the commented tail part.
|
|
72
64
|
// But that breaks code in _runtime which expects it to be the wrong parent.
|
|
73
65
|
}
|