1
0

run npm install to generate a package lock

This commit is contained in:
sashinexists
2024-12-07 13:18:31 +11:00
parent e7d08a91b5
commit 23437d228e
2501 changed files with 290663 additions and 0 deletions

10
node_modules/tiny-readdir/.editorconfig generated vendored Normal file
View File

@@ -0,0 +1,10 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

5
node_modules/tiny-readdir/dist/constants.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import type { Callback } from './types.js';
declare const NOOP_PROMISE_LIKE: {
then: (fn: Callback) => void;
};
export { NOOP_PROMISE_LIKE };

9
node_modules/tiny-readdir/dist/constants.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/* IMPORT */
/* MAIN */
const NOOP_PROMISE_LIKE = {
then: (fn) => {
fn();
}
};
/* EXPORT */
export { NOOP_PROMISE_LIKE };

4
node_modules/tiny-readdir/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import type { Dirent, Options, ResultDirectory, ResultDirectories, Result } from './types.js';
declare const readdir: (rootPath: string, options?: Options) => Promise<Result>;
export default readdir;
export type { Dirent, Options, ResultDirectory, ResultDirectories, Result };

185
node_modules/tiny-readdir/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,185 @@
/* IMPORT */
import fs from 'node:fs';
import path from 'node:path';
import makeCounterPromise from 'promise-make-counter';
import { NOOP_PROMISE_LIKE } from './constants.js';
import { castArray, isFunction } from './utils.js';
/* MAIN */
//TODO: Streamline the type of dirmaps
const readdir = (rootPath, options) => {
const followSymlinks = options?.followSymlinks ?? false;
const maxDepth = options?.depth ?? Infinity;
const maxPaths = options?.limit ?? Infinity;
const ignore = options?.ignore ?? [];
const ignores = castArray(ignore).map(ignore => isFunction(ignore) ? ignore : (targetPath) => ignore.test(targetPath));
const isIgnored = (targetPath) => ignores.some(ignore => ignore(targetPath));
const signal = options?.signal ?? { aborted: false };
const onDirents = options?.onDirents || (() => { });
const directories = [];
const directoriesNames = new Set();
const directoriesNamesToPaths = {};
const files = [];
const filesNames = new Set();
const filesNamesToPaths = {};
const symlinks = [];
const symlinksNames = new Set();
const symlinksNamesToPaths = {};
const map = {};
const visited = new Set();
const resultEmpty = { directories: [], directoriesNames: new Set(), directoriesNamesToPaths: {}, files: [], filesNames: new Set(), filesNamesToPaths: {}, symlinks: [], symlinksNames: new Set(), symlinksNamesToPaths: {}, map: {} };
const result = { directories, directoriesNames, directoriesNamesToPaths, files, filesNames, filesNamesToPaths, symlinks, symlinksNames, symlinksNamesToPaths, map };
const { promise, increment, decrement } = makeCounterPromise();
let foundPaths = 0;
const handleDirectory = (dirmap, subPath, name, depth) => {
if (visited.has(subPath))
return;
if (foundPaths >= maxPaths)
return;
foundPaths += 1;
dirmap.directories.push(subPath);
dirmap.directoriesNames.add(name);
// dirmap.directoriesNamesToPaths.propertyIsEnumerable(name) || ( dirmap.directoriesNamesToPaths[name] = [] );
// dirmap.directoriesNamesToPaths[name].push ( subPath );
directories.push(subPath);
directoriesNames.add(name);
directoriesNamesToPaths.propertyIsEnumerable(name) || (directoriesNamesToPaths[name] = []);
directoriesNamesToPaths[name].push(subPath);
visited.add(subPath);
if (depth >= maxDepth)
return;
if (foundPaths >= maxPaths)
return;
populateResultFromPath(subPath, depth + 1);
};
const handleFile = (dirmap, subPath, name) => {
if (visited.has(subPath))
return;
if (foundPaths >= maxPaths)
return;
foundPaths += 1;
dirmap.files.push(subPath);
dirmap.filesNames.add(name);
// dirmap.filesNamesToPaths.propertyIsEnumerable(name) || ( dirmap.filesNamesToPaths[name] = [] );
// dirmap.filesNamesToPaths[name].push ( subPath );
files.push(subPath);
filesNames.add(name);
filesNamesToPaths.propertyIsEnumerable(name) || (filesNamesToPaths[name] = []);
filesNamesToPaths[name].push(subPath);
visited.add(subPath);
};
const handleSymlink = (dirmap, subPath, name, depth) => {
if (visited.has(subPath))
return;
if (foundPaths >= maxPaths)
return;
foundPaths += 1;
dirmap.symlinks.push(subPath);
dirmap.symlinksNames.add(name);
// dirmap.symlinksNamesToPaths.propertyIsEnumerable(name) || ( dirmap.symlinksNamesToPaths[name] = [] );
// dirmap.symlinksNamesToPaths[name].push ( subPath );
symlinks.push(subPath);
symlinksNames.add(name);
symlinksNamesToPaths.propertyIsEnumerable(name) || (symlinksNamesToPaths[name] = []);
symlinksNamesToPaths[name].push(subPath);
visited.add(subPath);
if (!followSymlinks)
return;
if (depth >= maxDepth)
return;
if (foundPaths >= maxPaths)
return;
populateResultFromSymlink(subPath, depth + 1);
};
const handleStat = (dirmap, rootPath, name, stat, depth) => {
if (signal.aborted)
return;
if (isIgnored(rootPath))
return;
if (stat.isDirectory()) {
handleDirectory(dirmap, rootPath, name, depth);
}
else if (stat.isFile()) {
handleFile(dirmap, rootPath, name);
}
else if (stat.isSymbolicLink()) {
handleSymlink(dirmap, rootPath, name, depth);
}
};
const handleDirent = (dirmap, rootPath, dirent, depth) => {
if (signal.aborted)
return;
const separator = (rootPath === path.sep) ? '' : path.sep;
const name = dirent.name;
const subPath = `${rootPath}${separator}${name}`;
if (isIgnored(subPath))
return;
if (dirent.isDirectory()) {
handleDirectory(dirmap, subPath, name, depth);
}
else if (dirent.isFile()) {
handleFile(dirmap, subPath, name);
}
else if (dirent.isSymbolicLink()) {
handleSymlink(dirmap, subPath, name, depth);
}
};
const handleDirents = (dirmap, rootPath, dirents, depth) => {
for (let i = 0, l = dirents.length; i < l; i++) {
handleDirent(dirmap, rootPath, dirents[i], depth);
}
};
const populateResultFromPath = (rootPath, depth) => {
if (signal.aborted)
return;
if (depth > maxDepth)
return;
if (foundPaths >= maxPaths)
return;
increment();
fs.readdir(rootPath, { withFileTypes: true }, (error, dirents) => {
if (error)
return decrement();
if (signal.aborted)
return decrement();
if (!dirents.length)
return decrement();
const promise = onDirents(dirents) || NOOP_PROMISE_LIKE;
promise.then(() => {
const dirmap = map[rootPath] = { directories: [], directoriesNames: new Set(), directoriesNamesToPaths: {}, files: [], filesNames: new Set(), filesNamesToPaths: {}, symlinks: [], symlinksNames: new Set(), symlinksNamesToPaths: {} };
handleDirents(dirmap, rootPath, dirents, depth);
decrement();
});
});
};
const populateResultFromSymlink = (rootPath, depth) => {
increment();
fs.realpath(rootPath, (error, realPath) => {
if (error)
return decrement();
if (signal.aborted)
return decrement();
fs.stat(realPath, (error, stat) => {
if (error)
return decrement();
if (signal.aborted)
return decrement();
const name = path.basename(realPath);
const dirmap = map[rootPath] = { directories: [], directoriesNames: new Set(), directoriesNamesToPaths: {}, files: [], filesNames: new Set(), filesNamesToPaths: {}, symlinks: [], symlinksNames: new Set(), symlinksNamesToPaths: {} };
handleStat(dirmap, realPath, name, stat, depth);
decrement();
});
});
};
const getResult = async (rootPath, depth = 1) => {
rootPath = path.normalize(rootPath);
visited.add(rootPath);
populateResultFromPath(rootPath, depth);
await promise;
if (signal.aborted)
return resultEmpty;
return result;
};
return getResult(rootPath);
};
/* EXPORT */
export default readdir;

