@je-es/server 0.1.2 → 0.1.3

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.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mod/db.ts","../src/mod/router.ts","../src/mod/security.ts","../src/mod/logger.ts","../src/types.d.ts","../src/mod/static.ts","../src/main.ts"],"names":["DB","path","Database","schema","sql","index","indexSql","tableName","table","conditions","whereConditions","column","value","id","data","lastId","callback","error","params","builder","self","columns","condition","whereClauses","cond","placeholders","val","direction","count","setClauses","col","updateValues","result","results","columnDefs","def","name","type","integer","text","real","blob","numeric","primaryKey","autoIncrement","notNull","unique","defaultValue","references","Router","method","key","route","match","staticRoutes","handler","colonIndex","dynamicRoutes","r","config","pattern","existingIndex","SecurityManager","max","windowMs","now","record","sessionId","ttl","token","crypto","stored","html","input","ip","status","duration","first","Logger","level","pretty","msg","levelNum","safeData","safeMsg","output","str","c","time","methods","icon","color","keys","k","parts","m","s","AppError","message","statusCode","code","ValidationError","issues","DatabaseError","TimeoutError","RateLimitError","StaticFileServer","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","dbs","routes","activeRequests","cleanupInterval","handleRequest","request","startTime","requestId","getClientIp","contentLength","corsHeaders","handleCors","rateLimitCfg","rateLimitKey","body","parseBody","defaultDb","routeMatch","createAppContext","controller","timeoutPromise","_","reject","response","resHeaders","errorMessage","healthRoute","readinessRoute","dbConnected","ready","staticConfigs","staticCfg","staticRoute","bunServer","instance","dbConfigs","dbCfg","dbName","db","tableSchema","url","deadline","e","maxSize","contentType","parseCookies","cookieHeader","cookies","pairs","pair","valueParts","query","cookieStore","parsedCookies","options","cookie","h","forwarded","realIp","remoteAddress","corsConfig","origin","allowedHeaders","main_default"],"mappings":"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","file":"main.cjs","sourcesContent":["// src/mod/db.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { Database } from 'bun:sqlite'\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n export type ColumnType = 'INTEGER' | 'TEXT' | 'REAL' | 'BLOB' | 'NUMERIC'\r\n export type SqlValue = string | number | boolean | null | Uint8Array\r\n\r\n export interface ColumnDefinition {\r\n name : string\r\n type : ColumnType\r\n primaryKey? : boolean\r\n autoIncrement? : boolean\r\n notNull? : boolean\r\n unique? : boolean\r\n default? : SqlValue\r\n references? : { table: string; column: string }\r\n }\r\n\r\n export interface TableSchema {\r\n name : string\r\n columns : ColumnDefinition[]\r\n indexes? : { name: string; columns: string[]; unique?: boolean }[]\r\n }\r\n\r\n export interface WhereCondition {\r\n column : string\r\n operator : '=' | '!=' | '>' | '<' | '>=' | '<=' | 'LIKE' | 'IN' | 'IS NULL' | 'IS NOT NULL'\r\n value? : SqlValue | SqlValue[]\r\n }\r\n\r\n export interface QueryBuilder {\r\n select : (columns?: string[]) => QueryBuilder\r\n from : (table: string) => QueryBuilder\r\n where : (condition: WhereCondition | WhereCondition[]) => QueryBuilder\r\n and : (condition: WhereCondition) => QueryBuilder\r\n or : (condition: WhereCondition) => QueryBuilder\r\n orderBy : (column: string, direction?: 'ASC' | 'DESC') => QueryBuilder\r\n limit : (count: number) => QueryBuilder\r\n offset : (count: number) => QueryBuilder\r\n insert : (table: string, data: Record<string, SqlValue>) => QueryBuilder\r\n update : (table: string, data: Record<string, SqlValue>) => QueryBuilder\r\n delete : (table: string) => QueryBuilder\r\n execute : () => any[]\r\n executeOne : () => any | null\r\n executeRaw : (sql: string, params?: SqlValue[]) => any[]\r\n raw : (sql: string, params?: SqlValue[]) => QueryBuilder\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class DB {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n private db : Database\r\n private schemas : Map<string, TableSchema> = new Map()\r\n private currentQuery : string = ''\r\n private currentParams : SqlValue[] = []\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── CORE ──────────────────────────────┐\r\n\r\n constructor(path: string = ':memory:') {\r\n this.db = new Database(path)\r\n this.db.exec('PRAGMA foreign_keys = ON')\r\n }\r\n\r\n close() {\r\n this.db.close()\r\n }\r\n\r\n // ════════ Schema Management ════════\r\n defineSchema(schema: TableSchema): void {\r\n this.schemas.set(schema.name, schema)\r\n const sql = this.generateCreateTableSQL(schema)\r\n this.db.exec(sql)\r\n\r\n // Create indexes\r\n if (schema.indexes) {\r\n for (const index of schema.indexes) {\r\n const uniqueStr = index.unique ? 'UNIQUE' : ''\r\n const indexSql = `CREATE ${uniqueStr} INDEX IF NOT EXISTS ${index.name} ON ${schema.name} (${index.columns.join(', ')})`\r\n this.db.exec(indexSql)\r\n }\r\n }\r\n }\r\n\r\n getSchema(tableName: string): TableSchema | undefined {\r\n return this.schemas.get(tableName)\r\n }\r\n\r\n listTables(): string[] {\r\n const result = this.db.query(\"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'\").all()\r\n return result.map((r: any) => r.name)\r\n }\r\n\r\n dropTable(tableName: string): void {\r\n this.db.exec(`DROP TABLE IF EXISTS ${tableName}`)\r\n this.schemas.delete(tableName)\r\n }\r\n\r\n // ════════ Query Builder ════════\r\n query(): QueryBuilder {\r\n this.reset()\r\n return this.createQueryBuilder()\r\n }\r\n\r\n // ════════ Quick Operations ════════\r\n find(table: string, conditions: Record<string, SqlValue>): any[] {\r\n const whereConditions: WhereCondition[] = Object.entries(conditions).map(([column, value]) => ({\r\n column,\r\n operator: '=' as const,\r\n value\r\n }))\r\n\r\n return this.query()\r\n .select()\r\n .from(table)\r\n .where(whereConditions)\r\n .execute()\r\n }\r\n\r\n findOne(table: string, conditions: Record<string, SqlValue>): any | null {\r\n return this.query()\r\n .select()\r\n .from(table)\r\n .where(Object.entries(conditions).map(([column, value]) => ({\r\n column,\r\n operator: '=' as const,\r\n value\r\n })))\r\n .limit(1)\r\n .executeOne()\r\n }\r\n\r\n findById(table: string, id: number | string): any | null {\r\n return this.findOne(table, { id })\r\n }\r\n\r\n all(table: string): any[] {\r\n return this.query().select().from(table).execute()\r\n }\r\n\r\n insert(table: string, data: Record<string, SqlValue>): any {\r\n this.query().insert(table, data).execute()\r\n\r\n // Return inserted row\r\n const lastId = this.db.query('SELECT last_insert_rowid() as id').get() as any\r\n return this.findById(table, lastId.id)\r\n }\r\n\r\n update(table: string, id: number | string, data: Record<string, SqlValue>): any | null {\r\n this.query()\r\n .update(table, data)\r\n .where({ column: 'id', operator: '=', value: id })\r\n .execute()\r\n\r\n return this.findById(table, id)\r\n }\r\n\r\n delete(table: string, id: number | string): boolean {\r\n const result = this.query()\r\n .delete(table)\r\n .where({ column: 'id', operator: '=', value: id })\r\n .execute()\r\n\r\n return true\r\n }\r\n\r\n // ════════ Transactions ════════\r\n transaction(callback: (db: DB) => void): void {\r\n this.db.exec('BEGIN TRANSACTION')\r\n try {\r\n callback(this)\r\n this.db.exec('COMMIT')\r\n } catch (error) {\r\n this.db.exec('ROLLBACK')\r\n throw error\r\n }\r\n }\r\n\r\n // ════════ Raw SQL ════════\r\n exec(sql: string): void {\r\n this.db.exec(sql)\r\n }\r\n\r\n raw(sql: string, params: SqlValue[] = []): any[] {\r\n const stmt = this.db.query(sql)\r\n return stmt.all(...params) as any[]\r\n }\r\n\r\n rawOne(sql: string, params: SqlValue[] = []): any | null {\r\n const stmt = this.db.query(sql)\r\n return stmt.get(...params) as any | null\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── HELP ──────────────────────────────┐\r\n\r\n private reset(): void {\r\n this.currentQuery = ''\r\n this.currentParams = []\r\n }\r\n\r\n private createQueryBuilder(): QueryBuilder {\r\n const builder: any = {\r\n _select: ['*'],\r\n _from: '',\r\n _where: [] as string[],\r\n _orderBy: '',\r\n _limit: null as number | null,\r\n _offset: null as number | null,\r\n _isInsert: false,\r\n _isUpdate: false,\r\n _isDelete: false,\r\n _insertData: null as Record<string, SqlValue> | null,\r\n _updateData: null as Record<string, SqlValue> | null\r\n }\r\n\r\n const self = this\r\n\r\n builder.select = function(columns?: string[]) {\r\n this._select = columns || ['*']\r\n return this\r\n }\r\n\r\n builder.from = function(table: string) {\r\n this._from = table\r\n return this\r\n }\r\n\r\n builder.where = function(condition: WhereCondition | WhereCondition[]) {\r\n const conditions = Array.isArray(condition) ? condition : [condition]\r\n\r\n const whereClauses = conditions.map(cond => {\r\n if (cond.operator === 'IS NULL' || cond.operator === 'IS NOT NULL') {\r\n return `${cond.column} ${cond.operator}`\r\n } else if (cond.operator === 'IN' && Array.isArray(cond.value)) {\r\n const placeholders = cond.value.map(() => '?').join(', ')\r\n // Spread array values into params\r\n cond.value.forEach(val => {\r\n self.currentParams.push(val as SqlValue)\r\n })\r\n return `${cond.column} IN (${placeholders})`\r\n } else {\r\n self.currentParams.push(cond.value as SqlValue)\r\n return `${cond.column} ${cond.operator} ?`\r\n }\r\n })\r\n\r\n this._where.push(...whereClauses)\r\n return this\r\n }\r\n\r\n builder.and = function(condition: WhereCondition) {\r\n return this.where(condition)\r\n }\r\n\r\n builder.or = function(condition: WhereCondition) {\r\n if (condition.operator === 'IS NULL' || condition.operator === 'IS NOT NULL') {\r\n this._where.push(`OR ${condition.column} ${condition.operator}`)\r\n } else if (condition.operator === 'IN' && Array.isArray(condition.value)) {\r\n const placeholders = condition.value.map(() => '?').join(', ')\r\n // Spread array values into params\r\n condition.value.forEach(val => {\r\n self.currentParams.push(val as SqlValue)\r\n })\r\n this._where.push(`OR ${condition.column} IN (${placeholders})`)\r\n } else {\r\n self.currentParams.push(condition.value as SqlValue)\r\n this._where.push(`OR ${condition.column} ${condition.operator} ?`)\r\n }\r\n return this\r\n }\r\n\r\n builder.orderBy = function(column: string, direction: 'ASC' | 'DESC' = 'ASC') {\r\n this._orderBy = `ORDER BY ${column} ${direction}`\r\n return this\r\n }\r\n\r\n builder.limit = function(count: number) {\r\n this._limit = count\r\n return this\r\n }\r\n\r\n builder.offset = function(count: number) {\r\n this._offset = count\r\n return this\r\n }\r\n\r\n builder.insert = function(table: string, data: Record<string, SqlValue>) {\r\n this._isInsert = true\r\n this._from = table\r\n this._insertData = data\r\n return this\r\n }\r\n\r\n builder.update = function(table: string, data: Record<string, SqlValue>) {\r\n this._isUpdate = true\r\n this._from = table\r\n this._updateData = data\r\n return this\r\n }\r\n\r\n builder.delete = function(table: string) {\r\n this._isDelete = true\r\n this._from = table\r\n return this\r\n }\r\n\r\n builder.raw = function(sql: string, params: SqlValue[] = []) {\r\n self.currentQuery = sql\r\n self.currentParams = params\r\n return this\r\n }\r\n\r\n builder.execute = function() {\r\n let sql = ''\r\n\r\n if (this._isInsert && this._insertData) {\r\n const columns = Object.keys(this._insertData)\r\n const placeholders = columns.map(() => '?').join(', ')\r\n sql = `INSERT INTO ${this._from} (${columns.join(', ')}) VALUES (${placeholders})`\r\n self.currentParams = Object.values(this._insertData)\r\n } else if (this._isUpdate && this._updateData) {\r\n const setClauses = Object.keys(this._updateData).map(col => `${col} = ?`)\r\n const updateValues = Object.values(this._updateData)\r\n self.currentParams = [...updateValues, ...self.currentParams] as SqlValue[]\r\n sql = `UPDATE ${this._from} SET ${setClauses.join(', ')}`\r\n\r\n if (this._where.length > 0) {\r\n sql += ` WHERE ${this._where.join(' AND ')}`\r\n }\r\n } else if (this._isDelete) {\r\n sql = `DELETE FROM ${this._from}`\r\n\r\n if (this._where.length > 0) {\r\n sql += ` WHERE ${this._where.join(' AND ')}`\r\n }\r\n } else {\r\n // SELECT query\r\n sql = `SELECT ${this._select.join(', ')} FROM ${this._from}`\r\n\r\n if (this._where.length > 0) {\r\n sql += ` WHERE ${this._where.join(' AND ')}`\r\n }\r\n\r\n if (this._orderBy) {\r\n sql += ` ${this._orderBy}`\r\n }\r\n\r\n if (this._limit !== null) {\r\n sql += ` LIMIT ${this._limit}`\r\n }\r\n\r\n if (this._offset !== null) {\r\n sql += ` OFFSET ${this._offset}`\r\n }\r\n }\r\n\r\n if (!sql && self.currentQuery) {\r\n sql = self.currentQuery\r\n }\r\n\r\n const stmt = self.db.query(sql)\r\n const result = stmt.all(...self.currentParams) as unknown[]\r\n self.reset()\r\n return result as any[]\r\n }\r\n\r\n builder.executeOne = function() {\r\n const results = this.execute()\r\n return results.length > 0 ? results[0] : null\r\n }\r\n\r\n builder.executeRaw = function(sql: string, params: SqlValue[] = []) {\r\n const stmt = self.db.query(sql)\r\n const result = stmt.all(...params) as unknown[]\r\n return result as any[]\r\n }\r\n\r\n return builder as QueryBuilder\r\n }\r\n\r\n private generateCreateTableSQL(schema: TableSchema): string {\r\n const columnDefs = schema.columns.map(col => {\r\n let def = `${col.name} ${col.type}`\r\n\r\n if (col.primaryKey) {\r\n def += ' PRIMARY KEY'\r\n if (col.autoIncrement) {\r\n def += ' AUTOINCREMENT'\r\n }\r\n }\r\n\r\n if (col.notNull && !col.primaryKey) {\r\n def += ' NOT NULL'\r\n }\r\n\r\n if (col.unique) {\r\n def += ' UNIQUE'\r\n }\r\n\r\n if (col.default !== undefined) {\r\n if (typeof col.default === 'string') {\r\n def += ` DEFAULT '${col.default}'`\r\n } else if (col.default === null) {\r\n def += ' DEFAULT NULL'\r\n } else {\r\n def += ` DEFAULT ${col.default}`\r\n }\r\n }\r\n\r\n if (col.references) {\r\n def += ` REFERENCES ${col.references.table}(${col.references.column})`\r\n }\r\n\r\n return def\r\n })\r\n\r\n return `CREATE TABLE IF NOT EXISTS ${schema.name} (${columnDefs.join(', ')})`\r\n }\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ HELP ════════════════════════════════════════╗\r\n\r\n // ════════ Schema Builder Helpers ════════\r\n export function table(name: string, columns: ColumnDefinition[]): TableSchema {\r\n return { name, columns }\r\n }\r\n\r\n export function column(name: string, type: ColumnType): ColumnDefinition {\r\n return { name, type }\r\n }\r\n\r\n export function integer(name: string): ColumnDefinition {\r\n return { name, type: 'INTEGER' }\r\n }\r\n\r\n export function text(name: string): ColumnDefinition {\r\n return { name, type: 'TEXT' }\r\n }\r\n\r\n export function real(name: string): ColumnDefinition {\r\n return { name, type: 'REAL' }\r\n }\r\n\r\n export function blob(name: string): ColumnDefinition {\r\n return { name, type: 'BLOB' }\r\n }\r\n\r\n export function numeric(name: string): ColumnDefinition {\r\n return { name, type: 'NUMERIC' }\r\n }\r\n\r\n // ════════ Column Modifiers ════════\r\n export function primaryKey(col: ColumnDefinition, autoIncrement = false): ColumnDefinition {\r\n return { ...col, primaryKey: true, autoIncrement }\r\n }\r\n\r\n export function notNull(col: ColumnDefinition): ColumnDefinition {\r\n return { ...col, notNull: true }\r\n }\r\n\r\n export function unique(col: ColumnDefinition): ColumnDefinition {\r\n return { ...col, unique: true }\r\n }\r\n\r\n export function defaultValue(col: ColumnDefinition, value: SqlValue): ColumnDefinition {\r\n return { ...col, default: value }\r\n }\r\n\r\n export function references(col: ColumnDefinition, table: string, column: string): ColumnDefinition {\r\n return { ...col, references: { table, column } }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// 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\texport interface RegexRoute {\r\n\t\tpattern\t\t: RegExp\r\n\t\tmethod\t\t: string\r\n\t\thandler\t\t: any\r\n\t\tkey\t\t\t: string\r\n\t}\r\n\r\n\texport type RegexRoutes = Array<RegexRoute>\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\t\t\tprivate routes \t\t\t= new Map<string, any>()\r\n\t\t\tprivate regexRoutes\t\t: RegexRoutes = []\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n\t\t\tmatch(method: string, path: string): { handler: any; params: Record<string, string> } | null {\r\n\t\t\t\tconst key = `${method}:${path}`\r\n\r\n\t\t\t\t// Try static route first (faster)\r\n\t\t\t\tif (this.routes.has(key)) {\r\n\t\t\t\t\treturn { handler: this.routes.get(key), params: {} }\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Try dynamic routes\r\n\t\t\t\tfor (const route of this.regexRoutes) {\r\n\t\t\t\t\tif (route.method === method) {\r\n\t\t\t\t\t\tconst match = path.match(route.pattern)\r\n\t\t\t\t\t\tif (match) {\r\n\t\t\t\t\t\t\t// Extract named groups if they exist\r\n\t\t\t\t\t\t\tconst params = match.groups || {}\r\n\t\t\t\t\t\t\treturn { handler: route.handler, params }\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn null\r\n\t\t\t}\r\n\r\n\t\t\tgetAll() {\r\n\t\t\t\tconst staticRoutes = Array.from(this.routes.entries()).map(([key, handler]) => {\r\n\t\t\t\t\tconst colonIndex = key.indexOf(':')\r\n\t\t\t\t\tconst method = key.substring(0, colonIndex)\r\n\t\t\t\t\tconst path = key.substring(colonIndex + 1)\r\n\t\t\t\t\treturn { method, path, handler }\r\n\t\t\t\t})\r\n\r\n\t\t\t\tconst dynamicRoutes = this.regexRoutes.map(route => {\r\n\t\t\t\t\tconst colonIndex = route.key.indexOf(':')\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tmethod: route.method,\r\n\t\t\t\t\t\tpath: route.key.substring(colonIndex + 1),\r\n\t\t\t\t\t\thandler: route.handler\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\r\n\t\t\t\treturn [...staticRoutes, ...dynamicRoutes]\r\n\t\t\t}\r\n\r\n\t\t\tclear() {\r\n\t\t\t\tthis.routes.clear()\r\n\t\t\t\tthis.regexRoutes = []\r\n\t\t\t}\r\n\r\n\t\t\tremove(method: string, path: string): boolean {\r\n\t\t\t\tconst key = `${method}:${path}`\r\n\r\n\t\t\t\tif (this.routes.has(key)) {\r\n\t\t\t\t\tthis.routes.delete(key)\r\n\t\t\t\t\treturn true\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst index = this.regexRoutes.findIndex(r => r.key === key)\r\n\t\t\t\tif (index >= 0) {\r\n\t\t\t\t\tthis.regexRoutes.splice(index, 1)\r\n\t\t\t\t\treturn true\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn false\r\n\t\t\t}\r\n\r\n\t\t\tregister(method: string, path: string, handler: any, config: any = {}) {\r\n\t\t\t\tconst key = `${method}:${path}`\r\n\r\n\t\t\t\t// Check if path needs regex (has :params or wildcards)\r\n\t\t\t\tif (path.includes(':') || path.includes('*')) {\r\n\t\t\t\t\t// Dynamic route with params or wildcards\r\n\t\t\t\t\tconst pattern = this.pathToRegex(path)\r\n\r\n\t\t\t\t\t// Check if route already exists to prevent duplicates\r\n\t\t\t\t\tconst existingIndex = this.regexRoutes.findIndex(r => r.key === key)\r\n\r\n\t\t\t\t\tconst route = {\r\n\t\t\t\t\t\tpattern,\r\n\t\t\t\t\t\tmethod,\r\n\t\t\t\t\t\thandler,\r\n\t\t\t\t\t\tkey\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (existingIndex >= 0) {\r\n\t\t\t\t\t\t// Update existing route\r\n\t\t\t\t\t\tthis.regexRoutes[existingIndex] = route\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// Add new route\r\n\t\t\t\t\t\tthis.regexRoutes.push(route)\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// Static route\r\n\t\t\t\t\tthis.routes.set(key, handler)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── HELP ──────────────────────────────┐\r\n\r\n\t\t\tprivate pathToRegex(path: string): RegExp {\r\n\t\t\t\t// Escape special regex characters except ':' and '*'\r\n\t\t\t\tlet pattern = path.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&')\r\n\r\n\t\t\t\t// Replace :param with named capture groups\r\n\t\t\t\tpattern = pattern.replace(/:(\\w+)/g, '(?<$1>[^/]+)')\r\n\r\n\t\t\t\t// Replace * with wildcard pattern (matches everything including slashes)\r\n\t\t\t\tpattern = pattern.replace(/\\*/g, '.*')\r\n\r\n\t\t\t\treturn new RegExp(`^${pattern}$`)\r\n\t\t\t}\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// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class SecurityManager {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n\t\t\tprivate rateLimitStore \t= new Map<string, { count: number; reset: number }>()\r\n\t\t\tprivate csrfTokens \t\t= new Map<string, { sessionId: string; expires: number }>()\r\n\t\t\tprivate requestLog\t\t= new Map<string, any>()\r\n\r\n\t\t\tprivate readonly MAX_REQUEST_LOG_SIZE = 1000\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n\t\t\t// Rate Limiting with proper overflow handling\r\n\t\t\tcheckRateLimit(key: string, max: number, windowMs: number): boolean {\r\n\t\t\tconst now = Date.now()\r\n\t\t\tconst record = this.rateLimitStore.get(key)\r\n\r\n\t\t\tif (record) {\r\n\t\t\t\tif (now < record.reset) {\r\n\t\t\t\t// Within the current window\r\n\t\t\t\tif (record.count >= max) {\r\n\t\t\t\t\treturn false // Rate limit exceeded\r\n\t\t\t\t}\r\n\t\t\t\trecord.count++\r\n\t\t\t\treturn true\r\n\t\t\t\t} else {\r\n\t\t\t\t// Window expired, reset\r\n\t\t\t\tthis.rateLimitStore.set(key, { count: 1, reset: now + windowMs })\r\n\t\t\t\treturn true\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// First request for this key\r\n\t\t\t\tthis.rateLimitStore.set(key, { count: 1, reset: now + windowMs })\r\n\t\t\t\treturn true\r\n\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Cleanup old rate limit records\r\n\t\t\tcleanupRateLimit() {\r\n\t\t\tconst now = Date.now()\r\n\t\t\tfor (const [key, record] of this.rateLimitStore.entries()) {\r\n\t\t\t\tif (now > record.reset) {\r\n\t\t\t\tthis.rateLimitStore.delete(key)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// CSRF Token Generation with TTL\r\n\t\t\tgenerateCsrfToken(sessionId: string, ttl = 3600000): string {\r\n\t\t\tconst token = crypto.randomBytes(32).toString('hex')\r\n\t\t\tthis.csrfTokens.set(token, {\r\n\t\t\t\tsessionId,\r\n\t\t\t\texpires: Date.now() + ttl\r\n\t\t\t})\r\n\t\t\treturn token\r\n\t\t\t}\r\n\r\n\t\t\t// Validate CSRF Token with expiration check\r\n\t\t\tvalidateCsrfToken(token: string, sessionId: string): boolean {\r\n\t\t\tconst stored = this.csrfTokens.get(token)\r\n\r\n\t\t\tif (!stored) {\r\n\t\t\t\treturn false\r\n\t\t\t}\r\n\r\n\t\t\t// Check if token has expired\r\n\t\t\tif (Date.now() > stored.expires) {\r\n\t\t\t\tthis.csrfTokens.delete(token)\r\n\t\t\t\treturn false\r\n\t\t\t}\r\n\r\n\t\t\t// Validate session ID\r\n\t\t\tif (stored.sessionId === sessionId) {\r\n\t\t\t\tthis.csrfTokens.delete(token) // One-time use\r\n\t\t\t\treturn true\r\n\t\t\t}\r\n\r\n\t\t\treturn false\r\n\t\t\t}\r\n\r\n\t\t\t// Cleanup expired CSRF tokens\r\n\t\t\tcleanupCsrfTokens() {\r\n\t\t\tconst now = Date.now()\r\n\t\t\tfor (const [token, data] of this.csrfTokens.entries()) {\r\n\t\t\t\tif (now > data.expires) {\r\n\t\t\t\tthis.csrfTokens.delete(token)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// HTML Sanitization - comprehensive\r\n\t\t\tsanitizeHtml(html: string): string {\r\n\t\t\tif (!html) return ''\r\n\r\n\t\t\treturn html\r\n\t\t\t\t.replace(/&/g, '&amp;')\r\n\t\t\t\t.replace(/</g, '&lt;')\r\n\t\t\t\t.replace(/>/g, '&gt;')\r\n\t\t\t\t.replace(/\"/g, '&quot;')\r\n\t\t\t\t.replace(/'/g, '&#x27;')\r\n\t\t\t\t.replace(/\\//g, '&#x2F;')\r\n\t\t\t}\r\n\r\n\t\t\t// SQL Injection Prevention\r\n\t\t\tsanitizeSql(input: string): string {\r\n\t\t\tif (!input) return ''\r\n\r\n\t\t\treturn input\r\n\t\t\t\t.replace(/\\\\/g, '\\\\\\\\') // Escape backslashes first\r\n\t\t\t\t.replace(/;/g, '') // Remove semicolons to prevent multi-statement injection\r\n\t\t\t\t.replace(/'/g, \"''\") // Escape single quotes (SQL standard)\r\n\t\t\t\t.replace(/\"/g, '\\\\\"') // Escape double quotes\r\n\t\t\t\t.replace(/\\x00/g, '') // Remove null bytes\r\n\t\t\t}\r\n\r\n\t\t\t// Log request for audit trail with size limit\r\n\t\t\tlogRequest(\r\n\t\t\tid: string,\r\n\t\t\tmethod: string,\r\n\t\t\tpath: string,\r\n\t\t\tip: string,\r\n\t\t\tstatus: number,\r\n\t\t\tduration: number\r\n\t\t\t) {\r\n\t\t\tthis.requestLog.set(id, {\r\n\t\t\t\ttimestamp: new Date().toISOString(),\r\n\t\t\t\tmethod,\r\n\t\t\t\tpath,\r\n\t\t\t\tip,\r\n\t\t\t\tstatus,\r\n\t\t\t\tduration\r\n\t\t\t})\r\n\r\n\t\t\t// Keep only last MAX_REQUEST_LOG_SIZE requests\r\n\t\t\tif (this.requestLog.size > this.MAX_REQUEST_LOG_SIZE) {\r\n\t\t\t\tconst { value: first } = this.requestLog.keys().next() || { value: null }\r\n\t\t\t\tif (first) {\r\n\t\t\t\tthis.requestLog.delete(first)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Get request log by ID\r\n\t\t\tgetRequestLog(id: string) {\r\n\t\t\treturn this.requestLog.get(id)\r\n\t\t\t}\r\n\r\n\t\t\t// Get all request logs\r\n\t\t\tgetAllRequestLogs() {\r\n\t\t\treturn Array.from(this.requestLog.values())\r\n\t\t\t}\r\n\r\n\t\t\t// Clear all\r\n\t\t\tclearAll() {\r\n\t\t\tthis.rateLimitStore.clear()\r\n\t\t\tthis.csrfTokens.clear()\r\n\t\t\tthis.requestLog.clear()\r\n\t\t\t}\r\n\r\n\t\t\t// Get stats\r\n\t\t\tgetStats() {\r\n\t\t\t\treturn {\r\n\t\t\t\t\trateLimitEntries: this.rateLimitStore.size,\r\n\t\t\t\t\tcsrfTokens: this.csrfTokens.size,\r\n\t\t\t\t\trequestLogs: this.requestLog.size\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── HELP ──────────────────────────────┐\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n","// src/mod/logger.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n\texport class Logger {\r\n\r\n // ┌──────────────────────────────── INIT ──────────────────────────────┐\r\n\r\n\t\t\tprivate level\t: number \t= 1\r\n\t\t\tprivate pretty\t: boolean \t= false\r\n\t\t\tprivate levels\t\t\t\t= { debug: 0, info: 1, warn: 2, error: 3, fatal: 4 }\r\n\r\n\t\t\t// ANSI color codes\r\n\t\t\tprivate colors = {\r\n\t\t\t\treset\t: '\\x1b[0m',\r\n\t\t\t\tgray\t: '\\x1b[90m',\r\n\t\t\t\tcyan\t: '\\x1b[36m',\r\n\t\t\t\tgreen\t: '\\x1b[32m',\r\n\t\t\t\tyellow\t: '\\x1b[33m',\r\n\t\t\t\tred\t\t: '\\x1b[31m',\r\n\t\t\t\tmagenta\t: '\\x1b[35m',\r\n\t\t\t\tbold\t: '\\x1b[1m'\r\n\t\t\t}\r\n\r\n\t\t\tconstructor(level: 'debug' | 'info' | 'warn' | 'error' = 'info', pretty = false) {\r\n\t\t\t\tthis.level \t= this.levels[level] ?? 1\r\n\t\t\t\tthis.pretty = pretty\r\n\t\t\t}\r\n\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── MAIN ──────────────────────────────┐\r\n\r\n\t\t\tdebug(data: any, msg?: string) {\r\n\t\t\t\tthis.log('debug', this.levels.debug, data, msg)\r\n\t\t\t}\r\n\r\n\t\t\tinfo(data: any, msg?: string) {\r\n\t\t\t\tthis.log('info', this.levels.info, data, msg)\r\n\t\t\t}\r\n\r\n\t\t\twarn(data: any, msg?: string) {\r\n\t\t\t\tthis.log('warn', this.levels.warn, data, msg)\r\n\t\t\t}\r\n\r\n\t\t\terror(data: any, msg?: string) {\r\n\t\t\t\tthis.log('error', this.levels.error, data, msg)\r\n\t\t\t}\r\n\r\n\t\t\tfatal(data: any, msg?: string) {\r\n\t\t\t\tthis.log('fatal', this.levels.fatal, data, msg)\r\n\t\t\t\tif (process.env.NODE_ENV === 'production') {\r\n\t\t\t\t\t// Could send to external logging service here\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\r\n // ┌──────────────────────────────── HELP ──────────────────────────────┐\r\n\r\n private log(level: string, levelNum: number, data: any, msg?: string) {\r\n if (levelNum < this.level) return\r\n\r\n // Handle when data is a string message\r\n let safeData: any\r\n let safeMsg: string | undefined\r\n\r\n if (typeof data === 'string') {\r\n safeMsg = data\r\n safeData = {}\r\n } else {\r\n safeData = data ?? {}\r\n safeMsg = msg\r\n }\r\n\r\n if (this.pretty) {\r\n this.prettyLog(level, safeData, safeMsg)\r\n } else {\r\n // JSON format (unchanged for compatibility)\r\n const ts = new Date().toISOString()\r\n const output = {\r\n timestamp\t: ts,\r\n level\t\t: level.toUpperCase(),\r\n message\t\t: safeMsg || 'No message',\r\n ...safeData\r\n }\r\n const str = JSON.stringify(output)\r\n\r\n if (level === 'error' || level === 'fatal') {\r\n console.error(str)\r\n } else if (level === 'warn') {\r\n console.warn(str)\r\n } else {\r\n console.log(str)\r\n }\r\n }\r\n }\r\n\r\n\t\t\tprivate prettyLog(level: string, data: any, msg?: string) {\r\n\t\t\t\tconst c = this.colors\r\n\t\t\t\tconst time = new Date().toLocaleTimeString('en-US', { hour12: false })\r\n\r\n\t\t\t\t// Special handling for request logs (Morgan-style)\r\n\t\t\t\tif (data.method && data.path && data.status !== undefined) {\r\n\t\t\t\t\tconst method = this.colorizeMethod(data.method)\r\n\t\t\t\t\tconst status = this.colorizeStatus(data.status)\r\n\t\t\t\t\tconst duration = data.duration ? `${data.duration}ms` : ''\r\n\t\t\t\t\tconst path = data.path\r\n\r\n\t\t\t\t\tconsole.log(\r\n\t\t\t\t\t\t`${c.gray}${time}${c.reset} ` +\r\n\t\t\t\t\t\t`${method} ` +\r\n\t\t\t\t\t\t`${c.bold}${path}${c.reset} ` +\r\n\t\t\t\t\t\t`${status} ` +\r\n\t\t\t\t\t\t`${c.gray}${duration}${c.reset}`\r\n\t\t\t\t\t)\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Special handling for route registration\r\n\t\t\t\tif (msg === 'Route added' && data.method && data.path) {\r\n\t\t\t\t\tconst methods = Array.isArray(data.method) ? data.method.join('|') : data.method\r\n\t\t\t\t\tconsole.log(\r\n\t\t\t\t\t\t`${c.gray}${time}${c.reset} ` +\r\n\t\t\t\t\t\t`${c.cyan}→${c.reset} ` +\r\n\t\t\t\t\t\t`${c.bold}${methods.padEnd(6)}${c.reset} ` +\r\n\t\t\t\t\t\t`${data.path}`\r\n\t\t\t\t\t)\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Special handling for database connection\r\n\t\t\t\tif (msg === '✔ Database connected') {\r\n\t\t\t\t\tconsole.log(\r\n\t\t\t\t\t\t`${c.gray}${time}${c.reset} ` +\r\n\t\t\t\t\t\t`${c.green}✓${c.reset} ` +\r\n\t\t\t\t\t\t`Database connected ${c.gray}(${data.name})${c.reset}`\r\n\t\t\t\t\t)\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Special handling for server start\r\n\t\t\t\tif (msg === 'Server started') {\r\n\t\t\t\t\tconsole.log(\r\n\t\t\t\t\t\t`${c.gray}${time}${c.reset} ` +\r\n\t\t\t\t\t\t`${c.green}✓${c.reset} ` +\r\n\t\t\t\t\t\t`Server started at ${c.cyan}${data.url}${c.reset}`\r\n\t\t\t\t\t)\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Generic colored output\r\n\t\t\t\tconst icon = this.getLevelIcon(level)\r\n\t\t\t\tconst color = this.getLevelColor(level)\r\n\r\n\t\t\t\tlet output = `${c.gray}${time}${c.reset} ${color}${icon}${c.reset} `\r\n\r\n\t\t\t\tif (msg) {\r\n\t\t\t\t\toutput += `${msg} `\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Add key data points inline\r\n\t\t\t\tconst keys = Object.keys(data).filter(k =>\r\n\t\t\t\t\t!['timestamp', 'level', 'message'].includes(k)\r\n\t\t\t\t)\r\n\r\n\t\t\t\tif (keys.length > 0) {\r\n\t\t\t\t\tconst parts = keys.map(k => {\r\n\t\t\t\t\t\tconst val = data[k]\r\n\t\t\t\t\t\tif (typeof val === 'string' || typeof val === 'number') {\r\n\t\t\t\t\t\t\treturn `${c.gray}${k}:${c.reset}${val}`\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn null\r\n\t\t\t\t\t}).filter(Boolean)\r\n\r\n\t\t\t\t\tif (parts.length > 0) {\r\n\t\t\t\t\t\toutput += c.gray + parts.join(' ') + c.reset\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconsole.log(output)\r\n\t\t\t}\r\n\r\n\t\t\tprivate colorizeMethod(method: string): string {\r\n\t\t\t\tconst c = this.colors\r\n\t\t\t\tconst m = method.toUpperCase()\r\n\r\n\t\t\t\tswitch (m) {\r\n\t\t\t\t\tcase 'GET':\t\treturn `${c.green}${m}${c.reset}`\r\n\t\t\t\t\tcase 'POST':\treturn `${c.cyan}${m}${c.reset}`\r\n\t\t\t\t\tcase 'PUT':\t\treturn `${c.yellow}${m}${c.reset}`\r\n\t\t\t\t\tcase 'DELETE':\treturn `${c.red}${m}${c.reset}`\r\n\t\t\t\t\tcase 'PATCH':\treturn `${c.magenta}${m}${c.reset}`\r\n\t\t\t\t\tdefault:\t\treturn `${c.gray}${m}${c.reset}`\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tprivate colorizeStatus(status: number | undefined): string {\r\n\t\t\t\tif (!status) return ''\r\n\r\n\t\t\t\tconst c = this.colors\r\n\t\t\t\tconst s = status.toString()\r\n\r\n\t\t\t\tif (status >= 200 && status < 300) {\r\n\t\t\t\t\treturn `${c.green}${s}${c.reset}`\r\n\t\t\t\t} else if (status >= 300 && status < 400) {\r\n\t\t\t\t\treturn `${c.cyan}${s}${c.reset}`\r\n\t\t\t\t} else if (status >= 400 && status < 500) {\r\n\t\t\t\t\treturn `${c.yellow}${s}${c.reset}`\r\n\t\t\t\t} else if (status >= 500) {\r\n\t\t\t\t\treturn `${c.red}${s}${c.reset}`\r\n\t\t\t\t}\r\n\t\t\t\treturn `${c.gray}${s}${c.reset}`\r\n\t\t\t}\r\n\r\n\t\t\tprivate getLevelIcon(level: string): string {\r\n\t\t\t\tswitch (level) {\r\n\t\t\t\t\tcase 'debug':\treturn '-'\r\n\t\t\t\t\tcase 'info':\treturn '-'\r\n\t\t\t\t\tcase 'warn':\treturn '-'\r\n\t\t\t\t\tcase 'error':\treturn '-'\r\n\t\t\t\t\tcase 'fatal':\treturn '-'\r\n\t\t\t\t\tdefault:\t\treturn '-'\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tprivate getLevelColor(level: string): string {\r\n\t\t\t\tconst c = this.colors\r\n\t\t\t\tswitch (level) {\r\n\t\t\t\t\tcase 'debug':\treturn c.gray\r\n\t\t\t\t\tcase 'info':\treturn c.cyan\r\n\t\t\t\t\tcase 'warn':\treturn c.yellow\r\n\t\t\t\t\tcase 'error':\treturn c.red\r\n\t\t\t\t\tcase 'fatal':\treturn c.red + c.bold\r\n\t\t\t\t\tdefault:\t\treturn c.reset\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n // └────────────────────────────────────────────────────────────────────┘\r\n\r\n\t}\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/types.d.ts\r\n//\r\n// Developed with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ TYPE ════════════════════════════════════════╗\r\n\r\n export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD'\r\n export type RouteHandler = (c: AppContext) => any | Promise<any>\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, any>\r\n body : any\r\n headers : Headers\r\n db : any\r\n logger : Logger | null\r\n user? : any\r\n requestId : string\r\n\r\n // Response methods\r\n json (data: any, 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\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 RouteDefinition {\r\n method : HttpMethod | HttpMethod[]\r\n path : string\r\n handler : RouteHandler\r\n validate? : { body?: any, query?: any, params?: any }\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 export interface DatabaseConfig {\r\n name? : string\r\n connection : string // File path or ':memory:'\r\n schema? : Record<string, any>\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 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 | { level?: 'debug' | 'info' | 'warn' | 'error'; pretty?: boolean }\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 : any\r\n logger : Logger | null\r\n db : Map<string, any>\r\n bunServer : any\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: any, msg?: string): void\r\n info (data: any, msg?: string): void\r\n warn (data: any, msg?: string): void\r\n error (data: any, msg?: string): void\r\n fatal (data: any, 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?: any) {\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// ╚══════════════════════════════════════════════════════════════════════════════════════╝\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() {\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 (e) {\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)\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, pathname: 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)\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: any): 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: any): 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() {\r\n this.fileCache.clear()\r\n }\r\n\r\n /**\r\n * Get cache statistics\r\n */\r\n getCacheStats() {\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 { DB } from './mod/db'\n import { Router } from './mod/router'\n import { SecurityManager } from './mod/security'\n import { Logger } \tfrom './mod/logger'\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, any>()\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: any): 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\n logger?.warn({ requestId, size: contentLength, ip }, 'Request too large')\n\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 any)\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: any = 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 const response = await Promise.race([\n routeMatch.handler(ctx),\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 // ════════ 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, 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 // Register catch-all route for this static path\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 // FIXED: Handle root path differently\n if (staticCfg.path === '/') {\n // For root path, register both exact root and wildcard\n router.register('GET', '/', handler, staticRoute)\n router.register('HEAD', '/', handler, staticRoute)\n router.register('GET', '/*', handler, staticRoute)\n router.register('HEAD', '/*', handler, staticRoute)\n } else {\n // For prefixed paths like /public, /static\n router.register('GET', `${staticCfg.path}/*`, handler, staticRoute)\n router.register('HEAD', `${staticCfg.path}/*`, handler, staticRoute)\n }\n\n // logger?.info({\n // urlPath: staticCfg.path,\n // directory: staticCfg.directory,\n // maxAge: staticCfg.maxAge || 3600\n // }, '✔ Static file serving enabled')\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, healthRoute)\n router.register('GET', '/readiness', readinessRoute.handler, readinessRoute)\n\n let bunServer: any = null\n\n const instance: types.ServerInstance = {\n app : null,\n logger,\n db : dbs,\n bunServer : null,\n\n async start() {\n // Initialize databases with our custom DB solution\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 // Create DB instance with connection string\n const db = new DB(dbCfg.connection)\n\n // Define schemas if provided\n if (dbCfg.schema && typeof dbCfg.schema === 'object') {\n for (const [tableName, tableSchema] of Object.entries(dbCfg.schema)) {\n if (tableSchema && typeof tableSchema === 'object') {\n db.defineSchema(tableSchema as any)\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 // Wait for active requests to complete\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 // Close database connections\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) {\n bunServer.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, 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 // Better body parsing with size validation\n async function parseBody(\n request : Request,\n logger : Logger | null,\n maxSize : number\n ): Promise<any> {\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\t// Validate size after reading\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\n return Object.fromEntries(new URLSearchParams(text))\n }\n\n if (contentType.includes('multipart/form-data')) {\n // Note: FormData size can't be validated before parsing\n return await request.formData()\n }\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 // Better cookie parsing\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('=') // Handle '=' in value\n cookies.set(key, value ? decodeURIComponent(value) : '')\n }\n }\n\n return cookies\n }\n\n // Create app context with request ID\n function createAppContext(\n ip : string,\n request : Request,\n params : Record<string, string>,\n db : any,\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: any = {\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: any, 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: any = {}\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 // Better IP extraction with Bun server context\n function getClientIp(request: Request, server?: any): string {\n // Check proxy headers first (for production behind reverse proxy)\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 // Get IP from Bun server context (works for localhost)\n if (server) {\n try {\n const remoteAddress = server.requestIP(request)\n if (remoteAddress?.address) {\n return remoteAddress.address\n }\n } catch (e) {\n // Fallback if requestIP fails\n }\n }\n\n return 'unknown'\n }\n\n // CORS helper with proper configuration\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 all types\n export * from './types.d';\n\n // Export Logger\n export { Logger };\n\n // Export SecurityManager for advanced use cases\n export { SecurityManager };\n\n // Export Router for advanced use cases\n export { Router };\n\n // Export DB and database helpers\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 './mod/db';\n\n // Export DB types\n export type {\n ColumnType,\n SqlValue,\n ColumnDefinition,\n TableSchema,\n WhereCondition,\n QueryBuilder\n } from './mod/db';\n\n // Export StaticFileServer\n export { StaticFileServer, createStatic } from './mod/static';\n\n // Export Static types\n export type { StaticConfig } from './mod/static';\n\n // Default export\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/main.ts"],"names":["Router","method","path","key","route","match","params","staticRoutes","handler","colonIndex","dynamicRoutes","index","r","_","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","response","resHeaders","value","error","errorMessage","healthRoute","c","readinessRoute","dbConnected","ready","m","staticConfigs","staticCfg","staticRoute","bunServer","instance","dbConfigs","dbCfg","dbName","db","ee","tableSchema","url","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":"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","file":"main.cjs","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 }\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 }\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, RouteHandler>();\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 return { handler: this.routes.get(key)!, params: {} };\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 { handler: route.handler, params };\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, handler]) => {\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 };\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, _: 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 };\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);\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\n logger?.warn({ requestId, size: contentLength, ip }, 'Request too large');\n\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 const response = await Promise.race([\n routeMatch.handler(ctx),\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 // ════════ 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 // Register catch-all route for this static path\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 // FIXED: Handle root path differently\n if (staticCfg.path === '/') {\n // For root path, register both exact root and wildcard\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 // For prefixed paths like /public, /static\n router.register('GET', `${staticCfg.path}/*`, handler as types.RouteHandler, staticRoute);\n router.register('HEAD', `${staticCfg.path}/*`, handler as types.RouteHandler, staticRoute);\n }\n\n // logger?.info({\n // urlPath: staticCfg.path,\n // directory: staticCfg.directory,\n // maxAge: staticCfg.maxAge || 3600\n // }, '✔ Static file serving enabled');\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 // Initialize databases with our custom DB solution\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 // Create DB instance with connection string\n const db = new sdb.DB(dbCfg.connection);\n\n // Define schemas if provided\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 // Wait for active requests to complete\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 // Close database connections\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 // Better body parsing with size validation\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\t// Validate size after reading\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\n return Object.fromEntries(new URLSearchParams(text));\n }\n\n if (contentType.includes('multipart/form-data')) {\n // Note: FormData size can't be validated before parsing\n return await request.formData();\n }\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 // Better cookie parsing\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('='); // Handle '=' in value\n cookies.set(key, value ? decodeURIComponent(value) : '');\n }\n }\n\n return cookies;\n }\n\n // Create app context with request ID\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 // Better IP extraction with Bun server context\n function getClientIp(request: Request, server?: unknown): string {\n // Check proxy headers first (for production behind reverse proxy)\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 // Get IP from Bun server context (works for localhost)\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 // CORS helper with proper configuration\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 all types\n export * from './types.d';\n\n // Export Logger\n export { Logger };\n\n // Export SecurityManager for advanced use cases\n export { SecurityManager };\n\n // Export Router for advanced use cases\n export { Router };\n\n // Export DB and database helpers\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\n // Export DB types\n export type {\n ColumnType,\n SqlValue,\n ColumnDefinition,\n TableSchema,\n WhereCondition,\n QueryBuilder\n } from '@je-es/sdb';\n\n // Export StaticFileServer\n export { StaticFileServer, createStatic } from './mod/static';\n\n // Export Static types\n export type { StaticConfig } from './mod/static';\n\n // Default export\n export default server;\n\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝"]}