@minejs/server 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  </div>
9
9
 
10
10
  <div align="center">
11
- <img src="https://img.shields.io/badge/v-0.1.0-black"/>
11
+ <img src="https://img.shields.io/badge/v-0.1.2-black"/>
12
12
  <a href="https://github.com/minejs-org"><img src="https://img.shields.io/badge/🔥-@minejs-black"/></a>
13
13
  <br>
14
14
  <img src="https://img.shields.io/badge/coverage-94.29%25-brightgreen" alt="Test Coverage" />
@@ -323,7 +323,6 @@
323
323
  // User & Database
324
324
  c.user // User object (if set by middleware)
325
325
  c.db // Database instance
326
- c.i18n // i18n manager
327
326
  c.logger // Logger instance
328
327
 
329
328
  // Response methods
@@ -460,7 +459,7 @@
460
459
 
461
460
  ```typescript
462
461
  handler: (c: AppContext) => {
463
- import { t } from '@minejs/i18n';
462
+ import { t } from '@minejs/server';
464
463
 
465
464
  // Current language (auto-detected from ?lang, cookie, or header)
466
465
  const lang = c.lang;
@@ -471,10 +470,7 @@
471
470
  // With parameters
472
471
  const greeting = t('greeting', { name: 'John' });
473
472
 
474
- // Get supported languages
475
- const supported = c.i18n?.getSupportedLanguages();
476
-
477
- return c.json({ message, lang, supported });
473
+ return c.json({ message, lang });
478
474
  }
479
475
  ```
480
476
 
@@ -558,7 +554,6 @@
558
554
  return c.json({
559
555
  message : t('hello'),
560
556
  language : c.lang,
561
- supported : c.i18n?.getSupportedLanguages()
562
557
  });
563
558
  }
564
559
  },
@@ -644,7 +639,6 @@
644
639
  // Managers
645
640
  db : DB | undefined;
646
641
  logger : Logger | null;
647
- i18n : I18nManager | null;
648
642
 
649
643
  // Response methods
