spice-js 2.5.16 → 2.5.19
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/build/bootstrap/seed.js +21 -0
- package/build/docs/generator.js +6 -6
- package/build/events/events/ResourceLifecycleTriggered.js +30 -0
- package/build/index.js +12 -6
- package/build/models/SpiceModel.js +29 -0
- package/build/utility/RestHelper.js +27 -11
- package/package.json +2 -2
- package/src/bootstrap/seed.js +16 -0
- package/src/docs/generator.js +28 -26
- package/src/index.js +3 -2
- package/src/models/SpiceModel.js +16 -0
- package/src/utility/RestHelper.js +151 -136
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _path = _interopRequireDefault(require("path"));
|
|
4
|
+
|
|
5
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
6
|
+
|
|
7
|
+
spice.seeds = {};
|
|
8
|
+
|
|
9
|
+
var paths = _path.default.join(spice.root_path, "seeds");
|
|
10
|
+
|
|
11
|
+
require("fs").readdirSync(paths).forEach(function (file) {
|
|
12
|
+
if (file != "index.js") {
|
|
13
|
+
var seed = require(_path.default.join(paths, file));
|
|
14
|
+
|
|
15
|
+
spice.seeds[file.split(".")[0]] = seed;
|
|
16
|
+
|
|
17
|
+
if (seed.run) {
|
|
18
|
+
seed.run();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
});
|
package/build/docs/generator.js
CHANGED
|
@@ -103,16 +103,16 @@ function getRoutes(models) {
|
|
|
103
103
|
produces: ["application/json"]
|
|
104
104
|
};
|
|
105
105
|
_path.responses = {
|
|
106
|
-
|
|
106
|
+
200: {
|
|
107
107
|
description: "Successful Operation"
|
|
108
108
|
},
|
|
109
|
-
|
|
109
|
+
401: {
|
|
110
110
|
description: "Authentication Error"
|
|
111
111
|
},
|
|
112
|
-
|
|
112
|
+
400: {
|
|
113
113
|
description: "Bad Request"
|
|
114
114
|
},
|
|
115
|
-
|
|
115
|
+
404: {
|
|
116
116
|
description: "Not found"
|
|
117
117
|
}
|
|
118
118
|
};
|
|
@@ -427,8 +427,8 @@ function _generateSpec() {
|
|
|
427
427
|
security: [{
|
|
428
428
|
Bearer: []
|
|
429
429
|
}],
|
|
430
|
-
host: spice.config.spice.host + ":" + spice.config.spice.port,
|
|
431
|
-
port:
|
|
430
|
+
host: spice.config.spice.host + ":" + (spice.config.spice.external_port || spice.config.spice.port),
|
|
431
|
+
port: spice.config.spice.external_port || spice.config.spice.port,
|
|
432
432
|
basePath: "/",
|
|
433
433
|
tags: generateTags(),
|
|
434
434
|
paths: generatePaths(routes),
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
|
|
6
|
+
var _Event = _interopRequireDefault(require("../Event"));
|
|
7
|
+
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
|
|
10
|
+
var driver = "";
|
|
11
|
+
|
|
12
|
+
class ResourceLifecycleTriggered extends _Event.default {
|
|
13
|
+
constructor(args) {
|
|
14
|
+
if (args === void 0) {
|
|
15
|
+
args = {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!args.driver) {
|
|
19
|
+
args.driver = driver;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
args.topic = "ResourceLifecycleTriggered";
|
|
23
|
+
super(args);
|
|
24
|
+
this.topic = args.topic;
|
|
25
|
+
this.driver = args.driver;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
exports.default = ResourceLifecycleTriggered;
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
|
-
exports.default = exports.status = exports.addTask = exports.MapType = exports.MailFile = exports.Storage = exports.LocalStorage = exports.DebugStorage = exports.MailDebug = exports.DataType = exports.Mail = exports.RestHelper = exports.Serializer = exports.Crypt = exports.SpiceModel = exports.SocketEventDriver = exports.SpiceEventDriver = exports.EventDebugger = exports.Event = void 0;
|
|
4
|
+
exports.default = exports.status = exports.addTask = exports.MapType = exports.MailFile = exports.Storage = exports.LocalStorage = exports.DebugStorage = exports.MailDebug = exports.DataType = exports.Mail = exports.RestHelper = exports.Serializer = exports.Crypt = exports.SpiceModel = exports.ResourceLifecycleTriggered = exports.SocketEventDriver = exports.SpiceEventDriver = exports.EventDebugger = exports.Event = void 0;
|
|
5
5
|
|
|
6
6
|
var _Event = _interopRequireDefault(require("./events/Event"));
|
|
7
7
|
|
|
@@ -19,6 +19,10 @@ var _SocketEventDriver = _interopRequireDefault(require("./events/providers/Sock
|
|
|
19
19
|
|
|
20
20
|
exports.SocketEventDriver = _SocketEventDriver.default;
|
|
21
21
|
|
|
22
|
+
var _ResourceLifecycleTriggered = _interopRequireDefault(require("./events/events/ResourceLifecycleTriggered"));
|
|
23
|
+
|
|
24
|
+
exports.ResourceLifecycleTriggered = _ResourceLifecycleTriggered.default;
|
|
25
|
+
|
|
22
26
|
var _SpiceModel = _interopRequireDefault(require("./models/SpiceModel"));
|
|
23
27
|
|
|
24
28
|
exports.SpiceModel = _SpiceModel.default;
|
|
@@ -73,6 +77,8 @@ var _tasks = _interopRequireDefault(require("./bootstrap/tasks"));
|
|
|
73
77
|
|
|
74
78
|
exports.addTask = _tasks.default;
|
|
75
79
|
|
|
80
|
+
var _koa2SwaggerUi = require("koa2-swagger-ui");
|
|
81
|
+
|
|
76
82
|
var _generator = _interopRequireDefault(require("./docs/generator"));
|
|
77
83
|
|
|
78
84
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -100,8 +106,6 @@ spice.module_root_path = path.resolve(__dirname);
|
|
|
100
106
|
|
|
101
107
|
var convert = require("koa-convert");
|
|
102
108
|
|
|
103
|
-
var koaSwagger = require("koa2-swagger-ui");
|
|
104
|
-
|
|
105
109
|
spice.classes = {};
|
|
106
110
|
/* spice.classes.Event = Event;
|
|
107
111
|
spice.classes.Serializer = Serializer;
|
|
@@ -147,7 +151,7 @@ class Spice {
|
|
|
147
151
|
console.log("Connection Up", sock);
|
|
148
152
|
}); */
|
|
149
153
|
|
|
150
|
-
app.use(koaSwagger({
|
|
154
|
+
app.use((0, _koa2SwaggerUi.koaSwagger)({
|
|
151
155
|
hideTopbar: true,
|
|
152
156
|
title: "Spice JS",
|
|
153
157
|
routePrefix: "/docs",
|
|
@@ -155,8 +159,10 @@ class Spice {
|
|
|
155
159
|
swaggerOptions: {
|
|
156
160
|
spec: yield (0, _generator.default)(),
|
|
157
161
|
deepLinking: true,
|
|
158
|
-
displayRequestDuration: true
|
|
159
|
-
|
|
162
|
+
displayRequestDuration: true,
|
|
163
|
+
jsonEditor: true
|
|
164
|
+
},
|
|
165
|
+
exposeSpec: true
|
|
160
166
|
}));
|
|
161
167
|
yield require("./loaders").load();
|
|
162
168
|
return spice;
|
|
@@ -5,6 +5,10 @@ exports.default = void 0;
|
|
|
5
5
|
|
|
6
6
|
var _2 = require("..");
|
|
7
7
|
|
|
8
|
+
var _ResourceLifecycleTriggered = _interopRequireDefault(require("../events/events/ResourceLifecycleTriggered"));
|
|
9
|
+
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
|
|
8
12
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
9
13
|
|
|
10
14
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
@@ -89,6 +93,20 @@ class SpiceModel {
|
|
|
89
93
|
collection: args.collection,
|
|
90
94
|
scope: args.scope
|
|
91
95
|
});
|
|
96
|
+
|
|
97
|
+
function removeDynamicProps(props) {
|
|
98
|
+
var returnVal = {};
|
|
99
|
+
|
|
100
|
+
for (var i in props) {
|
|
101
|
+
if (!_.has(props[i], "source") || _.get(props[i], "source") == "static") {
|
|
102
|
+
returnVal[i] = props[i];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return returnVal;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
args.props = removeDynamicProps(args.props);
|
|
92
110
|
this[_props] = args.props;
|
|
93
111
|
|
|
94
112
|
for (var i in args.props) {
|
|
@@ -701,6 +719,17 @@ class SpiceModel {
|
|
|
701
719
|
|
|
702
720
|
return _asyncToGenerator(function* () {
|
|
703
721
|
try {
|
|
722
|
+
var resourceLifecycleTriggered = new _ResourceLifecycleTriggered.default({
|
|
723
|
+
data: {
|
|
724
|
+
data,
|
|
725
|
+
operation: op,
|
|
726
|
+
when,
|
|
727
|
+
old_data,
|
|
728
|
+
resource: _this9.type
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
resourceLifecycleTriggered.dispatch();
|
|
732
|
+
|
|
704
733
|
if (_this9[_hooks] && _this9[_hooks][op] && _this9[_hooks][op][when]) {
|
|
705
734
|
for (var i of _this9[_hooks][op][when]) {
|
|
706
735
|
data = yield i(data, old_data);
|
|
@@ -13,17 +13,25 @@ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try
|
|
|
13
13
|
|
|
14
14
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
15
15
|
|
|
16
|
-
var fs = require(
|
|
16
|
+
var fs = require("fs");
|
|
17
17
|
|
|
18
|
-
var path = require(
|
|
18
|
+
var path = require("path");
|
|
19
19
|
|
|
20
20
|
var {
|
|
21
21
|
parse
|
|
22
|
-
} = require(
|
|
22
|
+
} = require("json2csv");
|
|
23
23
|
|
|
24
24
|
class RestHelper {
|
|
25
25
|
constructor() {}
|
|
26
26
|
|
|
27
|
+
static clear_pagination(ctx, next) {
|
|
28
|
+
return _asyncToGenerator(function* () {
|
|
29
|
+
delete ctx.query.limit;
|
|
30
|
+
delete ctx.query.offset;
|
|
31
|
+
yield next();
|
|
32
|
+
})();
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
static send_response(ctx, next) {
|
|
28
36
|
return _asyncToGenerator(function* () {
|
|
29
37
|
try {
|
|
@@ -46,6 +54,14 @@ class RestHelper {
|
|
|
46
54
|
})();
|
|
47
55
|
}
|
|
48
56
|
|
|
57
|
+
static clear_pagination(ctx, next) {
|
|
58
|
+
return _asyncToGenerator(function* () {
|
|
59
|
+
delete ctx.query.limit;
|
|
60
|
+
delete ctx.query.offset;
|
|
61
|
+
yield next();
|
|
62
|
+
})();
|
|
63
|
+
}
|
|
64
|
+
|
|
49
65
|
static send_download(ctx, next) {
|
|
50
66
|
return _asyncToGenerator(function* () {
|
|
51
67
|
function makeDirectory(dir) {
|
|
@@ -55,10 +71,10 @@ class RestHelper {
|
|
|
55
71
|
}
|
|
56
72
|
|
|
57
73
|
try {
|
|
58
|
-
var download_type = ctx.request.query.format ||
|
|
74
|
+
var download_type = ctx.request.query.format || "csv";
|
|
59
75
|
var content;
|
|
60
76
|
|
|
61
|
-
if (download_type ==
|
|
77
|
+
if (download_type == "csv") {
|
|
62
78
|
var items = _lodash.default.map(ctx.data, item => {
|
|
63
79
|
return (0, _flat.default)(item);
|
|
64
80
|
});
|
|
@@ -69,10 +85,10 @@ class RestHelper {
|
|
|
69
85
|
fields
|
|
70
86
|
};
|
|
71
87
|
content = parse(items, opts);
|
|
72
|
-
ctx.set(
|
|
88
|
+
ctx.set("content-type", "text/csv");
|
|
73
89
|
} else {
|
|
74
90
|
content = JSON.stringify(ctx.data);
|
|
75
|
-
ctx.set(
|
|
91
|
+
ctx.set("content-type", "application/json");
|
|
76
92
|
}
|
|
77
93
|
|
|
78
94
|
makeDirectory("./storage/exports");
|
|
@@ -81,7 +97,7 @@ class RestHelper {
|
|
|
81
97
|
yield fs.writeFile(file, content, function (err) {
|
|
82
98
|
if (err) throw err;
|
|
83
99
|
});
|
|
84
|
-
ctx.set(
|
|
100
|
+
ctx.set("content-disposition", "attachment");
|
|
85
101
|
ctx.response.attachment(file);
|
|
86
102
|
ctx.status = 200;
|
|
87
103
|
ctx.body = fs.createReadStream(file);
|
|
@@ -94,8 +110,8 @@ class RestHelper {
|
|
|
94
110
|
}
|
|
95
111
|
|
|
96
112
|
static makeid(length) {
|
|
97
|
-
var result =
|
|
98
|
-
var characters =
|
|
113
|
+
var result = "";
|
|
114
|
+
var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
99
115
|
var charactersLength = characters.length;
|
|
100
116
|
|
|
101
117
|
for (var i = 0; i < length; i++) {
|
|
@@ -167,7 +183,7 @@ class RestHelper {
|
|
|
167
183
|
} catch (error) {
|
|
168
184
|
try {
|
|
169
185
|
if (value.toLowerCase() == "true" || value.toLowerCase() == "false") {
|
|
170
|
-
returnValue = value ===
|
|
186
|
+
returnValue = value === "true";
|
|
171
187
|
return returnValue;
|
|
172
188
|
} else {
|
|
173
189
|
throw Error;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spice-js",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.19",
|
|
4
4
|
"description": "spice",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"koa-static": "^5.0.0",
|
|
31
31
|
"koa-validation": "^0.1.9",
|
|
32
32
|
"koa-views": "^6.2.3",
|
|
33
|
-
"koa2-swagger-ui": "^
|
|
33
|
+
"koa2-swagger-ui": "^5.5.1",
|
|
34
34
|
"lodash": "^4.17.15",
|
|
35
35
|
"nunjucks": "^3.2.0",
|
|
36
36
|
"open": "7.0.0",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
|
|
3
|
+
spice.seeds = {};
|
|
4
|
+
|
|
5
|
+
let paths = path.join(spice.root_path, "seeds");
|
|
6
|
+
require("fs")
|
|
7
|
+
.readdirSync(paths)
|
|
8
|
+
.forEach(function (file) {
|
|
9
|
+
if (file != "index.js") {
|
|
10
|
+
let seed = require(path.join(paths, file));
|
|
11
|
+
spice.seeds[file.split(".")[0]] = seed;
|
|
12
|
+
if (seed.run) {
|
|
13
|
+
seed.run();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
});
|
package/src/docs/generator.js
CHANGED
|
@@ -82,16 +82,16 @@ function getRoutes(models) {
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
path.responses = {
|
|
85
|
-
|
|
85
|
+
200: {
|
|
86
86
|
description: "Successful Operation",
|
|
87
87
|
},
|
|
88
|
-
|
|
88
|
+
401: {
|
|
89
89
|
description: "Authentication Error",
|
|
90
90
|
},
|
|
91
|
-
|
|
91
|
+
400: {
|
|
92
92
|
description: "Bad Request",
|
|
93
93
|
},
|
|
94
|
-
|
|
94
|
+
404: {
|
|
95
95
|
description: "Not found",
|
|
96
96
|
},
|
|
97
97
|
};
|
|
@@ -271,27 +271,27 @@ function getProperties(obj) {
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
if (map != undefined && map.type == "model") {
|
|
274
|
-
if(map.reference != undefined){
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
274
|
+
if (map.reference != undefined) {
|
|
275
|
+
let references = _.isArray(map.reference)
|
|
276
|
+
? map.reference
|
|
277
|
+
: [map.reference];
|
|
278
|
+
let reference = `#/definitions/${
|
|
279
|
+
_.isString(map.reference) ? map.reference : references[0].name
|
|
280
|
+
}`;
|
|
281
|
+
if (to_return.type == "array") {
|
|
282
|
+
to_return.items.$ref = reference;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (to_return.type == "object") {
|
|
286
|
+
to_return.$ref = reference;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (to_return.type == "string") {
|
|
290
|
+
to_return.type = "object";
|
|
291
|
+
to_return.readOnly = true;
|
|
292
|
+
to_return.$ref = reference;
|
|
293
|
+
}
|
|
283
294
|
}
|
|
284
|
-
|
|
285
|
-
if (to_return.type == "object") {
|
|
286
|
-
to_return.$ref = reference;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (to_return.type == "string") {
|
|
290
|
-
to_return.type = "object";
|
|
291
|
-
to_return.readOnly = true;
|
|
292
|
-
to_return.$ref = reference;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
295
|
}
|
|
296
296
|
return to_return;
|
|
297
297
|
});
|
|
@@ -372,8 +372,10 @@ export default async function generateSpec() {
|
|
|
372
372
|
},
|
|
373
373
|
],
|
|
374
374
|
|
|
375
|
-
host: `${spice.config.spice.host}:${
|
|
376
|
-
|
|
375
|
+
host: `${spice.config.spice.host}:${
|
|
376
|
+
spice.config.spice.external_port || spice.config.spice.port
|
|
377
|
+
}`,
|
|
378
|
+
port: spice.config.spice.external_port || spice.config.spice.port,
|
|
377
379
|
basePath: "/",
|
|
378
380
|
tags: generateTags(),
|
|
379
381
|
paths: generatePaths(routes),
|
package/src/index.js
CHANGED
|
@@ -38,8 +38,7 @@ export { default as MailFile } from "./mail/providers/File";
|
|
|
38
38
|
export { default as MapType } from "./utility/MapType";
|
|
39
39
|
export { default as addTask } from "./bootstrap/tasks";
|
|
40
40
|
const convert = require("koa-convert");
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
import { koaSwagger } from "koa2-swagger-ui";
|
|
43
42
|
spice.classes = {};
|
|
44
43
|
/* spice.classes.Event = Event;
|
|
45
44
|
spice.classes.Serializer = Serializer;
|
|
@@ -90,7 +89,9 @@ export default class Spice {
|
|
|
90
89
|
spec: await docGen(),
|
|
91
90
|
deepLinking: true,
|
|
92
91
|
displayRequestDuration: true,
|
|
92
|
+
jsonEditor: true,
|
|
93
93
|
},
|
|
94
|
+
exposeSpec: true,
|
|
94
95
|
})
|
|
95
96
|
);
|
|
96
97
|
await require("./loaders").load();
|
package/src/models/SpiceModel.js
CHANGED
|
@@ -69,14 +69,30 @@ export default class SpiceModel {
|
|
|
69
69
|
cleaners: [],
|
|
70
70
|
},
|
|
71
71
|
};
|
|
72
|
+
|
|
72
73
|
this.deleted = false;
|
|
73
74
|
if (args.args) {
|
|
74
75
|
delete args.args["ctx"];
|
|
75
76
|
}
|
|
77
|
+
|
|
76
78
|
this[_database] = new Database(args.connection || "default", {
|
|
77
79
|
collection: args.collection,
|
|
78
80
|
scope: args.scope,
|
|
79
81
|
});
|
|
82
|
+
|
|
83
|
+
function removeDynamicProps(props) {
|
|
84
|
+
let returnVal = {};
|
|
85
|
+
for (let i in props) {
|
|
86
|
+
if (
|
|
87
|
+
!_.has(props[i], "source") ||
|
|
88
|
+
_.get(props[i], "source") == "static"
|
|
89
|
+
) {
|
|
90
|
+
returnVal[i] = props[i];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return returnVal;
|
|
94
|
+
}
|
|
95
|
+
args.props = removeDynamicProps(args.props);
|
|
80
96
|
this[_props] = args.props;
|
|
81
97
|
for (let i in args.props) {
|
|
82
98
|
if (args.args != undefined) {
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import flatten from
|
|
2
|
-
import _ from "lodash"
|
|
3
|
-
const fs = require(
|
|
4
|
-
const path = require(
|
|
5
|
-
|
|
6
|
-
const {
|
|
7
|
-
parse
|
|
8
|
-
} = require('json2csv');
|
|
1
|
+
import flatten from "flat";
|
|
2
|
+
import _ from "lodash";
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
const { parse } = require("json2csv");
|
|
9
7
|
export default class RestHelper {
|
|
10
8
|
constructor() { }
|
|
11
9
|
static async clear_pagination(ctx, next) {
|
|
@@ -31,150 +29,167 @@ export default class RestHelper {
|
|
|
31
29
|
console.log("Error at response: ", e, e.stack);
|
|
32
30
|
}
|
|
33
31
|
}
|
|
32
|
+
|
|
34
33
|
|
|
35
|
-
static async
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
try {
|
|
42
|
-
let download_type = ctx.request.query.format || 'csv';
|
|
43
|
-
let content;
|
|
44
|
-
if (download_type == 'csv') {
|
|
45
|
-
let items = _.map(ctx.data, item => {
|
|
46
|
-
return flatten(item);
|
|
47
|
-
});
|
|
48
|
-
let fields = _.union(_.keys(_.first(items)), _.keys(_.last(items)), _.keys(_.nth(items.length / 2)));
|
|
49
|
-
const opts = {
|
|
50
|
-
fields
|
|
51
|
-
};
|
|
52
|
-
content = parse(items, opts);
|
|
53
|
-
ctx.set('content-type', 'text/csv');
|
|
54
|
-
} else {
|
|
55
|
-
content = JSON.stringify(ctx.data);
|
|
56
|
-
ctx.set('content-type', 'application/json');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
makeDirectory(`./storage/exports`);
|
|
60
|
-
makeDirectory(`./storage/exports/${download_type}/`);
|
|
61
|
-
let file = path.resolve(`./storage/exports/${download_type}/${RestHelper.makeid(9)}.${download_type}`);
|
|
62
|
-
await fs.writeFile(file, content, function (err) {
|
|
63
|
-
if (err) throw err;
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
ctx.set('content-disposition', 'attachment');
|
|
67
|
-
ctx.response.attachment(file);
|
|
68
|
-
ctx.status = 200;
|
|
69
|
-
ctx.body = fs.createReadStream(file);
|
|
70
|
-
} catch (e) {
|
|
71
|
-
console.log(e.stack)
|
|
72
|
-
ctx.status = 400;
|
|
73
|
-
ctx.body = RestHelper.prepare_response(RestHelper.FAILURE, e);
|
|
74
|
-
}
|
|
34
|
+
static async clear_pagination(ctx, next) {
|
|
35
|
+
delete ctx.query.limit;
|
|
36
|
+
delete ctx.query.offset;
|
|
37
|
+
await next();
|
|
75
38
|
}
|
|
76
39
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
83
|
-
}
|
|
84
|
-
return result;
|
|
40
|
+
static async send_download(ctx, next) {
|
|
41
|
+
function makeDirectory(dir) {
|
|
42
|
+
if (!fs.existsSync(dir)) {
|
|
43
|
+
fs.mkdirSync(dir);
|
|
44
|
+
}
|
|
85
45
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
data
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
46
|
+
try {
|
|
47
|
+
let download_type = ctx.request.query.format || "csv";
|
|
48
|
+
let content;
|
|
49
|
+
if (download_type == "csv") {
|
|
50
|
+
let items = _.map(ctx.data, (item) => {
|
|
51
|
+
return flatten(item);
|
|
52
|
+
});
|
|
53
|
+
let fields = _.union(
|
|
54
|
+
_.keys(_.first(items)),
|
|
55
|
+
_.keys(_.last(items)),
|
|
56
|
+
_.keys(_.nth(items.length / 2))
|
|
57
|
+
);
|
|
58
|
+
const opts = {
|
|
59
|
+
fields,
|
|
60
|
+
};
|
|
61
|
+
content = parse(items, opts);
|
|
62
|
+
ctx.set("content-type", "text/csv");
|
|
63
|
+
} else {
|
|
64
|
+
content = JSON.stringify(ctx.data);
|
|
65
|
+
ctx.set("content-type", "application/json");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
makeDirectory(`./storage/exports`);
|
|
69
|
+
makeDirectory(`./storage/exports/${download_type}/`);
|
|
70
|
+
let file = path.resolve(
|
|
71
|
+
`./storage/exports/${download_type}/${RestHelper.makeid(
|
|
72
|
+
9
|
|
73
|
+
)}.${download_type}`
|
|
74
|
+
);
|
|
75
|
+
await fs.writeFile(file, content, function (err) {
|
|
76
|
+
if (err) throw err;
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
ctx.set("content-disposition", "attachment");
|
|
80
|
+
ctx.response.attachment(file);
|
|
81
|
+
ctx.status = 200;
|
|
82
|
+
ctx.body = fs.createReadStream(file);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
console.log(e.stack);
|
|
85
|
+
ctx.status = 400;
|
|
86
|
+
ctx.body = RestHelper.prepare_response(RestHelper.FAILURE, e);
|
|
104
87
|
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static makeid(length) {
|
|
91
|
+
var result = "";
|
|
92
|
+
var characters =
|
|
93
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
94
|
+
var charactersLength = characters.length;
|
|
95
|
+
for (var i = 0; i < length; i++) {
|
|
96
|
+
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static SUCCESS = "SUCCESS";
|
|
102
|
+
static FAILURE = "FAILURE";
|
|
103
|
+
static prepare_collection(
|
|
104
|
+
status,
|
|
105
|
+
obj = {
|
|
106
|
+
data: [],
|
|
107
|
+
total: null,
|
|
108
|
+
}
|
|
109
|
+
) {
|
|
110
|
+
var data = {
|
|
111
|
+
status: status,
|
|
112
|
+
type: "collection",
|
|
113
|
+
count: obj.data.length,
|
|
114
|
+
data: obj.data,
|
|
115
|
+
total: obj.total,
|
|
116
|
+
};
|
|
117
|
+
if (obj.total == null || obj.total == undefined) {
|
|
118
|
+
delete data.total;
|
|
119
|
+
}
|
|
120
|
+
return data;
|
|
121
|
+
}
|
|
105
122
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (token) {
|
|
113
|
-
response.token = token;
|
|
114
|
-
}
|
|
123
|
+
static prepare_response(status, data, errors, token) {
|
|
124
|
+
var response = {
|
|
125
|
+
status: status,
|
|
126
|
+
type: "single",
|
|
127
|
+
};
|
|
115
128
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
response.errors = errors;
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
if (data) {
|
|
123
|
-
response.data = data;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
129
|
+
if (token) {
|
|
130
|
+
response.token = token;
|
|
131
|
+
}
|
|
126
132
|
|
|
127
|
-
|
|
133
|
+
if (status == this.FAILURE) {
|
|
134
|
+
response.message = data;
|
|
135
|
+
if (errors) {
|
|
136
|
+
response.errors = errors;
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
if (data) {
|
|
140
|
+
response.data = data;
|
|
141
|
+
}
|
|
128
142
|
}
|
|
129
143
|
|
|
130
|
-
|
|
131
|
-
|
|
144
|
+
return response;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static get_typed_value(value) {
|
|
148
|
+
var returnValue;
|
|
149
|
+
try {
|
|
150
|
+
returnValue = Number(value);
|
|
151
|
+
if (isNaN(returnValue)) {
|
|
152
|
+
throw returnValue;
|
|
153
|
+
} else {
|
|
154
|
+
return returnValue;
|
|
155
|
+
}
|
|
156
|
+
} catch (error) {
|
|
157
|
+
try {
|
|
158
|
+
if (value.toLowerCase() == "true" || value.toLowerCase() == "false") {
|
|
159
|
+
returnValue = value === "true";
|
|
160
|
+
return returnValue;
|
|
161
|
+
} else {
|
|
162
|
+
throw Error;
|
|
163
|
+
}
|
|
164
|
+
} catch (error) {
|
|
132
165
|
try {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
throw returnValue;
|
|
136
|
-
} else {
|
|
137
|
-
return returnValue;
|
|
138
|
-
}
|
|
139
|
-
|
|
166
|
+
returnValue = JSON.parse(value);
|
|
167
|
+
return returnValue;
|
|
140
168
|
} catch (error) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
} catch (error) {
|
|
149
|
-
try {
|
|
150
|
-
returnValue = JSON.parse(value);
|
|
151
|
-
return returnValue;
|
|
152
|
-
} catch (error) {
|
|
153
|
-
try {
|
|
154
|
-
returnValue = String(value);
|
|
155
|
-
return returnValue;
|
|
156
|
-
} catch (error) {
|
|
157
|
-
console.log("Cant parse" + value);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
169
|
+
try {
|
|
170
|
+
returnValue = String(value);
|
|
171
|
+
return returnValue;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
console.log("Cant parse" + value);
|
|
174
|
+
}
|
|
161
175
|
}
|
|
176
|
+
}
|
|
162
177
|
}
|
|
178
|
+
}
|
|
163
179
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (isNaN(port)) {
|
|
168
|
-
// named pipe
|
|
169
|
-
return val;
|
|
170
|
-
}
|
|
180
|
+
static normalizePort(val) {
|
|
181
|
+
var port = parseInt(val, 10);
|
|
171
182
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
183
|
+
if (isNaN(port)) {
|
|
184
|
+
// named pipe
|
|
185
|
+
return val;
|
|
186
|
+
}
|
|
176
187
|
|
|
177
|
-
|
|
188
|
+
if (port >= 0) {
|
|
189
|
+
// port number
|
|
190
|
+
return port;
|
|
178
191
|
}
|
|
179
192
|
|
|
180
|
-
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
}
|