# core/loaders/folder.loader.ts

> 39 lines of code and 13 definitions.

Tree: Content Fingerprint
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/content-fingerprint#file-content-fingerprint-core-loaders-folder-loader-ts
Source text: https://banes-lab.com/source/content-fingerprint/core/loaders/folder.loader.ts.txt

Listed in [core/loaders](https://banes-lab.com/api/source/content-fingerprint/core/loaders.md).

## Definitions

- `includeAll` (lexical_declaration, line 5)
- `excludeNone` (lexical_declaration, line 9)
- `readEntries` (lexical_declaration, line 13)
- `scan` (lexical_declaration, line 17)
- `entries` (lexical_declaration, line 22)
- `dirs` (lexical_declaration, line 23)
- `files` (lexical_declaration, line 27)
- `collectFiles` (lexical_declaration, line 33, exported)
- `excluded` (lexical_declaration, line 34, exported)
- `include` (lexical_declaration, line 35, exported)
- `out` (lexical_declaration, line 36, exported)
- `stack` (lexical_declaration, line 37, exported)
- `{ dirs, files }` (lexical_declaration, line 39, exported)

## Contained in

- [core/loaders](https://banes-lab.com/anatomy/content-fingerprint/folder-content-fingerprint-core-loaders.md)

## Source

```typescript
import type { CollectOptions, FolderScan } from "#types/folder.types";
import { type Dirent, existsSync, readdirSync } from "node:fs";
import { join } from "node:path";

const includeAll = function includeAll(): boolean {
    return true;
};

const excludeNone = function excludeNone(): boolean {
    return false;
};

const readEntries = function readEntries(dir: string): Dirent[] {
    return existsSync(dir) ? readdirSync(dir, { withFileTypes: true }) : [];
};

const scan = function scan(
    dir: string,
    excluded: (dir: string) => boolean,
    include: (name: string) => boolean,
): FolderScan {
    const entries = readEntries(dir);
    const dirs = entries
        .filter((entry) => entry.isDirectory())
        .map((entry) => join(dir, entry.name))
        .filter((child) => !excluded(child));
    const files = entries
        .filter((entry) => !entry.isDirectory() && include(entry.name))
        .map((entry) => join(dir, entry.name));
    return { dirs, files };
};

export const collectFiles = function collectFiles(root: string, options: CollectOptions = {}): string[] {
    const excluded = options.excluded ?? excludeNone;
    const include = options.include ?? includeAll;
    const out: string[] = [];
    const stack: string[] = [root];
    while (stack.length > 0) {
        const { dirs, files } = scan(stack.pop() ?? root, excluded, include);
        out.push(...files);
        stack.push(...dirs);
    }
    return out.sort((a, b) => a.localeCompare(b));
};
```