42
node_modules/tiny-readdir/dist/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,42 @@
type Callback = () => void;
type ArrayMaybe<T> = T[] | T;
type PromiseMaybe<T> = Promise<T> | T;
type Dirent = {
isFile: () => boolean;
isDirectory: () => boolean;
isBlockDevice: () => boolean;
isCharacterDevice: () => boolean;
isSymbolicLink: () => boolean;
isFIFO: () => boolean;
isSocket: () => boolean;
name: string;
path: string;
};
type Options = {
depth?: number;
limit?: number;
followSymlinks?: boolean;
ignore?: ArrayMaybe<((targetPath: string) => boolean) | RegExp>;
signal?: {
aborted: boolean;
};
onDirents?: (dirents: Dirent[]) => PromiseMaybe<undefined>;
};
type ResultDirectory = {
directories: string[];
directoriesNames: Set<string>;
directoriesNamesToPaths: Record<string, string[]>;
files: string[];
filesNames: Set<string>;
filesNamesToPaths: Record<string, string[]>;
symlinks: string[];
symlinksNames: Set<string>;
symlinksNamesToPaths: Record<string, string[]>;
};
type ResultDirectories = {
[path: string]: ResultDirectory;
};
type Result = ResultDirectory & {
map: ResultDirectories;
};
export type { Callback, PromiseMaybe, Dirent, Options, ResultDirectory, ResultDirectories, Result };

