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 CHANGED
@@ -1 +1,3 @@
1
- if you changes code OR fixing bugs so after doing make sure to run tsc and bun build.js
1
+ only i know folder structure and codebase , if u dont understand it dont worry , just ping me.
2
+
3
+ if you changes code OR fixing bugs so after doing make sure to run tsc
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 h (xl) => {
174
- return xl.status(200).text("hi im from middleware")
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
- app.use(hello)
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
- // tsc will create main folder
2
- Bun.build({
3
- entrypoints: [
4
- './main/main.ts',
5
- './main/ctx.ts',
6
- './main/handleRequest.ts',
7
- './main/trie.ts',
8
- './main/router.ts'
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
- await Bun.spawn(['rm', '-rf', './main']);
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 $(E,F,I){let G=new Headers,R={},L=!1,U=null,X=null,Y=null,Z,_=200;return{req:E,server:F,url:I,next:()=>{},status(w){return _=w,this},getIP(){return this.server.requestIP(this.req)},async body(){if(!Z)Z=await O(E);if(Z.error)return new Response(JSON.stringify({error:Z.error}),{status:400});return Z},setHeader(w,z){return G.set(w,z),this},set(w,z){return R[w]=z,this},get(w){return R[w]||null},setAuth(w){return L=w,this},getAuth(){return L},text(w,z){return new Response(w,{status:z??_,headers:G})},json(w,z){return new Response(JSON.stringify(w),{status:z??_,headers:G})},html(w,z){return new Response(Bun.file(w),{status:z??_,headers:G})},file(w,z){return new Response(Bun.file(w),{status:z??_,headers:G})},redirect(w,z){return G.set("Location",w),new Response(null,{status:z??302,headers:G})},getParams(w){if(!Y)Y=W(E?.routePattern,I?.pathname);return w?Y[w]||null:Y},getQuery(w){if(!U)U=Object.fromEntries(I.searchParams);return w?U[w]||null:U},async cookie(w,z,J={}){let M=`${encodeURIComponent(w)}=${encodeURIComponent(z)}`;if(J.maxAge)M+=`; Max-Age=${J.maxAge}`;if(J.expires)M+=`; Expires=${J.expires.toUTCString()}`;if(J.path)M+=`; Path=${J.path}`;if(J.domain)M+=`; Domain=${J.domain}`;if(J.secure)M+="; Secure";if(J.httpOnly)M+="; HttpOnly";if(J.sameSite)M+=`; SameSite=${J.sameSite}`;return G?.append("Set-Cookie",M),this},async getCookie(w){if(!X){let z=E.headers.get("cookie");if(z)X=await K(z)}return w?X[w]||null:X}}}async function K(E){let F={};if(!E)return F;return E.split(";").forEach((G)=>{let[R,L]=G?.trim()?.split("=");if(R&&L)F[R.trim()]=L.split(" ")[0].trim()}),F}function W(E,F){let I={},G=E.split("/"),[R]=F.split("?"),L=R.split("/");if(G.length!==L.length)return null;return G.forEach((U,X)=>{if(U.startsWith(":")){let Y=U.slice(1);I[Y]=L[X]}}),I}async function O(E){let F=E.headers.get("Content-Type")||"";if(!F)return{};try{if(F.startsWith("application/json"))return await E.json();if(F.startsWith("application/x-www-form-urlencoded")){let I=await E.text();return Object.fromEntries(new URLSearchParams(I))}if(F.startsWith("multipart/form-data")){let I=await E.formData();return A(I)}return{error:"Unknown request body type"}}catch(I){return{error:"Invalid request body format"}}}function A(E){let F={};for(let[I,G]of E.entries())F[I]=G;return F}export{$ as default};
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};
@@ -1 +1 @@
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};
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{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 E{root;constructor(){this.root=new C}insert(w,z){let b=this.root,B=w.split("/").filter(Boolean);if(w==="/"){b.isEndOfWord=!0,b.handler.push(z.handler),b.path=w,b.method.push(z.method);return}for(let j of B){let A=!1,q=j;if(j.startsWith(":"))A=!0,q=":";if(!b.children[q])b.children[q]=new C;b=b.children[q],b.isDynamic=A,b.pattern=j}b.isEndOfWord=!0,b.method.push(z.method),b.handler.push(z.handler),b.path=w}search(w,z){let b=this.root,B=w.split("/").filter(Boolean);for(let A of B){let q=A;if(!b.children[q])if(b.children[":"])b=b.children[":"];else return null;else b=b.children[q]}let j=b.method.indexOf(z);if(j!==-1)return{path:b.path,handler:b.handler[j],isDynamic:b.isDynamic,pattern:b.pattern,method:b.method[j]};return{path:b.path,handler:b.handler,isDynamic:b.isDynamic,pattern:b.pattern,method:b.method[j]}}}export{E as default};
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) => Promise<this>;
46
- getCookie: (cookieName?: string) => Promise<any>;
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 ,{rateLimit} from "../src/main";
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 (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
- }
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
- // app.use(h)
36
+
38
37
  // app.use(limiter)
39
38
 
40
- // app
41
- // .filter()
42
- // .routeMatcher('/api/user/register','/api/user/login','/test/:id','/cookie')
43
- // .permitAll()
44
- // .require(authJwt as middlewareFunc)
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.getUser()
54
- // return xl.json({user:user});
55
- return xl.status(200).text("hello world")
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
- 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
- await xl.cookie("accessToken", accessToken, options)
84
- await xl.cookie("refreshToken", refreshToken, options)
85
- // xl.cookie("refreshToken", refreshToken, options);
86
- await xl.getCookie()
87
- return xl.json({msg:"setting cookies"})
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
 
@@ -10,8 +10,11 @@
10
10
  "license": "ISC",
11
11
  "description": "",
12
12
  "dependencies": {
13
+ "@types/cors": "^2.8.17",
13
14
  "@types/jsonwebtoken": "^9.0.7",
15
+ "cors": "^2.8.5",
14
16
  "diesel-core": "^0.0.13",
17
+ "i": "^0.3.7",
15
18
  "jsonwebtoken": "^9.0.2",
16
19
  "jwt": "^0.2.0"
17
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diesel-core",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/main.d.ts",
6
6
  "scripts": {
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> | null {
114
+ : string | Record<string, string> | {} {
115
115
  if (!parsedParams) {
116
116
  parsedParams = extractDynamicParams(req?.routePattern, url?.pathname);
117
117
  }
118
- return props ? parsedParams[props] || null : parsedParams;
118
+ return props ? parsedParams[props] || {} : parsedParams;
119
119
  },
120
120
 
121
121
  getQuery(props?: any)
122
- : string | Record<string, string> | null {
123
- if (!parsedQuery) {
124
- parsedQuery = Object.fromEntries(url.searchParams);
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
- async cookie(name: string, value: string, options: CookieOptions = {}): Promise<ContextType> {
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
- async getCookie(cookieName?: string)
147
- : Promise<string | Record<string, string> | null> {
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 = await parseCookie(cookieHeader);
154
+ parsedCookie = parseCookie(cookieHeader);
155
+ } else {
156
+ return null
152
157
  }
153
158
  }
154
- return cookieName ? parsedCookie[cookieName] || null : parsedCookie;
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
- async function parseCookie(header: string | undefined)
161
- : Promise<Record<string, string>> {
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
 
@@ -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 = await applyCors(req, ctx, diesel.corsConfig)
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
- const middlewares = [
61
- ...diesel.globalMiddlewares,
62
- ...diesel.middlewares.get(url.pathname) || []
63
- ] as middlewareFunc[]
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
- for (const middleware of middlewares) {
66
- const result = await middleware(ctx, server);
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
- async function applyCors(req: Request, ctx: ContextType, config: corsT = {}): Promise<Response | null> {
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
@@ -269,6 +269,7 @@ export default class Diesel {
269
269
  }
270
270
  }
271
271
 
272
+
272
273
  get(
273
274
  path: string,
274
275
  ...handlers: handlerFunction[]
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) => Promise<this>;
51
- getCookie: (cookieName?: string) => Promise<any>;
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
@@ -14,4 +14,4 @@
14
14
  },
15
15
  "include": ["src/**/*.ts"], // Specify the files to include
16
16
  "exclude": ["node_modules"] // Exclude the 'node_modules' directory
17
- }
17
+ }
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};