var fs = require ('graceful-fs') var dz = require ('dezalgo') var once = require ('once') var path = require ('path') var debug = require ('debuglog') ('rds') module . exports = readdir readdir.sync = readdirSync function readdir (dir, cb) { fs . readdir (dir, function (er, kids) { if (er) return cb (er) debug ('dir=%j, kids=%j', dir, kids) readScopes (dir, kids, function (er, data) { if (er) return cb (er) // Sort for bonus consistency points data = data . sort (function (a, b) { return a > b ? 1 : -1 }) return cb (null, data) }) }) } function readdirSync (dir) { var kids = fs . readdirSync (dir) debug ('dir=%j, kids=%j', dir, kids) var data = readScopesSync (dir, kids) // Sort for bonus consistency points data = data . sort (function (a, b) { return a > b ? 1 : -1 }) return data } // Turn [ 'a', '@scope' ] into // ['a', '@scope/foo', '@scope/bar'] function readScopes (root, kids, cb) { var scopes = kids . filter (function (kid) { return kid . charAt (0) === '@' }) kids = kids . filter (function (kid) { return kid . charAt (0) !== '@' }) debug ('scopes=%j', scopes) if (scopes . length === 0) dz (cb) (null, kids) // prevent maybe-sync zalgo release cb = once (cb) var l = scopes . length scopes . forEach (function (scope) { var scopedir = path . resolve (root, scope) debug ('root=%j scope=%j scopedir=%j', root, scope, scopedir) fs . readdir (scopedir, then . bind (null, scope)) }) function then (scope, er, scopekids) { if (er) return cb (er) // XXX: Not sure how old this node bug is. Maybe superstition? scopekids = scopekids . filter (function (scopekid) { return !(scopekid === '.' || scopekid === '..' || !scopekid) }) kids . push . apply (kids, scopekids . map (function (scopekid) { return scope + '/' + scopekid })) debug ('scope=%j scopekids=%j kids=%j', scope, scopekids, kids) if (--l === 0) cb (null, kids) } } function readScopesSync (root, kids) { var scopes = kids . filter (function (kid) { return kid . charAt (0) === '@' }) kids = kids . filter (function (kid) { return kid . charAt (0) !== '@' }) debug ('scopes=%j', scopes) if (scopes . length === 0) return kids var l = scopes . length scopes . forEach (function (scope) { var scopedir = path . resolve (root, scope) debug ('root=%j scope=%j scopedir=%j', root, scope, scopedir) then (scope, fs . readdirSync (scopedir)) }) function then (scope, scopekids) { // XXX: Not sure how old this node bug is. Maybe superstition? scopekids = scopekids . filter (function (scopekid) { return !(scopekid === '.' || scopekid === '..' || !scopekid) }) kids . push . apply (kids, scopekids . map (function (scopekid) { return scope + '/' + scopekid })) debug ('scope=%j scopekids=%j kids=%j', scope, scopekids, kids) } return kids }