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,94 @@
|
|
|
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
|
+
const http = require("http");
|
|
19
|
+
const Route = require("./Route");
|
|
20
|
+
|
|
21
|
+
module.exports = class ResponseInterface
|
|
22
|
+
{
|
|
23
|
+
/** @type{http.OutgoingMessage} */ OutgoingMessage;
|
|
24
|
+
/** @type {Route} */ current;
|
|
25
|
+
/** @type {import("../TurboServer")} */ instance;
|
|
26
|
+
/** @type {Map<String, import("mongoose").Model>} */ models;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {http.OutgoingMessage} res
|
|
30
|
+
* @param {Route} current
|
|
31
|
+
* @param {import("../TurboServer")} instance
|
|
32
|
+
*/
|
|
33
|
+
constructor(res, current, instance)
|
|
34
|
+
{
|
|
35
|
+
this.current = current;
|
|
36
|
+
this.OutgoingMessage = res;
|
|
37
|
+
this.statusCode = 200;
|
|
38
|
+
this.response = new Object();
|
|
39
|
+
this.instance = instance;
|
|
40
|
+
this.models = instance.models;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
status(status)
|
|
44
|
+
{
|
|
45
|
+
this.statusCode = !isNaN(status) ? Number(status) : 500;
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
send(string, contentType)
|
|
50
|
+
{
|
|
51
|
+
this.OutgoingMessage.writeHead(this.statusCode, {
|
|
52
|
+
"Content-Type": contentType || "text/html",
|
|
53
|
+
});
|
|
54
|
+
this.OutgoingMessage.end(string);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
json(data)
|
|
58
|
+
{
|
|
59
|
+
this.OutgoingMessage.writeHead(this.statusCode, {
|
|
60
|
+
"Content-Type": "application/json",
|
|
61
|
+
});
|
|
62
|
+
this.OutgoingMessage.end(JSON.stringify(data));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** @require_implemetation @returns {void} should implement 1) convert object to xml 2) send response 3) close the connection */
|
|
66
|
+
xml() {
|
|
67
|
+
console.log("You have not implemeneted method 'xml'");
|
|
68
|
+
}
|
|
69
|
+
/** @require_implemetation @returns {BasicAuth} comming soon */
|
|
70
|
+
sendFile() {
|
|
71
|
+
console.log("You have not implemeneted method 'sendFile'");
|
|
72
|
+
}
|
|
73
|
+
/** @require_implemetation @returns {Object} broadact data to specific users, works with web sockets connections */
|
|
74
|
+
broadcast() {
|
|
75
|
+
console.log("You have not implemeneted method 'broadcast'");
|
|
76
|
+
}
|
|
77
|
+
/** @require_implemetation @returns {Number} broadact data to specific user, works with web sockets connections */
|
|
78
|
+
broadcastTo() {
|
|
79
|
+
console.log("You have not implemeneted method 'broadcastTo'");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** @doc - require to be implemented */
|
|
83
|
+
useRedis() {
|
|
84
|
+
console.log("You have not implemeneted method 'useRedis'");
|
|
85
|
+
}
|
|
86
|
+
/** @doc - require to be implemented */
|
|
87
|
+
storeRedis() {
|
|
88
|
+
console.log("You have not implemeneted method 'storeRedis'");
|
|
89
|
+
}
|
|
90
|
+
/** @doc - require to be implemented */
|
|
91
|
+
refreshRedis() {
|
|
92
|
+
console.log("You have not implemeneted method 'refreshRedis'");
|
|
93
|
+
}
|
|
94
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
// todo implmenet some basic methods for mongodb;
|
|
19
|
+
|
|
20
|
+
const ResponseInterface = require("./ResponseInterface");
|
|
21
|
+
|
|
22
|
+
module.exports = class ResponseMongo extends ResponseInterface
|
|
23
|
+
{
|
|
24
|
+
|
|
25
|
+
sendCollRead () {}
|
|
26
|
+
|
|
27
|
+
sendCollWrite () {}
|
|
28
|
+
|
|
29
|
+
sendCollUpdate () {}
|
|
30
|
+
|
|
31
|
+
sendCollDelete () {}
|
|
32
|
+
|
|
33
|
+
exeRaadOperation(Model, )
|
|
34
|
+
|
|
35
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
const { matching_route_middlewares } = require("../utils")
|
|
19
|
+
const Middleware = require("./Middleware")
|
|
20
|
+
|
|
21
|
+
module.exports = class Route
|
|
22
|
+
{
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @doc all this properties will be used once to find if middleware is matching the route.
|
|
26
|
+
* if it does then the callbacks will be pushed at the begining of the route.callbacks
|
|
27
|
+
*
|
|
28
|
+
* @useMinLength actually if path endwith /* that group all of these middlewares in their own category
|
|
29
|
+
* on server callback will be executed 2 matching functions
|
|
30
|
+
*
|
|
31
|
+
* 1rst one is exact that mean it will try to match route that not end with /* and has the same length of path parts;
|
|
32
|
+
*
|
|
33
|
+
* if the first not find something, only then it will go to the next function
|
|
34
|
+
* in the second function, here is where useMinLength = true group is used.
|
|
35
|
+
*
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @typedef {Object} DynamicPathPart;
|
|
41
|
+
* @property {Number} index;
|
|
42
|
+
* @property {String} property;
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/** @type {String} */ path
|
|
46
|
+
/** @type {String} */ method
|
|
47
|
+
/** @type {String[]} */ path_parts
|
|
48
|
+
/** @type {DynamicPathPart[]} */ dynamic_path_parts
|
|
49
|
+
/** @type {Boolean} */ useMinlength
|
|
50
|
+
/** @type {Number} */ size
|
|
51
|
+
/** @type {Function[]} */ callbacks = []
|
|
52
|
+
/** @type {String[]} */ current_path_parts = [];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* todo validation check and warn for wrong type;
|
|
56
|
+
* @param {String} path
|
|
57
|
+
* @param {Function[]} callbacks
|
|
58
|
+
* @param {Middleware[]} middlewares
|
|
59
|
+
* @param {Middleware[]} middlewares_end
|
|
60
|
+
*/
|
|
61
|
+
constructor(path, method, callbacks, middlewares, middlewares_end) {
|
|
62
|
+
this.path = path;
|
|
63
|
+
this.method = method;
|
|
64
|
+
this.path_parts = path.split("/").filter(f => f !== "");
|
|
65
|
+
this.dynamic_path_parts = this.#setDynamicPathParts();
|
|
66
|
+
this.useMinlength = path.endsWith("/*");
|
|
67
|
+
this.size = path.endsWith("/*") ? this.path_parts.length - 1 : this.path_parts.length;
|
|
68
|
+
this.useMiddlewares(middlewares)
|
|
69
|
+
callbacks.map(c => {
|
|
70
|
+
if(c instanceof Function) return this.callbacks.push(c);
|
|
71
|
+
throw new Error("Callback should be instance of function");
|
|
72
|
+
})
|
|
73
|
+
this.useMiddlewares(middlewares_end)
|
|
74
|
+
//console.log(this)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
setCurrentPathParts (current_path_parts) { this.current_path_parts = current_path_parts; }
|
|
78
|
+
getCurrentPathParts () { return this.current_path_parts; }
|
|
79
|
+
|
|
80
|
+
#setDynamicPathParts ()
|
|
81
|
+
{
|
|
82
|
+
let tmpArr = []
|
|
83
|
+
for (let i = 0; i < this.path_parts.length; i++) {
|
|
84
|
+
if(this.path_parts[i].startsWith(":")) { tmpArr.push({ index: i, property: this.path_parts[i].substring(1, this.path_parts[i].length) }) }
|
|
85
|
+
}
|
|
86
|
+
return tmpArr;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @param {Middleware[]} middlewares
|
|
91
|
+
*/
|
|
92
|
+
useMiddlewares (middlewares)
|
|
93
|
+
{
|
|
94
|
+
matching_route_middlewares(this.path_parts, this.useMinlength, this.size, middlewares).map(m => m.callbacks.map(mc => this.callbacks.push(mc)))
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
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 RunMethodType
|
|
20
|
+
{
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
/** @type {String} */ path;
|
|
29
|
+
/** @type {String[]} */ path_parts;
|
|
30
|
+
/** @type {Boolean} */ useMinlength;
|
|
31
|
+
/** @type {Number} */ size;
|
|
32
|
+
/** @type {Function[]} */ callbacks = new Array();
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* todo validation check and warn for wrong type;
|
|
36
|
+
* @param {String} path
|
|
37
|
+
* @param {Function[]} callbacks
|
|
38
|
+
*/
|
|
39
|
+
constructor(path, callbacks)
|
|
40
|
+
{
|
|
41
|
+
this.path = path;
|
|
42
|
+
this.path_parts = path.split("/").filter((f) => f !== "");
|
|
43
|
+
this.useMinlength = path.endsWith("/*");
|
|
44
|
+
this.size = path.endsWith("/*")
|
|
45
|
+
? this.path_parts.length - 1
|
|
46
|
+
: this.path_parts.length;
|
|
47
|
+
this.callbacks = callbacks || [];
|
|
48
|
+
}
|
|
49
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
3
|
+
*
|
|
4
|
+
* @PerfecTEvolutioN
|
|
5
|
+
* @MikeKarypidis
|
|
6
|
+
* @project - TurboExpress
|
|
7
|
+
* @name ValidationError
|
|
8
|
+
* @namespace TurboExpress::types::ValidationError
|
|
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
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** @Type */
|
|
22
|
+
module.exports = class ValidationError
|
|
23
|
+
{
|
|
24
|
+
|
|
25
|
+
/** @type {String} */ namespace;
|
|
26
|
+
/** @type {String} */ property;
|
|
27
|
+
/** @type {*} */ value;
|
|
28
|
+
/** @type {String[]} */ errors = new Array();
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @param {String} path
|
|
33
|
+
* @param {Function[]} callbacks
|
|
34
|
+
*/
|
|
35
|
+
constructor(namespace, property)
|
|
36
|
+
{
|
|
37
|
+
this.namespace = namespace;
|
|
38
|
+
this.property = property;
|
|
39
|
+
this.value = null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {String} error
|
|
44
|
+
*/
|
|
45
|
+
addError (error)
|
|
46
|
+
{
|
|
47
|
+
this.errors.push(error);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setValue(value) {
|
|
51
|
+
if(value === undefined) this.value = null;
|
|
52
|
+
this.value = value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
3
|
+
*
|
|
4
|
+
* @PerfecTEvolutioN
|
|
5
|
+
* @MikeKarypidis
|
|
6
|
+
* @project - TurboExpress
|
|
7
|
+
* @name ValidationSchema
|
|
8
|
+
* @namespace TurboExpress::types::ValidationSchema
|
|
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
|
+
* For each property, we are set a new validation schema instance;
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const ValidationMethodType = require("../enum/ValidationMethodType");
|
|
23
|
+
const RequestInterface = require("./RequestInterface");
|
|
24
|
+
const ValidationError = require("./ValidationError");
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {Object} ValidationType
|
|
28
|
+
* @property {String} name;
|
|
29
|
+
* @property {String} value;
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/** @Type */
|
|
33
|
+
module.exports = class ValidationSchema
|
|
34
|
+
{
|
|
35
|
+
|
|
36
|
+
/** @type {String} */ namespace;
|
|
37
|
+
/** @type {String} */ property;
|
|
38
|
+
/** @type {ValidationType[]} */ validations;
|
|
39
|
+
/** @type {Boolean} */ is_required;
|
|
40
|
+
/** @type {*} */ default_value;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {String} property - is required
|
|
44
|
+
* @param {ValidationType[]} validations - is required
|
|
45
|
+
* @param {Boolean} is_required - default false
|
|
46
|
+
* @param {*} default_value
|
|
47
|
+
* @param {String} namespace - default is body
|
|
48
|
+
*/
|
|
49
|
+
constructor(property, validations, is_required=true, default_value=null, namespace="body")
|
|
50
|
+
{
|
|
51
|
+
this.namespace = namespace;
|
|
52
|
+
this.default_value = default_value;
|
|
53
|
+
this.validations = validations instanceof Array === true ? validations : [];
|
|
54
|
+
if(typeof property === "string") {
|
|
55
|
+
this.property = property;
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error("property is required and should be type of string.");
|
|
58
|
+
}
|
|
59
|
+
this.is_required = typeof is_required === "boolean" ? is_required : false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* This method is async in case we want to intergrate it with database
|
|
64
|
+
* like is doc exist with that id.
|
|
65
|
+
* This is out of the box of the default implemetations.
|
|
66
|
+
*
|
|
67
|
+
* @param {RequestInterface} req
|
|
68
|
+
*/
|
|
69
|
+
async validate (req)
|
|
70
|
+
{
|
|
71
|
+
const vError = new ValidationError(this.namespace, this.property);
|
|
72
|
+
let currentValue = await this.getCurrentValue(req);
|
|
73
|
+
if(currentValue === undefined) {
|
|
74
|
+
if(this.default_value) {
|
|
75
|
+
currentValue = this.default_value;
|
|
76
|
+
}
|
|
77
|
+
if(this.is_required && (currentValue === undefined || currentValue === null)) {
|
|
78
|
+
vError.addError(`Property ${this.property} is required.`);
|
|
79
|
+
req._validation_errors.push(vError);
|
|
80
|
+
return console.log("~~~~~~~~~`");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if(currentValue === undefined && this.is_required === false) return;
|
|
84
|
+
this.validations.map((validation, vindex) => {
|
|
85
|
+
switch (validation.name) {
|
|
86
|
+
case ValidationMethodType.MINLENGTH:
|
|
87
|
+
if(currentValue.length < validation.value) {
|
|
88
|
+
vError.addError(`Property ${this.property} min length is ${validation.value}`)
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
|
|
92
|
+
case ValidationMethodType.MAXLENGTH:
|
|
93
|
+
if(currentValue.length > validation.value) {
|
|
94
|
+
vError.addError(`Property ${this.property} max length is ${validation.value}`)
|
|
95
|
+
}
|
|
96
|
+
break;
|
|
97
|
+
|
|
98
|
+
case ValidationMethodType.ONEOF:
|
|
99
|
+
if(validation.value instanceof Array === true && !validation.value.some(s => s === currentValue)) {
|
|
100
|
+
vError.addError(`Property ${this.property} should be one of: < ${validation.value.join(",")} >`)
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
|
|
104
|
+
case ValidationMethodType.SIZE:
|
|
105
|
+
console.log("min size here", validation.value);
|
|
106
|
+
|
|
107
|
+
break;
|
|
108
|
+
|
|
109
|
+
default:
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
if(vError.errors.length > 0) {
|
|
114
|
+
vError.setValue(currentValue);
|
|
115
|
+
req._validation_errors.push(vError);
|
|
116
|
+
} else {
|
|
117
|
+
req.validData.set(this.property, currentValue);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
*
|
|
124
|
+
* @param {RequestInterface} req
|
|
125
|
+
*/
|
|
126
|
+
async getCurrentValue (req)
|
|
127
|
+
{
|
|
128
|
+
if(this.namespace === "query") {
|
|
129
|
+
return req.queriesObj()[this.property];
|
|
130
|
+
} else if(this.namespace === "body") {
|
|
131
|
+
const body = await req.body();
|
|
132
|
+
return body[this.property];
|
|
133
|
+
} else if(this.namespace === "params") {
|
|
134
|
+
return req.params().get(this.property);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* -->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>
|
|
3
|
+
*
|
|
4
|
+
* @PerfecTEvolutioN
|
|
5
|
+
* @MikeKarypidis
|
|
6
|
+
* @project - TurboExpress
|
|
7
|
+
* @name ValidationStaticTypes
|
|
8
|
+
* @namespace TurboExpress::types::ValidationStaticTypes
|
|
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
|
+
* For each property, we are set a new validation schema instance;
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/** @StaticType */
|
|
23
|
+
module.exports = class ValidationStaticTypes
|
|
24
|
+
{
|
|
25
|
+
static MINLENGTH = "MINLENGTH";
|
|
26
|
+
static MAXLENGTH = "MAXLENGTH";
|
|
27
|
+
static ISREQUIRED = "ISREQUIRED";
|
|
28
|
+
static ONEOF = "ONEOF";
|
|
29
|
+
static NOTONEOF = "NOTONEOF";
|
|
30
|
+
static REGEX = "REGEX";
|
|
31
|
+
static RANGE = "RANGE";
|
|
32
|
+
static FUNCTION = "FUNCTION";
|
|
33
|
+
}
|
|
34
|
+
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const Middleware = require("./types/Middleware");
|
|
2
|
+
const Route = require("./types/Route");
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {String} current_path
|
|
6
|
+
* @param {Route[]} routes
|
|
7
|
+
* @returns {Route | null}
|
|
8
|
+
*/
|
|
9
|
+
module.exports.matching_route = (current_path, routes) => {
|
|
10
|
+
|
|
11
|
+
const path_parts = current_path.split("/").filter(f => f !== "");
|
|
12
|
+
let samelength = routes.filter(f=> f.size === path_parts.length && !f.useMinlength)
|
|
13
|
+
let curr = null;
|
|
14
|
+
for (let index = 0; index < samelength.length; index++) {
|
|
15
|
+
let ok = true;
|
|
16
|
+
path_parts.map((p, i) => {
|
|
17
|
+
if(samelength[index].path_parts[i].startsWith(":")) return;
|
|
18
|
+
if(p !== samelength[index].path_parts[i]) ok = false;
|
|
19
|
+
});
|
|
20
|
+
if(ok) { curr = samelength[index]; break; }
|
|
21
|
+
}
|
|
22
|
+
if(curr) curr.setCurrentPathParts(path_parts);
|
|
23
|
+
return curr;
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {String} current_path
|
|
30
|
+
* @param {Route[]} routes
|
|
31
|
+
* @returns {Route | null}
|
|
32
|
+
*/
|
|
33
|
+
module.exports.matching_nonexact_route = (current_path, routes) => {
|
|
34
|
+
|
|
35
|
+
const path_parts = current_path.split("/").filter(f => f !== "");
|
|
36
|
+
let nonexactroutes = routes.filter(f => f.useMinlength && f.size < path_parts.length).sort((a, b) => b.size - a.size);
|
|
37
|
+
let globalnotfound = routes.find(f => f.size === 1 && f.path_parts[0] === "*");
|
|
38
|
+
if(globalnotfound) { nonexactroutes.push(globalnotfound); }
|
|
39
|
+
let curr = null;
|
|
40
|
+
for (let index = 0; index < nonexactroutes.length; index++) {
|
|
41
|
+
let ok = true;
|
|
42
|
+
path_parts.map((p, i) => {
|
|
43
|
+
if(i === path_parts.length - 1) return;
|
|
44
|
+
if(i > nonexactroutes[index].path_parts.length - 2) return // route.path_parts are smaller in length than current path;
|
|
45
|
+
if(nonexactroutes[index].path_parts[i].startsWith(":")) return; // dynamic route
|
|
46
|
+
if(p !== nonexactroutes[index].path_parts[i]) ok = false;
|
|
47
|
+
});
|
|
48
|
+
if(ok) { curr = nonexactroutes[index]; break; }
|
|
49
|
+
}
|
|
50
|
+
if(curr) curr.setCurrentPathParts(path_parts);
|
|
51
|
+
return curr;
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {String[]} current_path
|
|
58
|
+
* @param {Boolean} current_useMinLength
|
|
59
|
+
* @param {Number} current_length
|
|
60
|
+
* @param {Middleware[]} middlewares
|
|
61
|
+
* @returns {Middleware[]}
|
|
62
|
+
*/
|
|
63
|
+
module.exports.matching_route_middlewares = (current_path_parts, current_useMinLength, current_length, middlewares) =>
|
|
64
|
+
{
|
|
65
|
+
const matchedMiddlewares = []
|
|
66
|
+
for (let m = 0; m < middlewares.length; m++) {
|
|
67
|
+
if(middlewares[m].useMinlength === false)
|
|
68
|
+
{
|
|
69
|
+
if(current_useMinLength) continue;
|
|
70
|
+
if(middlewares[m].size !== current_length) continue;
|
|
71
|
+
let checker = true;
|
|
72
|
+
for (let i = 0; i < current_path_parts.length; i++) {
|
|
73
|
+
if(current_path_parts[i].startsWith(":") && middlewares[m].path_parts[i].startsWith(":")) continue;
|
|
74
|
+
if(current_path_parts[i] !== middlewares[m].path_parts[i]) {
|
|
75
|
+
checker = false;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if(checker) {matchedMiddlewares.push(middlewares[m]); }
|
|
80
|
+
|
|
81
|
+
} else
|
|
82
|
+
{
|
|
83
|
+
if(current_useMinLength)
|
|
84
|
+
{
|
|
85
|
+
if( !(middlewares[m].size <= current_length) ) continue;
|
|
86
|
+
let checker = true;
|
|
87
|
+
for (let i = 0; i < middlewares[m].size; i++) {
|
|
88
|
+
if(current_path_parts[i].startsWith(":") && middlewares[m].path_parts[i].startsWith(":")) continue;
|
|
89
|
+
if(current_path_parts[i] !== middlewares[m].path_parts[i]) {
|
|
90
|
+
checker = false;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if(checker) {matchedMiddlewares.push(middlewares[m]); }
|
|
95
|
+
} else
|
|
96
|
+
{
|
|
97
|
+
if( !(middlewares[m].size < current_length) ) continue;
|
|
98
|
+
let checker = true;
|
|
99
|
+
for (let i = 0; i < middlewares[m].size; i++) {
|
|
100
|
+
if(current_path_parts[i].startsWith(":") && middlewares[m].path_parts[i].startsWith(":")) continue;
|
|
101
|
+
if(current_path_parts[i] !== middlewares[m].path_parts[i]) {
|
|
102
|
+
checker = false;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if(checker) {matchedMiddlewares.push(middlewares[m]); }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return matchedMiddlewares;
|
|
111
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "turbo-express-js",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "turbo express performance security easy to use web server framework ",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"directories": {
|
|
7
|
+
"lib": "lib"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"multiparty": "^4.2.3"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"start": "nodemon index.test.js"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/breathfunwithmindte/turbo-express.git"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"web",
|
|
25
|
+
"server",
|
|
26
|
+
"framwork",
|
|
27
|
+
"lightweight",
|
|
28
|
+
"minimalistic",
|
|
29
|
+
"superfast",
|
|
30
|
+
"fast"
|
|
31
|
+
],
|
|
32
|
+
"author": "Mike Karypidis",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/breathfunwithmindte/turbo-express/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/breathfunwithmindte/turbo-express#readme"
|
|
38
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# comming soon samples
|
package/todo.md
ADDED