-
Notifications
You must be signed in to change notification settings - Fork 0
/
arborist.js
66 lines (53 loc) · 1.51 KB
/
arborist.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
const Path = require('path');
const fs = require('fs').promises;
const defaultOptions = {
typeKey: 'type',
body: false,
exclude: [],
path: []
};
async function step (p, o, m, l) {
let stats = await fs.lstat(p);
let pathObj = Path.parse(p);
let info = {
path: p,
[o.typeKey]: undefined
};
if (o && o.path && Array.isArray(o.path)) {
o.path.forEach(x => {
if (pathObj[x]) info[x] = pathObj[x];
});
}
if (o && o.stats && Array.isArray(o.stats)) {
o.stats.forEach(x => {
if (stats[x]) info[x] = stats[x];
});
}
if (stats.isFile()) {
info[o.typeKey] = 'file';
info.extension = pathObj.ext;
if (o.body) info[o.body] = await fs.readFile(p);
}
if (stats.isDirectory()) {
info[o.typeKey] = 'directory';
let childNodes = await fs.readdir(p).then(d => d.map(c => {
return { base: c, path: Path.join(p, c) };
}));
if (o && o.exclude && Array.isArray(o.exclude)) {
let exclusions = o.exclude.map(r => new RegExp(r));
childNodes = childNodes.filter(c => {
return exclusions.reduce((o, e) => {
if (o === true) return !e.test(c.base) && !e.test(c.path);
else return false;
}, true);
});
}
if (!m || l + 1 < m) info.children = await Promise.all(childNodes.map((c) => step(c.path, o, m, l+1)));
else info.children = childNodes;
}
return info;
}
module.exports = function (path, options, m) {
const o = Object.assign(defaultOptions, options);
return step(path, o, m, 0);
};