@sap/cds 7.8.2 → 7.9.1
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 +45 -0
- package/_i18n/i18n_ar.properties +3 -0
- package/_i18n/i18n_cs.properties +3 -0
- package/_i18n/i18n_da.properties +3 -0
- package/_i18n/i18n_es_MX.properties +3 -0
- package/_i18n/i18n_fi.properties +3 -0
- package/_i18n/i18n_hu.properties +6 -0
- package/_i18n/i18n_ko.properties +3 -0
- package/_i18n/i18n_ms.properties +3 -0
- package/_i18n/i18n_nl.properties +3 -0
- package/_i18n/i18n_no.properties +3 -0
- package/_i18n/i18n_ro.properties +3 -0
- package/_i18n/i18n_sv.properties +3 -0
- package/_i18n/i18n_th.properties +3 -0
- package/_i18n/i18n_tr.properties +6 -0
- package/_i18n/i18n_zh_TW.properties +3 -0
- package/bin/serve.js +5 -5
- package/lib/auth/basic-auth.js +1 -1
- package/lib/compile/cdsc.js +33 -6
- package/lib/compile/etc/_localized.js +14 -7
- package/lib/compile/for/lean_drafts.js +9 -0
- package/lib/compile/to/edm-files.js +116 -0
- package/lib/compile/to/edm.js +8 -1
- package/lib/compile/to/hdbtabledata.js +3 -3
- package/lib/compile/to/sql.js +4 -2
- package/lib/compile/to/srvinfo.js +6 -5
- package/lib/compile/to/yaml.js +22 -21
- package/lib/dbs/cds-deploy.js +5 -6
- package/lib/env/cds-env.js +7 -0
- package/lib/env/cds-requires.js +20 -1
- package/lib/env/defaults.js +21 -5
- package/lib/env/schemas/cds-package.js +1 -1
- package/lib/env/schemas/cds-rc.js +85 -4
- package/lib/index.js +1 -1
- package/lib/linked/entities.js +10 -0
- package/lib/linked/models.js +1 -1
- package/lib/plugins.js +1 -1
- package/lib/ql/INSERT.js +17 -3
- package/lib/ql/Query.js +4 -0
- package/lib/ql/infer.js +1 -1
- package/lib/req/request.js +1 -1
- package/lib/srv/cds-serve.js +1 -0
- package/lib/srv/middlewares/cds-context.js +1 -1
- package/lib/srv/protocols/odata-v4.js +5 -6
- package/lib/srv/srv-models.js +9 -2
- package/lib/utils/cds-test.js +2 -0
- package/lib/utils/cds-utils.js +9 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +3 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +22 -10
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +4 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +4 -1
- 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 +38 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +32 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +1 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +0 -10
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +3 -1
- package/libx/_runtime/cds-services/services/utils/compareJson.js +2 -274
- package/libx/_runtime/{cds-services/services → common}/Service.js +39 -29
- package/libx/_runtime/common/generic/auth/autoexpose.js +41 -0
- package/libx/_runtime/common/generic/auth/index.js +2 -0
- package/libx/_runtime/common/generic/auth/readOnly.js +0 -11
- package/libx/_runtime/common/generic/auth/restrict.js +6 -5
- package/libx/_runtime/common/generic/auth/utils.js +1 -1
- package/libx/_runtime/common/generic/crud.js +5 -8
- package/libx/_runtime/common/generic/etag.js +8 -6
- package/libx/_runtime/common/generic/sorting.js +2 -2
- package/libx/_runtime/common/i18n/messages.properties +1 -0
- package/libx/_runtime/{cds-services/services → common}/utils/columns.js +4 -4
- package/libx/_runtime/common/utils/compareJson.js +274 -0
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +1 -1
- package/libx/_runtime/{cds-services/services → common}/utils/differ.js +8 -8
- package/libx/_runtime/common/utils/ensureIEEE754.js +29 -0
- package/libx/_runtime/common/utils/{postProcessing.js → postProcess.js} +1 -3
- package/libx/_runtime/common/utils/resolveView.js +0 -16
- package/libx/_runtime/common/utils/rewriteAsterisks.js +1 -1
- package/libx/_runtime/common/utils/search2cqn4sql.js +1 -1
- package/libx/_runtime/common/utils/streamProp.js +9 -2
- package/libx/_runtime/common/utils/ucsn.js +1 -1
- package/libx/_runtime/db/expand/expandCQNToJoin.js +5 -3
- package/libx/_runtime/db/generic/rewrite.js +7 -13
- package/libx/_runtime/fiori/generic/activate.js +1 -1
- package/libx/_runtime/fiori/generic/edit.js +1 -1
- package/libx/_runtime/fiori/generic/prepare.js +1 -1
- package/libx/_runtime/fiori/lean-draft.js +151 -46
- package/libx/_runtime/fiori/utils/handler.js +1 -1
- package/libx/_runtime/hana/execute.js +6 -2
- package/libx/_runtime/hana/pool.js +3 -0
- package/libx/_runtime/hana/search2cqn4sql.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +1 -2
- package/libx/_runtime/messaging/event-broker.js +212 -0
- package/libx/_runtime/remote/Service.js +9 -32
- package/libx/_runtime/remote/utils/client.js +13 -21
- package/libx/_runtime/sqlite/convertAssocToOneManaged.js +7 -1
- package/libx/_runtime/sqlite/execute.js +8 -3
- package/libx/_runtime/ucl/Service.js +259 -0
- package/libx/common/assert/index.js +5 -11
- package/libx/common/assert/validation.js +6 -1
- package/libx/odata/index.js +47 -25
- package/libx/odata/middleware/batch.js +8 -7
- package/libx/odata/middleware/create.js +42 -16
- package/libx/odata/middleware/delete.js +18 -11
- package/libx/odata/middleware/metadata.js +15 -14
- package/libx/odata/middleware/operation.js +30 -40
- package/libx/odata/middleware/parse.js +2 -3
- package/libx/odata/middleware/read.js +59 -52
- package/libx/odata/middleware/service-document.js +7 -7
- package/libx/odata/middleware/stream.js +26 -24
- package/libx/odata/middleware/update.js +53 -92
- package/libx/odata/parse/afterburner.js +45 -47
- package/libx/odata/parse/grammar.peggy +3 -3
- package/libx/odata/parse/multipartToJson.js +10 -22
- package/libx/odata/parse/parser.js +1 -1
- package/libx/odata/utils/etag.js +13 -0
- package/libx/odata/utils/handler.js +120 -0
- package/libx/odata/utils/index.js +15 -2
- package/libx/odata/utils/metaInfo.js +410 -0
- package/libx/odata/utils/path.js +5 -2
- package/libx/odata/utils/readAfterWrite.js +23 -0
- package/libx/odata/utils/result.js +4 -5
- package/libx/rest/RestAdapter.js +4 -13
- package/libx/rest/middleware/parse.js +40 -7
- package/package.json +1 -1
- package/server.js +1 -0
- package/libx/_runtime/cds-services/util/dataProcessUtils.js +0 -93
- package/libx/_runtime/common/utils/thenable.js +0 -51
- package/libx/_runtime/rest/service.js +0 -2
- package/libx/odata/parse/parseToCqn.js +0 -39
- package/libx/rest/middleware/input.js +0 -54
- package/libx/rest/middleware/payload.js +0 -13
package/lib/compile/to/yaml.js
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
// A simple YAML serializer
|
|
2
|
-
module.exports = function _2yaml (object,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if (o === null) return o
|
|
8
|
-
if (typeof o === 'function') return ''
|
|
9
|
-
if (o.toJSON) o = o.toJSON()
|
|
2
|
+
module.exports = function _2yaml (object, {limit=111}={}) {
|
|
3
|
+
return $(object,'',1).toString().replace(/^\n/,'')
|
|
4
|
+
function $(o, indent, count, _visited) {
|
|
5
|
+
if (o == null) return o
|
|
6
|
+
if (o.toJSON) o = o.toJSON()
|
|
10
7
|
if (Array.isArray(o)) {
|
|
11
8
|
let s = ''
|
|
12
|
-
for (let e of o) s += '\n'+indent+'- '+ $(e,indent+'
|
|
13
|
-
return s.length > limit ? s : '['+ s.replace (/\n\s*- /g, ', ').
|
|
9
|
+
for (let e of o) s += '\n'+indent+'- '+ $(e,indent+' ',0)
|
|
10
|
+
return s.length > limit ? s : '['+ s.replace (/\n\s*- /g, ', ').replace(/^, /,'') +']'
|
|
14
11
|
}
|
|
15
12
|
if (typeof o === 'object') {
|
|
13
|
+
const visited = new Set (_visited)
|
|
14
|
+
if (visited.has(o)) return console.error('circular reference to',o)
|
|
15
|
+
else visited.add(o)
|
|
16
16
|
let s = ''
|
|
17
17
|
for (let k in o) {
|
|
18
18
|
let e = o[k]
|
|
19
|
-
if (e === undefined)
|
|
20
|
-
if (typeof e === 'function')
|
|
21
|
-
if (
|
|
22
|
-
if (
|
|
19
|
+
if (e === undefined) continue
|
|
20
|
+
if (typeof e === 'function') continue
|
|
21
|
+
if (e?.valueOf && e.valueOf() === undefined) continue
|
|
22
|
+
if (e?.toJSON && e.toJSON() === undefined) continue
|
|
23
23
|
let key = /^[$\w]/.test(k) ? k : "'"+ k +"'"
|
|
24
|
-
s += '\n'+indent
|
|
24
|
+
if (count++ > 0) s += '\n'+indent
|
|
25
|
+
s += key +': '+ $(e,indent+' ',1,visited)
|
|
25
26
|
}
|
|
26
|
-
return s.length > limit ? s : '{'+ s.replace (/\n\s*/g, ', ').
|
|
27
|
+
return s.length > limit ? s : '{'+ s.replace (/\n\s*/g, ', ').replace(/^, /,'') +'}'
|
|
27
28
|
}
|
|
28
29
|
if (typeof o === 'string') {
|
|
29
|
-
if (o.indexOf('\n')>=0)
|
|
30
|
+
if (o.indexOf('\n')>=0) return '|'+'\n'+indent+ o.replace(/\n/g,'\n'+indent)
|
|
30
31
|
let s = o.trim()
|
|
31
|
-
return
|
|
32
|
+
return !s || /^[\^@#:,=!<>*|]/.test(s) ? '"'+ o.replace(/\\/g,'\\\\') +'"' : s
|
|
32
33
|
}
|
|
34
|
+
if (typeof o === 'function') return ''
|
|
33
35
|
else return o
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
36
|
+
}
|
|
37
|
+
}
|
package/lib/dbs/cds-deploy.js
CHANGED
|
@@ -58,14 +58,13 @@ const deploy = module.exports = function cds_deploy (model, options, csvs) {
|
|
|
58
58
|
deploy.schema = async function (db, csn = db.model, o) {
|
|
59
59
|
|
|
60
60
|
if (!o.to || o.to === db.options.kind) o = { ...db.options, ...o }
|
|
61
|
-
if (o.impl === '@cap-js/sqlite') {
|
|
62
|
-
// REVISIT: Move that to configuration or to cds.compile -> currently cds compile creates wrong output
|
|
63
|
-
o.betterSqliteSessionVariables = true
|
|
64
|
-
o.sqlDialect = 'sqlite'
|
|
65
|
-
}
|
|
66
61
|
|
|
67
62
|
let drops, creas
|
|
68
|
-
let schevo =
|
|
63
|
+
let schevo = (o.kind === 'postgres' && o.schema_evolution !== false)
|
|
64
|
+
|| o.schema_evolution === 'auto'
|
|
65
|
+
|| o['with-auto-schema-evolution']
|
|
66
|
+
|| o['model-only']
|
|
67
|
+
|| o['delta-from']
|
|
69
68
|
if (schevo) {
|
|
70
69
|
const { prior, table_exists } = await get_prior_model()
|
|
71
70
|
const { afterImage, drops: d, createsAndAlters } = cds.compile.to.sql.delta(csn, o, prior);
|
package/lib/env/cds-env.js
CHANGED
|
@@ -91,6 +91,13 @@ 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
|
+
}
|
|
94
101
|
}
|
|
95
102
|
|
|
96
103
|
/**
|
package/lib/env/cds-requires.js
CHANGED
|
@@ -91,7 +91,7 @@ const _services = {
|
|
|
91
91
|
|
|
92
92
|
"app-service": {
|
|
93
93
|
// this is the default implementation used for provided services
|
|
94
|
-
impl: `${_runtime}/
|
|
94
|
+
impl: `${_runtime}/common/Service.js`
|
|
95
95
|
},
|
|
96
96
|
"rest": {
|
|
97
97
|
impl: `${_runtime}/remote/Service.js`,
|
|
@@ -125,6 +125,7 @@ const _databases = {
|
|
|
125
125
|
},
|
|
126
126
|
|
|
127
127
|
"sqlite": {
|
|
128
|
+
'[legacy-sqlite]': { impl: `${_runtime}/sqlite/Service.js` },
|
|
128
129
|
'[better-sqlite]': { impl: '@cap-js/sqlite' },
|
|
129
130
|
impl: `${_runtime}/sqlite/Service.js`,
|
|
130
131
|
credentials: { url: 'db.sqlite' },
|
|
@@ -141,11 +142,16 @@ const _databases = {
|
|
|
141
142
|
},
|
|
142
143
|
|
|
143
144
|
"hana": {
|
|
145
|
+
'[better-hana]': { impl: '@cap-js/hana' },
|
|
144
146
|
impl: `${_runtime}/hana/Service.js`,
|
|
145
147
|
},
|
|
146
148
|
"hana-cloud": {
|
|
147
149
|
kind: 'hana', "deploy-format": "hdbtable",
|
|
148
150
|
},
|
|
151
|
+
"legacy-hana": {
|
|
152
|
+
impl: `${_runtime}/hana/Service.js`,
|
|
153
|
+
kind: 'hana'
|
|
154
|
+
},
|
|
149
155
|
|
|
150
156
|
"sql-mt": { // For compatibility only
|
|
151
157
|
'[development]': { kind: 'sqlite' },
|
|
@@ -213,6 +219,12 @@ const _messaging = {
|
|
|
213
219
|
vcap: { label: "enterprise-messaging" },
|
|
214
220
|
outbox: true
|
|
215
221
|
},
|
|
222
|
+
"event-broker": {
|
|
223
|
+
impl: `${_runtime}/messaging/event-broker.js`,
|
|
224
|
+
vcap: {
|
|
225
|
+
label: "eventmesh-sap2sap-internal"
|
|
226
|
+
}
|
|
227
|
+
},
|
|
216
228
|
'message-queuing': {
|
|
217
229
|
impl: `${_runtime}/messaging/message-queuing.js`,
|
|
218
230
|
outbox: true
|
|
@@ -243,6 +255,13 @@ const _messaging = {
|
|
|
243
255
|
|
|
244
256
|
const _platform_services = {
|
|
245
257
|
|
|
258
|
+
ucl: {
|
|
259
|
+
impl: `${_runtime}/ucl/Service.js`,
|
|
260
|
+
host: 'compass-gateway-sap-mtls.mps.kyma.cloud.sap',
|
|
261
|
+
path: '/director/graphql',
|
|
262
|
+
vcap: { label: 'xsuaa' }
|
|
263
|
+
},
|
|
264
|
+
|
|
246
265
|
destinations: {
|
|
247
266
|
vcap: {
|
|
248
267
|
label: 'destination'
|
package/lib/env/defaults.js
CHANGED
|
@@ -20,6 +20,8 @@ const defaults = module.exports = {
|
|
|
20
20
|
|
|
21
21
|
features: {
|
|
22
22
|
folders: 'fts/*', // where to find feature toggles -> switch on by default when released
|
|
23
|
+
pre_compile_edmxs: false,
|
|
24
|
+
odata_new_adapter: false, // switch default with cds^8
|
|
23
25
|
live_reload: !production,
|
|
24
26
|
in_memory_db: !production,
|
|
25
27
|
test_data: !production,
|
|
@@ -34,24 +36,26 @@ const defaults = module.exports = {
|
|
|
34
36
|
assert_integrity: false,
|
|
35
37
|
cds_tx_inheritance: true,
|
|
36
38
|
serve_on_root: false,
|
|
37
|
-
precise_timestamps: false
|
|
39
|
+
precise_timestamps: false,
|
|
40
|
+
string_decimals: false, // switch default with cds^8
|
|
38
41
|
},
|
|
39
42
|
|
|
40
43
|
fiori: {
|
|
41
44
|
preview: !production,
|
|
42
45
|
routes: !production,
|
|
43
46
|
lean_draft: true,
|
|
44
|
-
wrap_multiple_errors: true, // switch default with cds
|
|
47
|
+
wrap_multiple_errors: true, // switch default with cds^8
|
|
45
48
|
draft_lock_timeout: true,
|
|
46
|
-
draft_deletion_timeout: false, // switch default with cds
|
|
49
|
+
draft_deletion_timeout: false, // switch default with cds^8
|
|
47
50
|
draft_compat: undefined,
|
|
48
51
|
'[better-sqlite]': { lean_draft: true },
|
|
52
|
+
'[better-hana]': { lean_draft: true },
|
|
49
53
|
'[lean-draft]': { lean_draft: true },
|
|
50
54
|
'[draft-compat]': { draft_compat: true },
|
|
51
55
|
},
|
|
52
56
|
|
|
53
57
|
ql: {
|
|
54
|
-
quirks_mode: true, // IMPORTANT: Remove that for
|
|
58
|
+
quirks_mode: true, // IMPORTANT: Remove that for cds^7 !!
|
|
55
59
|
},
|
|
56
60
|
|
|
57
61
|
log: {
|
|
@@ -65,7 +69,7 @@ const defaults = module.exports = {
|
|
|
65
69
|
service: false,
|
|
66
70
|
// the rest is only applicable for the json formatter
|
|
67
71
|
user: false,
|
|
68
|
-
mask_headers: ['/authorization/i', '/cookie/i'],
|
|
72
|
+
mask_headers: ['/authorization/i', '/cookie/i', '/cert/i', '/ssl/i'],
|
|
69
73
|
aspects: ['./aspects/cf', './aspects/als'], //> EXPERIMENTAL!!!
|
|
70
74
|
// adds custom fields in kibana's error rendering (unknown fields are ignored); key: index
|
|
71
75
|
// note: custom fields are a feature of Application Logging Service (ALS) and not Kibana per se
|
|
@@ -142,6 +146,17 @@ const defaults = module.exports = {
|
|
|
142
146
|
},
|
|
143
147
|
|
|
144
148
|
sql: {
|
|
149
|
+
/**
|
|
150
|
+
* Allows to skip generating transitive localized views for entities which don't have own localized elements, but only associations to such.
|
|
151
|
+
* - `undefined` → skipped for new db services.
|
|
152
|
+
* - `false` → always skipped.
|
|
153
|
+
* - `true` → never skipped.
|
|
154
|
+
*/
|
|
155
|
+
transitive_localized_views: true,
|
|
156
|
+
'[java]': {
|
|
157
|
+
transitive_localized_views: false
|
|
158
|
+
},
|
|
159
|
+
native_hana_associations: true,
|
|
145
160
|
names: 'plain', // or 'quoted', or 'hdbcds'
|
|
146
161
|
dialect: 'sqlite' // or 'plain' or 'hana'
|
|
147
162
|
},
|
|
@@ -173,6 +188,7 @@ const defaults = module.exports = {
|
|
|
173
188
|
cdsc: {
|
|
174
189
|
moduleLookupDirectories: ['node_modules/'],
|
|
175
190
|
'[java]': {
|
|
191
|
+
betterSqliteSessionVariables: true,
|
|
176
192
|
moduleLookupDirectories: ['node_modules/', 'target/cds/'],
|
|
177
193
|
}
|
|
178
194
|
// cv2: {
|
|
@@ -8,7 +8,7 @@ module.exports = {
|
|
|
8
8
|
// and not in the root of the package.json
|
|
9
9
|
|
|
10
10
|
title: 'JSON schema for CDS configuration in package.json',
|
|
11
|
-
$schema: 'https://json-schema.org/draft
|
|
11
|
+
$schema: 'https://json-schema.org/draft-07/schema',
|
|
12
12
|
description: 'This is a JSON schema representation of the CDS project configuration inside a project root level package.json',
|
|
13
13
|
type: 'object',
|
|
14
14
|
properties: {
|
|
@@ -4,7 +4,7 @@ module.exports = {
|
|
|
4
4
|
_version: cds.version,
|
|
5
5
|
|
|
6
6
|
title: 'JSON schema for CDS configuration',
|
|
7
|
-
$schema: 'https://json-schema.org/draft
|
|
7
|
+
$schema: 'https://json-schema.org/draft-07/schema',
|
|
8
8
|
description: 'This is a JSON schema representation for CDS project configuration',
|
|
9
9
|
type: 'object',
|
|
10
10
|
additionalProperties: true,
|
|
@@ -27,17 +27,32 @@ module.exports = {
|
|
|
27
27
|
|
|
28
28
|
$defs: {
|
|
29
29
|
cdsRoot: {
|
|
30
|
+
allowAdditionalProperties: true,
|
|
31
|
+
patternProperties: {
|
|
32
|
+
'\\[.+\\]': {
|
|
33
|
+
default: {},
|
|
34
|
+
description: 'Generic cds profile',
|
|
35
|
+
$ref: '#/$defs/cdsRoot'
|
|
36
|
+
}
|
|
37
|
+
},
|
|
30
38
|
properties: {
|
|
31
39
|
'[development]': {
|
|
32
|
-
|
|
40
|
+
default: {},
|
|
41
|
+
description: 'Development profile',
|
|
42
|
+
$ref: '#/$defs/cdsRoot'
|
|
33
43
|
},
|
|
34
44
|
'[production]': {
|
|
35
|
-
|
|
45
|
+
default: {},
|
|
46
|
+
description: 'Production profile',
|
|
47
|
+
$ref: '#/$defs/cdsRoot'
|
|
36
48
|
},
|
|
37
49
|
'[hybrid]': {
|
|
38
|
-
|
|
50
|
+
default: {},
|
|
51
|
+
description: 'Hybrid profile',
|
|
52
|
+
$ref: '#/$defs/cdsRoot'
|
|
39
53
|
},
|
|
40
54
|
profile: {
|
|
55
|
+
default: {},
|
|
41
56
|
description: 'A single static profile',
|
|
42
57
|
anyOf: [
|
|
43
58
|
{
|
|
@@ -53,6 +68,7 @@ module.exports = {
|
|
|
53
68
|
]
|
|
54
69
|
},
|
|
55
70
|
profiles: {
|
|
71
|
+
default: [],
|
|
56
72
|
description: 'An array of profiles',
|
|
57
73
|
type: 'array',
|
|
58
74
|
uniqueItems: true,
|
|
@@ -62,6 +78,7 @@ module.exports = {
|
|
|
62
78
|
},
|
|
63
79
|
folders: {
|
|
64
80
|
type: 'object',
|
|
81
|
+
default: {},
|
|
65
82
|
description: 'Only set folders if you don\'t want to use the defaults \'app/\', \'db/\', \'srv/\'.',
|
|
66
83
|
additionalProperties: true,
|
|
67
84
|
properties: {
|
|
@@ -82,6 +99,11 @@ module.exports = {
|
|
|
82
99
|
}
|
|
83
100
|
},
|
|
84
101
|
patternProperties: {
|
|
102
|
+
'\\[.+\\]': {
|
|
103
|
+
default: {},
|
|
104
|
+
description: 'Generic folders profile',
|
|
105
|
+
$ref: '#/$defs/cdsRoot/properties/folders'
|
|
106
|
+
},
|
|
85
107
|
'.+': {
|
|
86
108
|
description: 'A static name identifying this folder.'
|
|
87
109
|
}
|
|
@@ -91,6 +113,13 @@ module.exports = {
|
|
|
91
113
|
type: 'object',
|
|
92
114
|
description: 'Customize CDS translation settings.',
|
|
93
115
|
additionalProperties: true,
|
|
116
|
+
patternProperties: {
|
|
117
|
+
'\\[.+\\]': {
|
|
118
|
+
default: {},
|
|
119
|
+
description: 'Generic i18n profile',
|
|
120
|
+
$ref: '#/$defs/cdsRoot/properties/i18n'
|
|
121
|
+
}
|
|
122
|
+
},
|
|
94
123
|
properties: {
|
|
95
124
|
default_language: {
|
|
96
125
|
type: 'string'
|
|
@@ -104,6 +133,7 @@ module.exports = {
|
|
|
104
133
|
},
|
|
105
134
|
requires: {
|
|
106
135
|
type: 'object',
|
|
136
|
+
default: {},
|
|
107
137
|
description: 'List CDS dependencies to databases and services within the requires section.',
|
|
108
138
|
additionalProperties: true,
|
|
109
139
|
properties: {
|
|
@@ -126,6 +156,13 @@ module.exports = {
|
|
|
126
156
|
description: 'Use custom authentication settings.',
|
|
127
157
|
default: {},
|
|
128
158
|
additionalProperties: true,
|
|
159
|
+
// support for [profileName] syntax
|
|
160
|
+
patternProperties: {
|
|
161
|
+
'\\[.+\\]': {
|
|
162
|
+
description: 'aloha',
|
|
163
|
+
$ref: '#/$defs/cdsRoot/properties/requires/properties/auth'
|
|
164
|
+
}
|
|
165
|
+
},
|
|
129
166
|
properties: {
|
|
130
167
|
kind: {
|
|
131
168
|
type: 'string',
|
|
@@ -176,6 +213,11 @@ module.exports = {
|
|
|
176
213
|
description: 'Use custom database-specific settings.',
|
|
177
214
|
default: {},
|
|
178
215
|
additionalProperties: true,
|
|
216
|
+
patternProperties: {
|
|
217
|
+
'\\[.+\\]': {
|
|
218
|
+
$ref: '#/$defs/cdsRoot/properties/requires/properties/db'
|
|
219
|
+
}
|
|
220
|
+
},
|
|
179
221
|
properties: {
|
|
180
222
|
kind: {
|
|
181
223
|
type: 'string',
|
|
@@ -232,6 +274,12 @@ module.exports = {
|
|
|
232
274
|
{
|
|
233
275
|
type: 'object',
|
|
234
276
|
description: 'Multitenancy configuration options.',
|
|
277
|
+
additionalProperties: true,
|
|
278
|
+
patternProperties: {
|
|
279
|
+
'\\[.+\\]': {
|
|
280
|
+
$ref: '#/$defs/cdsRoot/properties/requires/properties/multitenancy'
|
|
281
|
+
}
|
|
282
|
+
},
|
|
235
283
|
properties: {
|
|
236
284
|
jobs: {
|
|
237
285
|
type: 'object',
|
|
@@ -260,6 +308,12 @@ module.exports = {
|
|
|
260
308
|
{
|
|
261
309
|
type: 'object',
|
|
262
310
|
description: 'Extensibility configuration options.',
|
|
311
|
+
additionalProperties: true,
|
|
312
|
+
patternProperties: {
|
|
313
|
+
'\\[.+\\]': {
|
|
314
|
+
$ref: '#/$defs/cdsRoot/properties/requires/properties/extensibility'
|
|
315
|
+
}
|
|
316
|
+
},
|
|
263
317
|
properties: {
|
|
264
318
|
tenantCheckInterval: {
|
|
265
319
|
type: 'number',
|
|
@@ -290,6 +344,11 @@ module.exports = {
|
|
|
290
344
|
type: 'object',
|
|
291
345
|
description: 'ModelProviderService configuration options.',
|
|
292
346
|
additionalProperties: true,
|
|
347
|
+
patternProperties: {
|
|
348
|
+
'\\[.+\\]': {
|
|
349
|
+
$ref: '#/$defs/cdsRoot/properties/requires/properties/cds.xt.ModelProviderService'
|
|
350
|
+
}
|
|
351
|
+
},
|
|
293
352
|
properties: {
|
|
294
353
|
root: {
|
|
295
354
|
type: 'string',
|
|
@@ -323,6 +382,12 @@ module.exports = {
|
|
|
323
382
|
{
|
|
324
383
|
type: 'object',
|
|
325
384
|
description: 'DeploymentService configuration options.',
|
|
385
|
+
additionalProperties: true,
|
|
386
|
+
patternProperties: {
|
|
387
|
+
'\\[.+\\]': {
|
|
388
|
+
$ref: '#/$defs/cdsRoot/properties/requires/properties/cds.xt.DeploymentService'
|
|
389
|
+
}
|
|
390
|
+
},
|
|
326
391
|
properties: {
|
|
327
392
|
hdi: {
|
|
328
393
|
type: 'object',
|
|
@@ -367,6 +432,11 @@ module.exports = {
|
|
|
367
432
|
type: 'object',
|
|
368
433
|
description: 'SaasProvisioningService configuration options.',
|
|
369
434
|
additionalProperties: true,
|
|
435
|
+
patternProperties: {
|
|
436
|
+
'\\[.+\\]': {
|
|
437
|
+
$ref: '#/$defs/cdsRoot/properties/requires/properties/cds.xt.SaasProvisioningService'
|
|
438
|
+
}
|
|
439
|
+
},
|
|
370
440
|
properties: {
|
|
371
441
|
jobs: {
|
|
372
442
|
type: 'object',
|
|
@@ -389,6 +459,11 @@ module.exports = {
|
|
|
389
459
|
}
|
|
390
460
|
},
|
|
391
461
|
patternProperties: {
|
|
462
|
+
'\\[.+\\]': {
|
|
463
|
+
default: {},
|
|
464
|
+
description: 'Generic requires profile',
|
|
465
|
+
$ref: '#/$defs/cdsRoot/properties/requires'
|
|
466
|
+
},
|
|
392
467
|
'.+': {
|
|
393
468
|
oneOf: [
|
|
394
469
|
{
|
|
@@ -448,9 +523,15 @@ module.exports = {
|
|
|
448
523
|
},
|
|
449
524
|
protocols: {
|
|
450
525
|
type: 'object',
|
|
526
|
+
default: {},
|
|
451
527
|
description: 'List protocols to enable in addition to the default protocol adaptors.',
|
|
452
528
|
additionalProperties: true,
|
|
453
529
|
patternProperties: {
|
|
530
|
+
'\\[.+\\]': {
|
|
531
|
+
default: {},
|
|
532
|
+
description: 'Generic protocols profile',
|
|
533
|
+
$ref: '#/$defs/cdsRoot/properties/protocols/patternProperties/.+/oneOf/2'
|
|
534
|
+
},
|
|
454
535
|
'.+': {
|
|
455
536
|
oneOf: [
|
|
456
537
|
{
|
package/lib/index.js
CHANGED
|
@@ -79,7 +79,7 @@ const cds = module.exports = global.cds = new class cds extends EventEmitter {
|
|
|
79
79
|
get User() { return super.User = require('./req/user') }
|
|
80
80
|
|
|
81
81
|
// Services, Protocols and Periphery
|
|
82
|
-
get ApplicationService() { return super.ApplicationService = require('../libx/_runtime/
|
|
82
|
+
get ApplicationService() { return super.ApplicationService = require('../libx/_runtime/common/Service.js') }
|
|
83
83
|
get MessagingService() { return super.MessagingService = require('../libx/_runtime/messaging/service.js') }
|
|
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') }
|
package/lib/linked/entities.js
CHANGED
|
@@ -5,6 +5,16 @@ const _derived = Symbol('derived')
|
|
|
5
5
|
|
|
6
6
|
class entity extends struct {
|
|
7
7
|
is (kind) { return kind === 'entity' || kind === 'view' && !!this.query || super.is(kind) }
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Experimental API to write:
|
|
11
|
+
* ```js
|
|
12
|
+
* SELECT.from(Foo.as('bar')) // ... as alternative to:
|
|
13
|
+
* SELECT.from(Foo).alias('bar')
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
as (alias) { return { ntt:this, ref:[this.name], as:alias } }
|
|
17
|
+
|
|
8
18
|
get keys() {
|
|
9
19
|
return this._elements ('key')
|
|
10
20
|
}
|
package/lib/linked/models.js
CHANGED
|
@@ -15,7 +15,7 @@ class LinkedCSN {
|
|
|
15
15
|
constructor(x) {
|
|
16
16
|
|
|
17
17
|
if (typeof x === 'string') x = require('../index').compile(x) //> for convenience in repl
|
|
18
|
-
const defs = x.definitions = _iterable (x.definitions)
|
|
18
|
+
const defs = x.definitions = _iterable (x.definitions||{})
|
|
19
19
|
for (let d in defs) _link (defs[d],d)
|
|
20
20
|
return Object.setPrototypeOf (x, new.target.prototype)
|
|
21
21
|
|
package/lib/plugins.js
CHANGED
|
@@ -30,7 +30,7 @@ exports.fetch = function (DEV = process.env.NODE_ENV !== 'production') {
|
|
|
30
30
|
exports.activate = async function () {
|
|
31
31
|
const DEBUG = cds.debug ('plugins', {label:'cds'})
|
|
32
32
|
DEBUG && console.time ('[cds] - loaded plugins in')
|
|
33
|
-
const
|
|
33
|
+
const plugins = exports.fetch(), { local } = cds.utils
|
|
34
34
|
await Promise.all (Object.entries(plugins) .map (async ([ plugin, conf ]) => {
|
|
35
35
|
DEBUG?.(`loading plugin ${plugin}:`, { impl: local(conf.impl) })
|
|
36
36
|
// TODO: support ESM plugins. But see cap/cds/pull/1838#issuecomment-1177200 !
|
package/lib/ql/INSERT.js
CHANGED
|
@@ -13,6 +13,8 @@ module.exports = class Query extends require('./Query') {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
entries (...x) {
|
|
16
|
+
if (!x.length) return this
|
|
17
|
+
if (x[0].SELECT) return this.from(x[0])
|
|
16
18
|
this[this.cmd].entries = is_array(x[0]) ? x[0] : x
|
|
17
19
|
return this
|
|
18
20
|
}
|
|
@@ -31,11 +33,22 @@ module.exports = class Query extends require('./Query') {
|
|
|
31
33
|
return this
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
if (!query
|
|
36
|
-
|
|
36
|
+
from (query) {
|
|
37
|
+
if (!query) return this
|
|
38
|
+
if (!query.SELECT) {
|
|
39
|
+
if (query.name || typeof query === 'string') query = SELECT.from(query)
|
|
40
|
+
else this._expected `${{query}} to be a CQN {SELECT} query object`
|
|
41
|
+
}
|
|
42
|
+
this[this.cmd].as = query // REVISIT: should we also change CSN spec, and adopt db service impls?
|
|
37
43
|
return this
|
|
38
44
|
}
|
|
45
|
+
|
|
46
|
+
/** @deprecated */ as (query) {
|
|
47
|
+
INSERT_as_SELECT ??= require('../utils').deprecated(()=>{},{old:'INSERT.as(SELECT)', use:'INSERT.entries(SELECT)'})
|
|
48
|
+
INSERT_as_SELECT()
|
|
49
|
+
return this.from(query)
|
|
50
|
+
}
|
|
51
|
+
|
|
39
52
|
valueOf() {
|
|
40
53
|
return super.valueOf('INSERT INTO')
|
|
41
54
|
}
|
|
@@ -44,3 +57,4 @@ module.exports = class Query extends require('./Query') {
|
|
|
44
57
|
}
|
|
45
58
|
|
|
46
59
|
const is_array = Array.isArray
|
|
60
|
+
let INSERT_as_SELECT
|
package/lib/ql/Query.js
CHANGED
|
@@ -5,6 +5,10 @@ class Query {
|
|
|
5
5
|
|
|
6
6
|
constructor(_={}) { this[this.cmd] = _ }
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Note to self: We can't use .as (alias) as that would conflict with
|
|
10
|
+
* sub selects in columns, which in turn may has aliases in .as.
|
|
11
|
+
*/
|
|
8
12
|
alias (a) {
|
|
9
13
|
this._target_ref.as = a
|
|
10
14
|
return this
|
package/lib/ql/infer.js
CHANGED
|
@@ -78,7 +78,7 @@ function elements4 (columns, source) {
|
|
|
78
78
|
if (c.ref && d?.elements) {
|
|
79
79
|
for (let r of ref) d = (d.SELECT ? d : d._target||d).elements?.[r]
|
|
80
80
|
|| cds.error `Couldn't resolve element "${ref.join('/')}" in ${source.kind} ${source.name||''} ${Object.keys(source.elements)}`
|
|
81
|
-
if (d._target) { is2many = d.is2many; d = d._target }
|
|
81
|
+
if (d._target) { is2many = d.is2many; c.expand || c.inline ? d = d._target : d }
|
|
82
82
|
// ... d is further processed in steps 5,6,7 below
|
|
83
83
|
}
|
|
84
84
|
|
package/lib/req/request.js
CHANGED
|
@@ -205,5 +205,5 @@ const _path4 = (x,p) => {
|
|
|
205
205
|
// REVISIT: Legacy stuff...
|
|
206
206
|
//
|
|
207
207
|
Object.defineProperties (Request.prototype, {
|
|
208
|
-
diff: { get: ()=> require('../../libx/_runtime/
|
|
208
|
+
diff: { get: ()=> require('../../libx/_runtime/common/utils/differ').reqDiff }
|
|
209
209
|
})
|
package/lib/srv/cds-serve.js
CHANGED
|
@@ -101,6 +101,7 @@ module.exports = function cds_serve (som, _options) { // NOSONAR
|
|
|
101
101
|
|
|
102
102
|
/** Fluent method to serve constructed providers to express app */
|
|
103
103
|
in (app) {
|
|
104
|
+
if (!cds.env.features.odata_new_adapter && cds.edmxs) ready = ready.then (()=> cds.edmxs)
|
|
104
105
|
ready = ready.then (()=> all.forEach (each => {
|
|
105
106
|
const d = each.definition
|
|
106
107
|
if (d['@protocol'] === 'none' || d['@cds.api.ignore']) return each._is_dark = true
|
|
@@ -4,11 +4,10 @@ const cds = require('../../index'),
|
|
|
4
4
|
const express = require('express') // eslint-disable-line cds/no-missing-dependencies
|
|
5
5
|
|
|
6
6
|
if (cds.env.features.odata_new_adapter) {
|
|
7
|
+
cds.log().info('using new OData adapter')
|
|
8
|
+
|
|
7
9
|
const { isStream, stream } = require('../../../libx/odata/middleware/stream')
|
|
8
10
|
const BaseProtocolAdapter = require('./http')
|
|
9
|
-
// REVISIT: odata_new_adapter shouldn't influence odata_new_parser and cds_assert, but we'd need to set marker in cds.context or so to remove this
|
|
10
|
-
cds.env.features.odata_new_parser = true
|
|
11
|
-
cds.env.features.cds_assert = true
|
|
12
11
|
|
|
13
12
|
module.exports = class ODataAdapter extends BaseProtocolAdapter {
|
|
14
13
|
log(req) {
|
|
@@ -44,7 +43,7 @@ if (cds.env.features.odata_new_adapter) {
|
|
|
44
43
|
if (typeof req.body === 'object') return next()
|
|
45
44
|
if (req.method === 'PUT' && isStream(req._query)) {
|
|
46
45
|
req.body = { value: req }
|
|
47
|
-
return next(
|
|
46
|
+
return next()
|
|
48
47
|
}
|
|
49
48
|
// TODO: check if the raw body still exists, then we can remove deepCopy() in the handlers
|
|
50
49
|
return jsonBodyParser(req, res, next)
|
|
@@ -59,8 +58,8 @@ if (cds.env.features.odata_new_adapter) {
|
|
|
59
58
|
.post('*', require('../../../libx/odata/middleware/create')(srv))
|
|
60
59
|
.get('*', stream(srv))
|
|
61
60
|
.get('*', require('../../../libx/odata/middleware/read')(srv))
|
|
62
|
-
.put('*', require('../../../libx/odata/middleware/update')(srv))
|
|
63
|
-
.patch('*', require('../../../libx/odata/middleware/update')(srv))
|
|
61
|
+
.put('*', require('../../../libx/odata/middleware/update')(srv, router))
|
|
62
|
+
.patch('*', require('../../../libx/odata/middleware/update')(srv, router))
|
|
64
63
|
.delete('*', require('../../../libx/odata/middleware/delete')(srv))
|
|
65
64
|
// error
|
|
66
65
|
.use(require('../../../libx/odata/middleware/error')(srv))
|
package/lib/srv/srv-models.js
CHANGED
|
@@ -182,9 +182,16 @@ if (!extensibility) {
|
|
|
182
182
|
|
|
183
183
|
// helper to get model for tenant/features
|
|
184
184
|
const _is_extended = extensibility ? ()=> cds.db.exists('cds.xt.Extensions') : ()=> false
|
|
185
|
-
const _get_model4 = (tenant, features) => {
|
|
185
|
+
const _get_model4 = async (tenant, features) => {
|
|
186
186
|
const { 'cds.xt.ModelProviderService':mps } = cds.services
|
|
187
|
-
|
|
187
|
+
const csn = await mps.getCsn (tenant, features)
|
|
188
|
+
const nsn = cds.compile.for.nodejs(csn)
|
|
189
|
+
if (cds.edmxs) await cds.compile.to.edmx.files ( csn,
|
|
190
|
+
// adding tenant and features to runtime model, for later use when fetching generated files
|
|
191
|
+
nsn.tenant = tenant,
|
|
192
|
+
nsn.features = features.join()
|
|
193
|
+
)
|
|
194
|
+
return nsn
|
|
188
195
|
}
|
|
189
196
|
|
|
190
197
|
|
package/lib/utils/cds-test.js
CHANGED
|
@@ -53,6 +53,7 @@ class Test extends require('./axios') {
|
|
|
53
53
|
|
|
54
54
|
// launch cds server...
|
|
55
55
|
before (async ()=>{
|
|
56
|
+
process.env.cds_test_temp = cds.utils.path.resolve(cds.root,'_out',''+process.pid)
|
|
56
57
|
if (!args.includes('--port')) args.push('--port', '0')
|
|
57
58
|
let { server, url } = await cds.exec(...args)
|
|
58
59
|
this.server = server
|
|
@@ -66,6 +67,7 @@ class Test extends require('./axios') {
|
|
|
66
67
|
// delete cds.services
|
|
67
68
|
// delete cds.plugins
|
|
68
69
|
// delete cds.env
|
|
70
|
+
return cds.utils.rimraf(process.env.cds_test_temp)
|
|
69
71
|
})
|
|
70
72
|
|
|
71
73
|
return this
|