@wxn0brp/falcon-frame 0.0.16 → 0.0.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/dist/helpers.js +1 -0
- package/dist/middleware.d.ts +3 -0
- package/dist/middleware.js +69 -0
- package/dist/render.js +2 -0
- package/dist/req.js +43 -103
- package/dist/res.d.ts +66 -3
- package/dist/res.js +82 -2
- package/dist/router.d.ts +9 -8
- package/dist/router.js +13 -1
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/helpers.js
CHANGED
|
@@ -76,6 +76,7 @@ export function handleStaticFiles(dirPath, utf8 = true) {
|
|
|
76
76
|
if (fs.existsSync(indexPath) && fs.statSync(indexPath).isFile()) {
|
|
77
77
|
if (!req.path.endsWith("/")) {
|
|
78
78
|
res.redirect(req.path + "/");
|
|
79
|
+
return true;
|
|
79
80
|
}
|
|
80
81
|
res.ct(getContentType(indexPath, utf8));
|
|
81
82
|
fs.createReadStream(indexPath).pipe(res);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export function matchMiddleware(url, middlewares) {
|
|
2
|
+
const matchedMiddlewares = [];
|
|
3
|
+
url = url.replace(/\/$/, "");
|
|
4
|
+
for (const middleware of middlewares) {
|
|
5
|
+
const cleanedMiddleware = middleware.path.replace(/\/$/, "");
|
|
6
|
+
if (middleware.use) {
|
|
7
|
+
if (url.startsWith(cleanedMiddleware)) {
|
|
8
|
+
matchedMiddlewares.push(middleware);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
else if (cleanedMiddleware === "*") {
|
|
12
|
+
matchedMiddlewares.push(middleware);
|
|
13
|
+
}
|
|
14
|
+
else if (cleanedMiddleware.endsWith("/*")) {
|
|
15
|
+
const prefix = cleanedMiddleware.slice(0, -2);
|
|
16
|
+
if (url.startsWith(prefix)) {
|
|
17
|
+
matchedMiddlewares.push(middleware);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else if (cleanedMiddleware.includes(":")) {
|
|
21
|
+
const middlewareParts = cleanedMiddleware.split("/");
|
|
22
|
+
const urlParts = url.split("/");
|
|
23
|
+
if (middlewareParts.length !== urlParts.length) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
let matches = true;
|
|
27
|
+
for (let i = 0; i < middlewareParts.length; i++) {
|
|
28
|
+
if (middlewareParts[i].startsWith(":")) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
else if (middlewareParts[i] !== urlParts[i]) {
|
|
32
|
+
matches = false;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (matches) {
|
|
37
|
+
matchedMiddlewares.push(middleware);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
if (url === cleanedMiddleware) {
|
|
42
|
+
matchedMiddlewares.push(middleware);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return matchedMiddlewares;
|
|
47
|
+
}
|
|
48
|
+
export function getMiddlewares(middlewares, matchUrl, basePath = "") {
|
|
49
|
+
const result = [];
|
|
50
|
+
for (const middleware of middlewares) {
|
|
51
|
+
const midPath = (middleware.path || "").replace(/\/+$/, "");
|
|
52
|
+
const fullPath = (basePath + "/" + midPath).replace(/\/+/g, "/");
|
|
53
|
+
const matches = matchUrl === fullPath ||
|
|
54
|
+
(middleware.use && matchUrl.startsWith(fullPath)) ||
|
|
55
|
+
fullPath.includes(":") ||
|
|
56
|
+
fullPath.includes("*") ||
|
|
57
|
+
matchUrl.startsWith(fullPath + "/");
|
|
58
|
+
if (!matches)
|
|
59
|
+
continue;
|
|
60
|
+
if (middleware.router) {
|
|
61
|
+
const nested = getMiddlewares(middleware.router, matchUrl, fullPath);
|
|
62
|
+
result.push(...nested);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
result.push({ ...middleware, path: fullPath });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
package/dist/render.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
export function renderHTML(templatePath, data) {
|
|
4
|
+
if (!fs.existsSync(templatePath))
|
|
5
|
+
return "Template not found";
|
|
4
6
|
let template = fs.readFileSync(templatePath, "utf8");
|
|
5
7
|
// Inserting data, e.g. {{name}}
|
|
6
8
|
template = template.replace(/{{(.*?)}}/g, (_, key) => data[key.trim()] || "");
|
package/dist/req.js
CHANGED
|
@@ -2,6 +2,7 @@ import { URL } from "url";
|
|
|
2
2
|
import { parseBody, parseCookies } from "./helpers.js";
|
|
3
3
|
import { FFResponse } from "./res.js";
|
|
4
4
|
import { validate } from "./valid.js";
|
|
5
|
+
import { getMiddlewares, matchMiddleware } from "./middleware.js";
|
|
5
6
|
export function handleRequest(req, res, FF) {
|
|
6
7
|
Object.setPrototypeOf(res, FFResponse.prototype);
|
|
7
8
|
const originalEnd = res.end;
|
|
@@ -26,117 +27,56 @@ export function handleRequest(req, res, FF) {
|
|
|
26
27
|
req.params = {};
|
|
27
28
|
req.valid = (schema) => validate(schema, req.body);
|
|
28
29
|
logger.info(`Incoming request: ${req.method} ${req.url}`);
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
req.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
let middlewareIndex = 0;
|
|
43
|
-
const next = async () => {
|
|
44
|
-
if (middlewareIndex >= matchedMiddlewares.length) {
|
|
45
|
-
return res.status(404).end("404: File had second thoughts");
|
|
46
|
-
}
|
|
47
|
-
const middleware = matchedMiddlewares[middlewareIndex++];
|
|
48
|
-
logger.debug(`Executing middleware ${middlewareIndex} of ${matchedMiddlewares.length} matched for path [${middleware.path}]`);
|
|
49
|
-
if (middleware.path.includes(":")) {
|
|
50
|
-
const middlewareParts = middleware.path.split("/");
|
|
51
|
-
const reqPathParts = req.path.split("/");
|
|
52
|
-
req.params = {};
|
|
53
|
-
for (let i = 0; i < middlewareParts.length; i++) {
|
|
54
|
-
if (middlewareParts[i].startsWith(":")) {
|
|
55
|
-
const paramName = middlewareParts[i].slice(1);
|
|
56
|
-
req.params[paramName] = reqPathParts[i];
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
req.middleware = middleware;
|
|
61
|
-
const result = await middleware.middleware(req, res, next);
|
|
62
|
-
if (result && !res._ended) {
|
|
63
|
-
if (typeof result === "string") {
|
|
64
|
-
return res.end(result);
|
|
65
|
-
}
|
|
66
|
-
else if (typeof result === "object") {
|
|
67
|
-
return res.json(result);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
next();
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
function matchMiddleware(url, middlewares) {
|
|
75
|
-
const matchedMiddlewares = [];
|
|
76
|
-
url = url.replace(/\/$/, "");
|
|
77
|
-
for (const middleware of middlewares) {
|
|
78
|
-
const cleanedMiddleware = middleware.path.replace(/\/$/, "");
|
|
79
|
-
if (middleware.use) {
|
|
80
|
-
if (url.startsWith(cleanedMiddleware)) {
|
|
81
|
-
matchedMiddlewares.push(middleware);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
else if (cleanedMiddleware === "*") {
|
|
85
|
-
matchedMiddlewares.push(middleware);
|
|
86
|
-
}
|
|
87
|
-
else if (cleanedMiddleware.endsWith("/*")) {
|
|
88
|
-
const prefix = cleanedMiddleware.slice(0, -2);
|
|
89
|
-
if (url.startsWith(prefix)) {
|
|
90
|
-
matchedMiddlewares.push(middleware);
|
|
91
|
-
}
|
|
30
|
+
const middlewaresPath = req.path + "/";
|
|
31
|
+
const middlewares = getMiddlewares(FF.middlewares, middlewaresPath.replace(/\/+/g, "/"));
|
|
32
|
+
const matchedTypeMiddlewares = middlewares.filter(middleware => middleware.method === req.method.toLowerCase() || middleware.method === "all");
|
|
33
|
+
const matchedMiddlewares = matchMiddleware(req.path, matchedTypeMiddlewares);
|
|
34
|
+
logger.debug("Matched middlewares: " + matchedMiddlewares.map(middleware => middleware.path).join(", "));
|
|
35
|
+
if (matchedMiddlewares.length === 0) {
|
|
36
|
+
res.status(404).end("404: File had second thoughts");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
let middlewareIndex = 0;
|
|
40
|
+
async function next() {
|
|
41
|
+
if (middlewareIndex >= matchedMiddlewares.length) {
|
|
42
|
+
return res.status(404).end("404: File had second thoughts");
|
|
92
43
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
let matches = true;
|
|
44
|
+
const middleware = matchedMiddlewares[middlewareIndex++];
|
|
45
|
+
logger.debug(`Executing middleware ${middlewareIndex} of ${matchedMiddlewares.length} matched for path [${middleware.path}]`);
|
|
46
|
+
if (middleware.path.includes(":")) {
|
|
47
|
+
const middlewareParts = middleware.path.split("/");
|
|
48
|
+
const reqPathParts = req.path.split("/");
|
|
49
|
+
req.params = {};
|
|
100
50
|
for (let i = 0; i < middlewareParts.length; i++) {
|
|
101
51
|
if (middlewareParts[i].startsWith(":")) {
|
|
102
|
-
|
|
52
|
+
const paramName = middlewareParts[i].slice(1);
|
|
53
|
+
req.params[paramName] = reqPathParts[i];
|
|
103
54
|
}
|
|
104
|
-
else if (middlewareParts[i] !== urlParts[i]) {
|
|
105
|
-
matches = false;
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (matches) {
|
|
110
|
-
matchedMiddlewares.push(middleware);
|
|
111
55
|
}
|
|
112
56
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
57
|
+
req.middleware = middleware;
|
|
58
|
+
const result = await middleware.middleware(req, res, next);
|
|
59
|
+
if (result && !res._ended) {
|
|
60
|
+
if (typeof result === "string") {
|
|
61
|
+
return res.end(result);
|
|
62
|
+
}
|
|
63
|
+
else if (typeof result === "object") {
|
|
64
|
+
if (result instanceof FFResponse)
|
|
65
|
+
return res.end();
|
|
66
|
+
return res.json(result);
|
|
116
67
|
}
|
|
117
68
|
}
|
|
118
69
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const result = [];
|
|
123
|
-
for (const middleware of middlewares) {
|
|
124
|
-
const midPath = (middleware.path || "").replace(/\/+$/, "");
|
|
125
|
-
const fullPath = (basePath + "/" + midPath).replace(/\/+/g, "/");
|
|
126
|
-
const matches = matchUrl === fullPath ||
|
|
127
|
-
(middleware.use && matchUrl.startsWith(fullPath)) ||
|
|
128
|
-
fullPath.includes(":") ||
|
|
129
|
-
fullPath.includes("*") ||
|
|
130
|
-
matchUrl.startsWith(fullPath + "/");
|
|
131
|
-
if (!matches)
|
|
132
|
-
continue;
|
|
133
|
-
if (middleware.router) {
|
|
134
|
-
const nested = getMiddlewares(middleware.router, matchUrl, fullPath);
|
|
135
|
-
result.push(...nested);
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
result.push({ ...middleware, path: fullPath });
|
|
139
|
-
}
|
|
70
|
+
if (req.method === "GET" && middlewares[middlewares.length - 1]?.sse) {
|
|
71
|
+
next();
|
|
72
|
+
return;
|
|
140
73
|
}
|
|
141
|
-
|
|
74
|
+
let body = "";
|
|
75
|
+
req.on("data", chunk => (body += chunk.toString()));
|
|
76
|
+
req.on("end", () => {
|
|
77
|
+
const contentType = req.headers["content-type"] || "";
|
|
78
|
+
req.body = parseBody(contentType, body);
|
|
79
|
+
logger.debug(`Request body: ${JSON.stringify(req.body)}`);
|
|
80
|
+
next();
|
|
81
|
+
});
|
|
142
82
|
}
|
package/dist/res.d.ts
CHANGED
|
@@ -6,14 +6,77 @@ export declare class FFResponse extends http.ServerResponse {
|
|
|
6
6
|
* bind end for compatibility
|
|
7
7
|
*/
|
|
8
8
|
send(data: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* Sets a header. This is a shortcut for setHeader.
|
|
11
|
+
* @param name The name of the header
|
|
12
|
+
* @param value The value of the header
|
|
13
|
+
* @returns The response object
|
|
14
|
+
*/
|
|
15
|
+
header(name: string, value: string): this;
|
|
9
16
|
/**
|
|
10
17
|
* Set content type
|
|
11
18
|
*/
|
|
12
|
-
ct(contentType?: string):
|
|
19
|
+
ct(contentType?: string): this;
|
|
20
|
+
/**
|
|
21
|
+
* Set the content type to application/json and write the given data as json
|
|
22
|
+
* @param data The data to be written as json
|
|
23
|
+
*/
|
|
13
24
|
json(data: any): void;
|
|
25
|
+
/**
|
|
26
|
+
* Set a cookie in the response
|
|
27
|
+
* @param name The name of the cookie
|
|
28
|
+
* @param value The value of the cookie
|
|
29
|
+
* @param options The options for the cookie
|
|
30
|
+
*/
|
|
14
31
|
cookie(name: string, value: string, options?: CookieOptions): this;
|
|
32
|
+
/**
|
|
33
|
+
* Set the status code for the response
|
|
34
|
+
* @param code The status code to set
|
|
35
|
+
* @returns The response object
|
|
36
|
+
*/
|
|
15
37
|
status(code: number): this;
|
|
16
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Set status code to 302 and set location header to the provided url.
|
|
40
|
+
* If end is true, ends the response.
|
|
41
|
+
* @param url The url to redirect to
|
|
42
|
+
* @param end Whether to end the response after setting the headers
|
|
43
|
+
* @returns The response object
|
|
44
|
+
*/
|
|
45
|
+
redirect(url: string, end?: boolean): this;
|
|
46
|
+
/**
|
|
47
|
+
* Sends a file as the response.
|
|
48
|
+
* Sets the "Content-Type" header based on the provided contentType or the file's extension.
|
|
49
|
+
* Uses streaming to send the file content.
|
|
50
|
+
* @param filePath The path to the file to be sent.
|
|
51
|
+
* @param contentType Optional. The MIME type for the Content-Type header.
|
|
52
|
+
* If "utf8", the charset will be set to UTF-8.
|
|
53
|
+
* @returns The response object.
|
|
54
|
+
*/
|
|
17
55
|
sendFile(filePath: string, contentType?: string): this;
|
|
18
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Renders an HTML template with the provided data and sends it as the response.
|
|
58
|
+
* Sets the "Content-Type" header to "text/html".
|
|
59
|
+
* @param templatePath The path to the HTML template file.
|
|
60
|
+
* @param data An object containing data to be injected into the template.
|
|
61
|
+
* @returns The response object.
|
|
62
|
+
*/
|
|
63
|
+
render(templatePath: string, data?: any): this;
|
|
64
|
+
/**
|
|
65
|
+
* Initialize SSE headers to start a server-sent event stream.
|
|
66
|
+
* Sets:
|
|
67
|
+
*
|
|
68
|
+
* Content-Type: "text/event-stream"
|
|
69
|
+
*
|
|
70
|
+
* Cache-Control: "no-cache"
|
|
71
|
+
*
|
|
72
|
+
* Connection: "keep-alive"
|
|
73
|
+
* @returns The response object
|
|
74
|
+
*/
|
|
75
|
+
sseInit(): this;
|
|
76
|
+
/**
|
|
77
|
+
* Sends a Server-Sent Event to the client.
|
|
78
|
+
* @param data The data to be sent. If an object, it will be JSON.stringified.
|
|
79
|
+
* @returns The response object
|
|
80
|
+
*/
|
|
81
|
+
sseSend(data: string | object): this;
|
|
19
82
|
}
|
package/dist/res.js
CHANGED
|
@@ -10,16 +10,37 @@ export class FFResponse extends http.ServerResponse {
|
|
|
10
10
|
send(data) {
|
|
11
11
|
this.end(data);
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Sets a header. This is a shortcut for setHeader.
|
|
15
|
+
* @param name The name of the header
|
|
16
|
+
* @param value The value of the header
|
|
17
|
+
* @returns The response object
|
|
18
|
+
*/
|
|
19
|
+
header(name, value) {
|
|
20
|
+
this.setHeader(name, value);
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
13
23
|
/**
|
|
14
24
|
* Set content type
|
|
15
25
|
*/
|
|
16
26
|
ct(contentType = "text/plain") {
|
|
17
27
|
this.setHeader("Content-Type", contentType);
|
|
28
|
+
return this;
|
|
18
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Set the content type to application/json and write the given data as json
|
|
32
|
+
* @param data The data to be written as json
|
|
33
|
+
*/
|
|
19
34
|
json(data) {
|
|
20
35
|
this.setHeader("Content-Type", "application/json");
|
|
21
36
|
this.end(JSON.stringify(data));
|
|
22
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Set a cookie in the response
|
|
40
|
+
* @param name The name of the cookie
|
|
41
|
+
* @param value The value of the cookie
|
|
42
|
+
* @param options The options for the cookie
|
|
43
|
+
*/
|
|
23
44
|
cookie(name, value, options = {}) {
|
|
24
45
|
let cookie = `${name}=${encodeURIComponent(value)}`;
|
|
25
46
|
if (options.maxAge)
|
|
@@ -35,25 +56,84 @@ export class FFResponse extends http.ServerResponse {
|
|
|
35
56
|
this.setHeader("Set-Cookie", cookie);
|
|
36
57
|
return this;
|
|
37
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Set the status code for the response
|
|
61
|
+
* @param code The status code to set
|
|
62
|
+
* @returns The response object
|
|
63
|
+
*/
|
|
38
64
|
status(code) {
|
|
39
65
|
this.statusCode = code;
|
|
40
66
|
return this;
|
|
41
67
|
}
|
|
42
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Set status code to 302 and set location header to the provided url.
|
|
70
|
+
* If end is true, ends the response.
|
|
71
|
+
* @param url The url to redirect to
|
|
72
|
+
* @param end Whether to end the response after setting the headers
|
|
73
|
+
* @returns The response object
|
|
74
|
+
*/
|
|
75
|
+
redirect(url, end = true) {
|
|
43
76
|
this.statusCode = 302;
|
|
44
77
|
this.setHeader("Location", url);
|
|
78
|
+
if (end)
|
|
79
|
+
this.end();
|
|
45
80
|
return this;
|
|
46
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Sends a file as the response.
|
|
84
|
+
* Sets the "Content-Type" header based on the provided contentType or the file's extension.
|
|
85
|
+
* Uses streaming to send the file content.
|
|
86
|
+
* @param filePath The path to the file to be sent.
|
|
87
|
+
* @param contentType Optional. The MIME type for the Content-Type header.
|
|
88
|
+
* If "utf8", the charset will be set to UTF-8.
|
|
89
|
+
* @returns The response object.
|
|
90
|
+
*/
|
|
47
91
|
sendFile(filePath, contentType) {
|
|
48
92
|
if (contentType === "utf8")
|
|
49
93
|
contentType = getContentType(filePath);
|
|
50
94
|
this.ct(contentType || getContentType(filePath));
|
|
51
95
|
createReadStream(filePath).pipe(this);
|
|
96
|
+
this._ended = true;
|
|
52
97
|
return this;
|
|
53
98
|
}
|
|
54
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Renders an HTML template with the provided data and sends it as the response.
|
|
101
|
+
* Sets the "Content-Type" header to "text/html".
|
|
102
|
+
* @param templatePath The path to the HTML template file.
|
|
103
|
+
* @param data An object containing data to be injected into the template.
|
|
104
|
+
* @returns The response object.
|
|
105
|
+
*/
|
|
106
|
+
render(templatePath, data = {}) {
|
|
55
107
|
this.setHeader("Content-Type", "text/html");
|
|
56
108
|
this.end(renderHTML(templatePath, data));
|
|
57
109
|
return this;
|
|
58
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Initialize SSE headers to start a server-sent event stream.
|
|
113
|
+
* Sets:
|
|
114
|
+
*
|
|
115
|
+
* Content-Type: "text/event-stream"
|
|
116
|
+
*
|
|
117
|
+
* Cache-Control: "no-cache"
|
|
118
|
+
*
|
|
119
|
+
* Connection: "keep-alive"
|
|
120
|
+
* @returns The response object
|
|
121
|
+
*/
|
|
122
|
+
sseInit() {
|
|
123
|
+
this.setHeader("Content-Type", "text/event-stream");
|
|
124
|
+
this.setHeader("Cache-Control", "no-cache");
|
|
125
|
+
this.setHeader("Connection", "keep-alive");
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Sends a Server-Sent Event to the client.
|
|
130
|
+
* @param data The data to be sent. If an object, it will be JSON.stringified.
|
|
131
|
+
* @returns The response object
|
|
132
|
+
*/
|
|
133
|
+
sseSend(data) {
|
|
134
|
+
if (typeof data === "object")
|
|
135
|
+
data = JSON.stringify(data);
|
|
136
|
+
this.write(`data: ${data}\n\n`);
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
59
139
|
}
|
package/dist/router.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Method, Middleware, RouteHandler } from "./types.js";
|
|
2
2
|
export declare class Router {
|
|
3
3
|
middlewares: Middleware[];
|
|
4
|
-
addRoute(method: Method, path: string, ...handlers: RouteHandler[]):
|
|
5
|
-
use(path?: string | RouteHandler | Router, middlewareFn?: RouteHandler | Router, method?: Method):
|
|
6
|
-
get(path: string, ...handlers: RouteHandler[]):
|
|
7
|
-
post(path: string, ...handlers: RouteHandler[]):
|
|
8
|
-
put(path: string, ...handlers: RouteHandler[]):
|
|
9
|
-
delete(path: string, ...handlers: RouteHandler[]):
|
|
10
|
-
all(path: string, ...handlers: RouteHandler[]):
|
|
11
|
-
static(apiPath: string, dirPath?: string, utf8?: boolean):
|
|
4
|
+
addRoute(method: Method, path: string, ...handlers: RouteHandler[]): number;
|
|
5
|
+
use(path?: string | RouteHandler | Router, middlewareFn?: RouteHandler | Router, method?: Method): this;
|
|
6
|
+
get(path: string, ...handlers: RouteHandler[]): this;
|
|
7
|
+
post(path: string, ...handlers: RouteHandler[]): this;
|
|
8
|
+
put(path: string, ...handlers: RouteHandler[]): this;
|
|
9
|
+
delete(path: string, ...handlers: RouteHandler[]): this;
|
|
10
|
+
all(path: string, ...handlers: RouteHandler[]): this;
|
|
11
|
+
static(apiPath: string, dirPath?: string, utf8?: boolean): this;
|
|
12
|
+
sse(path: string, ...handlers: RouteHandler[]): this;
|
|
12
13
|
}
|
package/dist/router.js
CHANGED
|
@@ -4,7 +4,7 @@ export class Router {
|
|
|
4
4
|
addRoute(method, path, ...handlers) {
|
|
5
5
|
const handler = handlers.pop();
|
|
6
6
|
handlers.forEach(middleware => this.use(path, middleware));
|
|
7
|
-
this.middlewares.push({ path, middleware: handler, method });
|
|
7
|
+
return this.middlewares.push({ path, middleware: handler, method });
|
|
8
8
|
}
|
|
9
9
|
use(path = "/", middlewareFn, method = "all") {
|
|
10
10
|
if (typeof path === "function" || path instanceof Router) {
|
|
@@ -24,21 +24,27 @@ export class Router {
|
|
|
24
24
|
middleware.middleware = middlewareFn;
|
|
25
25
|
}
|
|
26
26
|
this.middlewares.push(middleware);
|
|
27
|
+
return this;
|
|
27
28
|
}
|
|
28
29
|
get(path, ...handlers) {
|
|
29
30
|
this.addRoute("get", path, ...handlers);
|
|
31
|
+
return this;
|
|
30
32
|
}
|
|
31
33
|
post(path, ...handlers) {
|
|
32
34
|
this.addRoute("post", path, ...handlers);
|
|
35
|
+
return this;
|
|
33
36
|
}
|
|
34
37
|
put(path, ...handlers) {
|
|
35
38
|
this.addRoute("put", path, ...handlers);
|
|
39
|
+
return this;
|
|
36
40
|
}
|
|
37
41
|
delete(path, ...handlers) {
|
|
38
42
|
this.addRoute("delete", path, ...handlers);
|
|
43
|
+
return this;
|
|
39
44
|
}
|
|
40
45
|
all(path, ...handlers) {
|
|
41
46
|
this.addRoute("all", path, ...handlers);
|
|
47
|
+
return this;
|
|
42
48
|
}
|
|
43
49
|
static(apiPath, dirPath, utf8 = true) {
|
|
44
50
|
if (!dirPath) {
|
|
@@ -46,5 +52,11 @@ export class Router {
|
|
|
46
52
|
apiPath = "/";
|
|
47
53
|
}
|
|
48
54
|
this.use(apiPath, handleStaticFiles(dirPath, utf8));
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
sse(path, ...handlers) {
|
|
58
|
+
const index = this.addRoute("get", path, ...handlers);
|
|
59
|
+
this.middlewares[index - 1].sse = true;
|
|
60
|
+
return this;
|
|
49
61
|
}
|
|
50
62
|
}
|
package/dist/types.d.ts
CHANGED