2
node_modules/tiny-readdir/dist/types.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
/* HELPERS */
export {};

3
node_modules/tiny-readdir/dist/utils.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
declare const castArray: <T>(value: T[] | T) => T[];
declare const isFunction: (value: unknown) => value is Function;
export { castArray, isFunction };

9
node_modules/tiny-readdir/dist/utils.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/* MAIN */
const castArray = (value) => {
return Array.isArray(value) ? value : [value];
};
const isFunction = (value) => {
return (typeof value === 'function');
};
/* EXPORT */
export { castArray, isFunction };

21
node_modules/tiny-readdir/license generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2020-present Fabio Spampinato
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

34
node_modules/tiny-readdir/package.json generated vendored Executable file
View File

@@ -0,0 +1,34 @@
{
"name": "tiny-readdir",
"repository": "github:fabiospampinato/tiny-readdir",
"description": "A simple promisified recursive readdir function.",
"version": "2.7.3",
"type": "module",
"main": "dist/index.js",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"clean": "tsex clean",
"compile": "tsex compile",
"compile:watch": "tsex compile --watch",
"test": "tsex test",
"test:watch": "tsex test --watch",
"prepublishOnly": "tsex prepare"
},
"keywords": [
"readdir",
"recursive",
"promise",
"simple",
"tiny"
],
"dependencies": {
"promise-make-counter": "^1.0.1"
},
"devDependencies": {
"@types/node": "^18.19.39",
"fava": "^0.3.4",
"tsex": "^4.0.2",
"typescript": "^5.5.2"
}
}

44
node_modules/tiny-readdir/readme.md generated vendored Normal file
View File

@@ -0,0 +1,44 @@
# Tiny Readdir
A simple promisified recursive readdir function.
## Install
```sh
npm install --save tiny-readdir
```
## Usage
```ts
import readdir from 'tiny-readdir';
const aborter = new AbortController ();
const result = await readdir ( '/foo/bar', {
depth: 20, // Maximum depth to look at
limit: 1_000_000, // Maximum number of files explored, useful as a stop gap in some edge cases
followSymlinks: true, // Whether to follow symlinks or not
ignore: targetPath => /node_modules/.test ( targetPath ), // Function that if returns true will ignore this particular file or a directory and its descendants
signal: aborter.signal, // Optional abort signal, useful for aborting potentially expensive operations
onDirents: dirents => console.log ( dirents ) // Optional callback that will be called as soon as new dirents are available, useful for example for discovering ".gitignore" files while searching
});
result.directories; // => Array of absolute paths pointing to directories
result.files; // => Array of absolute paths pointing to files
result.symlinks; // => Array of absolute paths pointing to symlinks
result.directoriesNames; // => Set of directories names found
result.filesNames; // => Set of files name found
result.symlinksNames; // => Set of symlinks names found
result.directoriesNamesToPaths; // => Record of directories names found to their paths
result.filesNamesToPaths; // => Record of files names found to their paths
result.symlinksNamesToPaths; // => Record of symlinks names found to their paths
setTimeout ( () => aborter.abort (), 10_000 ); // Aborting if it's going to take longer than 10s
```
## License
MIT © Fabio Spampinato

