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