@sap/cds 1.15.1 → 1.18.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 +25 -0
- package/{developer-license-3.1.txt → LICENSE} +37 -35
- package/_hdbext/README.md +373 -0
- package/_hdbext/index.js +4 -0
- package/_hdbext/lib/client-factory.js +62 -0
- package/_hdbext/lib/client-session.js +96 -0
- package/_hdbext/lib/conn-options.js +84 -0
- package/_hdbext/lib/constants.js +79 -0
- package/_hdbext/lib/internal-constants.js +7 -0
- package/_hdbext/lib/middleware.js +46 -0
- package/_hdbext/lib/pool.js +236 -0
- package/_hdbext/lib/safe-sql.js +17 -0
- package/_hdbext/lib/sql-injection-utils.js +149 -0
- package/cds-queries-geo.js +347 -371
- package/cds-queries.js +2692 -2229
- package/cds.js +111 -104
- package/exprs.js +118 -107
- package/manager.js +696 -614
- package/metadata.js +604 -542
- package/npm-shrinkwrap.json +268 -0
- package/package.json +40 -1
- package/transaction.js +45 -51
- package/util/Queue.js +32 -30
- package/utils.js +182 -159
- package/xsjs-cds.js +231 -221
- package/.project +0 -11
- package/SIGNATURE.SMF +0 -1747
- package/TUTORIAL.md +0 -1236
- package/dependencies +0 -56
package/utils.js
CHANGED
|
@@ -1,238 +1,261 @@
|
|
|
1
|
-
|
|
1
|
+
// / winston logger for node-cds ///////////////////////////////////
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
const winston = require('winston');
|
|
4
|
+
const logger = new (winston.Logger)({
|
|
5
|
+
transports: [
|
|
6
|
+
new (winston.transports.Console)(),
|
|
7
|
+
],
|
|
8
8
|
});
|
|
9
9
|
logger.level = process.env.CDS_LOGLEVEL || 'warn';
|
|
10
10
|
exports.logger = logger;
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
// / Property access and manipulation //////////////////////////////
|
|
14
14
|
|
|
15
15
|
// iterate over instance based on structure information
|
|
16
16
|
exports.forInstance = forInstance;
|
|
17
17
|
function forInstance(value, struct, fns, prefix) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (value !== null && value[f] !== undefined && f[0] !== "$")
|
|
26
|
-
forInstance(value[f], struct[f], fns, prefix + f + ".");
|
|
27
|
-
} else if ("$default" in fns) {
|
|
28
|
-
fns.$default(prefix, f, value, struct);
|
|
18
|
+
// fns: function(prefix, field, value, struct), ...
|
|
19
|
+
prefix = prefix || '';
|
|
20
|
+
for (const f in struct) {
|
|
21
|
+
if (typeof struct[f] === 'object') {
|
|
22
|
+
for (const a in fns) {
|
|
23
|
+
if (a in struct[f]) {
|
|
24
|
+
fns[a](prefix, f, value, struct);
|
|
29
25
|
}
|
|
26
|
+
}
|
|
27
|
+
if (value !== null && value[f] !== undefined && f[0] !== '$') {
|
|
28
|
+
forInstance(value[f], struct[f], fns, `${prefix + f }.`);
|
|
29
|
+
}
|
|
30
|
+
} else if ('$default' in fns) {
|
|
31
|
+
fns.$default(prefix, f, value, struct);
|
|
30
32
|
}
|
|
33
|
+
}
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
exports.forStruct = forStruct;
|
|
34
37
|
function forStruct(struct, fns, prefix) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (f[0] !== "$")
|
|
43
|
-
forStruct(struct[f], fns, prefix + f + ".");
|
|
44
|
-
} else if ("$default" in fns) {
|
|
45
|
-
fns.$default(struct, f, prefix);
|
|
38
|
+
// fns: function(struct, field, prefix), ...
|
|
39
|
+
prefix = prefix || '';
|
|
40
|
+
for (const f in struct) {
|
|
41
|
+
if (typeof struct[f] === 'object') {
|
|
42
|
+
for (const a in fns) {
|
|
43
|
+
if (a in struct[f]) {
|
|
44
|
+
fns[a](struct, f, prefix);
|
|
46
45
|
}
|
|
46
|
+
}
|
|
47
|
+
if (f[0] !== '$') {
|
|
48
|
+
forStruct(struct[f], fns, `${prefix + f }.`);
|
|
49
|
+
}
|
|
50
|
+
} else if ('$default' in fns) {
|
|
51
|
+
fns.$default(struct, f, prefix);
|
|
47
52
|
}
|
|
53
|
+
}
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
// add dotted path name to nested object with empty value
|
|
51
57
|
// e.g., { a: { x: 1 } } + a.b.c --> { a: { b: { c: {} }, x: 1 } }
|
|
52
58
|
exports.mkPropPath = mkPropPath;
|
|
53
59
|
function mkPropPath(obj, dottedPath) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
if (dottedPath === '') {
|
|
61
|
+
return obj;
|
|
62
|
+
}
|
|
63
|
+
const props = dottedPath.split('.');
|
|
64
|
+
let o = obj;
|
|
65
|
+
for (let i = 0; i < props.length; ++i) {
|
|
66
|
+
const p = props[i];
|
|
67
|
+
if (!(p in o) || typeof o[p] !== 'object') {
|
|
68
|
+
o[p] = {};
|
|
63
69
|
}
|
|
64
|
-
|
|
70
|
+
o = o[p];
|
|
71
|
+
}
|
|
72
|
+
return o;
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
// set value: set({}, "a.b.c", 69) --> { a: { b: { c: 69 } } }
|
|
68
76
|
// also supports array via numerical property names
|
|
69
77
|
exports.setPropPath = setPropPath;
|
|
70
78
|
function setPropPath(obj, dottedPath, value) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return o; // cannot set inside null instance
|
|
81
|
-
//throw new Error("*** ASSERT FAIL *** setting property of null value: " + p);
|
|
82
|
-
o = o[p];
|
|
79
|
+
if (dottedPath === '') {
|
|
80
|
+
return obj;
|
|
81
|
+
}
|
|
82
|
+
const props = dottedPath.split('.');
|
|
83
|
+
let o = obj;
|
|
84
|
+
for (let i = 0; i < props.length - 1; ++i) {
|
|
85
|
+
const p = props[i];
|
|
86
|
+
if (!(p in o) || typeof o[p] !== 'object') {
|
|
87
|
+
o[p] = {};
|
|
83
88
|
}
|
|
84
|
-
o[
|
|
85
|
-
|
|
89
|
+
if (o[p] === null) {
|
|
90
|
+
return o;
|
|
91
|
+
} // cannot set inside null instance
|
|
92
|
+
// throw new Error("*** ASSERT FAIL *** setting property of null value: " + p);
|
|
93
|
+
o = o[p];
|
|
94
|
+
}
|
|
95
|
+
o[props.pop()] = value;
|
|
96
|
+
return o;
|
|
86
97
|
}
|
|
87
98
|
|
|
88
99
|
// optimized version for new objects
|
|
89
100
|
exports.mkNewPath = function(dottedPath) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
const props = dottedPath.split('.');
|
|
102
|
+
let o = {};
|
|
103
|
+
while (props.length > 0) {
|
|
104
|
+
const p = props.pop();
|
|
105
|
+
const t = {};
|
|
106
|
+
t[p] = o;
|
|
107
|
+
o = t;
|
|
108
|
+
}
|
|
109
|
+
return o;
|
|
99
110
|
};
|
|
100
111
|
|
|
101
112
|
// extract property using dotted path
|
|
102
113
|
exports.getPropPath = function(obj, dottedPath) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
const props = dottedPath.split('.');
|
|
115
|
+
while (props.length > 0) {
|
|
116
|
+
if (typeof obj === 'undefined' || obj === null) {
|
|
117
|
+
return undefined;
|
|
118
|
+
} // missing property
|
|
119
|
+
const p = props.shift();
|
|
120
|
+
obj = obj[p];
|
|
121
|
+
}
|
|
122
|
+
return obj;
|
|
111
123
|
};
|
|
112
124
|
|
|
113
125
|
// (sync) ditto but handle arrays in between
|
|
114
126
|
// returns: { path1: value1, path2: value2, ... }
|
|
115
127
|
exports.getPropPathSet = function(obj, dottedPath) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
const props = dottedPath.split('.'); let values = {'': obj};
|
|
129
|
+
while (props.length > 0) {
|
|
130
|
+
const p = props.shift(); const nexts = {};
|
|
131
|
+
for (const i in values) {
|
|
132
|
+
const v = values[i];
|
|
133
|
+
if (v && p in v) {
|
|
134
|
+
if (exports.isArray(v[p])) {
|
|
135
|
+
for (const x in v[p]) {
|
|
136
|
+
nexts[`${i ? `${i }.${ p}` : p }.${ x}`] = v[p][x];
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
nexts[i ? `${i }.${ p}` : p] = v[p];
|
|
128
140
|
}
|
|
129
|
-
|
|
141
|
+
}
|
|
130
142
|
}
|
|
131
|
-
|
|
143
|
+
values = nexts;
|
|
144
|
+
}
|
|
145
|
+
return values;
|
|
132
146
|
};
|
|
133
147
|
|
|
134
148
|
// check if to-many association
|
|
135
|
-
exports.isToMany = function
|
|
136
|
-
|
|
137
|
-
}
|
|
149
|
+
exports.isToMany = function(a) {
|
|
150
|
+
return a.$viaBacklink || a.$viaEntity || a.$on;
|
|
151
|
+
};
|
|
138
152
|
|
|
139
153
|
|
|
140
|
-
|
|
154
|
+
// / misc. utility functions
|
|
141
155
|
|
|
142
156
|
// check for Array
|
|
143
157
|
// NOTE: using the simpler "instanceof Array" seems to mess with Fibrous?!
|
|
144
|
-
exports.isArray = function
|
|
145
|
-
|
|
146
|
-
}
|
|
158
|
+
exports.isArray = function(o) {
|
|
159
|
+
return Object.prototype.toString.call(o) === '[object Array]';
|
|
160
|
+
};
|
|
147
161
|
|
|
148
162
|
// create shallow copy of object or array
|
|
149
163
|
exports.shallowCopy = function(o) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
r = {};
|
|
158
|
-
for (var p in o)
|
|
159
|
-
if (o.hasOwnProperty(p))
|
|
160
|
-
r[p] = o[p];
|
|
161
|
-
}
|
|
162
|
-
return r;
|
|
164
|
+
if (typeof o === 'object' && o !== null) {
|
|
165
|
+
let r;
|
|
166
|
+
if (exports.isArray(o)) {
|
|
167
|
+
r = [];
|
|
168
|
+
for (let i = 0; i < o.length; ++i) {
|
|
169
|
+
r.push(o[i]);
|
|
170
|
+
}
|
|
163
171
|
} else {
|
|
164
|
-
|
|
172
|
+
r = {};
|
|
173
|
+
for (const p in o) {
|
|
174
|
+
if (o.hasOwnProperty(p)) {
|
|
175
|
+
r[p] = o[p];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
165
178
|
}
|
|
179
|
+
return r;
|
|
180
|
+
} else {
|
|
181
|
+
return o;
|
|
182
|
+
}
|
|
166
183
|
};
|
|
167
184
|
|
|
168
185
|
// create deep copy of object (unshares arrays, dates)
|
|
169
186
|
exports.deepCopy = function(obj) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
187
|
+
const seen = [];
|
|
188
|
+
const copy = function(o) {
|
|
189
|
+
if (o === null || typeof o !== 'object') {
|
|
190
|
+
return o;
|
|
191
|
+
}
|
|
192
|
+
if (o instanceof Date) {
|
|
193
|
+
return new Date(o.getTime());
|
|
194
|
+
}
|
|
195
|
+
if (o instanceof ctypes.Int64) {
|
|
196
|
+
return ctypes.Int64.join(ctypes.Int64.hi(o), ctypes.Int64.lo(o));
|
|
197
|
+
}
|
|
198
|
+
if (seen.indexOf(o) >= 0) {
|
|
199
|
+
throw new TypeError('deep copy of recursive data structure');
|
|
200
|
+
}
|
|
201
|
+
let clone;
|
|
202
|
+
if (exports.isArray(o)) {
|
|
203
|
+
clone = [];
|
|
204
|
+
for (let i = 0; i < o.length; ++i) {
|
|
205
|
+
clone.push(copy(o[i]));
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
const j = seen.length;
|
|
209
|
+
seen.push(o);
|
|
210
|
+
clone = {};
|
|
211
|
+
for (const p in o) {
|
|
212
|
+
if (o.hasOwnProperty(p)) {
|
|
213
|
+
clone[p] = copy(o[p]);
|
|
196
214
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
215
|
+
}
|
|
216
|
+
seen.splice(j);
|
|
217
|
+
}
|
|
218
|
+
return clone;
|
|
219
|
+
};
|
|
220
|
+
return copy(obj);
|
|
200
221
|
};
|
|
201
222
|
|
|
202
223
|
// add non-enumerable property to object
|
|
203
|
-
exports.addInternalProp = function
|
|
204
|
-
|
|
205
|
-
}
|
|
224
|
+
exports.addInternalProp = function(obj, prop, val) {
|
|
225
|
+
Object.defineProperty(obj, prop, {value: val, configurable: true});
|
|
226
|
+
};
|
|
206
227
|
|
|
207
228
|
|
|
208
|
-
|
|
229
|
+
// / DB Stuff /////////////////////////////////////////////////////////
|
|
209
230
|
|
|
210
231
|
// properly quote table or schema + table name
|
|
211
|
-
exports.quoteTable = function
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
(parts[0] ? (parts[0][0] === '"' ? parts[0] :
|
|
215
|
-
(parts[1][0] === '"' ? parts[1] :
|
|
216
|
-
|
|
217
|
-
}
|
|
232
|
+
exports.quoteTable = function(name) {
|
|
233
|
+
const parts = name.match(/^(?:("[^"]+"|[^".]+)\.)?(.*)$/);
|
|
234
|
+
const quotedName =
|
|
235
|
+
(parts[0] ? (parts[0][0] === '"' ? parts[0] : `"${ parts[0] }"`) : '') +
|
|
236
|
+
(parts[1][0] === '"' ? parts[1] : `"${ parts[1] }"`);
|
|
237
|
+
return quotedName;
|
|
238
|
+
};
|
|
218
239
|
|
|
219
240
|
|
|
220
|
-
|
|
241
|
+
// / Debugging ////////////////////////////////////////////////////////
|
|
221
242
|
|
|
222
243
|
// pretty-print non-internal properties
|
|
223
244
|
exports.ppp = function(obj, verbose) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
245
|
+
const seen = [];
|
|
246
|
+
function repl(k, v) {
|
|
247
|
+
if (typeof v === 'object') {
|
|
248
|
+
if (!verbose && k.substring(0, 2) === '$_') {
|
|
249
|
+
return '#$';
|
|
250
|
+
}
|
|
251
|
+
if (v !== null && seen.indexOf(v) >= 0) {
|
|
252
|
+
return '#obj';
|
|
253
|
+
} // v instanceof Struct ? "#" + v : "#obj";
|
|
254
|
+
seen.push(v);
|
|
255
|
+
} else if (typeof v === 'function') {
|
|
256
|
+
return '#fn';
|
|
236
257
|
}
|
|
237
|
-
return
|
|
258
|
+
return v;
|
|
259
|
+
}
|
|
260
|
+
return JSON.stringify(obj, repl, 4);
|
|
238
261
|
};
|