{"version":3,"file":"index.cjs","names":["fs","path","path","fs"],"sources":["../src/common/color.ts","../src/common/logger.ts","../src/common/consts.ts","../src/defines/options.ts","../src/common/promise-try.ts","../src/http/headers.ts","../src/http/request.ts","../src/http/respond.ts","../src/http/query.ts","../src/http/exceptions.ts","../src/http/body.ts","../src/http/cookie.ts","../src/http/server.ts","../node_modules/.pnpm/type-narrow@0.2.2/node_modules/type-narrow/dist/index.mjs","../src/common/injector.ts","../src/router/base.ts","../src/router/lazy.ts","../src/fluxion.ts","../src/defines/index.ts"],"sourcesContent":["const useColor = process.env.FLUXION_COLORS !== '0';\n\n/**\n * Color Control Characters for Terminal (cctl)\n */\nexport namespace cctl {\n  export const reset = useColor ? '\\x1b[0m' : '';\n  export const bold = useColor ? '\\x1b[1m' : '';\n  export const dim = useColor ? '\\x1b[2m' : '';\n  export const italic = useColor ? '\\x1b[3m' : '';\n  export const underline = useColor ? '\\x1b[4m' : '';\n  export const blink = useColor ? '\\x1b[5m' : '';\n  export const inverse = useColor ? '\\x1b[7m' : '';\n\n  export const black = useColor ? '\\x1b[30m' : '';\n  export const red = useColor ? '\\x1b[31m' : '';\n  export const green = useColor ? '\\x1b[32m' : '';\n  export const yellow = useColor ? '\\x1b[33m' : '';\n  export const blue = useColor ? '\\x1b[34m' : '';\n  export const magenta = useColor ? '\\x1b[35m' : '';\n  export const cyan = useColor ? '\\x1b[36m' : '';\n  export const white = useColor ? '\\x1b[37m' : '';\n\n  export const brightBlack = useColor ? '\\x1b[90m' : '';\n  export const brightRed = useColor ? '\\x1b[91m' : '';\n  export const brightGreen = useColor ? '\\x1b[92m' : '';\n  export const brightYellow = useColor ? '\\x1b[93m' : '';\n  export const brightBlue = useColor ? '\\x1b[94m' : '';\n  export const brightMagenta = useColor ? '\\x1b[95m' : '';\n  export const brightCyan = useColor ? '\\x1b[96m' : '';\n  export const brightWhite = useColor ? '\\x1b[97m' : '';\n\n  export const bgBlack = useColor ? '\\x1b[40m' : '';\n  export const bgRed = useColor ? '\\x1b[41m' : '';\n  export const bgGreen = useColor ? '\\x1b[42m' : '';\n  export const bgYellow = useColor ? '\\x1b[43m' : '';\n  export const bgBlue = useColor ? '\\x1b[44m' : '';\n  export const bgMagenta = useColor ? '\\x1b[45m' : '';\n  export const bgCyan = useColor ? '\\x1b[46m' : '';\n  export const bgWhite = useColor ? '\\x1b[47m' : '';\n\n  export const bgBrightBlack = useColor ? '\\x1b[100m' : '';\n  export const bgBrightRed = useColor ? '\\x1b[101m' : '';\n  export const bgBrightGreen = useColor ? '\\x1b[102m' : '';\n  export const bgBrightYellow = useColor ? '\\x1b[103m' : '';\n  export const bgBrightBlue = useColor ? '\\x1b[104m' : '';\n  export const bgBrightMagenta = useColor ? '\\x1b[105m' : '';\n  export const bgBrightCyan = useColor ? '\\x1b[106m' : '';\n  export const bgBrightWhite = useColor ? '\\x1b[107m' : '';\n\n  // 'rgb(225, 16, 248)';\n  export const purple = useColor ? '\\x1b[38;2;225;16;248m' : '';\n  // 'rgb(248, 147, 16)';\n  export const orange = useColor ? '\\x1b[38;2;248;147;16m' : '';\n  export const darkGreen = useColor ? '\\x1b[38;2;22;101;52m' : '';\n  export const claude = useColor ? '\\x1b[38;2;217;119;87m' : '';\n  export const deepseek = useColor ? '\\x1b[38;2;57;100;254m' : '';\n  export const gpt = useColor ? '\\x1b[38;2;41;60;77m' : '';\n}\n","import type { FluxionContext } from '@/types.js';\nimport type { otherstring } from '@/global.js';\nimport stringify from 'fast-json-stable-stringify';\nimport { createWriteStream, existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { mkdirSync } from 'node:fs';\n\nimport { cctl } from './color.js';\n\ntype LogLevel = 'CORE' | 'INFO' | 'WARN' | 'ERROR' | 'SUCC' | 'DEBUG' | 'VERBOSE' | otherstring;\n\ninterface LogEntry {\n  timestamp: string;\n  level: LogLevel;\n  [key: string]: unknown;\n}\n\nexport type LoggerOption = 'one-line' | 'json-line' | FluxionLoggerFn;\n\nexport type FluxionLoggerFn = (entry: LogEntry) => void;\n\nexport interface MessageObject {\n  [key: string]: unknown;\n  message?: string;\n}\n\nexport interface FluxionLogger {\n  /**\n   * [WARN] We assert that `fields` is an object or undefined.\n   */\n  write(level: LogLevel, messageOrObject: string | MessageObject): void;\n  info(messageOrObject: string | MessageObject): void;\n  warn(messageOrObject: string | MessageObject): void;\n  error(messageOrObject: string | MessageObject): void;\n  succ(messageOrObject: string | MessageObject): void;\n  debug(messageOrObject: string | MessageObject): void;\n  verbose(messageOrObject: string | MessageObject): void;\n}\n\n/**\n * Internal-only logger used by fluxion's own subsystems (router, injector,\n * ...). It extends the public {@link FluxionLogger}\n * with a `core` level that records framework-originated logs — e.g. route\n * registration, module lifecycle — so they are visually distinct\n * from logs emitted by user handlers.\n *\n * ! This type is NOT exported to application code: {@link FluxionModuleContext}\n * exposes only {@link FluxionLogger}, keeping\n * `core` off-limits to user handlers.\n */\nexport interface InternalFluxionLogger extends FluxionLogger {\n  core(messageOrObject: string | MessageObject): void;\n}\n\nconst safeStringify = (value: unknown): string => {\n  try {\n    return stringify(value);\n  } catch {\n    return '[unserializable]';\n  }\n};\n\nconst ColoredLevels: Record<LogLevel, string> = {\n  CORE: `${cctl.brightBlack}CORE${cctl.reset}`,\n  INFO: `${cctl.cyan}INFO${cctl.reset}`,\n  WARN: `${cctl.orange}WARN${cctl.reset}`,\n  ERROR: `${cctl.red}ERROR${cctl.reset}`,\n  SUCC: `${cctl.green}SUCC${cctl.reset}`,\n  DEBUG: `${cctl.blue}DEBUG${cctl.reset}`,\n  VERBOSE: `${cctl.purple}VERBOSE${cctl.reset}`,\n};\n\nexport const oneLineLogger: FluxionLoggerFn = (entry: LogEntry) => {\n  const { level: rawLevel, timestamp: rawTimestamp, message: rawMessage, pid, ...fields } = entry;\n\n  const timestamp = `${cctl.darkGreen}[${rawTimestamp}]${cctl.reset}`;\n  const level = ColoredLevels[rawLevel] ?? rawLevel;\n  const pidText = pid === undefined ? '' : ` [${pid}]`;\n  const fieldsText = Object.keys(fields).length > 0 ? ` ${cctl.dim}${safeStringify(fields)}${cctl.reset}` : '';\n\n  // 智能处理消息内容：如果有 message 字段就显示，否则只显示 fields\n  const content = rawMessage ? rawMessage + fieldsText : fieldsText.trim();\n\n  // eslint-disable-next-line @typescript-eslint/no-console\n  console.log(`${timestamp} ${level}${pidText} ${content}`);\n};\n\n/**\n * 创建文件日志写入器\n */\nfunction createFileSink(logFilePath: string): (entry: LogEntry) => void {\n  // 确保日志目录存在\n  if (!existsSync(logFilePath)) {\n    const dir = dirname(logFilePath);\n    if (!existsSync(dir)) {\n      mkdirSync(dir, { recursive: true });\n    }\n  }\n\n  const fileStream = createWriteStream(logFilePath, { flags: 'a' });\n\n  return (entry: LogEntry) => {\n    try {\n      const timestamp = entry.timestamp || new Date().toISOString();\n      const level = entry.level || 'INFO';\n      const pid = entry.pid !== undefined ? ` [${entry.pid}]` : '';\n      const message = entry.message ? entry.message : safeStringify(entry);\n\n      fileStream.write(`[${timestamp}] ${level}${pid} ${message}\\n`);\n    } catch {\n      // 忽略文件写入错误\n    }\n  };\n}\n\n/**\n * & Logger Options here is checked by normalizeOptions function.\n */\nfunction resolveLoggerSink(cx: Pick<FluxionContext, 'options'>): FluxionLoggerFn {\n  // 检查是否设置了 FLUXION_INSTANCE_LOG 环境变量\n  const instanceLogPath = process.env.FLUXION_INSTANCE_LOG;\n  const fileSink = instanceLogPath ? createFileSink(instanceLogPath) : null;\n\n  const loggerOption = cx.options.logger;\n  if (loggerOption === undefined || loggerOption === 'one-line') {\n    if (fileSink) {\n      // 同时输出到控制台和文件\n      return (entry: LogEntry) => {\n        oneLineLogger(entry);\n        fileSink(entry);\n      };\n    }\n    return oneLineLogger;\n  }\n\n  if (loggerOption === 'json-line') {\n    // eslint-disable-next-line @typescript-eslint/no-console\n    const jsonSink = (entry: LogEntry) => console.log(safeStringify(entry));\n    if (fileSink) {\n      return (entry: LogEntry) => {\n        jsonSink(entry);\n        fileSink(entry);\n      };\n    }\n    return jsonSink;\n  }\n\n  if (fileSink) {\n    // 自定义 logger + 文件输出\n    return (entry: LogEntry) => {\n      loggerOption(entry);\n      fileSink(entry);\n    };\n  }\n\n  return loggerOption;\n}\n\nexport function createLogger(cx: Pick<FluxionContext, 'options'>): InternalFluxionLogger {\n  const sink = resolveLoggerSink(cx);\n\n  const logger: InternalFluxionLogger = {\n    write(level: LogLevel, o: string | object): void {\n      const entry: LogEntry =\n        typeof o === 'string'\n          ? {\n              message: o,\n              timestamp: new Date().toISOString(),\n              level,\n            }\n          : {\n              ...o,\n              timestamp: new Date().toISOString(),\n              level,\n            };\n\n      try {\n        sink(entry);\n      } catch {\n        // Ignore logger sink failures to avoid breaking request handling.\n      }\n    },\n    info(messageOrObject: string | MessageObject): void {\n      this.write('INFO', messageOrObject);\n    },\n    warn(messageOrObject: string | MessageObject): void {\n      this.write('WARN', messageOrObject);\n    },\n    error(messageOrObject: string | MessageObject): void {\n      this.write('ERROR', messageOrObject);\n    },\n    succ(messageOrObject: string | MessageObject): void {\n      this.write('SUCC', messageOrObject);\n    },\n    debug(messageOrObject: string | MessageObject): void {\n      this.write('DEBUG', messageOrObject);\n    },\n    verbose(messageOrObject: string | MessageObject): void {\n      this.write('VERBOSE', messageOrObject);\n    },\n    core(messageOrObject: string | MessageObject): void {\n      this.write('CORE', messageOrObject);\n    },\n  };\n\n  return logger;\n}\n\n/**\n * Create a worker logger that prefixes all log messages with the worker PID.\n */\nexport function createWorkerLogger(baseLogger: FluxionLogger, pid: number): InternalFluxionLogger {\n  return {\n    write(level: LogLevel, messageOrObject: string | MessageObject): void {\n      baseLogger.write(\n        level,\n        typeof messageOrObject === 'string' ? { message: messageOrObject, pid } : { ...messageOrObject, pid },\n      );\n    },\n    info(messageOrObject: string | MessageObject): void {\n      this.write('INFO', messageOrObject);\n    },\n    warn(messageOrObject: string | MessageObject): void {\n      this.write('WARN', messageOrObject);\n    },\n    error(messageOrObject: string | MessageObject): void {\n      this.write('ERROR', messageOrObject);\n    },\n    succ(messageOrObject: string | MessageObject): void {\n      this.write('SUCC', messageOrObject);\n    },\n    debug(messageOrObject: string | MessageObject): void {\n      this.write('DEBUG', messageOrObject);\n    },\n    verbose(messageOrObject: string | MessageObject): void {\n      this.write('VERBOSE', messageOrObject);\n    },\n    core(messageOrObject: string | MessageObject): void {\n      this.write('CORE', messageOrObject);\n    },\n  };\n}\n\n/**\n * ! Error.isError needs Node.js 24\n */\nexport const getErrorMessage =\n  typeof Error.isError === 'function'\n    ? (e: unknown): string => (Error.isError(e) ? e.message : String(e))\n    : (e: unknown): string => (e as any)?.message || String(e);\n","export const DUMMY_BASE_URL = 'http://fluxion.local';\nexport const META_PREFIX = '/_fluxion';\n\nexport const OPTIONS_NORMALIZED_FLAG = Symbol('fluxion.options.normalized');\nexport const STATIC_HANDLED_FLAG = Symbol('fluxion.router.StaticHandled');\nexport const HANDLER_TIMEOUT_FLAG = Symbol('fluxion.handlerTimeout');\nexport const MIDDLEWARE_TIMEOUT_FLAG = Symbol('fluxion.middlewareTimeout');\n\nexport const STATIC_CONTENT_TYPES: Record<string, string> = {\n  '.css': 'text/css; charset=utf-8',\n  '.html': 'text/html; charset=utf-8',\n  '.ico': 'image/x-icon',\n  '.js': 'text/javascript; charset=utf-8',\n  '.json': 'application/json; charset=utf-8',\n  '.map': 'application/json; charset=utf-8',\n  '.png': 'image/png',\n  '.jpg': 'image/jpeg',\n  '.jpeg': 'image/jpeg',\n  '.svg': 'image/svg+xml',\n  '.txt': 'text/plain; charset=utf-8',\n  '.webp': 'image/webp',\n};\n\nexport enum HttpCode {\n  // 2xx Success\n  Ok = 200,\n  Created = 201,\n  Accepted = 202,\n  NoContent = 204,\n  PartialContent = 206,\n\n  // 3xx Redirection\n  MovedPermanently = 301,\n  Found = 302,\n  NotModified = 304,\n  TemporaryRedirect = 307,\n  PermanentRedirect = 308,\n\n  // 4xx Client Error\n  BadRequest = 400,\n  Unauthorized = 401,\n  Forbidden = 403,\n  NotFound = 404,\n  MethodNotAllowed = 405,\n  NotAcceptable = 406,\n  RequestTimeout = 408,\n  Conflict = 409,\n  Gone = 410,\n  PayloadTooLarge = 413,\n  UnsupportedMediaType = 415,\n  UnprocessableEntity = 422,\n  TooManyRequests = 429,\n\n  // 5xx Server Error\n  InternalServerError = 500,\n  NotImplemented = 501,\n  BadGateway = 502,\n  ServiceUnavailable = 503,\n  GatewayTimeout = 504,\n}\n\nexport const enum HandlerResult {\n  NotFound,\n  Handled,\n}\n\nexport const enum FluxionModuleType {\n  Api,\n  StaticResource,\n}\n\nexport const noop = () => {};\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { FluxionOptions, NormalizedFluxionOptions } from '../types.js';\nimport { OPTIONS_NORMALIZED_FLAG } from '@/common/consts.js';\n\n/**\n * Read certificate content from a file path or return the content directly.\n */\nfunction readCertificateContent(content: string | Buffer, moduleDir: string): Buffer {\n  if (Buffer.isBuffer(content)) {\n    return content;\n  }\n  if (typeof content === 'string') {\n    // Check if it looks like a file path (not a PEM certificate)\n    // PEM certificates start with \"-----BEGIN\"\n    if (!content.startsWith('-----BEGIN')) {\n      const filePath = path.isAbsolute(content) ? content : path.join(moduleDir, content);\n      if (fs.existsSync(filePath)) {\n        return fs.readFileSync(filePath);\n      }\n    }\n    return Buffer.from(content);\n  }\n  _throw('Certificate content must be a string or Buffer');\n}\n\n/**\n * Normalize HTTPS options.\n */\nfunction normalizeHttpsOptions(\n  https: FluxionOptions['https'],\n  moduleDir: string,\n): NormalizedFluxionOptions['https'] | undefined {\n  if (!https) {\n    return undefined;\n  }\n\n  if (typeof https !== 'object' || https === null || Array.isArray(https)) {\n    _throw('FluxionOptions.https must be an object');\n  }\n  if (typeof https.key !== 'string' && !Buffer.isBuffer(https.key)) {\n    _throw('FluxionOptions.https.key must be a string or Buffer');\n  }\n  if (typeof https.cert !== 'string' && !Buffer.isBuffer(https.cert)) {\n    _throw('FluxionOptions.https.cert must be a string or Buffer');\n  }\n\n  const result: NormalizedFluxionOptions['https'] = {\n    key: readCertificateContent(https.key, moduleDir),\n    cert: readCertificateContent(https.cert, moduleDir),\n  };\n\n  if (https.ca !== undefined) {\n    if (Array.isArray(https.ca)) {\n      result.ca = https.ca.map((item) => readCertificateContent(item, moduleDir));\n    } else {\n      result.ca = readCertificateContent(https.ca, moduleDir);\n    }\n  }\n\n  return result;\n}\n\n/**\n * Normalize options and create necessary resources like the dynamic directory and logger.\n */\nexport function defineFluxionOptions(o: FluxionOptions): NormalizedFluxionOptions {\n  if (typeof o !== 'object' || o === null || Array.isArray(o)) {\n    _throw('FluxionOptions must be an object');\n  }\n\n  // Check for deprecated 'include' option\n  if ('include' in o) {\n    _throw(\n      'The \"include\" option has been removed. Please use:\\n' +\n        '  - \"apiInclude\" for API handler patterns (default: [\"**/*.ts\"])\\n' +\n        '  - \"staticInclude\" for static resource patterns (default: [\"**/*\"])\\n' +\n        'Example migration:\\n' +\n        '  OLD: { include: [\"**/*.ts\", \"**/*.js\"], apiInclude: [\"**/*.ts\"] }\\n' +\n        '  NEW: { apiInclude: [\"**/*.ts\"], staticInclude: [\"**/*.js\"] }',\n    );\n  }\n\n  const {\n    dir: rawDir,\n    host,\n    port: userPort,\n    handlerTimeoutMs = 5000,\n    middlewareTimeoutMs = 3000,\n    staticResourceTimeoutMs = 3 * 60 * 1000,\n    shutdownTimeoutMs = 3000,\n    moduleDir: rawModuleDir = process.cwd(),\n    maxRequestBytes = 8_000_000,\n    apiInclude = ['**/*.ts'],\n    staticInclude = ['**/*'],\n    exclude = [\n      '**/node_modules/**',\n      '**/.git/**',\n      '**/dist/**',\n      '**/build/**',\n      '**/.vscode/**',\n      '**/.idea/**',\n      '**/*.log',\n      '**/.DS_Store',\n      '**/coverage/**',\n      '**/.nyc_output/**',\n      '**/*.tmp',\n      '**/*.temp',\n    ],\n    https,\n    metaApis = ['healthz', 'version', 'stats'],\n    metaSecret = o.metaSecret ?? process.env.FLUXION_META_SECRET,\n    csp = \"default-src 'self'\",\n  } = o as FluxionOptions;\n\n  const port = userPort;\n\n  const logger = o.logger ?? 'one-line';\n  if (logger !== 'one-line' && logger !== 'json-line' && typeof logger !== 'function') {\n    _throw(`Invalid logger option, Must be 'one-line', 'json-line' or a custom logger function`);\n  }\n\n  if (typeof rawDir !== 'string') {\n    _throw('FluxionOptions.dir must be a string');\n  }\n  const dir = path.resolve(process.cwd(), rawDir);\n\n  if (typeof rawModuleDir !== 'string') {\n    _throw('FluxionOptions.moduleDir must be a string');\n  }\n  const moduleDir = path.resolve(rawModuleDir);\n\n  if (typeof host !== 'string') {\n    _throw('FluxionOptions.host must be a string');\n  }\n\n  if (!Number.isSafeInteger(handlerTimeoutMs) || handlerTimeoutMs <= 100) {\n    _throw('FluxionOptions.handlerTimeoutMs must be an integer greater than 100');\n  }\n\n  if (!Number.isSafeInteger(middlewareTimeoutMs) || middlewareTimeoutMs <= 100) {\n    _throw('FluxionOptions.middlewareTimeoutMs must be an integer greater than 100');\n  }\n\n  if (!Number.isSafeInteger(shutdownTimeoutMs) || shutdownTimeoutMs <= 100) {\n    _throw('FluxionOptions.shutdownTimeoutMs must be an integer greater than 100');\n  }\n\n  if (typeof port !== 'number' || !Number.isSafeInteger(port)) {\n    _throw('FluxionOptions.port must be a positive integer');\n  }\n\n  if (port <= 1 || port > 65535) {\n    _throw('FluxionOptions.port must be 1 ~ 65535');\n  }\n\n  if (typeof maxRequestBytes !== 'number' || maxRequestBytes <= 0 || !Number.isSafeInteger(maxRequestBytes)) {\n    _throw('FluxionOptions.maxRequestBytes must be a positive integer');\n  }\n\n  if (!Array.isArray(metaApis) || metaApis.some((v) => !['healthz', 'version', 'stats', 'config'].includes(v))) {\n    _throw(`FluxionOptions.metaApis must be an array containing only 'healthz', 'version', 'stats', 'config'`);\n  }\n\n  if (\n    metaSecret !== undefined &&\n    (typeof metaSecret !== 'string' ||\n      metaSecret.length < 20 ||\n      /\\s/.test(metaSecret) ||\n      !/[A-Za-z]/.test(metaSecret) ||\n      !/\\d/.test(metaSecret))\n  ) {\n    _throw(\n      'FluxionOptions.metaSecret must be a string with at least 20 characters, include both letters and digits, and contain no whitespace',\n    );\n  }\n\n  if (!fs.existsSync(dir)) {\n    fs.mkdirSync(dir, { recursive: true });\n  }\n\n  return {\n    dir,\n    host,\n    port,\n    handlerTimeoutMs,\n    middlewareTimeoutMs,\n    staticResourceTimeoutMs,\n    shutdownTimeoutMs,\n    moduleDir,\n    maxRequestBytes,\n    logger,\n    apiInclude,\n    staticInclude,\n    exclude,\n    metaApis,\n    metaSecret,\n    csp,\n    https: normalizeHttpsOptions(https, moduleDir),\n    normalizedFlag: OPTIONS_NORMALIZED_FLAG,\n  };\n}\n","/**\n * For low version of Node.js that does not support `Promise.try`, we can implement it ourselves.\n *\n * Only for async functions.\n */\nexport function PromiseTry<T extends (...args: any[]) => any>(fn: T, ...args: Parameters<T>) {\n  return new Promise<ReturnType<T>>((resolve, reject) => {\n    // in case `fn` throws synchronously, we catch it and reject the promise\n    try {\n      const r = fn(...args);\n      if (r instanceof Promise) {\n        r.then(resolve).catch(reject);\n      } else {\n        resolve(r);\n      }\n    } catch (error) {\n      reject(error);\n    }\n  });\n}\n","import type { IncomingMessage } from 'node:http';\n\nexport function getRealIp(req: IncomingMessage): string {\n  const forwardedFor = req.headersDistinct['x-forwarded-for'];\n  if (forwardedFor) {\n    const firstForwarded = forwardedFor[0]?.split(',')[0]?.trim();\n    if (firstForwarded && firstForwarded.length > 0) {\n      return firstForwarded;\n    }\n  }\n\n  const realIp = req.headersDistinct['x-real-ip']?.[0].trim();\n  if (realIp !== undefined) {\n    return realIp;\n  }\n\n  return req.socket.remoteAddress ?? 'unknown';\n}\n\nexport function isTextualContentType(contentType: string | undefined): boolean {\n  if (contentType === undefined) {\n    return false;\n  }\n\n  const normalized = contentType.toLowerCase();\n\n  return (\n    normalized.startsWith('text/') ||\n    normalized.includes('json') ||\n    normalized.includes('xml') ||\n    normalized.includes('x-www-form-urlencoded') ||\n    normalized.includes('javascript')\n  );\n}\n","import { DUMMY_BASE_URL } from '@/common/consts.js';\n\nexport function toURL(rawUrl: string | undefined): URL | undefined {\n  if (rawUrl === undefined) {\n    return undefined;\n  }\n\n  try {\n    return new URL(rawUrl, DUMMY_BASE_URL);\n  } catch {\n    return undefined;\n  }\n}\n","import type { ServerResponse } from 'node:http';\nimport { HttpCode } from '@/common/consts.js';\n\nexport function sendJson(res: ServerResponse, payload: unknown, statusCode: HttpCode = HttpCode.Ok): void {\n  res.statusCode = statusCode;\n  res.setHeader('Content-Type', 'application/json; charset=utf-8');\n  res.end(JSON.stringify(payload));\n}\n\nexport function safeSendJson(res: ServerResponse, payload: unknown, statusCode: HttpCode = HttpCode.Ok): void {\n  if (res.writableEnded) {\n    return;\n  }\n\n  if (res.headersSent) {\n    res.end();\n    return;\n  }\n\n  sendJson(res, payload, statusCode);\n}\n","export function parseQuery(searchParams: URLSearchParams): Record<string, string | string[]> {\n  const query: Record<string, string | string[]> = {};\n\n  for (const [key, value] of searchParams.entries()) {\n    const existing = query[key];\n\n    if (existing === undefined) {\n      query[key] = value;\n      continue;\n    }\n\n    if (Array.isArray(existing)) {\n      existing.push(value);\n      continue;\n    }\n\n    query[key] = [existing, value];\n  }\n\n  return query;\n}\n","import { HttpCode } from '@/common/consts.js';\n\n/**\n * Base class for all HTTP exceptions\n */\nexport abstract class HttpException extends Error implements NodeJS.ErrnoException {\n  errno?: number | undefined;\n  code?: string | undefined;\n\n  constructor(message: string, statusCode: HttpCode, code: string) {\n    super(message);\n    this.name = 'HttpException';\n    this.errno = statusCode;\n    this.code = code;\n  }\n}\n\n// 4xx Client Error Exceptions\n\n/**\n * 400 Bad Request - Malformed or invalid request\n */\nexport class BadRequestException extends HttpException {\n  constructor(message: string = 'Bad Request') {\n    super(message, HttpCode.BadRequest, 'BAD_REQUEST');\n  }\n}\n\n/**\n * 401 Unauthorized - Authentication required or failed\n */\nexport class UnauthorizedException extends HttpException {\n  constructor(message: string = 'Unauthorized') {\n    super(message, HttpCode.Unauthorized, 'UNAUTHORIZED');\n  }\n}\n\n/**\n * 403 Forbidden - Valid request but refused authorization\n */\nexport class ForbiddenException extends HttpException {\n  constructor(message: string = 'Forbidden') {\n    super(message, HttpCode.Forbidden, 'FORBIDDEN');\n  }\n}\n\n/**\n * 404 Not Found - Resource does not exist\n */\nexport class NotFoundException extends HttpException {\n  constructor(message: string = 'Not Found') {\n    super(message, HttpCode.NotFound, 'NOT_FOUND');\n  }\n}\n\n/**\n * 405 Method Not Allowed - HTTP method not supported for resource\n */\nexport class MethodNotAllowedException extends HttpException {\n  constructor(message: string = 'Method Not Allowed') {\n    super(message, HttpCode.MethodNotAllowed, 'METHOD_NOT_ALLOWED');\n  }\n}\n\n/**\n * 406 Not Acceptable - Cannot generate acceptable response\n */\nexport class NotAcceptableException extends HttpException {\n  constructor(message: string = 'Not Acceptable') {\n    super(message, HttpCode.NotAcceptable, 'NOT_ACCEPTABLE');\n  }\n}\n\n/**\n * 408 Request Timeout - Client did not produce request within time\n */\nexport class RequestTimeoutException extends HttpException {\n  constructor(message: string = 'Request Timeout') {\n    super(message, HttpCode.RequestTimeout, 'REQUEST_TIMEOUT');\n  }\n}\n\n/**\n * 409 Conflict - Request conflicts with current state\n */\nexport class ConflictException extends HttpException {\n  constructor(message: string = 'Conflict') {\n    super(message, HttpCode.Conflict, 'CONFLICT');\n  }\n}\n\n/**\n * 410 Gone - Resource no longer available\n */\nexport class GoneException extends HttpException {\n  constructor(message: string = 'Gone') {\n    super(message, HttpCode.Gone, 'GONE');\n  }\n}\n\n/**\n * 413 Payload Too Large - Request entity larger than limits\n */\nexport class PayloadTooLargeException extends HttpException {\n  constructor(message: string = 'Payload Too Large') {\n    super(message, HttpCode.PayloadTooLarge, 'PAYLOAD_TOO_LARGE');\n  }\n}\n\n/**\n * 415 Unsupported Media Type - Requested format not supported\n */\nexport class UnsupportedMediaTypeException extends HttpException {\n  constructor(message: string = 'Unsupported Media Type') {\n    super(message, HttpCode.UnsupportedMediaType, 'UNSUPPORTED_MEDIA_TYPE');\n  }\n}\n\n/**\n * 422 Unprocessable Entity - Syntactically correct but semantically erroneous\n */\nexport class UnprocessableEntityException extends HttpException {\n  constructor(message: string = 'Unprocessable Entity') {\n    super(message, HttpCode.UnprocessableEntity, 'UNPROCESSABLE_ENTITY');\n  }\n}\n\n/**\n * 429 Too Many Requests - Rate limit exceeded\n */\nexport class TooManyRequestsException extends HttpException {\n  constructor(message: string = 'Too Many Requests') {\n    super(message, HttpCode.TooManyRequests, 'TOO_MANY_REQUESTS');\n  }\n}\n\n// 5xx Server Error Exceptions\n\n/**\n * 500 Internal Server Error - Unexpected server condition\n */\nexport class InternalServerErrorException extends HttpException {\n  constructor(message: string = 'Internal Server Error') {\n    super(message, HttpCode.InternalServerError, 'INTERNAL_SERVER_ERROR');\n  }\n}\n\n/**\n * 501 Not Implemented - Server does not support functionality\n */\nexport class NotImplementedException extends HttpException {\n  constructor(message: string = 'Not Implemented') {\n    super(message, HttpCode.NotImplemented, 'NOT_IMPLEMENTED');\n  }\n}\n\n/**\n * 502 Bad Gateway - Invalid response from upstream server\n */\nexport class BadGatewayException extends HttpException {\n  constructor(message: string = 'Bad Gateway') {\n    super(message, HttpCode.BadGateway, 'BAD_GATEWAY');\n  }\n}\n\n/**\n * 503 Service Unavailable - Server temporarily unavailable\n */\nexport class ServiceUnavailableException extends HttpException {\n  constructor(message: string = 'Service Unavailable') {\n    super(message, HttpCode.ServiceUnavailable, 'SERVICE_UNAVAILABLE');\n  }\n}\n\n/**\n * 504 Gateway Timeout - Upstream server timeout\n */\nexport class GatewayTimeoutException extends HttpException {\n  constructor(message: string = 'Gateway Timeout') {\n    super(message, HttpCode.GatewayTimeout, 'GATEWAY_TIMEOUT');\n  }\n}\n","import type http from 'node:http';\n\nimport { isTextualContentType } from './headers.js';\nimport { parseQuery } from './query.js';\nimport { PayloadTooLargeException } from './exceptions.js';\n\nexport interface BodyPreview {\n  exists: boolean;\n  value?: string;\n  bytes: number;\n  truncated: boolean;\n}\n\nfunction createPayloadTooLargeException(receivedBytes: number, maxBytes: number): PayloadTooLargeException {\n  return new PayloadTooLargeException(\n    `request body too large: ${receivedBytes.toString()} bytes exceeds ${maxBytes.toString()} bytes`,\n  );\n}\n\nfunction getHeaderValue(headerValue: string | string[] | undefined): string | undefined {\n  return Array.isArray(headerValue) ? headerValue[0] : headerValue;\n}\n\nfunction createEmptyPreview(): BodyPreview {\n  return {\n    exists: false,\n    bytes: 0,\n    truncated: false,\n  };\n}\n\nfunction createPreview(\n  previewBuffer: Buffer,\n  totalBytes: number,\n  contentType: string | undefined,\n  truncated: boolean,\n): BodyPreview {\n  if (totalBytes === 0) {\n    return createEmptyPreview();\n  }\n\n  if (isTextualContentType(contentType)) {\n    return {\n      exists: true,\n      value: previewBuffer.toString('utf8'),\n      bytes: totalBytes,\n      truncated,\n    };\n  }\n\n  return {\n    exists: true,\n    value: `<binary body: ${totalBytes} bytes>`,\n    bytes: totalBytes,\n    truncated,\n  };\n}\n\nasync function readRequestBodyWithPreview(\n  req: http.IncomingMessage,\n  method: string,\n  maxBytes: number,\n  previewMaxBytes = 8192,\n): Promise<{ rawBody: Buffer | undefined; preview: BodyPreview }> {\n  if (method === 'GET' || method === 'HEAD') {\n    return {\n      rawBody: undefined,\n      preview: createEmptyPreview(),\n    };\n  }\n\n  if (req.readableEnded) {\n    return {\n      rawBody: undefined,\n      preview: createEmptyPreview(),\n    };\n  }\n\n  const contentLengthRaw = getHeaderValue(req.headers['content-length']);\n  const declaredBytes = contentLengthRaw !== undefined ? Number.parseInt(contentLengthRaw, 10) : NaN;\n\n  return new Promise((resolve, reject) => {\n    const rawBodyChunks: Buffer[] = [];\n    const previewChunks: Buffer[] = [];\n    let totalBytes = 0;\n    let previewBytes = 0;\n    let previewTruncated = false;\n    let settled = false;\n\n    const cleanup = (): void => {\n      req.off('data', onData);\n      req.off('end', onEnd);\n      req.off('error', onError);\n      req.off('aborted', onAborted);\n    };\n\n    const settle = (action: () => void): void => {\n      if (settled) {\n        return;\n      }\n\n      settled = true;\n      action();\n    };\n\n    // Check content-length upfront, but still drain the request\n    if (Number.isFinite(declaredBytes) && declaredBytes > maxBytes) {\n      cleanup();\n      req.resume();\n      settle(() => reject(createPayloadTooLargeException(declaredBytes, maxBytes)));\n      return;\n    }\n\n    const onData = (chunk: Buffer | string | Uint8Array): void => {\n      const bufferChunk = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n      totalBytes += bufferChunk.byteLength;\n\n      if (totalBytes > maxBytes) {\n        cleanup();\n        req.resume();\n        settle(() => reject(createPayloadTooLargeException(totalBytes, maxBytes)));\n        return;\n      }\n\n      rawBodyChunks.push(bufferChunk);\n\n      if (previewBytes < previewMaxBytes) {\n        const remaining = previewMaxBytes - previewBytes;\n        const nextSlice = bufferChunk.subarray(0, remaining);\n        previewChunks.push(nextSlice);\n        previewBytes += nextSlice.length;\n\n        if (nextSlice.length < bufferChunk.length) {\n          previewTruncated = true;\n        }\n      } else {\n        previewTruncated = true;\n      }\n    };\n\n    const onEnd = (): void => {\n      cleanup();\n      settle(() => {\n        const rawBody = rawBodyChunks.length > 0 ? Buffer.concat(rawBodyChunks) : undefined;\n        const previewBuffer = previewChunks.length > 0 ? Buffer.concat(previewChunks) : Buffer.alloc(0);\n\n        resolve({\n          rawBody,\n          preview: createPreview(\n            previewBuffer,\n            rawBody?.byteLength ?? 0,\n            getHeaderValue(req.headers['content-type']),\n            previewTruncated,\n          ),\n        });\n      });\n    };\n\n    const onError = (error: Error): void => {\n      cleanup();\n      settle(() => reject(error));\n    };\n\n    const onAborted = (): void => {\n      cleanup();\n      settle(() => reject(new Error('request aborted while reading body')));\n    };\n\n    req.on('data', onData);\n    req.once('end', onEnd);\n    req.once('error', onError);\n    req.once('aborted', onAborted);\n  });\n}\n\nexport async function parseBody(\n  req: http.IncomingMessage,\n  method: string,\n  maxBytes: number,\n): Promise<{ body: Record<string, any>; preview: BodyPreview }> {\n  const { rawBody, preview } = await readRequestBodyWithPreview(req, method, maxBytes);\n\n  if (rawBody === undefined || rawBody.byteLength === 0) {\n    return {\n      body: {},\n      preview,\n    };\n  }\n\n  const contentType = getHeaderValue(req.headers['content-type'])?.toLowerCase() ?? '';\n\n  if (contentType.includes('json')) {\n    const textBody = rawBody.toString('utf8').trim();\n\n    if (textBody.length === 0) {\n      return {\n        body: {},\n        preview,\n      };\n    }\n\n    try {\n      const parsed = JSON.parse(textBody) as unknown;\n\n      if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {\n        return {\n          body: parsed as Record<string, any>,\n          preview,\n        };\n      }\n\n      return {\n        body: { value: parsed },\n        preview,\n      };\n    } catch {\n      return {\n        body: { raw: textBody },\n        preview,\n      };\n    }\n  }\n\n  if (contentType.includes('x-www-form-urlencoded')) {\n    return {\n      body: parseQuery(new URLSearchParams(rawBody.toString('utf8'))),\n      preview,\n    };\n  }\n\n  if (isTextualContentType(contentType)) {\n    return {\n      body: { raw: rawBody.toString('utf8') },\n      preview,\n    };\n  }\n\n  return {\n    body: {},\n    preview,\n  };\n}\n","/**\n * Parse Cookie header string into an object\n */\nexport function parseCookie(cookieHeader: string | undefined): Record<string, string> {\n  if (!cookieHeader) {\n    return {};\n  }\n\n  const cookies: Record<string, string> = {};\n  const pairs = cookieHeader.split(';');\n  let count = 0;\n  const MAX_COOKIE_KEYS = 100;\n\n  for (const pair of pairs) {\n    if (count >= MAX_COOKIE_KEYS) {\n      break;\n    }\n    const [key, ...valueParts] = pair.split('=');\n    if (!key) continue;\n\n    const trimmedKey = key.trim();\n    const value = valueParts.join('=').trim();\n    cookies[trimmedKey] = decodeURIComponent(value);\n    count++;\n  }\n\n  return cookies;\n}\n\n/**\n * Serialize an object into a Cookie header string\n */\nexport function serializeCookie(\n  name: string,\n  value: string,\n  options?: {\n    maxAge?: number;\n    expires?: Date;\n    domain?: string;\n    path?: string;\n    secure?: boolean;\n    httpOnly?: boolean;\n    sameSite?: 'strict' | 'lax' | 'none';\n  },\n): string {\n  let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;\n\n  if (options) {\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.domain) {\n      cookie += `; Domain=${options.domain}`;\n    }\n    if (options.path) {\n      cookie += `; Path=${options.path}`;\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\n  return cookie;\n}\n","import http from 'node:http';\nimport https from 'node:https';\n\nimport type { FluxionContext, FluxionModuleContext, FluxionRequest } from '../types.js';\nimport {\n  HttpCode,\n  HANDLER_TIMEOUT_FLAG,\n  META_PREFIX,\n  STATIC_HANDLED_FLAG,\n  FluxionModuleType,\n  MIDDLEWARE_TIMEOUT_FLAG,\n} from '@/common/consts.js';\nimport { PromiseTry } from '@/common/promise-try.js';\nimport { getErrorMessage } from '@/common/logger.js';\n\nimport { getRealIp } from './headers.js';\nimport { toURL } from './request.js';\nimport { safeSendJson } from './respond.js';\nimport { parseBody, type BodyPreview } from './body.js';\nimport { parseQuery } from './query.js';\nimport { parseCookie } from './cookie.js';\nimport { HttpException } from './exceptions.js';\n\nconst waiter = (mainPromise: Promise<any>, timeoutMs: number, flag: symbol) =>\n  Promise.race([mainPromise, new Promise((r) => setTimeout(() => r(flag), timeoutMs))]);\n\nexport function createServer(cx: FluxionContext): Promise<http.Server | https.Server> {\n  const moduleCx: FluxionModuleContext = Object.freeze({ logger: cx.logger });\n\n  const requestHandler = async (req: http.IncomingMessage, res: http.ServerResponse) => {\n    const method = req.method ?? 'GET';\n    const ip = getRealIp(req);\n    const url = toURL(req.url);\n    if (url === undefined) {\n      safeSendJson(res, { message: 'Bad Request: req.url is undefined' }, HttpCode.BadRequest);\n      return;\n    }\n\n    const normalized: FluxionRequest = {\n      method,\n      ip,\n      url,\n      query: parseQuery(url.searchParams),\n      body: {},\n      headers: req.headers,\n      cookie: parseCookie(req.headers.cookie as string | undefined),\n      meta: {},\n    };\n\n    // Security headers for all responses\n    res.setHeader('X-Content-Type-Options', 'nosniff');\n    res.setHeader('X-Frame-Options', 'DENY');\n    res.setHeader('X-XSS-Protection', '1; mode=block');\n    // Content-Security-Policy (user-configurable, disabled when set to false)\n    if (cx.options.csp !== false) {\n      res.setHeader('Content-Security-Policy', cx.options.csp);\n    }\n\n    let bodyPreview: BodyPreview = {\n      exists: false,\n      bytes: 0,\n      truncated: false,\n    };\n\n    cx.logger.core({ message: 'request', method, ip, path: url.pathname });\n\n    const start = performance.now();\n    res.once('finish', () => {\n      const o: Record<string, unknown> = {\n        message: 'response',\n        method,\n        ip,\n        path: url.pathname,\n        status: res.statusCode,\n        duration: (performance.now() - start).toFixed(4),\n      };\n\n      if (Object.keys(normalized.query).length > 0) {\n        o.query = normalized.query;\n      }\n\n      if (bodyPreview.exists) {\n        o.body = bodyPreview.value;\n        o.bodyBytes = bodyPreview.bytes;\n        o.bodyTruncated = bodyPreview.truncated;\n      }\n\n      cx.logger.core(o);\n    });\n\n    // * Start request handling\n    try {\n      // Handle meta API requests\n      if (normalized.url.pathname.startsWith(META_PREFIX + '/')) {\n        await handleMetaApi(cx, url, method, res);\n        return;\n      }\n\n      const parsed = await parseBody(req, normalized.method, cx.options.maxRequestBytes);\n      normalized.body = parsed.body;\n      bodyPreview = parsed.preview;\n\n      const m = await cx.router.get(url);\n      if (!m) {\n        safeSendJson(res, { message: 'Not Found' }, HttpCode.NotFound);\n        return;\n      }\n\n      if (req.method && m.methods && !m.methods.includes(req.method)) {\n        safeSendJson(res, { message: 'Method Not Allowed' }, HttpCode.MethodNotAllowed);\n        return;\n      }\n\n      const timeoutMs =\n        m.type === FluxionModuleType.Api\n          ? (m.handlerTimeoutMs ?? cx.options.handlerTimeoutMs)\n          : cx.options.staticResourceTimeoutMs;\n\n      // Middleware execution\n      if (m.middlewares) {\n        for (let i = 0; i < m.middlewares.length; i++) {\n          const result = await waiter(\n            PromiseTry(m.middlewares[i], normalized, moduleCx, req, res),\n            cx.options.middlewareTimeoutMs,\n            MIDDLEWARE_TIMEOUT_FLAG,\n          );\n\n          if (result === MIDDLEWARE_TIMEOUT_FLAG) {\n            cx.logger.warn({\n              message: 'MiddlewareTimeout',\n              method: normalized.method,\n              ip: normalized.ip,\n            });\n            safeSendJson(res, { message: 'Internal Server Error' }, HttpCode.InternalServerError);\n            return;\n          }\n          if (res.writableEnded) {\n            return;\n          }\n          if (res.headersSent) {\n            res.end();\n            return;\n          }\n        }\n      }\n\n      const result = await waiter(\n        PromiseTry(m.handler, normalized, moduleCx, req, res),\n        timeoutMs,\n        HANDLER_TIMEOUT_FLAG,\n      );\n\n      if (result === HANDLER_TIMEOUT_FLAG) {\n        cx.logger.warn({ message: 'HandlerTimeout', method: normalized.method, ip: normalized.ip });\n        safeSendJson(res, { message: 'Handler timed out' }, HttpCode.InternalServerError);\n        return;\n      }\n\n      if (result !== STATIC_HANDLED_FLAG) {\n        safeSendJson(res, result);\n      }\n    } catch (e) {\n      if (e instanceof HttpException) {\n        cx.logger.error({\n          ...normalized,\n          message: 'RequestFailed',\n          error: e.message,\n        });\n        safeSendJson(res, { message: e.message }, e.errno);\n      } else {\n        cx.logger.error({\n          ...normalized,\n          message: 'RequestFailed',\n          error: getErrorMessage(e),\n        });\n        safeSendJson(res, { message: 'Internal Server Error' }, HttpCode.InternalServerError);\n      }\n    }\n  };\n\n  const server = cx.options.https\n    ? https.createServer(\n        {\n          key: cx.options.https.key,\n          cert: cx.options.https.cert,\n          ca: cx.options.https.ca,\n        },\n        requestHandler,\n      )\n    : http.createServer(requestHandler);\n\n  return new Promise((resolve, reject) => {\n    let listening = false;\n\n    server.on('close', () => {\n      cx.logger.core({\n        message: 'ServerClosed',\n        host: cx.options.host,\n        port: cx.options.port,\n      });\n    });\n\n    server.once('listening', () => {\n      listening = true;\n      cx.logger.core({\n        message: 'FluxionStarted',\n        version: '__VERSION__',\n        pid: process.pid,\n        protocol: cx.options.https ? 'https' : 'http',\n        host: cx.options.host,\n        port: cx.options.port,\n      });\n      cx.logger.core({\n        message: 'DynamicDirectory',\n        directory: cx.options.dir,\n      });\n      resolve(server);\n    });\n\n    server.on('error', (e) => {\n      cx.logger.error({\n        message: 'ServerError',\n        error: getErrorMessage(e),\n      });\n      if (listening) {\n        // Server encountered an error after binding — log and let the\n        // caller (PM2 / user code) decide how to recover instead of\n        // forcing process.exit(1) here.\n        return;\n      }\n      reject(e);\n    });\n\n    server.listen(cx.options.port, cx.options.host);\n  });\n}\n\n/**\n * Validate meta API secret from request\n */\nfunction validateMetaSecret(url: URL, metaSecret: string | undefined): boolean {\n  if (!metaSecret) {\n    return false;\n  }\n  const providedSecret = url.searchParams.get('secret');\n  return providedSecret === metaSecret;\n}\n\n/**\n * Check if endpoint requires authentication\n */\nfunction requiresAuth(endpoint: string): boolean {\n  const protectedEndpoints = ['config'];\n  return protectedEndpoints.includes(endpoint);\n}\n\n/**\n * Handle meta API requests\n */\nasync function handleMetaApi(cx: FluxionContext, url: URL, method: string, res: http.ServerResponse): Promise<void> {\n  const pathname = url.pathname;\n\n  if (method !== 'GET') {\n    safeSendJson(res, { message: 'Method Not Allowed' }, HttpCode.MethodNotAllowed);\n    return;\n  }\n\n  const endpointName = pathname.replace(META_PREFIX + '/', '');\n\n  // Check authentication for protected endpoints\n  if (requiresAuth(endpointName)) {\n    if (!validateMetaSecret(url, cx.options.metaSecret)) {\n      safeSendJson(res, { message: 'Unauthorized' }, HttpCode.Unauthorized);\n      return;\n    }\n  }\n\n  if (pathname === META_PREFIX + '/healthz' && cx.options.metaApis.includes('healthz')) {\n    safeSendJson(res, {\n      ok: true,\n      pid: process.pid,\n      now: Date.now(),\n      uptimeSeconds: Number(process.uptime().toFixed(3)),\n    });\n    return;\n  }\n\n  if (pathname === META_PREFIX + '/version' && cx.options.metaApis.includes('version')) {\n    safeSendJson(res, {\n      ok: true,\n      version: '__VERSION__',\n    });\n    return;\n  }\n\n  if (pathname === META_PREFIX + '/stats' && cx.options.metaApis.includes('stats')) {\n    const memoryUsage = process.memoryUsage();\n    const cpuUsage = process.cpuUsage();\n    const uptime = process.uptime();\n\n    safeSendJson(res, {\n      ok: true,\n      now: Date.now(),\n      pid: process.pid,\n      uptime: {\n        seconds: Number(uptime.toFixed(3)),\n        human: formatUptime(uptime),\n      },\n      memory: {\n        rss: {\n          value: memoryUsage.rss,\n          mb: Number((memoryUsage.rss / 1024 / 1024).toFixed(2)),\n          description: 'Resident Set Size - total memory allocated',\n        },\n        heapTotal: {\n          value: memoryUsage.heapTotal,\n          mb: Number((memoryUsage.heapTotal / 1024 / 1024).toFixed(2)),\n          description: 'Total heap memory allocated',\n        },\n        heapUsed: {\n          value: memoryUsage.heapUsed,\n          mb: Number((memoryUsage.heapUsed / 1024 / 1024).toFixed(2)),\n          description: 'Heap memory currently in use',\n        },\n        external: {\n          value: memoryUsage.external,\n          mb: Number((memoryUsage.external / 1024 / 1024).toFixed(2)),\n          description: 'External memory (C++ objects, etc.)',\n        },\n        arrayBuffers: {\n          value: memoryUsage.arrayBuffers,\n          mb: Number((memoryUsage.arrayBuffers / 1024 / 1024).toFixed(2)),\n          description: 'Memory allocated for ArrayBuffers and SharedArrayBuffers',\n        },\n      },\n      cpu: {\n        user: Math.round(cpuUsage.user / 1000), // Convert microseconds to milliseconds\n        system: Math.round(cpuUsage.system / 1000),\n        description: 'CPU time used since start (milliseconds)',\n      },\n      runtime: {\n        nodeVersion: process.version,\n        platform: process.platform,\n        arch: process.arch,\n        execPath: process.execPath,\n      },\n    });\n    return;\n  }\n\n  if (pathname === META_PREFIX + '/config' && cx.options.metaApis.includes('config')) {\n    const safeConfig = {\n      dir: cx.options.dir,\n      host: cx.options.host,\n      port: cx.options.port,\n      handlerTimeoutMs: cx.options.handlerTimeoutMs,\n      middlewareTimeoutMs: cx.options.middlewareTimeoutMs,\n      staticResourceTimeoutMs: cx.options.staticResourceTimeoutMs,\n      moduleDir: cx.options.moduleDir,\n      maxRequestBytes: cx.options.maxRequestBytes,\n      apiInclude: cx.options.apiInclude,\n      staticInclude: cx.options.staticInclude,\n      exclude: cx.options.exclude,\n      metaApis: cx.options.metaApis,\n      metaSecretSet: cx.options.metaSecret !== undefined,\n      httpsEnabled: cx.options.https !== undefined,\n      csp: cx.options.csp,\n    };\n\n    safeSendJson(res, {\n      ok: true,\n      now: Date.now(),\n      config: safeConfig,\n    });\n    return;\n  }\n\n  safeSendJson(res, { message: 'Not Found' }, HttpCode.NotFound);\n}\n\n/**\n * Format uptime in human-readable format\n */\nfunction formatUptime(seconds: number): string {\n  const days = Math.floor(seconds / 86400);\n  const hours = Math.floor((seconds % 86400) / 3600);\n  const minutes = Math.floor((seconds % 3600) / 60);\n  const secs = Math.floor(seconds % 60);\n\n  const parts = [];\n  if (days > 0) {\n    parts.push(`${days}d`);\n  }\n  if (hours > 0) {\n    parts.push(`${hours}h`);\n  }\n  if (minutes > 0) {\n    parts.push(`${minutes}m`);\n  }\n  if (secs > 0 || parts.length === 0) {\n    parts.push(`${secs}s`);\n  }\n\n  return parts.join(' ');\n}\n","function n(n) {}\n\nconst t = n;\n\nfunction o() {\n  return n => {};\n}\n\nexport { o as createNarrower, n as narrow, t as static_cast };\n","import type { FluxionContext, NormalizedModule } from '@/types.js';\nimport { static_cast } from 'type-narrow';\nimport { FluxionModuleType } from './consts';\nimport { Stats } from 'node:fs';\n\nfunction isFluxionModule(cx: Pick<FluxionContext, 'options' | 'logger'>, o: unknown): o is NormalizedModule {\n  if (typeof o !== 'object' || o === null) {\n    return false;\n  }\n\n  static_cast<NormalizedModule>(o);\n\n  if (typeof o.handler !== 'function') {\n    cx.logger.error(`handler must be a function`);\n    return false;\n  }\n\n  if (o.disposer !== undefined && typeof o.disposer !== 'function') {\n    cx.logger.error(`disposer must be a function if provided`);\n    return false;\n  }\n\n  const ms = o.handlerTimeoutMs;\n  if (ms !== undefined && (!Number.isSafeInteger(ms) || ms < 100)) {\n    cx.logger.error(`handlerTimeoutMs must be an integer >= 100 if provided`);\n    return false;\n  }\n\n  if (o.type !== FluxionModuleType.Api) {\n    cx.logger.error(`You must use defineFluxionModule to create module`);\n    return false;\n  }\n\n  return true;\n}\n\nexport function loadFluxionModule(\n  cx: Pick<FluxionContext, 'options' | 'logger'>,\n  absolutePath: string,\n  stat: Stats,\n): NormalizedModule {\n  delete require.cache[absolutePath];\n  let m = require(absolutePath);\n  if (isFluxionModule(cx, m.default)) {\n    m = m.default;\n  } else if (isFluxionModule(cx, m)) {\n  } else {\n    _throw(`Invalid handler module '${absolutePath}', make sure it satisfies defineFluxionModule(...) helper`);\n  }\n\n  m.absolutePath = absolutePath;\n  m.mtimeMs = stat.mtimeMs;\n\n  return m;\n}\n","import type { FluxionContext, NormalizedModule, FluxionRouteMeta } from '../types.js';\nimport { FluxionModuleType, STATIC_CONTENT_TYPES, STATIC_HANDLED_FLAG } from '@/common/consts.js';\nimport { createReadStream, type Stats } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport abstract class FluxionRouterBase {\n  protected readonly cx: Pick<FluxionContext, 'options' | 'logger'>;\n  protected readonly handlers: Map<string, NormalizedModule> = new Map();\n\n  constructor(cx: Pick<FluxionContext, 'options' | 'logger'>) {\n    this.cx = cx;\n  }\n\n  protected async makeStaticResource(absolutePath: string): Promise<NormalizedModule> {\n    return {\n      type: FluxionModuleType.StaticResource,\n      mtimeMs: NaN,\n      absolutePath: absolutePath,\n      handler: async (normalized, cx, req, res) => {\n        if (normalized.method !== 'GET' && normalized.method !== 'HEAD') {\n          res.statusCode = 405;\n          res.setHeader('Allow', 'GET, HEAD');\n          res.end();\n          return;\n        }\n\n        const stat = await fs.stat(absolutePath).catch((e: Error) => e);\n        if (stat instanceof Error) {\n          res.statusCode = 404;\n          res.end('Not Accessible');\n          cx.logger.error({ action: 'StaticResourceError', url: normalized.url, error: stat.message });\n          return null;\n        }\n\n        if (!stat.isFile()) {\n          res.statusCode = 404;\n          res.end('Not Found');\n          return;\n        }\n\n        const extension = path.extname(absolutePath).toLowerCase();\n        const contentType = STATIC_CONTENT_TYPES[extension] ?? 'application/octet-stream';\n\n        res.statusCode = 200;\n        res.setHeader('Content-Type', contentType);\n        res.setHeader('Content-Length', String(stat.size));\n\n        if (normalized.method === 'HEAD') {\n          res.end();\n          return;\n        }\n\n        return new Promise<symbol>((resolve, reject) => {\n          const stream = createReadStream(absolutePath);\n\n          const cleanup = () => {\n            stream.off('error', onError);\n            stream.off('end', onEnd);\n            res.off('close', onClientClose);\n            req.off('aborted', onClientClose);\n          };\n\n          const onError = (error: Error) => {\n            cleanup();\n            reject(error);\n          };\n\n          const onEnd = () => {\n            cleanup();\n            resolve(STATIC_HANDLED_FLAG);\n          };\n\n          const onClientClose = () => {\n            cleanup();\n            stream.destroy();\n            resolve(STATIC_HANDLED_FLAG);\n          };\n\n          stream.on('error', onError);\n          stream.on('end', onEnd);\n          res.on('close', onClientClose);\n          req.on('aborted', onClientClose);\n\n          stream.pipe(res);\n        });\n      },\n    };\n  }\n\n  abstract register(absolutePath: string, relativePath: string, stat: Stats): Promise<NormalizedModule | undefined>;\n\n  abstract get(url: URL): NormalizedModule | undefined | Promise<NormalizedModule | undefined>;\n\n  getRoutes(): FluxionRouteMeta[] {\n    return [...this.handlers.entries()]\n      .map(\n        ([relativePath, m]): FluxionRouteMeta => ({\n          path: '/' + relativePath,\n          type: m.type === FluxionModuleType.Api ? 'api' : 'static',\n          methods: m.methods ? [...m.methods] : null,\n        }),\n      )\n      .sort((a, b) => a.path.localeCompare(b.path));\n  }\n}\n","import type { NormalizedModule } from '../types.js';\nimport type { Stats } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { minimatch } from 'minimatch';\nimport { loadFluxionModule } from '@/common/injector.js';\nimport { PromiseTry } from '@/common/promise-try.js';\n\nimport { FluxionRouterBase } from './base.js';\n\n// # Used by lazy mode\nexport class FluxionRouter extends FluxionRouterBase {\n  async register(absolutePath: string, relativePath: string, stat: Stats): Promise<NormalizedModule | undefined> {\n    // Step 1: Check if file matches exclude patterns\n    // If matching, skip registration\n    const excluded = this.cx.options.exclude.some((p) => minimatch(relativePath, p));\n    if (excluded) {\n      this.cx.logger.core({ action: 'Exclude', url: relativePath });\n      return;\n    }\n\n    // Step 2: Check if file matches apiInclude patterns\n    // If matching, register as API handler\n    const apiIncluded = this.cx.options.apiInclude.some((p) => minimatch(relativePath, p));\n    if (apiIncluded) {\n      const apiModule = loadFluxionModule(this.cx, absolutePath, stat);\n      this.handlers.set(relativePath, apiModule);\n      this.cx.logger.core({ action: 'RegisterApi', url: relativePath });\n      return apiModule;\n    }\n\n    // Step 3: Check if file matches staticInclude patterns\n    // If matching, register as static resource\n    const staticIncluded = this.cx.options.staticInclude.some((p) => minimatch(relativePath, p));\n    if (staticIncluded) {\n      const staticModule = await this.makeStaticResource(absolutePath);\n      this.handlers.set(relativePath, staticModule);\n      this.cx.logger.core({ action: 'RegisterStatic', url: relativePath });\n      return staticModule;\n    }\n\n    this.cx.logger.core({ action: 'Skip', url: relativePath });\n    return undefined;\n  }\n\n  async get(url: URL): Promise<NormalizedModule | undefined> {\n    const relativePath = url.pathname.replace(/^[/]+/, '').replace(/[/]+$/, '');\n    const absolutePath = path.join(this.cx.options.dir, relativePath);\n\n    // ! Fail if the resolved path escapes the configured directory\n    if (!absolutePath.startsWith(this.cx.options.dir + path.sep)) {\n      return undefined;\n    }\n\n    const cached = this.handlers.get(relativePath);\n    const stat = await fs.stat(absolutePath).catch(() => undefined);\n\n    // File does not exist or is not a file, returns undefined.\n    if (!stat || !stat.isFile()) {\n      if (cached?.disposer) {\n        this.handlers.delete(relativePath);\n        await PromiseTry(cached.disposer);\n      }\n      return undefined;\n    }\n\n    if (cached?.mtimeMs === stat.mtimeMs) {\n      return cached;\n    }\n\n    return this.register(absolutePath, relativePath, stat);\n  }\n}\n","import type { FluxionContext, FluxionOptions, NormalizedFluxionOptions } from './types.js';\n\nimport { createLogger } from './common/logger.js';\nimport { OPTIONS_NORMALIZED_FLAG } from './common/consts.js';\nimport { defineFluxionOptions } from './defines/options.js';\nimport { createServer } from './http/server.js';\nimport { FluxionRouter } from './router/index.js';\n\nexport async function fluxion(options: FluxionOptions | NormalizedFluxionOptions) {\n  const alreadyNormalized = (options as NormalizedFluxionOptions).normalizedFlag === OPTIONS_NORMALIZED_FLAG;\n  const context = { options: alreadyNormalized ? options : defineFluxionOptions(options) } as FluxionContext;\n\n  context.logger = createLogger(context as Pick<FluxionContext, 'options'>);\n  context.router = new FluxionRouter(context as Pick<FluxionContext, 'options' | 'logger'>);\n\n  // Start HTTP server\n  const server = await createServer(context);\n\n  // Register signal handlers for graceful shutdown\n  const shutdown = (signal: NodeJS.Signals) => {\n    context.logger.warn({ message: 'ShuttingDown', pid: process.pid, signal });\n    server.close(() => process.exit(0));\n    setTimeout(() => {\n      context.logger.error({ message: 'ShutdownTimeout', pid: process.pid, signal });\n      process.exit(1);\n    }, context.options.shutdownTimeoutMs).unref();\n  };\n\n  process.once('SIGINT', () => shutdown('SIGINT'));\n  process.once('SIGTERM', () => shutdown('SIGTERM'));\n}\n","import type { FluxionHandler, FluxionDisposer, NormalizedModule, FluxionModule, FluxionMiddleware } from '@/types.js';\nimport type { FluxionLoggerFn } from '@/common/logger.js';\nimport { FluxionModuleType } from '@/common/consts.js';\n\nexport { defineFluxionOptions } from './options.js';\n\n/**\n * Use handler function and optional disposer function to define a Fluxion module.\n * @param handler Main function that handles request and response instances\n * @param disposer Deal with resource cleanup when the server is about to close\n */\nexport function defineFluxionModule(handler: FluxionHandler, disposer?: FluxionDisposer): NormalizedModule;\n/**\n * Provides type safety for defining Fluxion modules.\n */\nexport function defineFluxionModule(fluxionModule: FluxionModule): NormalizedModule;\nexport function defineFluxionModule(a: FluxionModule | FluxionHandler, disposer?: FluxionDisposer): NormalizedModule {\n  if (typeof a === 'function') {\n    if (disposer !== undefined && typeof disposer !== 'function') {\n      _throw(`Invalid disposer, expected a function but got ${typeof disposer}`);\n    }\n    return { handler: a, disposer, type: FluxionModuleType.Api };\n  }\n\n  if (typeof a !== 'object' || a === null) {\n    _throw(`Invalid argument, expected a FluxionModule object or a handler function, but got ${typeof a}`);\n  }\n\n  if (typeof a.handler !== 'function') {\n    _throw(`Invalid FluxionModule, \"handler\" must be a function`);\n  }\n\n  if (a.disposer !== undefined && typeof a.disposer !== 'function') {\n    _throw(`Invalid FluxionModule, \"disposer\" must be a function if provided`);\n  }\n\n  if (a.methods !== undefined && (!Array.isArray(a.methods) || a.methods.some((v) => typeof v !== 'string'))) {\n    _throw(`Invalid FluxionModule, \"methods\" must be an array of strings if provided`);\n  }\n\n  if (\n    a.middlewares !== undefined &&\n    (!Array.isArray(a.middlewares) || a.middlewares.some((v) => typeof v !== 'function'))\n  ) {\n    _throw(`Invalid FluxionModule, \"middlewares\" must be an array of functions if provided`);\n  }\n\n  return { ...a, type: FluxionModuleType.Api };\n}\n\nexport function defineFluxionMiddleware(middleware: FluxionMiddleware): FluxionMiddleware {\n  if (typeof middleware !== 'function') {\n    _throw(`Invalid FluxionMiddleware, expected a function but got ${typeof middleware}`);\n  }\n  return middleware;\n}\n\nexport function defineFluxionLogger(loggerFn: FluxionLoggerFn) {\n  if (typeof loggerFn !== 'function') {\n    _throw(`Invalid FluxionLoggerFn, expected a function but got ${typeof loggerFn}`);\n  }\n  return loggerFn;\n}\n"],"x_google_ignoreList":[13],"mappings":"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"}