express-ext 0.1.15 → 0.1.18
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/lib/GenericSearchController.js +1 -1
- package/lib/LoadController.js +1 -1
- package/lib/LoadSearchController.js +1 -1
- package/lib/LogController.js +51 -43
- package/lib/LowCodeController.js +1 -1
- package/lib/SearchController.js +1 -1
- package/lib/http.js +41 -0
- package/lib/index.js +3 -1
- package/lib/log.js +39 -3
- package/lib/resources.js +19 -1
- package/lib/search.js +41 -14
- package/package.json +1 -1
- package/src/GenericSearchController.ts +3 -2
- package/src/LoadController.ts +2 -2
- package/src/LoadSearchController.ts +3 -2
- package/src/LogController.ts +51 -43
- package/src/LowCodeController.ts +3 -2
- package/src/SearchController.ts +3 -2
- package/src/http.ts +35 -0
- package/src/index.ts +18 -0
- package/src/log.ts +41 -6
- package/src/resources.ts +43 -1
- package/src/search.ts +38 -9
|
@@ -41,7 +41,7 @@ var GenericSearchController = (function (_super) {
|
|
|
41
41
|
}
|
|
42
42
|
GenericSearchController.prototype.search = function (req, res) {
|
|
43
43
|
var _this = this;
|
|
44
|
-
var s = search_1.fromRequest(req, this.fields, this.excluding);
|
|
44
|
+
var s = search_1.fromRequest(req, search_1.buildArray(this.array, this.fields, this.excluding));
|
|
45
45
|
var l = search_1.getParameters(s, this.config);
|
|
46
46
|
var s2 = search_1.format(s, this.dates, this.numbers);
|
|
47
47
|
this.find(s2, l.limit, l.skipOrRefId, l.fields)
|
package/lib/LoadController.js
CHANGED
|
@@ -45,7 +45,7 @@ var LoadController = (function () {
|
|
|
45
45
|
var id = view_1.buildAndCheckId(req, res, this.keys);
|
|
46
46
|
if (id) {
|
|
47
47
|
this.view(id)
|
|
48
|
-
.then(function (obj) { return http_1.respondModel(obj, res); })
|
|
48
|
+
.then(function (obj) { return http_1.respondModel(http_1.minimize(obj), res); })
|
|
49
49
|
.catch(function (err) { return http_1.handleError(err, res, _this.log); });
|
|
50
50
|
}
|
|
51
51
|
};
|
|
@@ -48,7 +48,7 @@ var LoadSearchController = (function (_super) {
|
|
|
48
48
|
}
|
|
49
49
|
LoadSearchController.prototype.search = function (req, res) {
|
|
50
50
|
var _this = this;
|
|
51
|
-
var s = search_1.fromRequest(req, this.fields, this.excluding);
|
|
51
|
+
var s = search_1.fromRequest(req, search_1.buildArray(this.array, this.fields, this.excluding));
|
|
52
52
|
var l = search_1.getParameters(s, this.config);
|
|
53
53
|
var s2 = search_1.format(s, this.dates, this.numbers);
|
|
54
54
|
this.find(s2, l.limit, l.skipOrRefId, l.fields)
|
package/lib/LogController.js
CHANGED
|
@@ -10,9 +10,10 @@ exports.map = {
|
|
|
10
10
|
FATAL: 4
|
|
11
11
|
};
|
|
12
12
|
var LogController = (function () {
|
|
13
|
-
function LogController(logger, mp) {
|
|
13
|
+
function LogController(logger, updateL, mp) {
|
|
14
14
|
this.logger = logger;
|
|
15
15
|
this.map = (mp ? mp : exports.map);
|
|
16
|
+
this.update = updateL ? updateL : updateLog;
|
|
16
17
|
this.config = this.config.bind(this);
|
|
17
18
|
}
|
|
18
19
|
LogController.prototype.config = function (req, res) {
|
|
@@ -23,53 +24,12 @@ var LogController = (function () {
|
|
|
23
24
|
if (!this.logger) {
|
|
24
25
|
return res.status(503).end('Logger is not available');
|
|
25
26
|
}
|
|
26
|
-
var changed = false;
|
|
27
27
|
if (typeof obj.level === 'string' && obj.level.length > 0) {
|
|
28
28
|
if (!this.map) {
|
|
29
29
|
return res.status(503).end('Map is not available');
|
|
30
30
|
}
|
|
31
|
-
var lv = this.map[obj.level.toUpperCase()];
|
|
32
|
-
if (lv !== undefined) {
|
|
33
|
-
this.logger.level = lv;
|
|
34
|
-
changed = true;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
if (obj.map) {
|
|
38
|
-
if (typeof obj.map.level === 'string' && obj.map.level.length > 0) {
|
|
39
|
-
this.logger.map.level = obj.map.level;
|
|
40
|
-
changed = true;
|
|
41
|
-
}
|
|
42
|
-
if (typeof obj.map.time === 'string' && obj.map.time.length > 0) {
|
|
43
|
-
this.logger.map.time = obj.map.time;
|
|
44
|
-
changed = true;
|
|
45
|
-
}
|
|
46
|
-
if (typeof obj.map.msg === 'string' && obj.map.msg.length > 0) {
|
|
47
|
-
this.logger.map.msg = obj.map.msg;
|
|
48
|
-
changed = true;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (obj.constants !== undefined && typeof obj.constants === 'object') {
|
|
52
|
-
var ks = Object.keys(obj.constants);
|
|
53
|
-
if (ks.length > 0) {
|
|
54
|
-
this.logger.constants = obj.constants;
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
this.logger.constants = undefined;
|
|
58
|
-
}
|
|
59
|
-
changed = true;
|
|
60
|
-
}
|
|
61
|
-
if (obj.name) {
|
|
62
|
-
if (typeof obj.name.trace === 'string'
|
|
63
|
-
&& typeof obj.name.debug === 'string'
|
|
64
|
-
&& typeof obj.name.info === 'string'
|
|
65
|
-
&& typeof obj.name.warn === 'string'
|
|
66
|
-
&& typeof obj.name.error === 'string'
|
|
67
|
-
&& typeof obj.name.panic === 'string'
|
|
68
|
-
&& typeof obj.name.fatal === 'string') {
|
|
69
|
-
this.logger.name = obj.name;
|
|
70
|
-
changed = true;
|
|
71
|
-
}
|
|
72
31
|
}
|
|
32
|
+
var changed = this.update(this.logger, obj, this.map);
|
|
73
33
|
if (changed) {
|
|
74
34
|
return res.status(200).json(true).end();
|
|
75
35
|
}
|
|
@@ -80,3 +40,51 @@ var LogController = (function () {
|
|
|
80
40
|
return LogController;
|
|
81
41
|
}());
|
|
82
42
|
exports.LogController = LogController;
|
|
43
|
+
function updateLog(logger, obj, mp) {
|
|
44
|
+
var changed = false;
|
|
45
|
+
if (typeof obj.level === 'string' && obj.level.length > 0) {
|
|
46
|
+
var lv = mp[obj.level.toUpperCase()];
|
|
47
|
+
if (lv !== undefined) {
|
|
48
|
+
logger.level = lv;
|
|
49
|
+
changed = true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (obj.map) {
|
|
53
|
+
if (typeof obj.map.level === 'string' && obj.map.level.length > 0) {
|
|
54
|
+
logger.map.level = obj.map.level;
|
|
55
|
+
changed = true;
|
|
56
|
+
}
|
|
57
|
+
if (typeof obj.map.time === 'string' && obj.map.time.length > 0) {
|
|
58
|
+
logger.map.time = obj.map.time;
|
|
59
|
+
changed = true;
|
|
60
|
+
}
|
|
61
|
+
if (typeof obj.map.msg === 'string' && obj.map.msg.length > 0) {
|
|
62
|
+
logger.map.msg = obj.map.msg;
|
|
63
|
+
changed = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (obj.constants !== undefined && typeof obj.constants === 'object') {
|
|
67
|
+
var ks = Object.keys(obj.constants);
|
|
68
|
+
if (ks.length > 0) {
|
|
69
|
+
logger.constants = obj.constants;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
logger.constants = undefined;
|
|
73
|
+
}
|
|
74
|
+
changed = true;
|
|
75
|
+
}
|
|
76
|
+
if (obj.name) {
|
|
77
|
+
if (typeof obj.name.trace === 'string'
|
|
78
|
+
&& typeof obj.name.debug === 'string'
|
|
79
|
+
&& typeof obj.name.info === 'string'
|
|
80
|
+
&& typeof obj.name.warn === 'string'
|
|
81
|
+
&& typeof obj.name.error === 'string'
|
|
82
|
+
&& typeof obj.name.panic === 'string'
|
|
83
|
+
&& typeof obj.name.fatal === 'string') {
|
|
84
|
+
logger.name = obj.name;
|
|
85
|
+
changed = true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return changed;
|
|
89
|
+
}
|
|
90
|
+
exports.updateLog = updateLog;
|
package/lib/LowCodeController.js
CHANGED
|
@@ -41,7 +41,7 @@ var LowCodeController = (function (_super) {
|
|
|
41
41
|
}
|
|
42
42
|
LowCodeController.prototype.search = function (req, res) {
|
|
43
43
|
var _this = this;
|
|
44
|
-
var s = search_1.fromRequest(req, this.fields, this.excluding);
|
|
44
|
+
var s = search_1.fromRequest(req, search_1.buildArray(this.array, this.fields, this.excluding));
|
|
45
45
|
var l = search_1.getParameters(s, this.config);
|
|
46
46
|
var s2 = search_1.format(s, this.dates, this.numbers);
|
|
47
47
|
this.lowCodeService.search(s2, l.limit, l.skipOrRefId, l.fields)
|
package/lib/SearchController.js
CHANGED
|
@@ -28,7 +28,7 @@ var SearchController = (function () {
|
|
|
28
28
|
}
|
|
29
29
|
SearchController.prototype.search = function (req, res) {
|
|
30
30
|
var _this = this;
|
|
31
|
-
var s = search_1.fromRequest(req, this.fields, this.excluding);
|
|
31
|
+
var s = search_1.fromRequest(req, search_1.buildArray(this.array, this.fields, this.excluding));
|
|
32
32
|
var l = search_1.getParameters(s, this.config);
|
|
33
33
|
var s2 = search_1.format(s, this.dates, this.numbers);
|
|
34
34
|
this.find(s2, l.limit, l.skipOrRefId, l.fields)
|
package/lib/http.js
CHANGED
|
@@ -10,6 +10,7 @@ function handleError(err, res, log) {
|
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
exports.handleError = handleError;
|
|
13
|
+
exports.error = handleError;
|
|
13
14
|
function toString(v) {
|
|
14
15
|
if (typeof v === 'string') {
|
|
15
16
|
return v;
|
|
@@ -174,6 +175,7 @@ function param(req, res, name) {
|
|
|
174
175
|
return v;
|
|
175
176
|
}
|
|
176
177
|
exports.param = param;
|
|
178
|
+
exports.getParam = param;
|
|
177
179
|
function params(req, name, d, split) {
|
|
178
180
|
var v = req.params[name];
|
|
179
181
|
if (!v || v.length === 0) {
|
|
@@ -185,6 +187,7 @@ function params(req, name, d, split) {
|
|
|
185
187
|
return v.split(split);
|
|
186
188
|
}
|
|
187
189
|
exports.params = params;
|
|
190
|
+
exports.getParams = params;
|
|
188
191
|
function getRequiredParameters(req, res, name, split) {
|
|
189
192
|
var v = req.params[name];
|
|
190
193
|
if (!v || v.length === 0) {
|
|
@@ -262,3 +265,41 @@ function getDate(req, name, d) {
|
|
|
262
265
|
return date;
|
|
263
266
|
}
|
|
264
267
|
exports.getDate = getDate;
|
|
268
|
+
var o = 'object';
|
|
269
|
+
function minimize(obj) {
|
|
270
|
+
if (!obj || typeof obj !== o) {
|
|
271
|
+
return obj;
|
|
272
|
+
}
|
|
273
|
+
var keys = Object.keys(obj);
|
|
274
|
+
for (var _i = 0, keys_2 = keys; _i < keys_2.length; _i++) {
|
|
275
|
+
var key = keys_2[_i];
|
|
276
|
+
var v = obj[key];
|
|
277
|
+
if (v == null) {
|
|
278
|
+
delete obj[key];
|
|
279
|
+
}
|
|
280
|
+
else if (Array.isArray(v) && v.length > 0) {
|
|
281
|
+
var v1 = v[0];
|
|
282
|
+
if (typeof v1 === o && !(v1 instanceof Date)) {
|
|
283
|
+
for (var _a = 0, v_1 = v; _a < v_1.length; _a++) {
|
|
284
|
+
var item = v_1[_a];
|
|
285
|
+
minimize(item);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return obj;
|
|
291
|
+
}
|
|
292
|
+
exports.minimize = minimize;
|
|
293
|
+
function minimizeArray(arrs) {
|
|
294
|
+
if (!arrs) {
|
|
295
|
+
return arrs;
|
|
296
|
+
}
|
|
297
|
+
if (arrs.length > 0) {
|
|
298
|
+
for (var _i = 0, arrs_1 = arrs; _i < arrs_1.length; _i++) {
|
|
299
|
+
var obj = arrs_1[_i];
|
|
300
|
+
minimize(obj);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return arrs;
|
|
304
|
+
}
|
|
305
|
+
exports.minimizeArray = minimizeArray;
|
package/lib/index.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
"use strict";function __export(
|
|
1
|
+
"use strict";function __export(m){for(var p in m)if(!exports.hasOwnProperty(p))exports[p]=m[p]}
|
|
2
|
+
Object.defineProperty(exports,"__esModule",{value:!0});var GenericController_1=require("./GenericController");exports.GenericHandler=GenericController_1.GenericController;var GenericSearchController_1=require("./GenericSearchController");exports.GenericSearchHandler=GenericSearchController_1.GenericSearchController;var HealthController_1=require("./HealthController");exports.HealthHandler=HealthController_1.HealthController;var LoadController_1=require("./LoadController");exports.LoadHandler=LoadController_1.LoadController;exports.ViewHandler=LoadController_1.LoadController;exports.ViewController=LoadController_1.LoadController;var LoadSearchController_1=require("./LoadSearchController");exports.LoadSearchHandler=LoadSearchController_1.LoadSearchController;var LogController_1=require("./LogController");exports.LogHandler=LogController_1.LogController;var LowCodeController_1=require("./LowCodeController");exports.LowCodeHandler=LowCodeController_1.LowCodeController;exports.Handler=LowCodeController_1.LowCodeController;exports.Controller=LowCodeController_1.LowCodeController;var SearchController_1=require("./SearchController");exports.SearchHandler=SearchController_1.SearchController;__export(require("./health"));__export(require("./HealthController"));__export(require("./LogController"));__export(require("./log"));__export(require("./http"));__export(require("./view"));__export(require("./LoadController"));__export(require("./search_func"));__export(require("./search"));__export(require("./SearchController"));__export(require("./LoadSearchController"));__export(require("./resources"));__export(require("./edit"));__export(require("./GenericController"));__export(require("./GenericSearchController"));__export(require("./LowCodeController"));function allow(access){return function(req,res,next){res.header('Access-Control-Allow-Origin',access.origin);res.header('Access-Control-Allow-Credentials',access.credentials);res.header('Access-Control-Allow-Methods',access.methods);res.setHeader('Access-Control-Allow-Headers',access.headers);next()}}
|
|
3
|
+
exports.allow=allow
|
package/lib/log.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
var stream_1 = require("stream");
|
|
4
|
+
var resources_1 = require("./resources");
|
|
4
5
|
function createConfig(c) {
|
|
5
6
|
if (!c) {
|
|
6
7
|
return { skips: [], duration: 'duration', request: '', response: '', status: '', size: '' };
|
|
@@ -37,6 +38,7 @@ function removeUrlParams(url) {
|
|
|
37
38
|
return startParams !== -1 ? url.substring(0, startParams) : url;
|
|
38
39
|
}
|
|
39
40
|
exports.removeUrlParams = removeUrlParams;
|
|
41
|
+
var o = 'OPTIONS';
|
|
40
42
|
var MiddlewareLogger = (function () {
|
|
41
43
|
function MiddlewareLogger(write, conf, build) {
|
|
42
44
|
this.write = write;
|
|
@@ -46,9 +48,9 @@ var MiddlewareLogger = (function () {
|
|
|
46
48
|
}
|
|
47
49
|
MiddlewareLogger.prototype.log = function (req, res, next) {
|
|
48
50
|
var _this = this;
|
|
49
|
-
|
|
51
|
+
var m = req.method;
|
|
52
|
+
if (m !== o && this.conf.log && !skip(this.conf.skips, req.originalUrl)) {
|
|
50
53
|
var start_1 = process.hrtime();
|
|
51
|
-
var m = req.method;
|
|
52
54
|
var x_1 = this.conf.request;
|
|
53
55
|
var r_1 = false;
|
|
54
56
|
if (m !== 'GET' && m !== 'DELETE') {
|
|
@@ -77,7 +79,7 @@ var MiddlewareLogger = (function () {
|
|
|
77
79
|
op[x_1] = JSON.stringify(req.body);
|
|
78
80
|
}
|
|
79
81
|
if (_this.conf.response.length > 0) {
|
|
80
|
-
var rsBody = Buffer.concat(chunks_1).toString();
|
|
82
|
+
var rsBody = Buffer.concat(chunks_1).toString(resources_1.resources.encoding);
|
|
81
83
|
op[_this.conf.response] = rsBody;
|
|
82
84
|
}
|
|
83
85
|
if (_this.conf.status.length > 0) {
|
|
@@ -209,3 +211,37 @@ function isValidSkips(s) {
|
|
|
209
211
|
return true;
|
|
210
212
|
}
|
|
211
213
|
exports.isValidSkips = isValidSkips;
|
|
214
|
+
function mask(s, start, end, replace) {
|
|
215
|
+
if (start < 0) {
|
|
216
|
+
start = 0;
|
|
217
|
+
}
|
|
218
|
+
if (end < 0) {
|
|
219
|
+
end = 0;
|
|
220
|
+
}
|
|
221
|
+
var t = start + end;
|
|
222
|
+
if (t >= s.length) {
|
|
223
|
+
return replace.repeat(s.length);
|
|
224
|
+
}
|
|
225
|
+
return s.substr(0, start) + replace.repeat(s.length - t) + s.substr(s.length - end);
|
|
226
|
+
}
|
|
227
|
+
exports.mask = mask;
|
|
228
|
+
function margin(s, start, end, replace) {
|
|
229
|
+
if (start >= end) {
|
|
230
|
+
return '';
|
|
231
|
+
}
|
|
232
|
+
if (start < 0) {
|
|
233
|
+
start = 0;
|
|
234
|
+
}
|
|
235
|
+
if (end < 0) {
|
|
236
|
+
end = 0;
|
|
237
|
+
}
|
|
238
|
+
if (start >= s.length) {
|
|
239
|
+
return replace.repeat(s.length);
|
|
240
|
+
}
|
|
241
|
+
if (end >= s.length) {
|
|
242
|
+
return replace.repeat(start) + s.substr(start);
|
|
243
|
+
}
|
|
244
|
+
return replace.repeat(start) + s.substr(start, end - start) + replace.repeat(s.length - end);
|
|
245
|
+
}
|
|
246
|
+
exports.margin = margin;
|
|
247
|
+
exports.maskMargin = margin;
|
package/lib/resources.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var fs = require("fs");
|
|
3
4
|
var resources = (function () {
|
|
4
5
|
function resources() {
|
|
5
6
|
}
|
|
7
|
+
resources.encoding = 'utf-8';
|
|
6
8
|
return resources;
|
|
7
9
|
}());
|
|
8
10
|
exports.resources = resources;
|
|
@@ -15,7 +17,7 @@ var TypeChecker = (function () {
|
|
|
15
17
|
TypeChecker.prototype.check = function (req, res, next) {
|
|
16
18
|
var obj = req.body;
|
|
17
19
|
if (!obj || obj === '') {
|
|
18
|
-
|
|
20
|
+
res.status(400).end('The request body cannot be empty');
|
|
19
21
|
}
|
|
20
22
|
else {
|
|
21
23
|
var errors = resources.check(obj, this.attributes, this.allowUndefined);
|
|
@@ -35,3 +37,19 @@ function check(attributes, allowUndefined) {
|
|
|
35
37
|
return x.check;
|
|
36
38
|
}
|
|
37
39
|
exports.check = check;
|
|
40
|
+
function loadTemplates(ok, buildTemplates, correct, files) {
|
|
41
|
+
if (!ok) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
if (!files) {
|
|
45
|
+
files = ['./src/query.xml'];
|
|
46
|
+
}
|
|
47
|
+
var mappers = [];
|
|
48
|
+
for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
|
|
49
|
+
var file = files_1[_i];
|
|
50
|
+
var mapper = fs.readFileSync(file, 'utf8');
|
|
51
|
+
mappers.push(mapper);
|
|
52
|
+
}
|
|
53
|
+
return buildTemplates(mappers, correct);
|
|
54
|
+
}
|
|
55
|
+
exports.loadTemplates = loadTemplates;
|
package/lib/search.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var http_1 = require("./http");
|
|
3
4
|
function jsonResult(res, result, quick, fields, config) {
|
|
4
5
|
if (quick && fields && fields.length > 0) {
|
|
5
6
|
res.status(200).json(toCsv(fields, result)).end();
|
|
@@ -15,7 +16,7 @@ function buildResult(r, conf) {
|
|
|
15
16
|
}
|
|
16
17
|
var x = {};
|
|
17
18
|
var li = (conf.list ? conf.list : 'list');
|
|
18
|
-
x[li] = r.list;
|
|
19
|
+
x[li] = http_1.minimizeArray(r.list);
|
|
19
20
|
var to = (conf.total ? conf.total : 'total');
|
|
20
21
|
x[to] = r.total;
|
|
21
22
|
if (r.nextPageToken && r.nextPageToken.length > 0) {
|
|
@@ -83,27 +84,40 @@ function initializeConfig(conf) {
|
|
|
83
84
|
return c;
|
|
84
85
|
}
|
|
85
86
|
exports.initializeConfig = initializeConfig;
|
|
86
|
-
function fromRequest(req,
|
|
87
|
-
var s = (req.method === 'GET' ? fromUrl(req,
|
|
87
|
+
function fromRequest(req, arr) {
|
|
88
|
+
var s = (req.method === 'GET' ? fromUrl(req, arr) : req.body);
|
|
88
89
|
return s;
|
|
89
90
|
}
|
|
90
91
|
exports.fromRequest = fromRequest;
|
|
91
|
-
function
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
function buildArray(arr, s0, s1, s2) {
|
|
93
|
+
var r = [];
|
|
94
|
+
if (arr && arr.length > 0) {
|
|
95
|
+
for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
|
|
96
|
+
var a = arr_1[_i];
|
|
97
|
+
r.push(a);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (s0 && s0.length > 0) {
|
|
101
|
+
r.push(s0);
|
|
102
|
+
}
|
|
103
|
+
if (s1 && s1.length > 0) {
|
|
104
|
+
r.push(s1);
|
|
94
105
|
}
|
|
106
|
+
if (s2 && s2.length > 0) {
|
|
107
|
+
r.push(s2);
|
|
108
|
+
}
|
|
109
|
+
return r;
|
|
110
|
+
}
|
|
111
|
+
exports.buildArray = buildArray;
|
|
112
|
+
function fromUrl(req, arr) {
|
|
95
113
|
var s = {};
|
|
96
114
|
var obj = req.query;
|
|
97
115
|
var keys = Object.keys(obj);
|
|
98
116
|
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
|
|
99
117
|
var key = keys_1[_i];
|
|
100
|
-
if (key
|
|
101
|
-
var x = obj[key].split(',');
|
|
102
|
-
s[key] = x;
|
|
103
|
-
}
|
|
104
|
-
else if (key === excluding) {
|
|
118
|
+
if (inArray(key, arr)) {
|
|
105
119
|
var x = obj[key].split(',');
|
|
106
|
-
s
|
|
120
|
+
setValue(s, key, x);
|
|
107
121
|
}
|
|
108
122
|
else {
|
|
109
123
|
setValue(s, key, obj[key]);
|
|
@@ -112,6 +126,19 @@ function fromUrl(req, fields, excluding) {
|
|
|
112
126
|
return s;
|
|
113
127
|
}
|
|
114
128
|
exports.fromUrl = fromUrl;
|
|
129
|
+
function inArray(s, arr) {
|
|
130
|
+
if (!arr || arr.length === 0) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
for (var _i = 0, arr_2 = arr; _i < arr_2.length; _i++) {
|
|
134
|
+
var a = arr_2[_i];
|
|
135
|
+
if (s === a) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
exports.inArray = inArray;
|
|
115
142
|
function setValue(obj, path, value) {
|
|
116
143
|
var paths = path.split('.');
|
|
117
144
|
if (paths.length === 1) {
|
|
@@ -315,8 +342,8 @@ function deletePageInfo(obj, arr) {
|
|
|
315
342
|
delete obj['nextPageToken'];
|
|
316
343
|
}
|
|
317
344
|
else {
|
|
318
|
-
for (var _i = 0,
|
|
319
|
-
var o =
|
|
345
|
+
for (var _i = 0, arr_3 = arr; _i < arr_3.length; _i++) {
|
|
346
|
+
var o = arr_3[_i];
|
|
320
347
|
if (o && o.length > 0) {
|
|
321
348
|
delete obj[o];
|
|
322
349
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import {ResultInfo, StatusConfig} from './edit';
|
|
|
3
3
|
import {GenericController, GenericService} from './GenericController';
|
|
4
4
|
import {handleError, Log} from './http';
|
|
5
5
|
import {ErrorMessage} from './metadata';
|
|
6
|
-
import {Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
|
|
6
|
+
import {buildArray, Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
|
|
7
7
|
import {getMetadataFunc} from './search_func';
|
|
8
8
|
|
|
9
9
|
export interface Config extends StatusConfig, SearchConfig {
|
|
@@ -15,6 +15,7 @@ export class GenericSearchController<T, ID, S extends Filter> extends GenericCon
|
|
|
15
15
|
numbers?: string[];
|
|
16
16
|
fields?: string;
|
|
17
17
|
excluding?: string;
|
|
18
|
+
array?: string[];
|
|
18
19
|
constructor(log: Log, public find: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>, service: GenericService<T, ID, number|ResultInfo<T>>, config?: Config, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>, dates?: string[], numbers?: string[]) {
|
|
19
20
|
super(log, service, config, validate);
|
|
20
21
|
this.search = this.search.bind(this);
|
|
@@ -34,7 +35,7 @@ export class GenericSearchController<T, ID, S extends Filter> extends GenericCon
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
search(req: Request, res: Response) {
|
|
37
|
-
const s = fromRequest<S>(req, this.fields, this.excluding);
|
|
38
|
+
const s = fromRequest<S>(req, buildArray(this.array, this.fields, this.excluding));
|
|
38
39
|
const l = getParameters(s, this.config);
|
|
39
40
|
const s2 = format(s, this.dates, this.numbers);
|
|
40
41
|
this.find(s2, l.limit, l.skipOrRefId, l.fields)
|
package/src/LoadController.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {Request, Response} from 'express';
|
|
2
|
-
import {attrs, handleError, Log, respondModel} from './http';
|
|
2
|
+
import {attrs, handleError, Log, minimize, respondModel} from './http';
|
|
3
3
|
import {Attribute, Attributes} from './metadata';
|
|
4
4
|
import {buildAndCheckId, buildKeys} from './view';
|
|
5
5
|
|
|
@@ -48,7 +48,7 @@ export class LoadController<T, ID> {
|
|
|
48
48
|
const id = buildAndCheckId<ID>(req, res, this.keys);
|
|
49
49
|
if (id) {
|
|
50
50
|
this.view(id)
|
|
51
|
-
.then(obj => respondModel(obj, res))
|
|
51
|
+
.then(obj => respondModel(minimize(obj), res))
|
|
52
52
|
.catch(err => handleError(err, res, this.log));
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -2,7 +2,7 @@ import {Request, Response} from 'express';
|
|
|
2
2
|
import {handleError, Log} from './http';
|
|
3
3
|
import {LoadController, ViewService} from './LoadController';
|
|
4
4
|
import {Attribute, Attributes} from './metadata';
|
|
5
|
-
import {Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
|
|
5
|
+
import {buildArray, Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
|
|
6
6
|
import {getMetadataFunc} from './search_func';
|
|
7
7
|
|
|
8
8
|
export class LoadSearchController<T, ID, S extends Filter> extends LoadController<T, ID> {
|
|
@@ -12,6 +12,7 @@ export class LoadSearchController<T, ID, S extends Filter> extends LoadControlle
|
|
|
12
12
|
numbers?: string[];
|
|
13
13
|
fields?: string;
|
|
14
14
|
excluding?: string;
|
|
15
|
+
array?: string[];
|
|
15
16
|
constructor(log: Log, public find: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>, viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T>), keys?: Attributes|Attribute[]|string[], config?: SearchConfig|boolean, dates?: string[], numbers?: string[]) {
|
|
16
17
|
super(log, viewService, keys);
|
|
17
18
|
this.search = this.search.bind(this);
|
|
@@ -37,7 +38,7 @@ export class LoadSearchController<T, ID, S extends Filter> extends LoadControlle
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
search(req: Request, res: Response) {
|
|
40
|
-
const s = fromRequest<S>(req, this.fields, this.excluding);
|
|
41
|
+
const s = fromRequest<S>(req, buildArray(this.array, this.fields, this.excluding));
|
|
41
42
|
const l = getParameters(s, this.config);
|
|
42
43
|
const s2 = format(s, this.dates, this.numbers);
|
|
43
44
|
this.find(s2, l.limit, l.skipOrRefId, l.fields)
|
package/src/LogController.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { SimpleMap } from './log';
|
|
|
4
4
|
export interface NumberMap {
|
|
5
5
|
[key: string]: number;
|
|
6
6
|
}
|
|
7
|
-
export interface
|
|
7
|
+
export interface LogConfig {
|
|
8
8
|
level?: string;
|
|
9
9
|
map?: LogMapConfig;
|
|
10
10
|
constants?: SimpleMap;
|
|
@@ -61,68 +61,76 @@ export const map: NumberMap = {
|
|
|
61
61
|
};
|
|
62
62
|
export class LogController {
|
|
63
63
|
map: NumberMap;
|
|
64
|
-
|
|
64
|
+
update: (logger: Logger, obj: LogConfig, mp: NumberMap) => boolean;
|
|
65
|
+
constructor(public logger: Logger, updateL?: (logger: Logger, obj: LogConfig, mp: NumberMap) => boolean, mp?: NumberMap) {
|
|
65
66
|
this.map = (mp ? mp : map);
|
|
67
|
+
this.update = updateL ? updateL : updateLog;
|
|
66
68
|
this.config = this.config.bind(this);
|
|
67
69
|
}
|
|
68
70
|
config(req: Request, res: Response) {
|
|
69
|
-
const obj:
|
|
71
|
+
const obj: LogConfig = req.body;
|
|
70
72
|
if (!obj || obj === '') {
|
|
71
73
|
return res.status(400).end('The request body cannot be empty');
|
|
72
74
|
}
|
|
73
75
|
if (!this.logger) {
|
|
74
76
|
return res.status(503).end('Logger is not available');
|
|
75
77
|
}
|
|
76
|
-
let changed = false;
|
|
77
78
|
if (typeof obj.level === 'string' && obj.level.length > 0) {
|
|
78
79
|
if (!this.map) {
|
|
79
80
|
return res.status(503).end('Map is not available');
|
|
80
81
|
}
|
|
81
|
-
const lv = this.map[obj.level.toUpperCase()];
|
|
82
|
-
if (lv !== undefined) {
|
|
83
|
-
this.logger.level = lv;
|
|
84
|
-
changed = true;
|
|
85
|
-
}
|
|
86
82
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (typeof obj.map.time === 'string' && obj.map.time.length > 0) {
|
|
93
|
-
this.logger.map.time = obj.map.time;
|
|
94
|
-
changed = true;
|
|
95
|
-
}
|
|
96
|
-
if (typeof obj.map.msg === 'string' && obj.map.msg.length > 0) {
|
|
97
|
-
this.logger.map.msg = obj.map.msg;
|
|
98
|
-
changed = true;
|
|
99
|
-
}
|
|
83
|
+
const changed = this.update(this.logger, obj, this.map);
|
|
84
|
+
if (changed) {
|
|
85
|
+
return res.status(200).json(true).end();
|
|
86
|
+
} else {
|
|
87
|
+
return res.status(204).json(false).end();
|
|
100
88
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export function updateLog(logger: Logger, obj: LogConfig, mp: NumberMap): boolean {
|
|
92
|
+
let changed = false;
|
|
93
|
+
if (typeof obj.level === 'string' && obj.level.length > 0) {
|
|
94
|
+
const lv = mp[obj.level.toUpperCase()];
|
|
95
|
+
if (lv !== undefined) {
|
|
96
|
+
logger.level = lv;
|
|
108
97
|
changed = true;
|
|
109
98
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
&& typeof obj.name.error === 'string'
|
|
116
|
-
&& typeof obj.name.panic === 'string'
|
|
117
|
-
&& typeof obj.name.fatal === 'string') {
|
|
118
|
-
this.logger.name = obj.name;
|
|
119
|
-
changed = true;
|
|
120
|
-
}
|
|
99
|
+
}
|
|
100
|
+
if (obj.map) {
|
|
101
|
+
if (typeof obj.map.level === 'string' && obj.map.level.length > 0) {
|
|
102
|
+
logger.map.level = obj.map.level;
|
|
103
|
+
changed = true;
|
|
121
104
|
}
|
|
122
|
-
if (
|
|
123
|
-
|
|
105
|
+
if (typeof obj.map.time === 'string' && obj.map.time.length > 0) {
|
|
106
|
+
logger.map.time = obj.map.time;
|
|
107
|
+
changed = true;
|
|
108
|
+
}
|
|
109
|
+
if (typeof obj.map.msg === 'string' && obj.map.msg.length > 0) {
|
|
110
|
+
logger.map.msg = obj.map.msg;
|
|
111
|
+
changed = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (obj.constants !== undefined && typeof obj.constants === 'object') {
|
|
115
|
+
const ks = Object.keys(obj.constants);
|
|
116
|
+
if (ks.length > 0) {
|
|
117
|
+
logger.constants = obj.constants;
|
|
124
118
|
} else {
|
|
125
|
-
|
|
119
|
+
logger.constants = undefined;
|
|
120
|
+
}
|
|
121
|
+
changed = true;
|
|
122
|
+
}
|
|
123
|
+
if (obj.name) {
|
|
124
|
+
if (typeof obj.name.trace === 'string'
|
|
125
|
+
&& typeof obj.name.debug === 'string'
|
|
126
|
+
&& typeof obj.name.info === 'string'
|
|
127
|
+
&& typeof obj.name.warn === 'string'
|
|
128
|
+
&& typeof obj.name.error === 'string'
|
|
129
|
+
&& typeof obj.name.panic === 'string'
|
|
130
|
+
&& typeof obj.name.fatal === 'string') {
|
|
131
|
+
logger.name = obj.name;
|
|
132
|
+
changed = true;
|
|
126
133
|
}
|
|
127
134
|
}
|
|
135
|
+
return changed;
|
|
128
136
|
}
|
package/src/LowCodeController.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {ResultInfo, StatusConfig} from './edit';
|
|
|
3
3
|
import {GenericController, GenericService} from './GenericController';
|
|
4
4
|
import {handleError, Log} from './http';
|
|
5
5
|
import {ErrorMessage} from './metadata';
|
|
6
|
-
import {Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
|
|
6
|
+
import {buildArray, Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
|
|
7
7
|
import {getMetadataFunc} from './search_func';
|
|
8
8
|
|
|
9
9
|
export interface LowCodeConfig extends StatusConfig, SearchConfig {
|
|
@@ -18,6 +18,7 @@ export class LowCodeController<T, ID, S extends Filter> extends GenericControlle
|
|
|
18
18
|
numbers?: string[];
|
|
19
19
|
fields?: string;
|
|
20
20
|
excluding?: string;
|
|
21
|
+
array?: string[];
|
|
21
22
|
constructor(log: Log, public lowCodeService: Service<T, ID, number|ResultInfo<T>, S>, config?: LowCodeConfig, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>, dates?: string[], numbers?: string[]) {
|
|
22
23
|
super(log, lowCodeService, config, validate);
|
|
23
24
|
this.search = this.search.bind(this);
|
|
@@ -37,7 +38,7 @@ export class LowCodeController<T, ID, S extends Filter> extends GenericControlle
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
search(req: Request, res: Response) {
|
|
40
|
-
const s = fromRequest<S>(req, this.fields, this.excluding);
|
|
41
|
+
const s = fromRequest<S>(req, buildArray(this.array, this.fields, this.excluding));
|
|
41
42
|
const l = getParameters(s, this.config);
|
|
42
43
|
const s2 = format(s, this.dates, this.numbers);
|
|
43
44
|
this.lowCodeService.search(s2, l.limit, l.skipOrRefId, l.fields)
|
package/src/SearchController.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {Request, Response} from 'express';
|
|
2
2
|
import {handleError, Log} from './http';
|
|
3
|
-
import {Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
|
|
3
|
+
import {buildArray, Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
|
|
4
4
|
|
|
5
5
|
export class SearchController<T, S extends Filter> {
|
|
6
6
|
config?: SearchConfig;
|
|
7
7
|
csv?: boolean;
|
|
8
8
|
fields?: string;
|
|
9
9
|
excluding?: string;
|
|
10
|
+
array?: string[];
|
|
10
11
|
constructor(protected log: Log, public find: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>, config?: SearchConfig|boolean, public dates?: string[], public numbers?: string[]) {
|
|
11
12
|
this.search = this.search.bind(this);
|
|
12
13
|
if (config) {
|
|
@@ -26,7 +27,7 @@ export class SearchController<T, S extends Filter> {
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
search(req: Request, res: Response) {
|
|
29
|
-
const s = fromRequest<S>(req, this.fields, this.excluding);
|
|
30
|
+
const s = fromRequest<S>(req, buildArray(this.array, this.fields, this.excluding));
|
|
30
31
|
const l = getParameters(s, this.config);
|
|
31
32
|
const s2 = format(s, this.dates, this.numbers);
|
|
32
33
|
this.find(s2, l.limit, l.skipOrRefId, l.fields)
|
package/src/http.ts
CHANGED
|
@@ -11,6 +11,7 @@ export function handleError(err: any, res: Response, log?: (msg: string) => void
|
|
|
11
11
|
res.status(500).end(toString(err));
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
export const error = handleError;
|
|
14
15
|
export function toString(v: any): string {
|
|
15
16
|
if (typeof v === 'string') {
|
|
16
17
|
return v;
|
|
@@ -158,6 +159,7 @@ export function param(req: Request, res: Response, name: string): string|undefin
|
|
|
158
159
|
}
|
|
159
160
|
return v;
|
|
160
161
|
}
|
|
162
|
+
export const getParam = param;
|
|
161
163
|
export function params(req: Request, name: string, d?: string[], split?: string): string[]|undefined {
|
|
162
164
|
const v = req.params[name];
|
|
163
165
|
if (!v || v.length === 0) {
|
|
@@ -168,6 +170,7 @@ export function params(req: Request, name: string, d?: string[], split?: string)
|
|
|
168
170
|
}
|
|
169
171
|
return v.split(split);
|
|
170
172
|
}
|
|
173
|
+
export const getParams = params;
|
|
171
174
|
export function getRequiredParameters(req: Request, res: Response, name: string, split?: string): string[]|undefined {
|
|
172
175
|
const v = req.params[name];
|
|
173
176
|
if (!v || v.length === 0) {
|
|
@@ -239,3 +242,35 @@ export function getDate(req: Request, name: string, d?: Date): Date|undefined {
|
|
|
239
242
|
}
|
|
240
243
|
return date;
|
|
241
244
|
}
|
|
245
|
+
const o = 'object';
|
|
246
|
+
export function minimize(obj: any): any {
|
|
247
|
+
if (!obj || typeof obj !== o) {
|
|
248
|
+
return obj;
|
|
249
|
+
}
|
|
250
|
+
const keys = Object.keys(obj);
|
|
251
|
+
for (const key of keys) {
|
|
252
|
+
const v = obj[key];
|
|
253
|
+
if (v == null) {
|
|
254
|
+
delete obj[key];
|
|
255
|
+
} else if (Array.isArray(v) && v.length > 0) {
|
|
256
|
+
const v1 = v[0];
|
|
257
|
+
if (typeof v1 === o && !(v1 instanceof Date)) {
|
|
258
|
+
for (const item of v) {
|
|
259
|
+
minimize(item);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return obj;
|
|
265
|
+
}
|
|
266
|
+
export function minimizeArray<T>(arrs: T[]): T[] {
|
|
267
|
+
if (!arrs) {
|
|
268
|
+
return arrs;
|
|
269
|
+
}
|
|
270
|
+
if (arrs.length > 0) {
|
|
271
|
+
for (const obj of arrs) {
|
|
272
|
+
minimize(obj);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return arrs;
|
|
276
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {NextFunction, Request, Response} from 'express';
|
|
1
2
|
import {GenericController} from './GenericController';
|
|
2
3
|
import {GenericSearchController} from './GenericSearchController';
|
|
3
4
|
import {HealthController} from './HealthController';
|
|
@@ -40,3 +41,20 @@ export * from './edit';
|
|
|
40
41
|
export * from './GenericController';
|
|
41
42
|
export * from './GenericSearchController';
|
|
42
43
|
export * from './LowCodeController';
|
|
44
|
+
|
|
45
|
+
export interface AccessConfig {
|
|
46
|
+
origin: string;
|
|
47
|
+
credentials: string;
|
|
48
|
+
methods: string;
|
|
49
|
+
headers: string;
|
|
50
|
+
}
|
|
51
|
+
export type AccessControlAllowConfig = AccessConfig;
|
|
52
|
+
export function allow(access: AccessConfig): (req: Request, res: Response, next: NextFunction) => void {
|
|
53
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
54
|
+
res.header('Access-Control-Allow-Origin', access.origin);
|
|
55
|
+
res.header('Access-Control-Allow-Credentials', access.credentials);
|
|
56
|
+
res.header('Access-Control-Allow-Methods', access.methods);
|
|
57
|
+
res.setHeader('Access-Control-Allow-Headers', access.headers);
|
|
58
|
+
next();
|
|
59
|
+
};
|
|
60
|
+
}
|
package/src/log.ts
CHANGED
|
@@ -2,8 +2,9 @@ import { NextFunction } from 'express';
|
|
|
2
2
|
import { ParamsDictionary, Request, Response } from 'express-serve-static-core';
|
|
3
3
|
import { ParsedQs } from 'qs';
|
|
4
4
|
import { PassThrough } from 'stream';
|
|
5
|
+
import { resources } from './resources';
|
|
5
6
|
|
|
6
|
-
export interface
|
|
7
|
+
export interface LogConf {
|
|
7
8
|
log?: boolean;
|
|
8
9
|
separate?: boolean;
|
|
9
10
|
skips?: string;
|
|
@@ -26,7 +27,7 @@ export interface MiddleLog {
|
|
|
26
27
|
export interface SimpleMap {
|
|
27
28
|
[key: string]: string|number|boolean|Date;
|
|
28
29
|
}
|
|
29
|
-
export function createConfig(c?:
|
|
30
|
+
export function createConfig(c?: LogConf): MiddleLog {
|
|
30
31
|
if (!c) {
|
|
31
32
|
return {skips: [], duration: 'duration', request: '', response: '', status: '', size: ''};
|
|
32
33
|
}
|
|
@@ -61,16 +62,17 @@ export function removeUrlParams(url: string): string {
|
|
|
61
62
|
export interface Middleware {
|
|
62
63
|
conf: MiddleLog;
|
|
63
64
|
}
|
|
65
|
+
const o = 'OPTIONS';
|
|
64
66
|
export class MiddlewareLogger {
|
|
65
|
-
constructor(public write: (msg: string, m?: SimpleMap) => void, conf?:
|
|
67
|
+
constructor(public write: (msg: string, m?: SimpleMap) => void, conf?: LogConf, public build?: (req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, m: SimpleMap) => SimpleMap) {
|
|
66
68
|
this.log = this.log.bind(this);
|
|
67
69
|
this.conf = createConfig(conf);
|
|
68
70
|
}
|
|
69
71
|
conf: MiddleLog;
|
|
70
72
|
log(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>, number>, next: NextFunction) {
|
|
71
|
-
|
|
73
|
+
const m = req.method;
|
|
74
|
+
if (m !== o && this.conf.log && !skip(this.conf.skips, req.originalUrl)) {
|
|
72
75
|
const start = process.hrtime();
|
|
73
|
-
const m = req.method;
|
|
74
76
|
const x = this.conf.request;
|
|
75
77
|
let r = false;
|
|
76
78
|
if (m !== 'GET' && m !== 'DELETE') {
|
|
@@ -98,7 +100,7 @@ export class MiddlewareLogger {
|
|
|
98
100
|
op[x] = JSON.stringify(req.body);
|
|
99
101
|
}
|
|
100
102
|
if (this.conf.response.length > 0) {
|
|
101
|
-
const rsBody = Buffer.concat(chunks).toString();
|
|
103
|
+
const rsBody = Buffer.concat(chunks).toString(resources.encoding);
|
|
102
104
|
op[this.conf.response] = rsBody;
|
|
103
105
|
}
|
|
104
106
|
if (this.conf.status.length > 0) {
|
|
@@ -152,6 +154,7 @@ const getDurationInMilliseconds = (start: [number, number] | undefined) => {
|
|
|
152
154
|
return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS;
|
|
153
155
|
};
|
|
154
156
|
|
|
157
|
+
// tslint:disable-next-line:max-classes-per-file
|
|
155
158
|
export class MiddlewareController {
|
|
156
159
|
constructor(public logger: Middleware) {
|
|
157
160
|
this.config = this.config.bind(this);
|
|
@@ -214,3 +217,35 @@ export function isValidSkips(s: string[]): boolean {
|
|
|
214
217
|
}
|
|
215
218
|
return true;
|
|
216
219
|
}
|
|
220
|
+
export function mask(s: string, start: number, end: number, replace: string): string {
|
|
221
|
+
if (start < 0) {
|
|
222
|
+
start = 0;
|
|
223
|
+
}
|
|
224
|
+
if (end < 0) {
|
|
225
|
+
end = 0;
|
|
226
|
+
}
|
|
227
|
+
const t = start + end;
|
|
228
|
+
if (t >= s.length) {
|
|
229
|
+
return replace.repeat(s.length);
|
|
230
|
+
}
|
|
231
|
+
return s.substr(0, start) + replace.repeat(s.length - t) + s.substr(s.length - end);
|
|
232
|
+
}
|
|
233
|
+
export function margin(s: string, start: number, end: number, replace: string): string {
|
|
234
|
+
if (start >= end) {
|
|
235
|
+
return '';
|
|
236
|
+
}
|
|
237
|
+
if (start < 0) {
|
|
238
|
+
start = 0;
|
|
239
|
+
}
|
|
240
|
+
if (end < 0) {
|
|
241
|
+
end = 0;
|
|
242
|
+
}
|
|
243
|
+
if (start >= s.length) {
|
|
244
|
+
return replace.repeat(s.length);
|
|
245
|
+
}
|
|
246
|
+
if (end >= s.length) {
|
|
247
|
+
return replace.repeat(start) + s.substr(start);
|
|
248
|
+
}
|
|
249
|
+
return replace.repeat(start) + s.substr(start, end - start) + replace.repeat(s.length - end);
|
|
250
|
+
}
|
|
251
|
+
export const maskMargin = margin;
|
package/src/resources.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { NextFunction, Request, Response } from 'express';
|
|
2
|
+
import * as fs from 'fs';
|
|
2
3
|
import { Attributes, ErrorMessage } from './metadata';
|
|
3
4
|
|
|
4
5
|
// tslint:disable-next-line:class-name
|
|
5
6
|
export class resources {
|
|
6
7
|
static createValidator?: <T>(attributes: Attributes, allowUndefined?: boolean, max?: number) => Validator<T>;
|
|
7
8
|
static check: (obj: any, attributes: Attributes, allowUndefined?: boolean, patch?: boolean) => ErrorMessage[];
|
|
9
|
+
static encoding?: BufferEncoding = 'utf-8';
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
export interface Validator<T> {
|
|
11
13
|
validate(obj: T, patch?: boolean): Promise<ErrorMessage[]>;
|
|
12
14
|
}
|
|
13
15
|
|
|
16
|
+
// tslint:disable-next-line:max-classes-per-file
|
|
14
17
|
export class TypeChecker {
|
|
15
18
|
constructor(public attributes: Attributes, public allowUndefined?: boolean) {
|
|
16
19
|
this.check = this.check.bind(this);
|
|
@@ -18,7 +21,7 @@ export class TypeChecker {
|
|
|
18
21
|
check(req: Request, res: Response, next: NextFunction): void {
|
|
19
22
|
const obj = req.body;
|
|
20
23
|
if (!obj || (obj as any) === '') {
|
|
21
|
-
|
|
24
|
+
res.status(400).end('The request body cannot be empty');
|
|
22
25
|
} else {
|
|
23
26
|
const errors = resources.check(obj, this.attributes, this.allowUndefined);
|
|
24
27
|
if (errors.length > 0) {
|
|
@@ -34,3 +37,42 @@ export function check(attributes: Attributes, allowUndefined?: boolean): Handler
|
|
|
34
37
|
const x = new TypeChecker(attributes, allowUndefined);
|
|
35
38
|
return x.check;
|
|
36
39
|
}
|
|
40
|
+
export interface Parameter {
|
|
41
|
+
name: string;
|
|
42
|
+
type: string;
|
|
43
|
+
}
|
|
44
|
+
export interface StringFormat {
|
|
45
|
+
texts: string[];
|
|
46
|
+
parameters: Parameter[];
|
|
47
|
+
}
|
|
48
|
+
export interface Template {
|
|
49
|
+
name?: string | null;
|
|
50
|
+
text: string;
|
|
51
|
+
templates: TemplateNode[];
|
|
52
|
+
}
|
|
53
|
+
export interface TemplateNode {
|
|
54
|
+
type: string;
|
|
55
|
+
text: string;
|
|
56
|
+
property: string | null;
|
|
57
|
+
encode?: string | null;
|
|
58
|
+
value: string | null;
|
|
59
|
+
format: StringFormat;
|
|
60
|
+
array?: string | null;
|
|
61
|
+
separator?: string | null;
|
|
62
|
+
suffix?: string | null;
|
|
63
|
+
prefix?: string | null;
|
|
64
|
+
}
|
|
65
|
+
export function loadTemplates(ok: boolean|undefined, buildTemplates: (streams: string[], correct?: (stream: string) => string) => Map<string, Template>, correct?: (stream: string) => string, files?: string[]): Map<string, Template>|undefined {
|
|
66
|
+
if (!ok) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
if (!files) {
|
|
70
|
+
files = ['./src/query.xml'];
|
|
71
|
+
}
|
|
72
|
+
const mappers: string[] = [];
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
const mapper = fs.readFileSync(file, 'utf8');
|
|
75
|
+
mappers.push(mapper);
|
|
76
|
+
}
|
|
77
|
+
return buildTemplates(mappers, correct);
|
|
78
|
+
}
|
package/src/search.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {Request, Response} from 'express';
|
|
2
|
+
import {minimizeArray} from './http';
|
|
2
3
|
import {Attribute, Attributes} from './metadata';
|
|
3
4
|
|
|
4
5
|
export interface Filter {
|
|
@@ -41,7 +42,7 @@ export function buildResult<T>(r: SearchResult<T>, conf?: SearchConfig): any {
|
|
|
41
42
|
}
|
|
42
43
|
const x: any = {};
|
|
43
44
|
const li = (conf.list ? conf.list : 'list');
|
|
44
|
-
x[li] = r.list;
|
|
45
|
+
x[li] = minimizeArray(r.list);
|
|
45
46
|
const to = (conf.total ? conf.total : 'total');
|
|
46
47
|
x[to] = r.total;
|
|
47
48
|
if (r.nextPageToken && r.nextPageToken.length > 0) {
|
|
@@ -107,30 +108,58 @@ export function initializeConfig(conf?: SearchConfig): SearchConfig | undefined
|
|
|
107
108
|
}
|
|
108
109
|
return c;
|
|
109
110
|
}
|
|
110
|
-
export function fromRequest<S>(req: Request,
|
|
111
|
-
const s: any = (req.method === 'GET' ? fromUrl(req,
|
|
111
|
+
export function fromRequest<S>(req: Request, arr?: string[]): S {
|
|
112
|
+
const s: any = (req.method === 'GET' ? fromUrl(req, arr) : req.body);
|
|
112
113
|
return s;
|
|
113
114
|
}
|
|
114
|
-
export function
|
|
115
|
+
export function buildArray(arr?: string[], s0?: string, s1?: string, s2?: string): string[] {
|
|
116
|
+
const r: string[] = [];
|
|
117
|
+
if (arr && arr.length > 0) {
|
|
118
|
+
for (const a of arr) {
|
|
119
|
+
r.push(a);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (s0 && s0.length > 0) {
|
|
123
|
+
r.push(s0);
|
|
124
|
+
}
|
|
125
|
+
if (s1 && s1.length > 0) {
|
|
126
|
+
r.push(s1);
|
|
127
|
+
}
|
|
128
|
+
if (s2 && s2.length > 0) {
|
|
129
|
+
r.push(s2);
|
|
130
|
+
}
|
|
131
|
+
return r;
|
|
132
|
+
}
|
|
133
|
+
export function fromUrl<S>(req: Request, arr?: string[]): S {
|
|
134
|
+
/*
|
|
115
135
|
if (!fields || fields.length === 0) {
|
|
116
136
|
fields = 'fields';
|
|
117
137
|
}
|
|
138
|
+
*/
|
|
118
139
|
const s: any = {};
|
|
119
140
|
const obj = req.query;
|
|
120
141
|
const keys = Object.keys(obj);
|
|
121
142
|
for (const key of keys) {
|
|
122
|
-
if (key
|
|
143
|
+
if (inArray(key, arr)) {
|
|
123
144
|
const x = (obj[key] as string).split(',');
|
|
124
|
-
s
|
|
125
|
-
} else if (key === excluding) {
|
|
126
|
-
const x = (obj[key] as string).split(',');
|
|
127
|
-
s[key] = x;
|
|
145
|
+
setValue(s, key, x);
|
|
128
146
|
} else {
|
|
129
147
|
setValue(s, key, obj[key] as string);
|
|
130
148
|
}
|
|
131
149
|
}
|
|
132
150
|
return s;
|
|
133
151
|
}
|
|
152
|
+
export function inArray(s: string, arr?: string[]): boolean {
|
|
153
|
+
if (!arr || arr.length === 0) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
for (const a of arr) {
|
|
157
|
+
if (s === a) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
134
163
|
/*
|
|
135
164
|
export function setValue<T>(obj: T, path: string, value: string): void {
|
|
136
165
|
const paths = path.split('.');
|