UNPKG

zephyr-agent

Version:
152 lines (151 loc) • 4.99 kB
import "node:module"; import { readFile, readdir, realpath, stat } from "node:fs/promises"; import { join, resolve } from "node:path"; const SKIP_PATH_PATTERNS = [ /(^|\/)node_modules($|\/)/i, /(^|\/)\.git($|\/)/i, /(^|\/)\.DS_Store$/i, /(^|\/)thumbs\.db$/i ]; async function readDirRecursive(dirPath, options = {}) { const files = []; for await (const file of resolveDir({ currentDir: resolve(dirPath), relativePrefix: '', readContents: false, activeRealDirs: new Set(), includeIgnoredPaths: options.includeIgnoredPaths ?? false, failOnError: options.failOnError ?? false }))files.push({ fullPath: file.fullPath, relativePath: file.relativePath }); return files; } async function readDirRecursiveWithContents(dirPath, options = {}) { const files = []; for await (const file of resolveDir({ currentDir: resolve(dirPath), relativePrefix: '', readContents: true, activeRealDirs: new Set(), includeIgnoredPaths: options.includeIgnoredPaths ?? false, failOnError: options.failOnError ?? false }))if (file.content) files.push(file); return files; } async function* resolveDir({ currentDir, relativePrefix, readContents, activeRealDirs, includeIgnoredPaths, failOnError }) { let entries; try { entries = await readdir(currentDir, { withFileTypes: true }); } catch (error) { if (failOnError) throw error; return; } const currentRealDir = await safeRealpath(currentDir, failOnError); if (activeRealDirs.has(currentRealDir)) return; activeRealDirs.add(currentRealDir); try { for (const entry of entries){ const fullPath = resolve(currentDir, entry.name); const relativePath = relativePrefix ? join(relativePrefix, entry.name) : entry.name; const normalizedRelativePath = normalizePath(relativePath); if (!(!includeIgnoredPaths && shouldSkipRelativePath(normalizedRelativePath, entry))) yield* resolveFile({ fullPath, relativePath, entry, readContents, activeRealDirs, includeIgnoredPaths, failOnError }); } } finally{ activeRealDirs.delete(currentRealDir); } } async function* resolveFile({ fullPath, relativePath, entry, readContents, activeRealDirs, includeIgnoredPaths, failOnError }) { if (entry.isSymbolicLink()) return void (yield* resolveSymbolicLink({ fullPath, relativePath, readContents, activeRealDirs, includeIgnoredPaths, failOnError })); if (entry.isDirectory()) return void (yield* resolveDir({ currentDir: fullPath, relativePrefix: relativePath, readContents, activeRealDirs, includeIgnoredPaths, failOnError })); if (entry.isFile()) { const content = readContents ? await safeReadFile(fullPath, failOnError) : void 0; if (readContents && !content) return; yield { fullPath, relativePath, content }; } } async function* resolveSymbolicLink({ fullPath, relativePath, readContents, activeRealDirs, includeIgnoredPaths, failOnError }) { const realPath = await safeRealpath(fullPath, failOnError); let realStat; try { realStat = await stat(realPath); } catch (error) { if (failOnError) throw error; return; } if (realStat.isDirectory()) { if (activeRealDirs.has(realPath)) return; yield* resolveDir({ currentDir: realPath, relativePrefix: relativePath, readContents, activeRealDirs, includeIgnoredPaths, failOnError }); return; } if (realStat.isFile()) { const content = readContents ? await safeReadFile(realPath, failOnError) : void 0; if (readContents && !content) return; yield { fullPath: realPath, relativePath, content }; } } async function safeReadFile(path, failOnError) { try { return await readFile(path); } catch (error) { if (failOnError) throw error; return; } } async function safeRealpath(path, failOnError) { try { return await realpath(path); } catch (error) { if (failOnError) throw error; return path; } } function normalizePath(filePath) { return filePath.replace(/\\/g, '/'); } function shouldSkipRelativePath(relativePath, entry) { if (entry.isDirectory()) return SKIP_PATH_PATTERNS.some((pattern)=>pattern.test(`${relativePath}/`)); return SKIP_PATH_PATTERNS.some((pattern)=>pattern.test(relativePath)); } export { readDirRecursive, readDirRecursiveWithContents }; //# sourceMappingURL=read-dir-recursive.mjs.map