diesel-core 0.0.15 → 0.0.17
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 +3 -1
- package/README.md +20 -3
- package/build.js +23 -13
- package/dist/ctx.js +1 -1
- package/dist/handleRequest.js +1 -1
- package/dist/main.js +1 -1
- package/dist/trie.js +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/utils.js +1 -0
- package/example/bun.lockb +0 -0
- package/example/main.ts +52 -53
- package/example/package.json +3 -0
- package/package.json +1 -1
- package/src/ctx.ts +25 -17
- package/src/handleRequest.ts +14 -12
- package/src/main.ts +1 -0
- package/src/types.ts +12 -4
- package/tsconfig.json +1 -1
- package/dist/router.d.ts +0 -12
- package/dist/router.js +0 -1
package/CONTRIBUTING.md
CHANGED
package/README.md
CHANGED
|
@@ -169,11 +169,28 @@ app.addHooks('onSend',async (xl, result) => {
|
|
|
169
169
|
|
|
170
170
|
# Middleware example
|
|
171
171
|
|
|
172
|
+
**No Need to call NonSense *next()* in Middleware**
|
|
173
|
+
|
|
174
|
+
**just dont return , if evrything goes right**
|
|
175
|
+
|
|
172
176
|
```javascript
|
|
173
|
-
function
|
|
174
|
-
|
|
177
|
+
async function authJwt (ctx:ContextType, server?:Server): Promise<void | Response> {
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const token = ctx?.getCookie("accessToken");
|
|
181
|
+
if (!token) {
|
|
182
|
+
return ctx.status(401).json({ message: "Authentication token missing" });
|
|
183
|
+
}
|
|
184
|
+
// Verify the JWT token using a secret key
|
|
185
|
+
const user = jwt.verify(token, secret);
|
|
186
|
+
ctx.set('user',user);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
return ctx.status(403).json({ message: "Invalid token" });
|
|
189
|
+
}
|
|
175
190
|
}
|
|
176
|
-
|
|
191
|
+
|
|
192
|
+
// this is a global middleware
|
|
193
|
+
app.use(authJwt)
|
|
177
194
|
|
|
178
195
|
// path middleware example
|
|
179
196
|
app.use("/user",authJWT)
|
package/build.js
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
outdir: './dist',
|
|
11
|
-
minify: true, // Enable minification
|
|
12
|
-
})
|
|
1
|
+
import path from 'path';
|
|
2
|
+
const entryPoints = [
|
|
3
|
+
'./main/main.js',
|
|
4
|
+
'./main/ctx.js',
|
|
5
|
+
'./main/handleRequest.js',
|
|
6
|
+
'./main/trie.js',
|
|
7
|
+
'./main/router.js',
|
|
8
|
+
'./main/utils.js'
|
|
9
|
+
];
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
entryPoints.forEach(entry => {
|
|
12
|
+
console.log(`Building: ${entry}`);
|
|
13
|
+
try {
|
|
14
|
+
Bun.build({
|
|
15
|
+
entrypoints: [path.resolve(entry)],
|
|
16
|
+
outdir: './dist',
|
|
17
|
+
minify: true,
|
|
18
|
+
});
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error(`Failed to build ${entry}:`, error);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Bun.spawn(['rm','-rf','./main'])
|
package/dist/ctx.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
var w=function(I,J,G,F){function Y(R){return R instanceof G?R:new G(function(L){L(R)})}return new(G||(G=Promise))(function(R,L){function X(U){try{Z(F.next(U))}catch(W){L(W)}}function $(U){try{Z(F.throw(U))}catch(W){L(W)}}function Z(U){U.done?R(U.value):Y(U.value).then(X,$)}Z((F=F.apply(I,J||[])).next())})};function O(I,J,G){let F=new Headers,Y={},R=!1,L,X=null,$,Z,U=200,W={};return{req:I,server:J,url:G,next:()=>{},getUser(){return W},setUser(z){if(z)W=z},status(z){return U=z,this},getIP(){return this.server.requestIP(this.req)},body(){return w(this,void 0,void 0,function*(){if(!Z)Z=yield V(I);if(Z.error)return new Response(JSON.stringify({error:Z.error}),{status:400});return Z})},setHeader(z,E){return F.set(z,E),this},set(z,E){return Y[z]=E,this},get(z){return Y[z]||null},setAuth(z){return R=z,this},getAuth(){return R},text(z,E){return new Response(z,{status:E!==null&&E!==void 0?E:U,headers:F})},json(z,E){return new Response(JSON.stringify(z),{status:E!==null&&E!==void 0?E:U,headers:F})},html(z,E){return new Response(Bun.file(z),{status:E!==null&&E!==void 0?E:U,headers:F})},file(z,E){return new Response(Bun.file(z),{status:E!==null&&E!==void 0?E:U,headers:F})},redirect(z,E){return F.set("Location",z),new Response(null,{status:E!==null&&E!==void 0?E:302,headers:F})},getParams(z){if(!$)$=x(I===null||I===void 0?void 0:I.routePattern,G===null||G===void 0?void 0:G.pathname);return z?$[z]||{}:$},getQuery(z){try{if(!L)L=Object.fromEntries(G.searchParams);return z?L[z]||{}:L}catch(E){return{}}},cookie(z,E,M={}){let K=`${encodeURIComponent(z)}=${encodeURIComponent(E)}`;if(M.maxAge)K+=`; Max-Age=${M.maxAge}`;if(M.expires)K+=`; Expires=${M.expires.toUTCString()}`;if(M.path)K+=`; Path=${M.path}`;if(M.domain)K+=`; Domain=${M.domain}`;if(M.secure)K+="; Secure";if(M.httpOnly)K+="; HttpOnly";if(M.sameSite)K+=`; SameSite=${M.sameSite}`;return F===null||F===void 0||F.append("Set-Cookie",K),this},getCookie(z){var E;if(!X||Object.keys(X).length===0){let M=(E=I.headers)===null||E===void 0?void 0:E.get("cookie");if(M)X=H(M);else return null}if(!X)return null;return z?X[z]!==void 0?X[z]:null:X}}}function H(I){let J={};if(!I)return J;return I.split(";").forEach((F)=>{var Y;let[R,L]=(Y=F===null||F===void 0?void 0:F.trim())===null||Y===void 0?void 0:Y.split("=");if(R&&L)J[R.trim()]=L.split(" ")[0].trim()}),J}function x(I,J){let G={},F=I.split("/"),[Y]=J.split("?"),R=Y.split("/");if(F.length!==R.length)return null;return F.forEach((L,X)=>{if(L.startsWith(":")){let $=L.slice(1);G[$]=R[X]}}),G}function V(I){return w(this,void 0,void 0,function*(){let J=I.headers.get("Content-Type")||"";if(!J)return{};try{if(J.startsWith("application/json"))return yield I.json();if(J.startsWith("application/x-www-form-urlencoded")){let G=yield I.text();return Object.fromEntries(new URLSearchParams(G))}if(J.startsWith("multipart/form-data")){let G=yield I.formData();return A(G)}return{error:"Unknown request body type"}}catch(G){return{error:"Invalid request body format"}}})}function A(I){let J={};for(let[G,F]of I.entries())J[G]=F;return J}export{O as default};
|
package/dist/handleRequest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
var Q=function(L,G,E,z){function K(Y){return Y instanceof E?Y:new E(function(U){U(Y)})}return new(E||(E=Promise))(function(Y,U){function Z(I){try{$(z.next(I))}catch(W){U(W)}}function X(I){try{$(z.throw(I))}catch(W){U(W)}}function $(I){I.done?Y(I.value):K(I.value).then(Z,X)}$((z=z.apply(L,G||[])).next())})};function D(L,G,E){let z=new Headers,K={},Y=!1,U,Z=null,X,$,I=200,W={};return{req:L,server:G,url:E,next:()=>{},getUser(){return W},setUser(F){if(F)W=F},status(F){return I=F,this},getIP(){return this.server.requestIP(this.req)},body(){return Q(this,void 0,void 0,function*(){if(!$)$=yield A(L);if($.error)return new Response(JSON.stringify({error:$.error}),{status:400});return $})},setHeader(F,J){return z.set(F,J),this},set(F,J){return K[F]=J,this},get(F){return K[F]||null},setAuth(F){return Y=F,this},getAuth(){return Y},text(F,J){return new Response(F,{status:J!==null&&J!==void 0?J:I,headers:z})},json(F,J){return new Response(JSON.stringify(F),{status:J!==null&&J!==void 0?J:I,headers:z})},html(F,J){return new Response(Bun.file(F),{status:J!==null&&J!==void 0?J:I,headers:z})},file(F,J){return new Response(Bun.file(F),{status:J!==null&&J!==void 0?J:I,headers:z})},redirect(F,J){return z.set("Location",F),new Response(null,{status:J!==null&&J!==void 0?J:302,headers:z})},getParams(F){if(!X)X=B(L===null||L===void 0?void 0:L.routePattern,E===null||E===void 0?void 0:E.pathname);return F?X[F]||{}:X},getQuery(F){try{if(!U)U=Object.fromEntries(E.searchParams);return F?U[F]||{}:U}catch(J){return{}}},cookie(F,J,M={}){let V=`${encodeURIComponent(F)}=${encodeURIComponent(J)}`;if(M.maxAge)V+=`; Max-Age=${M.maxAge}`;if(M.expires)V+=`; Expires=${M.expires.toUTCString()}`;if(M.path)V+=`; Path=${M.path}`;if(M.domain)V+=`; Domain=${M.domain}`;if(M.secure)V+="; Secure";if(M.httpOnly)V+="; HttpOnly";if(M.sameSite)V+=`; SameSite=${M.sameSite}`;return z===null||z===void 0||z.append("Set-Cookie",V),this},getCookie(F){var J;if(!Z||Object.keys(Z).length===0){let M=(J=L.headers)===null||J===void 0?void 0:J.get("cookie");if(M)Z=T(M);else return null}if(!Z)return null;return F?Z[F]!==void 0?Z[F]:null:Z}}}function T(L){let G={};if(!L)return G;return L.split(";").forEach((z)=>{var K;let[Y,U]=(K=z===null||z===void 0?void 0:z.trim())===null||K===void 0?void 0:K.split("=");if(Y&&U)G[Y.trim()]=U.split(" ")[0].trim()}),G}function B(L,G){let E={},z=L.split("/"),[K]=G.split("?"),Y=K.split("/");if(z.length!==Y.length)return null;return z.forEach((U,Z)=>{if(U.startsWith(":")){let X=U.slice(1);E[X]=Y[Z]}}),E}function A(L){return Q(this,void 0,void 0,function*(){let G=L.headers.get("Content-Type")||"";if(!G)return{};try{if(G.startsWith("application/json"))return yield L.json();if(G.startsWith("application/x-www-form-urlencoded")){let E=yield L.text();return Object.fromEntries(new URLSearchParams(E))}if(G.startsWith("multipart/form-data")){let E=yield L.formData();return N(E)}return{error:"Unknown request body type"}}catch(E){return{error:"Invalid request body format"}}})}function N(L){let G={};for(let[E,z]of L.entries())G[E]=z;return G}var O=function(L,G,E,z){function K(Y){return Y instanceof E?Y:new E(function(U){U(Y)})}return new(E||(E=Promise))(function(Y,U){function Z(I){try{$(z.next(I))}catch(W){U(W)}}function X(I){try{$(z.throw(I))}catch(W){U(W)}}function $(I){I.done?Y(I.value):K(I.value).then(Z,X)}$((z=z.apply(L,G||[])).next())})};function R(L,G,E,z){return O(this,void 0,void 0,function*(){var K,Y,U;let Z=z.trie.search(E.pathname,L.method);if(!Z||Z.method!==L.method)return new Response(Z?"Method not allowed":`Route not found for ${E.pathname}`,{status:Z?405:404});if(Z.isDynamic)L.routePattern=Z.path;let X=D(L,G,E);if(z.corsConfig){let I=C(L,X,z.corsConfig);if(I)return I}if(z.hasOnReqHook&&z.hooks.onRequest)z.hooks.onRequest(X,G);if(z.hasFilterEnabled){let I=(K=L.routePattern)!==null&&K!==void 0?K:E.pathname;if(z.filters.includes(I)===!1)if(z.filterFunction)try{let F=yield z.filterFunction(X,G);if(F)return F}catch(F){return console.error("Error in filterFunction:",F),new Response(JSON.stringify({message:"Internal Server Error"}),{status:500})}else return new Response(JSON.stringify({message:"Authentication required"}),{status:400})}if(z.hasMiddleware){for(let W of z.globalMiddlewares){let F=yield W(X,G);if(F)return F}let I=z.middlewares.get(E.pathname)||[];for(let W of I){let F=yield W(X,G);if(F)return F}}if(z.hasPreHandlerHook&&z.hooks.preHandler){let I=yield z.hooks.preHandler(X);if(I)return I}let $=z.hasPreHandlerHook?yield(U=(Y=z.hooks).preHandler)===null||U===void 0?void 0:U.call(Y,X):null;if($)return $;try{let I=yield Z.handler(X);if(z.hasPostHandlerHook&&z.hooks.postHandler)yield z.hooks.postHandler(X);if(z.hasOnSendHook&&z.hooks.onSend){let W=yield z.hooks.onSend(X,I);if(W)return W}return I!==null&&I!==void 0?I:new Response("No response from handler",{status:204})}catch(I){return new Response("Internal Server Error",{status:500})}})}function C(L,G,E={}){var z,K,Y,U,Z;let X=(z=L.headers.get("origin"))!==null&&z!==void 0?z:"*",$=E===null||E===void 0?void 0:E.origin,I=(K=E===null||E===void 0?void 0:E.allowedHeaders)!==null&&K!==void 0?K:["Content-Type","Authorization"],W=(Y=E===null||E===void 0?void 0:E.methods)!==null&&Y!==void 0?Y:["GET","POST","PUT","DELETE","OPTIONS"],F=(U=E===null||E===void 0?void 0:E.credentials)!==null&&U!==void 0?U:!1,J=(Z=E===null||E===void 0?void 0:E.exposedHeaders)!==null&&Z!==void 0?Z:[];if(G.setHeader("Access-Control-Allow-Methods",W),G.setHeader("Access-Control-Allow-Headers",I),G.setHeader("Access-Control-Allow-Credentials",F),J.length)G.setHeader("Access-Control-Expose-Headers",J);if($==="*")G.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray($))if(X&&$.includes(X))G.setHeader("Access-Control-Allow-Origin",X);else if($.includes("*"))G.setHeader("Access-Control-Allow-Origin","*");else return G.status(403).json({message:"CORS not allowed"});else if(typeof $==="string")if(X===$)G.setHeader("Access-Control-Allow-Origin",X);else return G.status(403).json({message:"CORS not allowed"});else return G.status(403).json({message:"CORS not allowed"});if(G.setHeader("Access-Control-Allow-Origin",X),L.method==="OPTIONS")return G.setHeader("Access-Control-Max-Age","86400"),G.status(204).text("");return null}export{R as default};
|
package/dist/main.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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};
|
|
1
|
+
class A{constructor(){this.children={},this.isEndOfWord=!1,this.handler=[],this.isDynamic=!1,this.pattern="",this.path="",this.method=[],this.subMiddlewares=new Map}}class K{constructor(){this.root=new A}insert(G,J){let z=this.root,U=G.split("/").filter(Boolean);if(G==="/"){z.isEndOfWord=!0,z.handler.push(J.handler),z.path=G,z.method.push(J.method);return}for(let Y of U){let Z=!1,X=Y;if(Y.startsWith(":"))Z=!0,X=":";if(!z.children[X])z.children[X]=new A;z=z.children[X],z.isDynamic=Z,z.pattern=Y,z.method.push(J.method),z.handler.push(J.handler),z.path=G}z.isEndOfWord=!0,z.method.push(J.method),z.handler.push(J.handler),z.path=G}search(G,J){let z=this.root,U=G.split("/").filter(Boolean);for(let Z of U){let X=Z;if(!z.children[X])if(z.children[":"])z=z.children[":"];else return null;else z=z.children[X]}let Y=z.method.indexOf(J);if(Y!==-1)return{path:z.path,handler:z.handler[Y],isDynamic:z.isDynamic,pattern:z.pattern,method:z.method[Y]};return{path:z.path,handler:z.handler,isDynamic:z.isDynamic,pattern:z.pattern,method:z.method[Y]}}}var N=function(G,J,z,U){function Y(Z){return Z instanceof z?Z:new z(function(X){X(Z)})}return new(z||(z=Promise))(function(Z,X){function F($){try{V(U.next($))}catch(Q){X(Q)}}function L($){try{V(U.throw($))}catch(Q){X(Q)}}function V($){$.done?Z($.value):Y($.value).then(F,L)}V((U=U.apply(G,J||[])).next())})};function M(G,J,z){let U=new Headers,Y={},Z=!1,X,F=null,L,V,$=200,Q={};return{req:G,server:J,url:z,next:()=>{},getUser(){return Q},setUser(E){if(E)Q=E},status(E){return $=E,this},getIP(){return this.server.requestIP(this.req)},body(){return N(this,void 0,void 0,function*(){if(!V)V=yield O(G);if(V.error)return new Response(JSON.stringify({error:V.error}),{status:400});return V})},setHeader(E,W){return U.set(E,W),this},set(E,W){return Y[E]=W,this},get(E){return Y[E]||null},setAuth(E){return Z=E,this},getAuth(){return Z},text(E,W){return new Response(E,{status:W!==null&&W!==void 0?W:$,headers:U})},json(E,W){return new Response(JSON.stringify(E),{status:W!==null&&W!==void 0?W:$,headers:U})},html(E,W){return new Response(Bun.file(E),{status:W!==null&&W!==void 0?W:$,headers:U})},file(E,W){return new Response(Bun.file(E),{status:W!==null&&W!==void 0?W:$,headers:U})},redirect(E,W){return U.set("Location",E),new Response(null,{status:W!==null&&W!==void 0?W:302,headers:U})},getParams(E){if(!L)L=I(G===null||G===void 0?void 0:G.routePattern,z===null||z===void 0?void 0:z.pathname);return E?L[E]||{}:L},getQuery(E){try{if(!X)X=Object.fromEntries(z.searchParams);return E?X[E]||{}:X}catch(W){return{}}},cookie(E,W,B={}){let D=`${encodeURIComponent(E)}=${encodeURIComponent(W)}`;if(B.maxAge)D+=`; Max-Age=${B.maxAge}`;if(B.expires)D+=`; Expires=${B.expires.toUTCString()}`;if(B.path)D+=`; Path=${B.path}`;if(B.domain)D+=`; Domain=${B.domain}`;if(B.secure)D+="; Secure";if(B.httpOnly)D+="; HttpOnly";if(B.sameSite)D+=`; SameSite=${B.sameSite}`;return U===null||U===void 0||U.append("Set-Cookie",D),this},getCookie(E){var W;if(!F||Object.keys(F).length===0){let B=(W=G.headers)===null||W===void 0?void 0:W.get("cookie");if(B)F=j(B);else return null}if(!F)return null;return E?F[E]!==void 0?F[E]:null:F}}}function j(G){let J={};if(!G)return J;return G.split(";").forEach((U)=>{var Y;let[Z,X]=(Y=U===null||U===void 0?void 0:U.trim())===null||Y===void 0?void 0:Y.split("=");if(Z&&X)J[Z.trim()]=X.split(" ")[0].trim()}),J}function I(G,J){let z={},U=G.split("/"),[Y]=J.split("?"),Z=Y.split("/");if(U.length!==Z.length)return null;return U.forEach((X,F)=>{if(X.startsWith(":")){let L=X.slice(1);z[L]=Z[F]}}),z}function O(G){return N(this,void 0,void 0,function*(){let J=G.headers.get("Content-Type")||"";if(!J)return{};try{if(J.startsWith("application/json"))return yield G.json();if(J.startsWith("application/x-www-form-urlencoded")){let z=yield G.text();return Object.fromEntries(new URLSearchParams(z))}if(J.startsWith("multipart/form-data")){let z=yield G.formData();return S(z)}return{error:"Unknown request body type"}}catch(z){return{error:"Invalid request body format"}}})}function S(G){let J={};for(let[z,U]of G.entries())J[z]=U;return J}var b=function(G,J,z,U){function Y(Z){return Z instanceof z?Z:new z(function(X){X(Z)})}return new(z||(z=Promise))(function(Z,X){function F($){try{V(U.next($))}catch(Q){X(Q)}}function L($){try{V(U.throw($))}catch(Q){X(Q)}}function V($){$.done?Z($.value):Y($.value).then(F,L)}V((U=U.apply(G,J||[])).next())})};function T(G,J,z,U){return b(this,void 0,void 0,function*(){var Y,Z,X;let F=U.trie.search(z.pathname,G.method);if(!F||F.method!==G.method)return new Response(F?"Method not allowed":`Route not found for ${z.pathname}`,{status:F?405:404});if(F.isDynamic)G.routePattern=F.path;let L=M(G,J,z);if(U.corsConfig){let $=w(G,L,U.corsConfig);if($)return $}if(U.hasOnReqHook&&U.hooks.onRequest)U.hooks.onRequest(L,J);if(U.hasFilterEnabled){let $=(Y=G.routePattern)!==null&&Y!==void 0?Y:z.pathname;if(U.filters.includes($)===!1)if(U.filterFunction)try{let E=yield U.filterFunction(L,J);if(E)return E}catch(E){return console.error("Error in filterFunction:",E),new Response(JSON.stringify({message:"Internal Server Error"}),{status:500})}else return new Response(JSON.stringify({message:"Authentication required"}),{status:400})}if(U.hasMiddleware){for(let Q of U.globalMiddlewares){let E=yield Q(L,J);if(E)return E}let $=U.middlewares.get(z.pathname)||[];for(let Q of $){let E=yield Q(L,J);if(E)return E}}if(U.hasPreHandlerHook&&U.hooks.preHandler){let $=yield U.hooks.preHandler(L);if($)return $}let V=U.hasPreHandlerHook?yield(X=(Z=U.hooks).preHandler)===null||X===void 0?void 0:X.call(Z,L):null;if(V)return V;try{let $=yield F.handler(L);if(U.hasPostHandlerHook&&U.hooks.postHandler)yield U.hooks.postHandler(L);if(U.hasOnSendHook&&U.hooks.onSend){let Q=yield U.hooks.onSend(L,$);if(Q)return Q}return $!==null&&$!==void 0?$:new Response("No response from handler",{status:204})}catch($){return new Response("Internal Server Error",{status:500})}})}function w(G,J,z={}){var U,Y,Z,X,F;let L=(U=G.headers.get("origin"))!==null&&U!==void 0?U:"*",V=z===null||z===void 0?void 0:z.origin,$=(Y=z===null||z===void 0?void 0:z.allowedHeaders)!==null&&Y!==void 0?Y:["Content-Type","Authorization"],Q=(Z=z===null||z===void 0?void 0:z.methods)!==null&&Z!==void 0?Z:["GET","POST","PUT","DELETE","OPTIONS"],E=(X=z===null||z===void 0?void 0:z.credentials)!==null&&X!==void 0?X:!1,W=(F=z===null||z===void 0?void 0:z.exposedHeaders)!==null&&F!==void 0?F:[];if(J.setHeader("Access-Control-Allow-Methods",Q),J.setHeader("Access-Control-Allow-Headers",$),J.setHeader("Access-Control-Allow-Credentials",E),W.length)J.setHeader("Access-Control-Expose-Headers",W);if(V==="*")J.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(V))if(L&&V.includes(L))J.setHeader("Access-Control-Allow-Origin",L);else if(V.includes("*"))J.setHeader("Access-Control-Allow-Origin","*");else return J.status(403).json({message:"CORS not allowed"});else if(typeof V==="string")if(L===V)J.setHeader("Access-Control-Allow-Origin",L);else return J.status(403).json({message:"CORS not allowed"});else return J.status(403).json({message:"CORS not allowed"});if(J.setHeader("Access-Control-Allow-Origin",L),G.method==="OPTIONS")return J.setHeader("Access-Control-Max-Age","86400"),J.status(204).text("");return null}function C(G){let{time:J=60000,max:z=100,message:U="Rate limit exceeded. Please try again later."}=G,Y=new Map;return(Z)=>{let X=new Date,F=Z.getIP().address;if(!Y.has(F))Y.set(F,{count:0,startTime:X});let L=Y.get(F);if(L)if(X-L.startTime>J)L.count=1,L.startTime=X;else L.count++;if(L&&L.count>z)return Z.status(429).json({error:U});Z.next()}}var H=function(G,J,z,U){function Y(Z){return Z instanceof z?Z:new z(function(X){X(Z)})}return new(z||(z=Promise))(function(Z,X){function F($){try{V(U.next($))}catch(Q){X(Q)}}function L($){try{V(U.throw($))}catch(Q){X(Q)}}function V($){$.done?Z($.value):Y($.value).then(F,L)}V((U=U.apply(G,J||[])).next())})};class R{constructor(){this.routes=[],this.globalMiddlewares=[],this.middlewares=new Map,this.trie=new K,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},this.filters=[],this.filterFunction=null,this.hasFilterEnabled=!1,this.wss=null}filter(){return this.hasFilterEnabled=!0,{routeMatcher:(...G)=>{return this.routes=G.sort(),this.filter()},permitAll:()=>{for(let G of this===null||this===void 0?void 0:this.routes)this.filters.push(G);return this.filter()},require:(G)=>{if(G)this.filterFunction=G}}}cors(G){this.corsConfig=G}addHooks(G,J){if(typeof G!=="string")throw new Error("hookName must be a string");if(typeof J!=="function")throw new Error("callback must be a instance of function");if(this.hooks.hasOwnProperty(G))this.hooks[G]=J;else throw new Error(`Unknown hook type: ${G}`)}compile(){if(this.globalMiddlewares.length>0)this.hasMiddleware=!0;for(let[G,J]of this.middlewares.entries())if(J.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(G,J,{sslCert:z=null,sslKey:U=null}={}){if(typeof Bun==="undefined")throw new Error(".listen() is designed to run on Bun only...");if(typeof G!=="number")throw new Error("Port must be a numeric value");this.compile();let Y={port:G,fetch:(X,F)=>H(this,void 0,void 0,function*(){let L=new URL(X.url);try{return yield T(X,F,L,this)}catch(V){return new Response("Internal Server Error",{status:500})}}),onClose(){console.log("Server is shutting down...")}};if(z&&U)Y.certFile=z,Y.keyFile=U;let Z=Bun.serve(Y);if(Bun===null||Bun===void 0||Bun.gc(!1),typeof J==="function")return J();if(z&&U)console.log(`HTTPS server is running on https://localhost:${G}`);else console.log(`HTTP server is running on http://localhost:${G}`);return Z}register(G,J){if(typeof G!=="string")throw new Error("path must be a string");if(typeof J!=="object")throw new Error("handler parameter should be a instance of router object",J);let z=Object.entries(J.trie.root.children);J.trie.root.subMiddlewares.forEach((U,Y)=>{if(!this.middlewares.has(G+Y))this.middlewares.set(G+Y,[]);U===null||U===void 0||U.forEach((Z)=>{var X,F;if(!((X=this.middlewares.get(G+Y))===null||X===void 0?void 0:X.includes(Z)))(F=this.middlewares.get(G+Y))===null||F===void 0||F.push(Z)})});for(let[U,Y]of z){let Z=G+(Y===null||Y===void 0?void 0:Y.path),X=Y.handler[0],F=Y.method[0];this.trie.insert(Z,{handler:X,method:F})}J.trie=new K}addRoute(G,J,z){if(typeof J!=="string")throw new Error("Path must be a string type");if(typeof G!=="string")throw new Error("method must be a string type");let U=z.slice(0,-1),Y=z[z.length-1];if(!this.middlewares.has(J))this.middlewares.set(J,[]);U.forEach((Z)=>{var X,F;if(J==="/"){if(!this.globalMiddlewares.includes(Z))this.globalMiddlewares.push(Z)}else if(!((X=this.middlewares.get(J))===null||X===void 0?void 0:X.includes(Z)))(F=this.middlewares.get(J))===null||F===void 0||F.push(Z)}),this.trie.insert(J,{handler:Y,method:G})}use(G,J){var z,U;if(typeof G==="function"){if(!this.globalMiddlewares.includes(G))this.globalMiddlewares.push(G);return}let Y=G;if(!this.middlewares.has(Y))this.middlewares.set(Y,[]);if(J){if(!((z=this.middlewares.get(Y))===null||z===void 0?void 0:z.includes(J)))(U=this.middlewares.get(Y))===null||U===void 0||U.push(J)}}get(G,...J){return this.addRoute("GET",G,J),this}post(G,...J){return this.addRoute("POST",G,J),this}put(G,...J){return this.addRoute("PUT",G,J),this}patch(G,...J){return this.addRoute("PATCH",G,J),this}delete(G,...J){return this.addRoute("DELETE",G,J),this}}export{C as rateLimit,R as default};
|
package/dist/trie.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class C{
|
|
1
|
+
class C{constructor(){this.children={},this.isEndOfWord=!1,this.handler=[],this.isDynamic=!1,this.pattern="",this.path="",this.method=[],this.subMiddlewares=new Map}}class E{constructor(){this.root=new C}insert(w,q){let j=this.root,B=w.split("/").filter(Boolean);if(w==="/"){j.isEndOfWord=!0,j.handler.push(q.handler),j.path=w,j.method.push(q.method);return}for(let v of B){let A=!1,z=v;if(v.startsWith(":"))A=!0,z=":";if(!j.children[z])j.children[z]=new C;j=j.children[z],j.isDynamic=A,j.pattern=v,j.method.push(q.method),j.handler.push(q.handler),j.path=w}j.isEndOfWord=!0,j.method.push(q.method),j.handler.push(q.handler),j.path=w}search(w,q){let j=this.root,B=w.split("/").filter(Boolean);for(let A of B){let z=A;if(!j.children[z])if(j.children[":"])j=j.children[":"];else return null;else j=j.children[z]}let v=j.method.indexOf(q);if(v!==-1)return{path:j.path,handler:j.handler[v],isDynamic:j.isDynamic,pattern:j.pattern,method:j.method[v]};return{path:j.path,handler:j.handler,isDynamic:j.isDynamic,pattern:j.pattern,method:j.method[v]}}}export{E as default};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Server } from "bun";
|
|
2
2
|
export type listenCalllBackType = () => void;
|
|
3
3
|
export type handlerFunction = (ctx: ContextType, server?: Server) => Response | Promise<Response | null | void>;
|
|
4
|
-
export type middlewareFunc = (ctx: ContextType, server?: Server | undefined) => void | Response | Promise<Response>;
|
|
4
|
+
export type middlewareFunc = (ctx: ContextType, server?: Server | undefined) => null | void | Response | Promise<Response | void | null>;
|
|
5
5
|
export type HookFunction = (ctx: ContextType, result?: Response | null | void, server?: Server) => Response | Promise<Response | null | void>;
|
|
6
6
|
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
|
|
7
7
|
export declare enum HookType {
|
|
@@ -42,8 +42,8 @@ export interface ContextType {
|
|
|
42
42
|
redirect: (path: string, status?: number) => Response;
|
|
43
43
|
getParams: (props?: any) => any;
|
|
44
44
|
getQuery: (props?: any) => any;
|
|
45
|
-
cookie: (name: string, value: string, options?: CookieOptions) =>
|
|
46
|
-
getCookie: (cookieName?: string) =>
|
|
45
|
+
cookie: (name: string, value: string, options?: CookieOptions) => this;
|
|
46
|
+
getCookie: (cookieName?: string) => any;
|
|
47
47
|
}
|
|
48
48
|
export interface CookieOptions {
|
|
49
49
|
maxAge?: number;
|
|
@@ -79,7 +79,7 @@ export interface DieselT {
|
|
|
79
79
|
};
|
|
80
80
|
filters: string[];
|
|
81
81
|
hasFilterEnabled: boolean;
|
|
82
|
-
filterFunction: (ctx: ContextType, serer?: Server) => void | Response | Promise<Response | void>;
|
|
82
|
+
filterFunction: (ctx: ContextType, serer?: Server) => void | Response | Promise<Response | void | null>;
|
|
83
83
|
corsConfig: corsT | null;
|
|
84
84
|
globalMiddlewares: Array<(ctx: ContextType, serer?: Server) => void | Promise<Response | null | void>>;
|
|
85
85
|
middlewares: Map<string, Array<(ctx: ContextType, serer?: Server) => void | Promise<Response | null | void>>>;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function H(v){let{time:z=60000,max:A=100,message:C="Rate limit exceeded. Please try again later."}=v,j=new Map;return(D)=>{let E=new Date,F=D.getIP().address;if(!j.has(F))j.set(F,{count:0,startTime:E});let l=j.get(F);if(l)if(E-l.startTime>z)l.count=1,l.startTime=E;else l.count++;if(l&&l.count>A)return D.status(429).json({error:C});D.next()}}var G=(v,z,A,C)=>{if(A>C)return!1;let j=A+(C-A)/2;if(v[j]==z)return!0;if(v[j]>z)return G(v,z,A,j-1);return G(v,z,j+1,C)};export{H as default,G as binaryS};
|
package/example/bun.lockb
CHANGED
|
Binary file
|
package/example/main.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Server } from "bun";
|
|
2
|
-
import Diesel
|
|
3
|
-
import { ContextType, CookieOptions, middlewareFunc } from "../dist/types";
|
|
2
|
+
import Diesel, { rateLimit } from "../dist/main";
|
|
4
3
|
import jwt from 'jsonwebtoken'
|
|
4
|
+
import { ContextType, CookieOptions, middlewareFunc } from "../dist/types";
|
|
5
5
|
|
|
6
6
|
const app = new Diesel()
|
|
7
7
|
const secret = 'pradeep'
|
|
@@ -11,19 +11,18 @@ const secret = 'pradeep'
|
|
|
11
11
|
// allowedHeaders: 'Content-Type,Authorization'
|
|
12
12
|
// })
|
|
13
13
|
|
|
14
|
-
async function authJwt
|
|
15
|
-
|
|
16
|
-
if (!token) {
|
|
17
|
-
return ctx.status(401).json({ message: "Authentication token missing" });
|
|
18
|
-
}
|
|
14
|
+
async function authJwt(ctx: ContextType, server?: Server): Promise<void | null | Response> {
|
|
15
|
+
|
|
19
16
|
try {
|
|
17
|
+
const token = ctx?.getCookie("accessToken");
|
|
18
|
+
|
|
19
|
+
if (!token) {
|
|
20
|
+
return ctx.status(401).json({ message: "Authentication token missing" });
|
|
21
|
+
}
|
|
20
22
|
// Verify the JWT token using a secret key
|
|
21
23
|
const user = jwt.verify(token, secret); // Replace with your JWT secret
|
|
22
24
|
// Set the user data in context
|
|
23
|
-
ctx.setUser(user)
|
|
24
|
-
|
|
25
|
-
// Proceed to the next middleware/route handler
|
|
26
|
-
return ctx.next();
|
|
25
|
+
ctx.setUser(user)
|
|
27
26
|
} catch (error) {
|
|
28
27
|
return ctx.status(403).json({ message: "Invalid token" });
|
|
29
28
|
}
|
|
@@ -34,58 +33,58 @@ const limiter = rateLimit({
|
|
|
34
33
|
max: 10, // Maximum number of requests allowed in the time window
|
|
35
34
|
message: "Rate limit exceeded. Please try again later." // Custom error message
|
|
36
35
|
});
|
|
37
|
-
|
|
36
|
+
|
|
38
37
|
// app.use(limiter)
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
app
|
|
40
|
+
.filter()
|
|
41
|
+
.routeMatcher('/api/user/register', '/api/user/login', '/test/:id', '/cookie')
|
|
42
|
+
.permitAll()
|
|
43
|
+
.require(authJwt as middlewareFunc)
|
|
45
44
|
|
|
46
|
-
// app.use(authJwt)
|
|
45
|
+
// app.use(authJwt as middlewareFunc)
|
|
47
46
|
|
|
48
47
|
// .require(you can pass jwt auth parser)
|
|
49
48
|
|
|
50
|
-
app.get("/", async(xl) => {
|
|
49
|
+
app.get("/", async (xl) => {
|
|
51
50
|
// // const ip = xl.req
|
|
52
|
-
// // console.log(ip)
|
|
53
|
-
// const user = xl.
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
// // // console.log(ip)
|
|
52
|
+
// const user = xl.get('user')
|
|
53
|
+
const q = xl.getUser()
|
|
54
|
+
|
|
55
|
+
return xl.status(200).json({ msg: "hello world", q })
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
app.get("/test/:id", async (xl) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
});
|
|
59
|
+
const q = xl.getQuery();
|
|
60
|
+
const params = xl.getParams('id');
|
|
61
|
+
return new Response(JSON.stringify({ msg: "hello world", q, params }));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
app.get("/ok", (xl) => {
|
|
65
|
+
return xl.status(200).text("kaise ho??")
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
app.get("/cookie", async (xl) => {
|
|
69
|
+
const user = {
|
|
70
|
+
name: "pk",
|
|
71
|
+
age: 22,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const accessToken = jwt.sign(user, secret, { expiresIn: "1d" });
|
|
75
|
+
const refreshToken = jwt.sign(user, secret, { expiresIn: "10d" });
|
|
76
|
+
const options: CookieOptions = {
|
|
77
|
+
httpOnly: true, // Makes cookie accessible only by the web server (not JS)
|
|
78
|
+
secure: true, // Ensures the cookie is sent over HTTPS
|
|
79
|
+
maxAge: 24 * 60 * 60 * 1000, // 1 day in milliseconds
|
|
80
|
+
sameSite: "Strict", // Prevents CSRF (strict origin policy)
|
|
81
|
+
path: "/", // Cookie available for all routes
|
|
82
|
+
};
|
|
83
|
+
return xl
|
|
84
|
+
.cookie("accessToken", accessToken, options)
|
|
85
|
+
.cookie("refreshToken", refreshToken, options)
|
|
86
|
+
.json({ msg: "setting cookies" })
|
|
87
|
+
});
|
|
89
88
|
|
|
90
89
|
|
|
91
90
|
|
package/example/package.json
CHANGED
package/package.json
CHANGED
package/src/ctx.ts
CHANGED
|
@@ -5,9 +5,9 @@ export default function createCtx(req: Request, server:Server ,url: URL): Contex
|
|
|
5
5
|
let headers: Headers = new Headers()
|
|
6
6
|
let settedValue: Record<string, string> = {};
|
|
7
7
|
let isAuthenticated: boolean = false;
|
|
8
|
-
let parsedQuery: any
|
|
9
|
-
let parsedCookie: any =
|
|
10
|
-
let parsedParams: any
|
|
8
|
+
let parsedQuery: any
|
|
9
|
+
let parsedCookie: any = null
|
|
10
|
+
let parsedParams: any
|
|
11
11
|
let parsedBody: ParseBodyResult | null;
|
|
12
12
|
let responseStatus: number = 200;
|
|
13
13
|
let user : any = {}
|
|
@@ -111,22 +111,26 @@ export default function createCtx(req: Request, server:Server ,url: URL): Contex
|
|
|
111
111
|
},
|
|
112
112
|
|
|
113
113
|
getParams(props: string)
|
|
114
|
-
: string | Record<string, string> |
|
|
114
|
+
: string | Record<string, string> | {} {
|
|
115
115
|
if (!parsedParams) {
|
|
116
116
|
parsedParams = extractDynamicParams(req?.routePattern, url?.pathname);
|
|
117
117
|
}
|
|
118
|
-
return props ? parsedParams[props] ||
|
|
118
|
+
return props ? parsedParams[props] || {} : parsedParams;
|
|
119
119
|
},
|
|
120
120
|
|
|
121
121
|
getQuery(props?: any)
|
|
122
|
-
: string | Record<string, string> |
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
: string | Record<string, string> | {} {
|
|
123
|
+
try {
|
|
124
|
+
if (!parsedQuery) {
|
|
125
|
+
parsedQuery = Object.fromEntries(url.searchParams);
|
|
126
|
+
}
|
|
127
|
+
return props ? parsedQuery[props] || {} : parsedQuery;
|
|
128
|
+
} catch (error) {
|
|
129
|
+
return {}
|
|
125
130
|
}
|
|
126
|
-
return props ? parsedQuery[props] || null : parsedQuery;
|
|
127
131
|
},
|
|
128
132
|
|
|
129
|
-
|
|
133
|
+
cookie(name: string, value: string, options: CookieOptions = {}) {
|
|
130
134
|
let cookieString = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
131
135
|
|
|
132
136
|
// Add options to cookie string (e.g., expiration, path, HttpOnly, etc.)
|
|
@@ -143,22 +147,26 @@ export default function createCtx(req: Request, server:Server ,url: URL): Contex
|
|
|
143
147
|
return this;
|
|
144
148
|
},
|
|
145
149
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (!parsedCookie) {
|
|
150
|
+
getCookie(cookieName?: string){
|
|
151
|
+
if (!parsedCookie || Object.keys(parsedCookie).length === 0) {
|
|
149
152
|
const cookieHeader = req.headers?.get("cookie")
|
|
150
153
|
if (cookieHeader) {
|
|
151
|
-
parsedCookie =
|
|
154
|
+
parsedCookie = parseCookie(cookieHeader);
|
|
155
|
+
} else {
|
|
156
|
+
return null
|
|
152
157
|
}
|
|
153
158
|
}
|
|
154
|
-
|
|
159
|
+
if (!parsedCookie) {
|
|
160
|
+
return null
|
|
161
|
+
}
|
|
162
|
+
return cookieName ? (parsedCookie[cookieName] !== undefined ? parsedCookie[cookieName] : null) : parsedCookie;
|
|
155
163
|
},
|
|
156
164
|
};
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
|
|
160
|
-
|
|
161
|
-
:
|
|
168
|
+
function parseCookie(header: string | undefined)
|
|
169
|
+
: Record<string, string> {
|
|
162
170
|
const cookies: Record<string, string> = {};
|
|
163
171
|
if (!header) return cookies;
|
|
164
172
|
|
package/src/handleRequest.ts
CHANGED
|
@@ -4,11 +4,9 @@ import type { ContextType, corsT, DieselT, middlewareFunc, RouteHandlerT } from
|
|
|
4
4
|
|
|
5
5
|
export default async function handleRequest(req: Request, server: Server, url: URL, diesel: DieselT): Promise<Response> {
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
7
|
// Try to find the route handler in the trie
|
|
10
8
|
const routeHandler: RouteHandlerT | undefined = diesel.trie.search(url.pathname, req.method);
|
|
11
|
-
|
|
9
|
+
|
|
12
10
|
// Early return if route or method is not found
|
|
13
11
|
if (!routeHandler || routeHandler.method !== req.method) {
|
|
14
12
|
return new Response(routeHandler ? "Method not allowed" : `Route not found for ${url.pathname}`, {
|
|
@@ -24,7 +22,7 @@ export default async function handleRequest(req: Request, server: Server, url: U
|
|
|
24
22
|
|
|
25
23
|
// cors execution
|
|
26
24
|
if (diesel.corsConfig) {
|
|
27
|
-
const corsResult =
|
|
25
|
+
const corsResult = applyCors(req, ctx, diesel.corsConfig)
|
|
28
26
|
if (corsResult) return corsResult;
|
|
29
27
|
}
|
|
30
28
|
|
|
@@ -33,9 +31,10 @@ export default async function handleRequest(req: Request, server: Server, url: U
|
|
|
33
31
|
|
|
34
32
|
// filter applying
|
|
35
33
|
if (diesel.hasFilterEnabled) {
|
|
36
|
-
|
|
34
|
+
|
|
37
35
|
const path = req.routePattern ?? url.pathname
|
|
38
36
|
const hasRoute = diesel.filters.includes(path)
|
|
37
|
+
|
|
39
38
|
if (hasRoute === false) {
|
|
40
39
|
if (diesel.filterFunction) {
|
|
41
40
|
try {
|
|
@@ -57,13 +56,16 @@ export default async function handleRequest(req: Request, server: Server, url: U
|
|
|
57
56
|
|
|
58
57
|
// middleware execution
|
|
59
58
|
if (diesel.hasMiddleware) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
// first run global midl
|
|
60
|
+
for (const globalMiddleware of diesel.globalMiddlewares) {
|
|
61
|
+
const result = await globalMiddleware(ctx, server);
|
|
62
|
+
if (result) return result;
|
|
63
|
+
}
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
// then path specific midl
|
|
66
|
+
const pathMiddlewares = diesel.middlewares.get(url.pathname) || [];
|
|
67
|
+
for (const pathMiddleware of pathMiddlewares) {
|
|
68
|
+
const result = await pathMiddleware(ctx, server);
|
|
67
69
|
if (result) return result;
|
|
68
70
|
}
|
|
69
71
|
|
|
@@ -100,7 +102,7 @@ export default async function handleRequest(req: Request, server: Server, url: U
|
|
|
100
102
|
}
|
|
101
103
|
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
function applyCors(req: Request, ctx: ContextType, config: corsT = {}): Response | null {
|
|
104
106
|
const origin = req.headers.get('origin') ?? '*'
|
|
105
107
|
const allowedOrigins = config?.origin
|
|
106
108
|
const allowedHeaders = config?.allowedHeaders ?? ["Content-Type", "Authorization"]
|
package/src/main.ts
CHANGED
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 | undefined) => void | Response | Promise<Response>
|
|
5
|
+
export type middlewareFunc = (ctx:ContextType,server?:Server | undefined) => null | void | Response | Promise<Response | void | null>
|
|
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";
|
|
@@ -47,8 +47,8 @@ export interface ContextType {
|
|
|
47
47
|
redirect: (path: string, status?: number) => Response;
|
|
48
48
|
getParams: (props?: any) => any;
|
|
49
49
|
getQuery: (props?: any) => any;
|
|
50
|
-
cookie: (name: string, value: string, options?: CookieOptions) =>
|
|
51
|
-
getCookie: (cookieName?: string) =>
|
|
50
|
+
cookie: (name: string, value: string, options?: CookieOptions) => this;
|
|
51
|
+
getCookie: (cookieName?: string) => any;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
export interface CookieOptions {
|
|
@@ -89,7 +89,7 @@ export interface DieselT {
|
|
|
89
89
|
};
|
|
90
90
|
filters: string[]
|
|
91
91
|
hasFilterEnabled:boolean
|
|
92
|
-
filterFunction: (ctx:ContextType,serer?:Server) => void | Response | Promise<Response|void>
|
|
92
|
+
filterFunction: (ctx:ContextType,serer?:Server) => void | Response | Promise<Response | void | null>
|
|
93
93
|
corsConfig: corsT | null
|
|
94
94
|
globalMiddlewares: Array<(ctx: ContextType, serer?: Server) => void | Promise<Response | null | void>>
|
|
95
95
|
middlewares: Map<string, Array<(ctx: ContextType, serer?: Server) => void | Promise<Response | null | void>>>
|
|
@@ -98,6 +98,14 @@ export interface DieselT {
|
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
// export interface routerT {
|
|
102
|
+
// get : (path: string, ...handlers: handlerFunction[]) => this,
|
|
103
|
+
// post: (path: string, ...handlers: handlerFunction[]) => this
|
|
104
|
+
// put: (path: string, ...handlers: handlerFunction[]) => this
|
|
105
|
+
// delete: (path: string, ...handlers: handlerFunction[]) => this
|
|
106
|
+
// patch: (path: string, ...handlers: handlerFunction[]) => this
|
|
107
|
+
// }
|
|
108
|
+
|
|
101
109
|
export interface RouteCache {
|
|
102
110
|
[key: string]: RouteHandlerT | undefined;
|
|
103
111
|
}
|
package/tsconfig.json
CHANGED
package/dist/router.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import Diesel from "./main";
|
|
2
|
-
import type { handlerFunction } from "./types";
|
|
3
|
-
declare class Router extends Diesel {
|
|
4
|
-
#private;
|
|
5
|
-
constructor();
|
|
6
|
-
get(path: string, ...handlers: handlerFunction[]): this;
|
|
7
|
-
post(path: string, ...handlers: handlerFunction[]): this;
|
|
8
|
-
put(path: string, ...handlers: handlerFunction[]): this;
|
|
9
|
-
patch(path: string, ...handlers: handlerFunction[]): this;
|
|
10
|
-
delete(path: string, ...handlers: handlerFunction[]): this;
|
|
11
|
-
}
|
|
12
|
-
export default Router;
|
package/dist/router.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
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};
|