or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

directory-operations.mddirectory-walking.mdfilesystem-metadata.mdindex.mdpath-objects.mdpath-resolution.md

directory-operations.mddocs/

0

# Directory Operations

1

2

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.

3

4

## Capabilities

5

6

### Asynchronous Directory Reading

7

8

Read directory contents asynchronously with configurable output formats.

9

10

```typescript { .api }

11

/**

12

* Read directory contents asynchronously

13

* @param entry - Directory to read (defaults to current working directory)

14

* @param opts - Options controlling output format

15

* @returns Promise resolving to array of Path objects or strings

16

*/

17

readdir(): Promise<PathBase[]>;

18

readdir(opts: { withFileTypes: true }): Promise<PathBase[]>;

19

readdir(opts: { withFileTypes: false }): Promise<string[]>;

20

readdir(opts: { withFileTypes: boolean }): Promise<PathBase[] | string[]>;

21

readdir(entry: PathBase | string): Promise<PathBase[]>;

22

readdir(entry: PathBase | string, opts: { withFileTypes: true }): Promise<PathBase[]>;

23

readdir(entry: PathBase | string, opts: { withFileTypes: false }): Promise<string[]>;

24

readdir(entry: PathBase | string, opts: { withFileTypes: boolean }): Promise<PathBase[] | string[]>;

25

```

26

27

**Usage Examples:**

28

29

```typescript

30

import { PathScurry } from "path-scurry";

31

32

const pw = new PathScurry();

33

34

// Default: returns Path objects

35

const entries1 = await pw.readdir();

36

for (const entry of entries1) {

37

console.log(`${entry.name}: ${entry.getType()}`);

38

}

39

40

// Return string names only

41

const names = await pw.readdir({ withFileTypes: false });

42

console.log("Files:", names);

43

44

// Read specific directory

45

const srcFiles = await pw.readdir("./src");

46

const textFiles = srcFiles.filter(entry =>

47

entry.isFile() && entry.name.endsWith(".txt")

48

);

49

50

// Mixed usage with Path objects

51

const configDir = await pw.readdir("./config", { withFileTypes: true });

52

for (const entry of configDir) {

53

if (entry.isFile()) {

54

console.log(`Config file: ${entry.fullpath()}`);

55

}

56

}

57

```

58

59

### Synchronous Directory Reading

60

61

Read directory contents synchronously with the same API as async version.

62

63

```typescript { .api }

64

/**

65

* Read directory contents synchronously

66

* @param entry - Directory to read (defaults to current working directory)

67

* @param opts - Options controlling output format

68

* @returns Array of Path objects or strings

69

*/

70

readdirSync(): PathBase[];

71

readdirSync(opts: { withFileTypes: true }): PathBase[];

72

readdirSync(opts: { withFileTypes: false }): string[];

73

readdirSync(opts: { withFileTypes: boolean }): PathBase[] | string[];

74

readdirSync(entry: PathBase | string): PathBase[];

75

readdirSync(entry: PathBase | string, opts: { withFileTypes: true }): PathBase[];

76

readdirSync(entry: PathBase | string, opts: { withFileTypes: false }): string[];

77

readdirSync(entry: PathBase | string, opts: { withFileTypes: boolean }): PathBase[] | string[];

78

```

79

80

**Usage Examples:**

81

82

```typescript

83

const pw = new PathScurry("/project");

84

85

// Synchronous directory reading

86

const entries = pw.readdirSync("src");

87

const jsFiles = entries.filter(entry =>

88

entry.isFile() && entry.name.endsWith(".js")

89

);

90

91

// Get just filenames

92

const fileNames = pw.readdirSync("dist", { withFileTypes: false });

93

console.log("Built files:", fileNames);

94

95

// Process directory structure

96

function listDirectory(path: string, level = 0) {

97

const indent = " ".repeat(level);

98

const entries = pw.readdirSync(path);

99

100

for (const entry of entries) {

101

console.log(`${indent}${entry.name} (${entry.getType()})`);

102

if (entry.isDirectory()) {

103

listDirectory(entry.fullpath(), level + 1);

104

}

105

}

106

}

107

108

listDirectory("./");

109

```

110

111

### Path Object Directory Methods

112

113

Directory operations available directly on Path objects.

114

115

```typescript { .api }

116

/**

117

* Read directory contents for this Path object

118

* @returns Promise resolving to array of child Path objects

119

*/

120

readdir(): Promise<PathBase[]>;

121

122

/**

123

* Read directory contents synchronously for this Path object

124

* @returns Array of child Path objects

125

*/

126

readdirSync(): PathBase[];

127

128

/**

129

* Node-style callback interface for directory reading

130

* @param cb - Callback function receiving (error, entries)

131

* @param allowZalgo - Whether to allow immediate callback execution

132

*/

133

readdirCB(

134

cb: (er: NodeJS.ErrnoException | null, entries: PathBase[]) => any,

135

allowZalgo?: boolean

136

): void;

137

138

/**

139

* Check if this path can be read as a directory

140

* @returns True if path is likely readable as directory

141

*/

142

canReaddir(): boolean;

143

144

/**

145

* Check if readdir has been successfully called on this path

146

* @returns True if directory contents are cached

147

*/

148

calledReaddir(): boolean;

149

150

/**

151

* Get cached directory contents without filesystem access

152

* @returns Array of cached child entries (may be empty if not cached)

153

*/

154

readdirCached(): PathBase[];

155

```

156

157

**Usage Examples:**

158

159

```typescript

160

const pw = new PathScurry();

161

const srcDir = pw.cwd.resolve("src");

162

163

// Direct Path object usage

164

if (srcDir.canReaddir()) {

165

const files = await srcDir.readdir();

166

console.log(`Found ${files.length} entries in src/`);

167

}

168

169

// Callback-style reading

170

srcDir.readdirCB((err, entries) => {

171

if (err) {

172

console.error("Failed to read directory:", err);

173

return;

174

}

175

176

console.log("Directory contents:", entries.map(e => e.name));

177

});

178

179

// Check cache status

180

if (srcDir.calledReaddir()) {

181

const cached = srcDir.readdirCached();

182

console.log("Cached entries:", cached.length);

183

} else {

184

console.log("Directory not yet read");

185

}

186

```

187

188

### Error Handling

189

190

Directory operations handle errors gracefully and return empty arrays when paths cannot be read.

191

192

**Error Scenarios:**

193

194

- **Non-existent directories**: Return empty array instead of throwing

195

- **Permission denied**: Return empty array, path marked accordingly

196

- **Not a directory**: Return empty array for files or other entry types

197

- **Filesystem errors**: Return empty array, error information cached

198

199

**Example:**

200

201

```typescript

202

const pw = new PathScurry();

203

204

// These all return empty arrays instead of throwing

205

const missing = await pw.readdir("./does-not-exist"); // []

206

const file = await pw.readdir("./package.json"); // []

207

const restricted = await pw.readdir("/root/.ssh"); // [] (if no permission)

208

209

// Check path status

210

const path = pw.cwd.resolve("./some-path");

211

if (path.isENOENT()) {

212

console.log("Path does not exist");

213

} else if (!path.canReaddir()) {

214

console.log("Path cannot be read as directory");

215

}

216

```

217

218

### Performance Considerations

219

220

- **First access**: Directory contents loaded from filesystem

221

- **Subsequent access**: Results served from cache (much faster)

222

- **Cache invalidation**: Manual invalidation not supported - assume filesystem is stable

223

- **Memory usage**: Controlled by `childrenCacheSize` option (default: 16384 entries)

224

- **Large directories**: Consider using streaming or iterator interfaces for directories with many entries