# core/loaders/source.loader.ts

> 29 lines of code and 3 definitions.

Tree: Project Scripts
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/scripts#file-scripts-core-loaders-source-loader-ts
Source text: https://banes-lab.com/source/scripts/core/loaders/source.loader.ts.txt

Listed in [core/loaders](https://banes-lab.com/api/source/scripts/core/loaders.md), after [core/loaders/server.loader.ts](https://banes-lab.com/source/scripts/core/loaders/server.loader.ts.md) and before [core/loaders/viewport.loader.ts](https://banes-lab.com/source/scripts/core/loaders/viewport.loader.ts.md).

## Definitions

- `sourceFilesUnder` (lexical_declaration, line 7, exported)
- `includedFilesUnder` (lexical_declaration, line 17, exported)
- `path` (lexical_declaration, line 25, exported)

## Contained in

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

## Used by

- [core/analyzers/export.analyzer.ts](https://banes-lab.com/source/scripts/core/analyzers/export.analyzer.ts.md)

## Linked from

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

## Source

```typescript
import { DECLARATION_EXTENSION, SOURCE_EXTENSION } from "#configuration/constants/closure.constants";
import { extname, join, relative } from "node:path";
import { readdirSync, statSync } from "node:fs";
import { MASTER_EXCLUDE_MARKERS } from "@ssot/govlab/shared/generated/exclusions.generated.ts";
import { isExcludedPath } from "@govlab/quality/core/matchers/exclusions.matcher.ts";

export const sourceFilesUnder = function sourceFilesUnder(dir: string): string[] {
    return readdirSync(dir).flatMap((name) => {
        const path = join(dir, name);
        if (statSync(path).isDirectory()) {
            return sourceFilesUnder(path);
        }
        return path.endsWith(SOURCE_EXTENSION) && !path.endsWith(DECLARATION_EXTENSION) ? [path] : [];
    });
};

export const includedFilesUnder = function includedFilesUnder(
    root: string,
    extensions: ReadonlySet<string>,
    dir: string = root,
): string[] {
    return readdirSync(dir, { withFileTypes: true })
        .filter((entry) => !isExcludedPath(relative(root, join(dir, entry.name)), MASTER_EXCLUDE_MARKERS))
        .flatMap((entry) => {
            const path = join(dir, entry.name);
            if (entry.isDirectory()) {
                return includedFilesUnder(root, extensions, path);
            }
            return entry.isFile() && extensions.has(extname(entry.name)) ? [path] : [];
        });
};
```