16
node_modules/tiny-readdir/src/constants.ts generated vendored Normal file
View File

@@ -0,0 +1,16 @@
/* IMPORT */
import type {Callback} from './types';
/* MAIN */
const NOOP_PROMISE_LIKE = {
then: ( fn: Callback ) => {
fn ();
}
};
/* EXPORT */
export {NOOP_PROMISE_LIKE};

257
node_modules/tiny-readdir/src/index.ts generated vendored Executable file
View File

@@ -0,0 +1,257 @@
/* IMPORT */
import fs from 'node:fs';
import path from 'node:path';
import makeCounterPromise from 'promise-make-counter';
import {NOOP_PROMISE_LIKE} from './constants';
import {castArray, isFunction} from './utils';
import type {Dirent, Options, ResultDirectory, ResultDirectories, Result} from './types';
/* MAIN */
//TODO: Streamline the type of dirmaps
const readdir = ( rootPath: string, options?: Options ): Promise<Result> => {
const followSymlinks = options?.followSymlinks ?? false;
const maxDepth = options?.depth ?? Infinity;
const maxPaths = options?.limit ?? Infinity;
const ignore = options?.ignore ?? [];
const ignores = castArray ( ignore ).map ( ignore => isFunction ( ignore ) ? ignore : ( targetPath: string ) => ignore.test ( targetPath ) );
const isIgnored = ( targetPath: string ) => ignores.some ( ignore => ignore ( targetPath ) );
const signal = options?.signal ?? { aborted: false };
const onDirents = options?.onDirents || (() => {});
const directories: string[] = [];
const directoriesNames: Set<string> = new Set ();
const directoriesNamesToPaths: Record<string, string[]> = {};
const files: string[] = [];
const filesNames: Set<string> = new Set ();
const filesNamesToPaths: Record<string, string[]> = {};
const symlinks: string[] = [];
const symlinksNames: Set<string> = new Set ();
const symlinksNamesToPaths: Record<string, string[]> = {};
const map: ResultDirectories = {};
const visited = new Set<string> ();
const resultEmpty: Result = { directories: [], directoriesNames: new Set (), directoriesNamesToPaths: {}, files: [], filesNames: new Set (), filesNamesToPaths: {}, symlinks: [], symlinksNames: new Set (), symlinksNamesToPaths: {}, map: {} };
const result: Result = { directories, directoriesNames, directoriesNamesToPaths, files, filesNames, filesNamesToPaths, symlinks, symlinksNames, symlinksNamesToPaths, map };
const {promise, increment, decrement} = makeCounterPromise ();
let foundPaths = 0;
const handleDirectory = ( dirmap: ResultDirectory, subPath: string, name: string, depth: number ): void => {
if ( visited.has ( subPath ) ) return;
if ( foundPaths >= maxPaths ) return;
foundPaths += 1;
dirmap.directories.push ( subPath );
dirmap.directoriesNames.add ( name );
// dirmap.directoriesNamesToPaths.propertyIsEnumerable(name) || ( dirmap.directoriesNamesToPaths[name] = [] );
// dirmap.directoriesNamesToPaths[name].push ( subPath );
directories.push ( subPath );
directoriesNames.add ( name );
directoriesNamesToPaths.propertyIsEnumerable(name) || ( directoriesNamesToPaths[name] = [] );
directoriesNamesToPaths[name].push ( subPath );
visited.add ( subPath );
if ( depth >= maxDepth ) return;
if ( foundPaths >= maxPaths ) return;
populateResultFromPath ( subPath, depth + 1 );
};
const handleFile = ( dirmap: ResultDirectory, subPath: string, name: string ): void => {
if ( visited.has ( subPath ) ) return;
if ( foundPaths >= maxPaths ) return;
foundPaths += 1;
dirmap.files.push ( subPath );
dirmap.filesNames.add ( name );
// dirmap.filesNamesToPaths.propertyIsEnumerable(name) || ( dirmap.filesNamesToPaths[name] = [] );
// dirmap.filesNamesToPaths[name].push ( subPath );
files.push ( subPath );
filesNames.add ( name );
filesNamesToPaths.propertyIsEnumerable(name) || ( filesNamesToPaths[name] = [] );
filesNamesToPaths[name].push ( subPath );
visited.add ( subPath );
};
const handleSymlink = ( dirmap: ResultDirectory, subPath: string, name: string, depth: number ): void => {
if ( visited.has ( subPath ) ) return;
if ( foundPaths >= maxPaths ) return;
foundPaths += 1;
dirmap.symlinks.push ( subPath );
dirmap.symlinksNames.add ( name );
// dirmap.symlinksNamesToPaths.propertyIsEnumerable(name) || ( dirmap.symlinksNamesToPaths[name] = [] );
// dirmap.symlinksNamesToPaths[name].push ( subPath );
symlinks.push ( subPath );
symlinksNames.add ( name );
symlinksNamesToPaths.propertyIsEnumerable(name) || ( symlinksNamesToPaths[name] = [] );
symlinksNamesToPaths[name].push ( subPath );
visited.add ( subPath );
if ( !followSymlinks ) return;
if ( depth >= maxDepth ) return;
if ( foundPaths >= maxPaths ) return;
populateResultFromSymlink ( subPath, depth + 1 );
};
const handleStat = ( dirmap: ResultDirectory, rootPath: string, name: string, stat: fs.Stats, depth: number ): void => {
if ( signal.aborted ) return;
if ( isIgnored ( rootPath ) ) return;
if ( stat.isDirectory () ) {
handleDirectory ( dirmap, rootPath, name, depth );
} else if ( stat.isFile () ) {
handleFile ( dirmap, rootPath, name );
} else if ( stat.isSymbolicLink () ) {
handleSymlink ( dirmap, rootPath, name, depth );
}
};
const handleDirent = ( dirmap: ResultDirectory, rootPath: string, dirent: fs.Dirent, depth: number ): void => {
if ( signal.aborted ) return;
const separator = ( rootPath === path.sep ) ? '' : path.sep;
const name = dirent.name;
const subPath = `${rootPath}${separator}${name}`;
if ( isIgnored ( subPath ) ) return;
if ( dirent.isDirectory () ) {
handleDirectory ( dirmap, subPath, name, depth );
} else if ( dirent.isFile () ) {
handleFile ( dirmap, subPath, name );
} else if ( dirent.isSymbolicLink () ) {
handleSymlink ( dirmap, subPath, name, depth );
}
};
const handleDirents = ( dirmap: ResultDirectory, rootPath: string, dirents: fs.Dirent[], depth: number ): void => {
for ( let i = 0, l = dirents.length; i < l; i++ ) {
handleDirent ( dirmap, rootPath, dirents[i], depth );
}
};
const populateResultFromPath = ( rootPath: string, depth: number ): void => {
if ( signal.aborted ) return;
if ( depth > maxDepth ) return;
if ( foundPaths >= maxPaths ) return;
increment ();
fs.readdir ( rootPath, { withFileTypes: true }, ( error, dirents ) => {
if ( error ) return decrement ();
if ( signal.aborted ) return decrement ();
if ( !dirents.length ) return decrement ();
const promise = onDirents ( dirents ) || NOOP_PROMISE_LIKE;
promise.then ( () => {
const dirmap = map[rootPath] = { directories: [], directoriesNames: new Set (), directoriesNamesToPaths: {}, files: [], filesNames: new Set (), filesNamesToPaths: {}, symlinks: [], symlinksNames: new Set (), symlinksNamesToPaths: {} };
handleDirents ( dirmap, rootPath, dirents, depth );
decrement ();
});
});
};
const populateResultFromSymlink = ( rootPath: string, depth: number ): void => {
increment ();
fs.realpath ( rootPath, ( error, realPath ) => {
if ( error ) return decrement ();
if ( signal.aborted ) return decrement ();
fs.stat ( realPath, ( error, stat ) => {
if ( error ) return decrement ();
if ( signal.aborted ) return decrement ();
const name = path.basename ( realPath );
const dirmap = map[rootPath] = { directories: [], directoriesNames: new Set (), directoriesNamesToPaths: {}, files: [], filesNames: new Set (), filesNamesToPaths: {}, symlinks: [], symlinksNames: new Set (), symlinksNamesToPaths: {} };
handleStat ( dirmap, realPath, name, stat, depth );
decrement ();
});
});
};
const getResult = async ( rootPath: string, depth: number = 1 ): Promise<Result> => {
rootPath = path.normalize ( rootPath );
visited.add ( rootPath );
populateResultFromPath ( rootPath, depth );
await promise;
if ( signal.aborted ) return resultEmpty;
return result;
};
return getResult ( rootPath );
};
/* EXPORT */
export default readdir;
export type {Dirent, Options, ResultDirectory, ResultDirectories, Result};

