UNPKG

3.32 kBJavaScriptView Raw
1const { sep, resolve: pathResolve } = require("path");
2const { cleanPath } = require("../utils");
3const fns = require("./fns");
4const readdirOpts = { withFileTypes: true };
5
6function init(dir, options, callback, isSync) {
7 if (options.resolvePaths) dir = pathResolve(dir);
8 if (options.normalizePath) dir = cleanPath(dir);
9
10 /* We use a local state object instead of direct global variables so that each function
11 * execution is independent of each other.
12 */
13 const state = {
14 // Perf: we explicitly tell the compiler to optimize for String arrays
15 paths: [""].slice(0, 0),
16 queue: 0,
17 counts: { files: 0, dirs: 0 },
18 options,
19 callback,
20 };
21
22 /*
23 * Perf: We conditionally change functions according to options. This gives a slight
24 * performance boost. Since these functions are so small, they are automatically inlined
25 * by the engine so there's no function call overhead (in most cases).
26 */
27 buildFunctions(options, isSync);
28
29 return { state, callbackInvoker, dir };
30}
31
32function walkSingleDir(walk, state, dir, dirents, currentDepth, callback) {
33 pushDir(dir, state.paths);
34 // in cases where we have / as path
35 if (dir === sep) dir = "";
36
37 const files = getArray(state);
38
39 for (var i = 0; i < dirents.length; ++i) {
40 const dirent = dirents[i];
41
42 if (dirent.isFile()) {
43 const filename = joinPath(dirent.name, dir);
44 pushFile(filename, files, dir, state);
45 } else if (dirent.isDirectory()) {
46 let dirPath = `${dir}${sep}${dirent.name}`;
47 walkDir(walk, state, dirPath, dirent.name, currentDepth - 1, callback);
48 }
49 }
50
51 groupFiles(dir, files, state);
52}
53
54function buildFunctions(options, isSync) {
55 const {
56 filters,
57 onlyCountsVar,
58 includeBasePath,
59 includeDirs,
60 groupVar,
61 excludeFn,
62 } = options;
63
64 buildPushFile(filters, onlyCountsVar);
65
66 pushDir = includeDirs ? fns.pushDir : fns.empty;
67
68 // build function for joining paths
69 joinPath = includeBasePath ? fns.joinPathWithBasePath : fns.joinPath;
70
71 // build recursive walk directory function
72 walkDir = excludeFn ? fns.walkDirExclude(excludeFn) : fns.walkDir;
73
74 // build groupFiles function for grouping files
75 groupFiles = groupVar ? fns.groupFiles : fns.empty;
76 getArray = groupVar ? fns.getArrayGroup : fns.getArray;
77
78 buildCallbackInvoker(onlyCountsVar, isSync);
79}
80
81module.exports = { buildFunctions, init, walkSingleDir, readdirOpts };
82
83function buildPushFile(filters, onlyCountsVar) {
84 if (filters.length && onlyCountsVar) {
85 pushFile = fns.pushFileFilterAndCount(filters);
86 } else if (filters.length) {
87 pushFile = fns.pushFileFilter(filters);
88 } else if (onlyCountsVar) {
89 pushFile = fns.pushFileCount;
90 } else {
91 pushFile = fns.pushFile;
92 }
93}
94
95function buildCallbackInvoker(onlyCountsVar, isSync) {
96 if (onlyCountsVar) {
97 callbackInvoker = isSync
98 ? fns.callbackInvokerOnlyCountsSync
99 : fns.callbackInvokerOnlyCountsAsync;
100 } else {
101 callbackInvoker = isSync
102 ? fns.callbackInvokerDefaultSync
103 : fns.callbackInvokerDefaultAsync;
104 }
105}
106
107/* Dummies that will be filled later conditionally based on options */
108var pushFile = fns.empty;
109var pushDir = fns.empty;
110var walkDir = fns.empty;
111var joinPath = fns.empty;
112var groupFiles = fns.empty;
113var callbackInvoker = fns.empty;
114var getArray = fns.empty;