# Documentation ## Introduction fdir > v3.0 closely follows builder pattern to make an instance of the crawler fluently. So instead of doing: ```js fdir.sync("path/to/dir", { includeBasePath: true, }); ``` You will simply do: ```js new fdir() .withBasePath() .crawl("path/to/dir") .sync(); ``` ## Installation Make sure you have Node (any version) installed with npm/yarn. Using `yarn`: ```sh $ yarn add fdir ``` Using `npm`: ```sh $ npm install fdir ``` You will also need to import fdir at the top of your file, like this: **ES5 Require** ```js const { fdir } = require("fdir"); ``` **ES6 Import** ```js import { fdir } from "fdir"; ``` ## Getting Started ### Creating a new Crawler ```js const crawler = new fdir(); ``` ### Crawling a Directory ```js const files = crawler.crawl("/path/to/dir").sync(); ``` Easy, peasy! ## Crawler Options The crawler options are in the form of methods. Each method returns the current instance of the crawler to enable fluency/method chaining. **Example:** ```js const crawler = new fdir() .withBasePath() .withDirs() .withMaxDepth(5); ``` ### `withBasePath` Use this to add the base path to each output path. > _By default, fdir does not add the base path to the output. For example, if you crawl `node_modules`, the output will contain only the filenames._ **Usage** ```js const crawler = new fdir().withBasePath(); ``` ### `withDirs` Use this to also add the directories to the output. > _For example, if you are crawling `node_modules`, the output will only contain the files ignoring the directories including `node_modules` itself._ **Usage** ```js const crawler = new fdir().withDirs(); ``` ### `withSymlinks({ resolvePaths: boolean })` Use this to follow all symlinks recursively. **Parameters:** - `resolvePaths: boolean` — By default, `fdir` returns original paths to files irrespective of whether they are inside a symlinked directory or not. If you want the paths to be relative to the symlink, set this flag to `false`. (Default is `true`). > NOTE: This will affect crawling performance. **Usage** ```js // to resolve all symlinked paths to their original path const crawler = new fdir().withSymlinks({ resolvePaths: true }); // to disable path resolution const crawler = new fdir().withSymlinks({ resolvePaths: false }); ``` ### `withMaxDepth(number)` Use this to limit the maximum depth fdir will crawl to before stopping. > _By default, fdir crawls recursively until the last directory._ **Usage** ```js const crawler = new fdir().withMaxDepth(5); ``` ### `withMaxFiles(number)` Use this to limit the maximum number of files fdir will crawl to before stopping. **Usage** ```js const crawler = new fdir().withMaxFiles(100); ``` ### `withFullPaths` Use this to get full absolute paths in the output. > _By default, fdir returns filenames._ **Usage** ```js const crawler = new fdir().withFullPaths(); ``` ### `withRelativePaths` Use this to get paths relative to the root directory in the output. **Usage** ```js const crawler = new fdir().withRelativePaths(); ``` ### `withPathSeparator` Use this to set the path separator in the output. **Usage** ```js const crawler = new fdir().withPathSeparator("/"); ``` ### `withAbortSignal(AbortSignal)` Use this to pass an `AbortSignal` to the crawler. **Usage** ```js const controller = new AbortController(); const crawler = new fdir().withAbortSignal(controller.signal); ``` ### `withErrors` Use this if you want to handle all errors manually. > _By default, fdir handles and supresses all errors including permission, non-existent directory ones._ **Usage** ```js const crawler = new fdir().withErrors(); ``` ### `onlyCounts` Return only the number of files and directories. Might be a little faster. **Usage** ```js const crawler = new fdir().onlyCounts(); ``` **Output** Using this will affect the output structure. In place of a simple array of file paths you will get an object containing the counts of files and directories. For example: ```js const { files, dirs } = new fdir().onlyCounts().sync(); ``` ### `onlyDirs` Ignore all files and return only the directory paths. Might be a little faster. **Usage** ```js const crawler = new fdir().onlyDirs(); ``` ### `normalize` Normalize the given directory path using `path.normalize`. > _Since `path.normalize` is not always needed and is quite resource intensive (relatively), fdir includes a flag for it._ **Usage** ```js const crawler = new fdir().normalize(); ``` ### `group` Group all files by directory. > _This does not give a tree-like output._ **Usage** ```js const crawler = new fdir().group(); ``` **Output** Using this will affect the output structure. In place of a simple array of `string` file paths you will get an array of `Group`: ```ts type Group = { dir: string; files: string[] }; ``` ### `glob(...string[])` Applies a `glob` filter to all files and only adds those that satisfy it. > _Uses [picomatch](https://github.com/micromatch/picomatch) underneath. To keep fdir dependency free, it is up to the user to install `picomatch` manually._ **Usage** ```js // only get js and md files const crawler = new fdir().glob("./**/*.js", "./**/*.md"); ``` ### `globWithOptions(string[], Object)` The same as `glob` but allows you to pass options to the matcher. **Usage** ```js // only get js and md files const crawler = new fdir().globWithOptions(["**/*.js", "**/*.md"], { strictSlashes: true }); ``` ### `withGlobFunction(Function)` Uses the specified glob function to match files against the provided glob pattern. **Usage** ```js // using picomatch or a similar library import picomatch from 'picomatch'; const crawler = new fdir().withGlobFunction(picomatch); // using a custom function const customGlob = (patterns: string | string[]) => { return (test: string): boolean => test.endsWith('.js'); }; const crawler = new fdir().withGlobFunction(customGlob); ``` ### `filter(Function)` Applies a filter to all directories and files and only adds those that satisfy the filter. > _Multiple filters are joined using AND._ > The function receives two parameters: the first is the path of the item, and the second is a flag that indicates whether the item is a directory or not. **Usage** ```js // only get hidden & .js files const crawler = new fdir() .filter((path, isDirectory) => path.startsWith(".")) .filter((path, isDirectory) => path.endsWith(".js")); ``` ### `exclude(Function)` Applies an exclusion filter to all directories and only crawls those that do not satisfy the condition. Useful for speeding up crawling if you know you can ignore some directories. > The function receives two parameters: the first is the name of the directory, and the second is the path to it. > _Currently, you can apply only one exclusion filter per crawler. This might change._ **Usage** ```js // do not crawl into hidden directories const crawler = new fdir().exclude((dirName, dirPath) => dirName.startsWith(".") ); ``` ### `crawl(string)` Prepare the crawler. This should be called at the end after all the configuration has been done. **Parameters** - `dirPath: string` - The path of the directory to start crawling from **Returns** `APIBuilder` **Usage** ```js const crawler = new fdir().withBasePath().crawl("path/to/dir"); ``` ## `APIBuilder` fdir currently includes 3 APIs (i.e. 3 ways of crawling a directory). 1. Asynchronous with `Promise` 2. Asynchronous with callback 3. Synchronous > Stream API will be added soon. ### 1. `withPromise()` Crawl the directory asynchronously using `Promise`. **Usage** ```js const files = await new fdir() .withBasePath() .withDirs() .crawl("/path/to/dir") .withPromise(); ``` ### 2. `withCallback(Function)` Crawl the directory asynchronously using callback. **Usage** ```js new fdir() .withBasePath() .withDirs() .crawl("/path/to/dir") .withCallback((err, files) => { // do something with files here }); ``` ### 3. `sync()` Crawl the directory synchronously. > **Note about performance:** > Sync performance is much, much slower than async performance. Only use this > if absolutely necessary. **Usage** ```js const files = new fdir() .withBasePath() .withDirs() .crawl("/path/to/dir") .sync(); ``` ## Method Chaining Alternative _Some people have raised issues saying method chaining is not recommended and/or good, so I have added this as an alternative._ It is now possible to pass an `Options` object to `crawlWithOptions`: ```js new fdir() .crawlWithOptions("path/to/dir", { includeBasePath: true, }) .sync(); ``` List of supported options: ```ts type Options = { includeBasePath?: boolean; includeDirs?: boolean; normalizePath?: boolean; maxDepth?: number; maxFiles?: number; resolvePaths?: boolean; suppressErrors?: boolean; group?: boolean; onlyCounts?: boolean; filters: FilterFn[]; resolveSymlinks?: boolean; useRealPaths?: boolean; excludeFiles?: boolean; excludeSymlinks?: boolean; exclude?: ExcludeFn; relativePaths?: boolean; pathSeparator: PathSeparator; signal?: AbortSignal; globFunction?: Function; }; ```