UNPKG

1.58 kBJavaScriptView Raw
1var assert = require('assert')
2var fs = require('fs')
3var path = require('path')
4var Readable = require('stream').Readable
5var util = require('util')
6var assign = require('./assign')
7
8function Walker (dir, options) {
9 assert.strictEqual(typeof dir, 'string', '`dir` parameter should be of type string. Got type: ' + typeof dir)
10 var defaultStreamOptions = { objectMode: true }
11 var defaultOpts = { queueMethod: 'shift', pathSorter: undefined }
12 options = assign(defaultOpts, options, defaultStreamOptions)
13
14 Readable.call(this, options)
15 this.root = path.resolve(dir)
16 this.paths = [this.root]
17 this.options = options
18 this.fs = options.fs || fs // mock-fs
19}
20util.inherits(Walker, Readable)
21
22Walker.prototype._read = function () {
23 if (this.paths.length === 0) return this.push(null)
24 var self = this
25 var pathItem = this.paths[this.options.queueMethod]()
26
27 self.fs.lstat(pathItem, function (err, stats) {
28 var item = { path: pathItem, stats: stats }
29 if (err) return self.emit('error', err, item)
30 if (!stats.isDirectory()) return self.push(item)
31
32 self.fs.readdir(pathItem, function (err, pathItems) {
33 if (err) {
34 self.push(item)
35 return self.emit('error', err, item)
36 }
37
38 pathItems = pathItems.map(function (part) { return path.join(pathItem, part) })
39 if (self.options.pathSorter) pathItems.sort(self.options.pathSorter)
40 pathItems.forEach(function (pi) { self.paths.push(pi) })
41
42 self.push(item)
43 })
44 })
45}
46
47function walk (root, options) {
48 return new Walker(root, options)
49}
50
51module.exports = walk