Extremely high performant utility for building tools that read the file system, minimizing filesystem and path string munging operations to the greatest degree possible
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
High-performance directory reading operations with intelligent caching, multiple output formats, and error handling. All operations cache results to minimize filesystem calls on subsequent accesses.
Read directory contents asynchronously with configurable output formats.
/**
* Read directory contents asynchronously
* @param entry - Directory to read (defaults to current working directory)
* @param opts - Options controlling output format
* @returns Promise resolving to array of Path objects or strings
*/
readdir(): Promise<PathBase[]>;
readdir(opts: { withFileTypes: true }): Promise<PathBase[]>;
readdir(opts: { withFileTypes: false }): Promise<string[]>;
readdir(opts: { withFileTypes: boolean }): Promise<PathBase[] | string[]>;
readdir(entry: PathBase | string): Promise<PathBase[]>;
readdir(entry: PathBase | string, opts: { withFileTypes: true }): Promise<PathBase[]>;
readdir(entry: PathBase | string, opts: { withFileTypes: false }): Promise<string[]>;
readdir(entry: PathBase | string, opts: { withFileTypes: boolean }): Promise<PathBase[] | string[]>;Usage Examples:
import { PathScurry } from "path-scurry";
const pw = new PathScurry();
// Default: returns Path objects
const entries1 = await pw.readdir();
for (const entry of entries1) {
console.log(`${entry.name}: ${entry.getType()}`);
}
// Return string names only
const names = await pw.readdir({ withFileTypes: false });
console.log("Files:", names);
// Read specific directory
const srcFiles = await pw.readdir("./src");
const textFiles = srcFiles.filter(entry =>
entry.isFile() && entry.name.endsWith(".txt")
);
// Mixed usage with Path objects
const configDir = await pw.readdir("./config", { withFileTypes: true });
for (const entry of configDir) {
if (entry.isFile()) {
console.log(`Config file: ${entry.fullpath()}`);
}
}Read directory contents synchronously with the same API as async version.
/**
* Read directory contents synchronously
* @param entry - Directory to read (defaults to current working directory)
* @param opts - Options controlling output format
* @returns Array of Path objects or strings
*/
readdirSync(): PathBase[];
readdirSync(opts: { withFileTypes: true }): PathBase[];
readdirSync(opts: { withFileTypes: false }): string[];
readdirSync(opts: { withFileTypes: boolean }): PathBase[] | string[];
readdirSync(entry: PathBase | string): PathBase[];
readdirSync(entry: PathBase | string, opts: { withFileTypes: true }): PathBase[];
readdirSync(entry: PathBase | string, opts: { withFileTypes: false }): string[];
readdirSync(entry: PathBase | string, opts: { withFileTypes: boolean }): PathBase[] | string[];Usage Examples:
const pw = new PathScurry("/project");
// Synchronous directory reading
const entries = pw.readdirSync("src");
const jsFiles = entries.filter(entry =>
entry.isFile() && entry.name.endsWith(".js")
);
// Get just filenames
const fileNames = pw.readdirSync("dist", { withFileTypes: false });
console.log("Built files:", fileNames);
// Process directory structure
function listDirectory(path: string, level = 0) {
const indent = " ".repeat(level);
const entries = pw.readdirSync(path);
for (const entry of entries) {
console.log(`${indent}${entry.name} (${entry.getType()})`);
if (entry.isDirectory()) {
listDirectory(entry.fullpath(), level + 1);
}
}
}
listDirectory("./");Directory operations available directly on Path objects.
/**
* Read directory contents for this Path object
* @returns Promise resolving to array of child Path objects
*/
readdir(): Promise<PathBase[]>;
/**
* Read directory contents synchronously for this Path object
* @returns Array of child Path objects
*/
readdirSync(): PathBase[];
/**
* Node-style callback interface for directory reading
* @param cb - Callback function receiving (error, entries)
* @param allowZalgo - Whether to allow immediate callback execution
*/
readdirCB(
cb: (er: NodeJS.ErrnoException | null, entries: PathBase[]) => any,
allowZalgo?: boolean
): void;
/**
* Check if this path can be read as a directory
* @returns True if path is likely readable as directory
*/
canReaddir(): boolean;
/**
* Check if readdir has been successfully called on this path
* @returns True if directory contents are cached
*/
calledReaddir(): boolean;
/**
* Get cached directory contents without filesystem access
* @returns Array of cached child entries (may be empty if not cached)
*/
readdirCached(): PathBase[];Usage Examples:
const pw = new PathScurry();
const srcDir = pw.cwd.resolve("src");
// Direct Path object usage
if (srcDir.canReaddir()) {
const files = await srcDir.readdir();
console.log(`Found ${files.length} entries in src/`);
}
// Callback-style reading
srcDir.readdirCB((err, entries) => {
if (err) {
console.error("Failed to read directory:", err);
return;
}
console.log("Directory contents:", entries.map(e => e.name));
});
// Check cache status
if (srcDir.calledReaddir()) {
const cached = srcDir.readdirCached();
console.log("Cached entries:", cached.length);
} else {
console.log("Directory not yet read");
}Directory operations handle errors gracefully and return empty arrays when paths cannot be read.
Error Scenarios:
Example:
const pw = new PathScurry();
// These all return empty arrays instead of throwing
const missing = await pw.readdir("./does-not-exist"); // []
const file = await pw.readdir("./package.json"); // []
const restricted = await pw.readdir("/root/.ssh"); // [] (if no permission)
// Check path status
const path = pw.cwd.resolve("./some-path");
if (path.isENOENT()) {
console.log("Path does not exist");
} else if (!path.canReaddir()) {
console.log("Path cannot be read as directory");
}childrenCacheSize option (default: 16384 entries)Install with Tessl CLI
npx tessl i tessl/npm-path-scurry