turbo-express-js 1.0.0
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/LICENSE +21 -0
- package/README.md +187 -0
- package/benchmarks/image.md +35 -0
- package/benchmarks/video.md +35 -0
- package/bin.test.js +59 -0
- package/express.test.js +73 -0
- package/index.js +3 -0
- package/index.test.js +116 -0
- package/lib/Router.js +100 -0
- package/lib/ServerCallback.js +65 -0
- package/lib/TurboServer.js +278 -0
- package/lib/enum/FileEndToContentType.js +35 -0
- package/lib/enum/ValidationMethodType.js +6 -0
- package/lib/middlewares/attachment_middleware.js +89 -0
- package/lib/middlewares/authentication_middleware.js +33 -0
- package/lib/middlewares/buildform_middleware.js +33 -0
- package/lib/middlewares/cors_middleware.js +33 -0
- package/lib/middlewares/runmethod_middleware.js +51 -0
- package/lib/middlewares/static_middleware.js +76 -0
- package/lib/middlewares/validation_middleware.js +39 -0
- package/lib/statictypes/RequestMethods.js +85 -0
- package/lib/types/FileType.js +55 -0
- package/lib/types/Middleware.js +59 -0
- package/lib/types/RequestInterface.js +398 -0
- package/lib/types/ResponseInterface.js +94 -0
- package/lib/types/ResponseMongo.js +35 -0
- package/lib/types/Route.js +97 -0
- package/lib/types/RunMethodType.js +49 -0
- package/lib/types/ValidationError.js +56 -0
- package/lib/types/ValidationSchema.js +139 -0
- package/lib/types/ValidationStaticTypes.js +34 -0
- package/lib/utils.js +111 -0
- package/package.json +38 -0
- package/samples/README.md +1 -0
- package/todo.md +11 -0
- package/version_management.md +13 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
3
|
+
*
|
|
4
|
+
* @PerfecTEvolutioN
|
|
5
|
+
* @project - TurboExpress
|
|
6
|
+
* @name TurboExpress
|
|
7
|
+
* @namespace TurboExpress::middlewares::static_middleware
|
|
8
|
+
* @license - MIT
|
|
9
|
+
* @author - Mike Karypidis
|
|
10
|
+
* @version - 1.0.0
|
|
11
|
+
* @link - https://npmjs.com/TurboExpress
|
|
12
|
+
* @github - https://github.com/TurboExpress
|
|
13
|
+
*
|
|
14
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require("fs");
|
|
18
|
+
const FileEndToContentType = require("../enum/FileEndToContentType");
|
|
19
|
+
const RequestInterface = require("../types/RequestInterface");
|
|
20
|
+
const ResponseInterface = require("../types/ResponseInterface");
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @param {RequestInterface} req
|
|
25
|
+
* @param {ResponseInterface} res
|
|
26
|
+
* @param {*} next
|
|
27
|
+
*/
|
|
28
|
+
module.exports = function static_middleware (req, res, next)
|
|
29
|
+
{
|
|
30
|
+
const filePathParam = req.url().split(req.current.path_parts.slice(0, req.current.path_parts.length - 1).join("/"))[1];
|
|
31
|
+
const correctHeaders = FileEndToContentType(filePathParam);
|
|
32
|
+
|
|
33
|
+
const filePath = require("path").resolve() + this.folder + filePathParam;
|
|
34
|
+
|
|
35
|
+
//console.log(filePath)
|
|
36
|
+
|
|
37
|
+
if(fs.existsSync(filePath) === false) {
|
|
38
|
+
res.OutgoingMessage.writeHead(200, { 'Content-Type': 'text/html', });
|
|
39
|
+
return res.OutgoingMessage.end("NOT FOUND || 404")
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @doc if in global property {TurboExpressCaching} exist the filepath
|
|
44
|
+
* then send file from cache;
|
|
45
|
+
*/
|
|
46
|
+
if(global["TurboExpressCaching"][filePath]) {
|
|
47
|
+
res.OutgoingMessage.writeHead(200, { 'Content-Type': correctHeaders, });
|
|
48
|
+
res.OutgoingMessage.end(global["TurboExpressCaching"][filePath]);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @doc read file using nodejs streams;
|
|
54
|
+
* when stream is over, check if cache property is true, then
|
|
55
|
+
* if true save the buffer to global {TurboExpressCaching}
|
|
56
|
+
* in any case send the file to the client;
|
|
57
|
+
*/
|
|
58
|
+
const stream = fs.createReadStream(filePath);
|
|
59
|
+
|
|
60
|
+
res.OutgoingMessage.writeHead(200, { 'Content-Type': correctHeaders });
|
|
61
|
+
|
|
62
|
+
let chunks = [];
|
|
63
|
+
|
|
64
|
+
stream.on("data", (chunk) => chunks.push(chunk))
|
|
65
|
+
stream.on("end", () => {
|
|
66
|
+
let fileData = Buffer.concat(chunks);
|
|
67
|
+
if(this.cache) global["TurboExpressCaching"][filePath] = fileData;
|
|
68
|
+
res.OutgoingMessage.end(fileData);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
stream.on('error', (err) => {
|
|
72
|
+
res.OutgoingMessage.writeHead(404);
|
|
73
|
+
res.OutgoingMessage.end(err.message);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
3
|
+
*
|
|
4
|
+
* @PerfecTEvolutioN
|
|
5
|
+
* @project - TurboExpress
|
|
6
|
+
* @name TurboExpress
|
|
7
|
+
* @namespace TurboExpress::middlewares::static_middleware
|
|
8
|
+
* @license - MIT
|
|
9
|
+
* @author - Mike Karypidis
|
|
10
|
+
* @version - 1.0.0
|
|
11
|
+
* @link - https://npmjs.com/TurboExpress
|
|
12
|
+
* @github - https://github.com/TurboExpress
|
|
13
|
+
*
|
|
14
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const RequestInterface = require("../types/RequestInterface");
|
|
18
|
+
const ResponseInterface = require("../types/ResponseInterface");
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* @param {RequestInterface} req
|
|
23
|
+
* @param {ResponseInterface} res
|
|
24
|
+
* @param {*} next
|
|
25
|
+
*/
|
|
26
|
+
module.exports = async function validation_middleware (req, res, next)
|
|
27
|
+
{
|
|
28
|
+
|
|
29
|
+
const { validations } = this;
|
|
30
|
+
|
|
31
|
+
validations.map(v => req.addValidation(v));
|
|
32
|
+
|
|
33
|
+
const validationResult = await req.validateIncomingData();
|
|
34
|
+
|
|
35
|
+
if(validationResult === -1) return res.status(400).json({ errors: req._validation_errors });
|
|
36
|
+
|
|
37
|
+
next();
|
|
38
|
+
|
|
39
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
3
|
+
*
|
|
4
|
+
* @PerfecTEvolutioN
|
|
5
|
+
* @project - TurboExpress
|
|
6
|
+
* @name TurboExpress
|
|
7
|
+
* @namespace TurboExpress::StaticTypes::RequestMethods
|
|
8
|
+
* @license - MIT
|
|
9
|
+
* @author - Mike Karypidis
|
|
10
|
+
* @version - 1.0.0
|
|
11
|
+
* @link - https://npmjs.com/TurboExpress
|
|
12
|
+
* @github - https://github.com/TurboExpress
|
|
13
|
+
*
|
|
14
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
module.exports = class RequestMethods
|
|
19
|
+
{
|
|
20
|
+
|
|
21
|
+
static GET = "get";
|
|
22
|
+
static POST = "post";
|
|
23
|
+
static PUT = "put";
|
|
24
|
+
static DELETE = "delete";
|
|
25
|
+
static HEAD = "head";
|
|
26
|
+
static PATCH = "patch";
|
|
27
|
+
static OPTIONS = "options";
|
|
28
|
+
static LINK = "link";
|
|
29
|
+
static UNLINK = "unlink";
|
|
30
|
+
static VIEW = "view";
|
|
31
|
+
static LOCK = "lock";
|
|
32
|
+
static UNLOCK = "unlock";
|
|
33
|
+
static COPY = "copy";
|
|
34
|
+
static PURGE = "purge";
|
|
35
|
+
static PROPFIND = "propfind"
|
|
36
|
+
|
|
37
|
+
http_methods = ["get", "post", "delete", "put", "head", "patch", "options", "link", "unlink", "view", "lock", "unlock", "copy", "purge", "propfind"];
|
|
38
|
+
|
|
39
|
+
get;
|
|
40
|
+
post;
|
|
41
|
+
put;
|
|
42
|
+
delete;
|
|
43
|
+
head;
|
|
44
|
+
patch;
|
|
45
|
+
options;
|
|
46
|
+
link;
|
|
47
|
+
unlink;
|
|
48
|
+
view;
|
|
49
|
+
lock;
|
|
50
|
+
unlock;
|
|
51
|
+
copy;
|
|
52
|
+
purge;
|
|
53
|
+
propfind;
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
constructor ()
|
|
57
|
+
{
|
|
58
|
+
this.get = RequestMethods.GET;
|
|
59
|
+
this.post = RequestMethods.POST;
|
|
60
|
+
this.put = RequestMethods.PUT;
|
|
61
|
+
this.delete = RequestMethods.DELETE;
|
|
62
|
+
this.head = RequestMethods.HEAD;
|
|
63
|
+
this.patch = RequestMethods.PATCH;
|
|
64
|
+
this.options = RequestMethods.OPTIONS;
|
|
65
|
+
this.link = RequestMethods.LINK;
|
|
66
|
+
this.unlink = RequestMethods.UNLINK;
|
|
67
|
+
this.view = RequestMethods.VIEW;
|
|
68
|
+
this.lock = RequestMethods.LOCK;
|
|
69
|
+
this.unlock = RequestMethods.UNLOCK;
|
|
70
|
+
this.copy = RequestMethods.COPY;
|
|
71
|
+
this.purge = RequestMethods.PURGE;
|
|
72
|
+
this.propfind = RequestMethods.PROPFIND;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* @param {Function} cb
|
|
78
|
+
* @returns {void}
|
|
79
|
+
*/
|
|
80
|
+
forEach (cb)
|
|
81
|
+
{
|
|
82
|
+
this.http_methods.map(cb);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
3
|
+
*
|
|
4
|
+
* @PerfecTEvolutioN
|
|
5
|
+
* @MikeKarypidis
|
|
6
|
+
* @project - TurboExpress
|
|
7
|
+
* @name Middleware
|
|
8
|
+
* @namespace TurboExpress::types::FileType
|
|
9
|
+
* @license - MIT
|
|
10
|
+
* @copyright - ©2022 PerfectEvolution Corporation;
|
|
11
|
+
* @author - Mike Karypidis
|
|
12
|
+
* @version - 1.0.0
|
|
13
|
+
* @link - https://turboserverjs.org
|
|
14
|
+
* @github - https://github.com/breathfunwithmindte/turbo-server.git
|
|
15
|
+
*
|
|
16
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** @type */
|
|
20
|
+
module.exports = class FileType
|
|
21
|
+
{
|
|
22
|
+
/** @type {String} */ name;
|
|
23
|
+
/** @type {String} */ fileName;
|
|
24
|
+
/** @type {String} */ extension;
|
|
25
|
+
/** @type {String} */ mime_type;
|
|
26
|
+
/** @type {String} */ description;
|
|
27
|
+
/** @type {boolean} */ is_saved;
|
|
28
|
+
/** @type {boolean} */ is_binary;
|
|
29
|
+
/** @type {boolean} */ is_compressible;
|
|
30
|
+
/** @type {boolean} */ is_encrypted;
|
|
31
|
+
/** @type {number} */ buffer_size;
|
|
32
|
+
/** @type {Buffer} */ buffer;
|
|
33
|
+
/** @type {String} */ owner;
|
|
34
|
+
/** @type {*} */ metadata;
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
save(path, cb)
|
|
38
|
+
{
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
saveSync (path)
|
|
43
|
+
{
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {*} by
|
|
49
|
+
*/
|
|
50
|
+
fileExtension (by)
|
|
51
|
+
{
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
3
|
+
*
|
|
4
|
+
* @PerfecTEvolutioN
|
|
5
|
+
* @MikeKarypidis
|
|
6
|
+
* @project - TurboExpress
|
|
7
|
+
* @name Middleware
|
|
8
|
+
* @namespace TurboExpress::ServerCallback
|
|
9
|
+
* @license - MIT
|
|
10
|
+
* @copyright - ©2022 PerfectEvolution Corporation;
|
|
11
|
+
* @author - Mike Karypidis
|
|
12
|
+
* @version - 1.0.0
|
|
13
|
+
* @link - https://turboserverjs.org
|
|
14
|
+
* @github - https://github.com/breathfunwithmindte/turbo-server.git
|
|
15
|
+
*
|
|
16
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
module.exports = class Middleware
|
|
20
|
+
{
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @doc all this properties will be used once to find if middleware is matching the route.
|
|
24
|
+
* if it does then the callbacks will be pushed at the begining of the route.callbacks
|
|
25
|
+
*
|
|
26
|
+
* @useMinLength actually if path endwith /* that group all of these middlewares in their own category
|
|
27
|
+
* on server callback will be executed 2 matching functions
|
|
28
|
+
*
|
|
29
|
+
* 1rst one is exact that mean it will try to match route that not end with /* and has the same length of path parts;
|
|
30
|
+
*
|
|
31
|
+
* if the first not find something, only then it will go to the next function
|
|
32
|
+
* in the second function, here is where useMinLength = true group is used.
|
|
33
|
+
*
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
/** @type {String} */ path;
|
|
39
|
+
/** @type {String[]} */ path_parts;
|
|
40
|
+
/** @type {Boolean} */ useMinlength;
|
|
41
|
+
/** @type {Number} */ size;
|
|
42
|
+
/** @type {Function[]} */ callbacks = new Array();
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* todo validation check and warn for wrong type;
|
|
46
|
+
* @param {String} path
|
|
47
|
+
* @param {Function[]} callbacks
|
|
48
|
+
*/
|
|
49
|
+
constructor(path, callbacks)
|
|
50
|
+
{
|
|
51
|
+
this.path = path;
|
|
52
|
+
this.path_parts = path.split("/").filter((f) => f !== "");
|
|
53
|
+
this.useMinlength = path.endsWith("/*");
|
|
54
|
+
this.size = path.endsWith("/*")
|
|
55
|
+
? this.path_parts.length - 1
|
|
56
|
+
: this.path_parts.length;
|
|
57
|
+
this.callbacks = callbacks || [];
|
|
58
|
+
}
|
|
59
|
+
};
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
3
|
+
*
|
|
4
|
+
* @PerfecTEvolutioN
|
|
5
|
+
* @MikeKarypidis
|
|
6
|
+
* @project - TurboServer
|
|
7
|
+
* @name TurboServer
|
|
8
|
+
* @license - MIT
|
|
9
|
+
* @copyright - ©2022 PerfectEvolution Corporation;
|
|
10
|
+
* @author - Mike Karypidis
|
|
11
|
+
* @version - 1.0.0
|
|
12
|
+
* @link - https://turboserverjs.org
|
|
13
|
+
* @github - https://github.com/breathfunwithmindte/turbo-server.git
|
|
14
|
+
*
|
|
15
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {Object} BasicAuth
|
|
20
|
+
* @property {String} user
|
|
21
|
+
* @property {String} pass
|
|
22
|
+
*
|
|
23
|
+
* @typedef {http.IncomingMessage} incme
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const http = require("http");
|
|
27
|
+
const FileType = require("./FileType");
|
|
28
|
+
const Route = require("./Route");
|
|
29
|
+
const ValidationSchema = require("./ValidationSchema");
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/** @interface */
|
|
33
|
+
module.exports = class RequestInterface
|
|
34
|
+
{
|
|
35
|
+
/** @type {http.IncomingMessage} */ IncomingMessage;
|
|
36
|
+
/** @type {Route} */ current;
|
|
37
|
+
/** @type {import("../TurboServer")} */ instance;
|
|
38
|
+
/** @type {Map<String, import("mongoose").Model>} */ models;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @type {Map<String, *>}
|
|
42
|
+
* @doc protected variable
|
|
43
|
+
* usually it will be Map<String, String>
|
|
44
|
+
* but also can be <String, Number> or <String, Boolean>
|
|
45
|
+
*/
|
|
46
|
+
_params;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @type {Buffer}
|
|
50
|
+
* @doc protected variable
|
|
51
|
+
*/
|
|
52
|
+
_body = Buffer.alloc(0);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @type {FileType[]}
|
|
56
|
+
* @doc protected variable
|
|
57
|
+
*/
|
|
58
|
+
_files = new Array();
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @type {ValidationSchema[]}
|
|
62
|
+
* @doc protected variable
|
|
63
|
+
*/
|
|
64
|
+
_validations = new Array();
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @type {Map<String, any>}
|
|
68
|
+
* @doc protected variable
|
|
69
|
+
*/
|
|
70
|
+
validData = new Map();
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @type {ValidationSchema[]}
|
|
74
|
+
* @doc protected variable
|
|
75
|
+
*/
|
|
76
|
+
_validation_errors = new Array();
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @type {Boolean}
|
|
80
|
+
* @doc protected variable
|
|
81
|
+
*/
|
|
82
|
+
bodyFetched = false;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {http.IncomingMessage} req
|
|
86
|
+
* @param {Route} current
|
|
87
|
+
* @param {import("../TurboServer")} instance
|
|
88
|
+
*/
|
|
89
|
+
constructor(req, current, instance)
|
|
90
|
+
{
|
|
91
|
+
this.current = current;
|
|
92
|
+
this.IncomingMessage = req;
|
|
93
|
+
this.state = new Map();
|
|
94
|
+
this.instance = instance;
|
|
95
|
+
this.models = instance.models;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
addValidation (validation) {
|
|
99
|
+
if(validation instanceof ValidationSchema === true) {
|
|
100
|
+
this._validations.push(validation);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async execute_validation (res, injectedData, next) {
|
|
105
|
+
const r = await this.validateIncomingData();
|
|
106
|
+
if(r === -1) return res.status(400).json({ errors: this._validation_errors })
|
|
107
|
+
next();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
runmethod_addvalidation (res, injectedData, next) {
|
|
111
|
+
this.addValidation(injectedData.validation);
|
|
112
|
+
next()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
getAppState () {
|
|
116
|
+
return this.instance.appState;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
validateDataObj () {
|
|
120
|
+
let obj = {};
|
|
121
|
+
this.validData.forEach((v, k) => obj[k] = v);
|
|
122
|
+
return obj;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
*
|
|
128
|
+
* @param {String} name
|
|
129
|
+
* @returns {import("mongoose").Model}
|
|
130
|
+
*/
|
|
131
|
+
getModel (name) {
|
|
132
|
+
return this.models.get(name) || null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
files () {
|
|
136
|
+
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @returns {Number} 0 | -1 for error;
|
|
141
|
+
*/
|
|
142
|
+
async validateIncomingData() {
|
|
143
|
+
await this.body();
|
|
144
|
+
for (let index = 0; index < this._validations.length; index++) await this._validations[index].validate(this);
|
|
145
|
+
if(this._validation_errors.length > 0) return -1;
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ! methods not implemented //
|
|
150
|
+
|
|
151
|
+
/** @require_implemetation @returns {String} token */
|
|
152
|
+
getBearerAuth() {
|
|
153
|
+
console.log("You have not implemeneted method 'getBearerAuth'");
|
|
154
|
+
}
|
|
155
|
+
/** @require_implemetation @returns {BasicAuth} {user:str, pass:str} */
|
|
156
|
+
getBasicAuth() {
|
|
157
|
+
console.log("You have not implemeneted method 'getBasicAuth'");
|
|
158
|
+
}
|
|
159
|
+
/** @require_implemetation @returns {Object} */
|
|
160
|
+
getBearerJWTData() {
|
|
161
|
+
console.log("You have not implemeneted method 'getBearerJWTData'");
|
|
162
|
+
}
|
|
163
|
+
/** @require_implemetation @returns {Number} 0 ok or -1 for error */
|
|
164
|
+
validateFormdata() {
|
|
165
|
+
console.log("You have not implemeneted method 'validateFormdata'");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @interface_method
|
|
170
|
+
* @param {String | Buffer} rowData
|
|
171
|
+
* @returns {String} xml string
|
|
172
|
+
*/
|
|
173
|
+
getXmlBody(rowData) {
|
|
174
|
+
console.log("You have not implemeneted method 'getXmlBody'");
|
|
175
|
+
return rowData;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @interface_method
|
|
180
|
+
* @doc - you can override this method;
|
|
181
|
+
* @param {String | Buffer} rowData
|
|
182
|
+
* @returns {Object | Object[]}
|
|
183
|
+
*/
|
|
184
|
+
getFormUrlEncoded(rowData) {
|
|
185
|
+
console.log("You have not implemeneted method 'getFormUrlEncoded'");
|
|
186
|
+
return rowData;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @interface_method
|
|
191
|
+
* @doc - you can override this method;
|
|
192
|
+
* @param {String | Buffer} rowData
|
|
193
|
+
* @returns {*} default is string
|
|
194
|
+
*/
|
|
195
|
+
getDefaultBody(rowData) {return rowData.toString()}
|
|
196
|
+
|
|
197
|
+
// ? implemented methods //
|
|
198
|
+
|
|
199
|
+
async genericBody()
|
|
200
|
+
{
|
|
201
|
+
if(this.bodyFetched === true) return this._body.toString(); // on 1 milion loops -> gain ~100ms performance;
|
|
202
|
+
return new Promise((resolve, reject) => {
|
|
203
|
+
let data = [];
|
|
204
|
+
this.IncomingMessage.on("data", (e) => {
|
|
205
|
+
data.push(e);
|
|
206
|
+
});
|
|
207
|
+
this.IncomingMessage.on("end", (e) => {
|
|
208
|
+
this.bodyFetched = true;
|
|
209
|
+
this._body = Buffer.concat(data);
|
|
210
|
+
resolve(this._body.toString());
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @doc some methods are not implmenent by default
|
|
217
|
+
* @returns {*} base on headers["content-type"]
|
|
218
|
+
*/
|
|
219
|
+
async body()
|
|
220
|
+
{
|
|
221
|
+
switch (this.headers()["content-type"]) {
|
|
222
|
+
case "application/json":
|
|
223
|
+
return this.getJsonBody(await this.genericBody());
|
|
224
|
+
case "application/javascript":
|
|
225
|
+
return this.getJavascriptBody(await this.genericBody());
|
|
226
|
+
case "application/xml":
|
|
227
|
+
return this.getXmlBody(await this.genericBody());
|
|
228
|
+
case "text/html":
|
|
229
|
+
return this.getHtmlBody(await this.genericBody());
|
|
230
|
+
case "text/plain":
|
|
231
|
+
return (await this.genericBody()).toString();
|
|
232
|
+
case "application/x-www-form-urlencoded":
|
|
233
|
+
return this.getFormUrlEncoded(await this.genericBody());
|
|
234
|
+
default:
|
|
235
|
+
return this.getDefaultBody(await this.genericBody());
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* @param {String | Buffer} rowData
|
|
242
|
+
* @returns {Object | Object[]}
|
|
243
|
+
*/
|
|
244
|
+
getJsonBody(rowData)
|
|
245
|
+
{
|
|
246
|
+
return JSON.parse(rowData.toString());
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* @param {String | Buffer} rowData
|
|
251
|
+
* @returns {String}
|
|
252
|
+
*/
|
|
253
|
+
getHtmlBody(rowData)
|
|
254
|
+
{
|
|
255
|
+
return rowData.toString();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* @doc - you can override this method;
|
|
260
|
+
* @param {String | Buffer} rowData
|
|
261
|
+
* @returns {String} string of javascript code;
|
|
262
|
+
*/
|
|
263
|
+
getJavascriptBody(rowData)
|
|
264
|
+
{
|
|
265
|
+
return rowData.toString();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @doc - the first time this function is running, will cache the params for next use;
|
|
270
|
+
* @returns {Map<String, Object>}
|
|
271
|
+
*/
|
|
272
|
+
params()
|
|
273
|
+
{
|
|
274
|
+
if (this._params) return this._params; // ! this line improving performance 2-3x times per 1000 lopping params();
|
|
275
|
+
this._params = new Map();
|
|
276
|
+
this.current.dynamic_path_parts.map((i) => {
|
|
277
|
+
this._params.set(i.property, this.current.current_path_parts[i.index]);
|
|
278
|
+
});
|
|
279
|
+
return this._params;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* @doc - the first time this function is running, will cache the params for next use;
|
|
284
|
+
* @returns {Object} Object
|
|
285
|
+
*/
|
|
286
|
+
paramsObj()
|
|
287
|
+
{
|
|
288
|
+
let returnObj = new Object();
|
|
289
|
+
if (this._params) { // ! this line improving performance 2-3x times per 1000 lopping params();
|
|
290
|
+
this._params.forEach((v, k) => returnObj[k] = v);
|
|
291
|
+
return returnObj;
|
|
292
|
+
}
|
|
293
|
+
this._params = new Map();
|
|
294
|
+
this.current.dynamic_path_parts.map((i) => {
|
|
295
|
+
this._params.set(i.property, this.current.current_path_parts[i.index]);
|
|
296
|
+
});
|
|
297
|
+
this._params.forEach((v, k) => returnObj[k] = v);
|
|
298
|
+
return returnObj;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/** @returns {URLSearchParams} URLSearchParams */
|
|
302
|
+
queries()
|
|
303
|
+
{
|
|
304
|
+
return new URLSearchParams(this.IncomingMessage.url.split("?")[1] || "");
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** @returns {Object} Object */
|
|
308
|
+
queriesObj ()
|
|
309
|
+
{
|
|
310
|
+
let queriesObj = new Object()
|
|
311
|
+
new URLSearchParams(this.IncomingMessage.url.split("?")[1] || "").forEach((v, k) => {
|
|
312
|
+
if(queriesObj[k]) {
|
|
313
|
+
if(queriesObj[k] instanceof Array === true) {
|
|
314
|
+
queriesObj[k].push(v);
|
|
315
|
+
} else {
|
|
316
|
+
queriesObj[k] = [queriesObj[k], v];
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
queriesObj[k] = v
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
return queriesObj;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** @returns {http.IncomingMessage.headers} http.IncomingMessage.headers */
|
|
326
|
+
headers()
|
|
327
|
+
{
|
|
328
|
+
return this.IncomingMessage.headers;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/** @returns {String} */
|
|
332
|
+
method()
|
|
333
|
+
{
|
|
334
|
+
return this.current.method;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** @returns {String} */
|
|
338
|
+
httpVersion()
|
|
339
|
+
{
|
|
340
|
+
return this.IncomingMessage.httpVersion;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/** @returns {String} */
|
|
344
|
+
remoteAddress()
|
|
345
|
+
{
|
|
346
|
+
return this.IncomingMessage.socket.remoteAddress;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/** @returns {Number} */
|
|
350
|
+
remotePort()
|
|
351
|
+
{
|
|
352
|
+
return this.IncomingMessage.socket.remotePort;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/** @returns {String} */
|
|
356
|
+
localAddress()
|
|
357
|
+
{
|
|
358
|
+
return this.IncomingMessage.socket.localAddress;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/** @returns {Number} */
|
|
362
|
+
localPort()
|
|
363
|
+
{
|
|
364
|
+
return this.IncomingMessage.socket.localPort;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** @returns {String} */
|
|
368
|
+
localPort()
|
|
369
|
+
{
|
|
370
|
+
return this.IncomingMessage.socket.localPort;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/** @returns {String} */
|
|
374
|
+
url()
|
|
375
|
+
{
|
|
376
|
+
return this.IncomingMessage.url;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* @param {String} key
|
|
381
|
+
* @param {*} value
|
|
382
|
+
* @returns {void}
|
|
383
|
+
*/
|
|
384
|
+
setState(key, value)
|
|
385
|
+
{
|
|
386
|
+
this.state.set(key, value);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* @param {String} key
|
|
391
|
+
* @returns {* | null}
|
|
392
|
+
*/
|
|
393
|
+
useState(key)
|
|
394
|
+
{
|
|
395
|
+
return this.state.get(key) || null;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
};
|