# core/analyzers/dependency.analyzer.ts

> 28 lines of code and 10 definitions.

Tree: Project Scripts
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/scripts#file-scripts-core-analyzers-dependency-analyzer-ts
Source text: https://banes-lab.com/source/scripts/core/analyzers/dependency.analyzer.ts.txt

Listed in [core/analyzers](https://banes-lab.com/api/source/scripts/core/analyzers.md), after [core/analyzers/credential.analyzer.ts](https://banes-lab.com/source/scripts/core/analyzers/credential.analyzer.ts.md) and before [core/analyzers/export.analyzer.ts](https://banes-lab.com/source/scripts/core/analyzers/export.analyzer.ts.md).

## Definitions

- `walk` (lexical_declaration, line 19, exported)
- `isBreach` (lexical_declaration, line 9)
- `descends` (lexical_declaration, line 13)
- `hoistBreaches` (lexical_declaration, line 17, exported)
- `MODULES_FOLDER` (lexical_declaration, line 4)
- `LOCKFILE` (lexical_declaration, line 5)
- `HISTORY_FOLDER` (lexical_declaration, line 6)
- `SKIPPED` (lexical_declaration, line 7)
- `found` (lexical_declaration, line 18, exported)
- `path` (lexical_declaration, line 21, exported)

## Contained in

- [core/analyzers](https://banes-lab.com/anatomy/scripts/folder-scripts-core-analyzers.md)

## Linked from

- [core/analyzers](https://banes-lab.com/anatomy/scripts/folder-scripts-core-analyzers.md)

## Source

```typescript
import { type Dirent, readdirSync } from "node:fs";
import { join, relative, sep } from "node:path";

const MODULES_FOLDER = "node_modules";
const LOCKFILE = "package-lock.json";
const HISTORY_FOLDER = ".git";
const SKIPPED: ReadonlySet<string> = new Set([HISTORY_FOLDER]);

const isBreach = function isBreach(entry: Dirent): boolean {
    return (entry.isDirectory() && entry.name === MODULES_FOLDER) || (entry.isFile() && entry.name === LOCKFILE);
};

const descends = function descends(entry: Dirent): boolean {
    return entry.isDirectory() && entry.name !== MODULES_FOLDER && !SKIPPED.has(entry.name);
};

export const hoistBreaches = function hoistBreaches(root: string): readonly string[] {
    const found: string[] = [];
    const walk = function walk(directory: string): void {
        for (const entry of readdirSync(directory, { withFileTypes: true })) {
            const path = join(directory, entry.name);
            if (directory !== root && isBreach(entry)) {
                found.push(path);
            }
            if (descends(entry)) {
                walk(path);
            }
        }
    };
    walk(root);
    return found.map((path) => relative(root, path).split(sep).join("/")).toSorted((a, b) => a.localeCompare(b));
};
```
