0
# Walker
1
2
Walker is a Node.js library that provides asynchronous directory tree traversal with an event-driven API. It broadcasts events for various file types as well as a generic "entry" event for all types and provides the ability to prune directory trees during traversal.
3
4
## Package Information
5
6
- **Package Name**: walker
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install walker`
10
11
## Core Imports
12
13
```javascript
14
const Walker = require('walker');
15
```
16
17
## Basic Usage
18
19
```javascript
20
const Walker = require('walker');
21
22
Walker('/path/to/directory')
23
.on('file', function(file, stat) {
24
console.log('Found file: ' + file);
25
})
26
.on('dir', function(dir, stat) {
27
console.log('Found directory: ' + dir);
28
})
29
.on('end', function() {
30
console.log('Directory traversal complete');
31
});
32
```
33
34
## Architecture
35
36
Walker is built around an EventEmitter pattern:
37
38
- **Event-Driven**: Emits specific events for different file types encountered during traversal
39
- **Asynchronous**: Non-blocking directory traversal using Node.js's async filesystem operations
40
- **Filtering**: Directory pruning capability through configurable filter functions
41
- **Flow Control**: Internal pending counter tracks async operations to emit proper completion events
42
43
## Capabilities
44
45
### Walker Constructor
46
47
Creates a new directory walker instance and immediately starts traversal.
48
49
```javascript { .api }
50
/**
51
* Creates a directory walker instance
52
* @param {string} root - The directory path to start walking from
53
* @returns {Walker} Walker instance (EventEmitter)
54
*/
55
function Walker(root);
56
```
57
58
**Usage Examples:**
59
60
```javascript
61
// Constructor with 'new'
62
const walker = new Walker('/etc');
63
64
// Constructor without 'new' (both work identically)
65
const walker = Walker('/etc');
66
67
// Chaining event handlers
68
Walker('/home/user')
69
.filterDir(function(dir, stat) {
70
return dir !== '/home/user/node_modules';
71
})
72
.on('file', function(file, stat) {
73
console.log('File:', file);
74
});
75
```
76
77
### Directory Filtering
78
79
Setup a function to filter out directory entries during traversal.
80
81
```javascript { .api }
82
/**
83
* Setup a function to filter out directory entries
84
* @param {function} fn - Filter function that receives (dir, stat) and returns boolean
85
* @returns {Walker} Walker instance for chaining
86
*/
87
Walker.prototype.filterDir(fn);
88
```
89
90
**Usage Examples:**
91
92
```javascript
93
// Skip specific directories
94
Walker('/project')
95
.filterDir(function(dir, stat) {
96
if (dir.endsWith('node_modules') || dir.endsWith('.git')) {
97
return false; // Skip these directories and their children
98
}
99
return true; // Include this directory
100
})
101
.on('entry', function(entry, stat) {
102
console.log('Processing:', entry);
103
});
104
105
// Filter based on directory stats
106
Walker('/logs')
107
.filterDir(function(dir, stat) {
108
// Skip directories older than 30 days
109
const thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000);
110
return stat.mtime.getTime() > thirtyDaysAgo;
111
});
112
```
113
114
### Events
115
116
Walker emits events for different file system entry types encountered during traversal.
117
118
#### Entry Event
119
120
Generic event emitted for all file system entries.
121
122
```javascript { .api }
123
/**
124
* Emitted for every file system entry encountered
125
* @param {string} entry - Path of the entry
126
* @param {fs.Stats} stat - File system stats object
127
*/
128
walker.on('entry', function(entry, stat) { });
129
```
130
131
#### Directory Event
132
133
Emitted for directory entries.
134
135
```javascript { .api }
136
/**
137
* Emitted for directory entries
138
* @param {string} dir - Directory path
139
* @param {fs.Stats} stat - File system stats object
140
*/
141
walker.on('dir', function(dir, stat) { });
142
```
143
144
#### File Event
145
146
Emitted for regular file entries.
147
148
```javascript { .api }
149
/**
150
* Emitted for regular file entries
151
* @param {string} file - File path
152
* @param {fs.Stats} stat - File system stats object
153
*/
154
walker.on('file', function(file, stat) { });
155
```
156
157
#### Symlink Event
158
159
Emitted for symbolic link entries.
160
161
```javascript { .api }
162
/**
163
* Emitted for symbolic link entries
164
* @param {string} symlink - Symlink path
165
* @param {fs.Stats} stat - File system stats object
166
*/
167
walker.on('symlink', function(symlink, stat) { });
168
```
169
170
#### Block Device Event
171
172
Emitted for block device entries.
173
174
```javascript { .api }
175
/**
176
* Emitted for block device entries
177
* @param {string} blockDevice - Block device path
178
* @param {fs.Stats} stat - File system stats object
179
*/
180
walker.on('blockDevice', function(blockDevice, stat) { });
181
```
182
183
#### Character Device Event
184
185
Emitted for character device entries.
186
187
```javascript { .api }
188
/**
189
* Emitted for character device entries
190
* @param {string} characterDevice - Character device path
191
* @param {fs.Stats} stat - File system stats object
192
*/
193
walker.on('characterDevice', function(characterDevice, stat) { });
194
```
195
196
#### FIFO Event
197
198
Emitted for FIFO (named pipe) entries.
199
200
```javascript { .api }
201
/**
202
* Emitted for FIFO (named pipe) entries
203
* @param {string} fifo - FIFO path
204
* @param {fs.Stats} stat - File system stats object
205
*/
206
walker.on('fifo', function(fifo, stat) { });
207
```
208
209
#### Socket Event
210
211
Emitted for socket entries.
212
213
```javascript { .api }
214
/**
215
* Emitted for socket entries
216
* @param {string} socket - Socket path
217
* @param {fs.Stats} stat - File system stats object
218
*/
219
walker.on('socket', function(socket, stat) { });
220
```
221
222
#### Error Event
223
224
Emitted when errors occur during traversal.
225
226
```javascript { .api }
227
/**
228
* Emitted when errors occur during traversal
229
* @param {Error} error - The error object
230
* @param {string} entry - Path where error occurred
231
* @param {fs.Stats|undefined} stat - File system stats object (may be undefined)
232
*/
233
walker.on('error', function(error, entry, stat) { });
234
```
235
236
**Usage Examples:**
237
238
```javascript
239
Walker('/some/path')
240
.on('error', function(er, entry, stat) {
241
console.error('Error processing ' + entry + ':', er.message);
242
// Continue processing other files
243
})
244
.on('end', function() {
245
console.log('Traversal completed despite errors');
246
});
247
```
248
249
#### End Event
250
251
Emitted when directory traversal is complete.
252
253
```javascript { .api }
254
/**
255
* Emitted when directory traversal is complete
256
*/
257
walker.on('end', function() { });
258
```
259
260
### Error Classes
261
262
#### UnknownFileTypeError
263
264
Custom error thrown when file type cannot be determined.
265
266
```javascript { .api }
267
/**
268
* Error thrown when the type of a file could not be determined
269
*/
270
Walker.UnknownFileTypeError;
271
```
272
273
**Usage Examples:**
274
275
```javascript
276
Walker('/some/path')
277
.on('error', function(er, entry, stat) {
278
if (er instanceof Walker.UnknownFileTypeError) {
279
console.warn('Unknown file type for:', entry);
280
} else {
281
console.error('Other error:', er.message);
282
}
283
});
284
```
285
286
## Complete Example
287
288
```javascript
289
const Walker = require('walker');
290
291
Walker('/etc/')
292
.filterDir(function(dir, stat) {
293
if (dir === '/etc/pam.d') {
294
console.warn('Skipping /etc/pam.d and children');
295
return false;
296
}
297
return true;
298
})
299
.on('entry', function(entry, stat) {
300
console.log('Got entry: ' + entry);
301
})
302
.on('dir', function(dir, stat) {
303
console.log('Got directory: ' + dir);
304
})
305
.on('file', function(file, stat) {
306
console.log('Got file: ' + file);
307
})
308
.on('symlink', function(symlink, stat) {
309
console.log('Got symlink: ' + symlink);
310
})
311
.on('blockDevice', function(blockDevice, stat) {
312
console.log('Got blockDevice: ' + blockDevice);
313
})
314
.on('fifo', function(fifo, stat) {
315
console.log('Got fifo: ' + fifo);
316
})
317
.on('socket', function(socket, stat) {
318
console.log('Got socket: ' + socket);
319
})
320
.on('characterDevice', function(characterDevice, stat) {
321
console.log('Got characterDevice: ' + characterDevice);
322
})
323
.on('error', function(er, entry, stat) {
324
console.log('Got error ' + er + ' on entry ' + entry);
325
})
326
.on('end', function() {
327
console.log('All files traversed.');
328
});
329
```