/** * 把 VirtualFS 里某个路径下的结构递归转换成 antd Tree 组件可用的节点结构 * (目录排在文件前面,各自按名称排序) * @param {VirtualFS} vfs - 虚拟文件系统实例 * @param {string} [pathStr] - 起始路径,默认根目录 * @param {string} [prefix] - 拼在 key 前面的前缀,用于避免多棵树的 key 冲突 * @returns {Promise<{title: string, key: string, isLeaf: boolean, children?: Array}|null>} * 树节点;路径无效/出错时返回 null */ declare function toTreePaths(vfs: VirtualFS, pathStr?: string, prefix?: string): Promise<{ title: string; key: string; isLeaf: boolean; children?: any[]; } | null>; /** * 内存中的虚拟文件系统,提供类似 Node fs 的增删改查 API(stat/dir/readFile/writeFile/mkdir/...), * 支持工作目录(scope)、变更订阅(subscribe)和文件查找(findFiles) */ declare class VirtualFS { /** * 创建一个虚拟文件系统实例 * @param {Object|Object[]|null} [initialStructure] - 初始文件系统结构 * - 如果是数组:将作为根目录的 children * - 如果是对象且 name 为 '/':将作为根节点 * - 如果是对象且 name 不为 '/':将添加到根目录的 children * - 如果为 null 或 undefined:创建空的文件系统 * @param {string} [working='/'] - 工作目录路径,默认为根目录 * * @example * // 创建空文件系统 * const vfs1 = new VirtualFS(); * * @example * // 使用数组初始化 * const vfs2 = new VirtualFS([ * { name: 'file.txt', type: 'file', content: 'hello' }, * { name: 'src', type: 'dir', children: [] } * ]); * * @example * // 使用根节点对象初始化 * const vfs3 = new VirtualFS({ * name: '/', * type: 'dir', * children: [{ name: 'file.txt', type: 'file', content: 'hello' }], * lastModified: Date.now() * }); * * @example * // 使用子节点对象初始化 * const vfs4 = new VirtualFS({ * name: 'src', * type: 'dir', * children: [] * }); * * @example * // 指定工作目录 * const vfs5 = new VirtualFS(rootNode, '/src'); */ constructor(initialStructure?: any | any[] | null, working?: string); root: any; /** * 获取文件/目录的状态信息 * @param {string} pathStr - 文件或目录路径(相对于工作目录或绝对路径) * @returns {Promise<{isFile: () => boolean, isDirectory: () => boolean, lastModified: number}>} * @throws {Error} 路径无效或不存在 */ stat(pathStr: string): Promise<{ isFile: () => boolean; isDirectory: () => boolean; lastModified: number; }>; /** * 列出目录下的所有子项名称 * @param {string} pathStr - 目录路径 * @returns {Promise} 子项名称数组 * @throws {Error} 路径无效、不存在或不是目录 */ dir(pathStr: string): Promise; /** * 读取文件内容 * @param {string} pathStr - 文件路径 * @returns {Promise} 文件内容,没有内容时返回空字符串 * @throws {Error} 路径无效、不存在或是目录 */ readFile(pathStr: string): Promise; /** * 写入文件内容,文件不存在则创建,存在则覆盖 * @param {string} pathStr - 文件路径 * @param {string} content - 文件内容 * @returns {Promise} * @throws {Error} 路径无效、父目录不存在或父路径不是目录 */ writeFile(pathStr: string, content: string): Promise; /** * 创建目录 * @param {string} pathStr - 目录路径 * @param {Object} [options] - 选项 * @param {boolean} [options.recursive] - 是否递归创建缺失的父目录(类似 mkdir -p) * @returns {Promise} * @throws {Error} 路径无效、父目录不存在/不是目录,或(非 recursive 时)目录已存在 */ mkdir(pathStr: string, options?: { recursive?: boolean; }): Promise; /** * 删除文件 * @param {string} pathStr - 文件路径 * @returns {Promise} * @throws {Error} 路径无效、不存在或是目录 */ unlink(pathStr: string): Promise; /** * 删除目录 * @param {string} pathStr - 目录路径 * @param {Object} [options] - 选项 * @param {boolean} [options.recursive] - 目录非空时是否强制删除(类似 rm -rf) * @returns {Promise} * @throws {Error} 路径无效、不存在、不是目录,或(非 recursive 时)目录非空 */ rmdir(pathStr: string, options?: { recursive?: boolean; }): Promise; /** * 重命名/移动文件或目录 * @param {string} oldPath - 原路径 * @param {string} newPath - 目标路径 * @returns {Promise} * @throws {Error} 路径无效、原路径不存在、目标父目录不存在,或目标路径已存在 */ rename(oldPath: string, newPath: string): Promise; /** * 判断路径是否存在 * @param {string} pathStr - 文件或目录路径 * @returns {Promise} 是否存在(路径无效时也返回 false) */ exists(pathStr: string): Promise; /** * 获取整个文件系统的最后修改时间 * @returns {number} 时间戳(毫秒) */ getLastModified(): number; /** * 订阅文件系统变更事件 * @param {Function} callback - 回调函数,接收事件对象 * @returns {Function} 取消订阅的函数 * * 事件对象格式: * - action: 'create' | 'update' | 'delete' | 'rename' * - path: 文件或目录的路径 * - type: 'file' | 'dir' * - timestamp: 操作时间戳 * - oldPath: (仅 rename 事件) 旧路径 * * @example * // 订阅文件系统变更 * const unsubscribe = vfs.subscribe((event) => { * console.log(`${event.action} ${event.type}: ${event.path}`); * // 输出示例: "create file: /src/index.js" * }); * * // 监听特定类型的变更 * const unsubscribe = vfs.subscribe((event) => { * if (event.action === 'create' && event.type === 'file') { * console.log('New file created:', event.path); * } * }); * * // 取消订阅 * unsubscribe(); */ subscribe(callback: Function): Function; /** * 获取当前工作目录 * @returns {string} 当前工作目录路径 */ getWorkingDirectory(): string; /** * 打开指定路径的目录,返回一个新的 VirtualFS 实例 * * 注意:返回的实例与原实例共享同一个节点树,对新实例的修改会影响原实例 * * @param {string} pathStr - 要打开的目录路径,默认为根目录 * @returns {VirtualFS} 新的 VirtualFS 实例,以指定目录为根(共享引用) * @throws {Error} 如果路径无效、不存在或不是目录 * * @example * const vfs = new VirtualFS(); * await vfs.mkdir('/src'); * await vfs.writeFile('/src/index.js', 'content1'); * * const srcVfs = vfs.scope('/src'); * await srcVfs.writeFile('/index.js', 'content2'); // 修改文件 * * // 原实例也会看到修改 * const content = await vfs.readFile('/src/index.js'); * console.log(content); // 'content2' */ scope(pathStr?: string): VirtualFS; /** * 在指定目录下查找匹配的文件 * @param {string} dirPath - 要搜索的目录路径 * @param {string|string[]|Function} patterns - 文件名模式,支持精确匹配、glob 通配符或过滤函数 * @param {Object} options - 选项对象 * @param {boolean} options.recursive - 是否递归搜索子目录(默认 false) * @param {boolean|string} options.fullPath - 返回路径的类型(默认 false) * - false:返回相对路径或文件名 * - true 或 'working':返回基于工作目录的相对路径(不带前导 /) * * 例如:'src/index.js', 'utils/helper.js' * - 'root':返回基于根目录的绝对路径(带前导 /) * * 例如:'/src/index.js', '/src/utils/helper.js' * @returns {Promise} 匹配的文件名数组 * @throws {Error} 如果路径无效、目录不存在或路径不是目录 * * 支持的模式类型: * 1. 精确匹配: 'index.js' - 查找具体的文件名 * 2. 通配符 *: '*.js' - 匹配任意数量的字符 * 3. 通配符 ?: 'App.?sx' - 匹配单个字符 * 4. 大括号展开: 'index.{js,jsx,ts}' - 匹配多个可选值 * 5. 数组模式: ['*.js', 'App.*', 'package.json'] - 组合多个模式 * 6. 过滤函数: (filename) => boolean - 自定义过滤逻辑 * * 使用示例: * ```javascript * // 精确查找单个文件 * await vfs.findFiles('/src', 'index.js') * // 返回: ['index.js'] (如果存在) * * // 查找多个精确文件 * await vfs.findFiles('/src', ['index.js', 'App.jsx', 'main.ts']) * // 返回: ['index.js', 'App.jsx'] (返回存在的文件) * * // 使用通配符查找所有 .js 文件 * await vfs.findFiles('/src', '*.js') * // 返回: ['index.js', 'main.js', 'utils.js'] * * // 使用 ? 匹配单个字符 * await vfs.findFiles('/src', 'App.?sx') * // 返回: ['App.jsx', 'App.tsx'] * * // 使用大括号展开 * await vfs.findFiles('/src', 'index.{js,jsx,ts,tsx}') * // 返回: ['index.js', 'index.jsx'] (返回存在的变体) * * // 组合通配符和大括号 * await vfs.findFiles('/src', '*.{js,jsx}') * // 返回: ['index.js', 'App.jsx', 'main.js'] * * // 混合精确匹配和模式 * await vfs.findFiles('/src', ['package.json', '*.ts', 'index.{js,jsx}']) * // 返回所有匹配的文件 * * // 使用过滤函数 * await vfs.findFiles('/src', (filename) => filename.startsWith('test')) * // 返回: ['test-utils.js', 'test-helpers.js'] * * // 使用过滤函数 - 复杂条件 * await vfs.findFiles('/src', (filename) => { * return filename.endsWith('.js') && filename.length > 10 * }) * // 返回所有长度大于10的 .js 文件 * * // 递归搜索所有子目录 * await vfs.findFiles('/src', '*.js', { recursive: true }) * // 返回: ['index.js', 'utils/helper.js', 'components/Button.js'] * * // 递归搜索 + 过滤函数 * await vfs.findFiles('/src', (filename) => filename.includes('test'), { recursive: true }) * // 返回: ['test.js', 'utils/test-helper.js', 'components/Button.test.js'] * * // 返回基于工作目录的完整路径 * await vfs.findFiles('/src', '*.js', { fullPath: true }) * // 或者 * await vfs.findFiles('/src', '*.js', { fullPath: 'working' }) * // 返回: ['src/index.js', 'src/main.js'] (相对路径,不带前导 /) * * // 返回基于根目录的完整路径 * await vfs.findFiles('/src', '*.js', { fullPath: 'root' }) * // 返回: ['/src/index.js', '/src/main.js'] (绝对路径,带前导 /) * * // 递归搜索 + 根目录完整路径 * await vfs.findFiles('/src', '*.js', { recursive: true, fullPath: 'root' }) * // 返回: ['/src/index.js', '/src/utils/helper.js', '/src/components/Button.js'] * ``` */ findFiles(dirPath: string, patterns: string | string[] | Function, options?: { recursive: boolean; fullPath: boolean | string; }): Promise; #private; } export { VirtualFS as default, toTreePaths };