@sap/cds 7.2.1 → 7.3.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 +168 -126
- package/README.md +1 -1
- package/apis/core.d.ts +6 -4
- package/apis/services.d.ts +24 -4
- package/apis/test.d.ts +24 -10
- package/bin/serve.js +4 -3
- package/lib/auth/ias-auth.js +7 -8
- package/lib/compile/cdsc.js +5 -7
- package/lib/compile/etc/csv.js +22 -11
- package/lib/compile/for/lean_drafts.js +1 -1
- package/lib/dbs/cds-deploy.js +1 -2
- package/lib/env/cds-env.js +26 -20
- package/lib/env/defaults.js +4 -3
- package/lib/env/schema.js +9 -0
- package/lib/i18n/localize.js +83 -77
- package/lib/index.js +6 -2
- package/lib/linked/classes.js +13 -13
- package/lib/plugins.js +41 -45
- package/lib/req/user.js +2 -2
- package/lib/srv/protocols/_legacy.js +0 -1
- package/lib/srv/protocols/odata-v4.js +4 -0
- package/lib/utils/axios.js +7 -1
- package/lib/utils/cds-test.js +140 -133
- package/lib/utils/cds-utils.js +10 -3
- package/lib/utils/check-version.js +6 -0
- package/lib/utils/data.js +19 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +20 -19
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +10 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +2 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +0 -14
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/OdataRequest.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/BatchRequestListBuilder.js +5 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/handler/MetadataHandler.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/handler/ServiceHandler.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DispatcherCommand.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/utils/BufferedWriter.js +1 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +1 -1
- package/libx/_runtime/common/composition/update.js +18 -2
- package/libx/_runtime/common/error/frontend.js +46 -34
- package/libx/_runtime/common/generic/auth/capabilities.js +33 -14
- package/libx/_runtime/common/generic/input.js +1 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +3 -3
- package/libx/_runtime/db/query/update.js +48 -30
- package/libx/_runtime/fiori/lean-draft.js +2 -3
- package/libx/_runtime/hana/conversion.js +3 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/getTenantInfo.js +1 -1
- package/libx/_runtime/messaging/outbox/utils.js +1 -1
- package/libx/_runtime/remote/Service.js +1 -17
- package/libx/_runtime/remote/utils/client.js +3 -3
- package/libx/_runtime/remote/utils/data.js +5 -7
- package/libx/odata/{grammar.pegjs → grammar.peggy} +1 -1
- package/libx/odata/metadata.js +121 -0
- package/libx/odata/parser.js +1 -1
- package/libx/odata/service-document.js +61 -0
- package/libx/odata/utils.js +102 -48
- package/libx/rest/RestAdapter.js +2 -2
- package/libx/rest/middleware/error.js +1 -1
- package/package.json +1 -1
package/lib/i18n/localize.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const cds = require
|
|
1
|
+
const cds = require('..')
|
|
2
2
|
const {existsSync, readdirSync} = require ('fs')
|
|
3
3
|
const {join,dirname,resolve,parse,sep} = require ('path')
|
|
4
4
|
|
|
@@ -6,68 +6,75 @@ const DEBUG = cds.debug('i18n')
|
|
|
6
6
|
const _node_modules = cds.env.cdsc.moduleLookupDirectories.map(d => sep+d.slice(0, -1))
|
|
7
7
|
|
|
8
8
|
module.exports = Object.assign (localize, {
|
|
9
|
-
bundles4, folders4, folder4, bundle4
|
|
9
|
+
localize, lookup, bundles4, folders4, folder4, bundle4
|
|
10
10
|
})
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Can be used like that:
|
|
14
|
+
* @example cds.i18n.lookup('CreatedAt','de')
|
|
15
|
+
*/
|
|
16
|
+
function lookup (key, locale, model = cds.context?.model || cds.model) {
|
|
17
|
+
let bundle = bundle4 (model, locale)
|
|
18
|
+
return bundle?.[key]
|
|
19
|
+
}
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Can be used like that:
|
|
23
|
+
* @example cds.localize(edmx,'de')
|
|
24
|
+
*/
|
|
25
|
+
function localize (aString, locale, model = cds.context?.model || cds.model, ext={}) {
|
|
15
26
|
|
|
16
|
-
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
// support for legacy signature
|
|
28
|
+
if (typeof aString === 'object') [ aString, model ] = [ model, aString ]
|
|
29
|
+
|
|
30
|
+
// in case of multiple locales, return a generator
|
|
31
|
+
if (Array.isArray(locale)) return (function*(){
|
|
32
|
+
let localized, bundles = bundles4 (model, locale)
|
|
33
|
+
if (bundles?.[Symbol.iterator]) for (let [lang,each] of bundles) {
|
|
34
|
+
localized = _localize_with (each)
|
|
35
|
+
yield [ localized, {lang} ]
|
|
36
|
+
}
|
|
37
|
+
if (!localized) yield [ aString, {lang:''} ]
|
|
38
|
+
})()
|
|
39
|
+
|
|
40
|
+
// otherwise return a single localized string
|
|
41
|
+
let bundle = bundle4 (model, locale)
|
|
42
|
+
return _localize_with (bundle)
|
|
43
|
+
|
|
44
|
+
function _localize_with (bundle) {
|
|
45
|
+
if (!bundle || !aString) return aString
|
|
46
|
+
if (typeof aString === 'object') aString = JSON.stringify(aString)
|
|
47
|
+
const escape = aString.startsWith('<?xml') ? escapeXmlAttr : /^[{[]/.test(aString) ? escapeJson : v=>v
|
|
48
|
+
return aString.replace (/{i18n>([^}]+)}/g, (_, key) => {
|
|
49
|
+
const val = ext[key] || bundle[key]
|
|
50
|
+
return !val ? key : escape(val)
|
|
51
|
+
})
|
|
27
52
|
}
|
|
28
53
|
}
|
|
29
54
|
|
|
30
|
-
const TEXT_KEY_MARKER = 'i18n>'
|
|
31
|
-
const TEXT_KEYS = /{b?i18n>([^"}]+)}/g
|
|
32
|
-
function localizeString (aString, bundle, extBundle) {
|
|
33
|
-
if (!bundle || !aString) return aString
|
|
34
|
-
if (typeof aString === 'object') aString = JSON.stringify(aString, null, 2)
|
|
35
|
-
// quick check for presence of any text key, to avoid expensive operation below
|
|
36
|
-
if (!aString.includes(TEXT_KEY_MARKER)) return aString
|
|
37
|
-
const escape = aString.startsWith('<?xml') ? escapeXmlAttr : /^[{[]/.test(aString) ? escapeJson : v=>v
|
|
38
|
-
return aString.replace (TEXT_KEYS, (_, key) => {
|
|
39
|
-
const val = (extBundle && extBundle[key]) || bundle[key]
|
|
40
|
-
return val ? escape(val) : key
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
55
|
|
|
44
56
|
|
|
45
57
|
/**
|
|
46
58
|
* Returns all property bundles, i.e. one for each available translation language,
|
|
47
59
|
* for the given model.
|
|
48
60
|
*/
|
|
49
|
-
function bundles4 (model, locales) {
|
|
50
|
-
|
|
51
|
-
const folders = folders4 (model)
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
// if no languages are specified, use all available
|
|
57
|
-
if (locales.length === 1 && (locales[0] === '*' || locales[0] === 'all')) {
|
|
58
|
-
locales = allLocales4 (folders)
|
|
59
|
-
if (!locales) return {}
|
|
61
|
+
function bundles4 (model, locales = cds.env.i18n.languages) {
|
|
62
|
+
|
|
63
|
+
const folders = folders4 (model); if (folders.length === 0) return
|
|
64
|
+
|
|
65
|
+
if (locales.split) locales = locales.split(',')
|
|
66
|
+
if (locales[0] === '*' || locales[0] === 'all') {
|
|
67
|
+
locales = allLocales4 (folders); if (!locales) return {}
|
|
60
68
|
if (!locales.includes(cds.env.i18n.fallback_bundle)) locales.push (cds.env.i18n.fallback_bundle)
|
|
61
69
|
}
|
|
62
|
-
|
|
70
|
+
|
|
71
|
+
DEBUG?.('Languages:', locales)
|
|
63
72
|
|
|
64
73
|
return (function*(){
|
|
65
74
|
for (let each of locales) {
|
|
66
|
-
let bundle = bundle4 (model, each)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
yield [ each, bundle ]
|
|
70
|
-
}
|
|
75
|
+
let bundle = bundle4 (model, each); if(!bundle) continue
|
|
76
|
+
DEBUG?.(bundle)
|
|
77
|
+
yield [ each, bundle ]
|
|
71
78
|
}
|
|
72
79
|
})()
|
|
73
80
|
}
|
|
@@ -79,13 +86,13 @@ function bundles4 (model, locales) { // NOSONAR
|
|
|
79
86
|
*/
|
|
80
87
|
function allLocales4 (folders) {
|
|
81
88
|
// find all languages in all folders
|
|
82
|
-
const files = folders
|
|
83
|
-
.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
const files = folders.map (folder => readdirSync(folder)
|
|
90
|
+
.filter (e => e.startsWith(cds.env.i18n.file))
|
|
91
|
+
.map(i18nFile => join (folder, i18nFile))
|
|
92
|
+
).reduce ((files, file) => files.concat(file)) // flatten
|
|
93
|
+
|
|
87
94
|
if (files.length === 0) {
|
|
88
|
-
DEBUG
|
|
95
|
+
DEBUG?.('No languages for folders:', folders)
|
|
89
96
|
return null
|
|
90
97
|
}
|
|
91
98
|
|
|
@@ -117,17 +124,26 @@ function allLocales4 (folders) {
|
|
|
117
124
|
*/
|
|
118
125
|
function bundle4 (model, locale) {
|
|
119
126
|
|
|
120
|
-
|
|
127
|
+
if (typeof model === 'string') [ model, locale ] = [ cds.context?.model || cds.model, model ]
|
|
128
|
+
|
|
129
|
+
const bundles = model.texts || Object.defineProperty (model,'texts',{value:{}}).texts
|
|
130
|
+
if (locale in bundles) return bundles[locale]
|
|
131
|
+
|
|
121
132
|
const bundle = {}
|
|
133
|
+
const folders = folders4(model)
|
|
134
|
+
try {
|
|
135
|
+
if (!folders.length) return bundle
|
|
136
|
+
|
|
137
|
+
add (cds.env.i18n.fallback_bundle) // e.g. i18n.properties
|
|
138
|
+
if (locale === cds.env.i18n.fallback_bundle) return bundle
|
|
122
139
|
|
|
123
|
-
|
|
124
|
-
|
|
140
|
+
add (cds.env.i18n.default_language) // e.g. i18n_en.properties
|
|
141
|
+
if (locale === cds.env.i18n.default_language) return bundle
|
|
125
142
|
|
|
126
|
-
|
|
127
|
-
|
|
143
|
+
add (locale) // e.g. i18n_de.properties
|
|
144
|
+
return bundle
|
|
128
145
|
|
|
129
|
-
|
|
130
|
-
return bundle
|
|
146
|
+
} finally { bundles[locale] = bundle }
|
|
131
147
|
|
|
132
148
|
function add (lang) {
|
|
133
149
|
for (let each of folders) {
|
|
@@ -154,18 +170,16 @@ function folders4 (model) {
|
|
|
154
170
|
// foo/bar.cds
|
|
155
171
|
// foo/node_modules/reuse-level-1/model.cds
|
|
156
172
|
// foo/node_modules/reuse-level-2/model.cds
|
|
157
|
-
|
|
158
|
-
const srcFolders = new Set (model.$sources.map
|
|
159
|
-
const folders = []
|
|
173
|
+
const folders = [] // using an array here to not screw up the folder order
|
|
174
|
+
const srcFolders = new Set ((model.$sources||[]).map(dirname))
|
|
160
175
|
srcFolders.forEach(src => {
|
|
161
|
-
|
|
176
|
+
const folder = folder4 (src)
|
|
162
177
|
if (folder && !folders.includes(folder)) {
|
|
163
|
-
folders.push(folder)
|
|
178
|
+
folders.push(folder)
|
|
164
179
|
}
|
|
165
180
|
})
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return folders.reverse()
|
|
181
|
+
Object.defineProperty (model, '_i18nfolders', {value:folders.reverse()})
|
|
182
|
+
return folders
|
|
169
183
|
}
|
|
170
184
|
|
|
171
185
|
/**
|
|
@@ -202,7 +216,7 @@ function loadFromJSON (res, lang=cds.env.i18n.default_language) {
|
|
|
202
216
|
const bundles = require (resolve (cds.root,res+'.json'))
|
|
203
217
|
return bundles[lang] || bundles [(lang.match(/\w+/)||[])[0]]
|
|
204
218
|
} catch(e) {
|
|
205
|
-
if (e.code !== 'MODULE_NOT_FOUND')
|
|
219
|
+
if (e.code !== 'MODULE_NOT_FOUND') throw e
|
|
206
220
|
}
|
|
207
221
|
}
|
|
208
222
|
|
|
@@ -231,17 +245,9 @@ function escapeXmlAttr (str) {
|
|
|
231
245
|
.replace(/</g, '<')
|
|
232
246
|
.replace(/"/g, '"')
|
|
233
247
|
.replace(/\r\n|\n/g, '
');
|
|
234
|
-
if (!result.startsWith('{i18n>')
|
|
235
|
-
result = result.replace(/>/g, '>')
|
|
248
|
+
if (!result.startsWith('{i18n>')) result = result.replace(/>/g, '>')
|
|
236
249
|
}
|
|
237
250
|
return result;
|
|
238
251
|
}
|
|
239
252
|
|
|
240
|
-
|
|
241
|
-
.replace(/"/g, '\\"')
|
|
242
|
-
.replace(/\\t/g, '\\t')
|
|
243
|
-
.replace(/\\n/g, '\\n')
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
/* eslint no-console:off */
|
|
253
|
+
const escapeJson = str => str.replace(/"/g, '\\"')
|
package/lib/index.js
CHANGED
|
@@ -7,9 +7,10 @@ const cds = module.exports = new class cds extends EventEmitter {
|
|
|
7
7
|
|
|
8
8
|
// Configuration & Information
|
|
9
9
|
get requires() { return super.requires = this.env.requires._resolved() }
|
|
10
|
-
get plugins() { return super.plugins = require('./plugins') }
|
|
10
|
+
get plugins() { return super.plugins = require('./plugins').activate() }
|
|
11
11
|
get version() { return super.version = require('../package.json').version }
|
|
12
12
|
get env() { return super.env = require('./env/cds-env').for('cds',this.root) }
|
|
13
|
+
get schema() { return super.schema = require('./env/schema') } // dynamic schema loading
|
|
13
14
|
get home() { return super.home = __dirname.slice(0,-4) }
|
|
14
15
|
cli = { command:'', options:{}, argv:[] }
|
|
15
16
|
root = process.cwd()
|
|
@@ -25,7 +26,6 @@ const cds = module.exports = new class cds extends EventEmitter {
|
|
|
25
26
|
get extend() { return super.extend = require('./compile/extend') }
|
|
26
27
|
get deploy() { return super.deploy = require('./dbs/cds-deploy') }
|
|
27
28
|
get localize() { return super.localize = require('./i18n/localize') }
|
|
28
|
-
get build() { return () => { throw new Error('This application uses @sap/cds version >= 7, which is not compatible with the installed @sap/cds-dk version 6. Either update @sap/cds-dk to version 7 or downgrade @sap/cds to version 6 instead.') } }
|
|
29
29
|
/** @type {{definitions:{},extensions:[]}} */ model = undefined
|
|
30
30
|
/** @type Service */ db = undefined
|
|
31
31
|
|
|
@@ -116,6 +116,10 @@ const cds = module.exports = new class cds extends EventEmitter {
|
|
|
116
116
|
|
|
117
117
|
// legacy and to be moved stuff -> hidden for tools in cds.__proto__
|
|
118
118
|
/** @deprecated */ in (cwd) { return !cwd ? this : {__proto__:this, cwd, env: this.env.for('cds',cwd) } }
|
|
119
|
+
get build() { return () => cds.error('\
|
|
120
|
+
This application uses @sap/cds version >= 7, which is not compatible with the installed @sap/cds-dk version 6. \
|
|
121
|
+
Either update @sap/cds-dk to version 7 or downgrade @sap/cds to version 6 instead.\
|
|
122
|
+
')}
|
|
119
123
|
}
|
|
120
124
|
|
|
121
125
|
// add global cds.ql commands
|
package/lib/linked/classes.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
const { serve_on_root } = global.cds?.env.features || {}
|
|
2
|
-
const { middlewares } = global.cds?.env.requires || {}
|
|
3
|
-
const { protocols: envProtocols } = global.cds?.env || {}
|
|
4
1
|
const { extend } = require('../lazy')
|
|
5
2
|
|
|
6
3
|
class any {
|
|
@@ -79,7 +76,7 @@ class service extends context {
|
|
|
79
76
|
|
|
80
77
|
// Return a sluggified variant of the service's name
|
|
81
78
|
const pathFromServiceName4 = (srv) => {
|
|
82
|
-
return (
|
|
79
|
+
return (
|
|
83
80
|
/[^.]+$/.exec(srv.name)[0] //> my.very.CatalogService --> CatalogService
|
|
84
81
|
.replace(/Service$/,'') //> CatalogService --> Catalog
|
|
85
82
|
.replace(/_/g,'-') //> foo_bar_baz --> foo-bar-baz
|
|
@@ -87,7 +84,7 @@ class service extends context {
|
|
|
87
84
|
.toLowerCase() //> FOO --> foo
|
|
88
85
|
)
|
|
89
86
|
}
|
|
90
|
-
|
|
87
|
+
|
|
91
88
|
// Return an array of service paths for a given service and protocol.
|
|
92
89
|
// The results are not prefixed with the protocol's path.
|
|
93
90
|
// Can return multiple results to support serving the same protocol on multiple paths:
|
|
@@ -108,10 +105,10 @@ class service extends context {
|
|
|
108
105
|
else paths.push(def['@path'] || pathFromServiceName4(srv))
|
|
109
106
|
}
|
|
110
107
|
}
|
|
111
|
-
|
|
108
|
+
|
|
112
109
|
// in case protocol is set via options.at but not contained in @protocol
|
|
113
110
|
if (paths.length === 0) paths.push(def['@path'] || pathFromServiceName4(srv))
|
|
114
|
-
|
|
111
|
+
|
|
115
112
|
return paths
|
|
116
113
|
}
|
|
117
114
|
|
|
@@ -125,15 +122,18 @@ class service extends context {
|
|
|
125
122
|
throw new Error(`Absolute @path (starting with '/') cannot be set for more than one protocol`)
|
|
126
123
|
}
|
|
127
124
|
|
|
128
|
-
const endpoints = []
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
125
|
+
const endpoints = [], env_protocols = global.cds?.env.protocols
|
|
126
|
+
const serve_on_root = global.cds?.env.features.serve_on_root
|
|
127
|
+
|
|
128
|
+
for (let each of protocols) {
|
|
129
|
+
let p = this._protocols[each] || env_protocols[each]
|
|
130
|
+
if (!p) throw new Error(`Protocol "${each}" is unknown`)
|
|
132
131
|
|
|
133
|
-
const
|
|
132
|
+
const middlewares = global.cds?.requires.middlewares
|
|
133
|
+
const kind = each
|
|
134
134
|
let prefix = middlewares ? p.path || '/' : '/' // > no middlewares, no prefix
|
|
135
135
|
if (!prefix.endsWith('/')) prefix += '/'
|
|
136
|
-
const unprefixedPaths = unprefixedPaths4(
|
|
136
|
+
const unprefixedPaths = unprefixedPaths4(each, srv, options)
|
|
137
137
|
for (let path of unprefixedPaths) {
|
|
138
138
|
if (path.startsWith('/')) endpoints.push({ kind, path})
|
|
139
139
|
else {
|
package/lib/plugins.js
CHANGED
|
@@ -1,49 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
const DEBUG = /\by|all|plugins\b/.test(process.env.DEBUG)
|
|
3
|
-
const cds = require('.'), { local } = cds.utils
|
|
1
|
+
const cds = require('.')
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Fetch cds-plugins from project's package dependencies.
|
|
5
|
+
* Used in and made available through cds.env.plugins.
|
|
6
|
+
*/
|
|
7
|
+
exports.fetch = function (DEV = process.env.NODE_ENV !== 'production') {
|
|
8
8
|
const plugins = {}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
fetch_plugins_in (cds.home, false)
|
|
10
|
+
fetch_plugins_in (cds.root, DEV)
|
|
11
|
+
function fetch_plugins_in (root, dev) {
|
|
12
|
+
let pkg; try { pkg = require(root + '/package.json') } catch { return }
|
|
13
|
+
let deps = { ...pkg.dependencies, ...dev && pkg.devDependencies }
|
|
14
|
+
for (let each in deps) try {
|
|
15
|
+
let impl = require.resolve(each + '/cds-plugin', { paths: [root] })
|
|
16
|
+
plugins[each] = { impl }
|
|
17
|
+
} catch { /* no cds-plugin.js */ }
|
|
18
|
+
}
|
|
17
19
|
return plugins
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
function _load_plugin (name, impl, conf) {
|
|
40
|
-
plugins[name] = async() => {
|
|
41
|
-
// TODO support ESM plugins. But see cap/cds/pull/1838#issuecomment-1177200 !
|
|
42
|
-
const plugin = plugins[name] = require(impl)
|
|
43
|
-
if (DEBUG) log('[cds] - loaded plugin:', { impl: local(impl) })
|
|
44
|
-
if (plugin.activate) await plugin.activate(conf)
|
|
45
|
-
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Load and activate cds-plugins from project's package dependencies.
|
|
24
|
+
* Used in and made available through cds.plugins.
|
|
25
|
+
*/
|
|
26
|
+
exports.activate = async function () {
|
|
27
|
+
const DEBUG = cds.debug ('plugins', {label:'cds'})
|
|
28
|
+
DEBUG && console.time ('[cds] - loaded plugins in')
|
|
29
|
+
const { plugins } = cds.env, { local } = cds.utils
|
|
30
|
+
await Promise.all (Object.entries(plugins) .map (async ([ plugin, conf ]) => {
|
|
31
|
+
DEBUG?.(`loading plugin ${plugin}:`, { impl: local(conf.impl) })
|
|
32
|
+
// TODO: support ESM plugins. But see cap/cds/pull/1838#issuecomment-1177200 !
|
|
33
|
+
const p = require (conf.impl)
|
|
34
|
+
if(p.activate) {
|
|
35
|
+
cds.log('plugins').warn(`WARNING: \n
|
|
36
|
+
Returning an 'activate' function is deprecated and won't be
|
|
37
|
+
supported in future releases. → Please return a Promise with 'module.exports' instead.
|
|
38
|
+
`)
|
|
39
|
+
await p.activate(conf)
|
|
46
40
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
return p
|
|
42
|
+
}))
|
|
43
|
+
DEBUG && console.timeEnd ('[cds] - loaded plugins in')
|
|
44
|
+
return plugins
|
|
45
|
+
}
|
package/lib/req/user.js
CHANGED
|
@@ -13,9 +13,9 @@ class User {
|
|
|
13
13
|
get attr() { return super.attr = {} }
|
|
14
14
|
set attr(a) { super.attr = a }
|
|
15
15
|
|
|
16
|
-
get roles(){ return super.roles = {} }
|
|
16
|
+
get roles() { return super.roles = {} }
|
|
17
17
|
set roles(r) {
|
|
18
|
-
super.roles =
|
|
18
|
+
super.roles = Array.isArray(r) ? r.reduce((p, n) => { p[n]=1; return p }, {}) : r
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
is (role) {
|
|
@@ -17,7 +17,6 @@ class LegacyProtocolAdapter extends ProtocolAdapter {
|
|
|
17
17
|
|
|
18
18
|
static serve (srv, /* in: */ app) {
|
|
19
19
|
return super.serve (srv, app, { before: [
|
|
20
|
-
// async (req, res, next) => { await 1; next() }, // REVISIT: AsyncResource.bind() -> enable to break cds/tests/_runtime/odata/__tests__/integration/crud-with-mtx.test.js with existing, non-middleware mode, *w/o* fix to BufferedWriter
|
|
21
20
|
cds_context,
|
|
22
21
|
libx.perf,
|
|
23
22
|
libx.auth(srv),
|
|
@@ -17,5 +17,9 @@ module.exports = function ODataAdapter (srv) { return [
|
|
|
17
17
|
|
|
18
18
|
next()
|
|
19
19
|
},
|
|
20
|
+
...cds.env.features.odata_new_adapter ? [
|
|
21
|
+
require('../../../libx/odata/service-document')(srv),
|
|
22
|
+
require('../../../libx/odata/metadata')(srv),
|
|
23
|
+
] : [],
|
|
20
24
|
libx.to.odata_v4 (srv)
|
|
21
25
|
]}
|
package/lib/utils/axios.js
CHANGED
|
@@ -2,10 +2,16 @@ class Axios {
|
|
|
2
2
|
|
|
3
3
|
get axios() {
|
|
4
4
|
// eslint-disable-next-line cds/no-missing-dependencies
|
|
5
|
-
|
|
5
|
+
const axios = require('axios').create ({
|
|
6
6
|
headers: { 'Content-Type': 'application/json' },
|
|
7
7
|
baseURL: this.url,
|
|
8
8
|
})
|
|
9
|
+
// fill in baseURL on subsequent this.url = url, after server has started
|
|
10
|
+
Reflect.defineProperty (this, 'url', { configurable: true, set: url => {
|
|
11
|
+
Reflect.defineProperty (this, 'url', { value: url })
|
|
12
|
+
axios.defaults.baseURL = url
|
|
13
|
+
}})
|
|
14
|
+
return super.axios = axios
|
|
9
15
|
}
|
|
10
16
|
get (..._) { return this.axios.get (..._args(_)) .catch(_error) }
|
|
11
17
|
put (..._) { return this.axios.put (..._args(_)) .catch(_error) }
|