'use strict'; const Promise = require("bluebird"); const fs = Promise.promisifyAll(require("fs")); const path = require("path"); const naturalSort = require("natural-sort"); function statComplete(target) { return Promise.try(() => { return Promise.try(() => { return fs.lstatAsync(target); }).then((stats) => { if (stats.isSymbolicLink()) { return Promise.try(() => { return fs.statAsync(target); }).then((targetStats) => { return { stats: targetStats, linkStats: stats } }); } else { return { stats: stats } } }); }) } function getType(stats) { if (stats.isSymbolicLink()) { return "link"; } else if (stats.isDirectory()) { return "folder"; } else if (stats.isFile()) { return "file"; } else { return "other"; } } module.exports = function(basePath) { return Promise.try(() => { return fs.readdirAsync(basePath); }).map((entry) => { let fullPath = path.join(basePath, entry); return Promise.try(() => { return statComplete(fullPath); }).then((stats) => { let type, targetType; if (stats.linkStats != null) { type = "link"; targetType = getType(stats.stats); } else { type = getType(stats.stats); targetType = type; } return { type: type, targetType: targetType, name: entry, path: fullPath, modified: stats.stats.mtime, size: stats.stats.size } }) }).then((entries) => { let sorter = naturalSort(); return entries.sort((entryA, entryB) => { if (entryA.targetType == "folder" && entryB.targetType != "folder") { return -1; } else if (entryB.targetType == "folder" && entryA.targetType != "folder") { return 1; } else { return sorter(entryA.name, entryB.name); } }); }); }