/**
 * error-overlay.ts — Dev 模式 HTML 错误覆盖层渲染器
 *
 * 接受一个 Error 对象和 projectRoot 路径，生成完整的 HTML 错误覆盖层字符串。
 * 功能：
 *   - 解析 Error.stack（--enable-source-maps 翻译后为 .ts 路径）
 *   - 区分用户代码帧（展开 + 源码上下文）与内部帧（折叠）
 *   - 支持 dark / light 主题
 *   - vscode:// 链接直接跳转到出错行
 *   - VextValidationError 专属：字段级错误列表
 *   - 最多展示 N 帧（防止超深调用栈撑爆 HTML）
 *
 * 设计约束：
 *   - 不 import 任何框架类型（error-overlay.ts 是框架内部工具，不暴露到公共 API）
 *   - 使用 fs.readFileSync 同步读取（仅 dev 模式错误路径，性能可接受）
 *   - 渲染失败时抛出异常，由外层 error-handler.ts 的 try/catch 降级到 JSON
 *
 * @module lib/dev/error-overlay
 * @see requirements/dev-error-overlay/02-技术方案.md §2.1
 */
/**
 * 解析后的堆栈帧
 */
export interface StackFrame {
    /** 函数名（未知时为 '<anonymous>'） */
    fn: string;
    /** 绝对文件路径（--enable-source-maps 翻译后为 .ts） */
    file: string;
    /** 行号（1-based） */
    line: number;
    /** 列号（1-based） */
    col: number;
}
/**
 * 源码上下文（出错行 ±3 行）
 */
export interface SourceContext {
    lines: Array<{
        /** 行号（1-based） */
        num: number;
        /** 行内容（原始文本） */
        content: string;
        /** 是否为出错行（高亮） */
        isError: boolean;
    }>;
}
/**
 * renderDevErrorPage 的可选配置
 */
export interface DevOverlayOptions {
    /** 主题：深色 / 浅色（默认 'dark'） */
    theme?: "dark" | "light";
    /** 最多显示的堆栈帧数（默认 25） */
    maxFrames?: number;
}
/**
 * HTML 特殊字符转义（防止 XSS）
 */
export declare function escapeHtml(str: string): string;
/**
 * 解析 Error.stack 字符串为 StackFrame 数组
 *
 * 支持两种格式：
 *   - "    at FunctionName (file:line:col)"
 *   - "    at file:line:col"
 *   - Windows 路径：反斜杠会被处理
 *   - node: 内置模块：file 以 "node:" 开头
 */
export declare function parseStackTrace(stack: string): StackFrame[];
/**
 * 将帧文件路径解析为绝对路径
 *
 * --enable-source-maps 翻译后的堆栈路径存在两种偏差：
 *   A. 相对路径（如 "../src/routes/index.ts"）
 *   B. 绝对但层级偏移（如 "E:/MySelf/src/routes/index.ts"，
 *      实际应为 "E:/MySelf/vext-test/src/routes/index.ts"）
 *
 * 这是因为 esbuild sourcemap 的 sources 路径相对于编译产物目录（.vext/dev/），
 * Node.js --enable-source-maps 解析时可能丢失中间层级。
 *
 * 解析策略（通用后缀匹配，按优先级）：
 *   1. 已是绝对路径且文件存在 → 直接返回
 *   2. "node:" 前缀 → 直接返回
 *   3. 从最长尾部到最短（至少 2 段）逐一拼接 projectRoot 检查是否存在
 *      e.g. "E:\MySelf\src\routes\index.ts" → 尝试 projectRoot/MySelf/src/routes/index.ts（否）
 *                                            → 尝试 projectRoot/src/routes/index.ts（是！）
 *      该策略覆盖 src/、plugins/、middlewares/、services/ 等任意子目录
 *   4. 相对路径 → path.resolve(projectRoot, file)
 *   5. 以上都失败 → 返回原始路径（graceful 降级）
 */
export declare function resolveFramePath(file: string, projectRoot: string): string;
/**
 * 判断帧是否为用户代码（而非框架内部或 node_modules）
 *
 * 条件：
 *   1. file 以 projectRoot 开头
 *   2. file 不包含 'node_modules'
 *   3. file 不以 'node:' 开头（Node.js 内置模块）
 *   4. file 不包含 '.vext/dev/'（未翻译的编译产物，--enable-source-maps 应已翻译）
 */
export declare function isUserFrame(frame: StackFrame, projectRoot: string): boolean;
/**
 * 读取文件中指定行号 ±3 行的上下文
 *
 * 边界处理：
 *   - 文件不存在 → 返回 null（E2）
 *   - 文件读取失败 → 返回 null（E3）
 *   - 行号超出范围 → 取可用范围
 */
export declare function getSourceContext(file: string, errorLine: number): SourceContext | null;
/**
 * renderDevErrorPage — 生成完整的 HTML 错误覆盖层字符串
 *
 * @param err          抛出的错误（任意类型，非 Error 对象会被转换）
 * @param projectRoot  用户项目根目录（绝对路径），用于区分用户帧/内部帧
 * @param options      可选配置（主题、最大帧数）
 * @returns            完整的 HTML 字符串（可直接作为 HTTP 响应体）
 */
export declare function renderDevErrorPage(err: unknown, projectRoot: string, options?: DevOverlayOptions): string;
