UNPKG

4.46 kBJavaScriptView Raw
1"use strict";
2
3const pathUtil = require("path");
4const treeWalker = require("./utils/tree_walker");
5const inspect = require("./inspect");
6const matcher = require("./utils/matcher");
7const validate = require("./utils/validate");
8
9const validateInput = (methodName, path, options) => {
10 const methodSignature = `${methodName}([path], options)`;
11 validate.argument(methodSignature, "path", path, ["string"]);
12 validate.options(methodSignature, "options", options, {
13 matching: ["string", "array of string"],
14 files: ["boolean"],
15 directories: ["boolean"],
16 recursive: ["boolean"]
17 });
18};
19
20const normalizeOptions = options => {
21 const opts = options || {};
22 // defaults:
23 if (opts.files === undefined) {
24 opts.files = true;
25 }
26 if (opts.directories === undefined) {
27 opts.directories = false;
28 }
29 if (opts.recursive === undefined) {
30 opts.recursive = true;
31 }
32 return opts;
33};
34
35const processFoundObjects = (foundObjects, cwd) => {
36 return foundObjects.map(inspectObj => {
37 return pathUtil.relative(cwd, inspectObj.absolutePath);
38 });
39};
40
41const generatePathDoesntExistError = path => {
42 const err = new Error(`Path you want to find stuff in doesn't exist ${path}`);
43 err.code = "ENOENT";
44 return err;
45};
46
47const generatePathNotDirectoryError = path => {
48 const err = new Error(
49 `Path you want to find stuff in must be a directory ${path}`
50 );
51 err.code = "ENOTDIR";
52 return err;
53};
54
55// ---------------------------------------------------------
56// Sync
57// ---------------------------------------------------------
58
59const findSync = (path, options) => {
60 const foundInspectObjects = [];
61 const matchesAnyOfGlobs = matcher.create(path, options.matching);
62
63 let maxLevelsDeep = Infinity;
64 if (options.recursive === false) {
65 maxLevelsDeep = 1;
66 }
67
68 treeWalker.sync(
69 path,
70 {
71 maxLevelsDeep,
72 inspectOptions: {
73 absolutePath: true,
74 symlinks: "follow"
75 }
76 },
77 (itemPath, item) => {
78 if (itemPath !== path && matchesAnyOfGlobs(itemPath)) {
79 if (
80 (item.type === "file" && options.files === true) ||
81 (item.type === "dir" && options.directories === true)
82 ) {
83 foundInspectObjects.push(item);
84 }
85 }
86 }
87 );
88
89 return processFoundObjects(foundInspectObjects, options.cwd);
90};
91
92const findSyncInit = (path, options) => {
93 const entryPointInspect = inspect.sync(path, { symlinks: "follow" });
94 if (entryPointInspect === undefined) {
95 throw generatePathDoesntExistError(path);
96 } else if (entryPointInspect.type !== "dir") {
97 throw generatePathNotDirectoryError(path);
98 }
99
100 return findSync(path, normalizeOptions(options));
101};
102
103// ---------------------------------------------------------
104// Async
105// ---------------------------------------------------------
106
107const findAsync = (path, options) => {
108 return new Promise((resolve, reject) => {
109 const foundInspectObjects = [];
110 const matchesAnyOfGlobs = matcher.create(path, options.matching);
111
112 let maxLevelsDeep = Infinity;
113 if (options.recursive === false) {
114 maxLevelsDeep = 1;
115 }
116
117 const walker = treeWalker
118 .stream(path, {
119 maxLevelsDeep,
120 inspectOptions: {
121 absolutePath: true,
122 symlinks: "follow"
123 }
124 })
125 .on("readable", () => {
126 const data = walker.read();
127 if (data && data.path !== path && matchesAnyOfGlobs(data.path)) {
128 const item = data.item;
129 if (
130 (item.type === "file" && options.files === true) ||
131 (item.type === "dir" && options.directories === true)
132 ) {
133 foundInspectObjects.push(item);
134 }
135 }
136 })
137 .on("error", reject)
138 .on("end", () => {
139 resolve(processFoundObjects(foundInspectObjects, options.cwd));
140 });
141 });
142};
143
144const findAsyncInit = (path, options) => {
145 return inspect.async(path, { symlinks: "follow" }).then(entryPointInspect => {
146 if (entryPointInspect === undefined) {
147 throw generatePathDoesntExistError(path);
148 } else if (entryPointInspect.type !== "dir") {
149 throw generatePathNotDirectoryError(path);
150 }
151 return findAsync(path, normalizeOptions(options));
152 });
153};
154
155// ---------------------------------------------------------
156// API
157// ---------------------------------------------------------
158
159exports.validateInput = validateInput;
160exports.sync = findSyncInit;
161exports.async = findAsyncInit;