55
node_modules/tiny-readdir/src/types.ts generated vendored Normal file
View File

@@ -0,0 +1,55 @@
/* HELPERS */
type Callback = () => void;
type ArrayMaybe<T> = T[] | T;
type PromiseMaybe<T> = Promise<T> | T;
/* MAIN */
type Dirent = {
isFile: () => boolean,
isDirectory: () => boolean,
isBlockDevice: () => boolean,
isCharacterDevice: () => boolean,
isSymbolicLink: () => boolean,
isFIFO: () => boolean,
isSocket: () => boolean,
name: string,
path: string
};
type Options = {
depth?: number,
limit?: number,
followSymlinks?: boolean,
ignore?: ArrayMaybe<(( targetPath: string ) => boolean) | RegExp>,
signal?: { aborted: boolean },
onDirents?: ( dirents: Dirent[] ) => PromiseMaybe<undefined>
};
type ResultDirectory = {
directories: string[],
directoriesNames: Set<string>,
directoriesNamesToPaths: Record<string, string[]>,
files: string[],
filesNames: Set<string>,
filesNamesToPaths: Record<string, string[]>,
symlinks: string[],
symlinksNames: Set<string>,
symlinksNamesToPaths: Record<string, string[]>
};
type ResultDirectories = {
[path: string]: ResultDirectory
};
type Result = ResultDirectory & {
map: ResultDirectories
};
/* EXPORT */
export type {Callback, PromiseMaybe, Dirent, Options, ResultDirectory, ResultDirectories, Result};

