summaryrefslogtreecommitdiff
path: root/node_modules/fdir/dist/index.mjs
diff options
context:
space:
mode:
authorShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
committerShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
commit7a52ddeba2a68388b544f529d2d92104420f77b0 (patch)
tree15ddd47457a2cb4a96060747437d36474e4f6b4e /node_modules/fdir/dist/index.mjs
parent53d6ae2b5568437afa5e4995580a3fb679b7b91b (diff)
Changed from static to 11ty!
Diffstat (limited to 'node_modules/fdir/dist/index.mjs')
-rw-r--r--node_modules/fdir/dist/index.mjs570
1 files changed, 570 insertions, 0 deletions
diff --git a/node_modules/fdir/dist/index.mjs b/node_modules/fdir/dist/index.mjs
new file mode 100644
index 0000000..5c37e09
--- /dev/null
+++ b/node_modules/fdir/dist/index.mjs
@@ -0,0 +1,570 @@
+import { createRequire } from "module";
+import { basename, dirname, normalize, relative, resolve, sep } from "path";
+import * as nativeFs from "fs";
+
+//#region rolldown:runtime
+var __require = /* @__PURE__ */ createRequire(import.meta.url);
+
+//#endregion
+//#region src/utils.ts
+function cleanPath(path) {
+ let normalized = normalize(path);
+ if (normalized.length > 1 && normalized[normalized.length - 1] === sep) normalized = normalized.substring(0, normalized.length - 1);
+ return normalized;
+}
+const SLASHES_REGEX = /[\\/]/g;
+function convertSlashes(path, separator) {
+ return path.replace(SLASHES_REGEX, separator);
+}
+const WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i;
+function isRootDirectory(path) {
+ return path === "/" || WINDOWS_ROOT_DIR_REGEX.test(path);
+}
+function normalizePath(path, options) {
+ const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options;
+ const pathNeedsCleaning = process.platform === "win32" && path.includes("/") || path.startsWith(".");
+ if (resolvePaths) path = resolve(path);
+ if (normalizePath$1 || pathNeedsCleaning) path = cleanPath(path);
+ if (path === ".") return "";
+ const needsSeperator = path[path.length - 1] !== pathSeparator;
+ return convertSlashes(needsSeperator ? path + pathSeparator : path, pathSeparator);
+}
+
+//#endregion
+//#region src/api/functions/join-path.ts
+function joinPathWithBasePath(filename, directoryPath) {
+ return directoryPath + filename;
+}
+function joinPathWithRelativePath(root, options) {
+ return function(filename, directoryPath) {
+ const sameRoot = directoryPath.startsWith(root);
+ if (sameRoot) return directoryPath.slice(root.length) + filename;
+ else return convertSlashes(relative(root, directoryPath), options.pathSeparator) + options.pathSeparator + filename;
+ };
+}
+function joinPath(filename) {
+ return filename;
+}
+function joinDirectoryPath(filename, directoryPath, separator) {
+ return directoryPath + filename + separator;
+}
+function build$7(root, options) {
+ const { relativePaths, includeBasePath } = options;
+ return relativePaths && root ? joinPathWithRelativePath(root, options) : includeBasePath ? joinPathWithBasePath : joinPath;
+}
+
+//#endregion
+//#region src/api/functions/push-directory.ts
+function pushDirectoryWithRelativePath(root) {
+ return function(directoryPath, paths) {
+ paths.push(directoryPath.substring(root.length) || ".");
+ };
+}
+function pushDirectoryFilterWithRelativePath(root) {
+ return function(directoryPath, paths, filters) {
+ const relativePath = directoryPath.substring(root.length) || ".";
+ if (filters.every((filter) => filter(relativePath, true))) paths.push(relativePath);
+ };
+}
+const pushDirectory = (directoryPath, paths) => {
+ paths.push(directoryPath || ".");
+};
+const pushDirectoryFilter = (directoryPath, paths, filters) => {
+ const path = directoryPath || ".";
+ if (filters.every((filter) => filter(path, true))) paths.push(path);
+};
+const empty$2 = () => {};
+function build$6(root, options) {
+ const { includeDirs, filters, relativePaths } = options;
+ if (!includeDirs) return empty$2;
+ if (relativePaths) return filters && filters.length ? pushDirectoryFilterWithRelativePath(root) : pushDirectoryWithRelativePath(root);
+ return filters && filters.length ? pushDirectoryFilter : pushDirectory;
+}
+
+//#endregion
+//#region src/api/functions/push-file.ts
+const pushFileFilterAndCount = (filename, _paths, counts, filters) => {
+ if (filters.every((filter) => filter(filename, false))) counts.files++;
+};
+const pushFileFilter = (filename, paths, _counts, filters) => {
+ if (filters.every((filter) => filter(filename, false))) paths.push(filename);
+};
+const pushFileCount = (_filename, _paths, counts, _filters) => {
+ counts.files++;
+};
+const pushFile = (filename, paths) => {
+ paths.push(filename);
+};
+const empty$1 = () => {};
+function build$5(options) {
+ const { excludeFiles, filters, onlyCounts } = options;
+ if (excludeFiles) return empty$1;
+ if (filters && filters.length) return onlyCounts ? pushFileFilterAndCount : pushFileFilter;
+ else if (onlyCounts) return pushFileCount;
+ else return pushFile;
+}
+
+//#endregion
+//#region src/api/functions/get-array.ts
+const getArray = (paths) => {
+ return paths;
+};
+const getArrayGroup = () => {
+ return [""].slice(0, 0);
+};
+function build$4(options) {
+ return options.group ? getArrayGroup : getArray;
+}
+
+//#endregion
+//#region src/api/functions/group-files.ts
+const groupFiles = (groups, directory, files) => {
+ groups.push({
+ directory,
+ files,
+ dir: directory
+ });
+};
+const empty = () => {};
+function build$3(options) {
+ return options.group ? groupFiles : empty;
+}
+
+//#endregion
+//#region src/api/functions/resolve-symlink.ts
+const resolveSymlinksAsync = function(path, state, callback$1) {
+ const { queue, fs, options: { suppressErrors } } = state;
+ queue.enqueue();
+ fs.realpath(path, (error, resolvedPath) => {
+ if (error) return queue.dequeue(suppressErrors ? null : error, state);
+ fs.stat(resolvedPath, (error$1, stat) => {
+ if (error$1) return queue.dequeue(suppressErrors ? null : error$1, state);
+ if (stat.isDirectory() && isRecursive(path, resolvedPath, state)) return queue.dequeue(null, state);
+ callback$1(stat, resolvedPath);
+ queue.dequeue(null, state);
+ });
+ });
+};
+const resolveSymlinks = function(path, state, callback$1) {
+ const { queue, fs, options: { suppressErrors } } = state;
+ queue.enqueue();
+ try {
+ const resolvedPath = fs.realpathSync(path);
+ const stat = fs.statSync(resolvedPath);
+ if (stat.isDirectory() && isRecursive(path, resolvedPath, state)) return;
+ callback$1(stat, resolvedPath);
+ } catch (e) {
+ if (!suppressErrors) throw e;
+ }
+};
+function build$2(options, isSynchronous) {
+ if (!options.resolveSymlinks || options.excludeSymlinks) return null;
+ return isSynchronous ? resolveSymlinks : resolveSymlinksAsync;
+}
+function isRecursive(path, resolved, state) {
+ if (state.options.useRealPaths) return isRecursiveUsingRealPaths(resolved, state);
+ let parent = dirname(path);
+ let depth = 1;
+ while (parent !== state.root && depth < 2) {
+ const resolvedPath = state.symlinks.get(parent);
+ const isSameRoot = !!resolvedPath && (resolvedPath === resolved || resolvedPath.startsWith(resolved) || resolved.startsWith(resolvedPath));
+ if (isSameRoot) depth++;
+ else parent = dirname(parent);
+ }
+ state.symlinks.set(path, resolved);
+ return depth > 1;
+}
+function isRecursiveUsingRealPaths(resolved, state) {
+ return state.visited.includes(resolved + state.options.pathSeparator);
+}
+
+//#endregion
+//#region src/api/functions/invoke-callback.ts
+const onlyCountsSync = (state) => {
+ return state.counts;
+};
+const groupsSync = (state) => {
+ return state.groups;
+};
+const defaultSync = (state) => {
+ return state.paths;
+};
+const limitFilesSync = (state) => {
+ return state.paths.slice(0, state.options.maxFiles);
+};
+const onlyCountsAsync = (state, error, callback$1) => {
+ report(error, callback$1, state.counts, state.options.suppressErrors);
+ return null;
+};
+const defaultAsync = (state, error, callback$1) => {
+ report(error, callback$1, state.paths, state.options.suppressErrors);
+ return null;
+};
+const limitFilesAsync = (state, error, callback$1) => {
+ report(error, callback$1, state.paths.slice(0, state.options.maxFiles), state.options.suppressErrors);
+ return null;
+};
+const groupsAsync = (state, error, callback$1) => {
+ report(error, callback$1, state.groups, state.options.suppressErrors);
+ return null;
+};
+function report(error, callback$1, output, suppressErrors) {
+ if (error && !suppressErrors) callback$1(error, output);
+ else callback$1(null, output);
+}
+function build$1(options, isSynchronous) {
+ const { onlyCounts, group, maxFiles } = options;
+ if (onlyCounts) return isSynchronous ? onlyCountsSync : onlyCountsAsync;
+ else if (group) return isSynchronous ? groupsSync : groupsAsync;
+ else if (maxFiles) return isSynchronous ? limitFilesSync : limitFilesAsync;
+ else return isSynchronous ? defaultSync : defaultAsync;
+}
+
+//#endregion
+//#region src/api/functions/walk-directory.ts
+const readdirOpts = { withFileTypes: true };
+const walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
+ state.queue.enqueue();
+ if (currentDepth < 0) return state.queue.dequeue(null, state);
+ const { fs } = state;
+ state.visited.push(crawlPath);
+ state.counts.directories++;
+ fs.readdir(crawlPath || ".", readdirOpts, (error, entries = []) => {
+ callback$1(entries, directoryPath, currentDepth);
+ state.queue.dequeue(state.options.suppressErrors ? null : error, state);
+ });
+};
+const walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
+ const { fs } = state;
+ if (currentDepth < 0) return;
+ state.visited.push(crawlPath);
+ state.counts.directories++;
+ let entries = [];
+ try {
+ entries = fs.readdirSync(crawlPath || ".", readdirOpts);
+ } catch (e) {
+ if (!state.options.suppressErrors) throw e;
+ }
+ callback$1(entries, directoryPath, currentDepth);
+};
+function build(isSynchronous) {
+ return isSynchronous ? walkSync : walkAsync;
+}
+
+//#endregion
+//#region src/api/queue.ts
+/**
+* This is a custom stateless queue to track concurrent async fs calls.
+* It increments a counter whenever a call is queued and decrements it
+* as soon as it completes. When the counter hits 0, it calls onQueueEmpty.
+*/
+var Queue = class {
+ count = 0;
+ constructor(onQueueEmpty) {
+ this.onQueueEmpty = onQueueEmpty;
+ }
+ enqueue() {
+ this.count++;
+ return this.count;
+ }
+ dequeue(error, output) {
+ if (this.onQueueEmpty && (--this.count <= 0 || error)) {
+ this.onQueueEmpty(error, output);
+ if (error) {
+ output.controller.abort();
+ this.onQueueEmpty = void 0;
+ }
+ }
+ }
+};
+
+//#endregion
+//#region src/api/counter.ts
+var Counter = class {
+ _files = 0;
+ _directories = 0;
+ set files(num) {
+ this._files = num;
+ }
+ get files() {
+ return this._files;
+ }
+ set directories(num) {
+ this._directories = num;
+ }
+ get directories() {
+ return this._directories;
+ }
+ /**
+ * @deprecated use `directories` instead
+ */
+ /* c8 ignore next 3 */
+ get dirs() {
+ return this._directories;
+ }
+};
+
+//#endregion
+//#region src/api/aborter.ts
+/**
+* AbortController is not supported on Node 14 so we use this until we can drop
+* support for Node 14.
+*/
+var Aborter = class {
+ aborted = false;
+ abort() {
+ this.aborted = true;
+ }
+};
+
+//#endregion
+//#region src/api/walker.ts
+var Walker = class {
+ root;
+ isSynchronous;
+ state;
+ joinPath;
+ pushDirectory;
+ pushFile;
+ getArray;
+ groupFiles;
+ resolveSymlink;
+ walkDirectory;
+ callbackInvoker;
+ constructor(root, options, callback$1) {
+ this.isSynchronous = !callback$1;
+ this.callbackInvoker = build$1(options, this.isSynchronous);
+ this.root = normalizePath(root, options);
+ this.state = {
+ root: isRootDirectory(this.root) ? this.root : this.root.slice(0, -1),
+ paths: [""].slice(0, 0),
+ groups: [],
+ counts: new Counter(),
+ options,
+ queue: new Queue((error, state) => this.callbackInvoker(state, error, callback$1)),
+ symlinks: /* @__PURE__ */ new Map(),
+ visited: [""].slice(0, 0),
+ controller: new Aborter(),
+ fs: options.fs || nativeFs
+ };
+ this.joinPath = build$7(this.root, options);
+ this.pushDirectory = build$6(this.root, options);
+ this.pushFile = build$5(options);
+ this.getArray = build$4(options);
+ this.groupFiles = build$3(options);
+ this.resolveSymlink = build$2(options, this.isSynchronous);
+ this.walkDirectory = build(this.isSynchronous);
+ }
+ start() {
+ this.pushDirectory(this.root, this.state.paths, this.state.options.filters);
+ this.walkDirectory(this.state, this.root, this.root, this.state.options.maxDepth, this.walk);
+ return this.isSynchronous ? this.callbackInvoker(this.state, null) : null;
+ }
+ walk = (entries, directoryPath, depth) => {
+ const { paths, options: { filters, resolveSymlinks: resolveSymlinks$1, excludeSymlinks, exclude, maxFiles, signal, useRealPaths, pathSeparator }, controller } = this.state;
+ if (controller.aborted || signal && signal.aborted || maxFiles && paths.length > maxFiles) return;
+ const files = this.getArray(this.state.paths);
+ for (let i = 0; i < entries.length; ++i) {
+ const entry = entries[i];
+ if (entry.isFile() || entry.isSymbolicLink() && !resolveSymlinks$1 && !excludeSymlinks) {
+ const filename = this.joinPath(entry.name, directoryPath);
+ this.pushFile(filename, files, this.state.counts, filters);
+ } else if (entry.isDirectory()) {
+ let path = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
+ if (exclude && exclude(entry.name, path)) continue;
+ this.pushDirectory(path, paths, filters);
+ this.walkDirectory(this.state, path, path, depth - 1, this.walk);
+ } else if (this.resolveSymlink && entry.isSymbolicLink()) {
+ let path = joinPathWithBasePath(entry.name, directoryPath);
+ this.resolveSymlink(path, this.state, (stat, resolvedPath) => {
+ if (stat.isDirectory()) {
+ resolvedPath = normalizePath(resolvedPath, this.state.options);
+ if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path + pathSeparator)) return;
+ this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path + pathSeparator, depth - 1, this.walk);
+ } else {
+ resolvedPath = useRealPaths ? resolvedPath : path;
+ const filename = basename(resolvedPath);
+ const directoryPath$1 = normalizePath(dirname(resolvedPath), this.state.options);
+ resolvedPath = this.joinPath(filename, directoryPath$1);
+ this.pushFile(resolvedPath, files, this.state.counts, filters);
+ }
+ });
+ }
+ }
+ this.groupFiles(this.state.groups, directoryPath, files);
+ };
+};
+
+//#endregion
+//#region src/api/async.ts
+function promise(root, options) {
+ return new Promise((resolve$1, reject) => {
+ callback(root, options, (err, output) => {
+ if (err) return reject(err);
+ resolve$1(output);
+ });
+ });
+}
+function callback(root, options, callback$1) {
+ let walker = new Walker(root, options, callback$1);
+ walker.start();
+}
+
+//#endregion
+//#region src/api/sync.ts
+function sync(root, options) {
+ const walker = new Walker(root, options);
+ return walker.start();
+}
+
+//#endregion
+//#region src/builder/api-builder.ts
+var APIBuilder = class {
+ constructor(root, options) {
+ this.root = root;
+ this.options = options;
+ }
+ withPromise() {
+ return promise(this.root, this.options);
+ }
+ withCallback(cb) {
+ callback(this.root, this.options, cb);
+ }
+ sync() {
+ return sync(this.root, this.options);
+ }
+};
+
+//#endregion
+//#region src/builder/index.ts
+let pm = null;
+/* c8 ignore next 6 */
+try {
+ __require.resolve("picomatch");
+ pm = __require("picomatch");
+} catch {}
+var Builder = class {
+ globCache = {};
+ options = {
+ maxDepth: Infinity,
+ suppressErrors: true,
+ pathSeparator: sep,
+ filters: []
+ };
+ globFunction;
+ constructor(options) {
+ this.options = {
+ ...this.options,
+ ...options
+ };
+ this.globFunction = this.options.globFunction;
+ }
+ group() {
+ this.options.group = true;
+ return this;
+ }
+ withPathSeparator(separator) {
+ this.options.pathSeparator = separator;
+ return this;
+ }
+ withBasePath() {
+ this.options.includeBasePath = true;
+ return this;
+ }
+ withRelativePaths() {
+ this.options.relativePaths = true;
+ return this;
+ }
+ withDirs() {
+ this.options.includeDirs = true;
+ return this;
+ }
+ withMaxDepth(depth) {
+ this.options.maxDepth = depth;
+ return this;
+ }
+ withMaxFiles(limit) {
+ this.options.maxFiles = limit;
+ return this;
+ }
+ withFullPaths() {
+ this.options.resolvePaths = true;
+ this.options.includeBasePath = true;
+ return this;
+ }
+ withErrors() {
+ this.options.suppressErrors = false;
+ return this;
+ }
+ withSymlinks({ resolvePaths = true } = {}) {
+ this.options.resolveSymlinks = true;
+ this.options.useRealPaths = resolvePaths;
+ return this.withFullPaths();
+ }
+ withAbortSignal(signal) {
+ this.options.signal = signal;
+ return this;
+ }
+ normalize() {
+ this.options.normalizePath = true;
+ return this;
+ }
+ filter(predicate) {
+ this.options.filters.push(predicate);
+ return this;
+ }
+ onlyDirs() {
+ this.options.excludeFiles = true;
+ this.options.includeDirs = true;
+ return this;
+ }
+ exclude(predicate) {
+ this.options.exclude = predicate;
+ return this;
+ }
+ onlyCounts() {
+ this.options.onlyCounts = true;
+ return this;
+ }
+ crawl(root) {
+ return new APIBuilder(root || ".", this.options);
+ }
+ withGlobFunction(fn) {
+ this.globFunction = fn;
+ return this;
+ }
+ /**
+ * @deprecated Pass options using the constructor instead:
+ * ```ts
+ * new fdir(options).crawl("/path/to/root");
+ * ```
+ * This method will be removed in v7.0
+ */
+ /* c8 ignore next 4 */
+ crawlWithOptions(root, options) {
+ this.options = {
+ ...this.options,
+ ...options
+ };
+ return new APIBuilder(root || ".", this.options);
+ }
+ glob(...patterns) {
+ if (this.globFunction) return this.globWithOptions(patterns);
+ return this.globWithOptions(patterns, ...[{ dot: true }]);
+ }
+ globWithOptions(patterns, ...options) {
+ const globFn = this.globFunction || pm;
+ /* c8 ignore next 5 */
+ if (!globFn) throw new Error("Please specify a glob function to use glob matching.");
+ var isMatch = this.globCache[patterns.join("\0")];
+ if (!isMatch) {
+ isMatch = globFn(patterns, ...options);
+ this.globCache[patterns.join("\0")] = isMatch;
+ }
+ this.options.filters.push((path) => isMatch(path));
+ return this;
+ }
+};
+
+//#endregion
+export { Builder as fdir }; \ No newline at end of file