@je-es/server 0.1.5 → 0.1.6

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/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mod/router.ts","../src/mod/security.ts","../src/types.d.ts","../src/mod/static.ts","../src/main.ts"],"names":["Router","method","path","key","route","match","params","staticRoutes","colonIndex","dynamicRoutes","index","r","handler","metadata","pattern","existingIndex","SecurityManager","max","windowMs","now","record","sessionId","ttl","token","crypto","stored","data","html","input","id","ip","status","duration","first","AppError","message","statusCode","code","ValidationError","issues","DatabaseError","TimeoutError","RateLimitError","StaticFileServer","config","existsSync","statSync","resolve","ctx","requestPath","pathname","p","filePath","stats","join","ext","withExt","relative","dirPath","_","indexFile","indexPath","cacheKey","cacheEntry","firstKey","ifNoneMatch","ifModifiedSince","ifModDate","file","headers","cache","mimeType","cacheControl","extname","MIME_TYPES","createStatic","security","router","server","port","hostname","maxReqSize","requestTimeout","gracefulShutdownTimeout","logCfg","logger","Logger","dbs","routes","activeRequests","cleanupInterval","handleRequest","request","startTime","requestId","getClientIp","contentLength","corsHeaders","handleCors","rateLimitCfg","rateLimitKey","body","parseBody","defaultDb","routeMatch","createAppContext","controller","timeoutPromise","reject","middlewares","handlerPromise","executeMiddlewares","response","resHeaders","value","error","errorMessage","earlyResponse","originalJson","originalText","originalHtml","originalRedirect","url","next","middleware","healthRoute","c","readinessRoute","dbConnected","ready","m","staticConfigs","staticCfg","staticRoute","bunServer","instance","dbConfigs","dbCfg","dbName","db","tableSchema","deadline","e","name","maxSize","contentType","text","parseCookies","cookieHeader","cookies","pairs","pair","valueParts","query","cookieStore","parsedCookies","options","cookie","h","forwarded","realIp","remoteAddress","corsConfig","origin","methods","allowedHeaders","main_default"],"mappings":"qUAyCW,IAAMA,CAAAA,CAAN,KAAa,CAAb,WAAA,EAAA,CAIC,IAAA,CAAQ,MAAA,CAAS,IAAI,GAAA,CACrB,IAAA,CAAQ,WAAA,CAA2B,GAAC,CAOpC,KAAA,CAAMC,CAAAA,CAAgBC,CAAAA,CAAiC,CACnD,IAAMC,CAAAA,CAAM,CAAA,EAAGF,CAAM,CAAA,CAAA,EAAIC,CAAI,CAAA,CAAA,CAG7B,GAAI,IAAA,CAAK,OAAO,GAAA,CAAIC,CAAG,CAAA,CAAG,CACtB,IAAMC,CAAAA,CAAQ,IAAA,CAAK,MAAA,CAAO,GAAA,CAAID,CAAG,CAAA,CACjC,OAAO,CACH,OAAA,CAASC,CAAAA,CAAM,OAAA,CACf,MAAA,CAAQ,EAAC,CACT,QAAA,CAAUA,CAAAA,CAAM,QACpB,CACJ,CAGA,IAAA,IAAWA,CAAAA,IAAS,IAAA,CAAK,WAAA,CACrB,GAAIA,CAAAA,CAAM,SAAWH,CAAAA,CAAQ,CACzB,IAAMI,CAAAA,CAAQH,CAAAA,CAAK,KAAA,CAAME,CAAAA,CAAM,OAAO,CAAA,CACtC,GAAIC,CAAAA,CAAO,CAEP,IAAMC,CAAAA,CAASD,EAAM,MAAA,EAAU,EAAC,CAChC,OAAO,CACH,OAAA,CAASD,CAAAA,CAAM,OAAA,CACf,MAAA,CAAAE,CAAAA,CACA,QAAA,CAAUF,CAAAA,CAAM,QACpB,CACJ,CACJ,CAGJ,OAAO,IACX,CAEA,MAAA,EAAsB,CAClB,IAAMG,CAAAA,CAAe,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,CAAC,CAACJ,CAAAA,CAAKC,CAAK,CAAA,GAAM,CACzE,IAAMI,CAAAA,CAAaL,CAAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,CAC5BF,CAAAA,CAASE,CAAAA,CAAI,UAAU,CAAA,CAAGK,CAAU,CAAA,CACpCN,CAAAA,CAAOC,CAAAA,CAAI,SAAA,CAAUK,CAAAA,CAAa,CAAC,CAAA,CACzC,OAAO,CAAE,MAAA,CAAAP,CAAAA,CAAQ,IAAA,CAAAC,EAAM,OAAA,CAASE,CAAAA,CAAM,OAAQ,CAClD,CAAC,CAAA,CAEKK,CAAAA,CAAgB,IAAA,CAAK,WAAA,CAAY,GAAA,CAAIL,CAAAA,EAAS,CAChD,IAAMI,CAAAA,CAAaJ,EAAM,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,CACxC,OAAO,CACH,MAAA,CAAQA,CAAAA,CAAM,MAAA,CACd,IAAA,CAAMA,CAAAA,CAAM,GAAA,CAAI,SAAA,CAAUI,CAAAA,CAAa,CAAC,CAAA,CACxC,OAAA,CAASJ,CAAAA,CAAM,OACnB,CACJ,CAAC,CAAA,CAED,OAAO,CAAC,GAAGG,CAAAA,CAAc,GAAGE,CAAa,CAC7C,CAEA,OAAc,CACV,IAAA,CAAK,MAAA,CAAO,KAAA,EAAM,CAClB,IAAA,CAAK,WAAA,CAAc,GACvB,CAEA,MAAA,CAAOR,CAAAA,CAAgBC,CAAAA,CAAuB,CAC1C,IAAMC,CAAAA,CAAM,CAAA,EAAGF,CAAM,CAAA,CAAA,EAAIC,CAAI,CAAA,CAAA,CAE7B,GAAI,IAAA,CAAK,MAAA,CAAO,GAAA,CAAIC,CAAG,CAAA,CACnB,OAAA,IAAA,CAAK,MAAA,CAAO,MAAA,CAAOA,CAAG,CAAA,CACf,IAAA,CAGX,IAAMO,CAAAA,CAAQ,IAAA,CAAK,WAAA,CAAY,SAAA,CAAUC,CAAAA,EAAKA,CAAAA,CAAE,GAAA,GAAQR,CAAG,CAAA,CAC3D,OAAIO,CAAAA,EAAS,CAAA,EACT,IAAA,CAAK,WAAA,CAAY,MAAA,CAAOA,CAAAA,CAAO,CAAC,CAAA,CACzB,IAAA,EAGJ,KACX,CAEA,QAAA,CAAST,CAAAA,CAAgBC,CAAAA,CAAcU,CAAAA,CAAuBC,CAAAA,CAAoB,GAAU,CACxF,IAAMV,CAAAA,CAAM,CAAA,EAAGF,CAAM,CAAA,CAAA,EAAIC,CAAI,CAAA,CAAA,CAG7B,GAAIA,CAAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAKA,CAAAA,CAAK,SAAS,GAAG,CAAA,CAAG,CAE1C,IAAMY,CAAAA,CAAU,IAAA,CAAK,WAAA,CAAYZ,CAAI,CAAA,CAG/Ba,CAAAA,CAAgB,IAAA,CAAK,WAAA,CAAY,SAAA,CAAUJ,CAAAA,EAAKA,EAAE,GAAA,GAAQR,CAAG,CAAA,CAE7DC,CAAAA,CAAoB,CACtB,OAAA,CAAAU,CAAAA,CACA,MAAA,CAAAb,CAAAA,CACA,OAAA,CAAAW,CAAAA,CACA,GAAA,CAAAT,CAAAA,CACA,QAAA,CAAAU,CACJ,CAAA,CAEIE,CAAAA,EAAiB,CAAA,CAEjB,IAAA,CAAK,WAAA,CAAYA,CAAa,CAAA,CAAIX,CAAAA,CAGlC,IAAA,CAAK,WAAA,CAAY,IAAA,CAAKA,CAAK,EAEnC,CAAA,KAEI,IAAA,CAAK,OAAO,GAAA,CAAID,CAAAA,CAAK,CAAE,OAAA,CAAAS,CAAAA,CAAS,QAAA,CAAAC,CAAS,CAAC,EAElD,CAOQ,WAAA,CAAYX,CAAAA,CAAsB,CAEtC,IAAIY,CAAAA,CAAUZ,CAAAA,CAAK,OAAA,CAAQ,oBAAA,CAAsB,MAAM,CAAA,CAGvD,OAAAY,CAAAA,CAAUA,CAAAA,CAAQ,OAAA,CAAQ,SAAA,CAAW,cAAc,CAAA,CAGnDA,CAAAA,CAAUA,CAAAA,CAAQ,OAAA,CAAQ,MAAO,IAAI,CAAA,CAE9B,IAAI,MAAA,CAAO,CAAA,CAAA,EAAIA,CAAO,CAAA,CAAA,CAAG,CACpC,CAIR,ECpIO,IAAME,CAAAA,CAAN,KAAsB,CAAtB,WAAA,EAAA,CAIC,IAAA,CAAQ,cAAA,CAAiB,IAAI,GAAA,CAC7B,IAAA,CAAQ,UAAA,CAAa,IAAI,GAAA,CACzB,IAAA,CAAQ,UAAA,CAAa,IAAI,GAAA,CAEzB,KAAiB,oBAAA,CAAuB,IAAA,CAQxC,cAAA,CAAeb,CAAAA,CAAac,CAAAA,CAAaC,CAAAA,CAA2B,CAChE,IAAMC,CAAAA,CAAM,IAAA,CAAK,GAAA,EAAI,CACfC,CAAAA,CAAS,IAAA,CAAK,eAAe,GAAA,CAAIjB,CAAG,CAAA,CAE1C,OAAIiB,CAAAA,CACID,CAAAA,CAAMC,CAAAA,CAAO,KAAA,CAETA,CAAAA,CAAO,KAAA,EAASH,CAAAA,CACT,KAAA,EAEXG,CAAAA,CAAO,KAAA,EAAA,CACA,OAGP,IAAA,CAAK,cAAA,CAAe,GAAA,CAAIjB,CAAAA,CAAK,CAAE,KAAA,CAAO,CAAA,CAAG,KAAA,CAAOgB,CAAAA,CAAMD,CAAS,CAAC,CAAA,CACzD,IAAA,CAAA,EAIX,IAAA,CAAK,cAAA,CAAe,GAAA,CAAIf,CAAAA,CAAK,CAAE,KAAA,CAAO,CAAA,CAAG,KAAA,CAAOgB,CAAAA,CAAMD,CAAS,CAAC,CAAA,CACzD,IAAA,CAEf,CAGA,gBAAA,EAAyB,CACrB,IAAMC,EAAM,IAAA,CAAK,GAAA,EAAI,CACrB,IAAA,GAAW,CAAChB,CAAAA,CAAKiB,CAAM,CAAA,GAAK,IAAA,CAAK,cAAA,CAAe,OAAA,EAAQ,CAChDD,CAAAA,CAAMC,CAAAA,CAAO,KAAA,EACb,IAAA,CAAK,cAAA,CAAe,MAAA,CAAOjB,CAAG,EAG1C,CAGA,iBAAA,CAAkBkB,CAAAA,CAAmBC,CAAAA,CAAM,IAAA,CAAiB,CACxD,IAAMC,CAAAA,CAAQC,EAAAA,CAAO,WAAA,CAAY,EAAE,CAAA,CAAE,QAAA,CAAS,KAAK,CAAA,CACnD,OAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAID,CAAAA,CAAO,CACvB,SAAA,CAAAF,CAAAA,CACA,OAAA,CAAS,IAAA,CAAK,GAAA,EAAI,CAAIC,CAC1B,CAAC,CAAA,CACMC,CACX,CAGA,iBAAA,CAAkBA,CAAAA,CAAeF,CAAAA,CAA4B,CACzD,IAAMI,CAAAA,CAAS,IAAA,CAAK,UAAA,CAAW,GAAA,CAAIF,CAAK,EAExC,OAAKE,CAAAA,CAKD,IAAA,CAAK,GAAA,EAAI,CAAIA,CAAAA,CAAO,OAAA,EACpB,IAAA,CAAK,UAAA,CAAW,MAAA,CAAOF,CAAK,CAAA,CACrB,KAAA,EAIPE,CAAAA,CAAO,YAAcJ,CAAAA,EACrB,IAAA,CAAK,UAAA,CAAW,MAAA,CAAOE,CAAK,CAAA,CACrB,IAAA,EAGJ,KAAA,CAfI,KAgBf,CAGA,iBAAA,EAA0B,CACtB,IAAMJ,CAAAA,CAAM,KAAK,GAAA,EAAI,CACrB,IAAA,GAAW,CAACI,CAAAA,CAAOG,CAAI,CAAA,GAAK,IAAA,CAAK,UAAA,CAAW,OAAA,EAAQ,CAC5CP,CAAAA,CAAMO,CAAAA,CAAK,OAAA,EACX,IAAA,CAAK,UAAA,CAAW,MAAA,CAAOH,CAAK,EAGxC,CAGA,YAAA,CAAaI,CAAAA,CAAsB,CAC/B,OAAKA,CAAAA,CAEEA,CAAAA,CACF,OAAA,CAAQ,IAAA,CAAM,OAAO,CAAA,CACrB,QAAQ,IAAA,CAAM,MAAM,CAAA,CACpB,OAAA,CAAQ,IAAA,CAAM,MAAM,CAAA,CACpB,OAAA,CAAQ,IAAA,CAAM,QAAQ,CAAA,CACtB,OAAA,CAAQ,IAAA,CAAM,QAAQ,EACtB,OAAA,CAAQ,KAAA,CAAO,QAAQ,CAAA,CARV,EAStB,CAGA,WAAA,CAAYC,CAAAA,CAAuB,CAC/B,OAAKA,CAAAA,CAEEA,CAAAA,CACF,OAAA,CAAQ,KAAA,CAAO,MAAM,CAAA,CACrB,OAAA,CAAQ,IAAA,CAAM,EAAE,CAAA,CAChB,OAAA,CAAQ,IAAA,CAAM,IAAI,CAAA,CAClB,OAAA,CAAQ,IAAA,CAAM,KAAK,CAAA,CAEnB,OAAA,CAAQ,SAAA,CAAW,EAAE,CAAA,CARP,EASvB,CAGA,UAAA,CACIC,CAAAA,CACA5B,CAAAA,CACAC,CAAAA,CACA4B,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACI,CAWJ,GAVA,IAAA,CAAK,UAAA,CAAW,IAAIH,CAAAA,CAAI,CACpB,SAAA,CAAW,IAAI,IAAA,EAAK,CAAE,WAAA,EAAY,CAClC,MAAA,CAAA5B,CAAAA,CACA,IAAA,CAAAC,CAAAA,CACA,EAAA,CAAA4B,CAAAA,CACA,OAAAC,CAAAA,CACA,QAAA,CAAAC,CACJ,CAAC,CAAA,CAGG,IAAA,CAAK,UAAA,CAAW,IAAA,CAAO,IAAA,CAAK,oBAAA,CAAsB,CAClD,GAAM,CAAE,KAAA,CAAOC,CAAM,CAAA,CAAI,IAAA,CAAK,UAAA,CAAW,IAAA,EAAK,CAAE,IAAA,EAAK,EAAK,CAAE,KAAA,CAAO,IAAK,CAAA,CACpEA,CAAAA,EACA,IAAA,CAAK,UAAA,CAAW,MAAA,CAAOA,CAAK,EAEpC,CACJ,CAGA,aAAA,CAAcJ,CAAAA,CAAyC,CACnD,OAAO,IAAA,CAAK,UAAA,CAAW,GAAA,CAAIA,CAAE,CACjC,CAGA,iBAAA,EAAuC,CACnC,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,MAAA,EAAQ,CAC9C,CAGA,QAAA,EAAiB,CACb,IAAA,CAAK,cAAA,CAAe,KAAA,EAAM,CAC1B,IAAA,CAAK,UAAA,CAAW,KAAA,EAAM,CACtB,IAAA,CAAK,UAAA,CAAW,KAAA,GACpB,CAGA,QAAA,EAA0B,CACtB,OAAO,CACH,gBAAA,CAAkB,IAAA,CAAK,eAAe,IAAA,CACtC,UAAA,CAAY,IAAA,CAAK,UAAA,CAAW,IAAA,CAC5B,WAAA,CAAa,IAAA,CAAK,UAAA,CAAW,IACjC,CACJ,CAIR,ECVO,IAAMK,CAAAA,CAAN,cAAuB,KAAM,CAChC,WAAA,CAAmBC,CAAAA,CAAwBC,CAAAA,CAAqB,GAAA,CAAYC,CAAAA,CAAe,CACvF,KAAA,CAAMF,CAAO,CAAA,CADE,aAAAA,CAAAA,CAAwB,IAAA,CAAA,UAAA,CAAAC,CAAAA,CAAiC,IAAA,CAAA,IAAA,CAAAC,CAAAA,CAExE,IAAA,CAAK,IAAA,CAAO,WAChB,CACJ,CAAA,CAEaC,CAAAA,CAAN,cAA8BJ,CAAS,CAC1C,YAAYC,CAAAA,CAAwBI,CAAAA,CAAkB,CAClD,KAAA,CAAMJ,CAAAA,CAAS,GAAA,CAAK,kBAAkB,CAAA,CADN,IAAA,CAAA,MAAA,CAAAI,CAAAA,CAEhC,IAAA,CAAK,IAAA,CAAO,kBAChB,CACJ,EAEaC,CAAAA,CAAN,cAA4BN,CAAS,CACxC,WAAA,CAAYC,CAAAA,CAAiB,CACzB,KAAA,CAAMA,CAAAA,CAAS,GAAA,CAAK,gBAAgB,CAAA,CACpC,IAAA,CAAK,IAAA,CAAO,gBAChB,CACJ,CAAA,CAEaM,CAAAA,CAAN,cAA2BP,CAAS,CACvC,WAAA,CAAYC,CAAAA,CAAU,iBAAA,CAAmB,CACrC,KAAA,CAAMA,CAAAA,CAAS,GAAA,CAAK,eAAe,CAAA,CACnC,KAAK,IAAA,CAAO,eAChB,CACJ,CAAA,CAEaO,EAAAA,CAAN,cAA6BR,CAAS,CACzC,WAAA,CAAYC,CAAAA,CAAU,mBAAA,CAAqB,CACvC,KAAA,CAAMA,CAAAA,CAAS,GAAA,CAAK,kBAAkB,CAAA,CACtC,IAAA,CAAK,IAAA,CAAO,iBAChB,CACJ,EC9LO,IAAMQ,CAAAA,CAAN,KAAuB,CActB,WAAA,CAAYC,CAAAA,CAAsB,CARlC,IAAA,CAAQ,SAAA,CAAkB,IAAI,GAAA,CAC9B,IAAA,CAAiB,cAAA,CAAiB,GAAA,CAS9B,GAAI,CAACC,UAAAA,CAAWD,CAAAA,CAAO,SAAS,CAAA,CAC5B,MAAM,IAAI,KAAA,CAAM,oCAAoCA,CAAAA,CAAO,SAAS,CAAA,CAAE,CAAA,CAI1E,GAAI,CADUE,QAAAA,CAASF,CAAAA,CAAO,SAAS,CAAA,CAC5B,WAAA,EAAY,CACnB,MAAM,IAAI,MAAM,CAAA,gCAAA,EAAmCA,CAAAA,CAAO,SAAS,CAAA,CAAE,CAAA,CAIzE,IAAA,CAAK,WAAA,CAAcG,OAAAA,CAAQH,CAAAA,CAAO,SAAS,CAAA,CAG3C,IAAA,CAAK,MAAA,CAAS,CACV,KAAkBA,CAAAA,CAAO,IAAA,CACzB,SAAA,CAAkBA,CAAAA,CAAO,SAAA,CACzB,MAAA,CAAkBA,CAAAA,CAAO,MAAA,EAAU,IAAA,CACnC,KAAA,CAAkBA,CAAAA,CAAO,KAAA,EAAS,CAAC,YAAY,CAAA,CAC/C,QAAA,CAAkBA,CAAAA,CAAO,QAAA,EAAY,MAAA,CACrC,IAAA,CAAkBA,CAAAA,CAAO,IAAA,EAAQ,IAAA,CACjC,YAAA,CAAkBA,CAAAA,CAAO,YAAA,EAAgB,IAAA,CACzC,SAAA,CAAkBA,CAAAA,CAAO,SAAA,EAAa,MACtC,UAAA,CAAkBA,CAAAA,CAAO,UAAA,EAAc,EAAC,CACxC,WAAA,CAAkBA,CAAAA,CAAO,WAAA,EAAe,KAAA,CACxC,UAAA,CAAkBA,CAAAA,CAAO,UAC7B,EACJ,CAUA,OAAA,EAAkD,CAC9C,OAAO,MAAOI,CAAAA,EAAuC,CACjD,IAAMC,CAAAA,CAAcD,CAAAA,CAAI,OAAA,CAAQ,GAAA,CAE5BE,CAAAA,CADQ,IAAI,GAAA,CAAID,CAAW,CAAA,CACZ,SAGfC,CAAAA,CAAS,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,GACpCA,CAAAA,CAAWA,CAAAA,CAAS,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAA,CAIrD,GAAI,CACAA,CAAAA,CAAW,kBAAA,CAAmBA,CAAQ,EAC1C,CAAA,KAAQ,CACJ,OAAOF,CAAAA,CAAI,IAAA,CAAK,CAAE,KAAA,CAAO,sBAAuB,CAAA,CAAG,GAAG,CAC1D,CAGA,GAAIE,CAAAA,CAAS,QAAA,CAAS,IAAI,CAAA,EAAKA,CAAAA,CAAS,QAAA,CAAS,IAAI,CAAA,CACjD,OAAOF,CAAAA,CAAI,IAAA,CAAK,CAAE,MAAO,WAAY,CAAA,CAAG,GAAG,CAAA,CAI/C,GAAI,IAAA,CAAK,MAAA,CAAO,QAAA,GAAa,OAAA,EAAWE,CAAAA,CAAS,KAAA,CAAM,GAAG,CAAA,CAAE,IAAA,CAAKC,GAAKA,CAAAA,CAAE,UAAA,CAAW,GAAG,CAAC,CAAA,CACnF,OAAI,IAAA,CAAK,MAAA,CAAO,QAAA,GAAa,MAAA,CAClBH,CAAAA,CAAI,IAAA,CAAK,CAAE,KAAA,CAAO,WAAY,CAAA,CAAG,GAAG,CAAA,CAGxC,IAAA,CAAK,cAAA,CAAeA,CAAG,CAAA,CAIlC,IAAMI,CAAAA,CAAW,IAAA,CAAK,eAAA,CAAgBF,CAAQ,CAAA,CAC9C,GAAI,CAACE,EACD,OAAO,IAAA,CAAK,cAAA,CAAeJ,CAAG,CAAA,CAIlC,GAAI,CAAC,IAAA,CAAK,UAAA,CAAWI,CAAQ,CAAA,CACzB,OAAOJ,CAAAA,CAAI,IAAA,CAAK,CAAE,KAAA,CAAO,WAAY,CAAA,CAAG,GAAG,CAAA,CAG/C,GAAI,CAACH,UAAAA,CAAWO,CAAQ,CAAA,CACpB,OAAO,IAAA,CAAK,cAAA,CAAeJ,CAAG,EAGlC,IAAMK,CAAAA,CAAQP,QAAAA,CAASM,CAAQ,CAAA,CAG/B,OAAIC,CAAAA,CAAM,WAAA,EAAY,CACX,IAAA,CAAK,cAAA,CAAeL,CAAAA,CAAKI,CAAAA,CAAUF,CAAQ,CAAA,CAI/C,IAAA,CAAK,SAAA,CAAUF,CAAAA,CAAKI,CAAAA,CAAUC,CAAK,CAC9C,CACJ,CAKA,cAAA,EAAyB,CAErB,OAAO,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,IAAI,IAC9B,CAOQ,eAAA,CAAgBH,CAAAA,CAAiC,CAEjDA,CAAAA,CAAS,UAAA,CAAW,GAAG,CAAA,GACvBA,CAAAA,CAAWA,CAAAA,CAAS,KAAA,CAAM,CAAC,CAAA,CAAA,CAG/B,IAAME,EAAWE,IAAAA,CAAK,IAAA,CAAK,WAAA,CAAaJ,CAAQ,CAAA,CAGhD,GAAI,CAACL,UAAAA,CAAWO,CAAQ,CAAA,EAAK,IAAA,CAAK,MAAA,CAAO,UAAA,CAAW,MAAA,CAAS,EACzD,IAAA,IAAWG,CAAAA,IAAO,IAAA,CAAK,MAAA,CAAO,UAAA,CAAY,CACtC,IAAMC,CAAAA,CAAU,CAAA,EAAGJ,CAAQ,CAAA,CAAA,EAAIG,CAAG,CAAA,CAAA,CAClC,GAAIV,UAAAA,CAAWW,CAAO,CAAA,CAClB,OAAOA,CAEf,CAGJ,OAAOJ,CACX,CAEQ,UAAA,CAAWA,CAAAA,CAA2B,CAG1C,OAAO,CADKK,QAAAA,CAAS,IAAA,CAAK,YAAaV,OAAAA,CAAQK,CAAQ,CAAC,CAAA,CAC5C,UAAA,CAAW,IAAI,CAAA,EAAK,CAACL,OAAAA,CAAQK,CAAQ,CAAA,CAAE,UAAA,CAAW,IAAI,CACtE,CAEA,MAAc,cAAA,CAAeJ,CAAAA,CAAiBU,CAAAA,CAAiBC,CAAAA,CAA8B,CAEzF,IAAA,IAAWC,CAAAA,IAAa,IAAA,CAAK,MAAA,CAAO,KAAA,CAAO,CACvC,IAAMC,CAAAA,CAAYP,IAAAA,CAAKI,EAASE,CAAS,CAAA,CACzC,GAAIf,UAAAA,CAAWgB,CAAS,CAAA,CAAG,CACvB,IAAMR,CAAAA,CAAQP,QAAAA,CAASe,CAAS,CAAA,CAChC,GAAIR,CAAAA,CAAM,MAAA,EAAO,CACb,OAAO,IAAA,CAAK,SAAA,CAAUL,CAAAA,CAAKa,CAAAA,CAAWR,CAAK,CAEnD,CACJ,CAGA,OAAO,IAAA,CAAK,cAAA,CAAeL,CAAG,CAClC,CAEA,MAAc,SAAA,CAAUA,CAAAA,CAAiBI,CAAAA,CAAkBC,CAAAA,CAAqC,CAC5F,IAAMpD,CAAAA,CAAS+C,CAAAA,CAAI,OAAA,CAAQ,MAAA,CAAO,WAAA,EAAY,CAG9C,GAAI/C,IAAW,KAAA,EAASA,CAAAA,GAAW,MAAA,CAC/B,OAAO+C,CAAAA,CAAI,IAAA,CAAK,CAAE,KAAA,CAAO,oBAAqB,CAAA,CAAG,GAAG,CAAA,CAIxD,IAAMc,CAAAA,CAAWV,EACbW,CAAAA,CAAa,IAAA,CAAK,SAAA,CAAU,GAAA,CAAID,CAAQ,CAAA,CAO5C,GAJIC,CAAAA,EAAcA,CAAAA,CAAW,KAAA,GAAUV,CAAAA,CAAM,OAAA,GACzCU,CAAAA,CAAa,MAAA,CAAA,CAGb,CAACA,CAAAA,CAAY,CASb,GARAA,CAAAA,CAAa,CACT,IAAA,CAAkB,IAAA,CAAK,YAAA,CAAaV,CAAK,CAAA,CACzC,YAAA,CAAkB,IAAI,IAAA,CAAKA,CAAAA,CAAM,KAAK,EACtC,IAAA,CAAkBA,CAAAA,CAAM,IAAA,CACxB,KAAA,CAAkBA,CAAAA,CAAM,OAC5B,CAAA,CAGI,IAAA,CAAK,SAAA,CAAU,IAAA,EAAQ,IAAA,CAAK,cAAA,CAAgB,CAC5C,IAAMW,CAAAA,CAAW,IAAA,CAAK,SAAA,CAAU,IAAA,EAAK,CAAE,IAAA,EAAK,CAAE,KAAA,CAC1CA,CAAAA,EAAU,IAAA,CAAK,SAAA,CAAU,MAAA,CAAOA,CAAQ,EAChD,CACA,IAAA,CAAK,UAAU,GAAA,CAAIF,CAAAA,CAAUC,CAAU,EAC3C,CAGA,IAAME,CAAAA,CAAcjB,CAAAA,CAAI,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA,CACrDkB,CAAAA,CAAkBlB,CAAAA,CAAI,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA,CAEnE,GAAI,IAAA,CAAK,MAAA,CAAO,IAAA,EAAQiB,CAAAA,GAAgBF,CAAAA,CAAW,IAAA,CAC/C,OAAO,IAAI,QAAA,CAAS,KAAM,CACtB,MAAA,CAAQ,GAAA,CACR,OAAA,CAAS,IAAA,CAAK,YAAA,CAAaX,CAAAA,CAAUW,CAAU,CACnD,CAAC,CAAA,CAGL,GAAI,IAAA,CAAK,MAAA,CAAO,cAAgBG,CAAAA,CAAiB,CAC7C,IAAMC,CAAAA,CAAY,IAAI,IAAA,CAAKD,CAAe,CAAA,CAC1C,GAAIH,CAAAA,CAAW,YAAA,EAAgBI,CAAAA,CAC3B,OAAO,IAAI,SAAS,IAAA,CAAM,CACtB,MAAA,CAAQ,GAAA,CACR,OAAA,CAAS,IAAA,CAAK,YAAA,CAAaf,CAAAA,CAAUW,CAAU,CACnD,CAAC,CAET,CAGA,IAAMK,CAAAA,CAAO,GAAA,CAAI,IAAA,CAAKhB,CAAQ,CAAA,CACxBiB,CAAAA,CAAU,IAAA,CAAK,YAAA,CAAajB,CAAAA,CAAUW,CAAU,CAAA,CAQtD,OALI,IAAA,CAAK,MAAA,CAAO,UAAA,EACZ,IAAA,CAAK,OAAO,UAAA,CAAWf,CAAAA,CAAKI,CAAQ,CAAA,CAIpCnD,CAAAA,GAAW,MAAA,CACJ,IAAI,QAAA,CAAS,IAAA,CAAM,CACtB,MAAA,CAAQ,GAAA,CACR,OAAA,CAAAoE,CACJ,CAAC,CAAA,CAGE,IAAI,QAAA,CAASD,CAAAA,CAAM,CACtB,MAAA,CAAQ,GAAA,CACR,OAAA,CAAAC,CACJ,CAAC,CACL,CAEQ,YAAA,CAAajB,CAAAA,CAAkBkB,CAAAA,CAA4B,CAC/D,IAAMD,CAAAA,CAAU,IAAI,OAAA,CAGdE,CAAAA,CAAW,IAAA,CAAK,WAAA,CAAYnB,CAAQ,CAAA,CAiB1C,GAhBAiB,CAAAA,CAAQ,GAAA,CAAI,cAAA,CAAgBE,CAAQ,CAAA,CAGpCF,CAAAA,CAAQ,GAAA,CAAI,gBAAA,CAAkBC,CAAAA,CAAM,IAAA,CAAK,QAAA,EAAU,CAAA,CAG/C,IAAA,CAAK,MAAA,CAAO,IAAA,EACZD,CAAAA,CAAQ,GAAA,CAAI,MAAA,CAAQC,CAAAA,CAAM,IAAI,CAAA,CAI9B,IAAA,CAAK,MAAA,CAAO,YAAA,EACZD,CAAAA,CAAQ,GAAA,CAAI,eAAA,CAAiBC,CAAAA,CAAM,YAAA,CAAa,WAAA,EAAa,CAAA,CAI7D,IAAA,CAAK,MAAA,CAAO,OAAS,CAAA,CAAG,CACxB,IAAIE,CAAAA,CAAe,CAAA,gBAAA,EAAmB,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA,CACpD,IAAA,CAAK,MAAA,CAAO,SAAA,GACZA,CAAAA,EAAgB,aAAA,CAAA,CAEpBH,EAAQ,GAAA,CAAI,eAAA,CAAiBG,CAAY,EAC7C,CAAA,KACIH,CAAAA,CAAQ,GAAA,CAAI,eAAA,CAAiB,UAAU,CAAA,CAI3C,OAAAA,CAAAA,CAAQ,GAAA,CAAI,eAAA,CAAiB,OAAO,CAAA,CAE7BA,CACX,CAEQ,YAAA,CAAahB,CAAAA,CAA0B,CAE3C,OAAO,CAAA,CAAA,EAAIA,CAAAA,CAAM,IAAA,CAAK,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAIA,CAAAA,CAAM,QAAQ,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,CACpE,CAEQ,WAAA,CAAYD,CAAAA,CAA0B,CAC1C,IAAMG,CAAAA,CAAMkB,OAAAA,CAAQrB,CAAQ,CAAA,CAAE,WAAA,GAC9B,OAAOsB,EAAAA,CAAWnB,CAAG,CAAA,EAAK,0BAC9B,CAEQ,cAAA,CAAeP,CAAAA,CAA2B,CAC9C,OAAI,IAAA,CAAK,MAAA,CAAO,WAAA,CAELA,CAAAA,CAAI,KAAK,CAAE,KAAA,CAAO,WAAY,CAAA,CAAG,GAAG,CAAA,CAExCA,CAAAA,CAAI,IAAA,CAAK,CAAE,KAAA,CAAO,WAAY,CAAA,CAAG,GAAG,CAC/C,CAKA,UAAA,EAAmB,CACf,IAAA,CAAK,SAAA,CAAU,KAAA,GACnB,CAKA,aAAA,EAAsD,CAClD,OAAO,CACH,OAAA,CAAS,IAAA,CAAK,SAAA,CAAU,IAAA,CACxB,QAAS,IAAA,CAAK,cAClB,CACJ,CAIR,EAWO,SAAS2B,EAAAA,CAAa/B,CAAAA,CAAwC,CACjE,OAAO,IAAID,CAAAA,CAAiBC,CAAM,CACtC,CAWA,IAAM8B,EAAAA,CAAqC,CAEvC,OAAA,CAAkB,0BAAA,CAClB,MAAA,CAAkB,0BAAA,CAClB,MAAA,CAAkB,yBAAA,CAClB,MAAA,CAAkB,2BAAA,CAClB,MAAA,CAAkB,yBAAA,CAClB,MAAA,CAAkB,0BAClB,KAAA,CAAkB,8BAAA,CAGlB,KAAA,CAAkB,uCAAA,CAClB,MAAA,CAAkB,uCAAA,CAClB,OAAA,CAAkB,iCAAA,CAClB,SAAA,CAAkB,qBAAA,CAClB,MAAA,CAAkB,iCAAA,CAGlB,MAAA,CAAkB,WAAA,CAClB,MAAA,CAAkB,YAAA,CAClB,OAAA,CAAkB,YAAA,CAClB,MAAA,CAAkB,WAAA,CAClB,MAAA,CAAkB,eAAA,CAClB,MAAA,CAAkB,cAAA,CAClB,OAAA,CAAkB,YAAA,CAClB,OAAA,CAAkB,YAAA,CAClB,MAAA,CAAkB,WAAA,CAClB,QAAkB,YAAA,CAGlB,OAAA,CAAkB,WAAA,CAClB,QAAA,CAAkB,YAAA,CAClB,MAAA,CAAkB,UAAA,CAClB,MAAA,CAAkB,UAAA,CAClB,MAAA,CAAkB,+BAAA,CAGlB,MAAA,CAAkB,YAAA,CAClB,MAAA,CAAkB,WAAA,CAClB,MAAA,CAAkB,WAAA,CAClB,MAAA,CAAkB,WAAA,CAClB,MAAA,CAAkB,WAAA,CAClB,OAAA,CAAkB,YAAA,CAGlB,MAAA,CAAkB,WAAA,CAClB,OAAA,CAAkB,YAAA,CAClB,MAAA,CAAkB,WAAA,CAClB,MAAA,CAAkB,kBAClB,MAAA,CAAkB,iBAAA,CAClB,MAAA,CAAkB,kBAAA,CAGlB,MAAA,CAAkB,iBAAA,CAClB,MAAA,CAAkB,oBAAA,CAClB,OAAA,CAAkB,yEAAA,CAClB,MAAA,CAAkB,0BAAA,CAClB,OAAA,CAAkB,mEAAA,CAClB,MAAA,CAAkB,+BAAA,CAClB,OAAA,CAAkB,2EAAA,CAGlB,MAAA,CAAkB,iBAAA,CAClB,MAAA,CAAkB,8BAAA,CAClB,KAAA,CAAkB,6BAAA,CAClB,MAAA,CAAkB,mBAAA,CAClB,KAAA,CAAkB,kBAAA,CAGlB,OAAA,CAAkB,kBAAA,CAClB,YAAkB,qBAAA,CAClB,cAAA,CAAkB,2BACtB,CAAA,CC/bA,IAAME,CAAAA,CAAY,IAAI5D,CAAAA,CAChB6D,CAAAA,CAAY,IAAI7E,CAAAA,CAQf,SAAS8E,EAAAA,CAAOlC,CAAAA,CAA6B,EAAC,CAAyB,CAGhF,IAAMmC,CAAAA,CAA4B,MAAA,CAAOnC,CAAAA,CAAO,IAAI,CAAA,EAAK,GAAA,CACnDoC,CAAAA,CAA4BpC,CAAAA,CAAO,QAAA,EAAY,WAAA,CAC/CqC,CAAAA,CAA4BrC,CAAAA,CAAO,cAAA,EAAkB,EAAA,CAAK,KAAO,IAAA,CACjEsC,CAAAA,CAA4BtC,CAAAA,CAAO,cAAA,EAAkB,GAAA,CACrDuC,CAAAA,CAA4BvC,CAAAA,CAAO,uBAAA,EAA2B,GAAA,CAE9DwC,CAAAA,CAA4B,OAAOxC,CAAAA,CAAO,OAAA,EAAY,QAAA,CAAWA,CAAAA,CAAO,OAAA,CAAU,EAAC,CACnFyC,CAAAA,CAA4BzC,CAAAA,CAAO,OAAA,CAAU,IAAI0C,MAAAA,CAAOF,CAAAA,CAAO,KAAA,EAAS,MAAA,CAAQA,CAAAA,CAAO,MAAM,CAAA,CAAI,IAAA,CAEjGG,EAA4B,IAAI,GAAA,CAChCC,CAAAA,CAAkC,EAAC,CACnCC,CAAAA,CAA4B,IAAI,GAAA,CAG1BC,CAAAA,CAAkB,WAAA,CAAY,IAAM,CACtCd,CAAAA,CAAS,gBAAA,EAAiB,CAC1BA,CAAAA,CAAS,iBAAA,GACb,CAAA,CAAG,GAAA,CAAS,GAAI,CAAA,CAEhB,eAAee,CAAAA,CAAcC,CAAAA,CAAkBd,CAAAA,CAAoC,CAC/E,IAAMe,CAAAA,CAAY,IAAA,CAAK,KAAI,CACrBC,CAAAA,CAAY,MAAA,CAAO,UAAA,EAAW,CAE9B5F,CAAAA,CADY,IAAI,GAAA,CAAI0F,CAAAA,CAAQ,GAAG,CAAA,CACf,QAAA,CAChB3F,CAAAA,CAAY2F,CAAAA,CAAQ,OAAO,WAAA,EAAY,CACvC9D,CAAAA,CAAYiE,EAAAA,CAAYH,CAAAA,CAASd,CAAM,CAAA,CAE7CW,CAAAA,CAAe,GAAA,CAAIK,CAAS,CAAA,CAE5B,GAAI,CAEA,IAAME,EAAgBJ,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAA,CAC1D,GAAII,CAAAA,EAAiB,QAAA,CAASA,CAAa,CAAA,CAAIf,CAAAA,CAC3C,OAAAI,CAAAA,EAAQ,IAAA,CAAK,CAAE,SAAA,CAAAS,CAAAA,CAAW,IAAA,CAAME,CAAAA,CAAe,EAAA,CAAAlE,CAAG,CAAA,CAAG,mBAAmB,CAAA,CACjE,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,CAAE,KAAA,CAAO,mBAAoB,CAAC,CAAA,CAAG,CAClF,MAAA,CAAS,GAAA,CACT,OAAA,CAAU,CAAE,cAAA,CAAgB,kBAAmB,CACjC,CAAC,CAAA,CAIL,IAAMmE,CAAAA,CAAcC,EAAAA,CAAWN,CAAAA,CAAShD,CAAM,CAAA,CAC9C,GAAI3C,CAAAA,GAAW,SAAA,CACX,OAAO,IAAI,QAAA,CAAS,IAAA,CAAM,CAAE,MAAA,CAAQ,GAAA,CAAK,OAAA,CAASgG,CAAY,CAAC,CAAA,CAInE,GAAIrD,CAAAA,CAAO,QAAA,EAAY,OAAOA,CAAAA,CAAO,QAAA,EAAa,QAAA,EAAYA,CAAAA,CAAO,QAAA,CAAS,SAAA,CAAW,CACrF,IAAMuD,CAAAA,CAAe,OAAOvD,CAAAA,CAAO,QAAA,CAAS,SAAA,EAAc,QAAA,CACxDA,CAAAA,CAAO,QAAA,CAAS,SAAA,CAChB,EAAC,CACG3B,CAAAA,CAAgBkF,CAAAA,CAAa,GAAA,EAAO,GAAA,CACpCjF,CAAAA,CAAgBiF,CAAAA,CAAa,UAAY,GAAA,CACzCC,CAAAA,CAAgBD,CAAAA,CAAa,YAAA,CACjCA,CAAAA,CAAa,YAAA,CAAa,CAAE,OAAA,CAAAP,CAAAA,CAAS,EAAA,CAAA9D,CAAG,CAAqB,CAAA,CAC7DA,CAAAA,CAEF,GAAI,CAAC8C,CAAAA,CAAS,cAAA,CAAewB,CAAAA,CAAcnF,CAAAA,CAAKC,CAAQ,CAAA,CACpD,OAAAmE,CAAAA,EAAQ,IAAA,CAAK,CAAE,SAAA,CAAAS,CAAAA,CAAW,EAAA,CAAAhE,EAAI,GAAA,CAAKsE,CAAa,CAAA,CAAG,qBAAqB,CAAA,CACjE,IAAI,QAAA,CACP,IAAA,CAAK,SAAA,CAAU,CAAE,KAAA,CAAOD,CAAAA,CAAa,OAAA,EAAW,mBAAoB,CAAC,CAAA,CACrE,CAAE,MAAA,CAAQ,GAAA,CAAK,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAE,CACnE,CAER,CAGA,IAAIE,CAAAA,CAAgB,IAAA,CAChB,CAAC,MAAA,CAAQ,KAAA,CAAO,OAAO,CAAA,CAAE,QAAA,CAASpG,CAAM,CAAA,GACxCoG,CAAAA,CAAO,MAAMC,EAAAA,CAAUV,CAAAA,CAASP,CAAAA,CAAQJ,CAAU,CAAA,CAAA,CAItD,IAAMsB,CAAAA,CAAYhB,CAAAA,CAAI,GAAA,CAAI,SAAS,CAAA,CAG7BiB,CAAAA,CAAa3B,CAAAA,CAAO,KAAA,CAAM5E,CAAAA,CAAQC,CAAI,CAAA,CAC5C,GAAI,CAACsG,CAAAA,CAAY,CACb,IAAMxD,CAAAA,CAAMyD,EAAAA,CAAiB3E,CAAAA,CAAI8D,CAAAA,CAAS,EAAC,CAAGW,CAAAA,CAAWlB,CAAAA,CAAQS,CAAS,CAAA,CAC1E,OAAAT,CAAAA,EAAQ,IAAA,CAAK,CAAE,SAAA,CAAAS,CAAAA,CAAW,MAAA,CAAA7F,CAAAA,CAAQ,IAAA,CAAAC,CAAAA,CAAM,EAAA,CAAA4B,CAAG,CAAA,CAAG,iBAAiB,CAAA,CACxDkB,CAAAA,CAAI,IAAA,CAAK,CAAE,KAAA,CAAO,YAAa,IAAA,CAAA9C,CAAK,CAAA,CAAG,GAAG,CACrD,CAEA,IAAM8C,CAAAA,CAAMyD,EAAAA,CAAiB3E,CAAAA,CAAI8D,CAAAA,CAASY,CAAAA,CAAW,MAAA,EAAU,GAAID,CAAAA,CAAWlB,CAAAA,CAAQS,CAAS,CAAA,CAC/F9C,CAAAA,CAAI,IAAA,CAAOqD,CAAAA,CACXrD,CAAAA,CAAI,OAAA,CAAU4C,CAAAA,CAGd,IAAMc,CAAAA,CAAa,IAAI,eAAA,CACjBC,GAAiB,IAAI,OAAA,CAAe,CAAChD,CAAAA,CAAGiD,CAAAA,GAAW,CACrD,IAAM/E,CAAAA,CAAK,UAAA,CAAW,IAAM,CACxB6E,CAAAA,CAAW,KAAA,EAAM,CACjBE,CAAAA,CAAO,IAAUnE,CAAAA,CAAa,iBAAiB,CAAC,EACpD,CAAA,CAAGyC,CAAc,CAAA,CACjBwB,CAAAA,CAAW,MAAA,CAAO,gBAAA,CAAiB,OAAA,CAAS,IAAM,YAAA,CAAa7E,CAAE,CAAC,EACtE,CAAC,CAAA,CAIKgF,CAAAA,CADkBL,CAAAA,CAAW,QAAA,EACE,WAAA,EAAe,EAAC,CAEjDM,CAAAA,CACAD,CAAAA,CAAY,MAAA,CAAS,CAAA,CACrBC,CAAAA,CAAiBC,CAAAA,CAAmB/D,CAAAA,CAAK6D,CAAAA,CAAaL,CAAAA,CAAW,OAAO,CAAA,CAExEM,CAAAA,CAAiB,OAAA,CAAQ,OAAA,CAAQN,CAAAA,CAAW,OAAA,CAAQxD,CAAG,CAAC,CAAA,CAG5D,IAAMgE,CAAAA,CAAW,MAAM,OAAA,CAAQ,IAAA,CAAK,CAChCF,CAAAA,CACAH,EACJ,CAAC,CAAA,CAGKM,CAAAA,CAAa,IAAI,OAAA,CAAQD,CAAAA,CAAS,OAAO,CAAA,CAC/Cf,CAAAA,CAAY,OAAA,CAAQ,CAACiB,CAAAA,CAAO/G,CAAAA,GAAQ,CAC3B8G,CAAAA,CAAW,GAAA,CAAI9G,CAAG,CAAA,EAAG8G,CAAAA,CAAW,GAAA,CAAI9G,CAAAA,CAAK+G,CAAK,EACvD,CAAC,CAAA,CAEDD,EAAW,GAAA,CAAI,cAAA,CAAgBnB,CAAS,CAAA,CACxCmB,CAAAA,CAAW,GAAA,CAAI,wBAAA,CAA0B,SAAS,CAAA,CAClDA,CAAAA,CAAW,GAAA,CAAI,iBAAA,CAAmB,MAAM,CAAA,CACxCA,EAAW,GAAA,CAAI,kBAAA,CAAoB,eAAe,CAAA,CAClDA,CAAAA,CAAW,GAAA,CAAI,iBAAA,CAAmB,iCAAiC,CAAA,CAGnE,IAAMjF,CAAAA,CAAW,IAAA,CAAK,GAAA,EAAI,CAAI6D,EAC9B,OAAAjB,CAAAA,CAAS,UAAA,CAAWkB,CAAAA,CAAW7F,CAAAA,CAAQC,CAAAA,CAAM4B,CAAAA,CAAIkF,CAAAA,CAAS,MAAA,CAAQhF,CAAQ,CAAA,CAC1EqD,CAAAA,EAAQ,IAAA,CAAK,CACT,SAAA,CAAAS,CAAAA,CACA,MAAA,CAAA7F,CAAAA,CACA,IAAA,CAAAC,CAAAA,CACA,MAAA,CAAQ8G,CAAAA,CAAS,MAAA,CACjB,QAAA,CAAAhF,CAAAA,CACA,EAAA,CAAAF,CACJ,CAAA,CAAG,mBAAmB,CAAA,CAEf,IAAI,QAAA,CAASkF,CAAAA,CAAS,IAAA,CAAM,CAC/B,MAAA,CAAQA,CAAAA,CAAS,MAAA,CACjB,OAAA,CAASC,CACb,CAAC,CACL,CAAA,MAASE,CAAAA,CAAO,CACZ,GAAIA,CAAAA,YAAuBjF,CAAAA,CACvB,OAAAmD,CAAAA,EAAQ,IAAA,CAAK,CAAE,KAAA,CAAO8B,CAAAA,CAAM,OAAA,CAAS,SAAA,CAAArB,CAAAA,CAAW,EAAA,CAAAhE,CAAG,CAAA,CAAG,CAAA,WAAA,EAAcqF,EAAM,OAAO,CAAA,CAAE,CAAA,CAC5E,IAAI,QAAA,CACP,IAAA,CAAK,SAAA,CAAU,CACX,KAAA,CAAQA,CAAAA,CAAM,OAAA,CACd,IAAA,CAAOA,CAAAA,CAAM,IAAA,CACb,SAAA,CAAArB,CACJ,CAAC,CAAA,CACD,CAAE,MAAA,CAAQqB,CAAAA,CAAM,UAAA,CAAY,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAE,CAChF,CAAA,CAGJ9B,CAAAA,EAAQ,MAAM,CAAE,KAAA,CAAO,MAAA,CAAO8B,CAAK,CAAA,CAAG,SAAA,CAAArB,CAAAA,CAAW,EAAA,CAAAhE,CAAG,CAAA,CAAG,iBAAiB,CAAA,CAExE,IAAMsF,CAAAA,CAAe,QAAQ,GAAA,CAAI,QAAA,GAAa,YAAA,CACxC,uBAAA,CACCD,CAAAA,CAAgB,OAAA,CAEvB,OAAO,IAAI,QAAA,CACP,IAAA,CAAK,SAAA,CAAU,CAAE,KAAA,CAAOC,CAAAA,CAAc,UAAAtB,CAAU,CAAC,CAAA,CACjD,CAAE,MAAA,CAAQ,GAAA,CAAK,OAAA,CAAS,CAAE,cAAA,CAAgB,kBAAmB,CAAE,CACnE,CACJ,CAAA,OAAE,CACEL,CAAAA,CAAe,MAAA,CAAOK,CAAS,EACnC,CACJ,CAEA,eAAeiB,CAAAA,CACX/D,CAAAA,CACA6D,CAAAA,CACAjG,CAAAA,CACiB,CACjB,IAAIF,CAAAA,CAAQ,CAAA,CACR2G,EAAiC,IAAA,CAG/BC,CAAAA,CAAetE,CAAAA,CAAI,IAAA,CAAK,IAAA,CAAKA,CAAG,CAAA,CAChCuE,CAAAA,CAAevE,CAAAA,CAAI,IAAA,CAAK,IAAA,CAAKA,CAAG,CAAA,CAChCwE,CAAAA,CAAexE,CAAAA,CAAI,IAAA,CAAK,IAAA,CAAKA,CAAG,CAAA,CAChCyE,CAAAA,CAAmBzE,CAAAA,CAAI,QAAA,CAAS,IAAA,CAAKA,CAAG,CAAA,CAE9CA,CAAAA,CAAI,IAAA,CAAO,SAAStB,CAAAA,CAAeK,CAAAA,CAA2B,CAC1D,IAAMiF,CAAAA,CAAWM,CAAAA,CAAa5F,CAAAA,CAAMK,CAAM,CAAA,CAC1C,OAAAsF,CAAAA,CAAgBL,CAAAA,CACTA,CACX,CAAA,CAEAhE,CAAAA,CAAI,IAAA,CAAO,SAAStB,CAAAA,CAAcK,CAAAA,CAA2B,CACzD,IAAMiF,CAAAA,CAAWO,CAAAA,CAAa7F,CAAAA,CAAMK,CAAM,CAAA,CAC1C,OAAAsF,CAAAA,CAAgBL,CAAAA,CACTA,CACX,CAAA,CAEAhE,CAAAA,CAAI,IAAA,CAAO,SAAStB,CAAAA,CAAcK,CAAAA,CAA2B,CACzD,IAAMiF,CAAAA,CAAWQ,CAAAA,CAAa9F,CAAAA,CAAMK,CAAM,CAAA,CAC1C,OAAAsF,CAAAA,CAAgBL,CAAAA,CACTA,CACX,CAAA,CAEAhE,EAAI,QAAA,CAAW,SAAS0E,CAAAA,CAAa3F,CAAAA,CAA2B,CAC5D,IAAMiF,CAAAA,CAAWS,CAAAA,CAAiBC,CAAAA,CAAK3F,CAAM,CAAA,CAC7C,OAAAsF,CAAAA,CAAgBL,CAAAA,CACTA,CACX,CAAA,CAEA,eAAeW,CAAAA,EAAsB,CAEjC,GAAI,CAAAN,CAAAA,EAIA3G,CAAAA,CAAQmG,CAAAA,CAAY,MAAA,CAAQ,CAC5B,IAAMe,CAAAA,CAAaf,CAAAA,CAAYnG,CAAK,CAAA,CACpCA,CAAAA,EAAAA,CACA,MAAMkH,CAAAA,CAAW5E,CAAAA,CAAK2E,CAAI,EAC9B,CACJ,CAYA,OATA,MAAMA,CAAAA,EAAK,CAGX3E,CAAAA,CAAI,IAAA,CAAOsE,EACXtE,CAAAA,CAAI,IAAA,CAAOuE,CAAAA,CACXvE,CAAAA,CAAI,IAAA,CAAOwE,CAAAA,CACXxE,CAAAA,CAAI,QAAA,CAAWyE,CAAAA,CAGXJ,CAAAA,EAKGzG,CAAAA,CAAQoC,CAAG,CACtB,CAGA,IAAM6E,CAAAA,CAAqC,CACvC,MAAA,CAAsB,KAAA,CACtB,IAAA,CAAsB,SAAA,CACtB,OAAA,CAAuBC,CAAAA,EAAwBA,CAAAA,CAAE,IAAA,CAAK,CAClD,MAAA,CAAkB,SAAA,CAClB,SAAA,CAAkB,IAAI,IAAA,EAAK,CAAE,WAAA,EAAY,CACzC,MAAA,CAAkB,OAAA,CAAQ,MAAA,EAAO,CACjC,cAAA,CAAkBrC,CAAAA,CAAe,IACrC,CAAC,CACL,CAAA,CAEMsC,CAAAA,CAAwC,CAC1C,MAAA,CAAc,KAAA,CACd,IAAA,CAAc,YAAA,CACd,OAAA,CAAeD,CAAAA,EAAwB,CACnC,IAAME,CAAAA,CAAczC,CAAAA,CAAI,IAAA,CAAO,CAAA,CACzB0C,CAAAA,CAAQD,CAAAA,EAAezC,EAAI,IAAA,GAAS,CAAA,CAC1C,OAAOuC,CAAAA,CAAE,IAAA,CAAK,CACV,KAAA,CAAAG,CAAAA,CACA,MAAA,CAAkB,CACd,QAAA,CAAkBD,CAAAA,CAAc,WAAA,CAAc,gBAAA,CAC9C,eAAkBvC,CAAAA,CAAe,IACrC,CAAA,CACA,SAAA,CAAW,IAAI,IAAA,EAAK,CAAE,WAAA,EAC1B,CAAA,CAAGwC,CAAAA,CAAQ,GAAA,CAAM,GAAG,CACxB,CACJ,CAAA,CAcA,GAXIrF,CAAAA,CAAO,MAAA,EACPA,CAAAA,CAAO,MAAA,CAAO,OAAA,CAAQxC,CAAAA,EAAS,CAC3BoF,CAAAA,CAAO,IAAA,CAAKpF,CAAK,CAAA,CAAA,CACD,KAAA,CAAM,OAAA,CAAQA,CAAAA,CAAM,MAAM,CAAA,CAAIA,CAAAA,CAAM,MAAA,CAAS,CAACA,CAAAA,CAAM,MAAM,CAAA,EAClE,OAAA,CAAQ8H,CAAAA,EAAK,CACjBrD,CAAAA,CAAO,QAAA,CAASqD,CAAAA,CAAG9H,EAAM,IAAA,CAAMA,CAAAA,CAAM,OAAA,CAA+BA,CAAK,EAC7E,CAAC,EACL,CAAC,CAAA,CAIDwC,CAAAA,CAAO,MAAA,CAAQ,CACf,IAAMuF,CAAAA,CAAgB,KAAA,CAAM,OAAA,CAAQvF,CAAAA,CAAO,MAAM,CAAA,CAAIA,CAAAA,CAAO,MAAA,CAAS,CAACA,CAAAA,CAAO,MAAM,CAAA,CAEnF,IAAA,IAAWwF,CAAAA,IAAaD,CAAAA,CACpB,GAAI,CAEA,IAAMvH,CAAAA,CADe,IAAI+B,CAAAA,CAAiByF,CAAS,CAAA,CACtB,OAAA,EAAQ,CAE/BC,CAAAA,CAAqC,CACvC,MAAA,CAAQ,KAAA,CACR,IAAA,CAAMD,CAAAA,CAAU,IAAA,GAAS,GAAA,CAAM,IAAA,CAAO,CAAA,EAAGA,CAAAA,CAAU,IAAI,CAAA,EAAA,CAAA,CACvD,OAAA,CAASxH,CACb,CAAA,CAEA4E,CAAAA,CAAO,IAAA,CAAK6C,CAAW,CAAA,CAEnBD,CAAAA,CAAU,IAAA,GAAS,GAAA,EACnBvD,EAAO,QAAA,CAAS,KAAA,CAAO,GAAA,CAAKjE,CAAAA,CAA+ByH,CAAW,CAAA,CACtExD,CAAAA,CAAO,QAAA,CAAS,MAAA,CAAQ,GAAA,CAAKjE,CAAAA,CAA+ByH,CAAW,CAAA,CACvExD,CAAAA,CAAO,SAAS,KAAA,CAAO,IAAA,CAAMjE,CAAAA,CAA+ByH,CAAW,CAAA,CACvExD,CAAAA,CAAO,QAAA,CAAS,MAAA,CAAQ,IAAA,CAAMjE,CAAAA,CAA+ByH,CAAW,CAAA,GAExExD,CAAAA,CAAO,QAAA,CAAS,MAAO,CAAA,EAAGuD,CAAAA,CAAU,IAAI,CAAA,EAAA,CAAA,CAAMxH,CAAAA,CAA+ByH,CAAW,CAAA,CACxFxD,CAAAA,CAAO,QAAA,CAAS,MAAA,CAAQ,CAAA,EAAGuD,CAAAA,CAAU,IAAI,CAAA,EAAA,CAAA,CAAMxH,CAAAA,CAA+ByH,CAAW,CAAA,EAEjG,CAAA,MAASlB,CAAAA,CAAO,CACZ,MAAA9B,CAAAA,EAAQ,KAAA,CAAM,CACV,KAAA,CAAO,MAAA,CAAO8B,CAAK,CAAA,CACnB,IAAA,CAAMiB,CAAAA,CAAU,IACpB,CAAA,CAAG,yCAAyC,CAAA,CACtCjB,CACV,CAER,CAEA3B,CAAAA,CAAO,IAAA,CAAKqC,CAAAA,CAAaE,CAAc,CAAA,CACvClD,CAAAA,CAAO,QAAA,CAAS,KAAA,CAAO,SAAA,CAAWgD,CAAAA,CAAY,OAAA,CAA+BA,CAAW,CAAA,CACxFhD,CAAAA,CAAO,QAAA,CAAS,KAAA,CAAO,YAAA,CAAckD,CAAAA,CAAe,OAAA,CAA+BA,CAAc,CAAA,CAEjG,IAAIO,CAAAA,CAAqB,IAAA,CAEnBC,EAAiC,CACnC,GAAA,CAAc,IAAA,CACd,MAAA,CAAAlD,CAAAA,CACA,EAAA,CAAcE,CAAAA,CACd,SAAA,CAAc,IAAA,CAEd,MAAM,KAAA,EAAQ,CACV,GAAI3C,CAAAA,CAAO,QAAA,CAAU,CACjB,IAAM4F,CAAAA,CAAY,KAAA,CAAM,OAAA,CAAQ5F,CAAAA,CAAO,QAAQ,CAAA,CAAIA,CAAAA,CAAO,QAAA,CAAW,CAACA,CAAAA,CAAO,QAAQ,CAAA,CACrF,IAAA,IAAW6F,KAASD,CAAAA,CAAW,CAC3B,IAAME,CAAAA,CAASD,CAAAA,CAAM,IAAA,EAAQ,SAAA,CAE7B,GAAI,CACA,GAAI,OAAOA,CAAAA,CAAM,UAAA,EAAe,QAAA,CAAU,CACtC,IAAME,CAAAA,CAAK,IAAQ,EAAA,CAAA,EAAA,CAAGF,CAAAA,CAAM,UAAU,CAAA,CAEtC,GAAIA,CAAAA,CAAM,MAAA,EAAU,OAAOA,CAAAA,CAAM,MAAA,EAAW,QAAA,CACxC,OAAW,EAAGG,CAAW,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQH,CAAAA,CAAM,MAAM,CAAA,CACjDG,CAAAA,EAAe,OAAOA,CAAAA,EAAgB,QAAA,EACtCD,CAAAA,CAAG,YAAA,CAAaC,CAA8B,CAAA,CAK1DrD,CAAAA,CAAI,GAAA,CAAImD,CAAAA,CAAQC,CAAE,CAAA,CAElBtD,CAAAA,EAAQ,IAAA,CAAK,CACT,IAAA,CAAMqD,CAAAA,CACN,UAAA,CAAYD,CAAAA,CAAM,UACtB,EAAG,2BAAsB,EAC7B,CAAA,KACI,MAAM,IAAI,KAAA,CAAM,CAAA,+CAAA,EAAkD,OAAOA,CAAAA,CAAM,UAAU,CAAA,CAAA,CAAG,CAEpG,CAAA,MAAStB,CAAAA,CAAO,CACZ,MAAA9B,CAAAA,EAAQ,KAAA,CAAM,CACV,KAAA,CAAO,MAAA,CAAO8B,CAAK,CAAA,CACnB,IAAA,CAAMuB,CACV,CAAA,CAAG,+BAA+B,CAAA,CAC5BvB,CACV,CACJ,CACJ,CAEAmB,CAAAA,CAAY,GAAA,CAAI,KAAA,CAAM,CAClB,IAAA,CAAAvD,CAAAA,CACA,QAAA,CAAAC,CAAAA,CACA,KAAA,CAAO,CAACY,CAAAA,CAASd,CAAAA,GAAWa,CAAAA,CAAcC,CAAAA,CAASd,CAAM,CAC7D,CAAC,CAAA,CACDyD,CAAAA,CAAS,SAAA,CAAYD,CAAAA,CAErB,IAAMZ,CAAAA,CAAM,CAAA,OAAA,EAAU1C,CAAQ,CAAA,CAAA,EAAID,CAAI,CAAA,CAAA,CACtCM,CAAAA,EAAQ,KAAK,CAAE,GAAA,CAAAqC,CAAI,CAAA,CAAG,uBAAkB,EAC5C,CAAA,CAEA,MAAM,IAAA,EAAO,CAGT,GAFArC,CAAAA,EAAQ,IAAA,CAAK,oBAAoB,EAE7BI,CAAAA,CAAe,IAAA,CAAO,CAAA,CAAG,CACzBJ,CAAAA,EAAQ,IAAA,CAAK,CAAE,KAAA,CAAOI,CAAAA,CAAe,IAAK,CAAA,CAAG,gCAAgC,CAAA,CAC7E,IAAMoD,EAAW,IAAA,CAAK,GAAA,EAAI,CAAI1D,CAAAA,CAE9B,KAAOM,CAAAA,CAAe,IAAA,CAAO,CAAA,EAAK,IAAA,CAAK,GAAA,EAAI,CAAIoD,CAAAA,EAC3C,MAAM,IAAI,OAAA,CAAQ9F,CAAAA,EAAW,UAAA,CAAWA,CAAAA,CAAS,GAAG,CAAC,CAAA,CAGrD0C,CAAAA,CAAe,IAAA,CAAO,CAAA,EACtBJ,CAAAA,EAAQ,IAAA,CAAK,CAAE,KAAA,CAAOI,CAAAA,CAAe,IAAK,EAAG,oCAAoC,EAEzF,CAIA,GAFA,aAAA,CAAcC,CAAe,CAAA,CAEzB9C,CAAAA,CAAO,UAAA,CACP,GAAI,CACA,MAAMA,CAAAA,CAAO,UAAA,GACjB,CAAA,MAASkG,CAAAA,CAAG,CACRzD,CAAAA,EAAQ,KAAA,CAAM,CAAE,KAAA,CAAO,MAAA,CAAOyD,CAAC,CAAE,CAAA,CAAG,2BAA2B,EACnE,CAGJ,OAAW,CAACC,CAAAA,CAAMJ,CAAE,CAAA,GAAKpD,CAAAA,CAAI,OAAA,EAAQ,CACjC,GAAI,CACIoD,CAAAA,EAAM,OAAOA,CAAAA,CAAG,KAAA,EAAU,UAAA,EAC1BA,CAAAA,CAAG,KAAA,EAAM,CAEbtD,CAAAA,EAAQ,IAAA,CAAK,CAAE,IAAA,CAAA0D,CAAK,CAAA,CAAG,iBAAiB,EAC5C,CAAA,MAASD,CAAAA,CAAG,CACRzD,CAAAA,EAAQ,KAAA,CAAM,CAAE,KAAA,CAAO,MAAA,CAAOyD,CAAC,CAAA,CAAG,IAAA,CAAAC,CAAK,CAAA,CAAG,wBAAwB,EACtE,CAGAT,CAAAA,EAAa,OAAQA,CAAAA,CAAoC,IAAA,EAAS,aACjEA,CAAAA,CAAmC,IAAA,EAAK,CACzCjD,CAAAA,EAAQ,IAAA,CAAK,oBAAoB,CAAA,CAAA,CAGrCA,CAAAA,EAAQ,IAAA,CAAK,6BAA6B,EAC9C,CAAA,CAEA,QAAA,CAASjF,CAAAA,CAA8B,CACnCoF,CAAAA,CAAO,IAAA,CAAKpF,CAAK,CAAA,CAAA,CACD,KAAA,CAAM,OAAA,CAAQA,CAAAA,CAAM,MAAM,CAAA,CAAIA,CAAAA,CAAM,MAAA,CAAS,CAACA,CAAAA,CAAM,MAAM,CAAA,EAClE,OAAA,CAAQ8H,CAAAA,EAAK,CACjBrD,CAAAA,CAAO,QAAA,CAASqD,CAAAA,CAAG9H,CAAAA,CAAM,IAAA,CAAMA,CAAAA,CAAM,OAAA,CAA+BA,CAAK,EAC7E,CAAC,CAAA,CACDiF,CAAAA,EAAQ,KAAK,CAAE,MAAA,CAAQjF,CAAAA,CAAM,MAAA,CAAQ,IAAA,CAAMA,CAAAA,CAAM,IAAK,CAAA,CAAG,aAAa,EAC1E,CAAA,CAEA,SAAA,CAAUoF,CAAAA,CAAiC,CACvCA,CAAAA,CAAO,OAAA,CAAQpF,CAAAA,EAAS,IAAA,CAAK,QAAA,CAASA,CAAK,CAAC,EAChD,CAAA,CAEA,SAAA,EAAY,CACR,OAAOoF,CACX,CACJ,CAAA,CAEA,OAAO+C,CACd,CAQG,eAAejC,EAAAA,CACXV,CAAAA,CACAP,CAAAA,CACA2D,CAAAA,CACgB,CAChB,IAAMC,CAAAA,CAAcrD,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,EAAK,EAAA,CAE3D,GAAI,CACA,GAAIqD,CAAAA,CAAY,QAAA,CAAS,kBAAkB,CAAA,CAAG,CACtD,IAAMC,CAAAA,CAAO,MAAMtD,CAAAA,CAAQ,IAAA,EAAK,CAEhC,GAAIsD,EAAK,MAAA,CAASF,CAAAA,CACjB,MAAM,IAAU1G,CAAAA,CAAgB,mBAAmB,CAAA,CAGpD,GAAI,CAAC4G,CAAAA,CAAK,IAAA,EAAK,CAAG,OAAO,GAEzB,GAAI,CACH,OAAO,IAAA,CAAK,KAAA,CAAMA,CAAI,CACvB,CAAA,MAASJ,CAAAA,CAAG,CACX,MAAAzD,CAAAA,EAAQ,IAAA,CAAK,CACZ,MAAS,MAAA,CAAOyD,CAAC,CAAA,CACjB,WAAA,CAAcI,CAAAA,CAAK,SAAA,CAAU,CAAA,CAAG,GAAG,CACpC,CAAA,CAAG,8BAA8B,CAAA,CAE3B,IAAU5G,CAAAA,CAAgB,8BAA8B,CAC/D,CACQ,CAEA,GAAI2G,CAAAA,CAAY,QAAA,CAAS,mCAAmC,CAAA,CAAG,CAC3D,IAAMC,CAAAA,CAAO,MAAMtD,CAAAA,CAAQ,IAAA,EAAK,CAChC,GAAIsD,CAAAA,CAAK,MAAA,CAASF,CAAAA,CACd,MAAM,IAAU1G,CAAAA,CAAgB,mBAAmB,CAAA,CAEvD,OAAO,MAAA,CAAO,WAAA,CAAY,IAAI,eAAA,CAAgB4G,CAAI,CAAC,CACvD,CAEA,GAAID,CAAAA,CAAY,QAAA,CAAS,qBAAqB,CAAA,CAC1C,OAAO,MAAMrD,CAAAA,CAAQ,QAAA,EAE7B,CAAA,MAASkD,CAAAA,CAAG,CACR,MAAIA,CAAAA,YAAmBxG,CAAAA,CAAuBwG,CAAAA,EAC9CzD,CAAAA,EAAQ,KAAA,CAAM,CAAE,KAAA,CAAO,MAAA,CAAOyD,CAAC,CAAE,CAAA,CAAG,4BAA4B,CAAA,CAC1D,IAAUxG,CAAAA,CAAgB,8BAA8B,CAAA,CAClE,CAEA,OAAO,EACX,CAEA,SAAS6G,EAAAA,CAAaC,CAAAA,CAA2C,CAC7D,IAAMC,CAAAA,CAAU,IAAI,GAAA,CAEpB,GAAI,CAACD,CAAAA,CAAc,OAAOC,CAAAA,CAE1B,IAAMC,CAAAA,CAAQF,CAAAA,CAAa,KAAA,CAAM,GAAG,CAAA,CACpC,IAAA,IAAWG,CAAAA,IAAQD,CAAAA,CAAO,CACtB,GAAM,CAACnJ,CAAAA,CAAK,GAAGqJ,CAAU,CAAA,CAAID,CAAAA,CAAK,IAAA,EAAK,CAAE,KAAA,CAAM,GAAG,CAAA,CAClD,GAAIpJ,CAAAA,CAAK,CACL,IAAM+G,CAAAA,CAAQsC,CAAAA,CAAW,IAAA,CAAK,GAAG,CAAA,CACjCH,CAAAA,CAAQ,GAAA,CAAIlJ,CAAAA,CAAK+G,CAAAA,CAAQ,kBAAA,CAAmBA,CAAK,CAAA,CAAI,EAAE,EAC3D,CACJ,CAEA,OAAOmC,CACX,CAEA,SAAS5C,EAAAA,CACL3E,CAAAA,CACA8D,CAAAA,CACAtF,CAAAA,CACAqI,CAAAA,CACAtD,CAAAA,CACAS,CAAAA,CACgB,CAChB,IAAM4B,CAAAA,CAAgB,IAAI,GAAA,CAAI9B,CAAAA,CAAQ,GAAG,CAAA,CACnC6D,CAAAA,CAAgB,MAAA,CAAO,WAAA,CAAY/B,CAAAA,CAAI,YAAY,CAAA,CACnDrD,CAAAA,CAAgBuB,CAAAA,CAAQ,OAAA,CAC1BxD,CAAAA,CAAkB,GAAA,CAChBsH,CAAAA,CAAgB,IAAI,GAAA,CACpBC,CAAAA,CAAgBR,EAAAA,CAAa9E,CAAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,EAAK,EAAE,CAAA,CAExDrB,CAAAA,CAAwB,CAC1B,EAAA,CAAAlB,CAAAA,CACA,QAAA8D,CAAAA,CACA,MAAA,CAAAtF,CAAAA,CACA,KAAA,CAAAmJ,CAAAA,CACA,OAAA,CAAApF,CAAAA,CACA,EAAA,CAAAsE,CAAAA,CACA,MAAA,CAAAtD,CAAAA,CACA,SAAA,CAAAS,CAAAA,CACA,IAAI,UAAA,EAAa,CAAE,OAAO1D,CAAY,CAAA,CACtC,IAAI,UAAA,CAAWC,CAAAA,CAAc,CAAED,CAAAA,CAAaC,EAAM,CAAA,CAClD,IAAA,CAAM,IAAA,CAEN,IAAA,CAAKX,CAAAA,CAAeK,EAA2B,CAC3C,OAAO,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAUL,CAAI,CAAA,CAAG,CACtC,MAAA,CAAUK,CAAAA,EAAUK,CAAAA,CACpB,OAAA,CAAU,CACN,eAAgB,kBAAA,CAChB,GAAG,IAAA,CAAK,iBAAA,EACZ,CACJ,CAAC,CACL,CAAA,CAEA,IAAA,CAAKV,CAAAA,CAAcK,CAAAA,CAA2B,CAC1C,OAAO,IAAI,QAAA,CAASL,CAAAA,CAAM,CACtB,MAAA,CAAUK,CAAAA,EAAUK,CAAAA,CACpB,OAAA,CAAU,CACN,cAAA,CAAgB,YAAA,CAChB,GAAG,IAAA,CAAK,iBAAA,EACZ,CACJ,CAAC,CACL,CAAA,CAEA,IAAA,CAAKV,CAAAA,CAAcK,CAAAA,CAA2B,CAC1C,OAAO,IAAI,QAAA,CAASL,CAAAA,CAAM,CACtB,MAAA,CAAUK,CAAAA,EAAUK,CAAAA,CACpB,QAAU,CACN,cAAA,CAAgB,0BAAA,CAChB,GAAG,IAAA,CAAK,iBAAA,EACZ,CACJ,CAAC,CACL,CAAA,CAEA,QAAA,CAASsF,CAAAA,CAAa3F,CAAAA,CAAS,IAAe,CAC1C,OAAO,IAAI,QAAA,CAAS,IAAA,CAAM,CACtB,MAAA,CAAAA,CAAAA,CACA,OAAA,CAAU,CACN,QAAA,CAAc2F,CAAAA,CACd,GAAG,IAAA,CAAK,mBACZ,CACJ,CAAC,CACL,CAAA,CAEA,IAAA,CAAKxH,CAAAA,CAAc+I,CAAAA,CAAc,0BAAA,CAAsC,CACnE,IAAM7E,CAAAA,CAAO,GAAA,CAAI,IAAA,CAAKlE,CAAI,CAAA,CAC1B,OAAO,IAAI,QAAA,CAASkE,CAAAA,CAAM,CACtB,OAAA,CAAS,CACL,cAAA,CAAgB6E,CAAAA,CAChB,GAAG,IAAA,CAAK,iBAAA,EACZ,CACJ,CAAC,CACL,CAAA,CAEA,SAAA,CAAUF,CAAAA,CAAc7B,CAAAA,CAAe0C,CAAAA,CAA+B,EAAC,CAAqB,CACxF,IAAIC,CAAAA,CAAS,CAAA,EAAGd,CAAI,CAAA,CAAA,EAAI,mBAAmB7B,CAAK,CAAC,CAAA,CAAA,CAEjD,OAAI0C,CAAAA,CAAQ,MAAA,GAAW,MAAA,GACnBC,CAAAA,EAAU,CAAA,UAAA,EAAaD,CAAAA,CAAQ,MAAM,CAAA,CAAA,CAAA,CAErCA,CAAAA,CAAQ,OAAA,GACRC,GAAU,CAAA,UAAA,EAAaD,CAAAA,CAAQ,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAA,CAAA,CAEpDA,CAAAA,CAAQ,IAAA,GACRC,CAAAA,EAAU,CAAA,OAAA,EAAUD,CAAAA,CAAQ,IAAI,CAAA,CAAA,CAAA,CAEhCA,CAAAA,CAAQ,MAAA,GACRC,CAAAA,EAAU,CAAA,SAAA,EAAYD,CAAAA,CAAQ,MAAM,CAAA,CAAA,CAAA,CAEpCA,CAAAA,CAAQ,MAAA,GACRC,CAAAA,EAAU,UAAA,CAAA,CAEVD,CAAAA,CAAQ,QAAA,GACRC,CAAAA,EAAU,YAAA,CAAA,CAEVD,CAAAA,CAAQ,QAAA,GACRC,GAAU,CAAA,WAAA,EAAcD,CAAAA,CAAQ,QAAQ,CAAA,CAAA,CAAA,CAG5CF,CAAAA,CAAY,GAAA,CAAIX,CAAAA,CAAMc,CAAM,CAAA,CACrB7G,CACX,CAAA,CAEA,SAAA,CAAU+F,CAAAA,CAAkC,CACxC,OAAOY,CAAAA,CAAc,GAAA,CAAIZ,CAAI,CACjC,CAAA,CAEA,YAAA,CAAaA,CAAAA,CAAca,CAAAA,CAAwC,EAAC,CAAqB,CACrF,OAAO5G,CAAAA,CAAI,SAAA,CAAU+F,CAAAA,CAAM,GAAI,CAC3B,GAAGa,CAAAA,CACH,MAAA,CAAQ,CAAA,CACR,IAAA,CAAMA,CAAAA,CAAQ,IAAA,EAAQ,GAC1B,CAAC,CACL,CAAA,CAEA,SAAA,CAAUzJ,CAAAA,CAAa+G,CAAAA,CAAiC,CACpD,OAAA7C,CAAAA,CAAQ,GAAA,CAAIlE,CAAAA,CAAK+G,CAAK,CAAA,CACflE,CACX,CAAA,CAEA,SAAA,CAAU7C,CAAAA,CAAiC,CACvC,OAAOkE,CAAAA,CAAQ,GAAA,CAAIlE,CAAG,CAAA,EAAK,MAC/B,CAAA,CAEA,MAAA,CAAOkC,CAAAA,CAAgC,CACnC,OAAAD,CAAAA,CAAaC,CAAAA,CACNW,CACX,CAAA,CAEA,iBAAA,EAAuD,CACnD,IAAM8G,EAAuC,EAAC,CAC9C,OAAIJ,CAAAA,CAAY,IAAA,CAAO,CAAA,GACnBI,CAAAA,CAAE,YAAY,CAAA,CAAI,KAAA,CAAM,IAAA,CAAKJ,CAAAA,CAAY,MAAA,EAAQ,GAE9CI,CACX,CACJ,CAAA,CAEA,OAAO9G,CACX,CAEA,SAAS+C,EAAAA,CAAYH,CAAAA,CAAkBd,CAAAA,CAA0B,CAC7D,IAAMiF,CAAAA,CAAYnE,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,iBAAiB,CAAA,CACvD,GAAImE,CAAAA,CAEA,OADYA,CAAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAIjI,CAAAA,EAAMA,CAAAA,CAAG,IAAA,EAAM,EACzC,CAAC,CAAA,EAAK,SAAA,CAGrB,IAAMkI,CAAAA,CAASpE,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,WAAW,CAAA,CAC9C,GAAIoE,CAAAA,CAAQ,OAAOA,CAAAA,CAEnB,GAAIlF,CAAAA,CACA,GAAI,CAEA,IAAMmF,CAAAA,CADsBnF,CAAAA,CACc,SAAA,GAAYc,CAAO,CAAA,CAC7D,GAAIqE,CAAAA,EAAe,OAAA,CACf,OAAOA,CAAAA,CAAc,OAE7B,MAAQ,CAER,CAGJ,OAAO,SACX,CAEA,SAAS/D,EAAAA,CAAWN,CAAAA,CAAkBhD,CAAAA,CAAqC,CACvE,IAAMyB,CAAAA,CAAU,IAAI,OAAA,CAEpB,GAAI,CAACzB,CAAAA,CAAO,QAAA,EAAY,OAAOA,CAAAA,CAAO,QAAA,EAAa,QAAA,EAAY,CAACA,CAAAA,CAAO,QAAA,CAAS,IAAA,CAC5E,OAAOyB,CAAAA,CAGX,IAAM6F,CAAAA,CAAa,OAAOtH,CAAAA,CAAO,QAAA,CAAS,IAAA,EAAS,QAAA,CAAWA,CAAAA,CAAO,QAAA,CAAS,IAAA,CAAO,EAAC,CAChFuH,CAAAA,CAASvE,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAQ,EAE3C,GAAIuE,CAAAA,CAAQ,CACJ,OAAOD,CAAAA,CAAW,MAAA,EAAW,UAAA,CACzBA,CAAAA,CAAW,MAAA,CAAOC,CAAM,CAAA,EACxB9F,CAAAA,CAAQ,GAAA,CAAI,6BAAA,CAA+B8F,CAAM,CAAA,CAE9C,KAAA,CAAM,OAAA,CAAQD,CAAAA,CAAW,MAAM,CAAA,CAClCA,CAAAA,CAAW,MAAA,CAAO,QAAA,CAASC,CAAM,CAAA,EACjC9F,CAAAA,CAAQ,GAAA,CAAI,6BAAA,CAA+B8F,CAAM,CAAA,CAE9C,OAAOD,CAAAA,CAAW,MAAA,EAAW,QAAA,CACpC7F,CAAAA,CAAQ,GAAA,CAAI,6BAAA,CAA+B6F,CAAAA,CAAW,MAAM,CAAA,CAE5D7F,CAAAA,CAAQ,GAAA,CAAI,6BAAA,CAA+B8F,CAAM,EAGrD,IAAMC,CAAAA,CAAUF,CAAAA,CAAW,OAAA,EAAW,CAAC,KAAA,CAAO,MAAA,CAAQ,KAAA,CAAO,QAAA,CAAU,OAAA,CAAS,SAAS,CAAA,CACzF7F,CAAAA,CAAQ,GAAA,CAAI,8BAAA,CAAgC+F,CAAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,CAE9D,IAAMC,CAAAA,CAAiBH,CAAAA,CAAW,cAAA,EAAkB,CAAC,cAAA,CAAgB,eAAA,CAAiB,kBAAkB,CAAA,CACxG7F,CAAAA,CAAQ,IAAI,8BAAA,CAAgCgG,CAAAA,CAAe,IAAA,CAAK,IAAI,CAAC,CAAA,CAEjEH,CAAAA,CAAW,WAAA,EACX7F,CAAAA,CAAQ,GAAA,CAAI,kCAAA,CAAoC,MAAM,CAAA,CAGtD6F,CAAAA,CAAW,MAAA,EACX7F,CAAAA,CAAQ,GAAA,CAAI,wBAAA,CAA0B6F,CAAAA,CAAW,MAAA,CAAO,QAAA,EAAU,EAE1E,CAEA,OAAO7F,CACX,CAqCA,IAAOiG,EAAAA,CAAQxF","file":"main.js","sourcesContent":["// src/mod/router.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n // Import AppContext from types to maintain type consistency\r\n import type { AppContext } from '../types.d';\r\n\r\n export type RouteHandler = (ctx: AppContext) => Response | Promise<Response>;\r\n\r\n export interface RegexRoute {\r\n pattern: RegExp;\r\n method: string;\r\n handler: RouteHandler;\r\n key: string;\r\n metadata?: unknown;\r\n }\r\n\r\n export type RegexRoutes = RegexRoute[];\r\n\r\n export interface RouteMatch {\r\n handler: RouteHandler;\r\n params: Record<string, string>;\r\n metadata?: unknown;\r\n }\r\n\r\n export interface RouteInfo {\r\n method: string;\r\n path: string;\r\n handler: RouteHandler;\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class Router {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n private routes = new Map<string, { handler: RouteHandler; metadata?: unknown }>();\r\n private regexRoutes: RegexRoutes = [];\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n match(method: string, path: string): RouteMatch | null {\r\n const key = `${method}:${path}`;\r\n\r\n // Try static route first (faster)\r\n if (this.routes.has(key)) {\r\n const route = this.routes.get(key)!;\r\n return {\r\n handler: route.handler,\r\n params: {},\r\n metadata: route.metadata\r\n };\r\n }\r\n\r\n // Try dynamic routes\r\n for (const route of this.regexRoutes) {\r\n if (route.method === method) {\r\n const match = path.match(route.pattern);\r\n if (match) {\r\n // Extract named groups if they exist\r\n const params = match.groups || {};\r\n return {\r\n handler: route.handler,\r\n params,\r\n metadata: route.metadata\r\n };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n getAll(): RouteInfo[] {\r\n const staticRoutes = Array.from(this.routes.entries()).map(([key, route]) => {\r\n const colonIndex = key.indexOf(':');\r\n const method = key.substring(0, colonIndex);\r\n const path = key.substring(colonIndex + 1);\r\n return { method, path, handler: route.handler };\r\n });\r\n\r\n const dynamicRoutes = this.regexRoutes.map(route => {\r\n const colonIndex = route.key.indexOf(':');\r\n return {\r\n method: route.method,\r\n path: route.key.substring(colonIndex + 1),\r\n handler: route.handler\r\n };\r\n });\r\n\r\n return [...staticRoutes, ...dynamicRoutes];\r\n }\r\n\r\n clear(): void {\r\n this.routes.clear();\r\n this.regexRoutes = [];\r\n }\r\n\r\n remove(method: string, path: string): boolean {\r\n const key = `${method}:${path}`;\r\n\r\n if (this.routes.has(key)) {\r\n this.routes.delete(key);\r\n return true;\r\n }\r\n\r\n const index = this.regexRoutes.findIndex(r => r.key === key);\r\n if (index >= 0) {\r\n this.regexRoutes.splice(index, 1);\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n register(method: string, path: string, handler: RouteHandler, metadata: unknown = {}): void {\r\n const key = `${method}:${path}`;\r\n\r\n // Check if path needs regex (has :params or wildcards)\r\n if (path.includes(':') || path.includes('*')) {\r\n // Dynamic route with params or wildcards\r\n const pattern = this.pathToRegex(path);\r\n\r\n // Check if route already exists to prevent duplicates\r\n const existingIndex = this.regexRoutes.findIndex(r => r.key === key);\r\n\r\n const route: RegexRoute = {\r\n pattern,\r\n method,\r\n handler,\r\n key,\r\n metadata\r\n };\r\n\r\n if (existingIndex >= 0) {\r\n // Update existing route\r\n this.regexRoutes[existingIndex] = route;\r\n } else {\r\n // Add new route\r\n this.regexRoutes.push(route);\r\n }\r\n } else {\r\n // Static route\r\n this.routes.set(key, { handler, metadata });\r\n }\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── HELP ──────────────────────────────┐\r\n\r\n private pathToRegex(path: string): RegExp {\r\n // Escape special regex characters except ':' and '*'\r\n let pattern = path.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n\r\n // Replace :param with named capture groups\r\n pattern = pattern.replace(/:(\\w+)/g, '(?<$1>[^/]+)');\r\n\r\n // Replace * with wildcard pattern (matches everything including slashes)\r\n pattern = pattern.replace(/\\*/g, '.*');\r\n\r\n return new RegExp(`^${pattern}$`);\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/mod/security.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import crypto from 'crypto';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n interface RateLimitRecord {\r\n count: number;\r\n reset: number;\r\n }\r\n\r\n interface CsrfTokenData {\r\n sessionId: string;\r\n expires: number;\r\n }\r\n\r\n interface RequestLogEntry {\r\n timestamp: string;\r\n method: string;\r\n path: string;\r\n ip: string;\r\n status: number;\r\n duration: number;\r\n }\r\n\r\n interface SecurityStats {\r\n rateLimitEntries: number;\r\n csrfTokens: number;\r\n requestLogs: number;\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class SecurityManager {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n private rateLimitStore = new Map<string, RateLimitRecord>();\r\n private csrfTokens = new Map<string, CsrfTokenData>();\r\n private requestLog = new Map<string, RequestLogEntry>();\r\n\r\n private readonly MAX_REQUEST_LOG_SIZE = 1000;\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n // Rate Limiting with proper overflow handling\r\n checkRateLimit(key: string, max: number, windowMs: number): boolean {\r\n const now = Date.now();\r\n const record = this.rateLimitStore.get(key);\r\n\r\n if (record) {\r\n if (now < record.reset) {\r\n // Within the current window\r\n if (record.count >= max) {\r\n return false; // Rate limit exceeded\r\n }\r\n record.count++;\r\n return true;\r\n } else {\r\n // Window expired, reset\r\n this.rateLimitStore.set(key, { count: 1, reset: now + windowMs });\r\n return true;\r\n }\r\n } else {\r\n // First request for this key\r\n this.rateLimitStore.set(key, { count: 1, reset: now + windowMs });\r\n return true;\r\n }\r\n }\r\n\r\n // Cleanup old rate limit records\r\n cleanupRateLimit(): void {\r\n const now = Date.now();\r\n for (const [key, record] of this.rateLimitStore.entries()) {\r\n if (now > record.reset) {\r\n this.rateLimitStore.delete(key);\r\n }\r\n }\r\n }\r\n\r\n // CSRF Token Generation with TTL\r\n generateCsrfToken(sessionId: string, ttl = 3600000): string {\r\n const token = crypto.randomBytes(32).toString('hex');\r\n this.csrfTokens.set(token, {\r\n sessionId,\r\n expires: Date.now() + ttl\r\n });\r\n return token;\r\n }\r\n\r\n // Validate CSRF Token with expiration check\r\n validateCsrfToken(token: string, sessionId: string): boolean {\r\n const stored = this.csrfTokens.get(token);\r\n\r\n if (!stored) {\r\n return false;\r\n }\r\n\r\n // Check if token has expired\r\n if (Date.now() > stored.expires) {\r\n this.csrfTokens.delete(token);\r\n return false;\r\n }\r\n\r\n // Validate session ID\r\n if (stored.sessionId === sessionId) {\r\n this.csrfTokens.delete(token); // One-time use\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n // Cleanup expired CSRF tokens\r\n cleanupCsrfTokens(): void {\r\n const now = Date.now();\r\n for (const [token, data] of this.csrfTokens.entries()) {\r\n if (now > data.expires) {\r\n this.csrfTokens.delete(token);\r\n }\r\n }\r\n }\r\n\r\n // HTML Sanitization - comprehensive\r\n sanitizeHtml(html: string): string {\r\n if (!html) return '';\r\n\r\n return html\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#x27;')\r\n .replace(/\\//g, '&#x2F;');\r\n }\r\n\r\n // SQL Injection Prevention\r\n sanitizeSql(input: string): string {\r\n if (!input) return '';\r\n\r\n return input\r\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes first\r\n .replace(/;/g, '') // Remove semicolons to prevent multi-statement injection\r\n .replace(/'/g, \"''\") // Escape single quotes (SQL standard)\r\n .replace(/\"/g, '\\\\\"') // Escape double quotes\r\n // eslint-disable-next-line no-control-regex\r\n .replace(/\\u0000/g, ''); // Remove null bytes\r\n }\r\n\r\n // Log request for audit trail with size limit\r\n logRequest(\r\n id: string,\r\n method: string,\r\n path: string,\r\n ip: string,\r\n status: number,\r\n duration: number\r\n ): void {\r\n this.requestLog.set(id, {\r\n timestamp: new Date().toISOString(),\r\n method,\r\n path,\r\n ip,\r\n status,\r\n duration\r\n });\r\n\r\n // Keep only last MAX_REQUEST_LOG_SIZE requests\r\n if (this.requestLog.size > this.MAX_REQUEST_LOG_SIZE) {\r\n const { value: first } = this.requestLog.keys().next() || { value: null };\r\n if (first) {\r\n this.requestLog.delete(first);\r\n }\r\n }\r\n }\r\n\r\n // Get request log by ID\r\n getRequestLog(id: string): RequestLogEntry | undefined {\r\n return this.requestLog.get(id);\r\n }\r\n\r\n // Get all request logs\r\n getAllRequestLogs(): RequestLogEntry[] {\r\n return Array.from(this.requestLog.values());\r\n }\r\n\r\n // Clear all\r\n clearAll(): void {\r\n this.rateLimitStore.clear();\r\n this.csrfTokens.clear();\r\n this.requestLog.clear();\r\n }\r\n\r\n // Get stats\r\n getStats(): SecurityStats {\r\n return {\r\n rateLimitEntries: this.rateLimitStore.size,\r\n csrfTokens: this.csrfTokens.size,\r\n requestLogs: this.requestLog.size\r\n };\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/types.d.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { DB } from '@je-es/sdb';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n\r\n export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';\r\n export type RouteHandler = (c: AppContext) => Response | Promise<Response>;\r\n export type AppMiddleware = (c: AppContext, next: () => Promise<void>) => void | Promise<void>;\r\n\r\n export interface AppContext {\r\n ip : string;\r\n request : Request;\r\n params : Record<string, string>;\r\n query : Record<string, string>;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n body : any;\r\n headers : Headers;\r\n db : DB | undefined;\r\n logger : Logger | null;\r\n user? : unknown;\r\n requestId : string;\r\n\r\n // Response methods\r\n json (data: unknown, status?: number): Response;\r\n text (data: string, status?: number): Response;\r\n html (data: string, status?: number): Response;\r\n redirect (url: string, status?: number): Response;\r\n file (path: string, contentType?: string): Response;\r\n\r\n // Cookie methods\r\n setCookie (name: string, value: string, options?: CookieOptions): AppContext;\r\n getCookie (name: string): string | undefined;\r\n deleteCookie (name: string, options?: Partial<CookieOptions>): AppContext;\r\n\r\n // Header methods\r\n setHeader(key: string, value: string): AppContext;\r\n getHeader(key: string): string | undefined;\r\n\r\n // Status code\r\n status(code: number): AppContext;\r\n statusCode: number;\r\n\r\n // Internal helper\r\n _setCookieHeaders(): Record<string, string | string[]>;\r\n }\r\n\r\n export interface StaticConfig {\r\n path : string; // URL path prefix (e.g., '/public' or '/static')\r\n directory : string; // Local directory to serve from\r\n maxAge? : number; // Cache control in seconds (default: 3600)\r\n index? : string[]; // Index files (default: ['index.html'])\r\n dotfiles? : 'allow' | 'deny' | 'ignore'; // How to handle dotfiles (default: 'deny')\r\n etag? : boolean; // Enable ETag headers (default: true)\r\n lastModified? : boolean; // Enable Last-Modified headers (default: true)\r\n immutable? : boolean; // Add immutable to cache-control (default: false)\r\n extensions? : string[]; // Try these extensions if file not found (e.g., ['html', 'htm'])\r\n fallthrough? : boolean; // Continue to next handler if file not found (default: false)\r\n setHeaders? : (ctx: AppContext, path: string) => void; // Custom header setter\r\n }\r\n\r\n export interface CookieOptions {\r\n maxAge? : number;\r\n expires? : Date;\r\n path? : string;\r\n domain? : string;\r\n secure? : boolean;\r\n httpOnly? : boolean;\r\n sameSite? : 'Strict' | 'Lax' | 'None';\r\n }\r\n\r\n export interface ValidationSchema {\r\n body?: unknown;\r\n query?: unknown;\r\n params?: unknown;\r\n }\r\n\r\n export interface RouteDefinition {\r\n method : HttpMethod | HttpMethod[];\r\n path : string;\r\n handler : RouteHandler;\r\n validate? : ValidationSchema;\r\n middlewares? : AppMiddleware[];\r\n timeout? : number;\r\n rateLimit? : { max: number; windowMs: number };\r\n cache? : number;\r\n tags? : string[];\r\n }\r\n\r\n // Database types\r\n export interface DatabaseConfig {\r\n name? : string;\r\n connection : string; // File path or ':memory:'\r\n schema? : Record<string, unknown>;\r\n timeout? : number;\r\n }\r\n\r\n export interface SecurityConfig {\r\n cors? : boolean | CorsConfig;\r\n rateLimit? : boolean | RateLimitConfig;\r\n csrf? : boolean | CsrfConfig;\r\n helmet? : boolean | HelmetConfig;\r\n auth? : boolean | AuthConfig;\r\n validation? : boolean;\r\n sanitize? : boolean;\r\n }\r\n\r\n export interface CorsConfig {\r\n origin? : string | string[] | ((origin: string) => boolean);\r\n methods? : HttpMethod[];\r\n allowedHeaders? : string[];\r\n credentials? : boolean;\r\n maxAge? : number;\r\n }\r\n\r\n export interface RateLimitConfig {\r\n windowMs? : number;\r\n max? : number;\r\n keyGenerator? : (c: AppContext) => string;\r\n message? : string;\r\n }\r\n\r\n export interface CsrfConfig {\r\n secret? : string;\r\n headerName? : string;\r\n tokenTTL? : number;\r\n }\r\n\r\n export interface HelmetConfig {\r\n contentSecurityPolicy? : Record<string, string[]> | boolean;\r\n hsts? : boolean | { maxAge?: number; includeSubDomains?: boolean; preload?: boolean };\r\n frameguard? : boolean | { action: 'deny' | 'sameorigin' };\r\n noSniff? : boolean;\r\n xssFilter? : boolean;\r\n referrerPolicy? : string | boolean;\r\n }\r\n\r\n export interface AuthConfig {\r\n jwt? : boolean | { secret: string; expiresIn?: string };\r\n apiKey? : boolean | { header?: string };\r\n bearer? : boolean;\r\n }\r\n\r\n export type LogLevel = 'debug' | 'info' | 'warn' | 'error';\r\n\r\n export interface LoggingConfig {\r\n level?: LogLevel;\r\n pretty?: boolean;\r\n }\r\n\r\n export interface ServerConfig {\r\n port? : number | string;\r\n hostname? : string;\r\n requestTimeout? : number;\r\n maxRequestSize? : number;\r\n maxJsonSize? : number;\r\n\r\n database? : DatabaseConfig | DatabaseConfig[];\r\n\r\n security? : boolean | SecurityConfig;\r\n\r\n compression? : boolean | { threshold?: number };\r\n\r\n logging? : boolean | LoggingConfig;\r\n\r\n // Static file serving\r\n static? : StaticConfig | StaticConfig[];\r\n\r\n routes? : RouteDefinition[];\r\n middlewares? : AppMiddleware[];\r\n\r\n errorHandler? : (error: Error, context: AppContext) => void | Promise<void>;\r\n onShutdown? : () => void | Promise<void>;\r\n\r\n apiPrefix? : string;\r\n apiVersion? : string;\r\n\r\n gracefulShutdownTimeout?: number;\r\n }\r\n\r\n export interface ServerInstance {\r\n app : unknown;\r\n logger : Logger | null;\r\n db : Map<string, unknown>;\r\n bunServer : unknown;\r\n start : () => Promise<void>;\r\n stop : () => Promise<void>;\r\n addRoute : (route: RouteDefinition) => void;\r\n addRoutes : (routes: RouteDefinition[]) => void;\r\n getRoutes : () => RouteDefinition[];\r\n }\r\n\r\n export interface Logger {\r\n debug (data: unknown, msg?: string): void;\r\n info (data: unknown, msg?: string): void;\r\n warn (data: unknown, msg?: string): void;\r\n error (data: unknown, msg?: string): void;\r\n fatal (data: unknown, msg?: string): void;\r\n }\r\n\r\n export class AppError extends Error {\r\n constructor(public message: string, public statusCode: number = 500, public code?: string) {\r\n super(message);\r\n this.name = 'AppError';\r\n }\r\n }\r\n\r\n export class ValidationError extends AppError {\r\n constructor(message: string, public issues?: unknown) {\r\n super(message, 400, 'VALIDATION_ERROR');\r\n this.name = 'ValidationError';\r\n }\r\n }\r\n\r\n export class DatabaseError extends AppError {\r\n constructor(message: string) {\r\n super(message, 500, 'DATABASE_ERROR');\r\n this.name = 'DatabaseError';\r\n }\r\n }\r\n\r\n export class TimeoutError extends AppError {\r\n constructor(message = 'Request timeout') {\r\n super(message, 408, 'TIMEOUT_ERROR');\r\n this.name = 'TimeoutError';\r\n }\r\n }\r\n\r\n export class RateLimitError extends AppError {\r\n constructor(message = 'Too many requests') {\r\n super(message, 429, 'RATE_LIMIT_ERROR');\r\n this.name = 'RateLimitError';\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/mod/static.ts\r\n//\r\n// Static file serving module with security and performance features\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { join, extname, resolve, relative } from 'path';\r\n import { existsSync, statSync } from 'fs';\r\n import type { AppContext } from '../types.d';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n export interface StaticConfig {\r\n path : string; // URL path prefix (e.g., '/public' or '/static')\r\n directory : string; // Local directory to serve from\r\n maxAge? : number; // Cache control in seconds (default: 3600)\r\n index? : string[]; // Index files (default: ['index.html'])\r\n dotfiles? : 'allow' | 'deny' | 'ignore'; // How to handle dotfiles (default: 'deny')\r\n etag? : boolean; // Enable ETag headers (default: true)\r\n lastModified? : boolean; // Enable Last-Modified headers (default: true)\r\n immutable? : boolean; // Add immutable to cache-control (default: false)\r\n extensions? : string[]; // Try these extensions if file not found (e.g., ['html', 'htm'])\r\n fallthrough? : boolean; // Continue to next handler if file not found (default: false)\r\n setHeaders? : (ctx: AppContext, path: string) => void; // Custom header setter\r\n }\r\n\r\n interface CacheEntry {\r\n etag : string;\r\n lastModified : Date;\r\n size : number;\r\n mtime : number;\r\n }\r\n\r\n interface FileStats {\r\n size: number;\r\n mtime: Date;\r\n mtimeMs: number;\r\n isDirectory(): boolean;\r\n isFile(): boolean;\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class StaticFileServer {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n private config : Required<Omit<StaticConfig, 'setHeaders'>> & Pick<StaticConfig, 'setHeaders'>;\r\n private resolvedDir : string;\r\n private fileCache = new Map<string, CacheEntry>();\r\n private readonly CACHE_MAX_SIZE = 1000;\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── CONS ──────────────────────────────┐\r\n\r\n constructor(config: StaticConfig) {\r\n // Validate directory exists\r\n if (!existsSync(config.directory)) {\r\n throw new Error(`Static directory does not exist: ${config.directory}`);\r\n }\r\n\r\n const stats = statSync(config.directory);\r\n if (!stats.isDirectory()) {\r\n throw new Error(`Static path is not a directory: ${config.directory}`);\r\n }\r\n\r\n // Resolve absolute path to prevent directory traversal\r\n this.resolvedDir = resolve(config.directory);\r\n\r\n // Set defaults\r\n this.config = {\r\n path : config.path,\r\n directory : config.directory,\r\n maxAge : config.maxAge ?? 3600,\r\n index : config.index ?? ['index.html'],\r\n dotfiles : config.dotfiles ?? 'deny',\r\n etag : config.etag ?? true,\r\n lastModified : config.lastModified ?? true,\r\n immutable : config.immutable ?? false,\r\n extensions : config.extensions ?? [],\r\n fallthrough : config.fallthrough ?? false,\r\n setHeaders : config.setHeaders\r\n };\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n /**\r\n * Create request handler for static files\r\n */\r\n handler(): (ctx: AppContext) => Promise<Response> {\r\n return async (ctx: AppContext): Promise<Response> => {\r\n const requestPath = ctx.request.url;\r\n const url = new URL(requestPath);\r\n let pathname = url.pathname;\r\n\r\n // Remove prefix from pathname\r\n if (pathname.startsWith(this.config.path)) {\r\n pathname = pathname.slice(this.config.path.length);\r\n }\r\n\r\n // Decode URI component\r\n try {\r\n pathname = decodeURIComponent(pathname);\r\n } catch {\r\n return ctx.json({ error: 'Invalid URL encoding' }, 400);\r\n }\r\n\r\n // Security: Prevent directory traversal\r\n if (pathname.includes('..') || pathname.includes('\\\\')) {\r\n return ctx.json({ error: 'Forbidden' }, 403);\r\n }\r\n\r\n // Handle dotfiles\r\n if (this.config.dotfiles !== 'allow' && pathname.split('/').some(p => p.startsWith('.'))) {\r\n if (this.config.dotfiles === 'deny') {\r\n return ctx.json({ error: 'Forbidden' }, 403);\r\n }\r\n // 'ignore' - treat as not found\r\n return this.handleNotFound(ctx);\r\n }\r\n\r\n // Resolve file path\r\n const filePath = this.resolveFilePath(pathname);\r\n if (!filePath) {\r\n return this.handleNotFound(ctx);\r\n }\r\n\r\n // Check if file exists and is within allowed directory\r\n if (!this.isPathSafe(filePath)) {\r\n return ctx.json({ error: 'Forbidden' }, 403);\r\n }\r\n\r\n if (!existsSync(filePath)) {\r\n return this.handleNotFound(ctx);\r\n }\r\n\r\n const stats = statSync(filePath) as FileStats;\r\n\r\n // If directory, try to serve index file\r\n if (stats.isDirectory()) {\r\n return this.serveDirectory(ctx, filePath, pathname);\r\n }\r\n\r\n // Serve file\r\n return this.serveFile(ctx, filePath, stats);\r\n };\r\n }\r\n\r\n /**\r\n * Get URL path pattern for router\r\n */\r\n getPathPattern(): string {\r\n // Match the prefix and anything after it\r\n return `${this.config.path}/*`;\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── HELP ──────────────────────────────┐\r\n\r\n private resolveFilePath(pathname: string): string | null {\r\n // Remove leading slash\r\n if (pathname.startsWith('/')) {\r\n pathname = pathname.slice(1);\r\n }\r\n\r\n const filePath = join(this.resolvedDir, pathname);\r\n\r\n // Try with extensions if file doesn't exist\r\n if (!existsSync(filePath) && this.config.extensions.length > 0) {\r\n for (const ext of this.config.extensions) {\r\n const withExt = `${filePath}.${ext}`;\r\n if (existsSync(withExt)) {\r\n return withExt;\r\n }\r\n }\r\n }\r\n\r\n return filePath;\r\n }\r\n\r\n private isPathSafe(filePath: string): boolean {\r\n // Ensure the resolved path is within the static directory\r\n const rel = relative(this.resolvedDir, resolve(filePath));\r\n return !rel.startsWith('..') && !resolve(filePath).startsWith('..');\r\n }\r\n\r\n private async serveDirectory(ctx: AppContext, dirPath: string, _: string): Promise<Response> {\r\n // Try index files\r\n for (const indexFile of this.config.index) {\r\n const indexPath = join(dirPath, indexFile);\r\n if (existsSync(indexPath)) {\r\n const stats = statSync(indexPath) as FileStats;\r\n if (stats.isFile()) {\r\n return this.serveFile(ctx, indexPath, stats);\r\n }\r\n }\r\n }\r\n\r\n // No index file found\r\n return this.handleNotFound(ctx);\r\n }\r\n\r\n private async serveFile(ctx: AppContext, filePath: string, stats: FileStats): Promise<Response> {\r\n const method = ctx.request.method.toUpperCase();\r\n\r\n // Only allow GET and HEAD\r\n if (method !== 'GET' && method !== 'HEAD') {\r\n return ctx.json({ error: 'Method not allowed' }, 405);\r\n }\r\n\r\n // Get or create cache entry\r\n const cacheKey = filePath;\r\n let cacheEntry = this.fileCache.get(cacheKey);\r\n\r\n // Check if cache is stale\r\n if (cacheEntry && cacheEntry.mtime !== stats.mtimeMs) {\r\n cacheEntry = undefined;\r\n }\r\n\r\n if (!cacheEntry) {\r\n cacheEntry = {\r\n etag : this.generateEtag(stats),\r\n lastModified : new Date(stats.mtime),\r\n size : stats.size,\r\n mtime : stats.mtimeMs\r\n };\r\n\r\n // Add to cache with size limit\r\n if (this.fileCache.size >= this.CACHE_MAX_SIZE) {\r\n const firstKey = this.fileCache.keys().next().value;\r\n if (firstKey) this.fileCache.delete(firstKey);\r\n }\r\n this.fileCache.set(cacheKey, cacheEntry);\r\n }\r\n\r\n // Check conditional requests\r\n const ifNoneMatch = ctx.request.headers.get('if-none-match');\r\n const ifModifiedSince = ctx.request.headers.get('if-modified-since');\r\n\r\n if (this.config.etag && ifNoneMatch === cacheEntry.etag) {\r\n return new Response(null, {\r\n status: 304,\r\n headers: this.buildHeaders(filePath, cacheEntry)\r\n });\r\n }\r\n\r\n if (this.config.lastModified && ifModifiedSince) {\r\n const ifModDate = new Date(ifModifiedSince);\r\n if (cacheEntry.lastModified <= ifModDate) {\r\n return new Response(null, {\r\n status: 304,\r\n headers: this.buildHeaders(filePath, cacheEntry)\r\n });\r\n }\r\n }\r\n\r\n // Read file using Bun.file\r\n const file = Bun.file(filePath);\r\n const headers = this.buildHeaders(filePath, cacheEntry);\r\n\r\n // Set custom headers if provided\r\n if (this.config.setHeaders) {\r\n this.config.setHeaders(ctx, filePath);\r\n }\r\n\r\n // Return 200 with file content (or just headers for HEAD)\r\n if (method === 'HEAD') {\r\n return new Response(null, {\r\n status: 200,\r\n headers\r\n });\r\n }\r\n\r\n return new Response(file, {\r\n status: 200,\r\n headers\r\n });\r\n }\r\n\r\n private buildHeaders(filePath: string, cache: CacheEntry): Headers {\r\n const headers = new Headers();\r\n\r\n // Content-Type\r\n const mimeType = this.getMimeType(filePath);\r\n headers.set('Content-Type', mimeType);\r\n\r\n // Content-Length\r\n headers.set('Content-Length', cache.size.toString());\r\n\r\n // ETag\r\n if (this.config.etag) {\r\n headers.set('ETag', cache.etag);\r\n }\r\n\r\n // Last-Modified\r\n if (this.config.lastModified) {\r\n headers.set('Last-Modified', cache.lastModified.toUTCString());\r\n }\r\n\r\n // Cache-Control\r\n if (this.config.maxAge > 0) {\r\n let cacheControl = `public, max-age=${this.config.maxAge}`;\r\n if (this.config.immutable) {\r\n cacheControl += ', immutable';\r\n }\r\n headers.set('Cache-Control', cacheControl);\r\n } else {\r\n headers.set('Cache-Control', 'no-cache');\r\n }\r\n\r\n // Accept-Ranges for partial content support\r\n headers.set('Accept-Ranges', 'bytes');\r\n\r\n return headers;\r\n }\r\n\r\n private generateEtag(stats: FileStats): string {\r\n // Simple ETag: size-mtime\r\n return `\"${stats.size.toString(16)}-${stats.mtimeMs.toString(16)}\"`;\r\n }\r\n\r\n private getMimeType(filePath: string): string {\r\n const ext = extname(filePath).toLowerCase();\r\n return MIME_TYPES[ext] || 'application/octet-stream';\r\n }\r\n\r\n private handleNotFound(ctx: AppContext): Response {\r\n if (this.config.fallthrough) {\r\n // Let the next handler deal with it\r\n return ctx.json({ error: 'Not Found' }, 404);\r\n }\r\n return ctx.json({ error: 'Not Found' }, 404);\r\n }\r\n\r\n /**\r\n * Clear file cache\r\n */\r\n clearCache(): void {\r\n this.fileCache.clear();\r\n }\r\n\r\n /**\r\n * Get cache statistics\r\n */\r\n getCacheStats(): { entries: number; maxSize: number } {\r\n return {\r\n entries: this.fileCache.size,\r\n maxSize: this.CACHE_MAX_SIZE\r\n };\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ UTIL ════════════════════════════════════════╗\r\n\r\n /**\r\n * Helper function to create static file server\r\n */\r\n export function createStatic(config: StaticConfig): StaticFileServer {\r\n return new StaticFileServer(config);\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ DATA ════════════════════════════════════════╗\r\n\r\n /**\r\n * Comprehensive MIME type mapping\r\n */\r\n const MIME_TYPES: Record<string, string> = {\r\n // Text\r\n '.html' : 'text/html; charset=utf-8',\r\n '.htm' : 'text/html; charset=utf-8',\r\n '.css' : 'text/css; charset=utf-8',\r\n '.txt' : 'text/plain; charset=utf-8',\r\n '.xml' : 'text/xml; charset=utf-8',\r\n '.csv' : 'text/csv; charset=utf-8',\r\n '.md' : 'text/markdown; charset=utf-8',\r\n\r\n // JavaScript\r\n '.js' : 'application/javascript; charset=utf-8',\r\n '.mjs' : 'application/javascript; charset=utf-8',\r\n '.json' : 'application/json; charset=utf-8',\r\n '.jsonld' : 'application/ld+json',\r\n '.map' : 'application/json; charset=utf-8',\r\n\r\n // Images\r\n '.png' : 'image/png',\r\n '.jpg' : 'image/jpeg',\r\n '.jpeg' : 'image/jpeg',\r\n '.gif' : 'image/gif',\r\n '.svg' : 'image/svg+xml',\r\n '.ico' : 'image/x-icon',\r\n '.webp' : 'image/webp',\r\n '.avif' : 'image/avif',\r\n '.bmp' : 'image/bmp',\r\n '.tiff' : 'image/tiff',\r\n\r\n // Fonts\r\n '.woff' : 'font/woff',\r\n '.woff2' : 'font/woff2',\r\n '.ttf' : 'font/ttf',\r\n '.otf' : 'font/otf',\r\n '.eot' : 'application/vnd.ms-fontobject',\r\n\r\n // Audio\r\n '.mp3' : 'audio/mpeg',\r\n '.wav' : 'audio/wav',\r\n '.ogg' : 'audio/ogg',\r\n '.m4a' : 'audio/mp4',\r\n '.aac' : 'audio/aac',\r\n '.flac' : 'audio/flac',\r\n\r\n // Video\r\n '.mp4' : 'video/mp4',\r\n '.webm' : 'video/webm',\r\n '.ogv' : 'video/ogg',\r\n '.mov' : 'video/quicktime',\r\n '.avi' : 'video/x-msvideo',\r\n '.mkv' : 'video/x-matroska',\r\n\r\n // Documents\r\n '.pdf' : 'application/pdf',\r\n '.doc' : 'application/msword',\r\n '.docx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\r\n '.xls' : 'application/vnd.ms-excel',\r\n '.xlsx' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n '.ppt' : 'application/vnd.ms-powerpoint',\r\n '.pptx' : 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\r\n\r\n // Archives\r\n '.zip' : 'application/zip',\r\n '.rar' : 'application/x-rar-compressed',\r\n '.7z' : 'application/x-7z-compressed',\r\n '.tar' : 'application/x-tar',\r\n '.gz' : 'application/gzip',\r\n\r\n // Other\r\n '.wasm' : 'application/wasm',\r\n '.manifest' : 'text/cache-manifest',\r\n '.webmanifest' : 'application/manifest+json',\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/main.ts\n//\n// Developed with ❤️ by Maysara.\n\n\n\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\n\n import * as sdb from '@je-es/sdb';\n import { Router } from './mod/router';\n import { SecurityManager } from './mod/security';\n import { Logger } \tfrom '@je-es/slog';\n import * as types from './types.d';\n import { StaticFileServer } from './mod/static';\n\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\n\n\n\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\n\n const security = new SecurityManager();\n const router = new Router();\n\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\n\n\n\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\n\n export function server(config: types.ServerConfig = {}): types.ServerInstance {\n\n\t\t// ════════ Configuration ════════\n\t\tconst port = Number(config.port) || 3000;\n\t\tconst hostname = config.hostname || 'localhost';\n\t\tconst maxReqSize = config.maxRequestSize || 10 * 1024 * 1024;\n\t\tconst requestTimeout = config.requestTimeout || 30000;\n\t\tconst gracefulShutdownTimeout = config.gracefulShutdownTimeout || 10000;\n\n\t\tconst logCfg = typeof config.logging === 'object' ? config.logging : {};\n\t\tconst logger = config.logging ? new Logger(logCfg.level || 'info', logCfg.pretty) : null;\n\n\t\tconst dbs = new Map<string, sdb.DB>();\n\t\tconst routes: types.RouteDefinition[] = [];\n\t\tconst activeRequests = new Set<string>();\n\n\t\t// ════════ Cleanup intervals ════════\n const cleanupInterval = setInterval(() => {\n security.cleanupRateLimit();\n security.cleanupCsrfTokens();\n }, 2 * 60 * 1000);\n\n async function handleRequest(request: Request, server: unknown): Promise<Response> {\n const startTime = Date.now();\n const requestId = crypto.randomUUID();\n const url = new URL(request.url);\n const path = url.pathname;\n const method = request.method.toUpperCase();\n const ip = getClientIp(request, server);\n\n activeRequests.add(requestId);\n\n try {\n // Check request size from header\n const contentLength = request.headers.get('content-length');\n if (contentLength && parseInt(contentLength) > maxReqSize) {\n logger?.warn({ requestId, size: contentLength, ip }, 'Request too large');\n return new Response(JSON.stringify({ error: 'Payload too large' }), {\n\t\t\t\t\t\tstatus\t: 413,\n\t\t\t\t\t\theaders\t: { 'Content-Type': 'application/json' }\n });\n }\n\n // CORS handling\n const corsHeaders = handleCors(request, config);\n if (method === 'OPTIONS') {\n return new Response(null, { status: 204, headers: corsHeaders });\n }\n\n // Rate limiting\n if (config.security && typeof config.security === 'object' && config.security.rateLimit) {\n const rateLimitCfg = typeof config.security.rateLimit === 'object'\n ? config.security.rateLimit\n : {};\n const max = rateLimitCfg.max || 100;\n const windowMs = rateLimitCfg.windowMs || 60000;\n const rateLimitKey = rateLimitCfg.keyGenerator\n ? rateLimitCfg.keyGenerator({ request, ip } as types.AppContext)\n : ip;\n\n if (!security.checkRateLimit(rateLimitKey, max, windowMs)) {\n logger?.warn({ requestId, ip, key: rateLimitKey }, 'Rate limit exceeded');\n return new Response(\n JSON.stringify({ error: rateLimitCfg.message || 'Too many requests' }),\n { status: 429, headers: { 'Content-Type': 'application/json' } }\n );\n }\n }\n\n // Parse body\n let body: unknown = null;\n if (['POST', 'PUT', 'PATCH'].includes(method)) {\n body = await parseBody(request, logger, maxReqSize);\n }\n\n // Get database\n const defaultDb = dbs.get('default');\n\n // Match route\n const routeMatch = router.match(method, path);\n if (!routeMatch) {\n const ctx = createAppContext(ip, request, {}, defaultDb, logger, requestId);\n logger?.warn({ requestId, method, path, ip }, 'Route not found');\n return ctx.json({ error: 'Not Found', path }, 404);\n }\n\n const ctx = createAppContext(ip, request, routeMatch.params || {}, defaultDb, logger, requestId);\n ctx.body = body;\n ctx.request = request;\n\n // Execute route handler with timeout\n const controller = new AbortController();\n const timeoutPromise = new Promise<never>((_, reject) => {\n const id = setTimeout(() => {\n controller.abort();\n reject(new types.TimeoutError('Request timeout'));\n }, requestTimeout);\n controller.signal.addEventListener('abort', () => clearTimeout(id));\n });\n\n // Get middlewares from route metadata\n const routeDefinition = routeMatch.metadata as types.RouteDefinition | undefined;\n const middlewares = routeDefinition?.middlewares || [];\n\n let handlerPromise: Promise<Response>;\n if (middlewares.length > 0) {\n handlerPromise = executeMiddlewares(ctx, middlewares, routeMatch.handler);\n } else {\n handlerPromise = Promise.resolve(routeMatch.handler(ctx));\n }\n\n const response = await Promise.race([\n handlerPromise,\n timeoutPromise\n ]) as Response;\n\n // Merge CORS and security headers\n const resHeaders = new Headers(response.headers);\n corsHeaders.forEach((value, key) => {\n if (!resHeaders.has(key)) resHeaders.set(key, value);\n });\n\n resHeaders.set('X-Request-ID', requestId);\n resHeaders.set('X-Content-Type-Options', 'nosniff');\n resHeaders.set('X-Frame-Options', 'DENY');\n resHeaders.set('X-XSS-Protection', '1; mode=block');\n resHeaders.set('Referrer-Policy', 'strict-origin-when-cross-origin');\n\n // Audit log\n const duration = Date.now() - startTime;\n security.logRequest(requestId, method, path, ip, response.status, duration);\n logger?.info({\n requestId,\n method,\n path,\n status: response.status,\n duration,\n ip\n }, 'Request completed');\n\n return new Response(response.body, {\n status: response.status,\n headers: resHeaders\n });\n } catch (error) {\n if (error instanceof types.AppError) {\n logger?.warn({ error: error.message, requestId, ip }, `App error: ${error.message}`);\n return new Response(\n JSON.stringify({\n error\t: error.message,\n code\t: error.code,\n requestId\n }),\n { status: error.statusCode, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n logger?.error({ error: String(error), requestId, ip }, 'Unhandled error');\n\n const errorMessage = process.env.NODE_ENV === 'production'\n ? 'Internal Server Error'\n : (error as Error).message;\n\n return new Response(\n JSON.stringify({ error: errorMessage, requestId }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n } finally {\n activeRequests.delete(requestId);\n }\n }\n\n async function executeMiddlewares(\n ctx: types.AppContext,\n middlewares: types.AppMiddleware[],\n handler: types.RouteHandler\n ): Promise<Response> {\n let index = 0;\n let earlyResponse: Response | null = null;\n\n // Override ctx methods to capture early responses\n const originalJson = ctx.json.bind(ctx);\n const originalText = ctx.text.bind(ctx);\n const originalHtml = ctx.html.bind(ctx);\n const originalRedirect = ctx.redirect.bind(ctx);\n\n ctx.json = function(data: unknown, status?: number): Response {\n const response = originalJson(data, status);\n earlyResponse = response;\n return response;\n };\n\n ctx.text = function(data: string, status?: number): Response {\n const response = originalText(data, status);\n earlyResponse = response;\n return response;\n };\n\n ctx.html = function(data: string, status?: number): Response {\n const response = originalHtml(data, status);\n earlyResponse = response;\n return response;\n };\n\n ctx.redirect = function(url: string, status?: number): Response {\n const response = originalRedirect(url, status);\n earlyResponse = response;\n return response;\n };\n\n async function next(): Promise<void> {\n // If middleware sent a response, stop\n if (earlyResponse) {\n return;\n }\n\n if (index < middlewares.length) {\n const middleware = middlewares[index];\n index++;\n await middleware(ctx, next);\n }\n }\n\n // Execute all middlewares\n await next();\n\n // Restore original methods\n ctx.json = originalJson;\n ctx.text = originalText;\n ctx.html = originalHtml;\n ctx.redirect = originalRedirect;\n\n // If middleware sent a response early, return it\n if (earlyResponse) {\n return earlyResponse;\n }\n\n // Otherwise, call the handler\n return handler(ctx);\n }\n\n // ════════ Health & Readiness routes ════════\n const healthRoute: types.RouteDefinition = {\n method : 'GET',\n path : '/health',\n handler : (c: types.AppContext) => c.json({\n status : 'healthy',\n timestamp : new Date().toISOString(),\n uptime : process.uptime(),\n activeRequests : activeRequests.size\n })\n };\n\n const readinessRoute: types.RouteDefinition = {\n method : 'GET',\n path : '/readiness',\n handler : (c: types.AppContext) => {\n const dbConnected = dbs.size > 0;\n const ready = dbConnected || dbs.size === 0;\n return c.json({\n ready,\n checks : {\n database : dbConnected ? 'connected' : 'not configured',\n activeRequests : activeRequests.size\n },\n timestamp: new Date().toISOString()\n }, ready ? 200 : 503);\n }\n };\n\n // ════════ Register routes ════════\n if (config.routes) {\n config.routes.forEach(route => {\n routes.push(route);\n const methods = Array.isArray(route.method) ? route.method : [route.method];\n methods.forEach(m => {\n router.register(m, route.path, route.handler as types.RouteHandler, route);\n });\n });\n }\n\n // ════════ Static file serving ════════\n if (config.static) {\n const staticConfigs = Array.isArray(config.static) ? config.static : [config.static];\n\n for (const staticCfg of staticConfigs) {\n try {\n const staticServer = new StaticFileServer(staticCfg);\n const handler = staticServer.handler();\n\n const staticRoute: types.RouteDefinition = {\n method: 'GET',\n path: staticCfg.path === '/' ? '/*' : `${staticCfg.path}/*`,\n handler: handler as types.RouteHandler\n };\n\n routes.push(staticRoute);\n\n if (staticCfg.path === '/') {\n router.register('GET', '/', handler as types.RouteHandler, staticRoute);\n router.register('HEAD', '/', handler as types.RouteHandler, staticRoute);\n router.register('GET', '/*', handler as types.RouteHandler, staticRoute);\n router.register('HEAD', '/*', handler as types.RouteHandler, staticRoute);\n } else {\n router.register('GET', `${staticCfg.path}/*`, handler as types.RouteHandler, staticRoute);\n router.register('HEAD', `${staticCfg.path}/*`, handler as types.RouteHandler, staticRoute);\n }\n } catch (error) {\n logger?.error({\n error: String(error),\n path: staticCfg.path\n }, 'Failed to initialize static file server');\n throw error;\n }\n }\n }\n\n routes.push(healthRoute, readinessRoute);\n router.register('GET', '/health', healthRoute.handler as types.RouteHandler, healthRoute);\n router.register('GET', '/readiness', readinessRoute.handler as types.RouteHandler, readinessRoute);\n\n let bunServer: unknown = null;\n\n const instance: types.ServerInstance = {\n app : null,\n logger,\n db : dbs,\n bunServer : null,\n\n async start() {\n if (config.database) {\n const dbConfigs = Array.isArray(config.database) ? config.database : [config.database];\n for (const dbCfg of dbConfigs) {\n const dbName = dbCfg.name || 'default';\n\n try {\n if (typeof dbCfg.connection === 'string') {\n const db = new sdb.DB(dbCfg.connection);\n\n if (dbCfg.schema && typeof dbCfg.schema === 'object') {\n for (const [, tableSchema] of Object.entries(dbCfg.schema)) {\n if (tableSchema && typeof tableSchema === 'object') {\n db.defineSchema(tableSchema as sdb.TableSchema);\n }\n }\n }\n\n dbs.set(dbName, db);\n\n logger?.info({\n name: dbName,\n connection: dbCfg.connection\n }, '✔ Database connected');\n } else {\n throw new Error(`Database connection must be a string path (got ${typeof dbCfg.connection})`);\n }\n } catch (error) {\n logger?.error({\n error: String(error),\n name: dbName\n }, 'Failed to connect to database');\n throw error;\n }\n }\n }\n\n bunServer = Bun.serve({\n port,\n hostname,\n fetch: (request, server) => handleRequest(request, server)\n });\n instance.bunServer = bunServer;\n\n const url = `http://${hostname}:${port}`;\n logger?.info({ url }, '✔ Server started');\n },\n\n async stop() {\n logger?.info('Stopping server...');\n\n if (activeRequests.size > 0) {\n logger?.info({ count: activeRequests.size }, 'Waiting for active requests...');\n const deadline = Date.now() + gracefulShutdownTimeout;\n\n while (activeRequests.size > 0 && Date.now() < deadline) {\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n\n if (activeRequests.size > 0) {\n logger?.warn({ count: activeRequests.size }, 'Force closing with active requests');\n }\n }\n\n clearInterval(cleanupInterval);\n\n if (config.onShutdown) {\n try {\n await config.onShutdown();\n } catch (e) {\n logger?.error({ error: String(e) }, 'Error in shutdown handler');\n }\n }\n\n for (const [name, db] of dbs.entries()) {\n try {\n if (db && typeof db.close === 'function') {\n db.close();\n }\n logger?.info({ name }, 'Database closed');\n } catch (e) {\n logger?.error({ error: String(e), name }, 'Error closing database');\n }\n }\n\n if (bunServer && typeof (bunServer as { stop?: () => void }).stop === 'function') {\n (bunServer as { stop: () => void }).stop();\n logger?.info('Bun server stopped');\n }\n\n logger?.info('Server stopped successfully');\n },\n\n addRoute(route: types.RouteDefinition) {\n routes.push(route);\n const methods = Array.isArray(route.method) ? route.method : [route.method];\n methods.forEach(m => {\n router.register(m, route.path, route.handler as types.RouteHandler, route);\n });\n logger?.info({ method: route.method, path: route.path }, 'Route added');\n },\n\n addRoutes(routes: types.RouteDefinition[]) {\n routes.forEach(route => this.addRoute(route));\n },\n\n getRoutes() {\n return routes;\n }\n };\n\n return instance;\n\t}\n\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\n\n\n\n// ╔════════════════════════════════════════ HELP ════════════════════════════════════════╗\n\n async function parseBody(\n request : Request,\n logger : Logger | null,\n maxSize : number\n ): Promise<unknown> {\n const contentType = request.headers.get('content-type') || '';\n\n try {\n if (contentType.includes('application/json')) {\n\t\t\t\tconst text = await request.text();\n\n\t\t\t\tif (text.length > maxSize) {\n\t\t\t\t\tthrow new types.ValidationError('Payload too large');\n\t\t\t\t}\n\n\t\t\t\tif (!text.trim()) return {};\n\n\t\t\t\ttry {\n\t\t\t\t\treturn JSON.parse(text);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlogger?.warn({\n\t\t\t\t\t\terror\t\t: String(e),\n\t\t\t\t\t\tbodyPreview\t: text.substring(0, 100)\n\t\t\t\t\t}, 'Invalid JSON in request body');\n\n\t\t\t\t\tthrow new types.ValidationError('Invalid JSON in request body');\n\t\t\t\t}\n }\n\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await request.text();\n if (text.length > maxSize) {\n throw new types.ValidationError('Payload too large');\n }\n return Object.fromEntries(new URLSearchParams(text));\n }\n\n if (contentType.includes('multipart/form-data')) {\n return await request.formData();\n }\n } catch (e) {\n if (e instanceof types.ValidationError) throw e;\n logger?.error({ error: String(e) }, 'Error parsing request body');\n throw new types.ValidationError('Failed to parse request body');\n }\n\n return {};\n }\n\n function parseCookies(cookieHeader: string): Map<string, string> {\n const cookies = new Map<string, string>();\n\n if (!cookieHeader) return cookies;\n\n const pairs = cookieHeader.split(';');\n for (const pair of pairs) {\n const [key, ...valueParts] = pair.trim().split('=');\n if (key) {\n const value = valueParts.join('=');\n cookies.set(key, value ? decodeURIComponent(value) : '');\n }\n }\n\n return cookies;\n }\n\n function createAppContext(\n ip : string,\n request : Request,\n params : Record<string, string>,\n db : sdb.DB | undefined,\n logger : Logger | null,\n requestId : string\n ): types.AppContext {\n const url = new URL(request.url);\n const query = Object.fromEntries(url.searchParams);\n const headers = request.headers;\n let statusCode = 200;\n const cookieStore = new Map<string, string>();\n const parsedCookies = parseCookies(headers.get('cookie') || '');\n\n const ctx: types.AppContext = {\n ip,\n request,\n params,\n query,\n headers,\n db,\n logger,\n requestId,\n get statusCode() { return statusCode; },\n set statusCode(code: number) { statusCode = code; },\n body: null,\n\n json(data: unknown, status?: number): Response {\n return new Response(JSON.stringify(data), {\n status : status ?? statusCode,\n headers : {\n 'Content-Type': 'application/json',\n ...this._setCookieHeaders()\n }\n });\n },\n\n text(data: string, status?: number): Response {\n return new Response(data, {\n status : status ?? statusCode,\n headers : {\n 'Content-Type': 'text/plain',\n ...this._setCookieHeaders()\n }\n });\n },\n\n html(data: string, status?: number): Response {\n return new Response(data, {\n status : status ?? statusCode,\n headers : {\n 'Content-Type': 'text/html; charset=utf-8',\n ...this._setCookieHeaders()\n }\n });\n },\n\n redirect(url: string, status = 302): Response {\n return new Response(null, {\n status,\n headers : {\n Location : url,\n ...this._setCookieHeaders()\n }\n });\n },\n\n file(path: string, contentType = 'application/octet-stream'): Response {\n const file = Bun.file(path);\n return new Response(file, {\n headers: {\n 'Content-Type': contentType,\n ...this._setCookieHeaders()\n }\n });\n },\n\n setCookie(name: string, value: string, options: types.CookieOptions = {}): types.AppContext {\n let cookie = `${name}=${encodeURIComponent(value)}`;\n\n if (options.maxAge !== undefined) {\n cookie += `; Max-Age=${options.maxAge}`;\n }\n if (options.expires) {\n cookie += `; Expires=${options.expires.toUTCString()}`;\n }\n if (options.path) {\n cookie += `; Path=${options.path}`;\n }\n if (options.domain) {\n cookie += `; Domain=${options.domain}`;\n }\n if (options.secure) {\n cookie += '; Secure';\n }\n if (options.httpOnly) {\n cookie += '; HttpOnly';\n }\n if (options.sameSite) {\n cookie += `; SameSite=${options.sameSite}`;\n }\n\n cookieStore.set(name, cookie);\n return ctx;\n },\n\n getCookie(name: string): string | undefined {\n return parsedCookies.get(name);\n },\n\n deleteCookie(name: string, options: Partial<types.CookieOptions> = {}): types.AppContext {\n return ctx.setCookie(name, '', {\n ...options,\n maxAge: 0,\n path: options.path || '/'\n });\n },\n\n setHeader(key: string, value: string): types.AppContext {\n headers.set(key, value);\n return ctx;\n },\n\n getHeader(key: string): string | undefined {\n return headers.get(key) || undefined;\n },\n\n status(code: number): types.AppContext {\n statusCode = code;\n return ctx;\n },\n\n _setCookieHeaders(): Record<string, string | string[]> {\n const h: Record<string, string | string[]> = {};\n if (cookieStore.size > 0) {\n h['Set-Cookie'] = Array.from(cookieStore.values());\n }\n return h;\n }\n };\n\n return ctx;\n }\n\n function getClientIp(request: Request, server?: unknown): string {\n const forwarded = request.headers.get('x-forwarded-for');\n if (forwarded) {\n const ips = forwarded.split(',').map(ip => ip.trim());\n return ips[0] || 'unknown';\n }\n\n const realIp = request.headers.get('x-real-ip');\n if (realIp) return realIp;\n\n if (server) {\n try {\n const serverWithRequestIP = server as { requestIP?: (req: Request) => { address?: string } | null };\n const remoteAddress = serverWithRequestIP.requestIP?.(request);\n if (remoteAddress?.address) {\n return remoteAddress.address;\n }\n } catch {\n // Fallback if requestIP fails\n }\n }\n\n return 'unknown';\n }\n\n function handleCors(request: Request, config: types.ServerConfig): Headers {\n const headers = new Headers();\n\n if (!config.security || typeof config.security !== 'object' || !config.security.cors) {\n return headers;\n }\n\n const corsConfig = typeof config.security.cors === 'object' ? config.security.cors : {};\n const origin = request.headers.get('Origin');\n\n if (origin) {\n if (typeof corsConfig.origin === 'function') {\n if (corsConfig.origin(origin)) {\n headers.set('Access-Control-Allow-Origin', origin);\n }\n } else if (Array.isArray(corsConfig.origin)) {\n if (corsConfig.origin.includes(origin)) {\n headers.set('Access-Control-Allow-Origin', origin);\n }\n } else if (typeof corsConfig.origin === 'string') {\n headers.set('Access-Control-Allow-Origin', corsConfig.origin);\n } else {\n headers.set('Access-Control-Allow-Origin', origin);\n }\n\n const methods = corsConfig.methods || ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'];\n headers.set('Access-Control-Allow-Methods', methods.join(', '));\n\n const allowedHeaders = corsConfig.allowedHeaders || ['Content-Type', 'Authorization', 'X-Requested-With'];\n headers.set('Access-Control-Allow-Headers', allowedHeaders.join(', '));\n\n if (corsConfig.credentials) {\n headers.set('Access-Control-Allow-Credentials', 'true');\n }\n\n if (corsConfig.maxAge) {\n headers.set('Access-Control-Max-Age', corsConfig.maxAge.toString());\n }\n }\n\n return headers;\n }\n\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\n\n\n\n// ╔════════════════════════════════════════ ════ ════════════════════════════════════════╗\n\n export * from './types.d';\n export { Logger };\n export { SecurityManager };\n export { Router };\n export {\n DB,\n table,\n column,\n integer,\n text,\n real,\n blob,\n numeric,\n primaryKey,\n notNull,\n unique,\n defaultValue,\n references\n } from '@je-es/sdb';\n export type {\n ColumnType,\n SqlValue,\n ColumnDefinition,\n TableSchema,\n WhereCondition,\n QueryBuilder\n } from '@je-es/sdb';\n export { StaticFileServer, createStatic } from './mod/static';\n export type { StaticConfig } from './mod/static';\n export default server;\n\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝"]}
1
+ {"version":3,"sources":["../src/mod/router.ts","../src/mod/security.ts","../src/types.d.ts","../src/mod/static.ts","../src/mod/i18n.ts","../src/main.ts"],"names":["Router","method","path","key","route","match","params","staticRoutes","colonIndex","dynamicRoutes","index","r","handler","metadata","pattern","existingIndex","SecurityManager","max","windowMs","now","record","sessionId","ttl","token","crypto","stored","data","html","input","id","ip","status","duration","first","AppError","message","statusCode","code","ValidationError","issues","DatabaseError","TimeoutError","RateLimitError","StaticFileServer","config","existsSync","statSync","resolve","ctx","requestPath","pathname","p","filePath","stats","join","ext","withExt","relative","dirPath","_","indexFile","indexPath","cacheKey","cacheEntry","firstKey","ifNoneMatch","ifModifiedSince","ifModDate","file","headers","cache","mimeType","cacheControl","extname","MIME_TYPES","createStatic","I18nManager","lang","translations","trans","defaultValue","translation","param","value","paramValue","currentLang","result","i18nInstance","initI18n","getI18n","t","setLanguage","getCurrentLanguage","getSupportedLanguages","security","router","server","port","hostname","maxReqSize","requestTimeout","gracefulShutdownTimeout","logCfg","logger","Logger","i18n","i18nCfg","dbs","routes","activeRequests","cleanupInterval","handleRequest","request","startTime","requestId","getClientIp","contentLength","corsHeaders","handleCors","rateLimitCfg","rateLimitKey","body","parseBody","defaultDb","requestLang","routeMatch","createAppContext","controller","timeoutPromise","reject","middlewares","handlerPromise","executeMiddlewares","response","resHeaders","error","errorMessage","earlyResponse","originalJson","originalText","originalHtml","originalRedirect","url","next","middleware","healthRoute","c","readinessRoute","dbConnected","ready","m","staticConfigs","staticCfg","staticRoute","bunServer","instance","staticPath","supportedLangs","dbConfigs","dbCfg","dbName","db","tableSchema","deadline","e","name","maxSize","contentType","text","parseCookies","cookieHeader","cookies","pairs","pair","valueParts","i18nMgr","query","cookieStore","parsedCookies","options","cookie","h","forwarded","realIp","remoteAddress","corsConfig","origin","methods","allowedHeaders","main_default"],"mappings":"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","file":"main.js","sourcesContent":["// src/mod/router.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { AppContext } from '../types.d';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n export type RouteHandler = (ctx: AppContext) => Response | Promise<Response>;\r\n export type RegexRoutes = RegexRoute[];\r\n\r\n export interface RegexRoute {\r\n pattern : RegExp;\r\n method : string;\r\n handler : RouteHandler;\r\n key : string;\r\n metadata? : unknown;\r\n }\r\n\r\n export interface RouteMatch {\r\n handler : RouteHandler;\r\n params : Record<string, string>;\r\n metadata? : unknown;\r\n }\r\n\r\n export interface RouteInfo {\r\n method : string;\r\n path : string;\r\n handler : RouteHandler;\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class Router {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n private routes = new Map<string, { handler: RouteHandler; metadata?: unknown }>();\r\n private regexRoutes: RegexRoutes = [];\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n match(method: string, path: string): RouteMatch | null {\r\n const key = `${method}:${path}`;\r\n\r\n // Try static route first (faster)\r\n if (this.routes.has(key)) {\r\n const route = this.routes.get(key)!;\r\n return {\r\n handler: route.handler,\r\n params: {},\r\n metadata: route.metadata\r\n };\r\n }\r\n\r\n // Try dynamic routes\r\n for (const route of this.regexRoutes) {\r\n if (route.method === method) {\r\n const match = path.match(route.pattern);\r\n if (match) {\r\n // Extract named groups if they exist\r\n const params = match.groups || {};\r\n return {\r\n handler: route.handler,\r\n params,\r\n metadata: route.metadata\r\n };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n getAll(): RouteInfo[] {\r\n const staticRoutes = Array.from(this.routes.entries()).map(([key, route]) => {\r\n const colonIndex = key.indexOf(':');\r\n const method = key.substring(0, colonIndex);\r\n const path = key.substring(colonIndex + 1);\r\n return { method, path, handler: route.handler };\r\n });\r\n\r\n const dynamicRoutes = this.regexRoutes.map(route => {\r\n const colonIndex = route.key.indexOf(':');\r\n return {\r\n method: route.method,\r\n path: route.key.substring(colonIndex + 1),\r\n handler: route.handler\r\n };\r\n });\r\n\r\n return [...staticRoutes, ...dynamicRoutes];\r\n }\r\n\r\n clear(): void {\r\n this.routes.clear();\r\n this.regexRoutes = [];\r\n }\r\n\r\n remove(method: string, path: string): boolean {\r\n const key = `${method}:${path}`;\r\n\r\n if (this.routes.has(key)) {\r\n this.routes.delete(key);\r\n return true;\r\n }\r\n\r\n const index = this.regexRoutes.findIndex(r => r.key === key);\r\n if (index >= 0) {\r\n this.regexRoutes.splice(index, 1);\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n register(method: string, path: string, handler: RouteHandler, metadata: unknown = {}): void {\r\n const key = `${method}:${path}`;\r\n\r\n // Check if path needs regex (has :params or wildcards)\r\n if (path.includes(':') || path.includes('*')) {\r\n // Dynamic route with params or wildcards\r\n const pattern = this.pathToRegex(path);\r\n\r\n // Check if route already exists to prevent duplicates\r\n const existingIndex = this.regexRoutes.findIndex(r => r.key === key);\r\n\r\n const route: RegexRoute = {\r\n pattern,\r\n method,\r\n handler,\r\n key,\r\n metadata\r\n };\r\n\r\n if (existingIndex >= 0) {\r\n // Update existing route\r\n this.regexRoutes[existingIndex] = route;\r\n } else {\r\n // Add new route\r\n this.regexRoutes.push(route);\r\n }\r\n } else {\r\n // Static route\r\n this.routes.set(key, { handler, metadata });\r\n }\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── HELP ──────────────────────────────┐\r\n\r\n private pathToRegex(path: string): RegExp {\r\n // Escape special regex characters except ':' and '*'\r\n let pattern = path.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n\r\n // Replace :param with named capture groups\r\n pattern = pattern.replace(/:(\\w+)/g, '(?<$1>[^/]+)');\r\n\r\n // Replace * with wildcard pattern (matches everything including slashes)\r\n pattern = pattern.replace(/\\*/g, '.*');\r\n\r\n return new RegExp(`^${pattern}$`);\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/mod/security.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import crypto from 'crypto';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n interface RateLimitRecord {\r\n count : number;\r\n reset : number;\r\n }\r\n\r\n interface CsrfTokenData {\r\n sessionId : string;\r\n expires : number;\r\n }\r\n\r\n interface RequestLogEntry {\r\n timestamp : string;\r\n method : string;\r\n path : string;\r\n ip : string;\r\n status : number;\r\n duration : number;\r\n }\r\n\r\n interface SecurityStats {\r\n rateLimitEntries : number;\r\n csrfTokens : number;\r\n requestLogs : number;\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class SecurityManager {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n private rateLimitStore = new Map<string, RateLimitRecord>();\r\n private csrfTokens = new Map<string, CsrfTokenData>();\r\n private requestLog = new Map<string, RequestLogEntry>();\r\n\r\n private readonly MAX_REQUEST_LOG_SIZE = 1000;\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n // Rate Limiting with proper overflow handling\r\n checkRateLimit(key: string, max: number, windowMs: number): boolean {\r\n const now = Date.now();\r\n const record = this.rateLimitStore.get(key);\r\n\r\n if (record) {\r\n if (now < record.reset) {\r\n // Within the current window\r\n if (record.count >= max) {\r\n return false; // Rate limit exceeded\r\n }\r\n record.count++;\r\n return true;\r\n } else {\r\n // Window expired, reset\r\n this.rateLimitStore.set(key, { count: 1, reset: now + windowMs });\r\n return true;\r\n }\r\n } else {\r\n // First request for this key\r\n this.rateLimitStore.set(key, { count: 1, reset: now + windowMs });\r\n return true;\r\n }\r\n }\r\n\r\n // Cleanup old rate limit records\r\n cleanupRateLimit(): void {\r\n const now = Date.now();\r\n for (const [key, record] of this.rateLimitStore.entries()) {\r\n if (now > record.reset) {\r\n this.rateLimitStore.delete(key);\r\n }\r\n }\r\n }\r\n\r\n // CSRF Token Generation with TTL\r\n generateCsrfToken(sessionId: string, ttl = 3600000): string {\r\n const token = crypto.randomBytes(32).toString('hex');\r\n this.csrfTokens.set(token, {\r\n sessionId,\r\n expires: Date.now() + ttl\r\n });\r\n return token;\r\n }\r\n\r\n // Validate CSRF Token with expiration check\r\n validateCsrfToken(token: string, sessionId: string): boolean {\r\n const stored = this.csrfTokens.get(token);\r\n\r\n if (!stored) {\r\n return false;\r\n }\r\n\r\n // Check if token has expired\r\n if (Date.now() > stored.expires) {\r\n this.csrfTokens.delete(token);\r\n return false;\r\n }\r\n\r\n // Validate session ID\r\n if (stored.sessionId === sessionId) {\r\n this.csrfTokens.delete(token); // One-time use\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n // Cleanup expired CSRF tokens\r\n cleanupCsrfTokens(): void {\r\n const now = Date.now();\r\n for (const [token, data] of this.csrfTokens.entries()) {\r\n if (now > data.expires) {\r\n this.csrfTokens.delete(token);\r\n }\r\n }\r\n }\r\n\r\n // HTML Sanitization - comprehensive\r\n sanitizeHtml(html: string): string {\r\n if (!html) return '';\r\n\r\n return html\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#x27;')\r\n .replace(/\\//g, '&#x2F;');\r\n }\r\n\r\n // SQL Injection Prevention\r\n sanitizeSql(input: string): string {\r\n if (!input) return '';\r\n\r\n return input\r\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes first\r\n .replace(/;/g, '') // Remove semicolons to prevent multi-statement injection\r\n .replace(/'/g, \"''\") // Escape single quotes (SQL standard)\r\n .replace(/\"/g, '\\\\\"') // Escape double quotes\r\n // eslint-disable-next-line no-control-regex\r\n .replace(/\\u0000/g, ''); // Remove null bytes\r\n }\r\n\r\n // Log request for audit trail with size limit\r\n logRequest(\r\n id: string,\r\n method: string,\r\n path: string,\r\n ip: string,\r\n status: number,\r\n duration: number\r\n ): void {\r\n this.requestLog.set(id, {\r\n timestamp: new Date().toISOString(),\r\n method,\r\n path,\r\n ip,\r\n status,\r\n duration\r\n });\r\n\r\n // Keep only last MAX_REQUEST_LOG_SIZE requests\r\n if (this.requestLog.size > this.MAX_REQUEST_LOG_SIZE) {\r\n const { value: first } = this.requestLog.keys().next() || { value: null };\r\n if (first) {\r\n this.requestLog.delete(first);\r\n }\r\n }\r\n }\r\n\r\n // Get request log by ID\r\n getRequestLog(id: string): RequestLogEntry | undefined {\r\n return this.requestLog.get(id);\r\n }\r\n\r\n // Get all request logs\r\n getAllRequestLogs(): RequestLogEntry[] {\r\n return Array.from(this.requestLog.values());\r\n }\r\n\r\n // Clear all\r\n clearAll(): void {\r\n this.rateLimitStore.clear();\r\n this.csrfTokens.clear();\r\n this.requestLog.clear();\r\n }\r\n\r\n // Get stats\r\n getStats(): SecurityStats {\r\n return {\r\n rateLimitEntries: this.rateLimitStore.size,\r\n csrfTokens: this.csrfTokens.size,\r\n requestLogs: this.requestLog.size\r\n };\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/types.d.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { DB } from '@je-es/sdb';\r\n import type { I18nManager } from './mod/i18n';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n\r\n export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';\r\n export type RouteHandler = (c: AppContext) => Response | Promise<Response>;\r\n export type AppMiddleware = (c: AppContext, next: () => Promise<void>) => void | Promise<void>;\r\n\r\n export interface AppContext {\r\n ip : string;\r\n request : Request;\r\n params : Record<string, string>;\r\n query : Record<string, string>;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n body : any;\r\n headers : Headers;\r\n db : DB | undefined;\r\n logger : Logger | null;\r\n i18n : I18nManager | null;\r\n lang? : string;\r\n user? : unknown;\r\n requestId : string;\r\n\r\n // Response methods\r\n json (data: unknown, status?: number): Response;\r\n text (data: string, status?: number): Response;\r\n html (data: string, status?: number): Response;\r\n redirect (url: string, status?: number): Response;\r\n file (path: string, contentType?: string): Response;\r\n\r\n // Cookie methods\r\n setCookie (name: string, value: string, options?: CookieOptions): AppContext;\r\n getCookie (name: string): string | undefined;\r\n deleteCookie (name: string, options?: Partial<CookieOptions>): AppContext;\r\n\r\n // Header methods\r\n setHeader(key: string, value: string): AppContext;\r\n getHeader(key: string): string | undefined;\r\n\r\n // Status code\r\n status(code: number): AppContext;\r\n statusCode: number;\r\n\r\n // Internal helper\r\n _setCookieHeaders(): Record<string, string | string[]>;\r\n }\r\n\r\n export interface StaticConfig {\r\n path : string; // URL path prefix (e.g., '/public' or '/static')\r\n directory : string; // Local directory to serve from\r\n maxAge? : number; // Cache control in seconds (default: 3600)\r\n index? : string[]; // Index files (default: ['index.html'])\r\n dotfiles? : 'allow' | 'deny' | 'ignore'; // How to handle dotfiles (default: 'deny')\r\n etag? : boolean; // Enable ETag headers (default: true)\r\n lastModified? : boolean; // Enable Last-Modified headers (default: true)\r\n immutable? : boolean; // Add immutable to cache-control (default: false)\r\n extensions? : string[]; // Try these extensions if file not found (e.g., ['html', 'htm'])\r\n fallthrough? : boolean; // Continue to next handler if file not found (default: false)\r\n setHeaders? : (ctx: AppContext, path: string) => void; // Custom header setter\r\n }\r\n\r\n export interface CookieOptions {\r\n maxAge? : number;\r\n expires? : Date;\r\n path? : string;\r\n domain? : string;\r\n secure? : boolean;\r\n httpOnly? : boolean;\r\n sameSite? : 'Strict' | 'Lax' | 'None';\r\n }\r\n\r\n export interface ValidationSchema {\r\n body?: unknown;\r\n query?: unknown;\r\n params?: unknown;\r\n }\r\n\r\n export interface RouteDefinition {\r\n method : HttpMethod | HttpMethod[];\r\n path : string;\r\n handler : RouteHandler;\r\n validate? : ValidationSchema;\r\n middlewares? : AppMiddleware[];\r\n timeout? : number;\r\n rateLimit? : { max: number; windowMs: number };\r\n cache? : number;\r\n tags? : string[];\r\n }\r\n\r\n // Database types\r\n export interface DatabaseConfig {\r\n name? : string;\r\n connection : string; // File path or ':memory:'\r\n schema? : Record<string, unknown>;\r\n timeout? : number;\r\n }\r\n\r\n export interface SecurityConfig {\r\n cors? : boolean | CorsConfig;\r\n rateLimit? : boolean | RateLimitConfig;\r\n csrf? : boolean | CsrfConfig;\r\n helmet? : boolean | HelmetConfig;\r\n auth? : boolean | AuthConfig;\r\n validation? : boolean;\r\n sanitize? : boolean;\r\n }\r\n\r\n export interface CorsConfig {\r\n origin? : string | string[] | ((origin: string) => boolean);\r\n methods? : HttpMethod[];\r\n allowedHeaders? : string[];\r\n credentials? : boolean;\r\n maxAge? : number;\r\n }\r\n\r\n export interface RateLimitConfig {\r\n windowMs? : number;\r\n max? : number;\r\n keyGenerator? : (c: AppContext) => string;\r\n message? : string;\r\n }\r\n\r\n export interface CsrfConfig {\r\n secret? : string;\r\n headerName? : string;\r\n tokenTTL? : number;\r\n }\r\n\r\n export interface HelmetConfig {\r\n contentSecurityPolicy? : Record<string, string[]> | boolean;\r\n hsts? : boolean | { maxAge?: number; includeSubDomains?: boolean; preload?: boolean };\r\n frameguard? : boolean | { action: 'deny' | 'sameorigin' };\r\n noSniff? : boolean;\r\n xssFilter? : boolean;\r\n referrerPolicy? : string | boolean;\r\n }\r\n\r\n export interface AuthConfig {\r\n jwt? : boolean | { secret: string; expiresIn?: string };\r\n apiKey? : boolean | { header?: string };\r\n bearer? : boolean;\r\n }\r\n\r\n export type LogLevel = 'debug' | 'info' | 'warn' | 'error';\r\n\r\n export interface LoggingConfig {\r\n level?: LogLevel;\r\n pretty?: boolean;\r\n }\r\n\r\n export interface I18nConfig {\r\n defaultLanguage? : string;\r\n supportedLanguages? : string[];\r\n staticPath? : string; // Path to static i18n files\r\n }\r\n\r\n export type TranslationSet = Record<string, Record<string, string>>;\r\n\r\n export interface ServerConfig {\r\n port? : number | string;\r\n hostname? : string;\r\n requestTimeout? : number;\r\n maxRequestSize? : number;\r\n maxJsonSize? : number;\r\n\r\n database? : DatabaseConfig | DatabaseConfig[];\r\n\r\n security? : boolean | SecurityConfig;\r\n\r\n compression? : boolean | { threshold?: number };\r\n\r\n logging? : boolean | LoggingConfig;\r\n\r\n // Internationalization (i18n)\r\n i18n? : boolean | I18nConfig;\r\n\r\n // Static file serving\r\n static? : StaticConfig | StaticConfig[];\r\n\r\n routes? : RouteDefinition[];\r\n middlewares? : AppMiddleware[];\r\n\r\n errorHandler? : (error: Error, context: AppContext) => void | Promise<void>;\r\n onShutdown? : () => void | Promise<void>;\r\n\r\n apiPrefix? : string;\r\n apiVersion? : string;\r\n\r\n gracefulShutdownTimeout?: number;\r\n }\r\n\r\n export interface ServerInstance {\r\n app : unknown;\r\n logger : Logger | null;\r\n db : Map<string, unknown>;\r\n bunServer : unknown;\r\n start : () => Promise<void>;\r\n stop : () => Promise<void>;\r\n addRoute : (route: RouteDefinition) => void;\r\n addRoutes : (routes: RouteDefinition[]) => void;\r\n getRoutes : () => RouteDefinition[];\r\n }\r\n\r\n export interface Logger {\r\n debug (data: unknown, msg?: string): void;\r\n info (data: unknown, msg?: string): void;\r\n warn (data: unknown, msg?: string): void;\r\n error (data: unknown, msg?: string): void;\r\n fatal (data: unknown, msg?: string): void;\r\n }\r\n\r\n export class AppError extends Error {\r\n constructor(public message: string, public statusCode: number = 500, public code?: string) {\r\n super(message);\r\n this.name = 'AppError';\r\n }\r\n }\r\n\r\n export class ValidationError extends AppError {\r\n constructor(message: string, public issues?: unknown) {\r\n super(message, 400, 'VALIDATION_ERROR');\r\n this.name = 'ValidationError';\r\n }\r\n }\r\n\r\n export class DatabaseError extends AppError {\r\n constructor(message: string) {\r\n super(message, 500, 'DATABASE_ERROR');\r\n this.name = 'DatabaseError';\r\n }\r\n }\r\n\r\n export class TimeoutError extends AppError {\r\n constructor(message = 'Request timeout') {\r\n super(message, 408, 'TIMEOUT_ERROR');\r\n this.name = 'TimeoutError';\r\n }\r\n }\r\n\r\n export class RateLimitError extends AppError {\r\n constructor(message = 'Too many requests') {\r\n super(message, 429, 'RATE_LIMIT_ERROR');\r\n this.name = 'RateLimitError';\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/mod/static.ts\r\n//\r\n// Static file serving module with security and performance features\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { join, extname, resolve, relative } from 'path';\r\n import { existsSync, statSync } from 'fs';\r\n import type { AppContext } from '../types.d';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n export interface StaticConfig {\r\n path : string; // URL path prefix (e.g., '/public' or '/static')\r\n directory : string; // Local directory to serve from\r\n maxAge? : number; // Cache control in seconds (default: 3600)\r\n index? : string[]; // Index files (default: ['index.html'])\r\n dotfiles? : 'allow' | 'deny' | 'ignore'; // How to handle dotfiles (default: 'deny')\r\n etag? : boolean; // Enable ETag headers (default: true)\r\n lastModified? : boolean; // Enable Last-Modified headers (default: true)\r\n immutable? : boolean; // Add immutable to cache-control (default: false)\r\n extensions? : string[]; // Try these extensions if file not found (e.g., ['html', 'htm'])\r\n fallthrough? : boolean; // Continue to next handler if file not found (default: false)\r\n setHeaders? : (ctx: AppContext, path: string) => void; // Custom header setter\r\n }\r\n\r\n interface CacheEntry {\r\n etag : string;\r\n lastModified : Date;\r\n size : number;\r\n mtime : number;\r\n }\r\n\r\n interface FileStats {\r\n size: number;\r\n mtime: Date;\r\n mtimeMs: number;\r\n isDirectory(): boolean;\r\n isFile(): boolean;\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class StaticFileServer {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n private config : Required<Omit<StaticConfig, 'setHeaders'>> & Pick<StaticConfig, 'setHeaders'>;\r\n private resolvedDir : string;\r\n private fileCache = new Map<string, CacheEntry>();\r\n private readonly CACHE_MAX_SIZE = 1000;\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── CONS ──────────────────────────────┐\r\n\r\n constructor(config: StaticConfig) {\r\n // Validate directory exists\r\n if (!existsSync(config.directory)) {\r\n throw new Error(`Static directory does not exist: ${config.directory}`);\r\n }\r\n\r\n const stats = statSync(config.directory);\r\n if (!stats.isDirectory()) {\r\n throw new Error(`Static path is not a directory: ${config.directory}`);\r\n }\r\n\r\n // Resolve absolute path to prevent directory traversal\r\n this.resolvedDir = resolve(config.directory);\r\n\r\n // Set defaults\r\n this.config = {\r\n path : config.path,\r\n directory : config.directory,\r\n maxAge : config.maxAge ?? 3600,\r\n index : config.index ?? ['index.html'],\r\n dotfiles : config.dotfiles ?? 'deny',\r\n etag : config.etag ?? true,\r\n lastModified : config.lastModified ?? true,\r\n immutable : config.immutable ?? false,\r\n extensions : config.extensions ?? [],\r\n fallthrough : config.fallthrough ?? false,\r\n setHeaders : config.setHeaders\r\n };\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n /**\r\n * Create request handler for static files\r\n */\r\n handler(): (ctx: AppContext) => Promise<Response> {\r\n return async (ctx: AppContext): Promise<Response> => {\r\n const requestPath = ctx.request.url;\r\n const url = new URL(requestPath);\r\n let pathname = url.pathname;\r\n\r\n // Remove prefix from pathname\r\n if (pathname.startsWith(this.config.path)) {\r\n pathname = pathname.slice(this.config.path.length);\r\n }\r\n\r\n // Decode URI component\r\n try {\r\n pathname = decodeURIComponent(pathname);\r\n } catch {\r\n return ctx.json({ error: 'Invalid URL encoding' }, 400);\r\n }\r\n\r\n // Security: Prevent directory traversal\r\n if (pathname.includes('..') || pathname.includes('\\\\')) {\r\n return ctx.json({ error: 'Forbidden' }, 403);\r\n }\r\n\r\n // Handle dotfiles\r\n if (this.config.dotfiles !== 'allow' && pathname.split('/').some(p => p.startsWith('.'))) {\r\n if (this.config.dotfiles === 'deny') {\r\n return ctx.json({ error: 'Forbidden' }, 403);\r\n }\r\n // 'ignore' - treat as not found\r\n return this.handleNotFound(ctx);\r\n }\r\n\r\n // Resolve file path\r\n const filePath = this.resolveFilePath(pathname);\r\n if (!filePath) {\r\n return this.handleNotFound(ctx);\r\n }\r\n\r\n // Check if file exists and is within allowed directory\r\n if (!this.isPathSafe(filePath)) {\r\n return ctx.json({ error: 'Forbidden' }, 403);\r\n }\r\n\r\n if (!existsSync(filePath)) {\r\n return this.handleNotFound(ctx);\r\n }\r\n\r\n const stats = statSync(filePath) as FileStats;\r\n\r\n // If directory, try to serve index file\r\n if (stats.isDirectory()) {\r\n return this.serveDirectory(ctx, filePath, pathname);\r\n }\r\n\r\n // Serve file\r\n return this.serveFile(ctx, filePath, stats);\r\n };\r\n }\r\n\r\n /**\r\n * Get URL path pattern for router\r\n */\r\n getPathPattern(): string {\r\n // Match the prefix and anything after it\r\n return `${this.config.path}/*`;\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── HELP ──────────────────────────────┐\r\n\r\n private resolveFilePath(pathname: string): string | null {\r\n // Remove leading slash\r\n if (pathname.startsWith('/')) {\r\n pathname = pathname.slice(1);\r\n }\r\n\r\n const filePath = join(this.resolvedDir, pathname);\r\n\r\n // Try with extensions if file doesn't exist\r\n if (!existsSync(filePath) && this.config.extensions.length > 0) {\r\n for (const ext of this.config.extensions) {\r\n const withExt = `${filePath}.${ext}`;\r\n if (existsSync(withExt)) {\r\n return withExt;\r\n }\r\n }\r\n }\r\n\r\n return filePath;\r\n }\r\n\r\n private isPathSafe(filePath: string): boolean {\r\n // Ensure the resolved path is within the static directory\r\n const rel = relative(this.resolvedDir, resolve(filePath));\r\n return !rel.startsWith('..') && !resolve(filePath).startsWith('..');\r\n }\r\n\r\n private async serveDirectory(ctx: AppContext, dirPath: string, _: string): Promise<Response> {\r\n // Try index files\r\n for (const indexFile of this.config.index) {\r\n const indexPath = join(dirPath, indexFile);\r\n if (existsSync(indexPath)) {\r\n const stats = statSync(indexPath) as FileStats;\r\n if (stats.isFile()) {\r\n return this.serveFile(ctx, indexPath, stats);\r\n }\r\n }\r\n }\r\n\r\n // No index file found\r\n return this.handleNotFound(ctx);\r\n }\r\n\r\n private async serveFile(ctx: AppContext, filePath: string, stats: FileStats): Promise<Response> {\r\n const method = ctx.request.method.toUpperCase();\r\n\r\n // Only allow GET and HEAD\r\n if (method !== 'GET' && method !== 'HEAD') {\r\n return ctx.json({ error: 'Method not allowed' }, 405);\r\n }\r\n\r\n // Get or create cache entry\r\n const cacheKey = filePath;\r\n let cacheEntry = this.fileCache.get(cacheKey);\r\n\r\n // Check if cache is stale\r\n if (cacheEntry && cacheEntry.mtime !== stats.mtimeMs) {\r\n cacheEntry = undefined;\r\n }\r\n\r\n if (!cacheEntry) {\r\n cacheEntry = {\r\n etag : this.generateEtag(stats),\r\n lastModified : new Date(stats.mtime),\r\n size : stats.size,\r\n mtime : stats.mtimeMs\r\n };\r\n\r\n // Add to cache with size limit\r\n if (this.fileCache.size >= this.CACHE_MAX_SIZE) {\r\n const firstKey = this.fileCache.keys().next().value;\r\n if (firstKey) this.fileCache.delete(firstKey);\r\n }\r\n this.fileCache.set(cacheKey, cacheEntry);\r\n }\r\n\r\n // Check conditional requests\r\n const ifNoneMatch = ctx.request.headers.get('if-none-match');\r\n const ifModifiedSince = ctx.request.headers.get('if-modified-since');\r\n\r\n if (this.config.etag && ifNoneMatch === cacheEntry.etag) {\r\n return new Response(null, {\r\n status: 304,\r\n headers: this.buildHeaders(filePath, cacheEntry)\r\n });\r\n }\r\n\r\n if (this.config.lastModified && ifModifiedSince) {\r\n const ifModDate = new Date(ifModifiedSince);\r\n if (cacheEntry.lastModified <= ifModDate) {\r\n return new Response(null, {\r\n status: 304,\r\n headers: this.buildHeaders(filePath, cacheEntry)\r\n });\r\n }\r\n }\r\n\r\n // Read file using Bun.file\r\n const file = Bun.file(filePath);\r\n const headers = this.buildHeaders(filePath, cacheEntry);\r\n\r\n // Set custom headers if provided\r\n if (this.config.setHeaders) {\r\n this.config.setHeaders(ctx, filePath);\r\n }\r\n\r\n // Return 200 with file content (or just headers for HEAD)\r\n if (method === 'HEAD') {\r\n return new Response(null, {\r\n status: 200,\r\n headers\r\n });\r\n }\r\n\r\n return new Response(file, {\r\n status: 200,\r\n headers\r\n });\r\n }\r\n\r\n private buildHeaders(filePath: string, cache: CacheEntry): Headers {\r\n const headers = new Headers();\r\n\r\n // Content-Type\r\n const mimeType = this.getMimeType(filePath);\r\n headers.set('Content-Type', mimeType);\r\n\r\n // Content-Length\r\n headers.set('Content-Length', cache.size.toString());\r\n\r\n // ETag\r\n if (this.config.etag) {\r\n headers.set('ETag', cache.etag);\r\n }\r\n\r\n // Last-Modified\r\n if (this.config.lastModified) {\r\n headers.set('Last-Modified', cache.lastModified.toUTCString());\r\n }\r\n\r\n // Cache-Control\r\n if (this.config.maxAge > 0) {\r\n let cacheControl = `public, max-age=${this.config.maxAge}`;\r\n if (this.config.immutable) {\r\n cacheControl += ', immutable';\r\n }\r\n headers.set('Cache-Control', cacheControl);\r\n } else {\r\n headers.set('Cache-Control', 'no-cache');\r\n }\r\n\r\n // Accept-Ranges for partial content support\r\n headers.set('Accept-Ranges', 'bytes');\r\n\r\n return headers;\r\n }\r\n\r\n private generateEtag(stats: FileStats): string {\r\n // Simple ETag: size-mtime\r\n return `\"${stats.size.toString(16)}-${stats.mtimeMs.toString(16)}\"`;\r\n }\r\n\r\n private getMimeType(filePath: string): string {\r\n const ext = extname(filePath).toLowerCase();\r\n return MIME_TYPES[ext] || 'application/octet-stream';\r\n }\r\n\r\n private handleNotFound(ctx: AppContext): Response {\r\n if (this.config.fallthrough) {\r\n // Let the next handler deal with it\r\n return ctx.json({ error: 'Not Found' }, 404);\r\n }\r\n return ctx.json({ error: 'Not Found' }, 404);\r\n }\r\n\r\n /**\r\n * Clear file cache\r\n */\r\n clearCache(): void {\r\n this.fileCache.clear();\r\n }\r\n\r\n /**\r\n * Get cache statistics\r\n */\r\n getCacheStats(): { entries: number; maxSize: number } {\r\n return {\r\n entries: this.fileCache.size,\r\n maxSize: this.CACHE_MAX_SIZE\r\n };\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ UTIL ════════════════════════════════════════╗\r\n\r\n /**\r\n * Helper function to create static file server\r\n */\r\n export function createStatic(config: StaticConfig): StaticFileServer {\r\n return new StaticFileServer(config);\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ DATA ════════════════════════════════════════╗\r\n\r\n /**\r\n * Comprehensive MIME type mapping\r\n */\r\n const MIME_TYPES: Record<string, string> = {\r\n // Text\r\n '.html' : 'text/html; charset=utf-8',\r\n '.htm' : 'text/html; charset=utf-8',\r\n '.css' : 'text/css; charset=utf-8',\r\n '.txt' : 'text/plain; charset=utf-8',\r\n '.xml' : 'text/xml; charset=utf-8',\r\n '.csv' : 'text/csv; charset=utf-8',\r\n '.md' : 'text/markdown; charset=utf-8',\r\n\r\n // JavaScript\r\n '.js' : 'application/javascript; charset=utf-8',\r\n '.mjs' : 'application/javascript; charset=utf-8',\r\n '.json' : 'application/json; charset=utf-8',\r\n '.jsonld' : 'application/ld+json',\r\n '.map' : 'application/json; charset=utf-8',\r\n\r\n // Images\r\n '.png' : 'image/png',\r\n '.jpg' : 'image/jpeg',\r\n '.jpeg' : 'image/jpeg',\r\n '.gif' : 'image/gif',\r\n '.svg' : 'image/svg+xml',\r\n '.ico' : 'image/x-icon',\r\n '.webp' : 'image/webp',\r\n '.avif' : 'image/avif',\r\n '.bmp' : 'image/bmp',\r\n '.tiff' : 'image/tiff',\r\n\r\n // Fonts\r\n '.woff' : 'font/woff',\r\n '.woff2' : 'font/woff2',\r\n '.ttf' : 'font/ttf',\r\n '.otf' : 'font/otf',\r\n '.eot' : 'application/vnd.ms-fontobject',\r\n\r\n // Audio\r\n '.mp3' : 'audio/mpeg',\r\n '.wav' : 'audio/wav',\r\n '.ogg' : 'audio/ogg',\r\n '.m4a' : 'audio/mp4',\r\n '.aac' : 'audio/aac',\r\n '.flac' : 'audio/flac',\r\n\r\n // Video\r\n '.mp4' : 'video/mp4',\r\n '.webm' : 'video/webm',\r\n '.ogv' : 'video/ogg',\r\n '.mov' : 'video/quicktime',\r\n '.avi' : 'video/x-msvideo',\r\n '.mkv' : 'video/x-matroska',\r\n\r\n // Documents\r\n '.pdf' : 'application/pdf',\r\n '.doc' : 'application/msword',\r\n '.docx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\r\n '.xls' : 'application/vnd.ms-excel',\r\n '.xlsx' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n '.ppt' : 'application/vnd.ms-powerpoint',\r\n '.pptx' : 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\r\n\r\n // Archives\r\n '.zip' : 'application/zip',\r\n '.rar' : 'application/x-rar-compressed',\r\n '.7z' : 'application/x-7z-compressed',\r\n '.tar' : 'application/x-tar',\r\n '.gz' : 'application/gzip',\r\n\r\n // Other\r\n '.wasm' : 'application/wasm',\r\n '.manifest' : 'text/cache-manifest',\r\n '.webmanifest' : 'application/manifest+json',\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/mod/i18n.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { I18nConfig, TranslationSet } from '../types.d';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n class I18nManager {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n private translations : TranslationSet = {};\r\n private currentLanguage : string = 'en';\r\n private defaultLanguage : string = 'en';\r\n private supportedLanguages = new Set<string>(['en']);\r\n private cachePath : string = '';\r\n\r\n constructor(config?: I18nConfig) {\r\n if (config) {\r\n this.defaultLanguage = config.defaultLanguage || 'en';\r\n this.currentLanguage = config.defaultLanguage || 'en';\r\n this.cachePath = config.staticPath || 'static/i18n';\r\n if (config.supportedLanguages) {\r\n this.supportedLanguages = new Set(config.supportedLanguages);\r\n }\r\n }\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n /**\r\n * Load translations for a specific language\r\n * @param lang Language code (e.g., 'en', 'ar', 'fr')\r\n * @param translations Translation object\r\n */\r\n public loadLanguage(lang: string, translations: Record<string, string>): void {\r\n if (!this.translations[lang]) {\r\n this.translations[lang] = {};\r\n }\r\n this.translations[lang] = { ...this.translations[lang], ...translations };\r\n this.supportedLanguages.add(lang);\r\n }\r\n\r\n /**\r\n * Load all translations from static files\r\n * @param translations Object with language codes as keys and translation objects as values\r\n */\r\n public loadTranslations(translations: Record<string, Record<string, string>>): void {\r\n Object.entries(translations).forEach(([lang, trans]) => {\r\n this.loadLanguage(lang, trans);\r\n });\r\n }\r\n\r\n /**\r\n * Set the current language\r\n * @param lang Language code\r\n */\r\n public setLanguage(lang: string): void {\r\n if (this.supportedLanguages.has(lang)) {\r\n this.currentLanguage = lang;\r\n } else if (this.supportedLanguages.has(this.defaultLanguage)) {\r\n this.currentLanguage = this.defaultLanguage;\r\n }\r\n }\r\n\r\n /**\r\n * Get the current language\r\n */\r\n public getLanguage(): string {\r\n return this.currentLanguage;\r\n }\r\n\r\n /**\r\n * Get all supported languages\r\n */\r\n public getSupportedLanguages(): string[] {\r\n return Array.from(this.supportedLanguages);\r\n }\r\n\r\n /**\r\n * Translate a key with smart parameter replacement\r\n * Supports nested translation keys as parameter values\r\n *\r\n * @example\r\n * // Simple translation\r\n * t('app.name') // => \"JE-ES Server\"\r\n *\r\n * @example\r\n * // With parameters\r\n * t('validation.invalid', { field: 'email' })\r\n * // => \"Invalid value for email\"\r\n *\r\n * @example\r\n * // With nested translation keys as parameters\r\n * t('message.validation', { error: 'validation.required' })\r\n * // => \"Message: This field is required\"\r\n *\r\n * @param key Translation key (dot-notation)\r\n * @param params Optional parameters for replacement\r\n * @param defaultValue Optional default value\r\n * @returns Translated string with replaced parameters\r\n */\r\n public t(key: string, params?: Record<string, string>, defaultValue?: string): string {\r\n const lang = this.currentLanguage;\r\n\r\n let translation = this.getTranslation(key, defaultValue);\r\n\r\n // Replace parameters if provided\r\n if (params) {\r\n Object.entries(params).forEach(([param, value]) => {\r\n // Check if the parameter value is a translation key\r\n const paramValue = this.translations[lang]?.[value] ||\r\n this.translations[this.defaultLanguage]?.[value] ||\r\n value;\r\n\r\n translation = translation.replace(\r\n new RegExp(`\\\\{${param}\\\\}`, 'g'),\r\n paramValue\r\n );\r\n });\r\n }\r\n\r\n return translation;\r\n }\r\n\r\n private getTranslation(key: string, defaultValue?: string): string {\r\n const lang = this.currentLanguage;\r\n\r\n // warn if not found\r\n if (!this.translations[lang]?.[key]) {\r\n console.warn(`Translation key not found: ${key}`);\r\n\r\n return defaultValue || key;\r\n }\r\n\r\n return this.translations[lang]?.[key] || this.translations[this.defaultLanguage]?.[key];\r\n }\r\n\r\n /**\r\n * Translate with a specific language (overrides current language temporarily)\r\n *\r\n * @param key Translation key\r\n * @param lang Language code\r\n * @param params Optional parameters\r\n * @returns Translated string\r\n */\r\n public tLang(key: string, lang: string, params?: Record<string, string>): string {\r\n const currentLang = this.currentLanguage;\r\n this.setLanguage(lang);\r\n const result = this.t(key, params);\r\n this.currentLanguage = currentLang;\r\n return result;\r\n }\r\n\r\n /**\r\n * Get all translations for current language\r\n */\r\n public getTranslations(): Record<string, string> {\r\n return this.translations[this.currentLanguage] || {};\r\n }\r\n\r\n /**\r\n * Check if a translation key exists\r\n * @param key Translation key\r\n * @returns true if key exists in current or default language\r\n */\r\n public hasKey(key: string): boolean {\r\n return !!(\r\n this.translations[this.currentLanguage]?.[key] ||\r\n this.translations[this.defaultLanguage]?.[key]\r\n );\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ GLOB ════════════════════════════════════════╗\r\n\r\n // Singleton instance\r\n let i18nInstance: I18nManager | null = null;\r\n\r\n /**\r\n * Initialize the i18n manager\r\n * @param config I18n configuration\r\n * @returns I18nManager instance\r\n */\r\n export function initI18n(config?: I18nConfig): I18nManager {\r\n if (!i18nInstance) {\r\n i18nInstance = new I18nManager(config);\r\n }\r\n return i18nInstance;\r\n }\r\n\r\n /**\r\n * Get the global i18n instance\r\n */\r\n export function getI18n(): I18nManager {\r\n if (!i18nInstance) {\r\n i18nInstance = new I18nManager();\r\n }\r\n return i18nInstance;\r\n }\r\n\r\n /**\r\n * Global translation function\r\n * @param key Translation key\r\n * @param params Optional parameters\r\n * @param defaultValue Optional default value\r\n * @returns Translated string\r\n */\r\n export function t(key: string, params?: Record<string, string>, defaultValue?: string): string {\r\n return getI18n().t(key, params, defaultValue);\r\n }\r\n\r\n /**\r\n * Set the current language globally\r\n * @param lang Language code\r\n */\r\n export function setLanguage(lang: string): void {\r\n getI18n().setLanguage(lang);\r\n }\r\n\r\n /**\r\n * Get the current language\r\n */\r\n export function getCurrentLanguage(): string {\r\n return getI18n().getLanguage();\r\n }\r\n\r\n /**\r\n * Get all supported languages\r\n */\r\n export function getSupportedLanguages(): string[] {\r\n return getI18n().getSupportedLanguages();\r\n }\r\n\r\n export { I18nManager };\r\n export type { I18nConfig, TranslationSet };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/main.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import * as sdb from '@je-es/sdb';\r\n import { Router } from './mod/router';\r\n import { SecurityManager } from './mod/security';\r\n import { Logger } \tfrom '@je-es/slog';\r\n import * as types from './types.d';\r\n import { StaticFileServer } from './mod/static';\r\n import { initI18n, I18nManager } from './mod/i18n';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n const security = new SecurityManager();\r\n const router = new Router();\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export function server(config: types.ServerConfig = {}): types.ServerInstance {\r\n\r\n\t\t// ════════ Configuration ════════\r\n\t\tconst port = Number(config.port) || 3000;\r\n\t\tconst hostname = config.hostname || 'localhost';\r\n\t\tconst maxReqSize = config.maxRequestSize || 10 * 1024 * 1024;\r\n\t\tconst requestTimeout = config.requestTimeout || 30000;\r\n\t\tconst gracefulShutdownTimeout = config.gracefulShutdownTimeout || 10000;\r\n\r\n\t\tconst logCfg = typeof config.logging === 'object' ? config.logging : {};\r\n\t\tconst logger = config.logging ? new Logger(logCfg.level || 'info', logCfg.pretty) : null;\r\n\r\n\t\t// ════════ i18n Configuration ════════\r\n\t\tlet i18n: I18nManager | null = null;\r\n\t\tif (config.i18n) {\r\n\t\t\tconst i18nCfg = typeof config.i18n === 'object' ? config.i18n : {};\r\n\t\t\ti18n = initI18n({\r\n\t\t\t\tdefaultLanguage: i18nCfg.defaultLanguage || 'en',\r\n\t\t\t\tsupportedLanguages: i18nCfg.supportedLanguages || ['en', 'ar', 'fr'],\r\n\t\t\t\tstaticPath: i18nCfg.staticPath || 'static/i18n'\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tconst dbs = new Map<string, sdb.DB>();\r\n\t\tconst routes: types.RouteDefinition[] = [];\r\n\t\tconst activeRequests = new Set<string>();\r\n\r\n\t\t// ════════ Cleanup intervals ════════\r\n const cleanupInterval = setInterval(() => {\r\n security.cleanupRateLimit();\r\n security.cleanupCsrfTokens();\r\n }, 2 * 60 * 1000);\r\n\r\n async function handleRequest(request: Request, server: unknown): Promise<Response> {\r\n const startTime = Date.now();\r\n const requestId = crypto.randomUUID();\r\n const url = new URL(request.url);\r\n const path = url.pathname;\r\n const method = request.method.toUpperCase();\r\n const ip = getClientIp(request, server);\r\n\r\n activeRequests.add(requestId);\r\n\r\n try {\r\n // Check request size from header\r\n const contentLength = request.headers.get('content-length');\r\n if (contentLength && parseInt(contentLength) > maxReqSize) {\r\n logger?.warn({ requestId, size: contentLength, ip }, 'Request too large');\r\n return new Response(JSON.stringify({ error: 'Payload too large' }), {\r\n\t\t\t\t\t\tstatus\t: 413,\r\n\t\t\t\t\t\theaders\t: { 'Content-Type': 'application/json' }\r\n });\r\n }\r\n\r\n // CORS handling\r\n const corsHeaders = handleCors(request, config);\r\n if (method === 'OPTIONS') {\r\n return new Response(null, { status: 204, headers: corsHeaders });\r\n }\r\n\r\n // Rate limiting\r\n if (config.security && typeof config.security === 'object' && config.security.rateLimit) {\r\n const rateLimitCfg = typeof config.security.rateLimit === 'object'\r\n ? config.security.rateLimit\r\n : {};\r\n const max = rateLimitCfg.max || 100;\r\n const windowMs = rateLimitCfg.windowMs || 60000;\r\n const rateLimitKey = rateLimitCfg.keyGenerator\r\n ? rateLimitCfg.keyGenerator({ request, ip } as types.AppContext)\r\n : ip;\r\n\r\n if (!security.checkRateLimit(rateLimitKey, max, windowMs)) {\r\n logger?.warn({ requestId, ip, key: rateLimitKey }, 'Rate limit exceeded');\r\n return new Response(\r\n JSON.stringify({ error: rateLimitCfg.message || 'Too many requests' }),\r\n { status: 429, headers: { 'Content-Type': 'application/json' } }\r\n );\r\n }\r\n }\r\n\r\n // Parse body\r\n let body: unknown = null;\r\n if (['POST', 'PUT', 'PATCH'].includes(method)) {\r\n body = await parseBody(request, logger, maxReqSize);\r\n }\r\n\r\n // Get database\r\n const defaultDb = dbs.get('default');\r\n\r\n // Detect language from request (query param, header, or cookie)\r\n const query = Object.fromEntries(new URL(request.url).searchParams);\r\n let requestLang = (query.lang as string) || request.headers.get('Accept-Language')?.split(',')[0]?.split('-')[0] || 'en';\r\n if (i18n && !i18n.getSupportedLanguages().includes(requestLang)) {\r\n requestLang = i18n.getLanguage();\r\n }\r\n if (i18n) {\r\n i18n.setLanguage(requestLang);\r\n }\r\n\r\n // Match route\r\n const routeMatch = router.match(method, path);\r\n if (!routeMatch) {\r\n const ctx = createAppContext(ip, request, {}, defaultDb, logger, requestId, i18n, requestLang);\r\n logger?.warn({ requestId, method, path, ip }, 'Route not found');\r\n return ctx.json({ error: 'Not Found', path }, 404);\r\n }\r\n\r\n const ctx = createAppContext(ip, request, routeMatch.params || {}, defaultDb, logger, requestId, i18n, requestLang);\r\n ctx.body = body;\r\n ctx.request = request;\r\n\r\n // Execute route handler with timeout\r\n const controller = new AbortController();\r\n const timeoutPromise = new Promise<never>((_, reject) => {\r\n const id = setTimeout(() => {\r\n controller.abort();\r\n reject(new types.TimeoutError('Request timeout'));\r\n }, requestTimeout);\r\n controller.signal.addEventListener('abort', () => clearTimeout(id));\r\n });\r\n\r\n // Get middlewares from route metadata\r\n const routeDefinition = routeMatch.metadata as types.RouteDefinition | undefined;\r\n const middlewares = routeDefinition?.middlewares || [];\r\n\r\n let handlerPromise: Promise<Response>;\r\n if (middlewares.length > 0) {\r\n handlerPromise = executeMiddlewares(ctx, middlewares, routeMatch.handler);\r\n } else {\r\n handlerPromise = Promise.resolve(routeMatch.handler(ctx));\r\n }\r\n\r\n const response = await Promise.race([\r\n handlerPromise,\r\n timeoutPromise\r\n ]) as Response;\r\n\r\n // Merge CORS and security headers\r\n const resHeaders = new Headers(response.headers);\r\n corsHeaders.forEach((value, key) => {\r\n if (!resHeaders.has(key)) resHeaders.set(key, value);\r\n });\r\n\r\n resHeaders.set('X-Request-ID', requestId);\r\n resHeaders.set('X-Content-Type-Options', 'nosniff');\r\n resHeaders.set('X-Frame-Options', 'DENY');\r\n resHeaders.set('X-XSS-Protection', '1; mode=block');\r\n resHeaders.set('Referrer-Policy', 'strict-origin-when-cross-origin');\r\n\r\n // Audit log\r\n const duration = Date.now() - startTime;\r\n security.logRequest(requestId, method, path, ip, response.status, duration);\r\n logger?.info({\r\n requestId,\r\n method,\r\n path,\r\n status: response.status,\r\n duration,\r\n ip\r\n }, 'Request completed');\r\n\r\n return new Response(response.body, {\r\n status: response.status,\r\n headers: resHeaders\r\n });\r\n } catch (error) {\r\n if (error instanceof types.AppError) {\r\n logger?.warn({ error: error.message, requestId, ip }, `App error: ${error.message}`);\r\n return new Response(\r\n JSON.stringify({\r\n error\t: error.message,\r\n code\t: error.code,\r\n requestId\r\n }),\r\n { status: error.statusCode, headers: { 'Content-Type': 'application/json' } }\r\n );\r\n }\r\n\r\n logger?.error({ error: String(error), requestId, ip }, 'Unhandled error');\r\n\r\n const errorMessage = process.env.NODE_ENV === 'production'\r\n ? 'Internal Server Error'\r\n : (error as Error).message;\r\n\r\n return new Response(\r\n JSON.stringify({ error: errorMessage, requestId }),\r\n { status: 500, headers: { 'Content-Type': 'application/json' } }\r\n );\r\n } finally {\r\n activeRequests.delete(requestId);\r\n }\r\n }\r\n\r\n async function executeMiddlewares(\r\n ctx: types.AppContext,\r\n middlewares: types.AppMiddleware[],\r\n handler: types.RouteHandler\r\n ): Promise<Response> {\r\n let index = 0;\r\n let earlyResponse: Response | null = null;\r\n\r\n // Override ctx methods to capture early responses\r\n const originalJson = ctx.json.bind(ctx);\r\n const originalText = ctx.text.bind(ctx);\r\n const originalHtml = ctx.html.bind(ctx);\r\n const originalRedirect = ctx.redirect.bind(ctx);\r\n\r\n ctx.json = function(data: unknown, status?: number): Response {\r\n const response = originalJson(data, status);\r\n earlyResponse = response;\r\n return response;\r\n };\r\n\r\n ctx.text = function(data: string, status?: number): Response {\r\n const response = originalText(data, status);\r\n earlyResponse = response;\r\n return response;\r\n };\r\n\r\n ctx.html = function(data: string, status?: number): Response {\r\n const response = originalHtml(data, status);\r\n earlyResponse = response;\r\n return response;\r\n };\r\n\r\n ctx.redirect = function(url: string, status?: number): Response {\r\n const response = originalRedirect(url, status);\r\n earlyResponse = response;\r\n return response;\r\n };\r\n\r\n async function next(): Promise<void> {\r\n // If middleware sent a response, stop\r\n if (earlyResponse) {\r\n return;\r\n }\r\n\r\n if (index < middlewares.length) {\r\n const middleware = middlewares[index];\r\n index++;\r\n await middleware(ctx, next);\r\n }\r\n }\r\n\r\n // Execute all middlewares\r\n await next();\r\n\r\n // Restore original methods\r\n ctx.json = originalJson;\r\n ctx.text = originalText;\r\n ctx.html = originalHtml;\r\n ctx.redirect = originalRedirect;\r\n\r\n // If middleware sent a response early, return it\r\n if (earlyResponse) {\r\n return earlyResponse;\r\n }\r\n\r\n // Otherwise, call the handler\r\n return handler(ctx);\r\n }\r\n\r\n // ════════ Health & Readiness routes ════════\r\n const healthRoute: types.RouteDefinition = {\r\n method : 'GET',\r\n path : '/health',\r\n handler : (c: types.AppContext) => c.json({\r\n status : 'healthy',\r\n timestamp : new Date().toISOString(),\r\n uptime : process.uptime(),\r\n activeRequests : activeRequests.size\r\n })\r\n };\r\n\r\n const readinessRoute: types.RouteDefinition = {\r\n method : 'GET',\r\n path : '/readiness',\r\n handler : (c: types.AppContext) => {\r\n const dbConnected = dbs.size > 0;\r\n const ready = dbConnected || dbs.size === 0;\r\n return c.json({\r\n ready,\r\n checks : {\r\n database : dbConnected ? 'connected' : 'not configured',\r\n activeRequests : activeRequests.size\r\n },\r\n timestamp: new Date().toISOString()\r\n }, ready ? 200 : 503);\r\n }\r\n };\r\n\r\n // ════════ Register routes ════════\r\n if (config.routes) {\r\n config.routes.forEach(route => {\r\n routes.push(route);\r\n const methods = Array.isArray(route.method) ? route.method : [route.method];\r\n methods.forEach(m => {\r\n router.register(m, route.path, route.handler as types.RouteHandler, route);\r\n });\r\n });\r\n }\r\n\r\n // ════════ Static file serving ════════\r\n if (config.static) {\r\n const staticConfigs = Array.isArray(config.static) ? config.static : [config.static];\r\n\r\n for (const staticCfg of staticConfigs) {\r\n try {\r\n const staticServer = new StaticFileServer(staticCfg);\r\n const handler = staticServer.handler();\r\n\r\n const staticRoute: types.RouteDefinition = {\r\n method: 'GET',\r\n path: staticCfg.path === '/' ? '/*' : `${staticCfg.path}/*`,\r\n handler: handler as types.RouteHandler\r\n };\r\n\r\n routes.push(staticRoute);\r\n\r\n if (staticCfg.path === '/') {\r\n router.register('GET', '/', handler as types.RouteHandler, staticRoute);\r\n router.register('HEAD', '/', handler as types.RouteHandler, staticRoute);\r\n router.register('GET', '/*', handler as types.RouteHandler, staticRoute);\r\n router.register('HEAD', '/*', handler as types.RouteHandler, staticRoute);\r\n } else {\r\n router.register('GET', `${staticCfg.path}/*`, handler as types.RouteHandler, staticRoute);\r\n router.register('HEAD', `${staticCfg.path}/*`, handler as types.RouteHandler, staticRoute);\r\n }\r\n } catch (error) {\r\n logger?.error({\r\n error: String(error),\r\n path: staticCfg.path\r\n }, 'Failed to initialize static file server');\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n routes.push(healthRoute, readinessRoute);\r\n router.register('GET', '/health', healthRoute.handler as types.RouteHandler, healthRoute);\r\n router.register('GET', '/readiness', readinessRoute.handler as types.RouteHandler, readinessRoute);\r\n\r\n let bunServer: unknown = null;\r\n\r\n const instance: types.ServerInstance = {\r\n app : null,\r\n logger,\r\n db : dbs,\r\n bunServer : null,\r\n\r\n async start() {\r\n // Load i18n translations from static files\r\n if (i18n && config.i18n) {\r\n const i18nCfg = typeof config.i18n === 'object' ? config.i18n : {};\r\n const staticPath = i18nCfg.staticPath || 'static/i18n';\r\n const supportedLangs = i18nCfg.supportedLanguages || ['en', 'ar', 'fr'];\r\n\r\n try {\r\n for (const lang of supportedLangs) {\r\n const filePath = `${staticPath}/${lang}.json`;\r\n const file = Bun.file(filePath);\r\n\r\n if (await file.exists()) {\r\n const data = await file.json() as Record<string, string>;\r\n i18n.loadLanguage(lang, data);\r\n }\r\n }\r\n\r\n logger?.info({ languages: i18n.getSupportedLanguages() }, 'i18n translations loaded');\r\n } catch (error) {\r\n logger?.warn({ error: String(error) }, 'Failed to load i18n translations');\r\n }\r\n }\r\n\r\n if (config.database) {\r\n const dbConfigs = Array.isArray(config.database) ? config.database : [config.database];\r\n for (const dbCfg of dbConfigs) {\r\n const dbName = dbCfg.name || 'default';\r\n\r\n try {\r\n if (typeof dbCfg.connection === 'string') {\r\n const db = new sdb.DB(dbCfg.connection);\r\n\r\n if (dbCfg.schema && typeof dbCfg.schema === 'object') {\r\n for (const [, tableSchema] of Object.entries(dbCfg.schema)) {\r\n if (tableSchema && typeof tableSchema === 'object') {\r\n db.defineSchema(tableSchema as sdb.TableSchema);\r\n }\r\n }\r\n }\r\n\r\n dbs.set(dbName, db);\r\n\r\n logger?.info({\r\n name: dbName,\r\n connection: dbCfg.connection\r\n }, '✔ Database connected');\r\n } else {\r\n throw new Error(`Database connection must be a string path (got ${typeof dbCfg.connection})`);\r\n }\r\n } catch (error) {\r\n logger?.error({\r\n error: String(error),\r\n name: dbName\r\n }, 'Failed to connect to database');\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n bunServer = Bun.serve({\r\n port,\r\n hostname,\r\n fetch: (request, server) => handleRequest(request, server)\r\n });\r\n instance.bunServer = bunServer;\r\n\r\n const url = `http://${hostname}:${port}`;\r\n logger?.info({ url }, '✔ Server started');\r\n },\r\n\r\n async stop() {\r\n logger?.info('Stopping server...');\r\n\r\n if (activeRequests.size > 0) {\r\n logger?.info({ count: activeRequests.size }, 'Waiting for active requests...');\r\n const deadline = Date.now() + gracefulShutdownTimeout;\r\n\r\n while (activeRequests.size > 0 && Date.now() < deadline) {\r\n await new Promise(resolve => setTimeout(resolve, 100));\r\n }\r\n\r\n if (activeRequests.size > 0) {\r\n logger?.warn({ count: activeRequests.size }, 'Force closing with active requests');\r\n }\r\n }\r\n\r\n clearInterval(cleanupInterval);\r\n\r\n if (config.onShutdown) {\r\n try {\r\n await config.onShutdown();\r\n } catch (e) {\r\n logger?.error({ error: String(e) }, 'Error in shutdown handler');\r\n }\r\n }\r\n\r\n for (const [name, db] of dbs.entries()) {\r\n try {\r\n if (db && typeof db.close === 'function') {\r\n db.close();\r\n }\r\n logger?.info({ name }, 'Database closed');\r\n } catch (e) {\r\n logger?.error({ error: String(e), name }, 'Error closing database');\r\n }\r\n }\r\n\r\n if (bunServer && typeof (bunServer as { stop?: () => void }).stop === 'function') {\r\n (bunServer as { stop: () => void }).stop();\r\n logger?.info('Bun server stopped');\r\n }\r\n\r\n logger?.info('Server stopped successfully');\r\n },\r\n\r\n addRoute(route: types.RouteDefinition) {\r\n routes.push(route);\r\n const methods = Array.isArray(route.method) ? route.method : [route.method];\r\n methods.forEach(m => {\r\n router.register(m, route.path, route.handler as types.RouteHandler, route);\r\n });\r\n logger?.info({ method: route.method, path: route.path }, 'Route added');\r\n },\r\n\r\n addRoutes(routes: types.RouteDefinition[]) {\r\n routes.forEach(route => this.addRoute(route));\r\n },\r\n\r\n getRoutes() {\r\n return routes;\r\n }\r\n };\r\n\r\n return instance;\r\n\t}\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ HELP ════════════════════════════════════════╗\r\n\r\n async function parseBody(\r\n request : Request,\r\n logger : Logger | null,\r\n maxSize : number\r\n ): Promise<unknown> {\r\n const contentType = request.headers.get('content-type') || '';\r\n\r\n try {\r\n if (contentType.includes('application/json')) {\r\n\t\t\t\tconst text = await request.text();\r\n\r\n\t\t\t\tif (text.length > maxSize) {\r\n\t\t\t\t\tthrow new types.ValidationError('Payload too large');\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!text.trim()) return {};\r\n\r\n\t\t\t\ttry {\r\n\t\t\t\t\treturn JSON.parse(text);\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tlogger?.warn({\r\n\t\t\t\t\t\terror\t\t: String(e),\r\n\t\t\t\t\t\tbodyPreview\t: text.substring(0, 100)\r\n\t\t\t\t\t}, 'Invalid JSON in request body');\r\n\r\n\t\t\t\t\tthrow new types.ValidationError('Invalid JSON in request body');\r\n\t\t\t\t}\r\n }\r\n\r\n if (contentType.includes('application/x-www-form-urlencoded')) {\r\n const text = await request.text();\r\n if (text.length > maxSize) {\r\n throw new types.ValidationError('Payload too large');\r\n }\r\n return Object.fromEntries(new URLSearchParams(text));\r\n }\r\n\r\n if (contentType.includes('multipart/form-data')) {\r\n return await request.formData();\r\n }\r\n } catch (e) {\r\n if (e instanceof types.ValidationError) throw e;\r\n logger?.error({ error: String(e) }, 'Error parsing request body');\r\n throw new types.ValidationError('Failed to parse request body');\r\n }\r\n\r\n return {};\r\n }\r\n\r\n function parseCookies(cookieHeader: string): Map<string, string> {\r\n const cookies = new Map<string, string>();\r\n\r\n if (!cookieHeader) return cookies;\r\n\r\n const pairs = cookieHeader.split(';');\r\n for (const pair of pairs) {\r\n const [key, ...valueParts] = pair.trim().split('=');\r\n if (key) {\r\n const value = valueParts.join('=');\r\n cookies.set(key, value ? decodeURIComponent(value) : '');\r\n }\r\n }\r\n\r\n return cookies;\r\n }\r\n\r\n function createAppContext(\r\n ip : string,\r\n request : Request,\r\n params : Record<string, string>,\r\n db : sdb.DB | undefined,\r\n logger : Logger | null,\r\n requestId : string,\r\n i18nMgr : I18nManager | null = null,\r\n lang : string = 'en'\r\n ): types.AppContext {\r\n const url = new URL(request.url);\r\n const query = Object.fromEntries(url.searchParams);\r\n const headers = request.headers;\r\n let statusCode = 200;\r\n const cookieStore = new Map<string, string>();\r\n const parsedCookies = parseCookies(headers.get('cookie') || '');\r\n\r\n const ctx: types.AppContext = {\r\n ip,\r\n request,\r\n params,\r\n query,\r\n headers,\r\n db,\r\n logger,\r\n i18n: i18nMgr,\r\n lang,\r\n requestId,\r\n get statusCode() { return statusCode; },\r\n set statusCode(code: number) { statusCode = code; },\r\n body: null,\r\n\r\n json(data: unknown, status?: number): Response {\r\n return new Response(JSON.stringify(data), {\r\n status : status ?? statusCode,\r\n headers : {\r\n 'Content-Type': 'application/json',\r\n ...this._setCookieHeaders()\r\n }\r\n });\r\n },\r\n\r\n text(data: string, status?: number): Response {\r\n return new Response(data, {\r\n status : status ?? statusCode,\r\n headers : {\r\n 'Content-Type': 'text/plain',\r\n ...this._setCookieHeaders()\r\n }\r\n });\r\n },\r\n\r\n html(data: string, status?: number): Response {\r\n return new Response(data, {\r\n status : status ?? statusCode,\r\n headers : {\r\n 'Content-Type': 'text/html; charset=utf-8',\r\n ...this._setCookieHeaders()\r\n }\r\n });\r\n },\r\n\r\n redirect(url: string, status = 302): Response {\r\n return new Response(null, {\r\n status,\r\n headers : {\r\n Location : url,\r\n ...this._setCookieHeaders()\r\n }\r\n });\r\n },\r\n\r\n file(path: string, contentType = 'application/octet-stream'): Response {\r\n const file = Bun.file(path);\r\n return new Response(file, {\r\n headers: {\r\n 'Content-Type': contentType,\r\n ...this._setCookieHeaders()\r\n }\r\n });\r\n },\r\n\r\n setCookie(name: string, value: string, options: types.CookieOptions = {}): types.AppContext {\r\n let cookie = `${name}=${encodeURIComponent(value)}`;\r\n\r\n if (options.maxAge !== undefined) {\r\n cookie += `; Max-Age=${options.maxAge}`;\r\n }\r\n if (options.expires) {\r\n cookie += `; Expires=${options.expires.toUTCString()}`;\r\n }\r\n if (options.path) {\r\n cookie += `; Path=${options.path}`;\r\n }\r\n if (options.domain) {\r\n cookie += `; Domain=${options.domain}`;\r\n }\r\n if (options.secure) {\r\n cookie += '; Secure';\r\n }\r\n if (options.httpOnly) {\r\n cookie += '; HttpOnly';\r\n }\r\n if (options.sameSite) {\r\n cookie += `; SameSite=${options.sameSite}`;\r\n }\r\n\r\n cookieStore.set(name, cookie);\r\n return ctx;\r\n },\r\n\r\n getCookie(name: string): string | undefined {\r\n return parsedCookies.get(name);\r\n },\r\n\r\n deleteCookie(name: string, options: Partial<types.CookieOptions> = {}): types.AppContext {\r\n return ctx.setCookie(name, '', {\r\n ...options,\r\n maxAge: 0,\r\n path: options.path || '/'\r\n });\r\n },\r\n\r\n setHeader(key: string, value: string): types.AppContext {\r\n headers.set(key, value);\r\n return ctx;\r\n },\r\n\r\n getHeader(key: string): string | undefined {\r\n return headers.get(key) || undefined;\r\n },\r\n\r\n status(code: number): types.AppContext {\r\n statusCode = code;\r\n return ctx;\r\n },\r\n\r\n _setCookieHeaders(): Record<string, string | string[]> {\r\n const h: Record<string, string | string[]> = {};\r\n if (cookieStore.size > 0) {\r\n h['Set-Cookie'] = Array.from(cookieStore.values());\r\n }\r\n return h;\r\n }\r\n };\r\n\r\n return ctx;\r\n }\r\n\r\n function getClientIp(request: Request, server?: unknown): string {\r\n const forwarded = request.headers.get('x-forwarded-for');\r\n if (forwarded) {\r\n const ips = forwarded.split(',').map(ip => ip.trim());\r\n return ips[0] || 'unknown';\r\n }\r\n\r\n const realIp = request.headers.get('x-real-ip');\r\n if (realIp) return realIp;\r\n\r\n if (server) {\r\n try {\r\n const serverWithRequestIP = server as { requestIP?: (req: Request) => { address?: string } | null };\r\n const remoteAddress = serverWithRequestIP.requestIP?.(request);\r\n if (remoteAddress?.address) {\r\n return remoteAddress.address;\r\n }\r\n } catch {\r\n // Fallback if requestIP fails\r\n }\r\n }\r\n\r\n return 'unknown';\r\n }\r\n\r\n function handleCors(request: Request, config: types.ServerConfig): Headers {\r\n const headers = new Headers();\r\n\r\n if (!config.security || typeof config.security !== 'object' || !config.security.cors) {\r\n return headers;\r\n }\r\n\r\n const corsConfig = typeof config.security.cors === 'object' ? config.security.cors : {};\r\n const origin = request.headers.get('Origin');\r\n\r\n if (origin) {\r\n if (typeof corsConfig.origin === 'function') {\r\n if (corsConfig.origin(origin)) {\r\n headers.set('Access-Control-Allow-Origin', origin);\r\n }\r\n } else if (Array.isArray(corsConfig.origin)) {\r\n if (corsConfig.origin.includes(origin)) {\r\n headers.set('Access-Control-Allow-Origin', origin);\r\n }\r\n } else if (typeof corsConfig.origin === 'string') {\r\n headers.set('Access-Control-Allow-Origin', corsConfig.origin);\r\n } else {\r\n headers.set('Access-Control-Allow-Origin', origin);\r\n }\r\n\r\n const methods = corsConfig.methods || ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'];\r\n headers.set('Access-Control-Allow-Methods', methods.join(', '));\r\n\r\n const allowedHeaders = corsConfig.allowedHeaders || ['Content-Type', 'Authorization', 'X-Requested-With'];\r\n headers.set('Access-Control-Allow-Headers', allowedHeaders.join(', '));\r\n\r\n if (corsConfig.credentials) {\r\n headers.set('Access-Control-Allow-Credentials', 'true');\r\n }\r\n\r\n if (corsConfig.maxAge) {\r\n headers.set('Access-Control-Max-Age', corsConfig.maxAge.toString());\r\n }\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ ════ ════════════════════════════════════════╗\r\n\r\n export * from './types.d';\r\n export { Logger };\r\n export { SecurityManager };\r\n export { Router };\r\n export {\r\n DB,\r\n table,\r\n column,\r\n integer,\r\n text,\r\n real,\r\n blob,\r\n numeric,\r\n primaryKey,\r\n notNull,\r\n unique,\r\n defaultValue,\r\n references\r\n } from '@je-es/sdb';\r\n export type {\r\n ColumnType,\r\n SqlValue,\r\n ColumnDefinition,\r\n TableSchema,\r\n WhereCondition,\r\n QueryBuilder\r\n } from '@je-es/sdb';\r\n export { StaticFileServer, createStatic } from './mod/static';\r\n export type { StaticConfig } from './mod/static';\r\n export {\r\n initI18n,\r\n getI18n,\r\n t,\r\n setLanguage,\r\n getCurrentLanguage,\r\n getSupportedLanguages,\r\n I18nManager\r\n } from './mod/i18n';\r\n export type { I18nConfig, TranslationSet } from './mod/i18n';\r\n export default server;\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝"]}