18
node_modules/tiny-readdir/src/utils.ts generated vendored Normal file
View File

@@ -0,0 +1,18 @@
/* MAIN */
const castArray = <T> ( value: T[] | T ): T[] => {
return Array.isArray ( value ) ? value : [value];
};
const isFunction = ( value: unknown ): value is Function => {
return ( typeof value === 'function' );
};
/* EXPORT */
export {castArray, isFunction};

291
node_modules/tiny-readdir/test/index.js generated vendored Normal file
View File

@@ -0,0 +1,291 @@
/* IMPORT */
import {describe} from 'fava';
import fs from 'node:fs';
import path from 'node:path';
import readdir from '../dist/index.js';
/* HELPERS */
const toBasename = filePath => path.basename ( filePath );
/* MAIN */
describe ( 'Tiny Readdir', it => {
it ( 'finds folders, files and symlinks', async t => {
const cwdPath = process.cwd ();
const root1Path = path.join ( cwdPath, 'test', 'root1' );
const root2Path = path.join ( cwdPath, 'test', 'root2' );
const folder1Path = path.join ( root1Path, 'folder1' );
const folder2Path = path.join ( root1Path, 'folder2' );
const folder1DeepPath = path.join ( folder1Path, 'deep' );
const file1aPath = path.join ( folder1Path, 'file1a.txt' );
const file1bPath = path.join ( folder1Path, 'file1b.txt' );
const file2Path = path.join ( folder2Path, 'file2.txt' );
const fileDeep1Path = path.join ( folder1DeepPath, 'file1.txt' );
const symlink1FromPath = path.join ( root1Path, 'symlink' );
const symlink1ToPath = root2Path;
const symlink2FromPath = path.join ( root2Path, 'symlink' );
const symlink2ToPath = root1Path;
fs.mkdirSync ( root1Path );
fs.mkdirSync ( root2Path );
fs.mkdirSync ( folder1Path );
fs.mkdirSync ( folder2Path );
fs.mkdirSync ( folder1DeepPath );
fs.writeFileSync ( file1aPath, '' );
fs.writeFileSync ( file1bPath, '' );
fs.writeFileSync ( file2Path, '' );
fs.writeFileSync ( fileDeep1Path, '' );
fs.symlinkSync ( symlink1ToPath, symlink1FromPath );
fs.symlinkSync ( symlink2ToPath, symlink2FromPath );
const expected = {
directories: [folder1Path, folder2Path, folder1DeepPath, root2Path],
directoriesNames: new Set ( [folder1Path, folder2Path, folder1DeepPath, root2Path].map ( toBasename ) ),
directoriesNamesToPaths: { folder1: [folder1Path], folder2: [folder2Path], deep: [folder1DeepPath], root2: [root2Path] },
files: [file1aPath, file1bPath, file2Path, fileDeep1Path],
filesNames: new Set ( [file1aPath, file1bPath, file2Path, fileDeep1Path].map ( toBasename ) ),
filesNamesToPaths: { 'file1a.txt': [file1aPath], 'file1b.txt': [file1bPath], 'file2.txt': [file2Path], 'file1.txt': [fileDeep1Path] },
symlinks: [symlink1FromPath, symlink2FromPath],
symlinksNames: new Set ( [symlink1FromPath, symlink2FromPath].map ( toBasename ) ),
symlinksNamesToPaths: { symlink: [symlink1FromPath, symlink2FromPath] },
map: {
[root1Path]: {
directories: [folder1Path, folder2Path],
directoriesNames: new Set ( [folder1Path, folder2Path].map ( toBasename ) ),
directoriesNamesToPaths: {},
files: [],
filesNames: new Set (),
filesNamesToPaths: {},
symlinks: [symlink1FromPath],
symlinksNames: new Set ( [symlink1FromPath].map ( toBasename ) ),
symlinksNamesToPaths: {}
},
[root2Path]: {
directories: [],
directoriesNames: new Set (),
directoriesNamesToPaths: {},
files: [],
filesNames: new Set (),
filesNamesToPaths: {},
symlinks: [symlink2FromPath],
symlinksNames: new Set ( [symlink2FromPath].map ( toBasename ) ),
symlinksNamesToPaths: {}
},
[folder1Path]: {
directories: [folder1DeepPath],
directoriesNames: new Set ( [folder1DeepPath].map ( toBasename ) ),
directoriesNamesToPaths: {},
files: [file1aPath, file1bPath],
filesNames: new Set ( [file1aPath, file1bPath].map ( toBasename ) ),
filesNamesToPaths: {},
symlinks: [],
symlinksNames: new Set (),
symlinksNamesToPaths: {}
},
[folder2Path]: {
directories: [],
directoriesNames: new Set (),
directoriesNamesToPaths: {},
files: [file2Path],
filesNames: new Set ( [file2Path].map ( toBasename ) ),
filesNamesToPaths: {},
symlinks: [],
symlinksNames: new Set (),
symlinksNamesToPaths: {}
},
[folder1DeepPath]: {
directories: [],
directoriesNames: new Set (),
directoriesNamesToPaths: {},
files: [fileDeep1Path],
filesNames: new Set ( [fileDeep1Path].map ( toBasename ) ),
filesNamesToPaths: {},
symlinks: [],
symlinksNames: new Set (),
symlinksNamesToPaths: {}
},
[symlink1FromPath]: {
directories: [root2Path],
directoriesNames: new Set ( [root2Path].map ( toBasename ) ),
directoriesNamesToPaths: {},
files: [],
filesNames: new Set (),
filesNamesToPaths: {},
symlinks: [],
symlinksNames: new Set (),
symlinksNamesToPaths: {}
},
[symlink2FromPath]: {
directories: [],
directoriesNames: new Set (),
directoriesNamesToPaths: {},
files: [],
filesNames: new Set (),
filesNamesToPaths: {},
symlinks: [],
symlinksNames: new Set (),
symlinksNamesToPaths: {}
}
}
};
try {
const result = await readdir ( root1Path, { followSymlinks: true } );
t.deepEqual ( result, expected );
} finally {
fs.rmSync ( root1Path, { recursive: true } );
fs.rmSync ( root2Path, { recursive: true } );
}
});
it ( 'supports a depth option', async t => {
const cwdPath = process.cwd ();
const {files: files0} = await readdir ( cwdPath, { depth: 0 } );
const {files: files1} = await readdir ( cwdPath, { depth: 1 } );
const {files: filesInfinity} = await readdir ( cwdPath, { depth: Infinity } );
t.true ( files0.length === 0 );
t.true ( files1.length > 0 && files1.length < 10 );
t.true ( filesInfinity.length > 100 );
});
it ( 'supports a limit option', async t => {
const cwdPath = process.cwd ();
const root1Path = path.join ( cwdPath, 'test', 'root1' );
const root2Path = path.join ( cwdPath, 'test', 'root2' );
const folder1Path = path.join ( root1Path, 'folder1' );
const folder2Path = path.join ( root1Path, 'folder2' );
const folder1DeepPath = path.join ( folder1Path, 'deep' );
const file1aPath = path.join ( folder1Path, 'file1a.txt' );
const file1bPath = path.join ( folder1Path, 'file1b.txt' );
const file2Path = path.join ( folder2Path, 'file2.txt' );
const fileDeep1Path = path.join ( folder1DeepPath, 'file1.txt' );
const symlink1FromPath = path.join ( root1Path, 'symlink' );
const symlink1ToPath = root2Path;
const symlink2FromPath = path.join ( root2Path, 'symlink' );
const symlink2ToPath = root1Path;
fs.mkdirSync ( root1Path );
fs.mkdirSync ( root2Path );
fs.mkdirSync ( folder1Path );
fs.mkdirSync ( folder2Path );
fs.mkdirSync ( folder1DeepPath );
fs.writeFileSync ( file1aPath, '' );
fs.writeFileSync ( file1bPath, '' );
fs.writeFileSync ( file2Path, '' );
fs.writeFileSync ( fileDeep1Path, '' );
fs.symlinkSync ( symlink1ToPath, symlink1FromPath );
fs.symlinkSync ( symlink2ToPath, symlink2FromPath );
const expected = {
directories: [folder1Path, folder2Path],
directoriesNames: new Set ( [folder1Path, folder2Path].map ( toBasename ) ),
directoriesNamesToPaths: { folder1: [folder1Path], folder2: [folder2Path] },
files: [],
filesNames: new Set (),
filesNamesToPaths: {},
symlinks: [symlink1FromPath],
symlinksNames: new Set ( [symlink1FromPath].map ( toBasename ) ),
symlinksNamesToPaths: { symlink: [symlink1FromPath] },
map: {
[root1Path]: {
directories: [folder1Path, folder2Path],
directoriesNames: new Set ( [folder1Path, folder2Path].map ( toBasename ) ),
directoriesNamesToPaths: {},
files: [],
filesNames: new Set (),
filesNamesToPaths: {},
symlinks: [symlink1FromPath],
symlinksNames: new Set ( [symlink1FromPath].map ( toBasename ) ),
symlinksNamesToPaths: {}
},
[folder1Path]: {
directories: [],
directoriesNames: new Set (),
directoriesNamesToPaths: {},
files: [],
filesNames: new Set (),
filesNamesToPaths: {},
symlinks: [],
symlinksNames: new Set (),
symlinksNamesToPaths: {}
},
[folder2Path]: {
directories: [],
directoriesNames: new Set (),
directoriesNamesToPaths: {},
files: [],
filesNames: new Set (),
filesNamesToPaths: {},
symlinks: [],
symlinksNames: new Set (),
symlinksNamesToPaths: {}
}
}
};
try {
const result = await readdir ( root1Path, { limit: 3, followSymlinks: true } );
t.deepEqual ( result, expected );
} finally {
fs.rmSync ( root1Path, { recursive: true } );
fs.rmSync ( root2Path, { recursive: true } );
}
});
it ( 'does not freeze the main thread', async t => {
return new Promise ( resolve => {
let count = 0;
let start = Date.now ();
const aborter = new AbortController ();
const signal = aborter.signal;
const intervalId = setInterval ( () => {
count += 1;
console.log ( 'tick', count );
if ( count !== 100 ) return;
clearInterval ( intervalId );
const end = Date.now ();
const elapsed = end - start;
console.log ( 'elapsed', elapsed );
console.log ( elapsed );
if ( elapsed > 1500 ) {
t.fail ();
} else {
t.pass ();
}
aborter.abort ();
resolve ();
}, 10 );
readdir ( '/', { signal } );
});
});
});

3
node_modules/tiny-readdir/tsconfig.json generated vendored Executable file
View File

@@ -0,0 +1,3 @@
{
"extends": "tsex/tsconfig.json"
}