te.js 1.1.5 → 1.2.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/package.json +2 -2
- package/server/ammo.js +112 -112
- package/server/handler.js +9 -8
- package/utils/auto-register.js +5 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "te.js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "A nodejs framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "te.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"formidable": "^3.5.1",
|
|
28
28
|
"mime": "^4.0.1",
|
|
29
29
|
"statuses": "^2.0.1",
|
|
30
|
-
"tej-env": "^1.1.
|
|
30
|
+
"tej-env": "^1.1.1",
|
|
31
31
|
"tej-logger": "^1.2.1"
|
|
32
32
|
},
|
|
33
33
|
"lint-staged": {
|
package/server/ammo.js
CHANGED
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
import { statusAndData } from './ammo/dispatch-helper.js';
|
|
2
|
-
import {
|
|
3
|
-
isStatusCode,
|
|
4
|
-
toStatusCode,
|
|
5
|
-
toStatusMessage,
|
|
6
|
-
} from '../utils/status-codes.js';
|
|
7
|
-
import html from '../utils/tejas-entrypoint-html.js';
|
|
8
|
-
import ammoEnhancer from './ammo/enhancer.js';
|
|
9
|
-
import TejError from './error.js';
|
|
10
|
-
|
|
11
|
-
class Ammo {
|
|
12
|
-
constructor(req, res) {
|
|
13
|
-
this.req = req;
|
|
14
|
-
this.res = res;
|
|
15
|
-
|
|
16
|
-
this.GET = false;
|
|
17
|
-
this.POST = false;
|
|
18
|
-
this.PUT = false;
|
|
19
|
-
this.DELETE = false;
|
|
20
|
-
this.PATCH = false;
|
|
21
|
-
this.HEAD = false;
|
|
22
|
-
this.OPTIONS = false;
|
|
23
|
-
|
|
24
|
-
// Request related data
|
|
25
|
-
this.ip = undefined;
|
|
26
|
-
this.headers = undefined;
|
|
27
|
-
this.payload = undefined;
|
|
28
|
-
this.method = undefined;
|
|
29
|
-
|
|
30
|
-
// URL related data
|
|
31
|
-
this.protocol = undefined;
|
|
32
|
-
this.hostname = undefined;
|
|
33
|
-
this.path = undefined;
|
|
34
|
-
this.endpoint = undefined;
|
|
35
|
-
|
|
36
|
-
this.fullURL = undefined;
|
|
37
|
-
|
|
38
|
-
// Response related data
|
|
39
|
-
this.dispatchedData = undefined;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async enhance() {
|
|
43
|
-
await ammoEnhancer(this);
|
|
44
|
-
|
|
45
|
-
this.GET = this.method === 'GET';
|
|
46
|
-
this.POST = this.method === 'POST';
|
|
47
|
-
this.PUT = this.method === 'PUT';
|
|
48
|
-
this.DELETE = this.method === 'DELETE';
|
|
49
|
-
this.PATCH = this.method === 'PATCH';
|
|
50
|
-
this.HEAD = this.method === 'HEAD';
|
|
51
|
-
this.OPTIONS = this.method === 'OPTIONS';
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
fire() {
|
|
55
|
-
const { statusCode, data, contentType } = statusAndData(arguments);
|
|
56
|
-
const contentTypeHeader = { 'Content-Type': contentType };
|
|
57
|
-
|
|
58
|
-
this.dispatchedData = data;
|
|
59
|
-
|
|
60
|
-
this.res.writeHead(statusCode, contentTypeHeader);
|
|
61
|
-
this.res.write(data ?? '');
|
|
62
|
-
this.res.end();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
notFound() {
|
|
66
|
-
throw new TejError(404, 'Not Found');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
notAllowed() {
|
|
70
|
-
throw new TejError(405, 'Method Not Allowed');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
unauthorized() {
|
|
74
|
-
throw new TejError(401, 'Unauthorized');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
defaultEntry() {
|
|
78
|
-
this.fire(html);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
throw() {
|
|
82
|
-
const errCode = arguments[0];
|
|
83
|
-
const err = arguments[1];
|
|
84
|
-
|
|
85
|
-
let errMsg = err instanceof Error ? err.message : err.toString();
|
|
86
|
-
|
|
87
|
-
if (errCode && isStatusCode(errCode)) {
|
|
88
|
-
if (!errMsg) errMsg = toStatusMessage(errCode);
|
|
89
|
-
this.fire(errCode, errMsg);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (err instanceof Error) {
|
|
94
|
-
const errMessage = err.message;
|
|
95
|
-
|
|
96
|
-
if (!isNaN(parseInt(errMessage))) {
|
|
97
|
-
// Execute when errMessage is a number. Notice ! in front of isNan
|
|
98
|
-
const message = toStatusMessage(errMessage) ?? toStatusMessage(500);
|
|
99
|
-
this.fire(message, message);
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const code = toStatusCode(errMsg) ?? 500;
|
|
104
|
-
this.fire(code, errMsg);
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
this.fire(err);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export default Ammo;
|
|
1
|
+
import { statusAndData } from './ammo/dispatch-helper.js';
|
|
2
|
+
import {
|
|
3
|
+
isStatusCode,
|
|
4
|
+
toStatusCode,
|
|
5
|
+
toStatusMessage,
|
|
6
|
+
} from '../utils/status-codes.js';
|
|
7
|
+
import html from '../utils/tejas-entrypoint-html.js';
|
|
8
|
+
import ammoEnhancer from './ammo/enhancer.js';
|
|
9
|
+
import TejError from './error.js';
|
|
10
|
+
|
|
11
|
+
class Ammo {
|
|
12
|
+
constructor(req, res) {
|
|
13
|
+
this.req = req;
|
|
14
|
+
this.res = res;
|
|
15
|
+
|
|
16
|
+
this.GET = false;
|
|
17
|
+
this.POST = false;
|
|
18
|
+
this.PUT = false;
|
|
19
|
+
this.DELETE = false;
|
|
20
|
+
this.PATCH = false;
|
|
21
|
+
this.HEAD = false;
|
|
22
|
+
this.OPTIONS = false;
|
|
23
|
+
|
|
24
|
+
// Request related data
|
|
25
|
+
this.ip = undefined;
|
|
26
|
+
this.headers = undefined;
|
|
27
|
+
this.payload = undefined;
|
|
28
|
+
this.method = undefined;
|
|
29
|
+
|
|
30
|
+
// URL related data
|
|
31
|
+
this.protocol = undefined;
|
|
32
|
+
this.hostname = undefined;
|
|
33
|
+
this.path = undefined;
|
|
34
|
+
this.endpoint = undefined;
|
|
35
|
+
|
|
36
|
+
this.fullURL = undefined;
|
|
37
|
+
|
|
38
|
+
// Response related data
|
|
39
|
+
this.dispatchedData = undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async enhance() {
|
|
43
|
+
await ammoEnhancer(this);
|
|
44
|
+
|
|
45
|
+
this.GET = this.method === 'GET';
|
|
46
|
+
this.POST = this.method === 'POST';
|
|
47
|
+
this.PUT = this.method === 'PUT';
|
|
48
|
+
this.DELETE = this.method === 'DELETE';
|
|
49
|
+
this.PATCH = this.method === 'PATCH';
|
|
50
|
+
this.HEAD = this.method === 'HEAD';
|
|
51
|
+
this.OPTIONS = this.method === 'OPTIONS';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fire() {
|
|
55
|
+
const { statusCode, data, contentType } = statusAndData(arguments);
|
|
56
|
+
const contentTypeHeader = { 'Content-Type': contentType };
|
|
57
|
+
|
|
58
|
+
this.dispatchedData = data;
|
|
59
|
+
|
|
60
|
+
this.res.writeHead(statusCode, contentTypeHeader);
|
|
61
|
+
this.res.write(data ?? '');
|
|
62
|
+
this.res.end();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
notFound() {
|
|
66
|
+
throw new TejError(404, 'Not Found');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
notAllowed() {
|
|
70
|
+
throw new TejError(405, 'Method Not Allowed');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
unauthorized() {
|
|
74
|
+
throw new TejError(401, 'Unauthorized');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
defaultEntry() {
|
|
78
|
+
this.fire(html);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
throw() {
|
|
82
|
+
const errCode = arguments[0];
|
|
83
|
+
const err = arguments[1];
|
|
84
|
+
|
|
85
|
+
let errMsg = err instanceof Error ? err.message : err.toString();
|
|
86
|
+
|
|
87
|
+
if (errCode && isStatusCode(errCode)) {
|
|
88
|
+
if (!errMsg) errMsg = toStatusMessage(errCode);
|
|
89
|
+
this.fire(errCode, errMsg);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (err instanceof Error) {
|
|
94
|
+
const errMessage = err.message;
|
|
95
|
+
|
|
96
|
+
if (!isNaN(parseInt(errMessage))) {
|
|
97
|
+
// Execute when errMessage is a number. Notice ! in front of isNan
|
|
98
|
+
const message = toStatusMessage(errMessage) ?? toStatusMessage(500);
|
|
99
|
+
this.fire(message, message);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const code = toStatusCode(errMsg) ?? 500;
|
|
104
|
+
this.fire(code, errMsg);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.fire(err);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export default Ammo;
|
package/server/handler.js
CHANGED
|
@@ -35,8 +35,7 @@ const executeChain = async (target, ammo) => {
|
|
|
35
35
|
const errorHandler = (ammo, err) => {
|
|
36
36
|
if (env('LOG_EXCEPTIONS')) errorLogger.error(err);
|
|
37
37
|
|
|
38
|
-
if (err instanceof TejError)
|
|
39
|
-
return ammo.throw(err.code, err);
|
|
38
|
+
if (err instanceof TejError) return ammo.throw(err.code, err);
|
|
40
39
|
|
|
41
40
|
ammo.throw(500, err);
|
|
42
41
|
};
|
|
@@ -44,22 +43,24 @@ const errorHandler = (ammo, err) => {
|
|
|
44
43
|
const handler = async (req, res) => {
|
|
45
44
|
const target = targetRegistry.aim(req.method, req.url.split('?')[0]);
|
|
46
45
|
const ammo = new Ammo(req, res);
|
|
47
|
-
await ammo.enhance();
|
|
48
|
-
|
|
49
|
-
if (env('LOG_HTTP_REQUESTS')) logHttpRequest(ammo);
|
|
50
46
|
|
|
51
47
|
try {
|
|
52
48
|
if (target) {
|
|
49
|
+
await ammo.enhance();
|
|
50
|
+
|
|
51
|
+
if (env('LOG_HTTP_REQUESTS')) logHttpRequest(ammo);
|
|
53
52
|
await executeChain(target, ammo);
|
|
53
|
+
|
|
54
54
|
} else {
|
|
55
55
|
if (req.url === '/') {
|
|
56
56
|
ammo.defaultEntry();
|
|
57
57
|
} else {
|
|
58
58
|
errorHandler(
|
|
59
59
|
ammo,
|
|
60
|
-
new TejError(
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
new TejError(
|
|
61
|
+
404,
|
|
62
|
+
`No target found for URL ${ammo.fullURL} with method ${ammo.method}`,
|
|
63
|
+
),
|
|
63
64
|
);
|
|
64
65
|
}
|
|
65
66
|
}
|
package/utils/auto-register.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'path';
|
|
2
3
|
|
|
3
4
|
const findTargetFiles = async () => {
|
|
4
5
|
if (!process.env.DIR_TARGETS) return;
|
|
5
|
-
const fullPath =
|
|
6
|
+
const fullPath = path.join(process.cwd(), process.env.DIR_TARGETS);
|
|
6
7
|
const directory = await fs.readdir(fullPath, {
|
|
7
8
|
withFileTypes: true,
|
|
8
|
-
recursive: true
|
|
9
|
+
recursive: true,
|
|
9
10
|
});
|
|
10
11
|
|
|
11
12
|
return directory.filter(
|
|
12
|
-
(file) => file.isFile() && file.name.endsWith('target.js')
|
|
13
|
-
|
|
13
|
+
(file) => file.isFile() && file.name.endsWith('target.js'),
|
|
14
|
+
);
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
export { findTargetFiles };
|