Files
ff-dist/dist/virtual-fs.d.ts
T
2026-08-11 13:47:48 +08:00

296 lines
12 KiB
TypeScript

/**
* 把 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<string[]>} 子项名称数组
* @throws {Error} 路径无效、不存在或不是目录
*/
dir(pathStr: string): Promise<string[]>;
/**
* 读取文件内容
* @param {string} pathStr - 文件路径
* @returns {Promise<string>} 文件内容,没有内容时返回空字符串
* @throws {Error} 路径无效、不存在或是目录
*/
readFile(pathStr: string): Promise<string>;
/**
* 写入文件内容,文件不存在则创建,存在则覆盖
* @param {string} pathStr - 文件路径
* @param {string} content - 文件内容
* @returns {Promise<void>}
* @throws {Error} 路径无效、父目录不存在或父路径不是目录
*/
writeFile(pathStr: string, content: string): Promise<void>;
/**
* 创建目录
* @param {string} pathStr - 目录路径
* @param {Object} [options] - 选项
* @param {boolean} [options.recursive] - 是否递归创建缺失的父目录(类似 mkdir -p)
* @returns {Promise<void>}
* @throws {Error} 路径无效、父目录不存在/不是目录,或(非 recursive 时)目录已存在
*/
mkdir(pathStr: string, options?: {
recursive?: boolean;
}): Promise<void>;
/**
* 删除文件
* @param {string} pathStr - 文件路径
* @returns {Promise<void>}
* @throws {Error} 路径无效、不存在或是目录
*/
unlink(pathStr: string): Promise<void>;
/**
* 删除目录
* @param {string} pathStr - 目录路径
* @param {Object} [options] - 选项
* @param {boolean} [options.recursive] - 目录非空时是否强制删除(类似 rm -rf)
* @returns {Promise<void>}
* @throws {Error} 路径无效、不存在、不是目录,或(非 recursive 时)目录非空
*/
rmdir(pathStr: string, options?: {
recursive?: boolean;
}): Promise<void>;
/**
* 重命名/移动文件或目录
* @param {string} oldPath - 原路径
* @param {string} newPath - 目标路径
* @returns {Promise<void>}
* @throws {Error} 路径无效、原路径不存在、目标父目录不存在,或目标路径已存在
*/
rename(oldPath: string, newPath: string): Promise<void>;
/**
* 判断路径是否存在
* @param {string} pathStr - 文件或目录路径
* @returns {Promise<boolean>} 是否存在(路径无效时也返回 false)
*/
exists(pathStr: string): Promise<boolean>;
/**
* 获取整个文件系统的最后修改时间
* @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<string[]>} 匹配的文件名数组
* @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<string[]>;
#private;
}
export { VirtualFS as default, toTreePaths };