@sap/cds 6.1.1 → 6.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -1
- package/apis/log.d.ts +111 -33
- package/apis/services.d.ts +13 -2
- package/lib/index.js +1 -1
- package/lib/log/format/kibana.js +19 -1
- package/lib/ql/UPDATE.js +2 -2
- package/lib/ql/cds-ql.js +4 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +2 -1
- package/libx/_runtime/common/utils/keys.js +14 -6
- package/libx/_runtime/db/expand/expandCQNToJoin.js +1 -1
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
- package/libx/_runtime/extensibility/token.js +2 -1
- package/libx/_runtime/fiori/utils/where.js +1 -1
- package/libx/_runtime/messaging/common-utils/authorizedRequest.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +1 -2
- package/libx/odata/cqn2odata.js +6 -2
- package/package.json +1 -1
- package/srv/model-provider.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,11 +4,32 @@
|
|
|
4
4
|
- The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
5
5
|
- This project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
|
+
## Version 6.1.2 - 2022-09-05
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Missing key insertion from where clauses in references for deep update statements
|
|
12
|
+
- Prevent duplicate entries for some `INSERT` statements
|
|
13
|
+
- Log details were not properly displayed in Kibana
|
|
14
|
+
- getCsn in model-provider if `cds.requires.toggles` is false
|
|
15
|
+
- HTTP calls in messaging have the correct content length
|
|
16
|
+
- Performance issue for OData <entity>/$count requests
|
|
17
|
+
- Typescript definition for SQL-native variant of `srv.run`, like `srv.run('SELECT * from Authors where name like ?',['%Poe%'])`
|
|
18
|
+
- Typescript definitions for `srv.run( [query] )` and `srv.send( {query, headers} )`
|
|
19
|
+
- Typescript definitions for `cds.log` are improved, level indicators like `cds.log()._debug` added
|
|
20
|
+
- Typescript definitions for `tx` now carry additional service methods
|
|
21
|
+
- `cds login` now returns errors with a better root cause messages
|
|
22
|
+
- `$expand` requests for to-one associations that do not select the foreign key
|
|
23
|
+
- `UPDATE` statement accepts empty objects: `UPDATE('Foo').with({ bar: {} })`
|
|
24
|
+
- URI encoding of parameters in remote service calls
|
|
25
|
+
|
|
26
|
+
### Removed
|
|
27
|
+
|
|
7
28
|
## Version 6.1.1 - 2022-08-24
|
|
8
29
|
|
|
9
30
|
### Added
|
|
10
|
-
- The configuration schema now includes `cds.extends` and `new-fields` (in `cds.xt.ExtensibilityService`)
|
|
11
31
|
|
|
32
|
+
- The configuration schema now includes `cds.extends` and `new-fields` (in `cds.xt.ExtensibilityService`)
|
|
12
33
|
- `srv.run(fn)` now accepts a function as first argument, which will be run in an active outer transaction, if any, or in a newly created one. This is in contrast to `srv.tx(fn)` which always creates a new tx.
|
|
13
34
|
```js
|
|
14
35
|
cds.run (tx => { // nested operations are guaranteed to run in a tx
|
package/apis/log.d.ts
CHANGED
|
@@ -1,44 +1,122 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a trace logger for the given module if trace is switched on for it,
|
|
3
|
-
* otherwise returns null. All cds runtime packages use this method for their
|
|
4
|
-
* trace and debug output.
|
|
5
|
-
*
|
|
6
|
-
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-log)
|
|
7
|
-
*
|
|
8
|
-
* By default this logger would prefix all output with '[sql] - '.
|
|
9
|
-
* You can change this by specifying another prefix in the options:
|
|
10
|
-
*
|
|
11
|
-
* const LOG = cds.log('sql|db',{ prefix:'cds.ql' })
|
|
12
|
-
*
|
|
13
|
-
* Call cds.log() for a given module again to dynamically change the log level
|
|
14
|
-
* of all formerly created loggers, for example:
|
|
15
|
-
*
|
|
16
|
-
* const LOG = cds.log('sql')
|
|
17
|
-
* LOG.info ('this will show, as default level is info')
|
|
18
|
-
* cds.log('sql','warn')
|
|
19
|
-
* LOG.info ('this will be suppressed now')
|
|
20
|
-
*
|
|
21
|
-
*/
|
|
22
1
|
export = cds
|
|
23
2
|
declare class cds {
|
|
24
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Create a new logger, or install a custom log formatter
|
|
5
|
+
*/
|
|
6
|
+
log: LogFactory
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Shortcut to `cds.log(...).debug`, returning `undefined` if `cds.log(...)._debug` is `false`.
|
|
10
|
+
* Use like this:
|
|
11
|
+
* ```
|
|
12
|
+
* const dbg = cds.debug('foo')
|
|
13
|
+
* ...
|
|
14
|
+
* dbg && dbg('message')
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @param name logger name
|
|
18
|
+
*/
|
|
19
|
+
debug(name: string): undefined | Log
|
|
25
20
|
}
|
|
26
21
|
|
|
27
|
-
declare
|
|
22
|
+
declare type LogFactory = {
|
|
23
|
+
/**
|
|
24
|
+
* Returns a trace logger for the given module if trace is switched on for it,
|
|
25
|
+
* otherwise returns null. All cds runtime packages use this method for their
|
|
26
|
+
* trace and debug output.
|
|
27
|
+
*
|
|
28
|
+
* By default this logger would prefix all output with `[sql] - `
|
|
29
|
+
* You can change this by specifying another prefix in the options:
|
|
30
|
+
* ```
|
|
31
|
+
* const LOG = cds.log('sql|db',{ prefix:'cds.ql' })
|
|
32
|
+
* ```
|
|
33
|
+
* Call `cds.log()` for a given module again to dynamically change the log level
|
|
34
|
+
* of all formerly created loggers, for example:
|
|
35
|
+
* ```
|
|
36
|
+
* const LOG = cds.log('sql')
|
|
37
|
+
* LOG.info ('this will show, as default level is info')
|
|
38
|
+
* cds.log('sql','warn')
|
|
39
|
+
* LOG.info ('this will be suppressed now')
|
|
40
|
+
* ```
|
|
41
|
+
* @param name logger name
|
|
42
|
+
* @param options level and prefix
|
|
43
|
+
* @returns the logger
|
|
44
|
+
*
|
|
45
|
+
* @see [capire](https://cap.cloud.sap/docs/node.js/cds-log)
|
|
46
|
+
*/
|
|
47
|
+
(name: string, options?: string | number | { level?: number, prefix?: string }): Logger
|
|
48
|
+
|
|
28
49
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
50
|
+
* Set a custom formatter function like that:
|
|
51
|
+
* ```
|
|
52
|
+
* cds.log.format = (module, level, ...args) => [ '[', module, ']', ...args ]
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* The formatter shall return an array of arguments, which are passed to the logger (for example, `console.log()`)
|
|
32
56
|
*
|
|
33
|
-
*
|
|
57
|
+
* @param module logger name
|
|
58
|
+
* @param level log level
|
|
59
|
+
* @param args additional arguments
|
|
34
60
|
*/
|
|
35
61
|
format(module: string, level: number, args: any[]): any[]
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare class Logger {
|
|
65
|
+
/**
|
|
66
|
+
* Logs with 'trace' level
|
|
67
|
+
*/
|
|
68
|
+
trace: Log
|
|
69
|
+
/**
|
|
70
|
+
* Logs with 'debug' level
|
|
71
|
+
*/
|
|
72
|
+
debug: Log
|
|
73
|
+
/**
|
|
74
|
+
* Logs with 'info' level
|
|
75
|
+
*/
|
|
76
|
+
info: Log
|
|
77
|
+
/**
|
|
78
|
+
* Logs with 'warn' level
|
|
79
|
+
*/
|
|
80
|
+
warn: Log
|
|
81
|
+
/**
|
|
82
|
+
* Logs with 'error' level
|
|
83
|
+
*/
|
|
84
|
+
error: Log
|
|
85
|
+
/**
|
|
86
|
+
* Logs with default level
|
|
87
|
+
*/
|
|
88
|
+
log: Log
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @returns whether 'trace' level is active
|
|
92
|
+
*/
|
|
93
|
+
_trace: boolean
|
|
94
|
+
/**
|
|
95
|
+
* @returns whether 'debug' level is active
|
|
96
|
+
*/
|
|
97
|
+
_debug: boolean
|
|
98
|
+
/**
|
|
99
|
+
* @returns whether 'info' level is active
|
|
100
|
+
*/
|
|
101
|
+
_info: boolean
|
|
102
|
+
/**
|
|
103
|
+
* @returns whether 'warn' level is active
|
|
104
|
+
*/
|
|
105
|
+
_warn: boolean
|
|
106
|
+
/**
|
|
107
|
+
* @returns whether 'error' level is active
|
|
108
|
+
*/
|
|
109
|
+
_error: boolean
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
declare type Log = {
|
|
113
|
+
/**
|
|
114
|
+
* Logs a message
|
|
115
|
+
*
|
|
116
|
+
* @param message text to log
|
|
117
|
+
* @param optionalParams additional parameters, same as in `console.log(text, param1, ...)`
|
|
118
|
+
*/
|
|
119
|
+
(message?: any, ...optionalParams: any[]): void
|
|
42
120
|
}
|
|
43
121
|
|
|
44
122
|
declare enum levels {
|
package/apis/services.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export class QueryAPI {
|
|
|
34
34
|
/**
|
|
35
35
|
* @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
|
|
36
36
|
*/
|
|
37
|
-
run (query : ConstructedQuery) : Promise<ResultSet | any>
|
|
37
|
+
run (query : ConstructedQuery|ConstructedQuery[]) : Promise<ResultSet | any>
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
|
|
@@ -42,6 +42,11 @@ export class QueryAPI {
|
|
|
42
42
|
run (query : Query) : Promise<ResultSet | any>
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
+
* @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run-sql)
|
|
46
|
+
*/
|
|
47
|
+
run (query : string, args? : any[]|object) : Promise<ResultSet | any>
|
|
48
|
+
|
|
49
|
+
/**
|
|
45
50
|
* @see [docs](https://cap.cloud.sap/docs/node.js/services#srv-run)
|
|
46
51
|
*/
|
|
47
52
|
foreach (query : Query, callback: (row:object) => void) : this
|
|
@@ -141,6 +146,12 @@ export class Service extends QueryAPI {
|
|
|
141
146
|
send (details: { event: Events, data?: object, headers?: object }) : Promise<this>
|
|
142
147
|
|
|
143
148
|
/**
|
|
149
|
+
* Constructs and sends a synchronous request.
|
|
150
|
+
* @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
|
|
151
|
+
*/
|
|
152
|
+
send (details: { query: ConstructedQuery, headers?: object }) : Promise<this>
|
|
153
|
+
|
|
154
|
+
/**
|
|
144
155
|
* Constructs and sends a GET request.
|
|
145
156
|
* @see [capire docs](https://cap.cloud.sap/docs/node.js/services#srv-send)
|
|
146
157
|
*/
|
|
@@ -190,7 +201,7 @@ export class Service extends QueryAPI {
|
|
|
190
201
|
|
|
191
202
|
}
|
|
192
203
|
|
|
193
|
-
export interface Transaction extends
|
|
204
|
+
export interface Transaction extends Service {
|
|
194
205
|
commit() : Promise<void>
|
|
195
206
|
rollback() : Promise<void>
|
|
196
207
|
}
|
package/lib/index.js
CHANGED
|
@@ -73,7 +73,7 @@ const cds = module.exports = extend (new facade) .with ({
|
|
|
73
73
|
Request: require ('./req/request'),
|
|
74
74
|
Event: require ('./req/event'),
|
|
75
75
|
User: require ('./req/user'),
|
|
76
|
-
ql:
|
|
76
|
+
ql: require ('./ql/cds-ql'),
|
|
77
77
|
tx: (..._) => (cds.db || cds.Service.prototype) .tx (..._),
|
|
78
78
|
/** @type Service */ db: undefined,
|
|
79
79
|
|
package/lib/log/format/kibana.js
CHANGED
|
@@ -56,6 +56,24 @@ module.exports = (module, level, ...args) => {
|
|
|
56
56
|
if (cf.length) toLog['#cf'] = { string: cf }
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
const getCircularReplacer = () => {
|
|
60
|
+
const seen = new WeakSet()
|
|
61
|
+
return (key, value) => {
|
|
62
|
+
if (typeof value === "object" && value !== null) {
|
|
63
|
+
if (seen.has(value)) {
|
|
64
|
+
return 'cyclic'
|
|
65
|
+
}
|
|
66
|
+
seen.add(value)
|
|
67
|
+
}
|
|
68
|
+
return value
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
59
72
|
// return array with the stringified toLog (to avoid multiple log lines) as the sole element
|
|
60
|
-
|
|
73
|
+
try {
|
|
74
|
+
return [JSON.stringify(toLog)]
|
|
75
|
+
} catch (e) {
|
|
76
|
+
// try again with removed circular references
|
|
77
|
+
return [JSON.stringify(toLog, getCircularReplacer())]
|
|
78
|
+
}
|
|
61
79
|
}
|
package/lib/ql/UPDATE.js
CHANGED
|
@@ -54,8 +54,8 @@ module.exports = class UPDATE extends Whereable {
|
|
|
54
54
|
const o = args[0]
|
|
55
55
|
for (let col in o) {
|
|
56
56
|
let op = '=', v = o[col]
|
|
57
|
-
if (typeof v === 'object' && !(v === null || v.map || v.pipe || v instanceof Buffer || v instanceof Date)) {
|
|
58
|
-
let o = Object.keys(v)[0]
|
|
57
|
+
if (typeof v === 'object' && !(v === null || v.map || v.pipe || v instanceof Buffer || v instanceof Date || v instanceof RegExp)) {
|
|
58
|
+
let o = Object.keys(v)[0] //|| this._expected `${{v}} to be an object with an operator as single key`
|
|
59
59
|
if (o in operators) v = v[op=o]
|
|
60
60
|
}
|
|
61
61
|
_add (this, col, op, v && (v.val !== undefined || v.ref || v.xpr || v.func || v.SELECT) ? v : {val:v})
|
package/lib/ql/cds-ql.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const cds = require('../index')
|
|
2
|
+
const Query = require('./Query')
|
|
2
3
|
require = path => { // eslint-disable-line no-global-assign
|
|
3
4
|
const clazz = module.require (path); if (!clazz._api) return clazz
|
|
4
5
|
Object.defineProperty (clazz.prototype, 'cmd', { value: path.match(/\w+$/)[0] })
|
|
@@ -6,12 +7,14 @@ require = path => { // eslint-disable-line no-global-assign
|
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
module.exports = Object.assign (_deprecated_srv_ql, { cdr: true,
|
|
10
|
+
Query,
|
|
9
11
|
SELECT: require('./SELECT'),
|
|
10
12
|
INSERT: require('./INSERT'),
|
|
11
13
|
UPDATE: require('./UPDATE'),
|
|
12
14
|
DELETE: require('./DELETE'),
|
|
13
15
|
CREATE: require('./CREATE'),
|
|
14
16
|
DROP: require('./DROP'),
|
|
17
|
+
clone(q) { return Query.prototype.clone.call(q) }
|
|
15
18
|
})
|
|
16
19
|
|
|
17
20
|
function _deprecated_srv_ql() { // eslint-disable-next-line no-console
|
|
@@ -24,7 +27,7 @@ function _deprecated_srv_ql() { // eslint-disable-next-line no-console
|
|
|
24
27
|
|
|
25
28
|
module.exports._reset = ()=>{ // for strange tests only
|
|
26
29
|
const _name = cds.env.sql.names === 'quoted' ? n =>`"${n}"` : n => n.replace(/[.:]/g,'_')
|
|
27
|
-
Object.defineProperty (
|
|
30
|
+
Object.defineProperty (Query.prototype,'valueOf',{ configurable:1, value: function(cmd=this.cmd) {
|
|
28
31
|
return `${cmd} ${_name(this._target.name)} `
|
|
29
32
|
}})
|
|
30
33
|
return this
|
|
@@ -81,7 +81,8 @@ const _getCount = async (tx, readReq) => {
|
|
|
81
81
|
// REVISIT: this process appears to be rather clumsy
|
|
82
82
|
// Copy CQN including from, where and search + changing columns
|
|
83
83
|
const select = SELECT.from(readReq.query.SELECT.from)
|
|
84
|
-
|
|
84
|
+
// { val: 1 } is used on purpose, as "numbers" are not used as param in prepared stmt
|
|
85
|
+
select.SELECT.columns = [{ func: 'count', args: [{ val: 1 }], as: '$count' }]
|
|
85
86
|
|
|
86
87
|
if (readReq.query.SELECT.where) select.SELECT.where = readReq.query.SELECT.where
|
|
87
88
|
if (readReq.query.SELECT.search) select.SELECT.search = readReq.query.SELECT.search
|
|
@@ -27,13 +27,18 @@ function _getOnCondElements(onCond, onCondElements = []) {
|
|
|
27
27
|
return onCondElements
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
function
|
|
31
|
-
if (
|
|
30
|
+
function _mergeWhere(base, additional) {
|
|
31
|
+
if (additional?.length) {
|
|
32
32
|
// copy where else query will be modified
|
|
33
|
-
const whereCopy = deepCopyArray(
|
|
34
|
-
if (
|
|
35
|
-
|
|
33
|
+
const whereCopy = deepCopyArray(additional)
|
|
34
|
+
if (base.length > 0) base.push('and')
|
|
35
|
+
base.push(...whereCopy)
|
|
36
36
|
}
|
|
37
|
+
return base
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function _modifyWhereWithNavigations(where, newWhere, entityKey, targetKey) {
|
|
41
|
+
_mergeWhere(newWhere, where)
|
|
37
42
|
|
|
38
43
|
newWhere.forEach(element => {
|
|
39
44
|
if (element.ref && element.ref[0] === targetKey) {
|
|
@@ -85,7 +90,10 @@ function _getWhereFromUpdate(query, target, model) {
|
|
|
85
90
|
return where
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
|
|
93
|
+
const where = query.UPDATE.where || []
|
|
94
|
+
if (query.UPDATE.entity.ref?.length === 1 && query.UPDATE.entity.ref[0].where)
|
|
95
|
+
return _mergeWhere(query.UPDATE.entity.ref[0].where, where)
|
|
96
|
+
return where
|
|
89
97
|
}
|
|
90
98
|
|
|
91
99
|
// params: data, req, service/tx
|
|
@@ -696,7 +696,7 @@ class JoinCQNFromExpanded {
|
|
|
696
696
|
|
|
697
697
|
const assoc = entity.associations[column.ref[0]]
|
|
698
698
|
if (assoc.is2one && assoc.on) {
|
|
699
|
-
const onCond =
|
|
699
|
+
const onCond = entity._relations[assoc.name].join('target', 'source')
|
|
700
700
|
const xpr = onCond[0].xpr
|
|
701
701
|
const fks = (xpr && xpr.filter(e => e.ref && e.ref[0] === 'target').map(e => e.ref[1])) || []
|
|
702
702
|
for (const k of fks) {
|
|
@@ -306,7 +306,7 @@ class InsertBuilder extends BaseBuilder {
|
|
|
306
306
|
const purelyManagedColumnValues = this._getAnnotatedInsertColumnValues(annotatedColumns, purelyManagedColumns)
|
|
307
307
|
|
|
308
308
|
this._addUuidToColumns(columns, flattenColumnMap)
|
|
309
|
-
columns.push(...flattenColumnMap.keys())
|
|
309
|
+
columns.push(...Array.from(flattenColumnMap.keys()).filter(k => !columns.includes(k)))
|
|
310
310
|
|
|
311
311
|
this._addEntries(valuesArray, { columns, flattenColumnMap, purelyManagedColumnValues, insertAnnotatedColumns })
|
|
312
312
|
|
|
@@ -43,7 +43,8 @@ module.exports = {
|
|
|
43
43
|
)
|
|
44
44
|
response.send(data)
|
|
45
45
|
} catch (error) {
|
|
46
|
-
|
|
46
|
+
const rootCause = error.response?.data ? JSON.stringify(error.response?.data) : error.message
|
|
47
|
+
error.message = `Authentication failed with root cause '${rootCause}'. Passcode URL: https://${parsedUrl.hostname}/passcode`
|
|
47
48
|
const {
|
|
48
49
|
constructor: { name },
|
|
49
50
|
message
|
|
@@ -160,7 +160,7 @@ const isActiveEntityRequested = where => {
|
|
|
160
160
|
|
|
161
161
|
while (where[i]) {
|
|
162
162
|
if (where[i].xpr) {
|
|
163
|
-
const isRequested = isActiveEntityRequested(where.xpr)
|
|
163
|
+
const isRequested = isActiveEntityRequested(where[i].xpr)
|
|
164
164
|
if (isRequested) return true
|
|
165
165
|
}
|
|
166
166
|
if (
|
|
@@ -19,7 +19,7 @@ const authorizedRequest = ({ method, uri, path, oa2, tenant, dataObj, headers, t
|
|
|
19
19
|
if (dataObj) {
|
|
20
20
|
data = JSON.stringify(dataObj)
|
|
21
21
|
httpOptions.headers['Content-Type'] = 'application/json'
|
|
22
|
-
httpOptions.headers['Content-Length'] = data
|
|
22
|
+
httpOptions.headers['Content-Length'] = Buffer.byteLength(data)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
if (headers) {
|
|
@@ -34,7 +34,6 @@ class EMManagement {
|
|
|
34
34
|
this.namespace = namespace
|
|
35
35
|
this.LOG = LOG
|
|
36
36
|
}
|
|
37
|
-
|
|
38
37
|
async getQueue(queueName = this.queueName) {
|
|
39
38
|
this.LOG._info &&
|
|
40
39
|
this.LOG.info(
|
|
@@ -303,7 +302,7 @@ class EMManagement {
|
|
|
303
302
|
grantType: 'client_credentials',
|
|
304
303
|
clientId: this.optionsMessagingREST.oa2.client,
|
|
305
304
|
clientSecret: this.optionsMessagingREST.oa2.secret,
|
|
306
|
-
tokenUrl: this.optionsMessagingREST.oa2.endpoint
|
|
305
|
+
tokenUrl: this.optionsMessagingREST.oa2.endpoint // this is the changed tokenUrl
|
|
307
306
|
}
|
|
308
307
|
}
|
|
309
308
|
|
package/libx/odata/cqn2odata.js
CHANGED
|
@@ -200,8 +200,12 @@ const _keysOfWhere = (where, kind, target) => {
|
|
|
200
200
|
if (where.length === 3) {
|
|
201
201
|
const [left, op, right] = where
|
|
202
202
|
if (op === '=' && (('val' in left && right.ref) || (left.ref && 'val' in right))) {
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
const formattedValue =
|
|
204
|
+
'val' in left
|
|
205
|
+
? formatVal(left.val, right.ref.join('/'), target, kind)
|
|
206
|
+
: formatVal(right.val, left.ref.join('/'), target, kind)
|
|
207
|
+
|
|
208
|
+
return `(${encodeURIComponent(formattedValue)})`
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
211
|
|
package/package.json
CHANGED
package/srv/model-provider.js
CHANGED
|
@@ -109,7 +109,7 @@ module.exports = class ModelProviderService extends cds.ApplicationService {
|
|
|
109
109
|
const extensions = !base && await _getExtensions4 (req.data.tenant)
|
|
110
110
|
if (!extensions && checkExt) req.reject(404, 'Missing extensions')
|
|
111
111
|
|
|
112
|
-
const features = !toggles ? [] : toggles === '*' || toggles.includes('*') ? [fts] : toggles.map (f => fts.replace('*',f))
|
|
112
|
+
const features = (!toggles || !main.requires.toggles) ? [] : toggles === '*' || toggles.includes('*') ? [fts] : toggles.map (f => fts.replace('*',f))
|
|
113
113
|
const models = cds.resolve (['*',...features], main); if (!models) return
|
|
114
114
|
|
|
115
115
|
DEBUG && DEBUG ('loading models for', { tenant, toggles } ,'from', models.map (cds.utils.local))
|