diesel-core 0.0.12 → 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 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
- // build.js
2
- await Bun.build({
1
+ // tsc will create main folder
2
+ Bun.build({
3
3
  entrypoints: [
4
- './src/main.ts',
5
- './src/ctx.ts',
6
- './src/handleRequest.ts',
7
- './src/trie.ts',
8
- './src/router.ts'
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']);
@@ -1 +1 @@
1
- function W(G,E,I){let z=new Headers,J={},X=!1,L=null,Z=null,Y=null,K,M=200;return{req:G,server:E,url:I,next:()=>{},status(F){return M=F,this},getIP(){return this.server.requestIP(this.req)},async body(){if(!K)K=await j(G);if(K.error)return new Response(JSON.stringify({error:K.error}),{status:400});return K},setHeader(F,U){return z.set(F,U),this},set(F,U){return J[F]=U,this},get(F){return J[F]||null},setAuth(F){return X=F,this},getAuth(){return X},text(F,U){return new Response(F,{status:U??M,headers:z})},json(F,U){return new Response(JSON.stringify(F),{status:U??M,headers:z})},html(F,U){return new Response(Bun.file(F),{status:U??M,headers:z})},file(F,U){return new Response(Bun.file(F),{status:U??M,headers:z})},redirect(F,U){return z.set("Location",F),new Response(null,{status:U??302,headers:z})},getParams(F){if(!Y)Y=V(G?.routePattern,I?.pathname);return F?Y[F]||null:Y},getQuery(F){if(!L)L=Object.fromEntries(I.searchParams);return F?L[F]||null:L},async cookie(F,U,_={}){let $=`${encodeURIComponent(F)}=${encodeURIComponent(U)}`;if(_.maxAge)$+=`; Max-Age=${_.maxAge}`;if(_.expires)$+=`; Expires=${_.expires.toUTCString()}`;if(_.path)$+=`; Path=${_.path}`;if(_.domain)$+=`; Domain=${_.domain}`;if(_.secure)$+="; Secure";if(_.httpOnly)$+="; HttpOnly";if(_.sameSite)$+=`; SameSite=${_.sameSite}`;return z?.append("Set-Cookie",$),this},async getCookie(F){if(!Z){let U=G.headers.get("cookie");if(U)Z=await A(U)}return F?Z[F]||null:Z}}}async function A(G){let E={};if(!G)return E;return G.split(";").forEach((z)=>{let[J,X]=z?.trim()?.split("=");if(J&&X)E[J.trim()]=X.split(" ")[0].trim()}),E}function V(G,E){let I={},z=G.split("/"),[J]=E.split("?"),X=J.split("/");if(z.length!==X.length)return null;return z.forEach((L,Z)=>{if(L.startsWith(":")){let Y=L.slice(1);I[Y]=X[Z]}}),I}async function j(G){let E=G.headers.get("Content-Type")||"";if(!E)return{};try{if(E.startsWith("application/json"))return await G.json();if(E.startsWith("application/x-www-form-urlencoded")){let I=await G.text();return Object.fromEntries(new URLSearchParams(I))}if(E.startsWith("multipart/form-data")){let I=await G.formData();return D(I)}return{error:"Unknown request body type"}}catch(I){return{error:"Invalid request body format"}}}function D(G){let E={};for(let[I,z]of G.entries())E[I]=z;return E}async function Q(G,E,I,z){let J=W(G,E,I),X=z.trie.search(I.pathname,G.method);if(!X||!X.handler)return new Response(`Route not found for ${I.pathname}`,{status:404});if(X.method!==G.method)return new Response("Method not allowed",{status:405});if(X.isDynamic)G.routePattern=X.path;if(z.corsConfig){let L=await T(G,J,z.corsConfig);if(L)return L}if(z.hasOnReqHook&&z.hooks.onRequest)z.hooks.onRequest(J,E);if(z.filters.length>0){let L=G.routePattern??I.pathname;if(z.filters.includes(L)===!1)if(z.filterFunction){let Y=await z?.filterFunction(J);if(Y)return Y}else return new Response(JSON.stringify({message:"Authentication required"}),{status:400})}if(z.hasMiddleware){let L=[...z.globalMiddlewares,...z.middlewares.get(I.pathname)||[]];for(let Z of L){let Y=await Z(J,E);if(Y)return Y}}if(z.hasPreHandlerHook&&z.hooks.preHandler){let L=await z.hooks.preHandler(J);if(L)return L}try{let L=await X.handler(J);if(z.hasPostHandlerHook&&z.hooks.postHandler)await z.hooks.postHandler(J);if(z.hasOnSendHook&&z.hooks.onSend){let Z=await z.hooks.onSend(J,L);if(Z)return Z}return L??new Response("No response from handler",{status:204})}catch(L){return new Response("Internal Server Error",{status:500})}}async function T(G,E,I={}){let z=G.headers.get("origin")??"*",J=I?.origin,X=I?.allowedHeaders??["Content-Type","Authorization"],L=I?.methods??["GET","POST","PUT","DELETE","OPTIONS"],Z=I?.credentials??!1,Y=I?.exposedHeaders??[];if(E.setHeader("Access-Control-Allow-Methods",L),E.setHeader("Access-Control-Allow-Headers",X),E.setHeader("Access-Control-Allow-Credentials",Z),Y.length)E.setHeader("Access-Control-Expose-Headers",Y);if(J==="*")E.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(J))if(z&&J.includes(z))E.setHeader("Access-Control-Allow-Origin",z);else if(J.includes("*"))E.setHeader("Access-Control-Allow-Origin","*");else return E.status(403).json({message:"CORS not allowed"});else if(typeof J==="string")if(z===J)E.setHeader("Access-Control-Allow-Origin",z);else return E.status(403).json({message:"CORS not allowed"});else return E.status(403).json({message:"CORS not allowed"});if(E.setHeader("Access-Control-Allow-Origin",z),G.method==="OPTIONS")return E.setHeader("Access-Control-Max-Age","86400"),E.status(204).text("");return null}export{Q as default};
1
+ function W(G,E,I){let z=new Headers,J={},U=!1,Z=null,L=null,Y=null,$,M=200;return{req:G,server:E,url:I,next:()=>{},status(F){return M=F,this},getIP(){return this.server.requestIP(this.req)},async body(){if(!$)$=await j(G);if($.error)return new Response(JSON.stringify({error:$.error}),{status:400});return $},setHeader(F,X){return z.set(F,X),this},set(F,X){return J[F]=X,this},get(F){return J[F]||null},setAuth(F){return U=F,this},getAuth(){return U},text(F,X){return new Response(F,{status:X??M,headers:z})},json(F,X){return new Response(JSON.stringify(F),{status:X??M,headers:z})},html(F,X){return new Response(Bun.file(F),{status:X??M,headers:z})},file(F,X){return new Response(Bun.file(F),{status:X??M,headers:z})},redirect(F,X){return z.set("Location",F),new Response(null,{status:X??302,headers:z})},getParams(F){if(!Y)Y=V(G?.routePattern,I?.pathname);return F?Y[F]||null:Y},getQuery(F){if(!Z)Z=Object.fromEntries(I.searchParams);return F?Z[F]||null:Z},async cookie(F,X,_={}){let K=`${encodeURIComponent(F)}=${encodeURIComponent(X)}`;if(_.maxAge)K+=`; Max-Age=${_.maxAge}`;if(_.expires)K+=`; Expires=${_.expires.toUTCString()}`;if(_.path)K+=`; Path=${_.path}`;if(_.domain)K+=`; Domain=${_.domain}`;if(_.secure)K+="; Secure";if(_.httpOnly)K+="; HttpOnly";if(_.sameSite)K+=`; SameSite=${_.sameSite}`;return z?.append("Set-Cookie",K),this},async getCookie(F){if(!L){let X=G.headers.get("cookie");if(X)L=await A(X)}return F?L[F]||null:L}}}async function A(G){let E={};if(!G)return E;return G.split(";").forEach((z)=>{let[J,U]=z?.trim()?.split("=");if(J&&U)E[J.trim()]=U.split(" ")[0].trim()}),E}function V(G,E){let I={},z=G.split("/"),[J]=E.split("?"),U=J.split("/");if(z.length!==U.length)return null;return z.forEach((Z,L)=>{if(Z.startsWith(":")){let Y=Z.slice(1);I[Y]=U[L]}}),I}async function j(G){let E=G.headers.get("Content-Type")||"";if(!E)return{};try{if(E.startsWith("application/json"))return await G.json();if(E.startsWith("application/x-www-form-urlencoded")){let I=await G.text();return Object.fromEntries(new URLSearchParams(I))}if(E.startsWith("multipart/form-data")){let I=await G.formData();return D(I)}return{error:"Unknown request body type"}}catch(I){return{error:"Invalid request body format"}}}function D(G){let E={};for(let[I,z]of G.entries())E[I]=z;return E}async function Q(G,E,I,z){let J=W(G,E,I),U=z.trie.search(I.pathname,G.method);if(!U||U.method!==G.method)return new Response(U?"Method not allowed":`Route not found for ${I.pathname}`,{status:U?405:404});if(U.isDynamic)G.routePattern=U.path;if(z.corsConfig){let L=await T(G,J,z.corsConfig);if(L)return L}if(z.hasOnReqHook&&z.hooks.onRequest)z.hooks.onRequest(J,E);if(z.filters.length>0){let L=G.routePattern??I.pathname;if(z.filters.includes(L)===!1)if(z.filterFunction){let $=await z?.filterFunction(J,E);if($)return $}else return new Response(JSON.stringify({message:"Authentication required"}),{status:400})}if(z.hasMiddleware){let L=[...z.globalMiddlewares,...z.middlewares.get(I.pathname)||[]];for(let Y of L){let $=await Y(J,E);if($)return $}}if(z.hasPreHandlerHook&&z.hooks.preHandler){let L=await z.hooks.preHandler(J);if(L)return L}let Z=z.hasPreHandlerHook?await z.hooks.preHandler?.(J):null;if(Z)return Z;try{let L=await U.handler(J);if(z.hasPostHandlerHook&&z.hooks.postHandler)await z.hooks.postHandler(J);if(z.hasOnSendHook&&z.hooks.onSend){let Y=await z.hooks.onSend(J,L);if(Y)return Y}return L??new Response("No response from handler",{status:204})}catch(L){return new Response("Internal Server Error",{status:500})}}async function T(G,E,I={}){let z=G.headers.get("origin")??"*",J=I?.origin,U=I?.allowedHeaders??["Content-Type","Authorization"],Z=I?.methods??["GET","POST","PUT","DELETE","OPTIONS"],L=I?.credentials??!1,Y=I?.exposedHeaders??[];if(E.setHeader("Access-Control-Allow-Methods",Z),E.setHeader("Access-Control-Allow-Headers",U),E.setHeader("Access-Control-Allow-Credentials",L),Y.length)E.setHeader("Access-Control-Expose-Headers",Y);if(J==="*")E.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(J))if(z&&J.includes(z))E.setHeader("Access-Control-Allow-Origin",z);else if(J.includes("*"))E.setHeader("Access-Control-Allow-Origin","*");else return E.status(403).json({message:"CORS not allowed"});else if(typeof J==="string")if(z===J)E.setHeader("Access-Control-Allow-Origin",z);else return E.status(403).json({message:"CORS not allowed"});else return E.status(403).json({message:"CORS not allowed"});if(E.setHeader("Access-Control-Allow-Origin",z),G.method==="OPTIONS")return E.setHeader("Access-Control-Max-Age","86400"),E.status(204).text("");return null}export{Q as default};
package/dist/main.d.ts CHANGED
@@ -2,7 +2,7 @@ import Trie from "./trie.js";
2
2
  import rateLimit from "./utils.js";
3
3
  import { corsT, FilterMethods, HookFunction, HookType, middlewareFunc, type handlerFunction, type Hooks, type listenCalllBackType } from "./types.js";
4
4
  import { Server } from "bun";
5
- declare class Diesel {
5
+ export default class Diesel {
6
6
  #private;
7
7
  routes: string[] | undefined;
8
8
  globalMiddlewares: middlewareFunc[];
@@ -31,4 +31,4 @@ declare class Diesel {
31
31
  patch(path: string, ...handlers: handlerFunction[]): this;
32
32
  delete(path: any, ...handlers: handlerFunction[]): this;
33
33
  }
34
- export { Diesel, rateLimit, };
34
+ export { rateLimit, };
package/dist/main.js CHANGED
@@ -1 +1 @@
1
- class K{children;isEndOfWord;handler;isDynamic;pattern;path;method;subMiddlewares;constructor(){this.children={},this.isEndOfWord=!1,this.handler=[],this.isDynamic=!1,this.pattern="",this.path="",this.method=[],this.subMiddlewares=new Map}}class Q{root;constructor(){this.root=new K}insert(z,F){let G=this.root,J=z.split("/").filter(Boolean);if(z==="/"){G.isEndOfWord=!0,G.handler.push(F.handler),G.path=z,G.method.push(F.method);return}for(let U of J){let X=!1,Y=U;if(U.startsWith(":"))X=!0,Y=":";if(!G.children[Y])G.children[Y]=new K;G=G.children[Y],G.isDynamic=X,G.pattern=U}G.isEndOfWord=!0,G.method.push(F.method),G.handler.push(F.handler),G.path=z}search(z,F){let G=this.root,J=z.split("/").filter(Boolean);for(let X of J){let Y=X;if(!G.children[Y])if(G.children[":"])G=G.children[":"];else return null;else G=G.children[Y]}let U=G.method.indexOf(F);if(U!==-1)return{path:G.path,handler:G.handler[U],isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[U]};return{path:G.path,handler:G.handler,isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[U]}}}function M(z,F,G){let J=new Headers,U={},X=!1,Y=null,$=null,_=null,A,V=200;return{req:z,server:F,url:G,next:()=>{},status(Z){return V=Z,this},getIP(){return this.server.requestIP(this.req)},async body(){if(!A)A=await T(z);if(A.error)return new Response(JSON.stringify({error:A.error}),{status:400});return A},setHeader(Z,E){return J.set(Z,E),this},set(Z,E){return U[Z]=E,this},get(Z){return U[Z]||null},setAuth(Z){return X=Z,this},getAuth(){return X},text(Z,E){return new Response(Z,{status:E??V,headers:J})},json(Z,E){return new Response(JSON.stringify(Z),{status:E??V,headers:J})},html(Z,E){return new Response(Bun.file(Z),{status:E??V,headers:J})},file(Z,E){return new Response(Bun.file(Z),{status:E??V,headers:J})},redirect(Z,E){return J.set("Location",Z),new Response(null,{status:E??302,headers:J})},getParams(Z){if(!_)_=N(z?.routePattern,G?.pathname);return Z?_[Z]||null:_},getQuery(Z){if(!Y)Y=Object.fromEntries(G.searchParams);return Z?Y[Z]||null:Y},async cookie(Z,E,L={}){let W=`${encodeURIComponent(Z)}=${encodeURIComponent(E)}`;if(L.maxAge)W+=`; Max-Age=${L.maxAge}`;if(L.expires)W+=`; Expires=${L.expires.toUTCString()}`;if(L.path)W+=`; Path=${L.path}`;if(L.domain)W+=`; Domain=${L.domain}`;if(L.secure)W+="; Secure";if(L.httpOnly)W+="; HttpOnly";if(L.sameSite)W+=`; SameSite=${L.sameSite}`;return J?.append("Set-Cookie",W),this},async getCookie(Z){if(!$){let E=z.headers.get("cookie");if(E)$=await D(E)}return Z?$[Z]||null:$}}}async function D(z){let F={};if(!z)return F;return z.split(";").forEach((J)=>{let[U,X]=J?.trim()?.split("=");if(U&&X)F[U.trim()]=X.split(" ")[0].trim()}),F}function N(z,F){let G={},J=z.split("/"),[U]=F.split("?"),X=U.split("/");if(J.length!==X.length)return null;return J.forEach((Y,$)=>{if(Y.startsWith(":")){let _=Y.slice(1);G[_]=X[$]}}),G}async function T(z){let F=z.headers.get("Content-Type")||"";if(!F)return{};try{if(F.startsWith("application/json"))return await z.json();if(F.startsWith("application/x-www-form-urlencoded")){let G=await z.text();return Object.fromEntries(new URLSearchParams(G))}if(F.startsWith("multipart/form-data")){let G=await z.formData();return b(G)}return{error:"Unknown request body type"}}catch(G){return{error:"Invalid request body format"}}}function b(z){let F={};for(let[G,J]of z.entries())F[G]=J;return F}async function B(z,F,G,J){let U=M(z,F,G),X=J.trie.search(G.pathname,z.method);if(!X||!X.handler)return new Response(`Route not found for ${G.pathname}`,{status:404});if(X.method!==z.method)return new Response("Method not allowed",{status:405});if(X.isDynamic)z.routePattern=X.path;if(J.corsConfig){let Y=await C(z,U,J.corsConfig);if(Y)return Y}if(J.hasOnReqHook&&J.hooks.onRequest)J.hooks.onRequest(U,F);if(J.filters.length>0){let Y=z.routePattern??G.pathname;if(J.filters.includes(Y)===!1)if(J.filterFunction){let _=await J?.filterFunction(U);if(_)return _}else return new Response(JSON.stringify({message:"Authentication required"}),{status:400})}if(J.hasMiddleware){let Y=[...J.globalMiddlewares,...J.middlewares.get(G.pathname)||[]];for(let $ of Y){let _=await $(U,F);if(_)return _}}if(J.hasPreHandlerHook&&J.hooks.preHandler){let Y=await J.hooks.preHandler(U);if(Y)return Y}try{let Y=await X.handler(U);if(J.hasPostHandlerHook&&J.hooks.postHandler)await J.hooks.postHandler(U);if(J.hasOnSendHook&&J.hooks.onSend){let $=await J.hooks.onSend(U,Y);if($)return $}return Y??new Response("No response from handler",{status:204})}catch(Y){return new Response("Internal Server Error",{status:500})}}async function C(z,F,G={}){let J=z.headers.get("origin")??"*",U=G?.origin,X=G?.allowedHeaders??["Content-Type","Authorization"],Y=G?.methods??["GET","POST","PUT","DELETE","OPTIONS"],$=G?.credentials??!1,_=G?.exposedHeaders??[];if(F.setHeader("Access-Control-Allow-Methods",Y),F.setHeader("Access-Control-Allow-Headers",X),F.setHeader("Access-Control-Allow-Credentials",$),_.length)F.setHeader("Access-Control-Expose-Headers",_);if(U==="*")F.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(U))if(J&&U.includes(J))F.setHeader("Access-Control-Allow-Origin",J);else if(U.includes("*"))F.setHeader("Access-Control-Allow-Origin","*");else return F.status(403).json({message:"CORS not allowed"});else if(typeof U==="string")if(J===U)F.setHeader("Access-Control-Allow-Origin",J);else return F.status(403).json({message:"CORS not allowed"});else return F.status(403).json({message:"CORS not allowed"});if(F.setHeader("Access-Control-Allow-Origin",J),z.method==="OPTIONS")return F.setHeader("Access-Control-Max-Age","86400"),F.status(204).text("");return null}function j(z){let{time:F=60000,max:G=100,message:J="Rate limit exceeded. Please try again later."}=z,U=new Map;return(X)=>{let Y=new Date,$=X.getIP().address;if(!U.has($))U.set($,{count:0,startTime:Y});let _=U.get($);if(_)if(Y-_.startTime>F)_.count=1,_.startTime=Y;else _.count++;if(_&&_.count>G)return X.status(429).json({error:J});X.next()}}class v{routes;globalMiddlewares;middlewares;trie;hasOnReqHook;hasMiddleware;hasPreHandlerHook;hasPostHandlerHook;hasOnSendHook;hooks;corsConfig;filters;filterFunction;constructor(){this.routes=[],this.filters=[],this.filterFunction=null,this.globalMiddlewares=[],this.middlewares=new Map,this.trie=new Q,this.corsConfig=null,this.hasMiddleware=!1,this.hasOnReqHook=!1,this.hasPreHandlerHook=!1,this.hasPostHandlerHook=!1,this.hasOnSendHook=!1,this.hooks={onRequest:null,preHandler:null,postHandler:null,onSend:null,onError:null,onClose:null}}filter(){return{routeMatcher:(...z)=>{return this.routes=z.sort(),this.filter()},permitAll:()=>{for(let z of this?.routes)this.filters.push(z);return this.filter()},require:(z)=>{if(!z||typeof z!=="function")return new Response(JSON.stringify({message:"Authentication required"}),{status:400});this.filterFunction=z}}}cors(z){this.corsConfig=z}addHooks(z,F){if(typeof z!=="string")throw new Error("hookName must be a string");if(typeof F!=="function")throw new Error("callback must be a instance of function");if(this.hooks.hasOwnProperty(z))this.hooks[z]=F;else throw new Error(`Unknown hook type: ${z}`)}compile(){if(this.globalMiddlewares.length>0)this.hasMiddleware=!0;for(let[z,F]of this.middlewares.entries())if(F.length>0){this.hasMiddleware=!0;break}if(this.hooks.onRequest)this.hasOnReqHook=!0;if(this.hooks.preHandler)this.hasPreHandlerHook=!0;if(this.hooks.postHandler)this.hasPostHandlerHook=!0;if(this.hooks.onSend)this.hasOnSendHook=!0}listen(z,F,{sslCert:G=null,sslKey:J=null}={}){if(typeof Bun==="undefined")throw new Error(".listen() is designed to run on Bun only...");if(typeof z!=="number")throw new Error("Port must be a numeric value");this.compile();let U=this,X={port:z,fetch:async($,_)=>{let A=new URL($.url);try{return await B($,_,A,this)}catch(V){return new Response("Internal Server Error",{status:500})}},onClose(){console.log("Server is shutting down...")}};if(G&&J)X.certFile=G,X.keyFile=J;let Y=Bun.serve(X);if(typeof F==="function")return F();if(G&&J)console.log(`HTTPS server is running on https://localhost:${z}`);else console.log(`HTTP server is running on http://localhost:${z}`);return Y}register(z,F){if(typeof z!=="string")throw new Error("path must be a string");if(typeof F!=="object")throw new Error("handler parameter should be a instance of router object",F);let G=Object.entries(F.trie.root.children);F.trie.root.subMiddlewares.forEach((J,U)=>{if(!this.middlewares.has(z+U))this.middlewares.set(z+U,[]);J?.forEach((X)=>{if(!this.middlewares.get(z+U)?.includes(X))this.middlewares.get(z+U)?.push(X)})});for(let[J,U]of G){let X=z+U?.path,Y=U.handler[0],$=U.method[0];this.trie.insert(X,{handler:Y,method:$})}F.trie=new Q}#z(z,F,G){if(typeof F!=="string")throw new Error("Path must be a string type");if(typeof z!=="string")throw new Error("method must be a string type");let J=G.slice(0,-1),U=G[G.length-1];if(!this.middlewares.has(F))this.middlewares.set(F,[]);J.forEach((X)=>{if(F==="/"){if(!this.globalMiddlewares.includes(X))this.globalMiddlewares.push(X)}else if(!this.middlewares.get(F)?.includes(X))this.middlewares.get(F)?.push(X)}),this.trie.insert(F,{handler:U,method:z})}use(z,F){if(typeof z==="function"){if(!this.globalMiddlewares.includes(z))this.globalMiddlewares.push(z);return}let G=z;if(!this.middlewares.has(G))this.middlewares.set(G,[]);if(F){if(!this.middlewares.get(G)?.includes(F))this.middlewares.get(G)?.push(F)}}get(z,...F){return this.#z("GET",z,F),this}post(z,...F){return this.#z("POST",z,F),this}put(z,...F){return this.#z("PUT",z,F),this}patch(z,...F){return this.#z("PATCH",z,F),this}delete(z,...F){return this.#z("DELETE",z,F),this}}export{j as rateLimit,v as Diesel};
1
+ class D{children;isEndOfWord;handler;isDynamic;pattern;path;method;subMiddlewares;constructor(){this.children={},this.isEndOfWord=!1,this.handler=[],this.isDynamic=!1,this.pattern="",this.path="",this.method=[],this.subMiddlewares=new Map}}class Q{root;constructor(){this.root=new D}insert(z,F){let G=this.root,J=z.split("/").filter(Boolean);if(z==="/"){G.isEndOfWord=!0,G.handler.push(F.handler),G.path=z,G.method.push(F.method);return}for(let U of J){let X=!1,_=U;if(U.startsWith(":"))X=!0,_=":";if(!G.children[_])G.children[_]=new D;G=G.children[_],G.isDynamic=X,G.pattern=U}G.isEndOfWord=!0,G.method.push(F.method),G.handler.push(F.handler),G.path=z}search(z,F){let G=this.root,J=z.split("/").filter(Boolean);for(let X of J){let _=X;if(!G.children[_])if(G.children[":"])G=G.children[":"];else return null;else G=G.children[_]}let U=G.method.indexOf(F);if(U!==-1)return{path:G.path,handler:G.handler[U],isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[U]};return{path:G.path,handler:G.handler,isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[U]}}}function K(z,F,G){let J=new Headers,U={},X=!1,_=null,Y=null,$=null,L,V=200;return{req:z,server:F,url:G,next:()=>{},status(Z){return V=Z,this},getIP(){return this.server.requestIP(this.req)},async body(){if(!L)L=await b(z);if(L.error)return new Response(JSON.stringify({error:L.error}),{status:400});return L},setHeader(Z,E){return J.set(Z,E),this},set(Z,E){return U[Z]=E,this},get(Z){return U[Z]||null},setAuth(Z){return X=Z,this},getAuth(){return X},text(Z,E){return new Response(Z,{status:E??V,headers:J})},json(Z,E){return new Response(JSON.stringify(Z),{status:E??V,headers:J})},html(Z,E){return new Response(Bun.file(Z),{status:E??V,headers:J})},file(Z,E){return new Response(Bun.file(Z),{status:E??V,headers:J})},redirect(Z,E){return J.set("Location",Z),new Response(null,{status:E??302,headers:J})},getParams(Z){if(!$)$=T(z?.routePattern,G?.pathname);return Z?$[Z]||null:$},getQuery(Z){if(!_)_=Object.fromEntries(G.searchParams);return Z?_[Z]||null:_},async cookie(Z,E,W={}){let A=`${encodeURIComponent(Z)}=${encodeURIComponent(E)}`;if(W.maxAge)A+=`; Max-Age=${W.maxAge}`;if(W.expires)A+=`; Expires=${W.expires.toUTCString()}`;if(W.path)A+=`; Path=${W.path}`;if(W.domain)A+=`; Domain=${W.domain}`;if(W.secure)A+="; Secure";if(W.httpOnly)A+="; HttpOnly";if(W.sameSite)A+=`; SameSite=${W.sameSite}`;return J?.append("Set-Cookie",A),this},async getCookie(Z){if(!Y){let E=z.headers.get("cookie");if(E)Y=await N(E)}return Z?Y[Z]||null:Y}}}async function N(z){let F={};if(!z)return F;return z.split(";").forEach((J)=>{let[U,X]=J?.trim()?.split("=");if(U&&X)F[U.trim()]=X.split(" ")[0].trim()}),F}function T(z,F){let G={},J=z.split("/"),[U]=F.split("?"),X=U.split("/");if(J.length!==X.length)return null;return J.forEach((_,Y)=>{if(_.startsWith(":")){let $=_.slice(1);G[$]=X[Y]}}),G}async function b(z){let F=z.headers.get("Content-Type")||"";if(!F)return{};try{if(F.startsWith("application/json"))return await z.json();if(F.startsWith("application/x-www-form-urlencoded")){let G=await z.text();return Object.fromEntries(new URLSearchParams(G))}if(F.startsWith("multipart/form-data")){let G=await z.formData();return C(G)}return{error:"Unknown request body type"}}catch(G){return{error:"Invalid request body format"}}}function C(z){let F={};for(let[G,J]of z.entries())F[G]=J;return F}async function M(z,F,G,J){let U=K(z,F,G),X=J.trie.search(G.pathname,z.method);if(!X||X.method!==z.method)return new Response(X?"Method not allowed":`Route not found for ${G.pathname}`,{status:X?405:404});if(X.isDynamic)z.routePattern=X.path;if(J.corsConfig){let Y=await v(z,U,J.corsConfig);if(Y)return Y}if(J.hasOnReqHook&&J.hooks.onRequest)J.hooks.onRequest(U,F);if(J.filters.length>0){let Y=z.routePattern??G.pathname;if(J.filters.includes(Y)===!1)if(J.filterFunction){let L=await J?.filterFunction(U,F);if(L)return L}else return new Response(JSON.stringify({message:"Authentication required"}),{status:400})}if(J.hasMiddleware){let Y=[...J.globalMiddlewares,...J.middlewares.get(G.pathname)||[]];for(let $ of Y){let L=await $(U,F);if(L)return L}}if(J.hasPreHandlerHook&&J.hooks.preHandler){let Y=await J.hooks.preHandler(U);if(Y)return Y}let _=J.hasPreHandlerHook?await J.hooks.preHandler?.(U):null;if(_)return _;try{let Y=await X.handler(U);if(J.hasPostHandlerHook&&J.hooks.postHandler)await J.hooks.postHandler(U);if(J.hasOnSendHook&&J.hooks.onSend){let $=await J.hooks.onSend(U,Y);if($)return $}return Y??new Response("No response from handler",{status:204})}catch(Y){return new Response("Internal Server Error",{status:500})}}async function v(z,F,G={}){let J=z.headers.get("origin")??"*",U=G?.origin,X=G?.allowedHeaders??["Content-Type","Authorization"],_=G?.methods??["GET","POST","PUT","DELETE","OPTIONS"],Y=G?.credentials??!1,$=G?.exposedHeaders??[];if(F.setHeader("Access-Control-Allow-Methods",_),F.setHeader("Access-Control-Allow-Headers",X),F.setHeader("Access-Control-Allow-Credentials",Y),$.length)F.setHeader("Access-Control-Expose-Headers",$);if(U==="*")F.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(U))if(J&&U.includes(J))F.setHeader("Access-Control-Allow-Origin",J);else if(U.includes("*"))F.setHeader("Access-Control-Allow-Origin","*");else return F.status(403).json({message:"CORS not allowed"});else if(typeof U==="string")if(J===U)F.setHeader("Access-Control-Allow-Origin",J);else return F.status(403).json({message:"CORS not allowed"});else return F.status(403).json({message:"CORS not allowed"});if(F.setHeader("Access-Control-Allow-Origin",J),z.method==="OPTIONS")return F.setHeader("Access-Control-Max-Age","86400"),F.status(204).text("");return null}function B(z){let{time:F=60000,max:G=100,message:J="Rate limit exceeded. Please try again later."}=z,U=new Map;return(X)=>{let _=new Date,Y=X.getIP().address;if(!U.has(Y))U.set(Y,{count:0,startTime:_});let $=U.get(Y);if($)if(_-$.startTime>F)$.count=1,$.startTime=_;else $.count++;if($&&$.count>G)return X.status(429).json({error:J});X.next()}}class j{routes;globalMiddlewares;middlewares;trie;hasOnReqHook;hasMiddleware;hasPreHandlerHook;hasPostHandlerHook;hasOnSendHook;hooks;corsConfig;filters;filterFunction;constructor(){this.routes=[],this.filters=[],this.filterFunction=null,this.globalMiddlewares=[],this.middlewares=new Map,this.trie=new Q,this.corsConfig=null,this.hasMiddleware=!1,this.hasOnReqHook=!1,this.hasPreHandlerHook=!1,this.hasPostHandlerHook=!1,this.hasOnSendHook=!1,this.hooks={onRequest:null,preHandler:null,postHandler:null,onSend:null,onError:null,onClose:null}}filter(){return{routeMatcher:(...z)=>{return this.routes=z.sort(),this.filter()},permitAll:()=>{for(let z of this?.routes)this.filters.push(z);return this.filter()},require:(z)=>{if(!z||typeof z!=="function")return new Response(JSON.stringify({message:"Authentication required"}),{status:400});this.filterFunction=z}}}cors(z){this.corsConfig=z}addHooks(z,F){if(typeof z!=="string")throw new Error("hookName must be a string");if(typeof F!=="function")throw new Error("callback must be a instance of function");if(this.hooks.hasOwnProperty(z))this.hooks[z]=F;else throw new Error(`Unknown hook type: ${z}`)}compile(){if(this.globalMiddlewares.length>0)this.hasMiddleware=!0;for(let[z,F]of this.middlewares.entries())if(F.length>0){this.hasMiddleware=!0;break}if(this.hooks.onRequest)this.hasOnReqHook=!0;if(this.hooks.preHandler)this.hasPreHandlerHook=!0;if(this.hooks.postHandler)this.hasPostHandlerHook=!0;if(this.hooks.onSend)this.hasOnSendHook=!0}listen(z,F,{sslCert:G=null,sslKey:J=null}={}){if(typeof Bun==="undefined")throw new Error(".listen() is designed to run on Bun only...");if(typeof z!=="number")throw new Error("Port must be a numeric value");this.compile();let U=this,X={port:z,fetch:async(Y,$)=>{let L=new URL(Y.url);try{return await M(Y,$,L,this)}catch(V){return new Response("Internal Server Error",{status:500})}},onClose(){console.log("Server is shutting down...")}};if(G&&J)X.certFile=G,X.keyFile=J;let _=Bun.serve(X);if(typeof F==="function")return F();if(G&&J)console.log(`HTTPS server is running on https://localhost:${z}`);else console.log(`HTTP server is running on http://localhost:${z}`);return _}register(z,F){if(typeof z!=="string")throw new Error("path must be a string");if(typeof F!=="object")throw new Error("handler parameter should be a instance of router object",F);let G=Object.entries(F.trie.root.children);F.trie.root.subMiddlewares.forEach((J,U)=>{if(!this.middlewares.has(z+U))this.middlewares.set(z+U,[]);J?.forEach((X)=>{if(!this.middlewares.get(z+U)?.includes(X))this.middlewares.get(z+U)?.push(X)})});for(let[J,U]of G){let X=z+U?.path,_=U.handler[0],Y=U.method[0];this.trie.insert(X,{handler:_,method:Y})}F.trie=new Q}#z(z,F,G){if(typeof F!=="string")throw new Error("Path must be a string type");if(typeof z!=="string")throw new Error("method must be a string type");let J=G.slice(0,-1),U=G[G.length-1];if(!this.middlewares.has(F))this.middlewares.set(F,[]);J.forEach((X)=>{if(F==="/"){if(!this.globalMiddlewares.includes(X))this.globalMiddlewares.push(X)}else if(!this.middlewares.get(F)?.includes(X))this.middlewares.get(F)?.push(X)}),this.trie.insert(F,{handler:U,method:z})}use(z,F){if(typeof z==="function"){if(!this.globalMiddlewares.includes(z))this.globalMiddlewares.push(z);return}let G=z;if(!this.middlewares.has(G))this.middlewares.set(G,[]);if(F){if(!this.middlewares.get(G)?.includes(F))this.middlewares.get(G)?.push(F)}}get(z,...F){return this.#z("GET",z,F),this}post(z,...F){return this.#z("POST",z,F),this}put(z,...F){return this.#z("PUT",z,F),this}patch(z,...F){return this.#z("PATCH",z,F),this}delete(z,...F){return this.#z("DELETE",z,F),this}}export{B as rateLimit,j as default};
package/dist/router.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Diesel } from "./main";
1
+ import Diesel from "./main";
2
2
  import type { handlerFunction } from "./types";
3
3
  declare class Router extends Diesel {
4
4
  #private;
package/dist/router.js CHANGED
@@ -1 +1 @@
1
- class K{children;isEndOfWord;handler;isDynamic;pattern;path;method;subMiddlewares;constructor(){this.children={},this.isEndOfWord=!1,this.handler=[],this.isDynamic=!1,this.pattern="",this.path="",this.method=[],this.subMiddlewares=new Map}}class Q{root;constructor(){this.root=new K}insert(F,z){let G=this.root,J=F.split("/").filter(Boolean);if(F==="/"){G.isEndOfWord=!0,G.handler.push(z.handler),G.path=F,G.method.push(z.method);return}for(let U of J){let X=!1,Y=U;if(U.startsWith(":"))X=!0,Y=":";if(!G.children[Y])G.children[Y]=new K;G=G.children[Y],G.isDynamic=X,G.pattern=U}G.isEndOfWord=!0,G.method.push(z.method),G.handler.push(z.handler),G.path=F}search(F,z){let G=this.root,J=F.split("/").filter(Boolean);for(let X of J){let Y=X;if(!G.children[Y])if(G.children[":"])G=G.children[":"];else return null;else G=G.children[Y]}let U=G.method.indexOf(z);if(U!==-1)return{path:G.path,handler:G.handler[U],isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[U]};return{path:G.path,handler:G.handler,isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[U]}}}function B(F,z,G){let J=new Headers,U={},X=!1,Y=null,$=null,_=null,A,V=200;return{req:F,server:z,url:G,next:()=>{},status(Z){return V=Z,this},getIP(){return this.server.requestIP(this.req)},async body(){if(!A)A=await b(F);if(A.error)return new Response(JSON.stringify({error:A.error}),{status:400});return A},setHeader(Z,E){return J.set(Z,E),this},set(Z,E){return U[Z]=E,this},get(Z){return U[Z]||null},setAuth(Z){return X=Z,this},getAuth(){return X},text(Z,E){return new Response(Z,{status:E??V,headers:J})},json(Z,E){return new Response(JSON.stringify(Z),{status:E??V,headers:J})},html(Z,E){return new Response(Bun.file(Z),{status:E??V,headers:J})},file(Z,E){return new Response(Bun.file(Z),{status:E??V,headers:J})},redirect(Z,E){return J.set("Location",Z),new Response(null,{status:E??302,headers:J})},getParams(Z){if(!_)_=C(F?.routePattern,G?.pathname);return Z?_[Z]||null:_},getQuery(Z){if(!Y)Y=Object.fromEntries(G.searchParams);return Z?Y[Z]||null:Y},async cookie(Z,E,L={}){let W=`${encodeURIComponent(Z)}=${encodeURIComponent(E)}`;if(L.maxAge)W+=`; Max-Age=${L.maxAge}`;if(L.expires)W+=`; Expires=${L.expires.toUTCString()}`;if(L.path)W+=`; Path=${L.path}`;if(L.domain)W+=`; Domain=${L.domain}`;if(L.secure)W+="; Secure";if(L.httpOnly)W+="; HttpOnly";if(L.sameSite)W+=`; SameSite=${L.sameSite}`;return J?.append("Set-Cookie",W),this},async getCookie(Z){if(!$){let E=F.headers.get("cookie");if(E)$=await T(E)}return Z?$[Z]||null:$}}}async function T(F){let z={};if(!F)return z;return F.split(";").forEach((J)=>{let[U,X]=J?.trim()?.split("=");if(U&&X)z[U.trim()]=X.split(" ")[0].trim()}),z}function C(F,z){let G={},J=F.split("/"),[U]=z.split("?"),X=U.split("/");if(J.length!==X.length)return null;return J.forEach((Y,$)=>{if(Y.startsWith(":")){let _=Y.slice(1);G[_]=X[$]}}),G}async function b(F){let z=F.headers.get("Content-Type")||"";if(!z)return{};try{if(z.startsWith("application/json"))return await F.json();if(z.startsWith("application/x-www-form-urlencoded")){let G=await F.text();return Object.fromEntries(new URLSearchParams(G))}if(z.startsWith("multipart/form-data")){let G=await F.formData();return v(G)}return{error:"Unknown request body type"}}catch(G){return{error:"Invalid request body format"}}}function v(F){let z={};for(let[G,J]of F.entries())z[G]=J;return z}async function j(F,z,G,J){let U=B(F,z,G),X=J.trie.search(G.pathname,F.method);if(!X||!X.handler)return new Response(`Route not found for ${G.pathname}`,{status:404});if(X.method!==F.method)return new Response("Method not allowed",{status:405});if(X.isDynamic)F.routePattern=X.path;if(J.corsConfig){let Y=await I(F,U,J.corsConfig);if(Y)return Y}if(J.hasOnReqHook&&J.hooks.onRequest)J.hooks.onRequest(U,z);if(J.filters.length>0){let Y=F.routePattern??G.pathname;if(J.filters.includes(Y)===!1)if(J.filterFunction){let _=await J?.filterFunction(U);if(_)return _}else return new Response(JSON.stringify({message:"Authentication required"}),{status:400})}if(J.hasMiddleware){let Y=[...J.globalMiddlewares,...J.middlewares.get(G.pathname)||[]];for(let $ of Y){let _=await $(U,z);if(_)return _}}if(J.hasPreHandlerHook&&J.hooks.preHandler){let Y=await J.hooks.preHandler(U);if(Y)return Y}try{let Y=await X.handler(U);if(J.hasPostHandlerHook&&J.hooks.postHandler)await J.hooks.postHandler(U);if(J.hasOnSendHook&&J.hooks.onSend){let $=await J.hooks.onSend(U,Y);if($)return $}return Y??new Response("No response from handler",{status:204})}catch(Y){return new Response("Internal Server Error",{status:500})}}async function I(F,z,G={}){let J=F.headers.get("origin")??"*",U=G?.origin,X=G?.allowedHeaders??["Content-Type","Authorization"],Y=G?.methods??["GET","POST","PUT","DELETE","OPTIONS"],$=G?.credentials??!1,_=G?.exposedHeaders??[];if(z.setHeader("Access-Control-Allow-Methods",Y),z.setHeader("Access-Control-Allow-Headers",X),z.setHeader("Access-Control-Allow-Credentials",$),_.length)z.setHeader("Access-Control-Expose-Headers",_);if(U==="*")z.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(U))if(J&&U.includes(J))z.setHeader("Access-Control-Allow-Origin",J);else if(U.includes("*"))z.setHeader("Access-Control-Allow-Origin","*");else return z.status(403).json({message:"CORS not allowed"});else if(typeof U==="string")if(J===U)z.setHeader("Access-Control-Allow-Origin",J);else return z.status(403).json({message:"CORS not allowed"});else return z.status(403).json({message:"CORS not allowed"});if(z.setHeader("Access-Control-Allow-Origin",J),F.method==="OPTIONS")return z.setHeader("Access-Control-Max-Age","86400"),z.status(204).text("");return null}function M(F){let{time:z=60000,max:G=100,message:J="Rate limit exceeded. Please try again later."}=F,U=new Map;return(X)=>{let Y=new Date,$=X.getIP().address;if(!U.has($))U.set($,{count:0,startTime:Y});let _=U.get($);if(_)if(Y-_.startTime>z)_.count=1,_.startTime=Y;else _.count++;if(_&&_.count>G)return X.status(429).json({error:J});X.next()}}class D{routes;globalMiddlewares;middlewares;trie;hasOnReqHook;hasMiddleware;hasPreHandlerHook;hasPostHandlerHook;hasOnSendHook;hooks;corsConfig;filters;filterFunction;constructor(){this.routes=[],this.filters=[],this.filterFunction=null,this.globalMiddlewares=[],this.middlewares=new Map,this.trie=new Q,this.corsConfig=null,this.hasMiddleware=!1,this.hasOnReqHook=!1,this.hasPreHandlerHook=!1,this.hasPostHandlerHook=!1,this.hasOnSendHook=!1,this.hooks={onRequest:null,preHandler:null,postHandler:null,onSend:null,onError:null,onClose:null}}filter(){return{routeMatcher:(...F)=>{return this.routes=F.sort(),this.filter()},permitAll:()=>{for(let F of this?.routes)this.filters.push(F);return this.filter()},require:(F)=>{if(!F||typeof F!=="function")return new Response(JSON.stringify({message:"Authentication required"}),{status:400});this.filterFunction=F}}}cors(F){this.corsConfig=F}addHooks(F,z){if(typeof F!=="string")throw new Error("hookName must be a string");if(typeof z!=="function")throw new Error("callback must be a instance of function");if(this.hooks.hasOwnProperty(F))this.hooks[F]=z;else throw new Error(`Unknown hook type: ${F}`)}compile(){if(this.globalMiddlewares.length>0)this.hasMiddleware=!0;for(let[F,z]of this.middlewares.entries())if(z.length>0){this.hasMiddleware=!0;break}if(this.hooks.onRequest)this.hasOnReqHook=!0;if(this.hooks.preHandler)this.hasPreHandlerHook=!0;if(this.hooks.postHandler)this.hasPostHandlerHook=!0;if(this.hooks.onSend)this.hasOnSendHook=!0}listen(F,z,{sslCert:G=null,sslKey:J=null}={}){if(typeof Bun==="undefined")throw new Error(".listen() is designed to run on Bun only...");if(typeof F!=="number")throw new Error("Port must be a numeric value");this.compile();let U=this,X={port:F,fetch:async($,_)=>{let A=new URL($.url);try{return await j($,_,A,this)}catch(V){return new Response("Internal Server Error",{status:500})}},onClose(){console.log("Server is shutting down...")}};if(G&&J)X.certFile=G,X.keyFile=J;let Y=Bun.serve(X);if(typeof z==="function")return z();if(G&&J)console.log(`HTTPS server is running on https://localhost:${F}`);else console.log(`HTTP server is running on http://localhost:${F}`);return Y}register(F,z){if(typeof F!=="string")throw new Error("path must be a string");if(typeof z!=="object")throw new Error("handler parameter should be a instance of router object",z);let G=Object.entries(z.trie.root.children);z.trie.root.subMiddlewares.forEach((J,U)=>{if(!this.middlewares.has(F+U))this.middlewares.set(F+U,[]);J?.forEach((X)=>{if(!this.middlewares.get(F+U)?.includes(X))this.middlewares.get(F+U)?.push(X)})});for(let[J,U]of G){let X=F+U?.path,Y=U.handler[0],$=U.method[0];this.trie.insert(X,{handler:Y,method:$})}z.trie=new Q}#z(F,z,G){if(typeof z!=="string")throw new Error("Path must be a string type");if(typeof F!=="string")throw new Error("method must be a string type");let J=G.slice(0,-1),U=G[G.length-1];if(!this.middlewares.has(z))this.middlewares.set(z,[]);J.forEach((X)=>{if(z==="/"){if(!this.globalMiddlewares.includes(X))this.globalMiddlewares.push(X)}else if(!this.middlewares.get(z)?.includes(X))this.middlewares.get(z)?.push(X)}),this.trie.insert(z,{handler:U,method:F})}use(F,z){if(typeof F==="function"){if(!this.globalMiddlewares.includes(F))this.globalMiddlewares.push(F);return}let G=F;if(!this.middlewares.has(G))this.middlewares.set(G,[]);if(z){if(!this.middlewares.get(G)?.includes(z))this.middlewares.get(G)?.push(z)}}get(F,...z){return this.#z("GET",F,z),this}post(F,...z){return this.#z("POST",F,z),this}put(F,...z){return this.#z("PUT",F,z),this}patch(F,...z){return this.#z("PATCH",F,z),this}delete(F,...z){return this.#z("DELETE",F,z),this}}class N extends D{constructor(){super()}#z(F,z,G){if(!this.trie.root.subMiddlewares.has(z))this.trie.root.subMiddlewares.set(z,[]);let J=G.slice(0,-1),U=this.trie.root.subMiddlewares.get(z);J.forEach((Y)=>{if(!U?.includes(Y))U?.push(Y)});let X=G[G.length-1];this.trie.insert(z,{handler:X,method:F})}get(F,...z){return this.#z("GET",F,z),this}post(F,...z){return this.#z("POST",F,z),this}put(F,...z){return this.#z("PUT",F,z),this}patch(F,...z){return this.#z("PATCH",F,z),this}delete(F,...z){return this.#z("DELETE",F,z),this}}var x=N;export{x as default};
1
+ class B{children;isEndOfWord;handler;isDynamic;pattern;path;method;subMiddlewares;constructor(){this.children={},this.isEndOfWord=!1,this.handler=[],this.isDynamic=!1,this.pattern="",this.path="",this.method=[],this.subMiddlewares=new Map}}class Q{root;constructor(){this.root=new B}insert(F,z){let G=this.root,J=F.split("/").filter(Boolean);if(F==="/"){G.isEndOfWord=!0,G.handler.push(z.handler),G.path=F,G.method.push(z.method);return}for(let U of J){let X=!1,Y=U;if(U.startsWith(":"))X=!0,Y=":";if(!G.children[Y])G.children[Y]=new B;G=G.children[Y],G.isDynamic=X,G.pattern=U}G.isEndOfWord=!0,G.method.push(z.method),G.handler.push(z.handler),G.path=F}search(F,z){let G=this.root,J=F.split("/").filter(Boolean);for(let X of J){let Y=X;if(!G.children[Y])if(G.children[":"])G=G.children[":"];else return null;else G=G.children[Y]}let U=G.method.indexOf(z);if(U!==-1)return{path:G.path,handler:G.handler[U],isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[U]};return{path:G.path,handler:G.handler,isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[U]}}}function D(F,z,G){let J=new Headers,U={},X=!1,Y=null,Z=null,$=null,L,V=200;return{req:F,server:z,url:G,next:()=>{},status(_){return V=_,this},getIP(){return this.server.requestIP(this.req)},async body(){if(!L)L=await b(F);if(L.error)return new Response(JSON.stringify({error:L.error}),{status:400});return L},setHeader(_,E){return J.set(_,E),this},set(_,E){return U[_]=E,this},get(_){return U[_]||null},setAuth(_){return X=_,this},getAuth(){return X},text(_,E){return new Response(_,{status:E??V,headers:J})},json(_,E){return new Response(JSON.stringify(_),{status:E??V,headers:J})},html(_,E){return new Response(Bun.file(_),{status:E??V,headers:J})},file(_,E){return new Response(Bun.file(_),{status:E??V,headers:J})},redirect(_,E){return J.set("Location",_),new Response(null,{status:E??302,headers:J})},getParams(_){if(!$)$=C(F?.routePattern,G?.pathname);return _?$[_]||null:$},getQuery(_){if(!Y)Y=Object.fromEntries(G.searchParams);return _?Y[_]||null:Y},async cookie(_,E,W={}){let A=`${encodeURIComponent(_)}=${encodeURIComponent(E)}`;if(W.maxAge)A+=`; Max-Age=${W.maxAge}`;if(W.expires)A+=`; Expires=${W.expires.toUTCString()}`;if(W.path)A+=`; Path=${W.path}`;if(W.domain)A+=`; Domain=${W.domain}`;if(W.secure)A+="; Secure";if(W.httpOnly)A+="; HttpOnly";if(W.sameSite)A+=`; SameSite=${W.sameSite}`;return J?.append("Set-Cookie",A),this},async getCookie(_){if(!Z){let E=F.headers.get("cookie");if(E)Z=await T(E)}return _?Z[_]||null:Z}}}async function T(F){let z={};if(!F)return z;return F.split(";").forEach((J)=>{let[U,X]=J?.trim()?.split("=");if(U&&X)z[U.trim()]=X.split(" ")[0].trim()}),z}function C(F,z){let G={},J=F.split("/"),[U]=z.split("?"),X=U.split("/");if(J.length!==X.length)return null;return J.forEach((Y,Z)=>{if(Y.startsWith(":")){let $=Y.slice(1);G[$]=X[Z]}}),G}async function b(F){let z=F.headers.get("Content-Type")||"";if(!z)return{};try{if(z.startsWith("application/json"))return await F.json();if(z.startsWith("application/x-www-form-urlencoded")){let G=await F.text();return Object.fromEntries(new URLSearchParams(G))}if(z.startsWith("multipart/form-data")){let G=await F.formData();return v(G)}return{error:"Unknown request body type"}}catch(G){return{error:"Invalid request body format"}}}function v(F){let z={};for(let[G,J]of F.entries())z[G]=J;return z}async function j(F,z,G,J){let U=D(F,z,G),X=J.trie.search(G.pathname,F.method);if(!X||X.method!==F.method)return new Response(X?"Method not allowed":`Route not found for ${G.pathname}`,{status:X?405:404});if(X.isDynamic)F.routePattern=X.path;if(J.corsConfig){let Z=await I(F,U,J.corsConfig);if(Z)return Z}if(J.hasOnReqHook&&J.hooks.onRequest)J.hooks.onRequest(U,z);if(J.filters.length>0){let Z=F.routePattern??G.pathname;if(J.filters.includes(Z)===!1)if(J.filterFunction){let L=await J?.filterFunction(U,z);if(L)return L}else return new Response(JSON.stringify({message:"Authentication required"}),{status:400})}if(J.hasMiddleware){let Z=[...J.globalMiddlewares,...J.middlewares.get(G.pathname)||[]];for(let $ of Z){let L=await $(U,z);if(L)return L}}if(J.hasPreHandlerHook&&J.hooks.preHandler){let Z=await J.hooks.preHandler(U);if(Z)return Z}let Y=J.hasPreHandlerHook?await J.hooks.preHandler?.(U):null;if(Y)return Y;try{let Z=await X.handler(U);if(J.hasPostHandlerHook&&J.hooks.postHandler)await J.hooks.postHandler(U);if(J.hasOnSendHook&&J.hooks.onSend){let $=await J.hooks.onSend(U,Z);if($)return $}return Z??new Response("No response from handler",{status:204})}catch(Z){return new Response("Internal Server Error",{status:500})}}async function I(F,z,G={}){let J=F.headers.get("origin")??"*",U=G?.origin,X=G?.allowedHeaders??["Content-Type","Authorization"],Y=G?.methods??["GET","POST","PUT","DELETE","OPTIONS"],Z=G?.credentials??!1,$=G?.exposedHeaders??[];if(z.setHeader("Access-Control-Allow-Methods",Y),z.setHeader("Access-Control-Allow-Headers",X),z.setHeader("Access-Control-Allow-Credentials",Z),$.length)z.setHeader("Access-Control-Expose-Headers",$);if(U==="*")z.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(U))if(J&&U.includes(J))z.setHeader("Access-Control-Allow-Origin",J);else if(U.includes("*"))z.setHeader("Access-Control-Allow-Origin","*");else return z.status(403).json({message:"CORS not allowed"});else if(typeof U==="string")if(J===U)z.setHeader("Access-Control-Allow-Origin",J);else return z.status(403).json({message:"CORS not allowed"});else return z.status(403).json({message:"CORS not allowed"});if(z.setHeader("Access-Control-Allow-Origin",J),F.method==="OPTIONS")return z.setHeader("Access-Control-Max-Age","86400"),z.status(204).text("");return null}function M(F){let{time:z=60000,max:G=100,message:J="Rate limit exceeded. Please try again later."}=F,U=new Map;return(X)=>{let Y=new Date,Z=X.getIP().address;if(!U.has(Z))U.set(Z,{count:0,startTime:Y});let $=U.get(Z);if($)if(Y-$.startTime>z)$.count=1,$.startTime=Y;else $.count++;if($&&$.count>G)return X.status(429).json({error:J});X.next()}}class K{routes;globalMiddlewares;middlewares;trie;hasOnReqHook;hasMiddleware;hasPreHandlerHook;hasPostHandlerHook;hasOnSendHook;hooks;corsConfig;filters;filterFunction;constructor(){this.routes=[],this.filters=[],this.filterFunction=null,this.globalMiddlewares=[],this.middlewares=new Map,this.trie=new Q,this.corsConfig=null,this.hasMiddleware=!1,this.hasOnReqHook=!1,this.hasPreHandlerHook=!1,this.hasPostHandlerHook=!1,this.hasOnSendHook=!1,this.hooks={onRequest:null,preHandler:null,postHandler:null,onSend:null,onError:null,onClose:null}}filter(){return{routeMatcher:(...F)=>{return this.routes=F.sort(),this.filter()},permitAll:()=>{for(let F of this?.routes)this.filters.push(F);return this.filter()},require:(F)=>{if(!F||typeof F!=="function")return new Response(JSON.stringify({message:"Authentication required"}),{status:400});this.filterFunction=F}}}cors(F){this.corsConfig=F}addHooks(F,z){if(typeof F!=="string")throw new Error("hookName must be a string");if(typeof z!=="function")throw new Error("callback must be a instance of function");if(this.hooks.hasOwnProperty(F))this.hooks[F]=z;else throw new Error(`Unknown hook type: ${F}`)}compile(){if(this.globalMiddlewares.length>0)this.hasMiddleware=!0;for(let[F,z]of this.middlewares.entries())if(z.length>0){this.hasMiddleware=!0;break}if(this.hooks.onRequest)this.hasOnReqHook=!0;if(this.hooks.preHandler)this.hasPreHandlerHook=!0;if(this.hooks.postHandler)this.hasPostHandlerHook=!0;if(this.hooks.onSend)this.hasOnSendHook=!0}listen(F,z,{sslCert:G=null,sslKey:J=null}={}){if(typeof Bun==="undefined")throw new Error(".listen() is designed to run on Bun only...");if(typeof F!=="number")throw new Error("Port must be a numeric value");this.compile();let U=this,X={port:F,fetch:async(Z,$)=>{let L=new URL(Z.url);try{return await j(Z,$,L,this)}catch(V){return new Response("Internal Server Error",{status:500})}},onClose(){console.log("Server is shutting down...")}};if(G&&J)X.certFile=G,X.keyFile=J;let Y=Bun.serve(X);if(typeof z==="function")return z();if(G&&J)console.log(`HTTPS server is running on https://localhost:${F}`);else console.log(`HTTP server is running on http://localhost:${F}`);return Y}register(F,z){if(typeof F!=="string")throw new Error("path must be a string");if(typeof z!=="object")throw new Error("handler parameter should be a instance of router object",z);let G=Object.entries(z.trie.root.children);z.trie.root.subMiddlewares.forEach((J,U)=>{if(!this.middlewares.has(F+U))this.middlewares.set(F+U,[]);J?.forEach((X)=>{if(!this.middlewares.get(F+U)?.includes(X))this.middlewares.get(F+U)?.push(X)})});for(let[J,U]of G){let X=F+U?.path,Y=U.handler[0],Z=U.method[0];this.trie.insert(X,{handler:Y,method:Z})}z.trie=new Q}#z(F,z,G){if(typeof z!=="string")throw new Error("Path must be a string type");if(typeof F!=="string")throw new Error("method must be a string type");let J=G.slice(0,-1),U=G[G.length-1];if(!this.middlewares.has(z))this.middlewares.set(z,[]);J.forEach((X)=>{if(z==="/"){if(!this.globalMiddlewares.includes(X))this.globalMiddlewares.push(X)}else if(!this.middlewares.get(z)?.includes(X))this.middlewares.get(z)?.push(X)}),this.trie.insert(z,{handler:U,method:F})}use(F,z){if(typeof F==="function"){if(!this.globalMiddlewares.includes(F))this.globalMiddlewares.push(F);return}let G=F;if(!this.middlewares.has(G))this.middlewares.set(G,[]);if(z){if(!this.middlewares.get(G)?.includes(z))this.middlewares.get(G)?.push(z)}}get(F,...z){return this.#z("GET",F,z),this}post(F,...z){return this.#z("POST",F,z),this}put(F,...z){return this.#z("PUT",F,z),this}patch(F,...z){return this.#z("PATCH",F,z),this}delete(F,...z){return this.#z("DELETE",F,z),this}}class N extends K{constructor(){super()}#z(F,z,G){if(!this.trie.root.subMiddlewares.has(z))this.trie.root.subMiddlewares.set(z,[]);let J=G.slice(0,-1),U=this.trie.root.subMiddlewares.get(z);J.forEach((Y)=>{if(!U?.includes(Y))U?.push(Y)});let X=G[G.length-1];this.trie.insert(z,{handler:X,method:F})}get(F,...z){return this.#z("GET",F,z),this}post(F,...z){return this.#z("POST",F,z),this}put(F,...z){return this.#z("PUT",F,z),this}patch(F,...z){return this.#z("PATCH",F,z),this}delete(F,...z){return this.#z("DELETE",F,z),this}}var x=N;export{x as default};
package/dist/types.d.ts CHANGED
@@ -76,7 +76,7 @@ export interface DieselT {
76
76
  onSend: ((ctx?: ContextType, result?: Response | null | void, serer?: Server) => Promise<Response | void | null>) | null;
77
77
  };
78
78
  filters: string[];
79
- filterFunction: (ctx: ContextType) => void | Response | Promise<Response | void>;
79
+ filterFunction: (ctx: ContextType, serer?: Server) => void | Response | Promise<Response | void>;
80
80
  corsConfig: corsT | null;
81
81
  globalMiddlewares: Array<(ctx: ContextType, serer?: Server) => void | Promise<Response | null | void>>;
82
82
  middlewares: Map<string, Array<(ctx: ContextType, serer?: Server) => void | Promise<Response | null | void>>>;
package/example/bun.lockb CHANGED
Binary file
package/example/main.ts CHANGED
@@ -1,15 +1,32 @@
1
- import {Diesel, rateLimit} from "../src/main";
1
+ import { Server } from "bun";
2
+ import Diesel ,{rateLimit} from "../src/main";
3
+ import { ContextType, CookieOptions, middlewareFunc } from "../dist/types";
4
+ import jwt from 'jsonwebtoken'
2
5
 
3
6
  const app = new Diesel()
4
-
7
+ const secret = 'pradeep'
5
8
  // app.cors({
6
9
  // origin: ['http://localhost:5173','*'],
7
10
  // methods: 'GET,POST,PUT,DELETE',
8
11
  // allowedHeaders: 'Content-Type,Authorization'
9
12
  // })
10
13
 
11
- function h() {
12
- return new Response("hello world")
14
+ async function authJwt (ctx:ContextType, server?:Server): Promise<void | Response> {
15
+ const token = await ctx.getCookie("accessToken"); // Retrieve the JWT token from cookies
16
+ if (!token) {
17
+ return ctx.status(401).json({ message: "Authentication token missing" });
18
+ }
19
+ try {
20
+ // Verify the JWT token using a secret key
21
+ const user = jwt.verify(token, secret); // Replace with your JWT secret
22
+ // Set the user data in context
23
+ ctx.set("user", user);
24
+
25
+ // Proceed to the next middleware/route handler
26
+ return ctx.next();
27
+ } catch (error) {
28
+ return ctx.status(403).json({ message: "Invalid token" });
29
+ }
13
30
  }
14
31
 
15
32
  const limiter = rateLimit({
@@ -22,21 +39,19 @@ const limiter = rateLimit({
22
39
 
23
40
  app
24
41
  .filter()
25
- .routeMatcher('/api/user/register','/api/user/login','/test/:id','/')
42
+ .routeMatcher('/api/user/register','/api/user/login','/test/:id','/cookie')
26
43
  .permitAll()
27
- .require()
44
+ .require(authJwt)
45
+
46
+ // app.use(authJwt)
28
47
 
29
48
  // .require(you can pass jwt auth parser)
30
49
 
31
50
  app.get("/", async(xl) => {
32
51
  // const ip = xl.req
33
52
  // console.log(ip)
34
- return xl.json({
35
- message: 'Hello from Express!',
36
- author: 'Pradeep',
37
- app: 'Express App',
38
- features: ['Fast', 'Flexible', 'Lightweight']
39
- });
53
+ const user = xl.get('user')
54
+ return xl.json({user:user});
40
55
  });
41
56
 
42
57
  app.get("/test/:id", async (xl) => {
@@ -49,4 +64,28 @@ app.get("/test/:id", async (xl) => {
49
64
  return xl.status(200).text("kaise ho??")
50
65
  })
51
66
 
67
+ app.get("/cookie", async(xl) => {
68
+ const user = {
69
+ name: "pk",
70
+ age: 22,
71
+ };
72
+
73
+ const accessToken = jwt.sign(user, secret, { expiresIn: "1d" });
74
+ const refreshToken = jwt.sign(user, secret, { expiresIn: "10d" });
75
+ const options : CookieOptions= {
76
+ httpOnly: true, // Makes cookie accessible only by the web server (not JS)
77
+ secure: true, // Ensures the cookie is sent over HTTPS
78
+ maxAge: 24 * 60 * 60 * 1000, // 1 day in milliseconds
79
+ sameSite: "Strict", // Prevents CSRF (strict origin policy)
80
+ path: "/", // Cookie available for all routes
81
+ };
82
+ await xl.cookie("accessToken", accessToken, options)
83
+ await xl.cookie("refreshToken", refreshToken, options)
84
+ // xl.cookie("refreshToken", refreshToken, options);
85
+ await xl.getCookie()
86
+ return xl.json({msg:"setting cookies"})
87
+ });
88
+
89
+
90
+
52
91
  app.listen(3000)
@@ -0,0 +1,177 @@
1
+ {
2
+ "name": "test",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "test",
9
+ "version": "1.0.0",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "@types/jsonwebtoken": "^9.0.7",
13
+ "diesel-core": "^0.0.12",
14
+ "jsonwebtoken": "^9.0.2",
15
+ "jwt": "^0.2.0"
16
+ }
17
+ },
18
+ "node_modules/@types/jsonwebtoken": {
19
+ "version": "9.0.7",
20
+ "license": "MIT",
21
+ "dependencies": {
22
+ "@types/node": "*"
23
+ }
24
+ },
25
+ "node_modules/@types/node": {
26
+ "version": "22.7.7",
27
+ "license": "MIT",
28
+ "dependencies": {
29
+ "undici-types": "~6.19.2"
30
+ }
31
+ },
32
+ "node_modules/buffer-equal-constant-time": {
33
+ "version": "1.0.1",
34
+ "license": "BSD-3-Clause"
35
+ },
36
+ "node_modules/diesel-core": {
37
+ "version": "0.0.12",
38
+ "license": "ISC",
39
+ "peerDependencies": {
40
+ "typescript": "^5.0.0"
41
+ }
42
+ },
43
+ "node_modules/ecdsa-sig-formatter": {
44
+ "version": "1.0.11",
45
+ "license": "Apache-2.0",
46
+ "dependencies": {
47
+ "safe-buffer": "^5.0.1"
48
+ }
49
+ },
50
+ "node_modules/jsonwebtoken": {
51
+ "version": "9.0.2",
52
+ "license": "MIT",
53
+ "dependencies": {
54
+ "jws": "^3.2.2",
55
+ "lodash.includes": "^4.3.0",
56
+ "lodash.isboolean": "^3.0.3",
57
+ "lodash.isinteger": "^4.0.4",
58
+ "lodash.isnumber": "^3.0.3",
59
+ "lodash.isplainobject": "^4.0.6",
60
+ "lodash.isstring": "^4.0.1",
61
+ "lodash.once": "^4.0.0",
62
+ "ms": "^2.1.1",
63
+ "semver": "^7.5.4"
64
+ },
65
+ "engines": {
66
+ "node": ">=12",
67
+ "npm": ">=6"
68
+ }
69
+ },
70
+ "node_modules/jwa": {
71
+ "version": "1.4.1",
72
+ "license": "MIT",
73
+ "dependencies": {
74
+ "buffer-equal-constant-time": "1.0.1",
75
+ "ecdsa-sig-formatter": "1.0.11",
76
+ "safe-buffer": "^5.0.1"
77
+ }
78
+ },
79
+ "node_modules/jws": {
80
+ "version": "3.2.2",
81
+ "license": "MIT",
82
+ "dependencies": {
83
+ "jwa": "^1.4.1",
84
+ "safe-buffer": "^5.0.1"
85
+ }
86
+ },
87
+ "node_modules/jwt": {
88
+ "version": "0.2.0",
89
+ "dependencies": {
90
+ "node-base64": "0.0.1"
91
+ },
92
+ "engines": {
93
+ "node": "*"
94
+ }
95
+ },
96
+ "node_modules/lodash.includes": {
97
+ "version": "4.3.0",
98
+ "license": "MIT"
99
+ },
100
+ "node_modules/lodash.isboolean": {
101
+ "version": "3.0.3",
102
+ "license": "MIT"
103
+ },
104
+ "node_modules/lodash.isinteger": {
105
+ "version": "4.0.4",
106
+ "license": "MIT"
107
+ },
108
+ "node_modules/lodash.isnumber": {
109
+ "version": "3.0.3",
110
+ "license": "MIT"
111
+ },
112
+ "node_modules/lodash.isplainobject": {
113
+ "version": "4.0.6",
114
+ "license": "MIT"
115
+ },
116
+ "node_modules/lodash.isstring": {
117
+ "version": "4.0.1",
118
+ "license": "MIT"
119
+ },
120
+ "node_modules/lodash.once": {
121
+ "version": "4.1.1",
122
+ "license": "MIT"
123
+ },
124
+ "node_modules/ms": {
125
+ "version": "2.1.3",
126
+ "license": "MIT"
127
+ },
128
+ "node_modules/node-base64": {
129
+ "version": "0.0.1",
130
+ "hasInstallScript": true
131
+ },
132
+ "node_modules/safe-buffer": {
133
+ "version": "5.2.1",
134
+ "funding": [
135
+ {
136
+ "type": "github",
137
+ "url": "https://github.com/sponsors/feross"
138
+ },
139
+ {
140
+ "type": "patreon",
141
+ "url": "https://www.patreon.com/feross"
142
+ },
143
+ {
144
+ "type": "consulting",
145
+ "url": "https://feross.org/support"
146
+ }
147
+ ],
148
+ "license": "MIT"
149
+ },
150
+ "node_modules/semver": {
151
+ "version": "7.6.3",
152
+ "license": "ISC",
153
+ "bin": {
154
+ "semver": "bin/semver.js"
155
+ },
156
+ "engines": {
157
+ "node": ">=10"
158
+ }
159
+ },
160
+ "node_modules/typescript": {
161
+ "version": "5.6.3",
162
+ "license": "Apache-2.0",
163
+ "peer": true,
164
+ "bin": {
165
+ "tsc": "bin/tsc",
166
+ "tsserver": "bin/tsserver"
167
+ },
168
+ "engines": {
169
+ "node": ">=14.17"
170
+ }
171
+ },
172
+ "node_modules/undici-types": {
173
+ "version": "6.19.8",
174
+ "license": "MIT"
175
+ }
176
+ }
177
+ }
@@ -10,6 +10,9 @@
10
10
  "license": "ISC",
11
11
  "description": "",
12
12
  "dependencies": {
13
- "jsonwebtoken": "^9.0.2"
13
+ "@types/jsonwebtoken": "^9.0.7",
14
+ "diesel-core": "^0.0.13",
15
+ "jsonwebtoken": "^9.0.2",
16
+ "jwt": "^0.2.0"
14
17
  }
15
18
  }
package/example/route.js CHANGED
@@ -1,4 +1,4 @@
1
- import Router from "../src/router";
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 {Diesel} from "../src/main";
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diesel-core",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/main.d.ts",
6
6
  "scripts": {
@@ -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
- // const routeCache:RouteCache = {}
7
5
 
8
- export default async function handleRequest(req:Request, server:Server ,url:URL, diesel:DieselT): Promise<Response> {
6
+ const routeCache:RouteCache = {}
9
7
 
10
- const ctx:ContextType = createCtx(req, server,url);
8
+ export default async function handleRequest(req: Request, server: Server, url: URL, diesel: DieselT): Promise<Response> {
9
+
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 {
@@ -19,99 +20,94 @@ export default async function handleRequest(req:Request, server:Server ,url:URL,
19
20
  // }
20
21
 
21
22
  // Early return if route or method is not found
22
- if (!routeHandler || !routeHandler.handler) {
23
- return new Response(`Route not found for ${url.pathname}`, { status: 404 })
24
- }
25
-
26
- if (routeHandler.method !== req.method) {
27
- return new Response("Method not allowed", { status: 405 })
23
+ if (!routeHandler || routeHandler.method !== req.method) {
24
+ return new Response(routeHandler ? "Method not allowed" : `Route not found for ${url.pathname}`, {
25
+ status: routeHandler ? 405 : 404,
26
+ });
28
27
  }
29
28
 
30
29
  // If the route is dynamic, we only set routePattern if necessary
31
30
  if (routeHandler.isDynamic) req.routePattern = routeHandler.path;
32
31
 
32
+ // cors execution
33
33
  if (diesel.corsConfig) {
34
34
  const corsResult = await applyCors(req, ctx, diesel.corsConfig)
35
- if(corsResult) return corsResult;
35
+ if (corsResult) return corsResult;
36
36
  }
37
37
 
38
38
  // OnReq hook 1
39
- if (diesel.hasOnReqHook && diesel.hooks.onRequest) {
40
- diesel.hooks.onRequest(ctx,server)
41
- }
39
+ if (diesel.hasOnReqHook && diesel.hooks.onRequest) diesel.hooks.onRequest(ctx, server)
42
40
 
41
+ // filter applying
42
+ if (diesel.hasFilterEnabled) {
43
43
 
44
- if (diesel.filters.length > 0) {
45
44
  const path = req.routePattern ?? url.pathname
46
45
  const hasRoute = diesel.filters.includes(path)
47
-
48
46
  if (hasRoute === false) {
49
47
  if (diesel.filterFunction) {
50
- const filterResult = await diesel?.filterFunction(ctx)
51
- if(filterResult) return filterResult
52
- }
53
- else {
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 {
54
58
  return new Response(JSON.stringify({
55
- message:"Authentication required"
56
- }),{status:400})
59
+ message: "Authentication required"
60
+ }), { status: 400 })
57
61
  }
58
62
  }
59
63
  }
60
64
 
61
65
  // middleware execution
62
66
  if (diesel.hasMiddleware) {
63
- const middlewares = [
67
+ const middlewares = [
64
68
  ...diesel.globalMiddlewares,
65
69
  ...diesel.middlewares.get(url.pathname) || []
66
- ] as middlewareFunc[]
70
+ ] as middlewareFunc[]
67
71
 
68
72
  for (const middleware of middlewares) {
69
- const result = await middleware(ctx,server);
70
- if (result) return result;
73
+ const result = await middleware(ctx, server);
74
+ if (result) return result;
71
75
  }
72
76
 
73
77
  }
74
78
 
75
-
76
-
77
79
  // Run preHandler hooks 2
78
80
  if (diesel.hasPreHandlerHook && diesel.hooks.preHandler) {
79
- const Hookresult = await diesel.hooks.preHandler(ctx);
80
- if(Hookresult) return Hookresult;
81
- }
82
-
81
+ const Hookresult = await diesel.hooks.preHandler(ctx);
82
+ if (Hookresult) return Hookresult;
83
+ }
84
+
85
+ const preHandlerResult = diesel.hasPreHandlerHook ? await diesel.hooks.preHandler?.(ctx) : null;
86
+ if (preHandlerResult) return preHandlerResult;
83
87
 
84
88
  // Finally, execute the route handler and return its result
85
89
  try {
86
- const result = await routeHandler.handler(ctx) as Response | null | void ;
90
+ const result = await routeHandler.handler(ctx) as Response | null | void;
87
91
 
88
92
  // 3. run the postHandler hooks
89
93
  if (diesel.hasPostHandlerHook && diesel.hooks.postHandler) {
90
- await diesel.hooks.postHandler(ctx)
94
+ await diesel.hooks.postHandler(ctx)
91
95
  }
92
96
 
93
97
  // 4. Run onSend hooks before sending the response
94
98
  if (diesel.hasOnSendHook && diesel.hooks.onSend) {
95
- const hookResponse = await diesel.hooks.onSend(ctx,result);
96
- if(hookResponse) return hookResponse
99
+ const hookResponse = await diesel.hooks.onSend(ctx, result);
100
+ if (hookResponse) return hookResponse
97
101
  }
98
102
 
99
- return result ?? new Response("No response from handler", { status: 204 })
103
+ return result ?? new Response("No response from handler", { status: 204 })
100
104
  } catch (error) {
101
105
  return new Response("Internal Server Error", { status: 500 });
102
106
  }
103
107
  }
104
108
 
105
- // middleware execution
106
- async function executeMiddleware(middlewares: middlewareFunc[], ctx: ContextType, server: Server): Promise<Response | null | void> {
107
- for (const middleware of middlewares) {
108
- const result = await middleware(ctx,server);
109
- if (result) return result;
110
- }
111
- }
112
-
113
109
 
114
- async function applyCors(req:Request,ctx:ContextType,config:corsT={}) :Promise<Response | null> {
110
+ async function applyCors(req: Request, ctx: ContextType, config: corsT = {}): Promise<Response | null> {
115
111
  const origin = req.headers.get('origin') ?? '*'
116
112
  const allowedOrigins = config?.origin
117
113
  const allowedHeaders = config?.allowedHeaders ?? ["Content-Type", "Authorization"]
@@ -119,27 +115,27 @@ async function applyCors(req:Request,ctx:ContextType,config:corsT={}) :Promise<R
119
115
  const allowedCredentials = config?.credentials ?? false
120
116
  const exposedHeaders = config?.exposedHeaders ?? []
121
117
 
122
- ctx.setHeader('Access-Control-Allow-Methods',allowedMethods)
118
+ ctx.setHeader('Access-Control-Allow-Methods', allowedMethods)
123
119
  ctx.setHeader("Access-Control-Allow-Headers", allowedHeaders);
124
120
  ctx.setHeader("Access-Control-Allow-Credentials", allowedCredentials);
125
121
  if (exposedHeaders.length) {
126
122
  ctx.setHeader("Access-Control-Expose-Headers", exposedHeaders);
127
123
  }
128
124
 
129
- if (allowedOrigins === '*'){
125
+ if (allowedOrigins === '*') {
130
126
  ctx.setHeader("Access-Control-Allow-Origin", "*")
131
- } else if (Array.isArray(allowedOrigins)){
127
+ } else if (Array.isArray(allowedOrigins)) {
132
128
  if (origin && allowedOrigins.includes(origin)) {
133
- ctx.setHeader("Access-Control-Allow-Origin",origin)
134
- } else if(allowedOrigins.includes('*')){
135
- ctx.setHeader("Access-Control-Allow-Origin",'*')
129
+ ctx.setHeader("Access-Control-Allow-Origin", origin)
130
+ } else if (allowedOrigins.includes('*')) {
131
+ ctx.setHeader("Access-Control-Allow-Origin", '*')
136
132
  }
137
133
  else {
138
134
  return ctx.status(403).json({ message: "CORS not allowed" })
139
135
  }
140
- } else if (typeof allowedOrigins === 'string'){
141
- if(origin === allowedOrigins){
142
- ctx.setHeader("Access-Control-Allow-Origin",origin)
136
+ } else if (typeof allowedOrigins === 'string') {
137
+ if (origin === allowedOrigins) {
138
+ ctx.setHeader("Access-Control-Allow-Origin", origin)
143
139
  }
144
140
  else {
145
141
  return ctx.status(403).json({ message: "CORS not allowed" });
@@ -148,10 +144,10 @@ async function applyCors(req:Request,ctx:ContextType,config:corsT={}) :Promise<R
148
144
  return ctx.status(403).json({ message: "CORS not allowed" })
149
145
  }
150
146
 
151
- ctx.setHeader("Access-Control-Allow-Origin",origin)
147
+ ctx.setHeader("Access-Control-Allow-Origin", origin)
152
148
 
153
149
  if (req.method === 'OPTIONS') {
154
- ctx.setHeader('Access-Control-Max-Age','86400')
150
+ ctx.setHeader('Access-Control-Max-Age', '86400')
155
151
  return ctx.status(204).text('')
156
152
  }
157
153
 
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,
@@ -16,9 +17,8 @@ import {
16
17
  import { Server } from "bun";
17
18
 
18
19
 
20
+ export default class Diesel {
19
21
 
20
-
21
- class Diesel {
22
22
  routes : string[] | undefined
23
23
  globalMiddlewares: middlewareFunc[]
24
24
  middlewares: Map<string, middlewareFunc[]>;
@@ -32,11 +32,11 @@ class Diesel {
32
32
  corsConfig: corsT
33
33
  filters: string[]
34
34
  filterFunction : middlewareFunc | null
35
+ hasFilterEnabled: boolean
36
+ wss : WebSocket | null | undefined
35
37
 
36
38
  constructor() {
37
39
  this.routes = []
38
- this.filters = []
39
- this.filterFunction = null
40
40
  this.globalMiddlewares = [];
41
41
  this.middlewares = new Map();
42
42
  this.trie = new Trie();
@@ -54,10 +54,15 @@ class Diesel {
54
54
  onError: null,
55
55
  onClose: null
56
56
  }
57
+ this.filters = []
58
+ this.filterFunction = null
59
+ this.hasFilterEnabled = false
60
+ this.wss = null
57
61
  }
58
62
 
59
63
 
60
64
  filter() :FilterMethods {
65
+ this.hasFilterEnabled = true
61
66
 
62
67
  return {
63
68
  routeMatcher: (...routes:string[]) => {
@@ -69,17 +74,13 @@ class Diesel {
69
74
  for(const route of this?.routes!){
70
75
  this.filters.push(route)
71
76
  }
72
- // this.routes = []
73
77
  return this.filter()
74
78
  },
75
79
 
76
80
  require: (fnc?:middlewareFunc) => {
77
- if(!fnc || typeof fnc !== 'function' ){
78
- return new Response(JSON.stringify({
79
- message:"Authentication required"
80
- }),{status:400})
81
+ if (fnc) {
82
+ this.filterFunction = fnc
81
83
  }
82
- this.filterFunction = fnc
83
84
  }
84
85
  };
85
86
  }
@@ -140,13 +141,13 @@ class Diesel {
140
141
  }
141
142
 
142
143
  this.compile();
143
- const dieselInstance = this as Diesel
144
+
144
145
  const options: any = {
145
146
  port,
146
147
  fetch: async (req: Request, server: Server) => {
147
148
  const url = new URL(req.url);
148
149
  try {
149
- return await handleRequest(req, server, url, this);
150
+ return await handleRequest(req, server, url, this as DieselT);
150
151
  } catch (error) {
151
152
  return new Response("Internal Server Error", { status: 500 });
152
153
  }
@@ -162,7 +163,7 @@ class Diesel {
162
163
  }
163
164
  const server = Bun.serve(options);
164
165
 
165
- // Bun?.gc(false)
166
+ Bun?.gc(false)
166
167
 
167
168
  if (typeof callback === "function") {
168
169
  return callback();
@@ -188,7 +189,7 @@ class Diesel {
188
189
  throw new Error("handler parameter should be a instance of router object", handlerInstance)
189
190
  }
190
191
  const routeEntries: [string, RouteNodeType][] = Object.entries(handlerInstance.trie.root.children) as [string, RouteNodeType][];
191
-
192
+
192
193
  handlerInstance.trie.root.subMiddlewares.forEach((middleware: middlewareFunc[], path: string) => {
193
194
  if (!this.middlewares.has(pathPrefix + path)) {
194
195
  this.middlewares.set(pathPrefix + path, []);
@@ -210,7 +211,7 @@ class Diesel {
210
211
  handlerInstance.trie = new Trie();
211
212
  }
212
213
 
213
- #addRoute(
214
+ addRoute(
214
215
  method: HttpMethod,
215
216
  path: string,
216
217
  handlers: handlerFunction[]
@@ -254,7 +255,7 @@ class Diesel {
254
255
  }
255
256
  return
256
257
  }
257
- // now it means it is path midl
258
+
258
259
  const path: string = pathORHandler as string;
259
260
 
260
261
  if (!this.middlewares.has(path)) {
@@ -272,7 +273,7 @@ class Diesel {
272
273
  path: string,
273
274
  ...handlers: handlerFunction[]
274
275
  ) : this {
275
- this.#addRoute("GET", path, handlers);
276
+ this.addRoute("GET", path, handlers);
276
277
  return this
277
278
  }
278
279
 
@@ -280,12 +281,12 @@ class Diesel {
280
281
  path: string,
281
282
  ...handlers: handlerFunction[]
282
283
  ): this {
283
- this.#addRoute("POST", path, handlers);
284
+ this.addRoute("POST", path, handlers);
284
285
  return this
285
286
  }
286
287
 
287
288
  put(path: string, ...handlers: handlerFunction[]) : this{
288
- this.#addRoute("PUT", path, handlers);
289
+ this.addRoute("PUT", path, handlers);
289
290
  return this
290
291
  }
291
292
 
@@ -293,7 +294,7 @@ class Diesel {
293
294
  path: string,
294
295
  ...handlers: handlerFunction[]
295
296
  ) : this {
296
- this.#addRoute("PATCH", path, handlers);
297
+ this.addRoute("PATCH", path, handlers);
297
298
  return this
298
299
  }
299
300
 
@@ -301,14 +302,12 @@ class Diesel {
301
302
  path: any,
302
303
  ...handlers: handlerFunction[]
303
304
  ) : this {
304
- this.#addRoute("DELETE", path, handlers);
305
+ this.addRoute("DELETE", path, handlers);
305
306
  return this;
306
307
  }
307
308
  }
308
309
 
309
310
 
310
311
  export {
311
- Diesel,
312
312
  rateLimit,
313
- // filter
314
313
  }
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; // Store the actual pattern like ':id'
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,7 +86,8 @@ 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
- filterFunction: (ctx:ContextType) => void | Response | Promise<Response|void>
89
+ hasFilterEnabled:boolean
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>>
92
93
  middlewares: Map<string, Array<(ctx: ContextType, serer?: Server) => void | Promise<Response | null | void>>>
package/tsconfig.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES6", // Specify ECMAScript target version
4
- "module": "commonjs", // Specify module code generation
5
- "outDir": "./dist", // Redirect output structure to the 'dist' directory
4
+ "module": "ESNext", // Specify module code generation
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;