| 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 |
| } |