1 | 'use strict';
|
2 | const fs = require('fs');
|
3 | const path = require('path');
|
4 | const async = require('async');
|
5 | const pathExists = require('path-exists');
|
6 | const untildify = require('untildify');
|
7 |
|
8 | const home = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'];
|
9 | const pascal = str => str[0].toUpperCase() + str.slice(1);
|
10 | const parseHome = str => str.split(path.sep).slice(0,3).join(path.sep) === home ? str : path.join(home, str);
|
11 |
|
12 | module.exports = (ptc, type, cb) => {
|
13 | ptc = parseHome(untildify(ptc));
|
14 | type = Array.isArray(type) ? type.map(pascal) : pascal(type);
|
15 |
|
16 | pathExists(ptc)
|
17 | .then(result => {
|
18 | if (!result) return cb(new Error(`${ptc} is not a valid path\n`));
|
19 |
|
20 | async.waterfall([
|
21 | async.apply(read, ptc),
|
22 | filter
|
23 | ], (err, ofType) => {
|
24 | if (err) return cb(err);
|
25 |
|
26 | cb(null, ofType);
|
27 | })
|
28 | })
|
29 |
|
30 | function read(pathTo, cb) {
|
31 | fs.readdir(pathTo, (err, contents) => {
|
32 | if (err) return cb(err);
|
33 |
|
34 | cb(null, contents);
|
35 | })
|
36 | }
|
37 |
|
38 | function filter(contents, cb) {
|
39 | async.filter(contents, (item, cb) => {
|
40 | fs.stat(path.join(ptc, item), (err, stats) => {
|
41 | if (err) return cb(err);
|
42 |
|
43 | cb(null, Array.isArray(type) ? type.some(t => stats['is' + t]()) : stats['is' + type]());
|
44 | })
|
45 | }, (err, filtered) => {
|
46 | if (err) return cb(err);
|
47 |
|
48 | cb(null, filtered);
|
49 | })
|
50 | }
|
51 | }
|