diesel-core 0.0.13 → 0.0.14
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/CONTRIBUTING.md +1 -1
- package/README.md +78 -0
- package/build.js +10 -8
- package/example/bun.lockb +0 -0
- package/example/main.ts +12 -11
- package/example/package.json +1 -1
- package/example/route.js +2 -2
- package/example/tester.js +3 -1
- package/package.json +1 -1
- package/src/handleRequest.ts +16 -10
- package/src/main.ts +22 -19
- package/src/route.ts +56 -0
- package/src/trie.ts +5 -3
- package/src/types.ts +2 -1
- package/tsconfig.json +2 -2
- package/src/router.ts +0 -55
package/CONTRIBUTING.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
if you changes code OR fixing bugs so after doing make sure to run bun build.js
|
|
1
|
+
if you changes code OR fixing bugs so after doing make sure to run tsc and bun build.js
|
package/README.md
CHANGED
|
@@ -38,11 +38,89 @@ app.listen(port, () => {
|
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
```
|
|
41
|
+
## Filter and Route Security
|
|
42
|
+
**Diesel** provides a simple way to manage public and protected routes by using a filter() method. You can define specific routes to be publicly accessible, while others will require authentication or custom middleware functions.
|
|
43
|
+
|
|
44
|
+
### How to Use the Filter
|
|
45
|
+
The **filter()** method allows you to secure certain endpoints while keeping others public. You can specify routes that should be publicly accessible using permitAll(), and apply authentication or other middleware to the remaining routes with require().
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Example Usage
|
|
49
|
+
```javascript
|
|
50
|
+
import Diesel from "diesel-core";
|
|
51
|
+
import jwt from 'jsonwebtoken';
|
|
52
|
+
|
|
53
|
+
const app = new Diesel();
|
|
54
|
+
|
|
55
|
+
async function authJwt (ctx:ContextType, server?:Server): Promise<void | Response> {
|
|
56
|
+
const token = await ctx.getCookie("accessToken"); // Retrieve the JWT token from cookies
|
|
57
|
+
if (!token) {
|
|
58
|
+
return ctx.status(401).json({ message: "Authentication token missing" });
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
// Verify the JWT token using a secret key
|
|
62
|
+
const user = jwt.verify(token, secret); // Replace with your JWT secret
|
|
63
|
+
// Set the user data in context
|
|
64
|
+
ctx.set("user", user);
|
|
65
|
+
|
|
66
|
+
// Proceed to the next middleware/route handler
|
|
67
|
+
return ctx.next();
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return ctx.status(403).json({ message: "Invalid token" });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Define routes and apply filter
|
|
74
|
+
app
|
|
75
|
+
.filter()
|
|
76
|
+
.routeMatcher('/api/user/register', '/api/user/login', '/test/:id', '/cookie') // Define public routes
|
|
77
|
+
.permitAll() // Mark these routes as public (no auth required)
|
|
78
|
+
.require(authJwt); // Apply the authJwt middleware to all other routes
|
|
79
|
+
|
|
80
|
+
// Example public route (no auth required)
|
|
81
|
+
app.get("/api/user/register", async (xl) => {
|
|
82
|
+
return xl.json({ msg: "This is a public route. No authentication needed." });
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Example protected route (requires auth)
|
|
86
|
+
app.get("/api/user/profile", async (xl) => {
|
|
87
|
+
// This route is protected, so the auth middleware will run before this handler
|
|
88
|
+
return xl.json({ msg: "You are authenticated!" });
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Start the server
|
|
92
|
+
const port = 3000;
|
|
93
|
+
app.listen(port, () => {
|
|
94
|
+
console.log(`Diesel is running on port ${port}`);
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
## Filter Methods
|
|
98
|
+
1. **routeMatcher(...routes: string[])** : Passed endpoints in this routeMatcher will be ***Public*** means they don't need authentication, including those with dynamic parameters (e.g., /test/:id).
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
.routeMatcher('/api/user/register', '/api/user/login', '/test/:id')
|
|
102
|
+
```
|
|
103
|
+
1. **permitAll()** : Marks the routes specified in routeMatcher() as publicly accessible, meaning no middleware (like authentication) will be required for these routes.
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
.permitAll()
|
|
107
|
+
```
|
|
108
|
+
1. **require(fnc?: middlewareFunc)** :Means that defined routes in ***routeMatcher*** is public & All endpoints needs authentication.
|
|
109
|
+
|
|
110
|
+
*Note* : If you don't pass a middleware function to require(), DieselJS will throw an "Unauthorized" error by default. Ensure that you implement and pass a valid authentication function
|
|
111
|
+
```javascript
|
|
112
|
+
.require(authJwt)
|
|
113
|
+
```
|
|
114
|
+
## Use Case
|
|
115
|
+
* **Public Routes** : Some routes ***(like /api/user/register or /api/user/login)*** are often open to all users without authentication. These routes can be specified with permitAll().
|
|
116
|
+
|
|
117
|
+
* **Protected Routes** : For other routes ***(like /api/user/profile)***, you'll want to require authentication or custom middleware. Use require(authJwt) to ensure that the user is authenticated before accessing these routes.
|
|
41
118
|
|
|
42
119
|
## Using Hooks in DieselJS
|
|
43
120
|
|
|
44
121
|
DieselJS allows you to enhance your request handling by utilizing hooks at various stages of the request lifecycle. This gives you the flexibility to execute custom logic for logging, authentication, data manipulation, and more.
|
|
45
122
|
|
|
123
|
+
|
|
46
124
|
### Available Hooks
|
|
47
125
|
|
|
48
126
|
1. **onRequest**: Triggered when a request is received.
|
package/build.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
1
|
+
// tsc will create main folder
|
|
2
|
+
Bun.build({
|
|
3
3
|
entrypoints: [
|
|
4
|
-
'./
|
|
5
|
-
'./
|
|
6
|
-
'./
|
|
7
|
-
'./
|
|
8
|
-
'./
|
|
4
|
+
'./main/main.ts',
|
|
5
|
+
'./main/ctx.ts',
|
|
6
|
+
'./main/handleRequest.ts',
|
|
7
|
+
'./main/trie.ts',
|
|
8
|
+
'./main/router.ts'
|
|
9
9
|
],
|
|
10
10
|
outdir: './dist',
|
|
11
11
|
minify: true, // Enable minification
|
|
12
|
-
})
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
await Bun.spawn(['rm', '-rf', './main']);
|
package/example/bun.lockb
CHANGED
|
Binary file
|
package/example/main.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Server } from "bun";
|
|
2
|
+
import Diesel ,{rateLimit} from "../src/main";
|
|
3
|
+
import { ContextType, CookieOptions, middlewareFunc } from "../dist/types";
|
|
2
4
|
import jwt from 'jsonwebtoken'
|
|
3
5
|
|
|
4
6
|
const app = new Diesel()
|
|
5
|
-
const secret = '
|
|
7
|
+
const secret = 'pradeep'
|
|
6
8
|
// app.cors({
|
|
7
9
|
// origin: ['http://localhost:5173','*'],
|
|
8
10
|
// methods: 'GET,POST,PUT,DELETE',
|
|
9
11
|
// allowedHeaders: 'Content-Type,Authorization'
|
|
10
12
|
// })
|
|
11
13
|
|
|
12
|
-
async function authJwt(ctx:
|
|
14
|
+
async function authJwt (ctx:ContextType, server?:Server): Promise<void | Response> {
|
|
13
15
|
const token = await ctx.getCookie("accessToken"); // Retrieve the JWT token from cookies
|
|
14
16
|
if (!token) {
|
|
15
17
|
return ctx.status(401).json({ message: "Authentication token missing" });
|
|
@@ -17,7 +19,6 @@ async function authJwt(ctx:any, server:any) {
|
|
|
17
19
|
try {
|
|
18
20
|
// Verify the JWT token using a secret key
|
|
19
21
|
const user = jwt.verify(token, secret); // Replace with your JWT secret
|
|
20
|
-
console.log(user)
|
|
21
22
|
// Set the user data in context
|
|
22
23
|
ctx.set("user", user);
|
|
23
24
|
|
|
@@ -42,17 +43,15 @@ app
|
|
|
42
43
|
.permitAll()
|
|
43
44
|
.require(authJwt)
|
|
44
45
|
|
|
46
|
+
// app.use(authJwt)
|
|
47
|
+
|
|
45
48
|
// .require(you can pass jwt auth parser)
|
|
46
49
|
|
|
47
50
|
app.get("/", async(xl) => {
|
|
48
51
|
// const ip = xl.req
|
|
49
52
|
// console.log(ip)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
author: 'Pradeep',
|
|
53
|
-
app: 'Express App',
|
|
54
|
-
features: ['Fast', 'Flexible', 'Lightweight']
|
|
55
|
-
});
|
|
53
|
+
const user = xl.get('user')
|
|
54
|
+
return xl.json({user:user});
|
|
56
55
|
});
|
|
57
56
|
|
|
58
57
|
app.get("/test/:id", async (xl) => {
|
|
@@ -73,7 +72,7 @@ app.get("/test/:id", async (xl) => {
|
|
|
73
72
|
|
|
74
73
|
const accessToken = jwt.sign(user, secret, { expiresIn: "1d" });
|
|
75
74
|
const refreshToken = jwt.sign(user, secret, { expiresIn: "10d" });
|
|
76
|
-
const options = {
|
|
75
|
+
const options : CookieOptions= {
|
|
77
76
|
httpOnly: true, // Makes cookie accessible only by the web server (not JS)
|
|
78
77
|
secure: true, // Ensures the cookie is sent over HTTPS
|
|
79
78
|
maxAge: 24 * 60 * 60 * 1000, // 1 day in milliseconds
|
|
@@ -87,4 +86,6 @@ app.get("/test/:id", async (xl) => {
|
|
|
87
86
|
return xl.json({msg:"setting cookies"})
|
|
88
87
|
});
|
|
89
88
|
|
|
89
|
+
|
|
90
|
+
|
|
90
91
|
app.listen(3000)
|
package/example/package.json
CHANGED
package/example/route.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Router from "../src/
|
|
1
|
+
import Router from "../src/route";
|
|
2
2
|
|
|
3
3
|
const route = new Router();
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ const s = () =>{
|
|
|
10
10
|
console.log('s')
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
route.get("/register", h,(xl) => {
|
|
13
|
+
route.get("/register/:id", h,(xl) => {
|
|
14
14
|
return xl.text("from register user");
|
|
15
15
|
})
|
|
16
16
|
|
package/example/tester.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Diesel from "../dist/main";
|
|
2
2
|
import jwt from "jsonwebtoken";
|
|
3
3
|
|
|
4
4
|
const app = new Diesel();
|
|
5
5
|
const secret = "secret";
|
|
6
6
|
|
|
7
|
+
// app.filter().permitAll().require()
|
|
8
|
+
|
|
7
9
|
app.get("/r", (xl) => {
|
|
8
10
|
return xl.html(`${import.meta.dir}/index.html`);
|
|
9
11
|
});
|
package/package.json
CHANGED
package/src/handleRequest.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { Server } from "bun";
|
|
2
2
|
import createCtx from "./ctx";
|
|
3
3
|
import type { ContextType, corsT, DieselT, handlerFunction, middlewareFunc, RouteCache, RouteHandlerT } from "./types";
|
|
4
|
-
import { binaryS } from "./utils";
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
const routeCache:RouteCache = {}
|
|
7
7
|
|
|
8
8
|
export default async function handleRequest(req: Request, server: Server, url: URL, diesel: DieselT): Promise<Response> {
|
|
9
9
|
|
|
10
10
|
const ctx: ContextType = createCtx(req, server, url);
|
|
11
11
|
|
|
12
12
|
// Try to find the route handler in the trie
|
|
13
|
-
let routeHandler: RouteHandlerT | undefined = diesel.trie.search(url.pathname, req.method)
|
|
13
|
+
let routeHandler: RouteHandlerT | undefined = diesel.trie.search(url.pathname, req.method);
|
|
14
|
+
|
|
14
15
|
// if(routeCache[url.pathname+req.method]) {
|
|
15
16
|
// routeHandler = routeCache[url.pathname+req.method]
|
|
16
17
|
// } else {
|
|
@@ -31,24 +32,29 @@ export default async function handleRequest(req: Request, server: Server, url: U
|
|
|
31
32
|
// cors execution
|
|
32
33
|
if (diesel.corsConfig) {
|
|
33
34
|
const corsResult = await applyCors(req, ctx, diesel.corsConfig)
|
|
34
|
-
if(corsResult) return corsResult;
|
|
35
|
+
if (corsResult) return corsResult;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
// OnReq hook 1
|
|
38
39
|
if (diesel.hasOnReqHook && diesel.hooks.onRequest) diesel.hooks.onRequest(ctx, server)
|
|
39
40
|
|
|
40
41
|
// filter applying
|
|
41
|
-
if (diesel.
|
|
42
|
+
if (diesel.hasFilterEnabled) {
|
|
42
43
|
|
|
43
44
|
const path = req.routePattern ?? url.pathname
|
|
44
45
|
const hasRoute = diesel.filters.includes(path)
|
|
45
|
-
|
|
46
46
|
if (hasRoute === false) {
|
|
47
47
|
if (diesel.filterFunction) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
try {
|
|
49
|
+
const filterResult = await diesel.filterFunction(ctx, server)
|
|
50
|
+
if (filterResult) return filterResult
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error("Error in filterFunction:", error);
|
|
53
|
+
return new Response(JSON.stringify({
|
|
54
|
+
message: "Internal Server Error"
|
|
55
|
+
}), { status: 500 });
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
52
58
|
return new Response(JSON.stringify({
|
|
53
59
|
message: "Authentication required"
|
|
54
60
|
}), { status: 400 })
|
package/src/main.ts
CHANGED
|
@@ -3,6 +3,7 @@ import handleRequest from "./handleRequest.js";
|
|
|
3
3
|
import rateLimit from "./utils.js";
|
|
4
4
|
import {
|
|
5
5
|
corsT,
|
|
6
|
+
DieselT,
|
|
6
7
|
FilterMethods,
|
|
7
8
|
HookFunction,
|
|
8
9
|
HookType,
|
|
@@ -17,6 +18,7 @@ import { Server } from "bun";
|
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
export default class Diesel {
|
|
21
|
+
|
|
20
22
|
routes : string[] | undefined
|
|
21
23
|
globalMiddlewares: middlewareFunc[]
|
|
22
24
|
middlewares: Map<string, middlewareFunc[]>;
|
|
@@ -30,11 +32,11 @@ export default class Diesel {
|
|
|
30
32
|
corsConfig: corsT
|
|
31
33
|
filters: string[]
|
|
32
34
|
filterFunction : middlewareFunc | null
|
|
35
|
+
hasFilterEnabled: boolean
|
|
36
|
+
wss : WebSocket | null | undefined
|
|
33
37
|
|
|
34
38
|
constructor() {
|
|
35
39
|
this.routes = []
|
|
36
|
-
this.filters = []
|
|
37
|
-
this.filterFunction = null
|
|
38
40
|
this.globalMiddlewares = [];
|
|
39
41
|
this.middlewares = new Map();
|
|
40
42
|
this.trie = new Trie();
|
|
@@ -52,10 +54,15 @@ export default class Diesel {
|
|
|
52
54
|
onError: null,
|
|
53
55
|
onClose: null
|
|
54
56
|
}
|
|
57
|
+
this.filters = []
|
|
58
|
+
this.filterFunction = null
|
|
59
|
+
this.hasFilterEnabled = false
|
|
60
|
+
this.wss = null
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
|
|
58
64
|
filter() :FilterMethods {
|
|
65
|
+
this.hasFilterEnabled = true
|
|
59
66
|
|
|
60
67
|
return {
|
|
61
68
|
routeMatcher: (...routes:string[]) => {
|
|
@@ -67,17 +74,13 @@ export default class Diesel {
|
|
|
67
74
|
for(const route of this?.routes!){
|
|
68
75
|
this.filters.push(route)
|
|
69
76
|
}
|
|
70
|
-
// this.routes = []
|
|
71
77
|
return this.filter()
|
|
72
78
|
},
|
|
73
79
|
|
|
74
80
|
require: (fnc?:middlewareFunc) => {
|
|
75
|
-
if(
|
|
76
|
-
|
|
77
|
-
message:"Authentication required"
|
|
78
|
-
}),{status:400})
|
|
81
|
+
if (fnc) {
|
|
82
|
+
this.filterFunction = fnc
|
|
79
83
|
}
|
|
80
|
-
this.filterFunction = fnc
|
|
81
84
|
}
|
|
82
85
|
};
|
|
83
86
|
}
|
|
@@ -138,13 +141,13 @@ export default class Diesel {
|
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
this.compile();
|
|
141
|
-
|
|
144
|
+
|
|
142
145
|
const options: any = {
|
|
143
146
|
port,
|
|
144
147
|
fetch: async (req: Request, server: Server) => {
|
|
145
148
|
const url = new URL(req.url);
|
|
146
149
|
try {
|
|
147
|
-
return await handleRequest(req, server, url, this);
|
|
150
|
+
return await handleRequest(req, server, url, this as DieselT);
|
|
148
151
|
} catch (error) {
|
|
149
152
|
return new Response("Internal Server Error", { status: 500 });
|
|
150
153
|
}
|
|
@@ -160,7 +163,7 @@ export default class Diesel {
|
|
|
160
163
|
}
|
|
161
164
|
const server = Bun.serve(options);
|
|
162
165
|
|
|
163
|
-
|
|
166
|
+
Bun?.gc(false)
|
|
164
167
|
|
|
165
168
|
if (typeof callback === "function") {
|
|
166
169
|
return callback();
|
|
@@ -186,7 +189,7 @@ export default class Diesel {
|
|
|
186
189
|
throw new Error("handler parameter should be a instance of router object", handlerInstance)
|
|
187
190
|
}
|
|
188
191
|
const routeEntries: [string, RouteNodeType][] = Object.entries(handlerInstance.trie.root.children) as [string, RouteNodeType][];
|
|
189
|
-
|
|
192
|
+
|
|
190
193
|
handlerInstance.trie.root.subMiddlewares.forEach((middleware: middlewareFunc[], path: string) => {
|
|
191
194
|
if (!this.middlewares.has(pathPrefix + path)) {
|
|
192
195
|
this.middlewares.set(pathPrefix + path, []);
|
|
@@ -208,7 +211,7 @@ export default class Diesel {
|
|
|
208
211
|
handlerInstance.trie = new Trie();
|
|
209
212
|
}
|
|
210
213
|
|
|
211
|
-
|
|
214
|
+
addRoute(
|
|
212
215
|
method: HttpMethod,
|
|
213
216
|
path: string,
|
|
214
217
|
handlers: handlerFunction[]
|
|
@@ -252,7 +255,7 @@ export default class Diesel {
|
|
|
252
255
|
}
|
|
253
256
|
return
|
|
254
257
|
}
|
|
255
|
-
|
|
258
|
+
|
|
256
259
|
const path: string = pathORHandler as string;
|
|
257
260
|
|
|
258
261
|
if (!this.middlewares.has(path)) {
|
|
@@ -270,7 +273,7 @@ export default class Diesel {
|
|
|
270
273
|
path: string,
|
|
271
274
|
...handlers: handlerFunction[]
|
|
272
275
|
) : this {
|
|
273
|
-
this
|
|
276
|
+
this.addRoute("GET", path, handlers);
|
|
274
277
|
return this
|
|
275
278
|
}
|
|
276
279
|
|
|
@@ -278,12 +281,12 @@ export default class Diesel {
|
|
|
278
281
|
path: string,
|
|
279
282
|
...handlers: handlerFunction[]
|
|
280
283
|
): this {
|
|
281
|
-
this
|
|
284
|
+
this.addRoute("POST", path, handlers);
|
|
282
285
|
return this
|
|
283
286
|
}
|
|
284
287
|
|
|
285
288
|
put(path: string, ...handlers: handlerFunction[]) : this{
|
|
286
|
-
this
|
|
289
|
+
this.addRoute("PUT", path, handlers);
|
|
287
290
|
return this
|
|
288
291
|
}
|
|
289
292
|
|
|
@@ -291,7 +294,7 @@ export default class Diesel {
|
|
|
291
294
|
path: string,
|
|
292
295
|
...handlers: handlerFunction[]
|
|
293
296
|
) : this {
|
|
294
|
-
this
|
|
297
|
+
this.addRoute("PATCH", path, handlers);
|
|
295
298
|
return this
|
|
296
299
|
}
|
|
297
300
|
|
|
@@ -299,7 +302,7 @@ export default class Diesel {
|
|
|
299
302
|
path: any,
|
|
300
303
|
...handlers: handlerFunction[]
|
|
301
304
|
) : this {
|
|
302
|
-
this
|
|
305
|
+
this.addRoute("DELETE", path, handlers);
|
|
303
306
|
return this;
|
|
304
307
|
}
|
|
305
308
|
}
|
package/src/route.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import Diesel from "./main";
|
|
2
|
+
import type { handlerFunction, HttpMethod } from "./types";
|
|
3
|
+
|
|
4
|
+
class Router extends Diesel {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// #addRoute(method:HttpMethod, path:string, handlers:handlerFunction[]) {
|
|
10
|
+
// if (!this.trie.root.subMiddlewares.has(path)) {
|
|
11
|
+
// this.trie.root.subMiddlewares.set(path,[])
|
|
12
|
+
// }
|
|
13
|
+
// const middlewareHandlers : handlerFunction[]= handlers.slice(0, -1);
|
|
14
|
+
|
|
15
|
+
// const currentMiddlewares = this.trie.root.subMiddlewares.get(path)
|
|
16
|
+
|
|
17
|
+
// middlewareHandlers.forEach((midl:handlerFunction) => {
|
|
18
|
+
// if (!currentMiddlewares?.includes(midl)) {
|
|
19
|
+
// currentMiddlewares?.push(midl)
|
|
20
|
+
// }
|
|
21
|
+
// })
|
|
22
|
+
|
|
23
|
+
// // if (!this.trie.root.subMiddlewares.get(path).includes(...middlewareHandlers)) {
|
|
24
|
+
// // this.trie.root.subMiddlewares.get(path).push(...middlewareHandlers)
|
|
25
|
+
// // }
|
|
26
|
+
|
|
27
|
+
// const handler : handlerFunction = handlers[handlers.length - 1];
|
|
28
|
+
// this.trie.insert(path, { handler, method });
|
|
29
|
+
// }
|
|
30
|
+
get(path:string, ...handlers:handlerFunction[]) {
|
|
31
|
+
this.addRoute("GET", path, handlers);
|
|
32
|
+
return this
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
post(path:string, ...handlers:handlerFunction[]) {
|
|
36
|
+
this.addRoute("POST", path, handlers);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
put(path:string, ...handlers:handlerFunction[]) {
|
|
41
|
+
this.addRoute("PUT", path, handlers);
|
|
42
|
+
return this
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
patch(path:string, ...handlers:handlerFunction[]) {
|
|
46
|
+
this.addRoute("PATCH", path, handlers);
|
|
47
|
+
return this
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
delete(path:string, ...handlers:handlerFunction[]) {
|
|
51
|
+
this.addRoute("DELETE", path, handlers);
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default Router;
|
package/src/trie.ts
CHANGED
|
@@ -59,9 +59,11 @@ class TrieNode {
|
|
|
59
59
|
node = node.children[key];
|
|
60
60
|
// Set dynamic route information if applicable
|
|
61
61
|
node.isDynamic = isDynamic;
|
|
62
|
-
node.pattern = segment;
|
|
62
|
+
node.pattern = segment;
|
|
63
|
+
node.method.push(route.method)
|
|
64
|
+
node.handler.push(route.handler)
|
|
65
|
+
node.path = path; // Store the actual pattern like ':id'
|
|
63
66
|
}
|
|
64
|
-
|
|
65
67
|
// After looping through the entire path, assign route details
|
|
66
68
|
node.isEndOfWord = true;
|
|
67
69
|
node.method.push(route.method);
|
|
@@ -95,7 +97,7 @@ class TrieNode {
|
|
|
95
97
|
node = node.children[key];
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
|
-
|
|
100
|
+
|
|
99
101
|
// Method matching
|
|
100
102
|
let routeMethodIndex = node.method.indexOf(method); // More efficient method match
|
|
101
103
|
if (routeMethodIndex !== -1) {
|
package/src/types.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Server } from "bun";
|
|
|
2
2
|
|
|
3
3
|
export type listenCalllBackType = () => void;
|
|
4
4
|
export type handlerFunction = (ctx: ContextType, server?: Server) => Response | Promise<Response | null | void>;
|
|
5
|
-
export type middlewareFunc = (ctx:ContextType,server?:Server) => void | Response | Promise<Response>
|
|
5
|
+
export type middlewareFunc = (ctx:ContextType,server?:Server | undefined) => void | Response | Promise<Response>
|
|
6
6
|
export type HookFunction = (ctx: ContextType, result?: Response | null | void, server?: Server) => Response | Promise<Response | null | void>
|
|
7
7
|
// export type onSendHookFunc = (result?: Response | null | void, ctx?:ContextType) => Response | Promise<Response | null | void>
|
|
8
8
|
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
|
|
@@ -86,6 +86,7 @@ export interface DieselT {
|
|
|
86
86
|
onSend: ((ctx?: ContextType, result?: Response | null | void, serer?: Server) => Promise<Response | void | null>) | null;
|
|
87
87
|
};
|
|
88
88
|
filters: string[]
|
|
89
|
+
hasFilterEnabled:boolean
|
|
89
90
|
filterFunction: (ctx:ContextType,serer?:Server) => void | Response | Promise<Response|void>
|
|
90
91
|
corsConfig: corsT | null
|
|
91
92
|
globalMiddlewares: Array<(ctx: ContextType, serer?: Server) => void | Promise<Response | null | void>>
|
package/tsconfig.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"target": "ES6", // Specify ECMAScript target version
|
|
4
4
|
"module": "ESNext", // Specify module code generation
|
|
5
|
-
"outDir": "./
|
|
5
|
+
"outDir": "./main", // Redirect output structure to the 'dist' directory
|
|
6
6
|
"rootDir": "./src",
|
|
7
7
|
"declaration": true,
|
|
8
|
-
"emitDeclarationOnly": true, // Specify the root directory of input files
|
|
8
|
+
// "emitDeclarationOnly": true, // Specify the root directory of input files
|
|
9
9
|
"strict": true, // Enable all strict type-checking options
|
|
10
10
|
"esModuleInterop": true, // Enables emit interoperability between CommonJS and ES Modules
|
|
11
11
|
"skipLibCheck": true, // Skip type checking of declaration files
|
package/src/router.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import Diesel from "./main";
|
|
2
|
-
import type { handlerFunction, HttpMethod } from "./types";
|
|
3
|
-
|
|
4
|
-
class Router extends Diesel {
|
|
5
|
-
constructor() {
|
|
6
|
-
super();
|
|
7
|
-
}
|
|
8
|
-
#addRoute(method:HttpMethod, path:string, handlers:handlerFunction[]) {
|
|
9
|
-
if (!this.trie.root.subMiddlewares.has(path)) {
|
|
10
|
-
this.trie.root.subMiddlewares.set(path,[])
|
|
11
|
-
}
|
|
12
|
-
const middlewareHandlers : handlerFunction[]= handlers.slice(0, -1);
|
|
13
|
-
|
|
14
|
-
const currentMiddlewares = this.trie.root.subMiddlewares.get(path)
|
|
15
|
-
|
|
16
|
-
middlewareHandlers.forEach((midl:handlerFunction) => {
|
|
17
|
-
if (!currentMiddlewares?.includes(midl)) {
|
|
18
|
-
currentMiddlewares?.push(midl)
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
// if (!this.trie.root.subMiddlewares.get(path).includes(...middlewareHandlers)) {
|
|
23
|
-
// this.trie.root.subMiddlewares.get(path).push(...middlewareHandlers)
|
|
24
|
-
// }
|
|
25
|
-
|
|
26
|
-
const handler : handlerFunction = handlers[handlers.length - 1];
|
|
27
|
-
this.trie.insert(path, { handler, method });
|
|
28
|
-
}
|
|
29
|
-
get(path:string, ...handlers:handlerFunction[]) {
|
|
30
|
-
this.#addRoute("GET", path, handlers);
|
|
31
|
-
return this
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
post(path:string, ...handlers:handlerFunction[]) {
|
|
35
|
-
this.#addRoute("POST", path, handlers);
|
|
36
|
-
return this;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
put(path:string, ...handlers:handlerFunction[]) {
|
|
40
|
-
this.#addRoute("PUT", path, handlers);
|
|
41
|
-
return this
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
patch(path:string, ...handlers:handlerFunction[]) {
|
|
45
|
-
this.#addRoute("PATCH", path, handlers);
|
|
46
|
-
return this
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
delete(path : string, ...handlers:handlerFunction[]) {
|
|
50
|
-
this.#addRoute("DELETE", path, handlers);
|
|
51
|
-
return this;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export default Router;
|