diesel-core 0.0.19 → 0.0.20
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/LICENSE +1 -1
- package/dist/ctx.js +1 -1
- package/dist/handleRequest.js +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.js +1 -1
- package/example/main.ts +29 -14
- package/package.json +1 -1
- package/src/ctx.ts +2 -3
- package/src/handleRequest.ts +12 -17
- package/src/main.ts +43 -90
- package/src/route.ts +0 -21
package/LICENSE
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Diesel
|
|
1
|
+
Diesel.js License
|
|
2
2
|
Copyright (c) 2024 Pradeep Sahu
|
|
3
3
|
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
package/dist/ctx.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function K(F,L,G){let z=new Headers,M={},U=!1,I,Z=null,$,_,Y=200,x={};return{req:F,server:L,url:G,getUser(){return x},setUser(w){if(w)x=w},status(w){return Y=w,this},getIP(){return this.server.requestIP(this.req)},async getBody(){if(!_)_=await W(F);if(_.error)return new Response(JSON.stringify({error:_.error}),{status:400});return _},setHeader(w,E){return z.set(w,E),this},set(w,E){return M[w]=E,this},get(w){return M[w]||null},setAuth(w){return U=w,this},getAuth(){return U},text(w,E){return new Response(w,{status:E??Y,headers:z})},send(w,E){return new Response(w,{status:E??Y,headers:z})},json(w,E){return new Response(JSON.stringify(w),{status:E??Y,headers:z})},html(w,E){return new Response(Bun.file(w),{status:E??Y,headers:z})},file(w,E){return new Response(Bun.file(w),{status:E??Y,headers:z})},redirect(w,E){return z.set("Location",w),new Response(null,{status:E??302,headers:z})},setCookie(w,E,J={}){let X=`${encodeURIComponent(w)}=${encodeURIComponent(E)}`;if(J.maxAge)X+=`; Max-Age=${J.maxAge}`;if(J.expires)X+=`; Expires=${J.expires.toUTCString()}`;if(J.path)X+=`; Path=${J.path}`;if(J.domain)X+=`; Domain=${J.domain}`;if(J.secure)X+="; Secure";if(J.httpOnly)X+="; HttpOnly";if(J.sameSite)X+=`; SameSite=${J.sameSite}`;return z?.append("Set-Cookie",X),this},getParams(w){if(!$&&F?.routePattern)$=R(F?.routePattern,G?.pathname);return w?$[w]||{}:$},getQuery(w){try{if(!I)I=Object.fromEntries(G.searchParams);return w?I[w]||{}:I}catch(E){return{}}},getCookie(w){if(!Z){let E=F.headers.get("cookie");if(E)Z=O(E);else return null}if(!Z)return null;if(w)return Z[w]??null;else return Z}}}function O(F){let L={},G=F?.split(";");for(let z=0;z<G?.length;z++){let[M,...U]=G[z].trim().split("="),I=U?.join("=").trim();if(M)L[M.trim()]=decodeURIComponent(I)}return L}function R(F,L){let G={},z=F.split("/"),[M]=L.split("?"),U=M.split("/");if(z.length!==U.length)return null;for(let I=0;I<z.length;I++)if(z[I].startsWith(":"))G[z[I].slice(1)]=U[I];return G}async function W(F){let L=F.headers.get("Content-Type")
|
|
1
|
+
function K(F,L,G){let z=new Headers,M={},U=!1,I,Z=null,$,_,Y=200,x={};return{req:F,server:L,url:G,getUser(){return x},setUser(w){if(w)x=w},status(w){return Y=w,this},getIP(){return this.server.requestIP(this.req)},async getBody(){if(!_)_=await W(F);if(_.error)return new Response(JSON.stringify({error:_.error}),{status:400});return _},setHeader(w,E){return z.set(w,E),this},set(w,E){return M[w]=E,this},get(w){return M[w]||null},setAuth(w){return U=w,this},getAuth(){return U},text(w,E){return new Response(w,{status:E??Y,headers:z})},send(w,E){return new Response(w,{status:E??Y,headers:z})},json(w,E){return new Response(JSON.stringify(w),{status:E??Y,headers:z})},html(w,E){return new Response(Bun.file(w),{status:E??Y,headers:z})},file(w,E){return new Response(Bun.file(w),{status:E??Y,headers:z})},redirect(w,E){return z.set("Location",w),new Response(null,{status:E??302,headers:z})},setCookie(w,E,J={}){let X=`${encodeURIComponent(w)}=${encodeURIComponent(E)}`;if(J.maxAge)X+=`; Max-Age=${J.maxAge}`;if(J.expires)X+=`; Expires=${J.expires.toUTCString()}`;if(J.path)X+=`; Path=${J.path}`;if(J.domain)X+=`; Domain=${J.domain}`;if(J.secure)X+="; Secure";if(J.httpOnly)X+="; HttpOnly";if(J.sameSite)X+=`; SameSite=${J.sameSite}`;return z?.append("Set-Cookie",X),this},getParams(w){if(!$&&F?.routePattern)$=R(F?.routePattern,G?.pathname);return w?$[w]||{}:$},getQuery(w){try{if(!I)I=Object.fromEntries(G.searchParams);return w?I[w]||{}:I}catch(E){return{}}},getCookie(w){if(!Z){let E=F.headers.get("cookie");if(E)Z=O(E);else return null}if(!Z)return null;if(w)return Z[w]??null;else return Z}}}function O(F){let L={},G=F?.split(";");for(let z=0;z<G?.length;z++){let[M,...U]=G[z].trim().split("="),I=U?.join("=").trim();if(M)L[M.trim()]=decodeURIComponent(I)}return L}function R(F,L){let G={},z=F.split("/"),[M]=L.split("?"),U=M.split("/");if(z.length!==U.length)return null;for(let I=0;I<z.length;I++)if(z[I].startsWith(":"))G[z[I].slice(1)]=U[I];return G}async function W(F){let L=F.headers.get("Content-Type");if(!L)return{};try{if(L.startsWith("application/json"))return await F.json();if(L.startsWith("application/x-www-form-urlencoded")){let G=await F.text();return Object.fromEntries(new URLSearchParams(G))}if(L.startsWith("multipart/form-data")){let G=await F.formData(),z={};for(let[M,U]of G.entries())z[M]=U;return z}return{error:"Unknown request body type"}}catch(G){return{error:"Invalid request body format"}}}export{K as default};
|
package/dist/handleRequest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function D(I,F,G){let z=new Headers,J={},L=!1,Z,U=null,Y,_,$=200,A={};return{req:I,server:F,url:G,getUser(){return A},setUser(E){if(E)A=E},status(E){return $=E,this},getIP(){return this.server.requestIP(this.req)},async getBody(){if(!_)_=await
|
|
1
|
+
function D(I,F,G){let z=new Headers,J={},L=!1,Z,U=null,Y,_,$=200,A={};return{req:I,server:F,url:G,getUser(){return A},setUser(E){if(E)A=E},status(E){return $=E,this},getIP(){return this.server.requestIP(this.req)},async getBody(){if(!_)_=await M(I);if(_.error)return new Response(JSON.stringify({error:_.error}),{status:400});return _},setHeader(E,X){return z.set(E,X),this},set(E,X){return J[E]=X,this},get(E){return J[E]||null},setAuth(E){return L=E,this},getAuth(){return L},text(E,X){return new Response(E,{status:X??$,headers:z})},send(E,X){return new Response(E,{status:X??$,headers:z})},json(E,X){return new Response(JSON.stringify(E),{status:X??$,headers:z})},html(E,X){return new Response(Bun.file(E),{status:X??$,headers:z})},file(E,X){return new Response(Bun.file(E),{status:X??$,headers:z})},redirect(E,X){return z.set("Location",E),new Response(null,{status:X??302,headers:z})},setCookie(E,X,K={}){let W=`${encodeURIComponent(E)}=${encodeURIComponent(X)}`;if(K.maxAge)W+=`; Max-Age=${K.maxAge}`;if(K.expires)W+=`; Expires=${K.expires.toUTCString()}`;if(K.path)W+=`; Path=${K.path}`;if(K.domain)W+=`; Domain=${K.domain}`;if(K.secure)W+="; Secure";if(K.httpOnly)W+="; HttpOnly";if(K.sameSite)W+=`; SameSite=${K.sameSite}`;return z?.append("Set-Cookie",W),this},getParams(E){if(!Y&&I?.routePattern)Y=j(I?.routePattern,G?.pathname);return E?Y[E]||{}:Y},getQuery(E){try{if(!Z)Z=Object.fromEntries(G.searchParams);return E?Z[E]||{}:Z}catch(X){return{}}},getCookie(E){if(!U){let X=I.headers.get("cookie");if(X)U=T(X);else return null}if(!U)return null;if(E)return U[E]??null;else return U}}}function T(I){let F={},G=I?.split(";");for(let z=0;z<G?.length;z++){let[J,...L]=G[z].trim().split("="),Z=L?.join("=").trim();if(J)F[J.trim()]=decodeURIComponent(Z)}return F}function j(I,F){let G={},z=I.split("/"),[J]=F.split("?"),L=J.split("/");if(z.length!==L.length)return null;for(let Z=0;Z<z.length;Z++)if(z[Z].startsWith(":"))G[z[Z].slice(1)]=L[Z];return G}async function M(I){let F=I.headers.get("Content-Type");if(!F)return{};try{if(F.startsWith("application/json"))return await I.json();if(F.startsWith("application/x-www-form-urlencoded")){let G=await I.text();return Object.fromEntries(new URLSearchParams(G))}if(F.startsWith("multipart/form-data")){let G=await I.formData(),z={};for(let[J,L]of G.entries())z[J]=L;return z}return{error:"Unknown request body type"}}catch(G){return{error:"Invalid request body format"}}}async function Q(I,F,G,z){let J=z.trie.search(G.pathname,I.method);if(J?.isDynamic)I.routePattern=J.path;let L=D(I,F,G);if(z.corsConfig){let U=V(I,L,z.corsConfig);if(U)return U}if(z.hasOnReqHook&&z.hooks.onRequest)z.hooks.onRequest(I,G,F);if(z.hasFilterEnabled){let U=I.routePattern??G.pathname;if(!z.filters.has(U))if(z.filterFunction)try{let Y=await z.filterFunction(L,F);if(Y)return Y}catch(Y){return console.error("Error in filterFunction:",Y),L.status(500).json({message:"Internal Server Error",error:Y.message})}else return L.status(400).json({message:"Authentication required"})}if(z.hasMiddleware){let U=z.globalMiddlewares;for(let _=0;_<U.length;_++){let $=await U[_](L,F);if($)return $}let Y=z.middlewares.get(G.pathname)||[];for(let _=0;_<Y.length;_++){let $=await Y[_](L,F);if($)return $}}if(!J||J.method!==I.method){let U=J?"Method not allowed":`Route not found for ${G.pathname}`,Y=J?405:404;return new Response(JSON.stringify({message:U}),{status:Y})}if(z.hasPreHandlerHook&&z.hooks.preHandler){let U=await z.hooks.preHandler(L);if(U)return U}let Z=await J.handler(L);if(z.hasPostHandlerHook&&z.hooks.postHandler)await z.hooks.postHandler(L);if(z.hasOnSendHook&&z.hooks.onSend){let U=await z.hooks.onSend(L,Z);if(U)return U}return Z??L.status(204).json({message:"No response from this handler"})}function V(I,F,G={}){let z=I.headers.get("origin")??"*",J=G?.origin,L=G?.allowedHeaders??["Content-Type","Authorization"],Z=G?.methods??["GET","POST","PUT","DELETE","OPTIONS"],U=G?.credentials??!1,Y=G?.exposedHeaders??[];if(F.setHeader("Access-Control-Allow-Methods",Z),F.setHeader("Access-Control-Allow-Headers",L),F.setHeader("Access-Control-Allow-Credentials",U),Y.length)F.setHeader("Access-Control-Expose-Headers",Y);if(J==="*")F.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(J))if(z&&J.includes(z))F.setHeader("Access-Control-Allow-Origin",z);else if(J.includes("*"))F.setHeader("Access-Control-Allow-Origin","*");else return F.status(403).json({message:"CORS not allowed"});else if(typeof J==="string")if(z===J)F.setHeader("Access-Control-Allow-Origin",z);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",z),I.method==="OPTIONS")return F.setHeader("Access-Control-Max-Age","86400"),F.status(204).text("");return null}export{Q as default};
|
package/dist/main.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export default class Diesel {
|
|
|
27
27
|
route(basePath: string, routerInstance: any): void;
|
|
28
28
|
register(pathPrefix: string, handlerInstance: any): void;
|
|
29
29
|
addRoute(method: HttpMethod, path: string, handlers: handlerFunction[]): void;
|
|
30
|
-
use(pathORHandler?: string | middlewareFunc,
|
|
30
|
+
use(pathORHandler?: string | middlewareFunc, ...handlers: middlewareFunc[]): void;
|
|
31
31
|
get(path: string, ...handlers: handlerFunction[]): this;
|
|
32
32
|
post(path: string, ...handlers: handlerFunction[]): this;
|
|
33
33
|
put(path: string, ...handlers: handlerFunction[]): this;
|
package/dist/main.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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 A{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=[z.handler],G.path=F,G.method=[z.method];return}for(let L=0;L<J.length;L++){let U=J[L],Z=!1,X=U;if(U.startsWith(":"))Z=!0,X=":";if(!G.children[X])G.children[X]=new B;if(G=G.children[X],G.isDynamic=Z,G.pattern=U,L===J.length-1)G.handler=[z.handler],G.method=[z.method],G.isEndOfWord=!0,G.path=F}}search(F,z){let G=this.root,J=F.split("/").filter(Boolean);for(let U of J){let Z=U;if(!G.children[Z])if(G.children[":"])G=G.children[":"];else return null;else G=G.children[Z]}let L=G.method.indexOf(z);if(G.isEndOfWord&&L!==-1)return{path:G.path,handler:G.handler[L],isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[L]};return null}}function K(F,z,G){let J=new Headers,L={},U=!1,Z,X=null,_,$,E=200,Q={};return{req:F,server:z,url:G,getUser(){return Q},setUser(Y){if(Y)Q=Y},status(Y){return E=Y,this},getIP(){return this.server.requestIP(this.req)},async getBody(){if(!$)$=await N(F);if($.error)return new Response(JSON.stringify({error:$.error}),{status:400});return $},setHeader(Y,W){return J.set(Y,W),this},set(Y,W){return L[Y]=W,this},get(Y){return L[Y]||null},setAuth(Y){return U=Y,this},getAuth(){return U},text(Y,W){return new Response(Y,{status:W??E,headers:J})},send(Y,W){return new Response(Y,{status:W??E,headers:J})},json(Y,W){return new Response(JSON.stringify(Y),{status:W??E,headers:J})},html(Y,W){return new Response(Bun.file(Y),{status:W??E,headers:J})},file(Y,W){return new Response(Bun.file(Y),{status:W??E,headers:J})},redirect(Y,W){return J.set("Location",Y),new Response(null,{status:W??302,headers:J})},setCookie(Y,W,D={}){let V=`${encodeURIComponent(Y)}=${encodeURIComponent(W)}`;if(D.maxAge)V+=`; Max-Age=${D.maxAge}`;if(D.expires)V+=`; Expires=${D.expires.toUTCString()}`;if(D.path)V+=`; Path=${D.path}`;if(D.domain)V+=`; Domain=${D.domain}`;if(D.secure)V+="; Secure";if(D.httpOnly)V+="; HttpOnly";if(D.sameSite)V+=`; SameSite=${D.sameSite}`;return J?.append("Set-Cookie",V),this},getParams(Y){if(!_&&F?.routePattern)_=T(F?.routePattern,G?.pathname);return Y?_[Y]||{}:_},getQuery(Y){try{if(!Z)Z=Object.fromEntries(G.searchParams);return Y?Z[Y]||{}:Z}catch(W){return{}}},getCookie(Y){if(!X){let W=F.headers.get("cookie");if(W)X=I(W);else return null}if(!X)return null;if(Y)return X[Y]??null;else return X}}}function I(F){let z={},G=F?.split(";");for(let J=0;J<G?.length;J++){let[L,...U]=G[J].trim().split("="),Z=U?.join("=").trim();if(L)z[L.trim()]=decodeURIComponent(Z)}return z}function T(F,z){let G={},J=F.split("/"),[L]=z.split("?"),U=L.split("/");if(J.length!==U.length)return null;for(let Z=0;Z<J.length;Z++)if(J[Z].startsWith(":"))G[J[Z].slice(1)]=U[Z];return G}async function N(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(),J={};for(let[L,U]of G.entries())J[L]=U;return J}return{error:"Unknown request body type"}}catch(G){return{error:"Invalid request body format"}}}async function j(F,z,G,J){let L=J.trie.search(G.pathname,F.method);if(!L||L.method!==F.method){let X=L?"Method not allowed":`Route not found for ${G.pathname}`,_=L?405:404;return new Response(JSON.stringify({message:X}),{status:_})}if(L.isDynamic)F.routePattern=L.path;let U=K(F,z,G);if(J.corsConfig){let X=C(F,U,J.corsConfig);if(X)return X}if(J.hasOnReqHook&&J.hooks.onRequest)J.hooks.onRequest(F,G,z);if(J.hasFilterEnabled){let X=F.routePattern??G.pathname;if(!J.filters.has(X))if(J.filterFunction)try{let _=await J.filterFunction(U,z);if(_)return _}catch(_){return console.error("Error in filterFunction:",_),U.status(500).json({message:"Internal Server Error",error:_.message})}else return U.status(400).json({message:"Authentication required"})}if(J.hasMiddleware){let X=J.globalMiddlewares;for(let $=0;$<X.length;$++){let E=await X[$](U,z);if(E)return E}let _=J.middlewares.get(G.pathname)||[];for(let $=0;$<_.length;$++){let E=await _[$](U,z);if(E)return E}}if(J.hasPreHandlerHook&&J.hooks.preHandler){let X=await J.hooks.preHandler(U);if(X)return X}let Z=await L.handler(U);if(J.hasPostHandlerHook&&J.hooks.postHandler)await J.hooks.postHandler(U);if(J.hasOnSendHook&&J.hooks.onSend){let X=await J.hooks.onSend(U,Z);if(X)return X}return Z??U.status(204).json({message:"No response from this handler"})}function C(F,z,G={}){let J=F.headers.get("origin")??"*",L=G?.origin,U=G?.allowedHeaders??["Content-Type","Authorization"],Z=G?.methods??["GET","POST","PUT","DELETE","OPTIONS"],X=G?.credentials??!1,_=G?.exposedHeaders??[];if(z.setHeader("Access-Control-Allow-Methods",Z),z.setHeader("Access-Control-Allow-Headers",U),z.setHeader("Access-Control-Allow-Credentials",X),_.length)z.setHeader("Access-Control-Expose-Headers",_);if(L==="*")z.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(L))if(J&&L.includes(J))z.setHeader("Access-Control-Allow-Origin",J);else if(L.includes("*"))z.setHeader("Access-Control-Allow-Origin","*");else return z.status(403).json({message:"CORS not allowed"});else if(typeof L==="string")if(J===L)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}class M{tempRoutes;globalMiddlewares;middlewares;trie;hasOnReqHook;hasMiddleware;hasPreHandlerHook;hasPostHandlerHook;hasOnSendHook;hasOnError;hooks;corsConfig;FilterRoutes;filters;filterFunction;hasFilterEnabled;constructor(){this.tempRoutes=new Map,this.globalMiddlewares=[],this.middlewares=new Map,this.trie=new A,this.corsConfig=null,this.hasMiddleware=!1,this.hasOnReqHook=!1,this.hasPreHandlerHook=!1,this.hasPostHandlerHook=!1,this.hasOnSendHook=!1,this.hasOnError=!1,this.hooks={onRequest:null,preHandler:null,postHandler:null,onSend:null,onError:null,onClose:null},this.FilterRoutes=[],this.filters=new Set,this.filterFunction=null,this.hasFilterEnabled=!1}filter(){return this.hasFilterEnabled=!0,{routeMatcher:(...F)=>{return this.FilterRoutes=F,this.filter()},permitAll:()=>{for(let F of this?.FilterRoutes)this.filters.add(F);return this.FilterRoutes=null,this.filter()},require:(F)=>{if(F)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");switch(F){case"onRequest":this.hooks.onRequest=z,this.hasOnReqHook=!0;break;case"preHandler":this.hooks.preHandler=z,this.hasPreHandlerHook=!0;break;case"postHandler":this.hooks.postHandler=z,this.hasPostHandlerHook=!0;break;case"onSend":this.hooks.onSend=z,this.hasOnSendHook=!0;break;case"onError":this.hooks.onError=z,this.hasOnError=!0;break;case"onClose":this.hooks.onClose=z;break;default: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;if(this.hooks.onError)this.hasOnError=!0;this.tempRoutes=new Map}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 L={port:F,fetch:async(Z,X)=>{let _=new URL(Z.url);try{return await j(Z,X,_,this)}catch($){if(this.hasOnError&&this.hooks.onError){let E=await this.hooks.onError($,Z,_,X);if(E)return E}return new Response(JSON.stringify({message:"Internal Server Error",error:$.message}),{status:500})}}};if(G&&J)L.certFile=G,L.keyFile=J;let U=Bun?.serve(L);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 U}route(F,z){if(!F||typeof F!=="string")throw new Error("Path must be a string");let G=Object.fromEntries(z.tempRoutes),J=Object.entries(G);for(let L=0;L<J.length;L++){let[U,Z]=J[L],X=`${F}${U}`;if(!this.middlewares.has(X))this.middlewares.set(X,[]);Z.handlers.slice(0,-1).forEach((Q)=>{if(!this.middlewares.get(X)?.includes(Q))this.middlewares.get(X)?.push(Q)});let $=Z.handlers[Z.handlers.length-1],E=Z.method;try{this.trie.insert(X,{handler:$,method:E})}catch(Q){console.error(`Error inserting ${X}:`,Q)}}z=null}register(F,z){this.route(F,z)}addRoute(F,z,G){if(typeof z!=="string")throw new Error("Path must be a string");if(typeof F!=="string")throw new Error("Method must be a string");this.tempRoutes.set(z,{method:F,handlers:G});let J=G.slice(0,-1),L=G[G.length-1];if(!this.middlewares.has(z))this.middlewares.set(z,[]);J.forEach((U)=>{if(z==="/")this.globalMiddlewares=[...new Set([...this.globalMiddlewares,...J])];else if(!this.middlewares.get(z)?.includes(U))this.middlewares.get(z)?.push(U)});try{this.trie.insert(z,{handler:L,method:F})}catch(U){console.error(`Error inserting ${z}:`,U)}}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.addRoute("GET",F,z),this}post(F,...z){return this.addRoute("POST",F,z),this}put(F,...z){return this.addRoute("PUT",F,z),this}patch(F,...z){return this.addRoute("PATCH",F,z),this}delete(F,...z){return this.addRoute("DELETE",F,z),this}}export{M as default};
|
|
1
|
+
class V{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 V}insert(F,z){let G=this.root,J=F.split("/").filter(Boolean);if(F==="/"){G.isEndOfWord=!0,G.handler=[z.handler],G.path=F,G.method=[z.method];return}for(let L=0;L<J.length;L++){let U=J[L],Y=!1,Z=U;if(U.startsWith(":"))Y=!0,Z=":";if(!G.children[Z])G.children[Z]=new V;if(G=G.children[Z],G.isDynamic=Y,G.pattern=U,L===J.length-1)G.handler=[z.handler],G.method=[z.method],G.isEndOfWord=!0,G.path=F}}search(F,z){let G=this.root,J=F.split("/").filter(Boolean);for(let U of J){let Y=U;if(!G.children[Y])if(G.children[":"])G=G.children[":"];else return null;else G=G.children[Y]}let L=G.method.indexOf(z);if(G.isEndOfWord&&L!==-1)return{path:G.path,handler:G.handler[L],isDynamic:G.isDynamic,pattern:G.pattern,method:G.method[L]};return null}}function B(F,z,G){let J=new Headers,L={},U=!1,Y,Z=null,_,E,W=200,j={};return{req:F,server:z,url:G,getUser(){return j},setUser(X){if(X)j=X},status(X){return W=X,this},getIP(){return this.server.requestIP(this.req)},async getBody(){if(!E)E=await N(F);if(E.error)return new Response(JSON.stringify({error:E.error}),{status:400});return E},setHeader(X,$){return J.set(X,$),this},set(X,$){return L[X]=$,this},get(X){return L[X]||null},setAuth(X){return U=X,this},getAuth(){return U},text(X,$){return new Response(X,{status:$??W,headers:J})},send(X,$){return new Response(X,{status:$??W,headers:J})},json(X,$){return new Response(JSON.stringify(X),{status:$??W,headers:J})},html(X,$){return new Response(Bun.file(X),{status:$??W,headers:J})},file(X,$){return new Response(Bun.file(X),{status:$??W,headers:J})},redirect(X,$){return J.set("Location",X),new Response(null,{status:$??302,headers:J})},setCookie(X,$,A={}){let D=`${encodeURIComponent(X)}=${encodeURIComponent($)}`;if(A.maxAge)D+=`; Max-Age=${A.maxAge}`;if(A.expires)D+=`; Expires=${A.expires.toUTCString()}`;if(A.path)D+=`; Path=${A.path}`;if(A.domain)D+=`; Domain=${A.domain}`;if(A.secure)D+="; Secure";if(A.httpOnly)D+="; HttpOnly";if(A.sameSite)D+=`; SameSite=${A.sameSite}`;return J?.append("Set-Cookie",D),this},getParams(X){if(!_&&F?.routePattern)_=T(F?.routePattern,G?.pathname);return X?_[X]||{}:_},getQuery(X){try{if(!Y)Y=Object.fromEntries(G.searchParams);return X?Y[X]||{}:Y}catch($){return{}}},getCookie(X){if(!Z){let $=F.headers.get("cookie");if($)Z=I($);else return null}if(!Z)return null;if(X)return Z[X]??null;else return Z}}}function I(F){let z={},G=F?.split(";");for(let J=0;J<G?.length;J++){let[L,...U]=G[J].trim().split("="),Y=U?.join("=").trim();if(L)z[L.trim()]=decodeURIComponent(Y)}return z}function T(F,z){let G={},J=F.split("/"),[L]=z.split("?"),U=L.split("/");if(J.length!==U.length)return null;for(let Y=0;Y<J.length;Y++)if(J[Y].startsWith(":"))G[J[Y].slice(1)]=U[Y];return G}async function N(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(),J={};for(let[L,U]of G.entries())J[L]=U;return J}return{error:"Unknown request body type"}}catch(G){return{error:"Invalid request body format"}}}async function K(F,z,G,J){let L=J.trie.search(G.pathname,F.method);if(L?.isDynamic)F.routePattern=L.path;let U=B(F,z,G);if(J.corsConfig){let Z=C(F,U,J.corsConfig);if(Z)return Z}if(J.hasOnReqHook&&J.hooks.onRequest)J.hooks.onRequest(F,G,z);if(J.hasFilterEnabled){let Z=F.routePattern??G.pathname;if(!J.filters.has(Z))if(J.filterFunction)try{let _=await J.filterFunction(U,z);if(_)return _}catch(_){return console.error("Error in filterFunction:",_),U.status(500).json({message:"Internal Server Error",error:_.message})}else return U.status(400).json({message:"Authentication required"})}if(J.hasMiddleware){let Z=J.globalMiddlewares;for(let E=0;E<Z.length;E++){let W=await Z[E](U,z);if(W)return W}let _=J.middlewares.get(G.pathname)||[];for(let E=0;E<_.length;E++){let W=await _[E](U,z);if(W)return W}}if(!L||L.method!==F.method){let Z=L?"Method not allowed":`Route not found for ${G.pathname}`,_=L?405:404;return new Response(JSON.stringify({message:Z}),{status:_})}if(J.hasPreHandlerHook&&J.hooks.preHandler){let Z=await J.hooks.preHandler(U);if(Z)return Z}let Y=await L.handler(U);if(J.hasPostHandlerHook&&J.hooks.postHandler)await J.hooks.postHandler(U);if(J.hasOnSendHook&&J.hooks.onSend){let Z=await J.hooks.onSend(U,Y);if(Z)return Z}return Y??U.status(204).json({message:"No response from this handler"})}function C(F,z,G={}){let J=F.headers.get("origin")??"*",L=G?.origin,U=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",U),z.setHeader("Access-Control-Allow-Credentials",Z),_.length)z.setHeader("Access-Control-Expose-Headers",_);if(L==="*")z.setHeader("Access-Control-Allow-Origin","*");else if(Array.isArray(L))if(J&&L.includes(J))z.setHeader("Access-Control-Allow-Origin",J);else if(L.includes("*"))z.setHeader("Access-Control-Allow-Origin","*");else return z.status(403).json({message:"CORS not allowed"});else if(typeof L==="string")if(J===L)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}class M{tempRoutes;globalMiddlewares;middlewares;trie;hasOnReqHook;hasMiddleware;hasPreHandlerHook;hasPostHandlerHook;hasOnSendHook;hasOnError;hooks;corsConfig;FilterRoutes;filters;filterFunction;hasFilterEnabled;constructor(){this.tempRoutes=new Map,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.hasOnError=!1,this.hooks={onRequest:null,preHandler:null,postHandler:null,onSend:null,onError:null,onClose:null},this.FilterRoutes=[],this.filters=new Set,this.filterFunction=null,this.hasFilterEnabled=!1}filter(){return this.hasFilterEnabled=!0,{routeMatcher:(...F)=>{return this.FilterRoutes=F,this.filter()},permitAll:()=>{for(let F of this?.FilterRoutes)this.filters.add(F);return this.FilterRoutes=null,this.filter()},require:(F)=>{if(F)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");switch(F){case"onRequest":this.hooks.onRequest=z,this.hasOnReqHook=!0;break;case"preHandler":this.hooks.preHandler=z,this.hasPreHandlerHook=!0;break;case"postHandler":this.hooks.postHandler=z,this.hasPostHandlerHook=!0;break;case"onSend":this.hooks.onSend=z,this.hasOnSendHook=!0;break;case"onError":this.hooks.onError=z,this.hasOnError=!0;break;case"onClose":this.hooks.onClose=z;break;default: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;if(this.hooks.onError)this.hasOnError=!0;this.tempRoutes=new Map}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 L={port:F,fetch:async(Y,Z)=>{let _=new URL(Y.url);try{return await K(Y,Z,_,this)}catch(E){if(this.hasOnError&&this.hooks.onError){let W=await this.hooks.onError(E,Y,_,Z);if(W)return W}return new Response(JSON.stringify({message:"Internal Server Error",error:E.message}),{status:500})}}};if(G&&J)L.certFile=G,L.keyFile=J;let U=Bun?.serve(L);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 U}route(F,z){if(!F||typeof F!=="string")throw new Error("Path must be a string");let G=Object.fromEntries(z.tempRoutes);Object.entries(G).forEach(([L,U])=>{let Y=`${F}${L}`;if(!this.middlewares.has(Y))this.middlewares.set(Y,[]);U.handlers.slice(0,-1).forEach((W)=>{if(!this.middlewares.get(Y)?.includes(W))this.middlewares.get(Y)?.push(W)});let _=U.handlers[U.handlers.length-1],E=U.method;try{this.trie.insert(Y,{handler:_,method:E})}catch(W){console.error(`Error inserting ${Y}:`,W)}}),z=null}register(F,z){this.route(F,z)}addRoute(F,z,G){if(typeof z!=="string")throw new Error("Path must be a string");if(typeof F!=="string")throw new Error("Method must be a string");this.tempRoutes.set(z,{method:F,handlers:G});let J=G.slice(0,-1),L=G[G.length-1];if(!this.middlewares.has(z))this.middlewares.set(z,[]);J.forEach((U)=>{if(z==="/")this.globalMiddlewares=[...new Set([...this.globalMiddlewares,...J])];else if(!this.middlewares.get(z)?.includes(U))this.middlewares.get(z)?.push(U)});try{this.trie.insert(z,{handler:L,method:F})}catch(U){console.error(`Error inserting ${z}:`,U)}}use(F,...z){if(typeof F==="function"){if(!this.globalMiddlewares.includes(F))this.globalMiddlewares.push(F);z.forEach((J)=>{if(!this.globalMiddlewares.includes(J))this.globalMiddlewares.push(J)});return}let G=F;if(!this.middlewares.has(G))this.middlewares.set(G,[]);if(z)z.forEach((J)=>{if(!this.middlewares.get(G)?.includes(J))this.middlewares.get(G)?.push(J)})}get(F,...z){return this.addRoute("GET",F,z),this}post(F,...z){return this.addRoute("POST",F,z),this}put(F,...z){return this.addRoute("PUT",F,z),this}patch(F,...z){return this.addRoute("PATCH",F,z),this}delete(F,...z){return this.addRoute("DELETE",F,z),this}}export{M as default};
|
package/example/main.ts
CHANGED
|
@@ -12,6 +12,18 @@ const secret = "linux";
|
|
|
12
12
|
// allowedHeaders: 'Content-Type,Authorization'
|
|
13
13
|
// })
|
|
14
14
|
|
|
15
|
+
const hello = async () => {
|
|
16
|
+
console.log('hello',Math.random())
|
|
17
|
+
}
|
|
18
|
+
const hello2 = async () => {
|
|
19
|
+
console.log('hello2', Math.random())
|
|
20
|
+
}
|
|
21
|
+
const hello3 = async () => {
|
|
22
|
+
console.log('hello3', Math.random())
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
15
27
|
export async function authJwt(ctx: ContextType): Promise<void | null | Response> {
|
|
16
28
|
|
|
17
29
|
const token = ctx.getCookie("accessToken");
|
|
@@ -19,24 +31,27 @@ export async function authJwt(ctx: ContextType): Promise<void | null | Response>
|
|
|
19
31
|
return ctx.status(401).json({ message: "Authentication token missing" });
|
|
20
32
|
}
|
|
21
33
|
try {
|
|
22
|
-
const user = await jwt.verify(token, secret);
|
|
34
|
+
const user = await jwt.verify(token, secret);
|
|
23
35
|
ctx.setUser(user);
|
|
24
36
|
} catch (error) {
|
|
25
37
|
return ctx.status(403).json({ message: "Invalid token" });
|
|
26
38
|
}
|
|
27
39
|
}
|
|
28
40
|
|
|
29
|
-
app
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
// app.use('/ttt',hello,hello2,hello3)
|
|
42
|
+
|
|
43
|
+
// app
|
|
44
|
+
// .filter()
|
|
45
|
+
// .routeMatcher("/cookie",'/api/user/login','api/user/register')
|
|
46
|
+
// .permitAll()
|
|
47
|
+
// .require(authJwt as middlewareFunc);
|
|
34
48
|
|
|
35
49
|
|
|
36
50
|
app.addHooks('onError', (error: any, req: Request, url: URL, server: Server) => {
|
|
37
51
|
console.error(`Error occurred: ${error.message}`);
|
|
38
52
|
console.error(`Request Method: ${req.method}, Request URL: ${url}`);
|
|
39
|
-
|
|
53
|
+
throw new Error('just error')
|
|
54
|
+
// return new Response('Internal Server Error', { status: 500 });
|
|
40
55
|
});
|
|
41
56
|
|
|
42
57
|
|
|
@@ -79,24 +94,24 @@ app.get("/cookie", async (xl) => {
|
|
|
79
94
|
const accessToken = jwt.sign(user, secret, { expiresIn: "1d" });
|
|
80
95
|
const refreshToken = jwt.sign(user, secret, { expiresIn: "10d" });
|
|
81
96
|
const options: CookieOptions = {
|
|
82
|
-
httpOnly: true,
|
|
83
|
-
secure: true,
|
|
84
|
-
maxAge: 24 * 60 * 60 * 1000,
|
|
85
|
-
sameSite: "Strict",
|
|
86
|
-
path: "/",
|
|
97
|
+
httpOnly: true,
|
|
98
|
+
secure: true,
|
|
99
|
+
maxAge: 24 * 60 * 60 * 1000,
|
|
100
|
+
sameSite: "Strict",
|
|
101
|
+
path: "/",
|
|
87
102
|
};
|
|
88
103
|
|
|
89
104
|
return (
|
|
90
105
|
xl
|
|
91
106
|
.setCookie("accessToken", accessToken, options)
|
|
92
107
|
.setCookie("refreshToken", refreshToken, options)
|
|
93
|
-
.json({ msg: "
|
|
108
|
+
.json({ msg: "setted cookies" })
|
|
94
109
|
);
|
|
95
110
|
|
|
96
111
|
});
|
|
97
112
|
|
|
98
113
|
import {userRoute} from './route'
|
|
99
114
|
|
|
100
|
-
app.
|
|
115
|
+
app.route("/api/user",userRoute)
|
|
101
116
|
|
|
102
117
|
app.listen(3000);
|
package/package.json
CHANGED
package/src/ctx.ts
CHANGED
|
@@ -140,8 +140,7 @@ export default function createCtx(req: Request, server: Server, url: URL): Conte
|
|
|
140
140
|
return this;
|
|
141
141
|
},
|
|
142
142
|
|
|
143
|
-
getParams(props: string)
|
|
144
|
-
: string | Record<string, string> | {}
|
|
143
|
+
getParams(props: string) : string | Record<string, string> | {}
|
|
145
144
|
{
|
|
146
145
|
if (!parsedParams && req?.routePattern) {
|
|
147
146
|
parsedParams = extractDynamicParams(req?.routePattern, url?.pathname);
|
|
@@ -222,7 +221,7 @@ function extractDynamicParams(
|
|
|
222
221
|
}
|
|
223
222
|
|
|
224
223
|
async function parseBody(req: Request): Promise<ParseBodyResult> {
|
|
225
|
-
const contentType: string = req.headers.get("Content-Type")
|
|
224
|
+
const contentType: string = req.headers.get("Content-Type")!
|
|
226
225
|
|
|
227
226
|
if (!contentType) return {};
|
|
228
227
|
|
package/src/handleRequest.ts
CHANGED
|
@@ -6,16 +6,9 @@ export default async function handleRequest(req: Request, server: Server, url: U
|
|
|
6
6
|
|
|
7
7
|
// Try to find the route handler in the trie
|
|
8
8
|
const routeHandler: RouteHandlerT | undefined = diesel.trie.search(url.pathname, req.method);
|
|
9
|
-
// Early return if route or method is not found
|
|
10
|
-
|
|
11
|
-
if (!routeHandler || routeHandler.method !== req.method) {
|
|
12
|
-
const message = routeHandler ? "Method not allowed" : `Route not found for ${url.pathname}`;
|
|
13
|
-
const status = routeHandler ? 405 : 404;
|
|
14
|
-
return new Response(JSON.stringify({ message }), {status});
|
|
15
|
-
}
|
|
16
9
|
|
|
17
10
|
// If the route is dynamic, we only set routePattern if necessary
|
|
18
|
-
if (routeHandler
|
|
11
|
+
if (routeHandler?.isDynamic) req.routePattern = routeHandler.path;
|
|
19
12
|
|
|
20
13
|
// create the context which contains the methods Req,Res, many more
|
|
21
14
|
const ctx: ContextType = createCtx(req, server, url);
|
|
@@ -49,9 +42,7 @@ export default async function handleRequest(req: Request, server: Server, url: U
|
|
|
49
42
|
});
|
|
50
43
|
}
|
|
51
44
|
} else {
|
|
52
|
-
return ctx.status(400).json({
|
|
53
|
-
message: "Authentication required"
|
|
54
|
-
})
|
|
45
|
+
return ctx.status(400).json({ message: "Authentication required" })
|
|
55
46
|
}
|
|
56
47
|
}
|
|
57
48
|
}
|
|
@@ -75,6 +66,12 @@ export default async function handleRequest(req: Request, server: Server, url: U
|
|
|
75
66
|
|
|
76
67
|
}
|
|
77
68
|
|
|
69
|
+
if (!routeHandler || routeHandler.method !== req.method) {
|
|
70
|
+
const message = routeHandler ? "Method not allowed" : `Route not found for ${url.pathname}`;
|
|
71
|
+
const status = routeHandler ? 405 : 404;
|
|
72
|
+
return new Response(JSON.stringify({ message }), {status});
|
|
73
|
+
}
|
|
74
|
+
|
|
78
75
|
// Run preHandler hooks 2
|
|
79
76
|
if (diesel.hasPreHandlerHook && diesel.hooks.preHandler) {
|
|
80
77
|
const Hookresult = await diesel.hooks.preHandler(ctx);
|
|
@@ -95,9 +92,8 @@ export default async function handleRequest(req: Request, server: Server, url: U
|
|
|
95
92
|
if (hookResponse) return hookResponse
|
|
96
93
|
}
|
|
97
94
|
|
|
98
|
-
|
|
99
|
-
message:"No response from this handler"
|
|
100
|
-
})
|
|
95
|
+
// Default Response if Handler is Void
|
|
96
|
+
return result ?? ctx.status(204).json({ message:"No response from this handler" })
|
|
101
97
|
|
|
102
98
|
}
|
|
103
99
|
|
|
@@ -113,9 +109,8 @@ function applyCors(req: Request, ctx: ContextType, config: corsT = {}): Response
|
|
|
113
109
|
ctx.setHeader('Access-Control-Allow-Methods', allowedMethods)
|
|
114
110
|
ctx.setHeader("Access-Control-Allow-Headers", allowedHeaders);
|
|
115
111
|
ctx.setHeader("Access-Control-Allow-Credentials", allowedCredentials);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
112
|
+
|
|
113
|
+
if (exposedHeaders.length) ctx.setHeader("Access-Control-Expose-Headers", exposedHeaders);
|
|
119
114
|
|
|
120
115
|
if (allowedOrigins === '*') {
|
|
121
116
|
ctx.setHeader("Access-Control-Allow-Origin", "*")
|
package/src/main.ts
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
type Hooks,
|
|
14
14
|
type HttpMethod,
|
|
15
15
|
type listenCalllBackType,
|
|
16
|
-
type RouteNodeType
|
|
17
16
|
} from "./types.js";
|
|
18
17
|
import { Server } from "bun";
|
|
19
18
|
|
|
@@ -22,7 +21,7 @@ export default class Diesel {
|
|
|
22
21
|
// tempRoutes is used , so we can implement route method.
|
|
23
22
|
// although we have router class and register method for subrouting , still i wanna add a route method.
|
|
24
23
|
// in future we can also remove it, well see
|
|
25
|
-
tempRoutes:Map<string,any>
|
|
24
|
+
tempRoutes: Map<string, any>
|
|
26
25
|
globalMiddlewares: middlewareFunc[]
|
|
27
26
|
middlewares: Map<string, middlewareFunc[]>;
|
|
28
27
|
trie: Trie
|
|
@@ -95,10 +94,7 @@ export default class Diesel {
|
|
|
95
94
|
this.corsConfig = corsConfig
|
|
96
95
|
}
|
|
97
96
|
|
|
98
|
-
addHooks(
|
|
99
|
-
typeOfHook: HookType,
|
|
100
|
-
fnc: HookFunction | onError | onRequest
|
|
101
|
-
): void {
|
|
97
|
+
addHooks( typeOfHook: HookType, fnc: HookFunction | onError | onRequest ): void {
|
|
102
98
|
if (typeof typeOfHook !== 'string') {
|
|
103
99
|
throw new Error("hookName must be a string")
|
|
104
100
|
}
|
|
@@ -142,7 +138,6 @@ export default class Diesel {
|
|
|
142
138
|
this.hasMiddleware = true;
|
|
143
139
|
}
|
|
144
140
|
for (const [path, middlewares] of this.middlewares.entries()) {
|
|
145
|
-
|
|
146
141
|
if (middlewares.length > 0) {
|
|
147
142
|
this.hasMiddleware = true;
|
|
148
143
|
break;
|
|
@@ -156,14 +151,9 @@ export default class Diesel {
|
|
|
156
151
|
if (this.hooks.onSend) this.hasOnSendHook = true;
|
|
157
152
|
if (this.hooks.onError) this.hasOnError = true;
|
|
158
153
|
this.tempRoutes = new Map()
|
|
159
|
-
// console.log(this.trie)
|
|
160
154
|
}
|
|
161
155
|
|
|
162
|
-
listen(
|
|
163
|
-
port: number,
|
|
164
|
-
callback?: listenCalllBackType,
|
|
165
|
-
{ sslCert = null, sslKey = null }: any = {}
|
|
166
|
-
): Server | void {
|
|
156
|
+
listen( port: number, callback?: listenCalllBackType,{ sslCert = null, sslKey = null }: any = {} ): Server | void {
|
|
167
157
|
|
|
168
158
|
if (typeof Bun === 'undefined')
|
|
169
159
|
throw new Error(
|
|
@@ -222,78 +212,49 @@ export default class Diesel {
|
|
|
222
212
|
return server;
|
|
223
213
|
}
|
|
224
214
|
|
|
225
|
-
route(basePath:string,routerInstance:any): void {
|
|
215
|
+
route(basePath: string, routerInstance: any): void {
|
|
226
216
|
if (!basePath || typeof basePath !== 'string') throw new Error("Path must be a string");
|
|
227
217
|
|
|
228
|
-
const routes = Object.fromEntries(routerInstance.tempRoutes)
|
|
229
|
-
const routesArray = Object.entries(routes)
|
|
230
|
-
|
|
231
|
-
|
|
218
|
+
const routes = Object.fromEntries(routerInstance.tempRoutes);
|
|
219
|
+
const routesArray = Object.entries(routes);
|
|
220
|
+
|
|
221
|
+
routesArray.forEach(([path, args]) => {
|
|
232
222
|
const fullpath = `${basePath}${path}`;
|
|
233
223
|
if (!this.middlewares.has(fullpath)) {
|
|
234
224
|
this.middlewares.set(fullpath, []);
|
|
235
225
|
}
|
|
236
|
-
|
|
226
|
+
|
|
227
|
+
const middlewareHandlers: middlewareFunc[] = args.handlers.slice(0, -1);
|
|
237
228
|
middlewareHandlers.forEach((middleware: middlewareFunc) => {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
229
|
+
if (!this.middlewares.get(fullpath)?.includes(middleware)) {
|
|
230
|
+
this.middlewares.get(fullpath)?.push(middleware);
|
|
231
|
+
}
|
|
241
232
|
});
|
|
242
|
-
|
|
243
|
-
const
|
|
233
|
+
|
|
234
|
+
const handler = args.handlers[args.handlers.length - 1];
|
|
235
|
+
const method = args.method;
|
|
236
|
+
|
|
244
237
|
try {
|
|
245
|
-
this.trie.insert(fullpath, { handler: handler as handlerFunction, method
|
|
246
|
-
|
|
247
|
-
console.error(`Error inserting ${fullpath}:`, error);
|
|
238
|
+
this.trie.insert(fullpath, { handler: handler as handlerFunction, method });
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error(`Error inserting ${fullpath}:`, error);
|
|
248
241
|
}
|
|
249
|
-
}
|
|
250
|
-
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
routerInstance = null;
|
|
251
245
|
}
|
|
252
246
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
handlerInstance: any
|
|
256
|
-
): void {
|
|
247
|
+
|
|
248
|
+
register( pathPrefix: string, handlerInstance: any ): void {
|
|
257
249
|
this.route(pathPrefix, handlerInstance)
|
|
258
|
-
// if (typeof pathPrefix !== 'string') throw new Error("Path prefix must be a string");
|
|
259
|
-
// if (typeof handlerInstance !== 'object') throw new Error("Handler must be an object");
|
|
260
|
-
|
|
261
|
-
// const routeEntries: [string, RouteNodeType][] = Object.entries(handlerInstance.trie.root.children) as [string, RouteNodeType][];
|
|
262
|
-
|
|
263
|
-
// handlerInstance.trie.root.subMiddlewares.forEach((middleware: middlewareFunc[], path: string) => {
|
|
264
|
-
// if (!this.middlewares.has(pathPrefix + path)) {
|
|
265
|
-
// this.middlewares.set(pathPrefix + path, []);
|
|
266
|
-
// }
|
|
267
|
-
|
|
268
|
-
// middleware?.forEach((midl: middlewareFunc) => {
|
|
269
|
-
// if (!this.middlewares.get(pathPrefix + path)?.includes(midl)) {
|
|
270
|
-
// this.middlewares.get(pathPrefix + path)?.push(midl)
|
|
271
|
-
// }
|
|
272
|
-
// })
|
|
273
|
-
|
|
274
|
-
// });
|
|
275
|
-
// for (const [routeKey, routeNode] of routeEntries) {
|
|
276
|
-
// const fullpath = `${pathPrefix}${routeNode?.path}`;
|
|
277
|
-
// const routeHandler = routeNode.handler[0];
|
|
278
|
-
// const method = routeNode.method[0];
|
|
279
|
-
// try {
|
|
280
|
-
// this.trie.insert(fullpath, { handler: routeHandler as handlerFunction, method: method });
|
|
281
|
-
// } catch (error) {
|
|
282
|
-
// console.error(`Error inserting ${fullpath}:`, error);
|
|
283
|
-
// }
|
|
284
|
-
// }
|
|
285
250
|
}
|
|
286
251
|
|
|
287
|
-
addRoute(
|
|
288
|
-
method: HttpMethod,
|
|
289
|
-
path: string,
|
|
290
|
-
handlers: handlerFunction[]
|
|
291
|
-
): void {
|
|
252
|
+
addRoute( method: HttpMethod, path: string, handlers: handlerFunction[] ): void {
|
|
292
253
|
|
|
293
254
|
if (typeof path !== 'string') throw new Error("Path must be a string");
|
|
294
255
|
if (typeof method !== 'string') throw new Error("Method must be a string");
|
|
295
256
|
|
|
296
|
-
this.tempRoutes.set(path,{method,handlers})
|
|
257
|
+
this.tempRoutes.set(path, { method, handlers })
|
|
297
258
|
const middlewareHandlers = handlers.slice(0, -1) as middlewareFunc[]
|
|
298
259
|
const handler = handlers[handlers.length - 1];
|
|
299
260
|
|
|
@@ -317,15 +278,17 @@ export default class Diesel {
|
|
|
317
278
|
}
|
|
318
279
|
}
|
|
319
280
|
|
|
320
|
-
use(
|
|
321
|
-
pathORHandler?: string | middlewareFunc,
|
|
322
|
-
handler?: middlewareFunc
|
|
323
|
-
): void {
|
|
281
|
+
use( pathORHandler?: string | middlewareFunc, ...handlers: middlewareFunc[] ): void {
|
|
324
282
|
|
|
325
283
|
if (typeof pathORHandler === "function") {
|
|
326
284
|
if (!this.globalMiddlewares.includes(pathORHandler)) {
|
|
327
285
|
this.globalMiddlewares.push(pathORHandler);
|
|
328
286
|
}
|
|
287
|
+
handlers.forEach((handler:middlewareFunc) =>{
|
|
288
|
+
if (!this.globalMiddlewares.includes(handler)) {
|
|
289
|
+
this.globalMiddlewares.push(handler);
|
|
290
|
+
}
|
|
291
|
+
})
|
|
329
292
|
return
|
|
330
293
|
}
|
|
331
294
|
|
|
@@ -335,26 +298,22 @@ export default class Diesel {
|
|
|
335
298
|
this.middlewares.set(path, []);
|
|
336
299
|
}
|
|
337
300
|
|
|
338
|
-
if (
|
|
339
|
-
|
|
340
|
-
this.middlewares.get(path)?.
|
|
341
|
-
|
|
301
|
+
if (handlers) {
|
|
302
|
+
handlers.forEach((handler:middlewareFunc) =>{
|
|
303
|
+
if (!this.middlewares.get(path)?.includes(handler)) {
|
|
304
|
+
this.middlewares.get(path)?.push(handler);
|
|
305
|
+
}
|
|
306
|
+
})
|
|
342
307
|
}
|
|
343
308
|
}
|
|
344
309
|
|
|
345
310
|
|
|
346
|
-
get(
|
|
347
|
-
path: string,
|
|
348
|
-
...handlers: handlerFunction[]
|
|
349
|
-
): this {
|
|
311
|
+
get( path: string, ...handlers: handlerFunction[] ): this {
|
|
350
312
|
this.addRoute("GET", path, handlers);
|
|
351
313
|
return this
|
|
352
314
|
}
|
|
353
315
|
|
|
354
|
-
post(
|
|
355
|
-
path: string,
|
|
356
|
-
...handlers: handlerFunction[]
|
|
357
|
-
): this {
|
|
316
|
+
post( path: string, ...handlers: handlerFunction[] ): this {
|
|
358
317
|
this.addRoute("POST", path, handlers);
|
|
359
318
|
return this
|
|
360
319
|
}
|
|
@@ -364,18 +323,12 @@ export default class Diesel {
|
|
|
364
323
|
return this
|
|
365
324
|
}
|
|
366
325
|
|
|
367
|
-
patch(
|
|
368
|
-
path: string,
|
|
369
|
-
...handlers: handlerFunction[]
|
|
370
|
-
): this {
|
|
326
|
+
patch(path: string, ...handlers: handlerFunction[] ): this {
|
|
371
327
|
this.addRoute("PATCH", path, handlers);
|
|
372
328
|
return this
|
|
373
329
|
}
|
|
374
330
|
|
|
375
|
-
delete(
|
|
376
|
-
path: any,
|
|
377
|
-
...handlers: handlerFunction[]
|
|
378
|
-
): this {
|
|
331
|
+
delete( path: any, ...handlers: handlerFunction[] ): this {
|
|
379
332
|
this.addRoute("DELETE", path, handlers);
|
|
380
333
|
return this;
|
|
381
334
|
}
|
package/src/route.ts
CHANGED
|
@@ -6,27 +6,6 @@ class Router extends Diesel {
|
|
|
6
6
|
super();
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
// #addRoute(method:HttpMethod, path:string, handlers:handlerFunction[]) {
|
|
10
|
-
// if (!this.trie.root.subMiddlewares.has(path)) {
|
|
11
|
-
// this.trie.root.subMiddlewares.set(path,[])
|
|
12
|
-
// }
|
|
13
|
-
// const middlewareHandlers : handlerFunction[]= handlers.slice(0, -1);
|
|
14
|
-
|
|
15
|
-
// const currentMiddlewares = this.trie.root.subMiddlewares.get(path)
|
|
16
|
-
|
|
17
|
-
// middlewareHandlers.forEach((midl:handlerFunction) => {
|
|
18
|
-
// if (!currentMiddlewares?.includes(midl)) {
|
|
19
|
-
// currentMiddlewares?.push(midl)
|
|
20
|
-
// }
|
|
21
|
-
// })
|
|
22
|
-
|
|
23
|
-
// // if (!this.trie.root.subMiddlewares.get(path).includes(...middlewareHandlers)) {
|
|
24
|
-
// // this.trie.root.subMiddlewares.get(path).push(...middlewareHandlers)
|
|
25
|
-
// // }
|
|
26
|
-
|
|
27
|
-
// const handler : handlerFunction = handlers[handlers.length - 1];
|
|
28
|
-
// this.trie.insert(path, { handler, method });
|
|
29
|
-
// }
|
|
30
9
|
get(path:string, ...handlers:handlerFunction[]) {
|
|
31
10
|
this.addRoute("GET", path, handlers);
|
|
32
11
|
return this
|