@ooneex/app 0.15.3 → 0.16.1

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/dist/index.d.ts CHANGED
@@ -26,6 +26,7 @@ type AppConfigType = {
26
26
  };
27
27
  spa?: Bun.HTMLBundle;
28
28
  middlewares?: MiddlewareClassType[] | SocketMiddlewareClassType[];
29
+ generateRouteDoc?: boolean;
29
30
  };
30
31
  declare class App {
31
32
  private readonly config;
@@ -34,7 +35,7 @@ declare class App {
34
35
  run(): Promise<App>;
35
36
  }
36
37
  import { RouteConfigType } from "@ooneex/routing";
37
- declare const generateRouteDoc: (config: RouteConfigType) => Promise<void>;
38
+ declare const generateRouteDoc2: (config: RouteConfigType) => Promise<void>;
38
39
  import { RouteConfigType as RouteConfigType2 } from "@ooneex/routing";
39
40
  declare const generateRouteType: (config: RouteConfigType2) => Promise<void>;
40
- export { generateRouteType, generateRouteDoc, AppConfigType, App };
41
+ export { generateRouteType, generateRouteDoc2 as generateRouteDoc, AppConfigType, App };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{container as g}from"@ooneex/container";import{Exception as L}from"@ooneex/exception";import{HttpStatus as w}from"@ooneex/http-status";import{TerminalLogger as Z}from"@ooneex/logger";import{router as B}from"@ooneex/routing";import{AssertAppEnv as ee,AssertHostname as te,AssertPort as re}from"@ooneex/validation/constraints";import{Environment as k}from"@ooneex/app-env";import{container as y}from"@ooneex/container";import{Exception as A}from"@ooneex/exception";import{HttpRequest as O}from"@ooneex/http-request";import{HttpResponse as V}from"@ooneex/http-response";import{HttpStatus as m}from"@ooneex/http-status";import{LogsEntity as j}from"@ooneex/logger";import{Role as F}from"@ooneex/role";import{type as U}from"@ooneex/validation";var C=(e,r)=>{if(e!==null&&typeof e==="object"&&"validate"in e&&typeof e.validate==="function"){let o=e.validate(r);if(!o.isValid)return o.message||"Validation failed"}else if(typeof e==="function"){let o=e(r);if(o instanceof U.errors)return o.summary}return null},S=async(e)=>{let{req:r,server:o}=e,t=o.requestIP(r)?.address??"unknown",n=new V,a={},i=null;if(r.headers.get("content-type")?.includes("application/json"))try{a=await r.json()}catch(d){}else try{i=await r.formData()}catch(d){}let p=new O(r,{params:r.params,payload:a,form:i,ip:t});return{logger:y.get("logger"),analytics:y.get("analytics"),cache:y.get("cache"),storage:y.get("storage"),mailer:y.get("mailer"),database:y.get("database"),app:{env:y.get("app.env")},response:n,request:p,params:p.params,payload:p.payload,queries:p.queries,method:p.method,header:p.header,files:p.files,ip:p.ip,host:p.host,language:p.language,user:null}},E=async(e,r,o)=>{if(r.params)for(let[s,t]of Object.entries(r.params)){let n=C(t,e.params[s]);if(n)return{message:`Invalid parameter "${s}": ${n}`,status:m.Code.BadRequest}}if(r.queries){let s=C(r.queries,e.queries);if(s)return{message:`Invalid query parameters: ${s}`,status:m.Code.BadRequest}}if(r.payload){let s=C(r.payload,e.payload);if(s)return{message:`Invalid payload: ${s}`,status:m.Code.BadRequest}}if(r.env&&r.env.length>0&&!r.env.includes(o))return{message:`Route "${r.name}" is not available in "${o}" environment`,status:m.Code.NotAcceptable};if(r.ip&&r.ip.length>0&&(!e.ip||!r.ip.includes(e.ip)))return{message:`Route "${r.name}" is not available for IP "${e.ip}"`,status:m.Code.NotAcceptable};if(r.host&&r.host.length>0&&!r.host.includes(e.host))return{message:`Route "${r.name}" is not available for host "${e.host}"`,status:m.Code.NotAcceptable};if(r.roles&&r.roles.length>0){if(!e.user||!e.user.roles||e.user.roles.length===0)return{message:`Route "${r.name}" requires authentication`,status:m.Code.Forbidden};let s=new F;if(!r.roles.some((n)=>e.user?.roles.some((a)=>s.hasRole(a,n))))return{message:`Route "${r.name}" is not accessible for user roles`,status:m.Code.NotAcceptable}}if(r.permission){let s=y.get(r.permission);if(s.setUserPermissions(e.user).build(),!await s.check())return{message:`Route "${r.name}" permission denied`,status:m.Code.Forbidden}}return null},I=(e,r)=>{if(e.response){let o=C(e.response,r);if(o)return{message:`Invalid response: ${o}`,status:m.Code.NotAcceptable}}return null},v=(e,r,o,s)=>{return e.response.exception(r,{status:o}).get(s)},f=(e,r,o)=>{let s=e.logger;if(!s)return;let t=new j;if(t.date=new Date,t.status=r,t.method=e.method,t.path=o,t.params=e.params,t.payload=e.payload,t.queries=e.queries,e.ip)t.ip=e.ip;let n=e.header.get("User-Agent");if(n)t.userAgent=n;let a=e.header.getReferer();if(a)t.referer=a;if(e.user?.id)t.userId=e.user.id;if(e.user?.email)t.email=e.user.email;if(e.user?.lastName)t.lastName=e.user.lastName;if(e.user?.firstName)t.firstName=e.user.firstName;let i=`${e.method} ${o}`;if(r>=500)s.error(i,t);else if(r>=400)s.warn(i,t);else if(r>=300)s.info(i,t);else s.success(i,t)},_=async(e,r)=>{try{return[await e.index(r),null]}catch(o){if(o instanceof A)return[null,{message:o.message,status:o.status}];if(o instanceof Error)return[null,{message:o.message,status:m.Code.InternalServerError}];return[null,{message:"An unknown error occurred",status:m.Code.InternalServerError}]}},J=async(e,r)=>{let o=e.app.env.env||k.PRODUCTION,s=await E(e,r,o);if(s)return f(e,s.status,r.path),v(e,s.message,s.status,o);let t=y.get(r.controller),[n,a]=await _(t,e);if(a)return f(e,a.status,r.path),v(e,a.message,a.status,o);let i=I(r,n.getData());if(i)return f(e,i.status,r.path),v(e,i.message,i.status,o);let l=n.get(o);return f(e,l.status,r.path),l},W=async(e,r)=>{let o=e;for(let s of r)o=await y.get(s).handle(o);return o},P=(e,r=[])=>{let o={};for(let[s,t]of e){let n={};for(let a of t)n[a.method]=async(i,l)=>{let p=await S({req:i,server:l});try{p=await W(p,r)}catch(c){let d=p.app.env.env||k.PRODUCTION,u=c instanceof A?c.status:m.Code.InternalServerError;return f(p,u,a.path),v(p,c.message,u,d)}return J(p,a)};o[s]=n}return o};var q=(e,r)=>({error:(o,s)=>{e.forEach((t)=>{let n=r.get(t);if(n)n.error(o,s)})},warn:(o,s)=>{e.forEach((t)=>{let n=r.get(t);if(n)n.warn(o,s)})},info:(o,s)=>{e.forEach((t)=>{let n=r.get(t);if(n)n.info(o,s)})},debug:(o,s)=>{e.forEach((t)=>{let n=r.get(t);if(n)n.debug(o,s)})},log:(o,s)=>{e.forEach((t)=>{let n=r.get(t);if(n)n.log(o,s)})},success:(o,s)=>{e.forEach((t)=>{let n=r.get(t);if(n)n.success(o,s)})}});import{Environment as G}from"@ooneex/app-env";import{container as T}from"@ooneex/container";import{Exception as x}from"@ooneex/exception";import{HttpStatus as b}from"@ooneex/http-status";import{LogsEntity as K}from"@ooneex/logger";import{random as z}from"@ooneex/utils";var M=(e)=>{let r={};for(let[o,s]of e)r[o]=async(t,n)=>{let a=await S({req:t,server:n}),i=z.nanoid(30);T.addConstant(i,{context:a,route:s}),n.upgrade(t,{data:{id:i}});return};return r},Q=async(e,r)=>{let o=e;for(let s of r)o=await T.get(s).handle(o);return o},h=(e,r,o)=>{return e.response.exception(r,{status:o}),e.channel.send(e.response)},R=(e,r,o)=>{let s=e.logger;if(!s)return;let t=new K;if(t.date=new Date,t.status=r,t.method="GET",t.path=o,t.params=e.params,t.payload=e.payload,t.queries=e.queries,e.ip)t.ip=e.ip;let n=e.header.get("User-Agent");if(n)t.userAgent=n;let a=e.header.getReferer();if(a)t.referer=a;if(e.user?.id)t.userId=e.user.id;if(e.user?.email)t.email=e.user.email;if(e.user?.lastName)t.lastName=e.user.lastName;if(e.user?.firstName)t.firstName=e.user.firstName;let i=`WS ${o}`;if(r>=500)s.error(i,t);else if(r>=400)s.warn(i,t);else if(r>=300)s.info(i,t);else s.success(i,t)},N=async(e,r,o,s=[])=>{let{context:t,route:n}=T.getConstant(r.data.id),a=t.app.env.env||G.PRODUCTION;t.channel={send:async(d)=>{let u=await d.get(a).json();r.send(JSON.stringify(u))},close:(d,u)=>{r.close(d,u)},subscribe:async()=>{r.subscribe(n.name)},isSubscribed:()=>{return r.isSubscribed(n.name)},unsubscribe:async()=>{r.unsubscribe(n.name)},publish:async(d)=>{let u=await d.get(a).json();o.publish(n.name,u)}};let i=JSON.parse(e);t.queries=i.queries,t.payload=i.payload,t.language=i.language;try{t=await Q(t,s)}catch(d){let u=d instanceof x?d.status:b.Code.InternalServerError;return R(t,u,n.path),h(t,d.message,u)}let l=await E(t,n,a);if(l)return R(t,l.status,n.path),h(t,l.message,l.status);let p=T.get(n.controller);try{t.response=await p.index(t)}catch(d){let u=d instanceof x?d.status:b.Code.InternalServerError,$=d instanceof Error?d.message:"An unknown error occurred";return R(t,u,n.path),h(t,$,u)}let c=I(n,t.response.getData());if(c)return R(t,c.status,n.path),h(t,c.message,c.status);return R(t,b.Code.OK,n.path),t.channel.send(t.response)};import{join as X}from"path";import{HttpStatus as Y}from"@ooneex/http-status";var H=async(e)=>{let{req:r,cwd:o}=e,s=new URL(r.url).pathname,t=X(o,s),n=Bun.file(t);if(await n.exists())return new Response(n);return new Response("File not found",{status:Y.Code.NotFound})};class D{config;constructor(e){this.config=e;let{loggers:r,cronJobs:o,analytics:s,cache:t,storage:n,database:a,env:i,mailer:l}=this.config;if(r.forEach((p)=>{g.get(p).init()}),g.addConstant("logger",q(r,g)),o?.forEach((p)=>{g.get(p).start()}),i)g.addConstant("app.env",i);if(s)g.addAlias("analytics",s);if(t)g.addAlias("cache",t);if(n)g.addAlias("storage",n);if(l)g.addAlias("mailer",l);if(a)g.addConstant("database",a)}async init(){let e=Bun.env.APP_ENV,r=Bun.env.PORT?Number.parseInt(Bun.env.PORT,10):3000,o=Bun.env.HOST_NAME??"",t=new ee().validate(e);if(!t.isValid)throw new L(`Invalid APP_ENV: ${t.message}`,{status:w.Code.InternalServerError,data:{appEnv:e}});let a=new re().validate(r);if(!a.isValid)throw new L(`Invalid PORT: ${a.message}`,{status:w.Code.InternalServerError,data:{port:Bun.env.PORT}});let l=new te().validate(o);if(!l.isValid)throw new L(`Invalid HOST_NAME: ${l.message}`,{status:w.Code.InternalServerError,data:{hostname:o}});return this}async run(){let e=new Z;try{await this.init()}catch(p){e.error(p),process.exit(1)}let r=g.getConstant("app.env"),o=Bun.env.HOST_NAME||"0.0.0.0",{directories:s}=this.config,t=s.static,{middlewares:n=[]}=this.config,a={...P(B.getHttpRoutes(),n),...M(B.getSocketRoutes())};if(t){let p=t.replace(/^\/+|\/+$/g,"");a[`/${p}/*`]={GET:(c)=>H({req:c,cwd:s.cwd})}}let i=Bun.env.PORT?Number.parseInt(Bun.env.PORT,10):3000,l=Bun.serve({port:i,hostname:o,development:r.isLocal,routes:{...a,"/*":this.config.spa||new Response("Not Found",{status:w.Code.NotFound})},websocket:{perMessageDeflate:!0,async message(p,c){await N(c,p,l,n)},async close(p){g.removeConstant(p.data.id)}}});if(o=l.hostname||"0.0.0.0",o==="0.0.0.0")o="localhost";return e.info(`Server running at ${l.protocol}://${o}:${l.port}`),this}}import{join as oe}from"path";import{routeConfigToJsonDoc as se}from"@ooneex/routing";var ne=async(e)=>{let o=se(e),s=`${e.name}.json`,t=oe(process.cwd(),"docs/routes",s);await Bun.write(t,JSON.stringify(o,null,2))};import{join as ae}from"path";import{routeConfigToTypeString as ie}from"@ooneex/routing";import{toPascalCase as pe}from"@ooneex/utils";var le=async(e)=>{let o=ie(e),s=`${e.name}.ts`,t=ae(process.cwd(),"src/types/routes",s),a=`export type ${pe(e.name)}RouteType = ${o};
3
- `;await Bun.write(t,a)};export{le as generateRouteType,ne as generateRouteDoc,D as App};
2
+ import{container as g}from"@ooneex/container";import{Exception as q}from"@ooneex/exception";import{HttpStatus as I}from"@ooneex/http-status";import{TerminalLogger as ye}from"@ooneex/logger";import{router as A}from"@ooneex/routing";import{AssertAppEnv as Re,AssertHostname as Ce,AssertPort as Te}from"@ooneex/validation/constraints";import{join as K}from"path";import{routeConfigToJsonDoc as z}from"@ooneex/routing";var b=async(e)=>{let r=z(e),s=`${e.name}.json`,t=K(process.cwd(),"docs/routes",s);await Bun.write(t,JSON.stringify(r,null,2))};import{join as M}from"path";import{routeConfigToFetcherString as Q}from"@ooneex/routing";import{toPascalCase as X}from"@ooneex/utils";var N=async(e)=>{let o=M("src","fetchers","routes"),r=Q(e),s=`${X(e.name)}Fetcher.ts`,t=M(process.cwd(),o,s);await Bun.write(t,r)};import{join as H}from"path";import{routeConfigToHookString as Y}from"@ooneex/routing";import{toPascalCase as Z}from"@ooneex/utils";var $=async(e)=>{let o=H("src","hooks","routes"),r=Y(e),s=`use${Z(e.name)}.ts`,t=H(process.cwd(),o,s);await Bun.write(t,r)};import{join as D}from"path";import{routeConfigToSocketString as ee}from"@ooneex/routing";import{toPascalCase as te}from"@ooneex/utils";var B=async(e)=>{let o=D("src","fetchers","routes"),r=ee(e),s=`${te(e.name)}Socket.ts`,t=D(process.cwd(),o,s);await Bun.write(t,r)};import{Environment as O}from"@ooneex/app-env";import{container as y}from"@ooneex/container";import{Exception as V}from"@ooneex/exception";import{HttpRequest as oe}from"@ooneex/http-request";import{HttpResponse as re}from"@ooneex/http-response";import{HttpStatus as d}from"@ooneex/http-status";import{LogsEntity as se}from"@ooneex/logger";import{Role as ne}from"@ooneex/role";import{type as ae}from"@ooneex/validation";var w=(e,o)=>{if(e!==null&&typeof e==="object"&&"validate"in e&&typeof e.validate==="function"){let r=e.validate(o);if(!r.isValid)return r.message||"Validation failed"}else if(typeof e==="function"){let r=e(o);if(r instanceof ae.errors)return r.summary}return null},k=async(e)=>{let{req:o,server:r,route:s}=e,n=r.requestIP(o)?.address??"unknown",a=new re,i={},c=null;if(o.headers.get("content-type")?.includes("application/json"))try{i=await o.json()}catch(l){}else try{c=await o.formData()}catch(l){}let p=new oe(o,{params:o.params,payload:i,form:c,ip:n});return{logger:y.get("logger"),analytics:y.get("analytics"),cache:y.get("cache"),storage:y.get("storage"),mailer:y.get("mailer"),database:y.get("database"),route:{name:s.name,path:s.path,method:s.method,description:s.description??""},app:{env:y.get("app.env")},response:a,request:p,params:p.params,payload:p.payload,queries:p.queries,method:p.method,header:p.header,files:p.files,ip:p.ip,host:p.host,language:p.language,user:null}},L=async(e,o,r)=>{if(o.params)for(let[s,t]of Object.entries(o.params)){let n=w(t,e.params[s]);if(n)return{message:`Invalid parameter "${s}": ${n}`,status:d.Code.BadRequest}}if(o.queries){let s=w(o.queries,e.queries);if(s)return{message:`Invalid query parameters: ${s}`,status:d.Code.BadRequest}}if(o.payload){let s=w(o.payload,e.payload);if(s)return{message:`Invalid payload: ${s}`,status:d.Code.BadRequest}}if(o.env&&o.env.length>0&&!o.env.includes(r))return{message:`Route "${o.name}" is not available in "${r}" environment`,status:d.Code.NotAcceptable};if(o.ip&&o.ip.length>0&&(!e.ip||!o.ip.includes(e.ip)))return{message:`Route "${o.name}" is not available for IP "${e.ip}"`,status:d.Code.NotAcceptable};if(o.host&&o.host.length>0&&!o.host.includes(e.host))return{message:`Route "${o.name}" is not available for host "${e.host}"`,status:d.Code.NotAcceptable};if(o.roles&&o.roles.length>0){if(!e.user||!e.user.roles||e.user.roles.length===0)return{message:`Route "${o.name}" requires authentication`,status:d.Code.Forbidden};let s=new ne;if(!o.roles.some((n)=>e.user?.roles.some((a)=>s.hasRole(a,n))))return{message:`Route "${o.name}" is not accessible for user roles`,status:d.Code.NotAcceptable}}if(o.permission){let s=y.get(o.permission);if(s.setUserPermissions(e.user).build(),!await s.check())return{message:`Route "${o.name}" permission denied`,status:d.Code.Forbidden}}return null},P=(e,o)=>{if(e.response){let r=w(e.response,o);if(r)return{message:`Invalid response: ${r}`,status:d.Code.NotAcceptable}}return null},S=(e,o,r,s)=>{return e.response.exception(o,{status:r}).get(s)},T=(e,o,r)=>{let s=e.logger;if(!s)return;let t=new se;if(t.date=new Date,t.status=o,t.method=e.method,t.path=r,t.params=e.params,t.payload=e.payload,t.queries=e.queries,e.ip)t.ip=e.ip;let n=e.header.get("User-Agent");if(n)t.userAgent=n;let a=e.header.getReferer();if(a)t.referer=a;if(e.user?.id)t.userId=e.user.id;if(e.user?.email)t.email=e.user.email;if(e.user?.lastName)t.lastName=e.user.lastName;if(e.user?.firstName)t.firstName=e.user.firstName;let i=`${e.method} ${r}`;if(o>=500)s.error(i,t);else if(o>=400)s.warn(i,t);else if(o>=300)s.info(i,t);else s.success(i,t)},ie=async(e,o)=>{try{return[await e.index(o),null]}catch(r){if(r instanceof V)return[null,{message:r.message,status:r.status}];if(r instanceof Error)return[null,{message:r.message,status:d.Code.InternalServerError}];return[null,{message:"An unknown error occurred",status:d.Code.InternalServerError}]}},pe=async(e,o)=>{let r=e.app.env.env||O.PRODUCTION,s=await L(e,o,r);if(s)return T(e,s.status,o.path),S(e,s.message,s.status,r);let t=y.get(o.controller),[n,a]=await ie(t,e);if(a)return T(e,a.status,o.path),S(e,a.message,a.status,r);let i=P(o,n.getData());if(i)return T(e,i.status,o.path),S(e,i.message,i.status,r);let c=n.get(r);return T(e,c.status,o.path),c},ce=async(e,o)=>{let r=e;for(let s of o)r=await y.get(s).handler(r);return r},j=(e,o=[])=>{let r={};for(let[s,t]of e){let n={};for(let a of t)n[a.method]=async(i,c)=>{let m=await k({req:i,server:c,route:a});try{m=await ce(m,o)}catch(p){let u=m.app.env.env||O.PRODUCTION,l=p instanceof V?p.status:d.Code.InternalServerError;return T(m,l,a.path),S(m,p.message,l,u)}return pe(m,a)};r[s]=n}return r};var F=(e,o)=>({error:(r,s)=>{e.forEach((t)=>{let n=o.get(t);if(n)n.error(r,s)})},warn:(r,s)=>{e.forEach((t)=>{let n=o.get(t);if(n)n.warn(r,s)})},info:(r,s)=>{e.forEach((t)=>{let n=o.get(t);if(n)n.info(r,s)})},debug:(r,s)=>{e.forEach((t)=>{let n=o.get(t);if(n)n.debug(r,s)})},log:(r,s)=>{e.forEach((t)=>{let n=o.get(t);if(n)n.log(r,s)})},success:(r,s)=>{e.forEach((t)=>{let n=o.get(t);if(n)n.success(r,s)})}});import{Environment as ue}from"@ooneex/app-env";import{container as v}from"@ooneex/container";import{Exception as U}from"@ooneex/exception";import{HttpStatus as x}from"@ooneex/http-status";import{LogsEntity as le}from"@ooneex/logger";import{random as me}from"@ooneex/utils";var _=(e)=>{let o={};for(let[r,s]of e)o[r]=async(t,n)=>{let a=await k({req:t,server:n,route:s}),i=me.nanoid(30);v.addConstant(i,{context:a,route:s}),n.upgrade(t,{data:{id:i}});return};return o},de=async(e,o)=>{let r=e;for(let s of o)r=await v.get(s).handler(r);return r},E=(e,o,r)=>{return e.response.exception(o,{status:r}),e.channel.send(e.response)},h=(e,o,r)=>{let s=e.logger;if(!s)return;let t=new le;if(t.date=new Date,t.status=o,t.method="GET",t.path=r,t.params=e.params,t.payload=e.payload,t.queries=e.queries,e.ip)t.ip=e.ip;let n=e.header.get("User-Agent");if(n)t.userAgent=n;let a=e.header.getReferer();if(a)t.referer=a;if(e.user?.id)t.userId=e.user.id;if(e.user?.email)t.email=e.user.email;if(e.user?.lastName)t.lastName=e.user.lastName;if(e.user?.firstName)t.firstName=e.user.firstName;let i=`WS ${r}`;if(o>=500)s.error(i,t);else if(o>=400)s.warn(i,t);else if(o>=300)s.info(i,t);else s.success(i,t)},G=async(e,o,r,s=[])=>{let{context:t,route:n}=v.getConstant(o.data.id),a=t.app.env.env||ue.PRODUCTION;t.channel={send:async(u)=>{let l=await u.get(a).json();o.send(JSON.stringify(l))},close:(u,l)=>{o.close(u,l)},subscribe:async()=>{o.subscribe(n.name)},isSubscribed:()=>{return o.isSubscribed(n.name)},unsubscribe:async()=>{o.unsubscribe(n.name)},publish:async(u)=>{let l=await u.get(a).json();r.publish(n.name,l)}};let i=JSON.parse(e);t.queries=i.queries,t.payload=i.payload,t.language=i.language;try{t=await de(t,s)}catch(u){let l=u instanceof U?u.status:x.Code.InternalServerError;return h(t,l,n.path),E(t,u.message,l)}let c=await L(t,n,a);if(c)return h(t,c.status,n.path),E(t,c.message,c.status);let m=v.get(n.controller);try{t.response=await m.index(t)}catch(u){let l=u instanceof U?u.status:x.Code.InternalServerError,C=u instanceof Error?u.message:"An unknown error occurred";return h(t,l,n.path),E(t,C,l)}let p=P(n,t.response.getData());if(p)return h(t,p.status,n.path),E(t,p.message,p.status);return h(t,x.Code.OK,n.path),t.channel.send(t.response)};import{join as ge}from"path";import{HttpStatus as fe}from"@ooneex/http-status";var J=async(e)=>{let{req:o,cwd:r}=e,s=new URL(o.url).pathname,t=ge(r,s),n=Bun.file(t);if(await n.exists())return new Response(n);return new Response("File not found",{status:fe.Code.NotFound})};class W{config;constructor(e){this.config=e;let{loggers:o,cronJobs:r,analytics:s,cache:t,storage:n,database:a,env:i,mailer:c}=this.config;if(o.forEach((m)=>{g.get(m).init()}),g.addConstant("logger",F(o,g)),r?.forEach((m)=>{g.get(m).start()}),i)g.addConstant("app.env",i);if(s)g.addAlias("analytics",s);if(t)g.addAlias("cache",t);if(n)g.addAlias("storage",n);if(c)g.addAlias("mailer",c);if(a)g.addConstant("database",a)}async init(){let e=Bun.env.APP_ENV,o=Bun.env.PORT?Number.parseInt(Bun.env.PORT,10):3000,r=Bun.env.HOST_NAME??"",t=new Re().validate(e);if(!t.isValid)throw new q(`Invalid APP_ENV: ${t.message}`,{status:I.Code.InternalServerError,data:{appEnv:e}});let a=new Te().validate(o);if(!a.isValid)throw new q(`Invalid PORT: ${a.message}`,{status:I.Code.InternalServerError,data:{port:Bun.env.PORT}});let c=new Ce().validate(r);if(!c.isValid)throw new q(`Invalid HOST_NAME: ${c.message}`,{status:I.Code.InternalServerError,data:{hostname:r}});return this}async run(){let e=new ye;try{await this.init()}catch(R){e.error(R),process.exit(1)}let o=g.getConstant("app.env"),r=Bun.env.HOST_NAME||"0.0.0.0",{directories:s}=this.config,t=s.static,{middlewares:n=[]}=this.config,a={...j(A.getHttpRoutes(),n),..._(A.getSocketRoutes())};if(t){let R=t.replace(/^\/+|\/+$/g,"");a[`/${R}/*`]={GET:(f)=>J({req:f,cwd:s.cwd})}}let i=Bun.env.PORT?Number.parseInt(Bun.env.PORT,10):3000,c=Bun.serve({port:i,hostname:r,development:o.isLocal,routes:{...a,"/*":this.config.spa||new Response("Not Found",{status:I.Code.NotFound})},websocket:{perMessageDeflate:!0,async message(R,f){await G(f,R,c,n)},async close(R){g.removeConstant(R.data.id)}}});if(r=c.hostname||"0.0.0.0",r==="0.0.0.0")r="localhost";e.info(`Server running at ${c.protocol}://${r}:${c.port}`);let m=A.getRoutes(),p=0,u=0,l=0,C=0;for(let R of m.values())for(let f of R){if(this.config.generateRouteDoc)await b(f),p++;if(f.generate?.fetcher)if(f.isSocket)await B(f),l++;else await N(f),u++;if(f.generate?.queryHook)await $(f),C++}if(this.config.generateRouteDoc&&p>0)e.info(`Generated ${p} route doc${p>1?"s":""}`);if(u>0)e.info(`Generated ${u} route fetcher${u>1?"s":""}`);if(l>0)e.info(`Generated ${l} route socket${l>1?"s":""}`);if(C>0)e.info(`Generated ${C} route hook${C>1?"s":""}`);return this}}import{join as he}from"path";import{routeConfigToTypeString as ve}from"@ooneex/routing";import{toPascalCase as we}from"@ooneex/utils";var Se=async(e)=>{let r=ve(e),s=`${e.name}.ts`,t=he(process.cwd(),"src/types/routes",s),a=`export type ${we(e.name)}RouteType = ${r};
3
+ `;await Bun.write(t,a)};export{Se as generateRouteType,b as generateRouteDoc,W as App};
4
4
 
5
- //# debugId=21497BFA435EA40C64756E2164756E21
5
+ //# debugId=F30567500E6C026B64756E2164756E21
package/dist/index.js.map CHANGED
@@ -1,16 +1,19 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["src/App.ts", "src/httpRouteUtils.ts", "src/logger.ts", "src/socketRouteUtils.ts", "src/staticHandler.ts", "src/generateRouteDoc.ts", "src/generateRouteType.ts"],
3
+ "sources": ["src/App.ts", "src/generateRouteDoc.ts", "src/generateRouteFetcher.ts", "src/generateRouteHook.ts", "src/generateRouteSocket.ts", "src/httpRouteUtils.ts", "src/logger.ts", "src/socketRouteUtils.ts", "src/staticHandler.ts", "src/generateRouteType.ts"],
4
4
  "sourcesContent": [
5
- "import type { IAppEnv } from \"@ooneex/app-env\";\nimport { container } from \"@ooneex/container\";\nimport type { ICron } from \"@ooneex/cron\";\nimport { Exception, type IException } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\nimport { type ILogger, type LogsEntity, TerminalLogger } from \"@ooneex/logger\";\nimport type { MiddlewareClassType, SocketMiddlewareClassType } from \"@ooneex/middleware\";\nimport { router } from \"@ooneex/routing\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { AssertAppEnv, AssertHostname, AssertPort } from \"@ooneex/validation/constraints\";\nimport type { BunRequest, ServerWebSocket } from \"bun\";\nimport { formatHttpRoutes } from \"./httpRouteUtils\";\nimport { logger as loggerFunc } from \"./logger\";\nimport { formatSocketRoutes, socketRouteHandler } from \"./socketRouteUtils\";\nimport { staticHandler } from \"./staticHandler\";\nimport type { AppConfigType } from \"./types\";\n\nexport class App {\n constructor(private readonly config: AppConfigType) {\n const { loggers, cronJobs, analytics, cache, storage, database, env, mailer } = this.config;\n\n loggers.forEach((log) => {\n const logger = container.get<ILogger<Record<string, ScalarType>> | ILogger<LogsEntity>>(log);\n logger.init();\n });\n container.addConstant(\"logger\", loggerFunc(loggers, container));\n\n cronJobs?.forEach((cronJob) => {\n const cron = container.get<ICron>(cronJob);\n cron.start();\n });\n\n if (env) {\n container.addConstant(\"app.env\", env);\n }\n\n if (analytics) {\n container.addAlias(\"analytics\", analytics);\n }\n\n if (cache) {\n container.addAlias(\"cache\", cache);\n }\n\n if (storage) {\n container.addAlias(\"storage\", storage);\n }\n\n if (mailer) {\n container.addAlias(\"mailer\", mailer);\n }\n\n if (database) {\n container.addConstant(\"database\", database);\n }\n }\n\n public async init(): Promise<App> {\n const appEnv = Bun.env.APP_ENV;\n const port = Bun.env.PORT ? Number.parseInt(Bun.env.PORT, 10) : 3000;\n const hostname = Bun.env.HOST_NAME ?? \"\";\n\n const appEnvValidator = new AssertAppEnv();\n const appEnvResult = appEnvValidator.validate(appEnv);\n if (!appEnvResult.isValid) {\n throw new Exception(`Invalid APP_ENV: ${appEnvResult.message}`, {\n status: HttpStatus.Code.InternalServerError,\n data: { appEnv },\n });\n }\n\n const portValidator = new AssertPort();\n const portResult = portValidator.validate(port);\n if (!portResult.isValid) {\n throw new Exception(`Invalid PORT: ${portResult.message}`, {\n status: HttpStatus.Code.InternalServerError,\n data: { port: Bun.env.PORT },\n });\n }\n\n const hostnameValidator = new AssertHostname();\n const hostnameResult = hostnameValidator.validate(hostname);\n if (!hostnameResult.isValid) {\n throw new Exception(`Invalid HOST_NAME: ${hostnameResult.message}`, {\n status: HttpStatus.Code.InternalServerError,\n data: { hostname },\n });\n }\n\n return this;\n }\n\n public async run(): Promise<App> {\n const logger = new TerminalLogger();\n\n try {\n await this.init();\n } catch (error: unknown) {\n logger.error(error as IException);\n process.exit(1);\n }\n\n const env = container.getConstant<IAppEnv>(\"app.env\");\n let hostname = Bun.env.HOST_NAME || \"0.0.0.0\";\n const { directories } = this.config;\n const staticDir = directories.static;\n\n const { middlewares = [] } = this.config;\n\n const routes = {\n ...formatHttpRoutes(router.getHttpRoutes(), middlewares as MiddlewareClassType[]),\n ...formatSocketRoutes(router.getSocketRoutes()),\n };\n\n if (staticDir) {\n const trimmedStaticDir = staticDir.replace(/^\\/+|\\/+$/g, \"\");\n routes[`/${trimmedStaticDir}/*`] = {\n GET: (req: BunRequest) =>\n staticHandler({\n req,\n cwd: directories.cwd,\n }),\n };\n }\n\n const port = Bun.env.PORT ? Number.parseInt(Bun.env.PORT, 10) : 3000;\n\n const server = Bun.serve({\n port,\n hostname,\n development: env.isLocal,\n routes: {\n ...routes,\n \"/*\": this.config.spa || new Response(\"Not Found\", { status: HttpStatus.Code.NotFound }),\n },\n websocket: {\n perMessageDeflate: true,\n async message(ws: ServerWebSocket<{ id: string }>, message: string) {\n await socketRouteHandler(message, ws, server, middlewares as SocketMiddlewareClassType[]);\n },\n async close(ws: ServerWebSocket<{ id: string }>) {\n container.removeConstant(ws.data.id);\n },\n },\n });\n\n hostname = server.hostname || \"0.0.0.0\";\n\n if (hostname === \"0.0.0.0\") {\n hostname = \"localhost\";\n }\n\n logger.info(`Server running at ${server.protocol}://${hostname}:${server.port}`);\n\n return this;\n }\n}\n",
6
- "import { Environment } from \"@ooneex/app-env\";\nimport { container } from \"@ooneex/container\";\nimport type { ContextType } from \"@ooneex/controller\";\nimport { Exception } from \"@ooneex/exception\";\nimport { HttpRequest } from \"@ooneex/http-request\";\nimport { HttpResponse, type IResponse } from \"@ooneex/http-response\";\nimport { HttpStatus, type StatusCodeType } from \"@ooneex/http-status\";\nimport { LogsEntity } from \"@ooneex/logger\";\nimport type { IMiddleware, MiddlewareClassType } from \"@ooneex/middleware\";\nimport { Role } from \"@ooneex/role\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { type AssertType, type IAssert, type } from \"@ooneex/validation\";\nimport type { BunRequest, Server } from \"bun\";\n\ntype HttpRouteHandler = (req: BunRequest, server: Server<unknown>) => Promise<Response>;\ntype HttpMethodHandlers = Partial<Record<string, HttpRouteHandler | Response>>;\ntype HttpRoutesMap = Record<string, HttpMethodHandlers>;\n\nexport const validateConstraint = (constraint: AssertType | IAssert, value: unknown): string | null => {\n if (\n constraint !== null &&\n typeof constraint === \"object\" &&\n \"validate\" in constraint &&\n typeof constraint.validate === \"function\"\n ) {\n const result = constraint.validate(value);\n if (!result.isValid) {\n return result.message || \"Validation failed\";\n }\n } else if (typeof constraint === \"function\") {\n const result = constraint(value);\n if (result instanceof type.errors) {\n return result.summary;\n }\n }\n\n return null;\n};\n\nexport const buildHttpContext = async (ctx: { req: BunRequest; server: Server<unknown> }): Promise<ContextType> => {\n const { req, server } = ctx;\n\n const address = server.requestIP(req);\n const ip = address?.address ?? \"unknown\";\n\n const response = new HttpResponse();\n\n let payload = {};\n let form: FormData | null = null;\n const contentType = req.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n try {\n payload = await req.json();\n } catch (_e) {}\n } else {\n try {\n form = await req.formData();\n } catch (_e) {}\n }\n\n const request = new HttpRequest(req, {\n params: req.params,\n payload,\n form,\n ip,\n });\n\n const context: ContextType = {\n logger: container.get(\"logger\"),\n analytics: container.get(\"analytics\"),\n cache: container.get(\"cache\"),\n storage: container.get(\"storage\"),\n mailer: container.get(\"mailer\"),\n database: container.get(\"database\"),\n app: {\n env: container.get(\"app.env\"),\n },\n response,\n request,\n params: request.params,\n payload: request.payload,\n queries: request.queries,\n method: request.method,\n header: request.header,\n files: request.files,\n ip: request.ip,\n host: request.host,\n language: request.language,\n user: null,\n };\n\n return context;\n};\n\ntype ControllerError = { message: string; status: StatusCodeType };\ntype RouteValidationError = { message: string; status: StatusCodeType };\n\nexport const validateRouteAccess = async (\n context: ContextType,\n route: RouteConfigType,\n currentEnv: Environment,\n): Promise<RouteValidationError | null> => {\n // Check params\n if (route.params) {\n for (const [paramName, constraint] of Object.entries(route.params)) {\n const error = validateConstraint(constraint, context.params[paramName]);\n if (error) {\n return {\n message: `Invalid parameter \"${paramName}\": ${error}`,\n status: HttpStatus.Code.BadRequest,\n };\n }\n }\n }\n\n // Check queries\n if (route.queries) {\n const error = validateConstraint(route.queries, context.queries);\n if (error) {\n return {\n message: `Invalid query parameters: ${error}`,\n status: HttpStatus.Code.BadRequest,\n };\n }\n }\n\n // Check payload\n if (route.payload) {\n const error = validateConstraint(route.payload, context.payload);\n if (error) {\n return {\n message: `Invalid payload: ${error}`,\n status: HttpStatus.Code.BadRequest,\n };\n }\n }\n\n // Check env\n if (route.env && route.env.length > 0 && !route.env.includes(currentEnv)) {\n return {\n message: `Route \"${route.name}\" is not available in \"${currentEnv}\" environment`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n\n // Check ip\n if (route.ip && route.ip.length > 0 && (!context.ip || !route.ip.includes(context.ip))) {\n return {\n message: `Route \"${route.name}\" is not available for IP \"${context.ip}\"`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n\n // Check host\n if (route.host && route.host.length > 0 && !route.host.includes(context.host)) {\n return {\n message: `Route \"${route.name}\" is not available for host \"${context.host}\"`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n\n // Check roles\n if (route.roles && route.roles.length > 0) {\n if (!context.user || !context.user.roles || context.user.roles.length === 0) {\n return {\n message: `Route \"${route.name}\" requires authentication`,\n status: HttpStatus.Code.Forbidden,\n };\n }\n\n const role = new Role();\n const hasRequiredRole = route.roles.some((requiredRole) =>\n context.user?.roles.some((userRole) => role.hasRole(userRole, requiredRole)),\n );\n\n if (!hasRequiredRole) {\n return {\n message: `Route \"${route.name}\" is not accessible for user roles`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n }\n\n // Check permission\n if (route.permission) {\n const permission = container.get(route.permission);\n permission.setUserPermissions(context.user).build();\n const hasPermission = await permission.check();\n if (!hasPermission) {\n return {\n message: `Route \"${route.name}\" permission denied`,\n status: HttpStatus.Code.Forbidden,\n };\n }\n }\n\n return null;\n};\n\nexport const validateResponse = (route: RouteConfigType, data: unknown): RouteValidationError | null => {\n if (route.response) {\n const error = validateConstraint(route.response, data);\n if (error) {\n return {\n message: `Invalid response: ${error}`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n }\n return null;\n};\n\nconst buildExceptionResponse = (\n context: ContextType,\n message: string,\n status: StatusCodeType,\n env: Environment,\n): Response => {\n return context.response.exception(message, { status }).get(env);\n};\n\nconst logRequest = (context: ContextType, status: number, path: string): void => {\n const logger = context.logger as {\n success: (message: string, data?: LogsEntity) => void;\n info: (message: string, data?: LogsEntity) => void;\n warn: (message: string, data?: LogsEntity) => void;\n error: (message: string, data?: LogsEntity) => void;\n };\n\n if (!logger) {\n return;\n }\n\n const logData = new LogsEntity();\n logData.date = new Date();\n logData.status = status;\n logData.method = context.method;\n logData.path = path;\n logData.params = context.params as Record<string, ScalarType>;\n logData.payload = context.payload as Record<string, unknown>;\n logData.queries = context.queries as Record<string, ScalarType>;\n\n if (context.ip) logData.ip = context.ip;\n\n const userAgent = context.header.get(\"User-Agent\");\n if (userAgent) logData.userAgent = userAgent;\n\n const referer = context.header.getReferer();\n if (referer) logData.referer = referer;\n\n if (context.user?.id) logData.userId = context.user.id;\n if (context.user?.email) logData.email = context.user.email;\n if (context.user?.lastName) logData.lastName = context.user.lastName;\n if (context.user?.firstName) logData.firstName = context.user.firstName;\n\n const message = `${context.method} ${path}`;\n\n if (status >= 500) {\n logger.error(message, logData);\n } else if (status >= 400) {\n logger.warn(message, logData);\n } else if (status >= 300) {\n logger.info(message, logData);\n } else {\n logger.success(message, logData);\n }\n};\n\nconst executeController = async (\n controller: { index: (context: ContextType) => Promise<IResponse> | IResponse },\n context: ContextType,\n): Promise<[IResponse, null] | [null, ControllerError]> => {\n try {\n const response = await controller.index(context);\n return [response, null];\n } catch (error: unknown) {\n if (error instanceof Exception) {\n return [null, { message: error.message, status: error.status as StatusCodeType }];\n }\n if (error instanceof Error) {\n return [null, { message: error.message, status: HttpStatus.Code.InternalServerError }];\n }\n return [null, { message: \"An unknown error occurred\", status: HttpStatus.Code.InternalServerError }];\n }\n};\n\nexport const httpRouteHandler = async (context: ContextType, route: RouteConfigType): Promise<Response> => {\n const currentEnv = (context.app.env.env as Environment) || Environment.PRODUCTION;\n\n const validationError = await validateRouteAccess(context, route, currentEnv);\n if (validationError) {\n logRequest(context, validationError.status, route.path);\n return buildExceptionResponse(context, validationError.message, validationError.status, currentEnv);\n }\n\n const controller = container.get(route.controller);\n\n const [response, controllerError] = await executeController(controller, context);\n if (controllerError) {\n logRequest(context, controllerError.status, route.path);\n return buildExceptionResponse(context, controllerError.message, controllerError.status, currentEnv);\n }\n\n const responseValidationError = validateResponse(route, response.getData());\n if (responseValidationError) {\n logRequest(context, responseValidationError.status, route.path);\n return buildExceptionResponse(context, responseValidationError.message, responseValidationError.status, currentEnv);\n }\n\n const httpResponse = response.get(currentEnv);\n logRequest(context, httpResponse.status, route.path);\n\n return httpResponse;\n};\n\nconst runMiddlewares = async (context: ContextType, middlewares: MiddlewareClassType[]): Promise<ContextType> => {\n let currentContext = context;\n\n for (const MiddlewareClass of middlewares) {\n const middleware = container.get<IMiddleware>(MiddlewareClass);\n currentContext = await middleware.handle(currentContext);\n }\n\n return currentContext;\n};\n\nexport const formatHttpRoutes = (\n httpRoutes: Map<string, RouteConfigType[]>,\n middlewares: MiddlewareClassType[] = [],\n): HttpRoutesMap => {\n const routes: HttpRoutesMap = {};\n\n for (const [path, routeConfigs] of httpRoutes) {\n const methodHandlers: Record<string, (req: BunRequest, server: Server<unknown>) => Promise<Response>> = {};\n\n for (const route of routeConfigs) {\n methodHandlers[route.method] = async (req: BunRequest, server: Server<unknown>) => {\n let context = await buildHttpContext({ req, server });\n\n try {\n context = await runMiddlewares(context, middlewares);\n } catch (error: unknown) {\n const env = (context.app.env.env as Environment) || Environment.PRODUCTION;\n const status = (error instanceof Exception ? error.status : HttpStatus.Code.InternalServerError) as number;\n logRequest(context, status, route.path);\n return buildExceptionResponse(context, (error as Error).message, status as StatusCodeType, env);\n }\n\n return httpRouteHandler(context, route);\n };\n }\n\n routes[path] = methodHandlers;\n }\n\n return routes;\n};\n",
5
+ "import type { IAppEnv } from \"@ooneex/app-env\";\nimport { container } from \"@ooneex/container\";\nimport type { ICron } from \"@ooneex/cron\";\nimport { Exception, type IException } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\nimport { type ILogger, type LogsEntity, TerminalLogger } from \"@ooneex/logger\";\nimport type { MiddlewareClassType, SocketMiddlewareClassType } from \"@ooneex/middleware\";\nimport { router } from \"@ooneex/routing\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { AssertAppEnv, AssertHostname, AssertPort } from \"@ooneex/validation/constraints\";\nimport type { BunRequest, ServerWebSocket } from \"bun\";\nimport { generateRouteDoc } from \"./generateRouteDoc\";\nimport { generateRouteFetcher } from \"./generateRouteFetcher\";\nimport { generateRouteHook } from \"./generateRouteHook\";\nimport { generateRouteSocket } from \"./generateRouteSocket\";\nimport { formatHttpRoutes } from \"./httpRouteUtils\";\nimport { logger as loggerFunc } from \"./logger\";\nimport { formatSocketRoutes, socketRouteHandler } from \"./socketRouteUtils\";\nimport { staticHandler } from \"./staticHandler\";\nimport type { AppConfigType } from \"./types\";\n\nexport class App {\n constructor(private readonly config: AppConfigType) {\n const { loggers, cronJobs, analytics, cache, storage, database, env, mailer } = this.config;\n\n loggers.forEach((log) => {\n const logger = container.get<ILogger<Record<string, ScalarType>> | ILogger<LogsEntity>>(log);\n logger.init();\n });\n container.addConstant(\"logger\", loggerFunc(loggers, container));\n\n cronJobs?.forEach((cronJob) => {\n const cron = container.get<ICron>(cronJob);\n cron.start();\n });\n\n if (env) {\n container.addConstant(\"app.env\", env);\n }\n\n if (analytics) {\n container.addAlias(\"analytics\", analytics);\n }\n\n if (cache) {\n container.addAlias(\"cache\", cache);\n }\n\n if (storage) {\n container.addAlias(\"storage\", storage);\n }\n\n if (mailer) {\n container.addAlias(\"mailer\", mailer);\n }\n\n if (database) {\n container.addConstant(\"database\", database);\n }\n }\n\n public async init(): Promise<App> {\n const appEnv = Bun.env.APP_ENV;\n const port = Bun.env.PORT ? Number.parseInt(Bun.env.PORT, 10) : 3000;\n const hostname = Bun.env.HOST_NAME ?? \"\";\n\n const appEnvValidator = new AssertAppEnv();\n const appEnvResult = appEnvValidator.validate(appEnv);\n if (!appEnvResult.isValid) {\n throw new Exception(`Invalid APP_ENV: ${appEnvResult.message}`, {\n status: HttpStatus.Code.InternalServerError,\n data: { appEnv },\n });\n }\n\n const portValidator = new AssertPort();\n const portResult = portValidator.validate(port);\n if (!portResult.isValid) {\n throw new Exception(`Invalid PORT: ${portResult.message}`, {\n status: HttpStatus.Code.InternalServerError,\n data: { port: Bun.env.PORT },\n });\n }\n\n const hostnameValidator = new AssertHostname();\n const hostnameResult = hostnameValidator.validate(hostname);\n if (!hostnameResult.isValid) {\n throw new Exception(`Invalid HOST_NAME: ${hostnameResult.message}`, {\n status: HttpStatus.Code.InternalServerError,\n data: { hostname },\n });\n }\n\n return this;\n }\n\n public async run(): Promise<App> {\n const logger = new TerminalLogger();\n\n try {\n await this.init();\n } catch (error: unknown) {\n logger.error(error as IException);\n process.exit(1);\n }\n\n const env = container.getConstant<IAppEnv>(\"app.env\");\n let hostname = Bun.env.HOST_NAME || \"0.0.0.0\";\n const { directories } = this.config;\n const staticDir = directories.static;\n\n const { middlewares = [] } = this.config;\n\n const routes = {\n ...formatHttpRoutes(router.getHttpRoutes(), middlewares as MiddlewareClassType[]),\n ...formatSocketRoutes(router.getSocketRoutes()),\n };\n\n if (staticDir) {\n const trimmedStaticDir = staticDir.replace(/^\\/+|\\/+$/g, \"\");\n routes[`/${trimmedStaticDir}/*`] = {\n GET: (req: BunRequest) =>\n staticHandler({\n req,\n cwd: directories.cwd,\n }),\n };\n }\n\n const port = Bun.env.PORT ? Number.parseInt(Bun.env.PORT, 10) : 3000;\n\n const server = Bun.serve({\n port,\n hostname,\n development: env.isLocal,\n routes: {\n ...routes,\n \"/*\": this.config.spa || new Response(\"Not Found\", { status: HttpStatus.Code.NotFound }),\n },\n websocket: {\n perMessageDeflate: true,\n async message(ws: ServerWebSocket<{ id: string }>, message: string) {\n await socketRouteHandler(message, ws, server, middlewares as SocketMiddlewareClassType[]);\n },\n async close(ws: ServerWebSocket<{ id: string }>) {\n container.removeConstant(ws.data.id);\n },\n },\n });\n\n hostname = server.hostname || \"0.0.0.0\";\n\n if (hostname === \"0.0.0.0\") {\n hostname = \"localhost\";\n }\n\n logger.info(`Server running at ${server.protocol}://${hostname}:${server.port}`);\n\n const allRoutes = router.getRoutes();\n let routeDocCount = 0;\n let routeFetcherCount = 0;\n let routeSocketCount = 0;\n let routeHookCount = 0;\n\n for (const routeConfigs of allRoutes.values()) {\n for (const routeConfig of routeConfigs) {\n if (this.config.generateRouteDoc) {\n await generateRouteDoc(routeConfig);\n routeDocCount++;\n }\n\n if (routeConfig.generate?.fetcher) {\n if (routeConfig.isSocket) {\n await generateRouteSocket(routeConfig);\n routeSocketCount++;\n } else {\n await generateRouteFetcher(routeConfig);\n routeFetcherCount++;\n }\n }\n\n if (routeConfig.generate?.queryHook) {\n await generateRouteHook(routeConfig);\n routeHookCount++;\n }\n }\n }\n\n if (this.config.generateRouteDoc && routeDocCount > 0) {\n logger.info(`Generated ${routeDocCount} route doc${routeDocCount > 1 ? \"s\" : \"\"}`);\n }\n\n if (routeFetcherCount > 0) {\n logger.info(`Generated ${routeFetcherCount} route fetcher${routeFetcherCount > 1 ? \"s\" : \"\"}`);\n }\n\n if (routeSocketCount > 0) {\n logger.info(`Generated ${routeSocketCount} route socket${routeSocketCount > 1 ? \"s\" : \"\"}`);\n }\n\n if (routeHookCount > 0) {\n logger.info(`Generated ${routeHookCount} route hook${routeHookCount > 1 ? \"s\" : \"\"}`);\n }\n\n return this;\n }\n}\n",
6
+ "import { join } from \"node:path\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport { routeConfigToJsonDoc } from \"@ooneex/routing\";\n\nexport const generateRouteDoc = async (config: RouteConfigType): Promise<void> => {\n const outputDir = \"docs/routes\";\n const jsonDoc = routeConfigToJsonDoc(config);\n const fileName = `${config.name}.json`;\n const filePath = join(process.cwd(), outputDir, fileName);\n\n await Bun.write(filePath, JSON.stringify(jsonDoc, null, 2));\n};\n",
7
+ "import { join } from \"node:path\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport { routeConfigToFetcherString } from \"@ooneex/routing\";\nimport { toPascalCase } from \"@ooneex/utils\";\n\nexport const generateRouteFetcher = async (config: RouteConfigType): Promise<void> => {\n const outputDir = join(\"src\", \"fetchers\", \"routes\");\n const fetcherString = routeConfigToFetcherString(config);\n const fileName = `${toPascalCase(config.name)}Fetcher.ts`;\n const filePath = join(process.cwd(), outputDir, fileName);\n\n await Bun.write(filePath, fetcherString);\n};\n",
8
+ "import { join } from \"node:path\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport { routeConfigToHookString } from \"@ooneex/routing\";\nimport { toPascalCase } from \"@ooneex/utils\";\n\nexport const generateRouteHook = async (config: RouteConfigType): Promise<void> => {\n const outputDir = join(\"src\", \"hooks\", \"routes\");\n const hookString = routeConfigToHookString(config);\n const fileName = `use${toPascalCase(config.name)}.ts`;\n const filePath = join(process.cwd(), outputDir, fileName);\n\n await Bun.write(filePath, hookString);\n};\n",
9
+ "import { join } from \"node:path\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport { routeConfigToSocketString } from \"@ooneex/routing\";\nimport { toPascalCase } from \"@ooneex/utils\";\n\nexport const generateRouteSocket = async (config: RouteConfigType): Promise<void> => {\n const outputDir = join(\"src\", \"fetchers\", \"routes\");\n const socketString = routeConfigToSocketString(config);\n const fileName = `${toPascalCase(config.name)}Socket.ts`;\n const filePath = join(process.cwd(), outputDir, fileName);\n\n await Bun.write(filePath, socketString);\n};\n",
10
+ "import { Environment } from \"@ooneex/app-env\";\nimport { container } from \"@ooneex/container\";\nimport type { ContextType } from \"@ooneex/controller\";\nimport { Exception } from \"@ooneex/exception\";\nimport { HttpRequest } from \"@ooneex/http-request\";\nimport { HttpResponse, type IResponse } from \"@ooneex/http-response\";\nimport { HttpStatus, type StatusCodeType } from \"@ooneex/http-status\";\nimport { LogsEntity } from \"@ooneex/logger\";\nimport type { IMiddleware, MiddlewareClassType } from \"@ooneex/middleware\";\nimport { Role } from \"@ooneex/role\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { type AssertType, type IAssert, type } from \"@ooneex/validation\";\nimport type { BunRequest, Server } from \"bun\";\n\ntype HttpRouteHandler = (req: BunRequest, server: Server<unknown>) => Promise<Response>;\ntype HttpMethodHandlers = Partial<Record<string, HttpRouteHandler | Response>>;\ntype HttpRoutesMap = Record<string, HttpMethodHandlers>;\n\nexport const validateConstraint = (constraint: AssertType | IAssert, value: unknown): string | null => {\n if (\n constraint !== null &&\n typeof constraint === \"object\" &&\n \"validate\" in constraint &&\n typeof constraint.validate === \"function\"\n ) {\n const result = constraint.validate(value);\n if (!result.isValid) {\n return result.message || \"Validation failed\";\n }\n } else if (typeof constraint === \"function\") {\n const result = constraint(value);\n if (result instanceof type.errors) {\n return result.summary;\n }\n }\n\n return null;\n};\n\nexport const buildHttpContext = async (ctx: {\n req: BunRequest;\n server: Server<unknown>;\n route: RouteConfigType;\n}): Promise<ContextType> => {\n const { req, server, route } = ctx;\n\n const address = server.requestIP(req);\n const ip = address?.address ?? \"unknown\";\n\n const response = new HttpResponse();\n\n let payload = {};\n let form: FormData | null = null;\n const contentType = req.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n try {\n payload = await req.json();\n } catch (_e) {}\n } else {\n try {\n form = await req.formData();\n } catch (_e) {}\n }\n\n const request = new HttpRequest(req, {\n params: req.params,\n payload,\n form,\n ip,\n });\n\n const context: ContextType = {\n logger: container.get(\"logger\"),\n analytics: container.get(\"analytics\"),\n cache: container.get(\"cache\"),\n storage: container.get(\"storage\"),\n mailer: container.get(\"mailer\"),\n database: container.get(\"database\"),\n route: {\n name: route.name,\n path: route.path,\n method: route.method,\n description: route.description ?? \"\",\n },\n app: {\n env: container.get(\"app.env\"),\n },\n response,\n request,\n params: request.params,\n payload: request.payload,\n queries: request.queries,\n method: request.method,\n header: request.header,\n files: request.files,\n ip: request.ip,\n host: request.host,\n language: request.language,\n user: null,\n };\n\n return context;\n};\n\ntype ControllerError = { message: string; status: StatusCodeType };\ntype RouteValidationError = { message: string; status: StatusCodeType };\n\nexport const validateRouteAccess = async (\n context: ContextType,\n route: RouteConfigType,\n currentEnv: Environment,\n): Promise<RouteValidationError | null> => {\n // Check params\n if (route.params) {\n for (const [paramName, constraint] of Object.entries(route.params)) {\n const error = validateConstraint(constraint, context.params[paramName]);\n if (error) {\n return {\n message: `Invalid parameter \"${paramName}\": ${error}`,\n status: HttpStatus.Code.BadRequest,\n };\n }\n }\n }\n\n // Check queries\n if (route.queries) {\n const error = validateConstraint(route.queries, context.queries);\n if (error) {\n return {\n message: `Invalid query parameters: ${error}`,\n status: HttpStatus.Code.BadRequest,\n };\n }\n }\n\n // Check payload\n if (route.payload) {\n const error = validateConstraint(route.payload, context.payload);\n if (error) {\n return {\n message: `Invalid payload: ${error}`,\n status: HttpStatus.Code.BadRequest,\n };\n }\n }\n\n // Check env\n if (route.env && route.env.length > 0 && !route.env.includes(currentEnv)) {\n return {\n message: `Route \"${route.name}\" is not available in \"${currentEnv}\" environment`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n\n // Check ip\n if (route.ip && route.ip.length > 0 && (!context.ip || !route.ip.includes(context.ip))) {\n return {\n message: `Route \"${route.name}\" is not available for IP \"${context.ip}\"`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n\n // Check host\n if (route.host && route.host.length > 0 && !route.host.includes(context.host)) {\n return {\n message: `Route \"${route.name}\" is not available for host \"${context.host}\"`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n\n // Check roles\n if (route.roles && route.roles.length > 0) {\n if (!context.user || !context.user.roles || context.user.roles.length === 0) {\n return {\n message: `Route \"${route.name}\" requires authentication`,\n status: HttpStatus.Code.Forbidden,\n };\n }\n\n const role = new Role();\n const hasRequiredRole = route.roles.some((requiredRole) =>\n context.user?.roles.some((userRole) => role.hasRole(userRole, requiredRole)),\n );\n\n if (!hasRequiredRole) {\n return {\n message: `Route \"${route.name}\" is not accessible for user roles`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n }\n\n // Check permission\n if (route.permission) {\n const permission = container.get(route.permission);\n permission.setUserPermissions(context.user).build();\n const hasPermission = await permission.check();\n if (!hasPermission) {\n return {\n message: `Route \"${route.name}\" permission denied`,\n status: HttpStatus.Code.Forbidden,\n };\n }\n }\n\n return null;\n};\n\nexport const validateResponse = (route: RouteConfigType, data: unknown): RouteValidationError | null => {\n if (route.response) {\n const error = validateConstraint(route.response, data);\n if (error) {\n return {\n message: `Invalid response: ${error}`,\n status: HttpStatus.Code.NotAcceptable,\n };\n }\n }\n return null;\n};\n\nconst buildExceptionResponse = (\n context: ContextType,\n message: string,\n status: StatusCodeType,\n env: Environment,\n): Response => {\n return context.response.exception(message, { status }).get(env);\n};\n\nconst logRequest = (context: ContextType, status: number, path: string): void => {\n const logger = context.logger as {\n success: (message: string, data?: LogsEntity) => void;\n info: (message: string, data?: LogsEntity) => void;\n warn: (message: string, data?: LogsEntity) => void;\n error: (message: string, data?: LogsEntity) => void;\n };\n\n if (!logger) {\n return;\n }\n\n const logData = new LogsEntity();\n logData.date = new Date();\n logData.status = status;\n logData.method = context.method;\n logData.path = path;\n logData.params = context.params as Record<string, ScalarType>;\n logData.payload = context.payload as Record<string, unknown>;\n logData.queries = context.queries as Record<string, ScalarType>;\n\n if (context.ip) logData.ip = context.ip;\n\n const userAgent = context.header.get(\"User-Agent\");\n if (userAgent) logData.userAgent = userAgent;\n\n const referer = context.header.getReferer();\n if (referer) logData.referer = referer;\n\n if (context.user?.id) logData.userId = context.user.id;\n if (context.user?.email) logData.email = context.user.email;\n if (context.user?.lastName) logData.lastName = context.user.lastName;\n if (context.user?.firstName) logData.firstName = context.user.firstName;\n\n const message = `${context.method} ${path}`;\n\n if (status >= 500) {\n logger.error(message, logData);\n } else if (status >= 400) {\n logger.warn(message, logData);\n } else if (status >= 300) {\n logger.info(message, logData);\n } else {\n logger.success(message, logData);\n }\n};\n\nconst executeController = async (\n controller: { index: (context: ContextType) => Promise<IResponse> | IResponse },\n context: ContextType,\n): Promise<[IResponse, null] | [null, ControllerError]> => {\n try {\n const response = await controller.index(context);\n return [response, null];\n } catch (error: unknown) {\n if (error instanceof Exception) {\n return [null, { message: error.message, status: error.status as StatusCodeType }];\n }\n if (error instanceof Error) {\n return [null, { message: error.message, status: HttpStatus.Code.InternalServerError }];\n }\n return [null, { message: \"An unknown error occurred\", status: HttpStatus.Code.InternalServerError }];\n }\n};\n\nexport const httpRouteHandler = async (context: ContextType, route: RouteConfigType): Promise<Response> => {\n const currentEnv = (context.app.env.env as Environment) || Environment.PRODUCTION;\n\n const validationError = await validateRouteAccess(context, route, currentEnv);\n if (validationError) {\n logRequest(context, validationError.status, route.path);\n return buildExceptionResponse(context, validationError.message, validationError.status, currentEnv);\n }\n\n const controller = container.get(route.controller);\n\n const [response, controllerError] = await executeController(controller, context);\n if (controllerError) {\n logRequest(context, controllerError.status, route.path);\n return buildExceptionResponse(context, controllerError.message, controllerError.status, currentEnv);\n }\n\n const responseValidationError = validateResponse(route, response.getData());\n if (responseValidationError) {\n logRequest(context, responseValidationError.status, route.path);\n return buildExceptionResponse(context, responseValidationError.message, responseValidationError.status, currentEnv);\n }\n\n const httpResponse = response.get(currentEnv);\n logRequest(context, httpResponse.status, route.path);\n\n return httpResponse;\n};\n\nconst runMiddlewares = async (context: ContextType, middlewares: MiddlewareClassType[]): Promise<ContextType> => {\n let currentContext = context;\n\n for (const MiddlewareClass of middlewares) {\n const middleware = container.get<IMiddleware>(MiddlewareClass);\n currentContext = await middleware.handler(currentContext);\n }\n\n return currentContext;\n};\n\nexport const formatHttpRoutes = (\n httpRoutes: Map<string, RouteConfigType[]>,\n middlewares: MiddlewareClassType[] = [],\n): HttpRoutesMap => {\n const routes: HttpRoutesMap = {};\n\n for (const [path, routeConfigs] of httpRoutes) {\n const methodHandlers: Record<string, (req: BunRequest, server: Server<unknown>) => Promise<Response>> = {};\n\n for (const route of routeConfigs) {\n methodHandlers[route.method] = async (req: BunRequest, server: Server<unknown>) => {\n let context = await buildHttpContext({ req, server, route });\n\n try {\n context = await runMiddlewares(context, middlewares);\n } catch (error: unknown) {\n const env = (context.app.env.env as Environment) || Environment.PRODUCTION;\n const status = (error instanceof Exception ? error.status : HttpStatus.Code.InternalServerError) as number;\n logRequest(context, status, route.path);\n return buildExceptionResponse(context, (error as Error).message, status as StatusCodeType, env);\n }\n\n return httpRouteHandler(context, route);\n };\n }\n\n routes[path] = methodHandlers;\n }\n\n return routes;\n};\n",
7
11
  "import type { IContainer } from \"@ooneex/container\";\nimport type { IException } from \"@ooneex/exception\";\nimport type { ILogger, LoggerClassType, LogsEntity } from \"@ooneex/logger\";\nimport type { ScalarType } from \"@ooneex/types\";\n\nexport const logger = (loggers: LoggerClassType[], container: IContainer) => ({\n error: (message: string | IException, data?: Record<string, ScalarType> & LogsEntity) => {\n loggers.forEach((logger) => {\n const log = container.get<ILogger<Record<string, ScalarType>> | ILogger<LogsEntity>>(logger);\n if (log) {\n log.error(message, data);\n }\n });\n },\n warn: (message: string, data?: Record<string, ScalarType> & LogsEntity) => {\n loggers.forEach((logger) => {\n const log = container.get<ILogger<Record<string, ScalarType>> | ILogger<LogsEntity>>(logger);\n if (log) {\n log.warn(message, data);\n }\n });\n },\n info: (message: string, data?: Record<string, ScalarType> & LogsEntity) => {\n loggers.forEach((logger) => {\n const log = container.get<ILogger<Record<string, ScalarType>> | ILogger<LogsEntity>>(logger);\n if (log) {\n log.info(message, data);\n }\n });\n },\n debug: (message: string, data?: Record<string, ScalarType> & LogsEntity) => {\n loggers.forEach((logger) => {\n const log = container.get<ILogger<Record<string, ScalarType>> | ILogger<LogsEntity>>(logger);\n if (log) {\n log.debug(message, data);\n }\n });\n },\n log: (message: string, data?: Record<string, ScalarType> & LogsEntity) => {\n loggers.forEach((logger) => {\n const log = container.get<ILogger<Record<string, ScalarType>> | ILogger<LogsEntity>>(logger);\n if (log) {\n log.log(message, data);\n }\n });\n },\n success: (message: string, data?: Record<string, ScalarType> & LogsEntity) => {\n loggers.forEach((logger) => {\n const log = container.get<ILogger<Record<string, ScalarType>> | ILogger<LogsEntity>>(logger);\n if (log) {\n log.success(message, data);\n }\n });\n },\n});\n",
8
- "import { Environment } from \"@ooneex/app-env\";\nimport { container } from \"@ooneex/container\";\nimport { Exception } from \"@ooneex/exception\";\nimport type { IResponse } from \"@ooneex/http-response\";\nimport { HttpStatus, type StatusCodeType } from \"@ooneex/http-status\";\nimport { LogsEntity } from \"@ooneex/logger\";\nimport type { ISocketMiddleware, SocketMiddlewareClassType } from \"@ooneex/middleware\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport type { ContextType } from \"@ooneex/socket\";\nimport type { RequestDataType } from \"@ooneex/socket/client\";\nimport type { LocaleInfoType } from \"@ooneex/translation\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { random } from \"@ooneex/utils\";\nimport type { BunRequest, Server, ServerWebSocket } from \"bun\";\nimport { buildHttpContext, validateResponse, validateRouteAccess } from \"./httpRouteUtils\";\n\ntype SocketRouteHandler = (req: BunRequest, server: Server<unknown>) => Promise<undefined>;\ntype SocketRoutesMap = Record<string, SocketRouteHandler>;\n\nexport const formatSocketRoutes = (socketRoutes: Map<string, RouteConfigType>): SocketRoutesMap => {\n const routes: SocketRoutesMap = {};\n\n for (const [path, route] of socketRoutes) {\n routes[path] = async (req: BunRequest, server: Server<unknown>) => {\n const context = await buildHttpContext({ req, server });\n const id = random.nanoid(30);\n container.addConstant(id, { context, route });\n server.upgrade(req, { data: { id } });\n\n return undefined;\n };\n }\n\n return routes;\n};\n\nconst runMiddlewares = async (context: ContextType, middlewares: SocketMiddlewareClassType[]): Promise<ContextType> => {\n let currentContext = context;\n\n for (const MiddlewareClass of middlewares) {\n const middleware = container.get<ISocketMiddleware>(MiddlewareClass);\n currentContext = await middleware.handle(currentContext);\n }\n\n return currentContext;\n};\n\nconst sendException = (context: ContextType, message: string, status: StatusCodeType): Promise<void> => {\n context.response.exception(message, { status });\n return context.channel.send(context.response);\n};\n\nconst logSocketRequest = (context: ContextType, status: number, path: string): void => {\n const logger = context.logger as {\n success: (message: string, data?: LogsEntity) => void;\n info: (message: string, data?: LogsEntity) => void;\n warn: (message: string, data?: LogsEntity) => void;\n error: (message: string, data?: LogsEntity) => void;\n };\n\n if (!logger) {\n return;\n }\n\n const logData = new LogsEntity();\n logData.date = new Date();\n logData.status = status;\n logData.method = \"GET\";\n logData.path = path;\n logData.params = context.params as Record<string, ScalarType>;\n logData.payload = context.payload as Record<string, unknown>;\n logData.queries = context.queries as Record<string, ScalarType>;\n\n if (context.ip) logData.ip = context.ip;\n\n const userAgent = context.header.get(\"User-Agent\");\n if (userAgent) logData.userAgent = userAgent;\n\n const referer = context.header.getReferer();\n if (referer) logData.referer = referer;\n\n if (context.user?.id) logData.userId = context.user.id;\n if (context.user?.email) logData.email = context.user.email;\n if (context.user?.lastName) logData.lastName = context.user.lastName;\n if (context.user?.firstName) logData.firstName = context.user.firstName;\n\n const message = `WS ${path}`;\n\n if (status >= 500) {\n logger.error(message, logData);\n } else if (status >= 400) {\n logger.warn(message, logData);\n } else if (status >= 300) {\n logger.info(message, logData);\n } else {\n logger.success(message, logData);\n }\n};\n\nexport const socketRouteHandler = async (\n message: string,\n ws: ServerWebSocket<{ id: string }>,\n server: Server<{ id: string }>,\n middlewares: SocketMiddlewareClassType[] = [],\n): Promise<void> => {\n let { context, route } = container.getConstant<{ context: ContextType; route: RouteConfigType }>(ws.data.id);\n const currentEnv = (context.app.env.env as Environment) || Environment.PRODUCTION;\n\n context.channel = {\n send: async (response: IResponse): Promise<void> => {\n const data = await response.get(currentEnv).json();\n ws.send(JSON.stringify(data));\n },\n close: (code?: number, reason?: string): void => {\n ws.close(code, reason);\n },\n subscribe: async (): Promise<void> => {\n ws.subscribe(route.name);\n },\n isSubscribed: (): boolean => {\n return ws.isSubscribed(route.name);\n },\n unsubscribe: async (): Promise<void> => {\n ws.unsubscribe(route.name);\n },\n publish: async (response: IResponse): Promise<void> => {\n const data = await response.get(currentEnv).json();\n\n server.publish(route.name, data);\n },\n };\n\n const requestData = JSON.parse(message) as RequestDataType;\n context.queries = requestData.queries as Record<string, ScalarType>;\n context.payload = requestData.payload as Record<string, ScalarType>;\n context.language = requestData.language as LocaleInfoType;\n\n try {\n context = await runMiddlewares(context, middlewares);\n } catch (error: unknown) {\n const status = (error instanceof Exception ? error.status : HttpStatus.Code.InternalServerError) as number;\n logSocketRequest(context, status, route.path);\n return sendException(context, (error as Error).message, status as StatusCodeType);\n }\n\n const validationError = await validateRouteAccess(context, route, currentEnv);\n if (validationError) {\n logSocketRequest(context, validationError.status, route.path);\n return sendException(context, validationError.message, validationError.status);\n }\n\n const controller = container.get(route.controller);\n try {\n context.response = await controller.index(context);\n } catch (error: unknown) {\n const status = (error instanceof Exception ? error.status : HttpStatus.Code.InternalServerError) as number;\n const message = error instanceof Error ? error.message : \"An unknown error occurred\";\n logSocketRequest(context, status, route.path);\n return sendException(context, message, status as StatusCodeType);\n }\n\n const responseValidationError = validateResponse(route, context.response.getData());\n if (responseValidationError) {\n logSocketRequest(context, responseValidationError.status, route.path);\n return sendException(context, responseValidationError.message, responseValidationError.status);\n }\n\n logSocketRequest(context, HttpStatus.Code.OK, route.path);\n return context.channel.send(context.response);\n};\n",
12
+ "import { Environment } from \"@ooneex/app-env\";\nimport { container } from \"@ooneex/container\";\nimport { Exception } from \"@ooneex/exception\";\nimport type { IResponse } from \"@ooneex/http-response\";\nimport { HttpStatus, type StatusCodeType } from \"@ooneex/http-status\";\nimport { LogsEntity } from \"@ooneex/logger\";\nimport type { ISocketMiddleware, SocketMiddlewareClassType } from \"@ooneex/middleware\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport type { ContextType } from \"@ooneex/socket\";\nimport type { RequestDataType } from \"@ooneex/socket/client\";\nimport type { LocaleInfoType } from \"@ooneex/translation\";\nimport type { ScalarType } from \"@ooneex/types\";\nimport { random } from \"@ooneex/utils\";\nimport type { BunRequest, Server, ServerWebSocket } from \"bun\";\nimport { buildHttpContext, validateResponse, validateRouteAccess } from \"./httpRouteUtils\";\n\ntype SocketRouteHandler = (req: BunRequest, server: Server<unknown>) => Promise<undefined>;\ntype SocketRoutesMap = Record<string, SocketRouteHandler>;\n\nexport const formatSocketRoutes = (socketRoutes: Map<string, RouteConfigType>): SocketRoutesMap => {\n const routes: SocketRoutesMap = {};\n\n for (const [path, route] of socketRoutes) {\n routes[path] = async (req: BunRequest, server: Server<unknown>) => {\n const context = await buildHttpContext({ req, server, route });\n const id = random.nanoid(30);\n container.addConstant(id, { context, route });\n server.upgrade(req, { data: { id } });\n\n return undefined;\n };\n }\n\n return routes;\n};\n\nconst runMiddlewares = async (context: ContextType, middlewares: SocketMiddlewareClassType[]): Promise<ContextType> => {\n let currentContext = context;\n\n for (const MiddlewareClass of middlewares) {\n const middleware = container.get<ISocketMiddleware>(MiddlewareClass);\n currentContext = await middleware.handler(currentContext);\n }\n\n return currentContext;\n};\n\nconst sendException = (context: ContextType, message: string, status: StatusCodeType): Promise<void> => {\n context.response.exception(message, { status });\n return context.channel.send(context.response);\n};\n\nconst logSocketRequest = (context: ContextType, status: number, path: string): void => {\n const logger = context.logger as {\n success: (message: string, data?: LogsEntity) => void;\n info: (message: string, data?: LogsEntity) => void;\n warn: (message: string, data?: LogsEntity) => void;\n error: (message: string, data?: LogsEntity) => void;\n };\n\n if (!logger) {\n return;\n }\n\n const logData = new LogsEntity();\n logData.date = new Date();\n logData.status = status;\n logData.method = \"GET\";\n logData.path = path;\n logData.params = context.params as Record<string, ScalarType>;\n logData.payload = context.payload as Record<string, unknown>;\n logData.queries = context.queries as Record<string, ScalarType>;\n\n if (context.ip) logData.ip = context.ip;\n\n const userAgent = context.header.get(\"User-Agent\");\n if (userAgent) logData.userAgent = userAgent;\n\n const referer = context.header.getReferer();\n if (referer) logData.referer = referer;\n\n if (context.user?.id) logData.userId = context.user.id;\n if (context.user?.email) logData.email = context.user.email;\n if (context.user?.lastName) logData.lastName = context.user.lastName;\n if (context.user?.firstName) logData.firstName = context.user.firstName;\n\n const message = `WS ${path}`;\n\n if (status >= 500) {\n logger.error(message, logData);\n } else if (status >= 400) {\n logger.warn(message, logData);\n } else if (status >= 300) {\n logger.info(message, logData);\n } else {\n logger.success(message, logData);\n }\n};\n\nexport const socketRouteHandler = async (\n message: string,\n ws: ServerWebSocket<{ id: string }>,\n server: Server<{ id: string }>,\n middlewares: SocketMiddlewareClassType[] = [],\n): Promise<void> => {\n let { context, route } = container.getConstant<{ context: ContextType; route: RouteConfigType }>(ws.data.id);\n const currentEnv = (context.app.env.env as Environment) || Environment.PRODUCTION;\n\n context.channel = {\n send: async (response: IResponse): Promise<void> => {\n const data = await response.get(currentEnv).json();\n ws.send(JSON.stringify(data));\n },\n close: (code?: number, reason?: string): void => {\n ws.close(code, reason);\n },\n subscribe: async (): Promise<void> => {\n ws.subscribe(route.name);\n },\n isSubscribed: (): boolean => {\n return ws.isSubscribed(route.name);\n },\n unsubscribe: async (): Promise<void> => {\n ws.unsubscribe(route.name);\n },\n publish: async (response: IResponse): Promise<void> => {\n const data = await response.get(currentEnv).json();\n\n server.publish(route.name, data);\n },\n };\n\n const requestData = JSON.parse(message) as RequestDataType;\n context.queries = requestData.queries as Record<string, ScalarType>;\n context.payload = requestData.payload as Record<string, ScalarType>;\n context.language = requestData.language as LocaleInfoType;\n\n try {\n context = await runMiddlewares(context, middlewares);\n } catch (error: unknown) {\n const status = (error instanceof Exception ? error.status : HttpStatus.Code.InternalServerError) as number;\n logSocketRequest(context, status, route.path);\n return sendException(context, (error as Error).message, status as StatusCodeType);\n }\n\n const validationError = await validateRouteAccess(context, route, currentEnv);\n if (validationError) {\n logSocketRequest(context, validationError.status, route.path);\n return sendException(context, validationError.message, validationError.status);\n }\n\n const controller = container.get(route.controller);\n try {\n context.response = await controller.index(context);\n } catch (error: unknown) {\n const status = (error instanceof Exception ? error.status : HttpStatus.Code.InternalServerError) as number;\n const message = error instanceof Error ? error.message : \"An unknown error occurred\";\n logSocketRequest(context, status, route.path);\n return sendException(context, message, status as StatusCodeType);\n }\n\n const responseValidationError = validateResponse(route, context.response.getData());\n if (responseValidationError) {\n logSocketRequest(context, responseValidationError.status, route.path);\n return sendException(context, responseValidationError.message, responseValidationError.status);\n }\n\n logSocketRequest(context, HttpStatus.Code.OK, route.path);\n return context.channel.send(context.response);\n};\n",
9
13
  "import { join } from \"node:path\";\nimport { HttpStatus } from \"@ooneex/http-status\";\nimport type { BunRequest } from \"bun\";\n\nexport const staticHandler = async (options: { req: BunRequest; cwd: string }): Promise<Response> => {\n const { req, cwd } = options;\n const path = new URL(req.url).pathname;\n\n const filePath = join(cwd, path);\n const file = Bun.file(filePath);\n if (await file.exists()) {\n return new Response(file);\n }\n\n return new Response(\"File not found\", {\n status: HttpStatus.Code.NotFound,\n });\n};\n",
10
- "import { join } from \"node:path\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport { routeConfigToJsonDoc } from \"@ooneex/routing\";\n\nexport const generateRouteDoc = async (config: RouteConfigType): Promise<void> => {\n const outputDir = \"docs/routes\";\n const jsonDoc = routeConfigToJsonDoc(config);\n const fileName = `${config.name}.json`;\n const filePath = join(process.cwd(), outputDir, fileName);\n\n await Bun.write(filePath, JSON.stringify(jsonDoc, null, 2));\n};\n",
11
14
  "import { join } from \"node:path\";\nimport type { RouteConfigType } from \"@ooneex/routing\";\nimport { routeConfigToTypeString } from \"@ooneex/routing\";\nimport { toPascalCase } from \"@ooneex/utils\";\n\nexport const generateRouteType = async (config: RouteConfigType): Promise<void> => {\n const outputDir = \"src/types/routes\";\n const typeString = routeConfigToTypeString(config);\n const fileName = `${config.name}.ts`;\n const filePath = join(process.cwd(), outputDir, fileName);\n\n const typeName = toPascalCase(config.name);\n\n const fileContent = `export type ${typeName}RouteType = ${typeString};\n`;\n\n await Bun.write(filePath, fileContent);\n};\n"
12
15
  ],
13
- "mappings": "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",
14
- "debugId": "21497BFA435EA40C64756E2164756E21",
16
+ "mappings": "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",
17
+ "debugId": "F30567500E6C026B64756E2164756E21",
15
18
  "names": []
16
19
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ooneex/app",
3
3
  "description": "Core application framework for building modern web applications with Bun, providing routing, middleware, caching, logging, and more",
4
- "version": "0.15.3",
4
+ "version": "0.16.1",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",