650
644
  json (data: unknown, status?: number): Response;
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var ue=require('@minejs/db'),me=require('crypto'),logger=require('@minejs/logger'),path=require('path'),fs=require('fs'),i18n=require('@minejs/i18n');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var ue__namespace=/*#__PURE__*/_interopNamespace(ue);var me__default=/*#__PURE__*/_interopDefault(me);var G=class{constructor(){this.routes=new Map;this.regexRoutes=[];}match(e,t){let r=`${e}:${t}`;if(this.routes.has(r)){let n=this.routes.get(r);return {handler:n.handler,params:{},metadata:n.metadata}}for(let n of this.regexRoutes)if(n.method===e){let i=t.match(n.pattern);if(i){let u=i.groups||{};return {handler:n.handler,params:u,metadata:n.metadata}}}return null}getAll(){let e=Array.from(this.routes.entries()).map(([r,n])=>{let i=r.indexOf(":"),u=r.substring(0,i),a=r.substring(i+1);return {method:u,path:a,handler:n.handler}}),t=this.regexRoutes.map(r=>{let n=r.key.indexOf(":");return {method:r.method,path:r.key.substring(n+1),handler:r.handler}});return [...e,...t]}clear(){this.routes.clear(),this.regexRoutes=[];}remove(e,t){let r=`${e}:${t}`;if(this.routes.has(r))return this.routes.delete(r),true;let n=this.regexRoutes.findIndex(i=>i.key===r);return n>=0?(this.regexRoutes.splice(n,1),true):false}register(e,t,r,n={}){let i=`${e}:${t}`;if(t.includes(":")||t.includes("*")){let u=this.pathToRegex(t),a=this.regexRoutes.findIndex(x=>x.key===i),C={pattern:u,method:e,handler:r,key:i,metadata:n};a>=0?this.regexRoutes[a]=C:this.regexRoutes.push(C);}else this.routes.set(i,{handler:r,metadata:n});}pathToRegex(e){let t=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return t=t.replace(/:(\w+)/g,"(?<$1>[^/]+)"),t=t.replace(/\*/g,".*"),new RegExp(`^${t}$`)}};var B=class{constructor(){this.rateLimitStore=new Map;this.csrfTokens=new Map;this.requestLog=new Map;this.MAX_REQUEST_LOG_SIZE=1e3;}checkRateLimit(e,t,r){let n=Date.now(),i=this.rateLimitStore.get(e);return i?n<i.reset?i.count>=t?false:(i.count++,true):(this.rateLimitStore.set(e,{count:1,reset:n+r}),true):(this.rateLimitStore.set(e,{count:1,reset:n+r}),true)}cleanupRateLimit(){let e=Date.now();for(let[t,r]of this.rateLimitStore.entries())e>r.reset&&this.rateLimitStore.delete(t);}generateCsrfToken(e,t=36e5){let r=me__default.default.randomBytes(32).toString("hex");return this.csrfTokens.set(r,{sessionId:e,expires:Date.now()+t}),r}validateCsrfToken(e,t){let r=this.csrfTokens.get(e);return r?Date.now()>r.expires?(this.csrfTokens.delete(e),false):r.sessionId===t?(this.csrfTokens.delete(e),true):false:false}cleanupCsrfTokens(){let e=Date.now();for(let[t,r]of this.csrfTokens.entries())e>r.expires&&this.csrfTokens.delete(t);}sanitizeHtml(e){return e?e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;"):""}sanitizeSql(e){return e?e.replace(/\\/g,"\\\\").replace(/;/g,"").replace(/'/g,"''").replace(/"/g,'\\"').replace(/\u0000/g,""):""}logRequest(e,t,r,n,i,u){if(this.requestLog.set(e,{timestamp:new Date().toISOString(),method:t,path:r,ip:n,status:i,duration:u}),this.requestLog.size>this.MAX_REQUEST_LOG_SIZE){let{value:a}=this.requestLog.keys().next()||{value:null};a&&this.requestLog.delete(a);}}getRequestLog(e){return this.requestLog.get(e)}getAllRequestLogs(){return Array.from(this.requestLog.values())}clearAll(){this.rateLimitStore.clear(),this.csrfTokens.clear(),this.requestLog.clear();}getStats(){return {rateLimitEntries:this.rateLimitStore.size,csrfTokens:this.csrfTokens.size,requestLogs:this.requestLog.size}}};var P=class extends Error{constructor(t,r=500,n){super(t);this.message=t;this.statusCode=r;this.code=n;this.name="AppError";}},M=class extends P{constructor(t,r){super(t,400,"VALIDATION_ERROR");this.issues=r;this.name="ValidationError";}},se=class extends P{constructor(e){super(e,500,"DATABASE_ERROR"),this.name="DatabaseError";}},V=class extends P{constructor(e="Request timeout"){super(e,408,"TIMEOUT_ERROR"),this.name="TimeoutError";}},oe=class extends P{constructor(e="Too many requests"){super(e,429,"RATE_LIMIT_ERROR"),this.name="RateLimitError";}};var O=class{constructor(e){this.fileCache=new Map;this.CACHE_MAX_SIZE=1e3;if(!fs.existsSync(e.directory))throw new Error(`Static directory does not exist: ${e.directory}`);if(!fs.statSync(e.directory).isDirectory())throw new Error(`Static path is not a directory: ${e.directory}`);this.resolvedDir=path.resolve(e.directory),this.config={path:e.path,directory:e.directory,maxAge:e.maxAge??3600,index:e.index??["index.html"],dotfiles:e.dotfiles??"deny",etag:e.etag??true,lastModified:e.lastModified??true,immutable:e.immutable??false,extensions:e.extensions??[],fallthrough:e.fallthrough??false,setHeaders:e.setHeaders};}handler(){return async e=>{let t=e.request.url,n=new URL(t).pathname;n.startsWith(this.config.path)&&(n=n.slice(this.config.path.length));try{n=decodeURIComponent(n);}catch{return e.json({error:"Invalid URL encoding"},400)}if(n.includes("..")||n.includes("\\"))return e.json({error:"Forbidden"},403);if(this.config.dotfiles!=="allow"&&n.split("/").some(a=>a.startsWith(".")))return this.config.dotfiles==="deny"?e.json({error:"Forbidden"},403):this.handleNotFound(e);let i=this.resolveFilePath(n);if(!i)return this.handleNotFound(e);if(!this.isPathSafe(i))return e.json({error:"Forbidden"},403);if(!fs.existsSync(i))return this.handleNotFound(e);let u=fs.statSync(i);return u.isDirectory()?this.serveDirectory(e,i,n):this.serveFile(e,i,u)}}getPathPattern(){return `${this.config.path}/*`}resolveFilePath(e){e.startsWith("/")&&(e=e.slice(1));let t=path.join(this.resolvedDir,e);if(!fs.existsSync(t)&&this.config.extensions.length>0)for(let r of this.config.extensions){let n=`${t}.${r}`;if(fs.existsSync(n))return n}return t}isPathSafe(e){return !path.relative(this.resolvedDir,path.resolve(e)).startsWith("..")&&!path.resolve(e).startsWith("..")}async serveDirectory(e,t,r){for(let n of this.config.index){let i=path.join(t,n);if(fs.existsSync(i)){let u=fs.statSync(i);if(u.isFile())return this.serveFile(e,i,u)}}return this.handleNotFound(e)}async serveFile(e,t,r){let n=e.request.method.toUpperCase();if(n!=="GET"&&n!=="HEAD")return e.json({error:"Method not allowed"},405);let i=t,u=this.fileCache.get(i);if(u&&u.mtime!==r.mtimeMs&&(u=void 0),!u){if(u={etag:this.generateEtag(r),lastModified:new Date(r.mtime),size:r.size,mtime:r.mtimeMs},this.fileCache.size>=this.CACHE_MAX_SIZE){let w=this.fileCache.keys().next().value;w&&this.fileCache.delete(w);}this.fileCache.set(i,u);}let a=e.request.headers.get("if-none-match"),C=e.request.headers.get("if-modified-since");if(this.config.etag&&a===u.etag)return new Response(null,{status:304,headers:this.buildHeaders(t,u)});if(this.config.lastModified&&C){let w=new Date(C);if(u.lastModified<=w)return new Response(null,{status:304,headers:this.buildHeaders(t,u)})}let x=Bun.file(t),E=this.buildHeaders(t,u);return this.config.setHeaders&&this.config.setHeaders(e,t),n==="HEAD"?new Response(null,{status:200,headers:E}):new Response(x,{status:200,headers:E})}buildHeaders(e,t){let r=new Headers,n=this.getMimeType(e);if(r.set("Content-Type",n),r.set("Content-Length",t.size.toString()),this.config.etag&&r.set("ETag",t.etag),this.config.lastModified&&r.set("Last-Modified",t.lastModified.toUTCString()),this.config.maxAge>0){let i=`public, max-age=${this.config.maxAge}`;this.config.immutable&&(i+=", immutable"),r.set("Cache-Control",i);}else r.set("Cache-Control","no-cache");return r.set("Accept-Ranges","bytes"),r}generateEtag(e){return `"${e.size.toString(16)}-${e.mtimeMs.toString(16)}"`}getMimeType(e){let t=path.extname(e).toLowerCase();return be[t]||"application/octet-stream"}handleNotFound(e){return this.config.fallthrough?e.json({error:"Not Found"},404):e.json({error:"Not Found"},404)}clearCache(){this.fileCache.clear();}getCacheStats(){return {entries:this.fileCache.size,maxSize:this.CACHE_MAX_SIZE}}};function Re(s){return new O(s)}var be={".html":"text/html; charset=utf-8",".htm":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".txt":"text/plain; charset=utf-8",".xml":"text/xml; charset=utf-8",".csv":"text/csv; charset=utf-8",".md":"text/markdown; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".jsonld":"application/ld+json",".map":"application/json; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".webp":"image/webp",".avif":"image/avif",".bmp":"image/bmp",".tiff":"image/tiff",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".aac":"audio/aac",".flac":"audio/flac",".mp4":"video/mp4",".webm":"video/webm",".ogv":"video/ogg",".mov":"video/quicktime",".avi":"video/x-msvideo",".mkv":"video/x-matroska",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".zip":"application/zip",".rar":"application/x-rar-compressed",".7z":"application/x-7z-compressed",".tar":"application/x-tar",".gz":"application/gzip",".wasm":"application/wasm",".manifest":"text/cache-manifest",".webmanifest":"application/manifest+json"};var W=new B,T=new G;async function Ce(s={}){let e=Number(s.port)||3e3,t=s.hostname||"localhost",r=s.maxRequestSize||10*1024*1024,n=s.requestTimeout||3e4,i=s.gracefulShutdownTimeout||1e4,u=typeof s.logging=="object"?s.logging:{},a=s.logging?new logger.Logger(u.level||"info",u.pretty):null,C=null,x=null;s.i18n&&(C=i18n.getI18n(),x=s.i18n===true?{defaultLanguage:"en",supportedLanguages:["en"]}:s.i18n,C&&await i18n.setupI18n(x));let E=new Map,w=[],R=new Set,z=[],X=setInterval(()=>{W.cleanupRateLimit(),W.cleanupCsrfTokens();},120*1e3);async function J(o,d){let p=Date.now(),l=crypto.randomUUID(),y=new URL(o.url).pathname,k=o.method.toUpperCase(),S=ve(o,d);R.add(l);try{let b=o.headers.get("content-length");if(b&&parseInt(b)>r)return a?.warn({requestId:l,size:b,ip:S},"Request too large"),new Response(JSON.stringify({error:"Payload too large"}),{status:413,headers:{"Content-Type":"application/json"}});let j=Ae(o,s);if(k==="OPTIONS")return new Response(null,{status:204,headers:j});if(s.security&&typeof s.security=="object"&&s.security.rateLimit){let H=typeof s.security.rateLimit=="object"?s.security.rateLimit:{},D=H.max||100,Z=H.windowMs||6e4,ne=H.keyGenerator?H.keyGenerator({request:o,ip:S}):S;if(!W.checkRateLimit(ne,D,Z))return a?.warn({requestId:l,ip:S,key:ne},"Rate limit exceeded"),new Response(JSON.stringify({error:H.message||"Too many requests"}),{status:429,headers:{"Content-Type":"application/json"}})}let h=null;["POST","PUT","PATCH"].includes(k)&&(h=await Se(o,a,r));let L=E.get("default"),A=Object.fromEntries(new URL(o.url).searchParams),ce=o.headers.get("cookie")||"",pe=le(ce).get("lang"),F=A.lang||pe||o.headers.get("Accept-Language")?.split(",")[0]?.split("-")[0]||x?.defaultLanguage||"en";x&&x.supportedLanguages&&!x.supportedLanguages.includes(F)&&(F=x.defaultLanguage||"en"),C&&C.setLanguage(F);let $=T.match(k,y);if(!$){let H=ae(S,o,{},L,a,l,C,F,x);if(a?.warn({requestId:l,method:k,path:y,ip:S},"Route not found"),s.onError)try{return await s.onError(404,y,k)}catch(D){a?.error({error:String(D),requestId:l},"Error in onError handler");}return H.json({error:"Not Found",path:y},404)}let U=ae(S,o,$.params||{},L,a,l,C,F,x);U.body=h,U.request=o;let ee=new AbortController,ge=new Promise((H,D)=>{let Z=setTimeout(()=>{ee.abort(),D(new V("Request timeout"));},n);ee.signal.addEventListener("abort",()=>clearTimeout(Z));}),te=$.metadata?.middlewares||[],K;te.length>0?K=q(U,te,$.handler):K=Promise.resolve($.handler(U));let N=await Promise.race([K,ge]),I=new Headers(N.headers);j.forEach((H,D)=>{I.has(D)||I.set(D,H);}),I.set("X-Request-ID",l),I.set("X-Content-Type-Options","nosniff"),I.set("X-Frame-Options","DENY"),I.set("X-XSS-Protection","1; mode=block"),I.set("Referrer-Policy","strict-origin-when-cross-origin");let re=Date.now()-p;return W.logRequest(l,k,y,S,N.status,re),a?.info({requestId:l,method:k,path:y,status:N.status,duration:re,ip:S},"Request completed"),new Response(N.body,{status:N.status,headers:I})}catch(b){if(b instanceof P){if(a?.warn({error:b.message,requestId:l,ip:S},`App error: ${b.message}`),s.onError)try{return await s.onError(b.statusCode,y,k)}catch(h){a?.error({error:String(h),requestId:l},"Error in onError handler");}return new Response(JSON.stringify({error:b.message,code:b.code,requestId:l}),{status:b.statusCode,headers:{"Content-Type":"application/json"}})}a?.error({error:String(b),requestId:l,ip:S},"Unhandled error");let j=process.env.NODE_ENV==="production"?"Internal Server Error":b.message;if(s.onError)try{return await s.onError(500,y,k)}catch(h){a?.error({error:String(h),requestId:l},"Error in onError handler");}return new Response(JSON.stringify({error:j,requestId:l}),{status:500,headers:{"Content-Type":"application/json"}})}finally{R.delete(l);}}async function q(o,d,p){let l=0,g=null,y=o.json.bind(o),k=o.text.bind(o),S=o.html.bind(o),b=o.redirect.bind(o);o.json=function(h,L){let A=y(h,L);return g=A,A},o.text=function(h,L){let A=k(h,L);return g=A,A},o.html=function(h,L){let A=S(h,L);return g=A,A},o.redirect=function(h,L){let A=b(h,L);return g=A,A};async function j(){if(!g&&l<d.length){let h=d[l];l++,await h(o,j);}}return await j(),o.json=y,o.text=k,o.html=S,o.redirect=b,g||p(o)}let c={method:"GET",path:"/health",handler:o=>o.json({status:"healthy",timestamp:new Date().toISOString(),uptime:process.uptime(),activeRequests:R.size})},m={method:"GET",path:"/readiness",handler:o=>{let d=E.size>0,p=d||E.size===0;return o.json({ready:p,checks:{database:d?"connected":"not configured",activeRequests:R.size},timestamp:new Date().toISOString()},p?200:503)}};if(s.routes&&s.routes.forEach(o=>{w.push(o),(Array.isArray(o.method)?o.method:[o.method]).forEach(p=>{T.register(p,o.path,o.handler,o);});}),s.static){let o=Array.isArray(s.static)?s.static:[s.static];for(let d of o)try{let l=new O(d).handler(),g={method:"GET",path:d.path==="/"?"/*":`${d.path}/*`,handler:l};w.push(g);let y=d.path==="/"?"/":d.path;z.push({prefix:y,handler:l}),d.path==="/"?(T.register("GET","/",l,g),T.register("HEAD","/",l,g),T.register("GET","/*",l,g),T.register("HEAD","/*",l,g)):(T.register("GET",`${d.path}/*`,l,g),T.register("HEAD",`${d.path}/*`,l,g));}catch(p){throw a?.error({error:String(p),path:d.path},"Failed to initialize static file server"),p}}w.push(c,m),T.register("GET","/health",c.handler,c),T.register("GET","/readiness",m.handler,m);let f=null,v={app:null,logger:a,db:E,bunServer:null,async start(){if(s.database){let d=Array.isArray(s.database)?s.database:[s.database];for(let p of d){let l=p.name||"default";try{if(typeof p.connection=="string"){let g=new ue__namespace.DB(p.connection);if(p.schema&&typeof p.schema=="object")for(let[,y]of Object.entries(p.schema))y&&typeof y=="object"&&g.defineSchema(y);E.set(l,g),a?.info({name:l,connection:p.connection},"\u2714 Database connected");}else throw new Error(`Database connection must be a string path (got ${typeof p.connection})`)}catch(g){throw a?.error({error:String(g),name:l},"Failed to connect to database"),g}}}f=Bun.serve({port:e,hostname:t,fetch:(d,p)=>J(d,p)}),v.bunServer=f;let o=`http://${t}:${e}`;if(a?.info({url:o},"\u2714 Server started"),s.onStartup)try{await s.onStartup(v);}catch(d){a?.error({error:String(d)},"Error in startup handler");}if(s.onReady)try{await s.onReady(v,E);}catch(d){a?.error({error:String(d)},"Error in ready handler");}},async stop(){if(a?.info("Stopping server..."),R.size>0){a?.info({count:R.size},"Waiting for active requests...");let o=Date.now()+i;for(;R.size>0&&Date.now()<o;)await new Promise(d=>setTimeout(d,100));R.size>0&&a?.warn({count:R.size},"Force closing with active requests");}if(clearInterval(X),s.onShutdown)try{await s.onShutdown();}catch(o){a?.error({error:String(o)},"Error in shutdown handler");}for(let[o,d]of E.entries())try{d&&typeof d.close=="function"&&d.close(),a?.info({name:o},"Database closed");}catch(p){a?.error({error:String(p),name:o},"Error closing database");}f&&typeof f.stop=="function"&&(f.stop(),a?.info("Bun server stopped")),a?.info("Server stopped successfully");},addRoute(o){w.push(o),(Array.isArray(o.method)?o.method:[o.method]).forEach(p=>{T.register(p,o.path,o.handler,o);}),a?.info({method:o.method,path:o.path},"Route added");},addRoutes(o){o.forEach(d=>this.addRoute(d));},getRoutes(){return w}};return v}async function Se(s,e,t){let r=s.headers.get("content-type")||"";try{if(r.includes("application/json")){let n=await s.text();if(n.length>t)throw new M("Payload too large");if(!n.trim())return {};try{return JSON.parse(n)}catch(i){throw e?.warn({error:String(i),bodyPreview:n.substring(0,100)},"Invalid JSON in request body"),new M("Invalid JSON in request body")}}if(r.includes("application/x-www-form-urlencoded")){let n=await s.text();if(n.length>t)throw new M("Payload too large");return Object.fromEntries(new URLSearchParams(n))}if(r.includes("multipart/form-data"))return await s.formData()}catch(n){throw n instanceof M?n:(e?.error({error:String(n)},"Error parsing request body"),new M("Failed to parse request body"))}return {}}function le(s){let e=new Map;if(!s)return e;let t=s.split(";");for(let r of t){let[n,...i]=r.trim().split("=");if(n){let u=i.join("=");e.set(n,u?decodeURIComponent(u):"");}}return e}function ae(s,e,t,r,n,i,u=null,a="en",C=null){let x=new URL(e.url),E=Object.fromEntries(x.searchParams),w=e.headers,R=200,z=new Map,X=le(w.get("cookie")||""),J=u?{...u,getSupportedLanguages:()=>C?.supportedLanguages||u.getSupportedLanguages(),getLanguage:()=>a||u.getLanguage()}:null,q={ip:s,request:e,params:t,query:E,headers:w,db:r,logger:n,i18n:J,lang:a,requestId:i,get statusCode(){return R},set statusCode(c){R=c;},body:null,state:{},json(c,m){return new Response(JSON.stringify(c),{status:m??R,headers:{"Content-Type":"application/json",...this._setCookieHeaders()}})},text(c,m){return new Response(c,{status:m??R,headers:{"Content-Type":"text/plain",...this._setCookieHeaders()}})},html(c,m){return new Response(c,{status:m??R,headers:{"Content-Type":"text/html; charset=utf-8",...this._setCookieHeaders()}})},redirect(c,m=302){return new Response(null,{status:m,headers:{Location:c,...this._setCookieHeaders()}})},file(c,m="application/octet-stream"){let f=Bun.file(c);return new Response(f,{headers:{"Content-Type":m,...this._setCookieHeaders()}})},setCookie(c,m,f={}){let v=`${c}=${encodeURIComponent(m)}`;return f.maxAge!==void 0&&(v+=`; Max-Age=${f.maxAge}`),f.expires&&(v+=`; Expires=${f.expires.toUTCString()}`),f.path&&(v+=`; Path=${f.path}`),f.domain&&(v+=`; Domain=${f.domain}`),f.secure&&(v+="; Secure"),f.httpOnly&&(v+="; HttpOnly"),f.sameSite&&(v+=`; SameSite=${f.sameSite}`),z.set(c,v),q},getCookie(c){return X.get(c)},deleteCookie(c,m={}){return q.setCookie(c,"",{...m,maxAge:0,path:m.path||"/"})},setHeader(c,m){return w.set(c,m),q},getHeader(c){return w.get(c)||void 0},status(c){return R=c,q},_setCookieHeaders(){let c={};return z.size>0&&(c["Set-Cookie"]=Array.from(z.values())),c}};return q}function ve(s,e){let t=s.headers.get("x-forwarded-for");if(t)return t.split(",").map(i=>i.trim())[0]||"unknown";let r=s.headers.get("x-real-ip");if(r)return r;if(e)try{let i=e.requestIP?.(s);if(i?.address)return i.address}catch{}return "unknown"}function Ae(s,e){let t=new Headers;if(!e.security||typeof e.security!="object"||!e.security.cors)return t;let r=typeof e.security.cors=="object"?e.security.cors:{},n=s.headers.get("Origin");if(n){typeof r.origin=="function"?r.origin(n)&&t.set("Access-Control-Allow-Origin",n):Array.isArray(r.origin)?r.origin.includes(n)&&t.set("Access-Control-Allow-Origin",n):typeof r.origin=="string"?t.set("Access-Control-Allow-Origin",r.origin):t.set("Access-Control-Allow-Origin",n);let i=r.methods||["GET","POST","PUT","DELETE","PATCH","OPTIONS"];t.set("Access-Control-Allow-Methods",i.join(", "));let u=r.allowedHeaders||["Content-Type","Authorization","X-Requested-With"];t.set("Access-Control-Allow-Headers",u.join(", ")),r.credentials&&t.set("Access-Control-Allow-Credentials","true"),r.maxAge&&t.set("Access-Control-Max-Age",r.maxAge.toString());}return t}function Ne(s,e){let t=i18n.getI18n();return t?t.t(s)??e??s:(console.warn("[ServerManager] i18n not initialized. Using default value or key."),e??s)}var _e=Ce;
2
- Object.defineProperty(exports,"DB",{enumerable:true,get:function(){return ue.DB}});Object.defineProperty(exports,"blob",{enumerable:true,get:function(){return ue.blob}});Object.defineProperty(exports,"column",{enumerable:true,get:function(){return ue.column}});Object.defineProperty(exports,"defaultValue",{enumerable:true,get:function(){return ue.defaultValue}});Object.defineProperty(exports,"index",{enumerable:true,get:function(){return ue.index}});Object.defineProperty(exports,"integer",{enumerable:true,get:function(){return ue.integer}});Object.defineProperty(exports,"notNull",{enumerable:true,get:function(){return ue.notNull}});Object.defineProperty(exports,"numeric",{enumerable:true,get:function(){return ue.numeric}});Object.defineProperty(exports,"primaryKey",{enumerable:true,get:function(){return ue.primaryKey}});Object.defineProperty(exports,"real",{enumerable:true,get:function(){return ue.real}});Object.defineProperty(exports,"references",{enumerable:true,get:function(){return ue.references}});Object.defineProperty(exports,"table",{enumerable:true,get:function(){return ue.table}});Object.defineProperty(exports,"text",{enumerable:true,get:function(){return ue.text}});Object.defineProperty(exports,"unique",{enumerable:true,get:function(){return ue.unique}});Object.defineProperty(exports,"Logger",{enumerable:true,get:function(){return logger.Logger}});Object.defineProperty(exports,"getI18n",{enumerable:true,get:function(){return i18n.getI18n}});Object.defineProperty(exports,"getLanguage",{enumerable:true,get:function(){return i18n.getLanguage}});Object.defineProperty(exports,"getSupportedLanguages",{enumerable:true,get:function(){return i18n.getSupportedLanguages}});Object.defineProperty(exports,"loadLanguage",{enumerable:true,get:function(){return i18n.loadLanguage}});Object.defineProperty(exports,"loadTranslations",{enumerable:true,get:function(){return i18n.loadTranslations}});Object.defineProperty(exports,"setLanguage",{enumerable:true,get:function(){return i18n.setLanguage}});Object.defineProperty(exports,"setupI18n",{enumerable:true,get:function(){return i18n.setupI18n}});Object.defineProperty(exports,"tLang",{enumerable:true,get:function(){return i18n.tLang}});Object.defineProperty(exports,"tParse",{enumerable:true,get:function(){return i18n.tParse}});exports.AppError=P;exports.DatabaseError=se;exports.RateLimitError=oe;exports.Router=G;exports.SecurityManager=B;exports.StaticFileServer=O;exports.TimeoutError=V;exports.ValidationError=M;exports.createStatic=Re;exports.default=_e;exports.server=Ce;exports.t=Ne;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var ce=require('@minejs/db'),me=require('crypto'),logger=require('@minejs/logger'),path=require('path'),fs=require('fs'),i18n=require('@minejs/i18n');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var ce__namespace=/*#__PURE__*/_interopNamespace(ce);var me__default=/*#__PURE__*/_interopDefault(me);var G=class{constructor(){this.routes=new Map;this.regexRoutes=[];}match(e,t){let r=`${e}:${t}`;if(this.routes.has(r)){let n=this.routes.get(r);return {handler:n.handler,params:{},metadata:n.metadata}}for(let n of this.regexRoutes)if(n.method===e){let i=t.match(n.pattern);if(i){let u=i.groups||{};return {handler:n.handler,params:u,metadata:n.metadata}}}return null}getAll(){let e=Array.from(this.routes.entries()).map(([r,n])=>{let i=r.indexOf(":"),u=r.substring(0,i),a=r.substring(i+1);return {method:u,path:a,handler:n.handler}}),t=this.regexRoutes.map(r=>{let n=r.key.indexOf(":");return {method:r.method,path:r.key.substring(n+1),handler:r.handler}});return [...e,...t]}clear(){this.routes.clear(),this.regexRoutes=[];}remove(e,t){let r=`${e}:${t}`;if(this.routes.has(r))return this.routes.delete(r),true;let n=this.regexRoutes.findIndex(i=>i.key===r);return n>=0?(this.regexRoutes.splice(n,1),true):false}register(e,t,r,n={}){let i=`${e}:${t}`;if(t.includes(":")||t.includes("*")){let u=this.pathToRegex(t),a=this.regexRoutes.findIndex(v=>v.key===i),T={pattern:u,method:e,handler:r,key:i,metadata:n};a>=0?this.regexRoutes[a]=T:this.regexRoutes.push(T);}else this.routes.set(i,{handler:r,metadata:n});}pathToRegex(e){let t=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return t=t.replace(/:(\w+)/g,"(?<$1>[^/]+)"),t=t.replace(/\*/g,".*"),new RegExp(`^${t}$`)}};var B=class{constructor(){this.rateLimitStore=new Map;this.csrfTokens=new Map;this.requestLog=new Map;this.MAX_REQUEST_LOG_SIZE=1e3;}checkRateLimit(e,t,r){let n=Date.now(),i=this.rateLimitStore.get(e);return i?n<i.reset?i.count>=t?false:(i.count++,true):(this.rateLimitStore.set(e,{count:1,reset:n+r}),true):(this.rateLimitStore.set(e,{count:1,reset:n+r}),true)}cleanupRateLimit(){let e=Date.now();for(let[t,r]of this.rateLimitStore.entries())e>r.reset&&this.rateLimitStore.delete(t);}generateCsrfToken(e,t=36e5){let r=me__default.default.randomBytes(32).toString("hex");return this.csrfTokens.set(r,{sessionId:e,expires:Date.now()+t}),r}validateCsrfToken(e,t){let r=this.csrfTokens.get(e);return r?Date.now()>r.expires?(this.csrfTokens.delete(e),false):r.sessionId===t?(this.csrfTokens.delete(e),true):false:false}cleanupCsrfTokens(){let e=Date.now();for(let[t,r]of this.csrfTokens.entries())e>r.expires&&this.csrfTokens.delete(t);}sanitizeHtml(e){return e?e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;"):""}sanitizeSql(e){return e?e.replace(/\\/g,"\\\\").replace(/;/g,"").replace(/'/g,"''").replace(/"/g,'\\"').replace(/\u0000/g,""):""}logRequest(e,t,r,n,i,u){if(this.requestLog.set(e,{timestamp:new Date().toISOString(),method:t,path:r,ip:n,status:i,duration:u}),this.requestLog.size>this.MAX_REQUEST_LOG_SIZE){let{value:a}=this.requestLog.keys().next()||{value:null};a&&this.requestLog.delete(a);}}getRequestLog(e){return this.requestLog.get(e)}getAllRequestLogs(){return Array.from(this.requestLog.values())}clearAll(){this.rateLimitStore.clear(),this.csrfTokens.clear(),this.requestLog.clear();}getStats(){return {rateLimitEntries:this.rateLimitStore.size,csrfTokens:this.csrfTokens.size,requestLogs:this.requestLog.size}}};var M=class extends Error{constructor(t,r=500,n){super(t);this.message=t;this.statusCode=r;this.code=n;this.name="AppError";}},I=class extends M{constructor(t,r){super(t,400,"VALIDATION_ERROR");this.issues=r;this.name="ValidationError";}},oe=class extends M{constructor(e){super(e,500,"DATABASE_ERROR"),this.name="DatabaseError";}},X=class extends M{constructor(e="Request timeout"){super(e,408,"TIMEOUT_ERROR"),this.name="TimeoutError";}},ie=class extends M{constructor(e="Too many requests"){super(e,429,"RATE_LIMIT_ERROR"),this.name="RateLimitError";}};var O=class{constructor(e){this.fileCache=new Map;this.CACHE_MAX_SIZE=1e3;if(!fs.existsSync(e.directory))throw new Error(`Static directory does not exist: ${e.directory}`);if(!fs.statSync(e.directory).isDirectory())throw new Error(`Static path is not a directory: ${e.directory}`);this.resolvedDir=path.resolve(e.directory),this.config={path:e.path,directory:e.directory,maxAge:e.maxAge??3600,index:e.index??["index.html"],dotfiles:e.dotfiles??"deny",etag:e.etag??true,lastModified:e.lastModified??true,immutable:e.immutable??false,extensions:e.extensions??[],fallthrough:e.fallthrough??false,setHeaders:e.setHeaders};}handler(){return async e=>{let t=e.request.url,n=new URL(t).pathname;n.startsWith(this.config.path)&&(n=n.slice(this.config.path.length));try{n=decodeURIComponent(n);}catch{return e.json({error:"Invalid URL encoding"},400)}if(n.includes("..")||n.includes("\\"))return e.json({error:"Forbidden"},403);if(this.config.dotfiles!=="allow"&&n.split("/").some(a=>a.startsWith(".")))return this.config.dotfiles==="deny"?e.json({error:"Forbidden"},403):this.handleNotFound(e);let i=this.resolveFilePath(n);if(!i)return this.handleNotFound(e);if(!this.isPathSafe(i))return e.json({error:"Forbidden"},403);if(!fs.existsSync(i))return this.handleNotFound(e);let u=fs.statSync(i);return u.isDirectory()?this.serveDirectory(e,i,n):this.serveFile(e,i,u)}}getPathPattern(){return `${this.config.path}/*`}resolveFilePath(e){e.startsWith("/")&&(e=e.slice(1));let t=path.join(this.resolvedDir,e);if(!fs.existsSync(t)&&this.config.extensions.length>0)for(let r of this.config.extensions){let n=`${t}.${r}`;if(fs.existsSync(n))return n}return t}isPathSafe(e){return !path.relative(this.resolvedDir,path.resolve(e)).startsWith("..")&&!path.resolve(e).startsWith("..")}async serveDirectory(e,t,r){for(let n of this.config.index){let i=path.join(t,n);if(fs.existsSync(i)){let u=fs.statSync(i);if(u.isFile())return this.serveFile(e,i,u)}}return this.handleNotFound(e)}async serveFile(e,t,r){let n=e.request.method.toUpperCase();if(n!=="GET"&&n!=="HEAD")return e.json({error:"Method not allowed"},405);let i=t,u=this.fileCache.get(i);if(u&&u.mtime!==r.mtimeMs&&(u=void 0),!u){if(u={etag:this.generateEtag(r),lastModified:new Date(r.mtime),size:r.size,mtime:r.mtimeMs},this.fileCache.size>=this.CACHE_MAX_SIZE){let x=this.fileCache.keys().next().value;x&&this.fileCache.delete(x);}this.fileCache.set(i,u);}let a=e.request.headers.get("if-none-match"),T=e.request.headers.get("if-modified-since");if(this.config.etag&&a===u.etag)return new Response(null,{status:304,headers:this.buildHeaders(t,u)});if(this.config.lastModified&&T){let x=new Date(T);if(u.lastModified<=x)return new Response(null,{status:304,headers:this.buildHeaders(t,u)})}let v=Bun.file(t),h=this.buildHeaders(t,u);return this.config.setHeaders&&this.config.setHeaders(e,t),n==="HEAD"?new Response(null,{status:200,headers:h}):new Response(v,{status:200,headers:h})}buildHeaders(e,t){let r=new Headers,n=this.getMimeType(e);if(r.set("Content-Type",n),r.set("Content-Length",t.size.toString()),this.config.etag&&r.set("ETag",t.etag),this.config.lastModified&&r.set("Last-Modified",t.lastModified.toUTCString()),this.config.maxAge>0){let i=`public, max-age=${this.config.maxAge}`;this.config.immutable&&(i+=", immutable"),r.set("Cache-Control",i);}else r.set("Cache-Control","no-cache");return r.set("Accept-Ranges","bytes"),r}generateEtag(e){return `"${e.size.toString(16)}-${e.mtimeMs.toString(16)}"`}getMimeType(e){let t=path.extname(e).toLowerCase();return be[t]||"application/octet-stream"}handleNotFound(e){return this.config.fallthrough?e.json({error:"Not Found"},404):e.json({error:"Not Found"},404)}clearCache(){this.fileCache.clear();}getCacheStats(){return {entries:this.fileCache.size,maxSize:this.CACHE_MAX_SIZE}}};function Re(s){return new O(s)}var be={".html":"text/html; charset=utf-8",".htm":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".txt":"text/plain; charset=utf-8",".xml":"text/xml; charset=utf-8",".csv":"text/csv; charset=utf-8",".md":"text/markdown; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".jsonld":"application/ld+json",".map":"application/json; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".webp":"image/webp",".avif":"image/avif",".bmp":"image/bmp",".tiff":"image/tiff",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".aac":"audio/aac",".flac":"audio/flac",".mp4":"video/mp4",".webm":"video/webm",".ogv":"video/ogg",".mov":"video/quicktime",".avi":"video/x-msvideo",".mkv":"video/x-matroska",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".zip":"application/zip",".rar":"application/x-rar-compressed",".7z":"application/x-7z-compressed",".tar":"application/x-tar",".gz":"application/gzip",".wasm":"application/wasm",".manifest":"text/cache-manifest",".webmanifest":"application/manifest+json"};var J=new B,k=new G;async function Ce(s={}){let e=Number(s.port)||3e3,t=s.hostname||"localhost",r=s.maxRequestSize||10*1024*1024,n=s.requestTimeout||3e4,i=s.gracefulShutdownTimeout||1e4,u=typeof s.logging=="object"?s.logging:{},a=s.logging?new logger.Logger(u.level||"info",u.pretty):null,T=null,v=null;s.i18n&&(T=i18n.getI18n(),v=s.i18n===true?{defaultLanguage:"en",supportedLanguages:["en"]}:s.i18n,T&&await i18n.setupI18n(v));let h=new Map,x=[],E=new Set,q=[],l=setInterval(()=>{J.cleanupRateLimit(),J.cleanupCsrfTokens();},120*1e3);async function m(o,c){let p=Date.now(),d=crypto.randomUUID(),y=new URL(o.url).pathname,A=o.method.toUpperCase(),w=Se(o,c);E.add(d);try{let b=o.headers.get("content-length");if(b&&parseInt(b)>r)return a?.warn({requestId:d,size:b,ip:w},"Request too large"),new Response(JSON.stringify({error:"Payload too large"}),{status:413,headers:{"Content-Type":"application/json"}});let j=Ae(o,s);if(A==="OPTIONS")return new Response(null,{status:204,headers:j});if(s.security&&typeof s.security=="object"&&s.security.rateLimit){let H=typeof s.security.rateLimit=="object"?s.security.rateLimit:{},D=H.max||100,K=H.windowMs||6e4,se=H.keyGenerator?H.keyGenerator({request:o,ip:w}):w;if(!J.checkRateLimit(se,D,K))return a?.warn({requestId:d,ip:w,key:se},"Rate limit exceeded"),new Response(JSON.stringify({error:H.message||"Too many requests"}),{status:429,headers:{"Content-Type":"application/json"}})}let f=null;["POST","PUT","PATCH"].includes(A)&&(f=await ve(o,a,r));let L=h.get("default"),C=Object.fromEntries(new URL(o.url).searchParams),le=o.headers.get("cookie")||"",pe=de(le).get("lang"),ee=C.lang||pe||o.headers.get("Accept-Language")?.split(",")[0]?.split("-")[0]||v?.defaultLanguage||"en",F=k.match(A,y);if(!F){let H=ue(w,o,{},L,a,d,ee);if(a?.warn({requestId:d,method:A,path:y,ip:w},"Route not found"),s.onError)try{return await s.onError(404,y,A)}catch(D){a?.error({error:String(D),requestId:d},"Error in onError handler");}return H.json({error:"Not Found",path:y},404)}let U=ue(w,o,F.params||{},L,a,d,ee);U.body=f,U.request=o;let te=new AbortController,ge=new Promise((H,D)=>{let K=setTimeout(()=>{te.abort(),D(new X("Request timeout"));},n);te.signal.addEventListener("abort",()=>clearTimeout(K));}),re=F.metadata?.middlewares||[],W;re.length>0?W=R(U,re,F.handler):W=Promise.resolve(F.handler(U));let $=await Promise.race([W,ge]),P=new Headers($.headers);j.forEach((H,D)=>{P.has(D)||P.set(D,H);}),P.set("X-Request-ID",d),P.set("X-Content-Type-Options","nosniff"),P.set("X-Frame-Options","DENY"),P.set("X-XSS-Protection","1; mode=block"),P.set("Referrer-Policy","strict-origin-when-cross-origin");let ne=Date.now()-p;return J.logRequest(d,A,y,w,$.status,ne),a?.info({requestId:d,method:A,path:y,status:$.status,duration:ne,ip:w},"Request completed"),new Response($.body,{status:$.status,headers:P})}catch(b){if(b instanceof M){if(a?.warn({error:b.message,requestId:d,ip:w},`App error: ${b.message}`),s.onError)try{return await s.onError(b.statusCode,y,A)}catch(f){a?.error({error:String(f),requestId:d},"Error in onError handler");}return new Response(JSON.stringify({error:b.message,code:b.code,requestId:d}),{status:b.statusCode,headers:{"Content-Type":"application/json"}})}a?.error({error:String(b),requestId:d,ip:w},"Unhandled error");let j=process.env.NODE_ENV==="production"?"Internal Server Error":b.message;if(s.onError)try{return await s.onError(500,y,A)}catch(f){a?.error({error:String(f),requestId:d},"Error in onError handler");}return new Response(JSON.stringify({error:j,requestId:d}),{status:500,headers:{"Content-Type":"application/json"}})}finally{E.delete(d);}}async function R(o,c,p){let d=0,g=null,y=o.json.bind(o),A=o.text.bind(o),w=o.html.bind(o),b=o.redirect.bind(o);o.json=function(f,L){let C=y(f,L);return g=C,C},o.text=function(f,L){let C=A(f,L);return g=C,C},o.html=function(f,L){let C=w(f,L);return g=C,C},o.redirect=function(f,L){let C=b(f,L);return g=C,C};async function j(){if(!g&&d<c.length){let f=c[d];d++,await f(o,j);}}return await j(),o.json=y,o.text=A,o.html=w,o.redirect=b,g||p(o)}let S={method:"GET",path:"/health",handler:o=>o.json({status:"healthy",timestamp:new Date().toISOString(),uptime:process.uptime(),activeRequests:E.size})},V={method:"GET",path:"/readiness",handler:o=>{let c=h.size>0,p=c||h.size===0;return o.json({ready:p,checks:{database:c?"connected":"not configured",activeRequests:E.size},timestamp:new Date().toISOString()},p?200:503)}};if(s.routes&&s.routes.forEach(o=>{x.push(o),(Array.isArray(o.method)?o.method:[o.method]).forEach(p=>{k.register(p,o.path,o.handler,o);});}),s.static){let o=Array.isArray(s.static)?s.static:[s.static];for(let c of o)try{let d=new O(c).handler(),g={method:"GET",path:c.path==="/"?"/*":`${c.path}/*`,handler:d};x.push(g);let y=c.path==="/"?"/":c.path;q.push({prefix:y,handler:d}),c.path==="/"?(k.register("GET","/",d,g),k.register("HEAD","/",d,g),k.register("GET","/*",d,g),k.register("HEAD","/*",d,g)):(k.register("GET",`${c.path}/*`,d,g),k.register("HEAD",`${c.path}/*`,d,g));}catch(p){throw a?.error({error:String(p),path:c.path},"Failed to initialize static file server"),p}}x.push(S,V),k.register("GET","/health",S.handler,S),k.register("GET","/readiness",V.handler,V);let z=null,_={app:null,logger:a,db:h,bunServer:null,async start(){if(s.database){let c=Array.isArray(s.database)?s.database:[s.database];for(let p of c){let d=p.name||"default";try{if(typeof p.connection=="string"){let g=new ce__namespace.DB(p.connection);if(p.schema&&typeof p.schema=="object")for(let[,y]of Object.entries(p.schema))y&&typeof y=="object"&&g.defineSchema(y);h.set(d,g),a?.info({name:d,connection:p.connection},"\u2714 Database connected");}else throw new Error(`Database connection must be a string path (got ${typeof p.connection})`)}catch(g){throw a?.error({error:String(g),name:d},"Failed to connect to database"),g}}}z=Bun.serve({port:e,hostname:t,fetch:(c,p)=>m(c,p)}),_.bunServer=z;let o=`http://${t}:${e}`;if(a?.info({url:o},"\u2714 Server started"),s.onStartup)try{await s.onStartup(_);}catch(c){a?.error({error:String(c)},"Error in startup handler");}if(s.onReady)try{await s.onReady(_,h);}catch(c){a?.error({error:String(c)},"Error in ready handler");}},async stop(){if(a?.info("Stopping server..."),E.size>0){a?.info({count:E.size},"Waiting for active requests...");let o=Date.now()+i;for(;E.size>0&&Date.now()<o;)await new Promise(c=>setTimeout(c,100));E.size>0&&a?.warn({count:E.size},"Force closing with active requests");}if(clearInterval(l),s.onShutdown)try{await s.onShutdown();}catch(o){a?.error({error:String(o)},"Error in shutdown handler");}for(let[o,c]of h.entries())try{c&&typeof c.close=="function"&&c.close(),a?.info({name:o},"Database closed");}catch(p){a?.error({error:String(p),name:o},"Error closing database");}z&&typeof z.stop=="function"&&(z.stop(),a?.info("Bun server stopped")),a?.info("Server stopped successfully");},addRoute(o){x.push(o),(Array.isArray(o.method)?o.method:[o.method]).forEach(p=>{k.register(p,o.path,o.handler,o);}),a?.info({method:o.method,path:o.path},"Route added");},addRoutes(o){o.forEach(c=>this.addRoute(c));},getRoutes(){return x}};return _}async function ve(s,e,t){let r=s.headers.get("content-type")||"";try{if(r.includes("application/json")){let n=await s.text();if(n.length>t)throw new I("Payload too large");if(!n.trim())return {};try{return JSON.parse(n)}catch(i){throw e?.warn({error:String(i),bodyPreview:n.substring(0,100)},"Invalid JSON in request body"),new I("Invalid JSON in request body")}}if(r.includes("application/x-www-form-urlencoded")){let n=await s.text();if(n.length>t)throw new I("Payload too large");return Object.fromEntries(new URLSearchParams(n))}if(r.includes("multipart/form-data"))return await s.formData()}catch(n){throw n instanceof I?n:(e?.error({error:String(n)},"Error parsing request body"),new I("Failed to parse request body"))}return {}}function de(s){let e=new Map;if(!s)return e;let t=s.split(";");for(let r of t){let[n,...i]=r.trim().split("=");if(n){let u=i.join("=");e.set(n,u?decodeURIComponent(u):"");}}return e}function ue(s,e,t,r,n,i,u="en"){let a=new URL(e.url),T=Object.fromEntries(a.searchParams),v=e.headers,h=200,x=new Map,E=de(v.get("cookie")||""),q={ip:s,request:e,params:t,query:T,headers:v,db:r,logger:n,lang:u,requestId:i,get statusCode(){return h},set statusCode(l){h=l;},body:null,state:{},json(l,m){return new Response(JSON.stringify(l),{status:m??h,headers:{"Content-Type":"application/json",...this._setCookieHeaders()}})},text(l,m){return new Response(l,{status:m??h,headers:{"Content-Type":"text/plain",...this._setCookieHeaders()}})},html(l,m){return new Response(l,{status:m??h,headers:{"Content-Type":"text/html; charset=utf-8",...this._setCookieHeaders()}})},redirect(l,m=302){return new Response(null,{status:m,headers:{Location:l,...this._setCookieHeaders()}})},file(l,m="application/octet-stream"){let R=Bun.file(l);return new Response(R,{headers:{"Content-Type":m,...this._setCookieHeaders()}})},setCookie(l,m,R={}){let S=`${l}=${encodeURIComponent(m)}`;return R.maxAge!==void 0&&(S+=`; Max-Age=${R.maxAge}`),R.expires&&(S+=`; Expires=${R.expires.toUTCString()}`),R.path&&(S+=`; Path=${R.path}`),R.domain&&(S+=`; Domain=${R.domain}`),R.secure&&(S+="; Secure"),R.httpOnly&&(S+="; HttpOnly"),R.sameSite&&(S+=`; SameSite=${R.sameSite}`),x.set(l,S),q},getCookie(l){return E.get(l)},deleteCookie(l,m={}){return q.setCookie(l,"",{...m,maxAge:0,path:m.path||"/"})},setHeader(l,m){return v.set(l,m),q},getHeader(l){return v.get(l)||void 0},status(l){return h=l,q},_setCookieHeaders(){let l={};return x.size>0&&(l["Set-Cookie"]=Array.from(x.values())),l}};return q}function Se(s,e){let t=s.headers.get("x-forwarded-for");if(t)return t.split(",").map(i=>i.trim())[0]||"unknown";let r=s.headers.get("x-real-ip");if(r)return r;if(e)try{let i=e.requestIP?.(s);if(i?.address)return i.address}catch{}return "unknown"}function Ae(s,e){let t=new Headers;if(!e.security||typeof e.security!="object"||!e.security.cors)return t;let r=typeof e.security.cors=="object"?e.security.cors:{},n=s.headers.get("Origin");if(n){typeof r.origin=="function"?r.origin(n)&&t.set("Access-Control-Allow-Origin",n):Array.isArray(r.origin)?r.origin.includes(n)&&t.set("Access-Control-Allow-Origin",n):typeof r.origin=="string"?t.set("Access-Control-Allow-Origin",r.origin):t.set("Access-Control-Allow-Origin",n);let i=r.methods||["GET","POST","PUT","DELETE","PATCH","OPTIONS"];t.set("Access-Control-Allow-Methods",i.join(", "));let u=r.allowedHeaders||["Content-Type","Authorization","X-Requested-With"];t.set("Access-Control-Allow-Headers",u.join(", ")),r.credentials&&t.set("Access-Control-Allow-Credentials","true"),r.maxAge&&t.set("Access-Control-Max-Age",r.maxAge.toString());}return t}function Ne(s,e){let t=i18n.getI18n();return t?t.t(s)??e??s:(console.warn("[ServerManager] i18n not initialized. Using default value or key."),e??s)}function _e(s,e,t){let r=i18n.getI18n();return r?r.tLang(s,e)??t??e:(console.warn("[ServerManager] i18n not initialized. Using default value or key."),t??e)}var Ue=Ce;
2
+ Object.defineProperty(exports,"DB",{enumerable:true,get:function(){return ce.DB}});Object.defineProperty(exports,"blob",{enumerable:true,get:function(){return ce.blob}});Object.defineProperty(exports,"column",{enumerable:true,get:function(){return ce.column}});Object.defineProperty(exports,"defaultValue",{enumerable:true,get:function(){return ce.defaultValue}});Object.defineProperty(exports,"index",{enumerable:true,get:function(){return ce.index}});Object.defineProperty(exports,"integer",{enumerable:true,get:function(){return ce.integer}});Object.defineProperty(exports,"notNull",{enumerable:true,get:function(){return ce.notNull}});Object.defineProperty(exports,"numeric",{enumerable:true,get:function(){return ce.numeric}});Object.defineProperty(exports,"primaryKey",{enumerable:true,get:function(){return ce.primaryKey}});Object.defineProperty(exports,"real",{enumerable:true,get:function(){return ce.real}});Object.defineProperty(exports,"references",{enumerable:true,get:function(){return ce.references}});Object.defineProperty(exports,"table",{enumerable:true,get:function(){return ce.table}});Object.defineProperty(exports,"text",{enumerable:true,get:function(){return ce.text}});Object.defineProperty(exports,"unique",{enumerable:true,get:function(){return ce.unique}});Object.defineProperty(exports,"Logger",{enumerable:true,get:function(){return logger.Logger}});Object.defineProperty(exports,"getI18n",{enumerable:true,get:function(){return i18n.getI18n}});Object.defineProperty(exports,"getLanguage",{enumerable:true,get:function(){return i18n.getLanguage}});Object.defineProperty(exports,"getSupportedLanguages",{enumerable:true,get:function(){return i18n.getSupportedLanguages}});Object.defineProperty(exports,"loadLanguage",{enumerable:true,get:function(){return i18n.loadLanguage}});Object.defineProperty(exports,"loadTranslations",{enumerable:true,get:function(){return i18n.loadTranslations}});Object.defineProperty(exports,"setLanguage",{enumerable:true,get:function(){return i18n.setLanguage}});Object.defineProperty(exports,"setupI18n",{enumerable:true,get:function(){return i18n.setupI18n}});Object.defineProperty(exports,"tParse",{enumerable:true,get:function(){return i18n.tParse}});exports.AppError=M;exports.DatabaseError=oe;exports.RateLimitError=ie;exports.Router=G;exports.SecurityManager=B;exports.StaticFileServer=O;exports.TimeoutError=X;exports.ValidationError=I;exports.createStatic=Re;exports.default=Ue;exports.server=Ce;exports.t=Ne;exports.tLang=_e;//# sourceMappingURL=index.cjs.map
3
3
  //# sourceMappingURL=index.cjs.map