# core/loaders/document.loader.ts

> 34 lines of code and 6 definitions.

Tree: GovLab Context
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/context#file-context-core-loaders-document-loader-ts
Source text: https://banes-lab.com/source/context/core/loaders/document.loader.ts.txt

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

## Definitions

- `sourcesOf` (lexical_declaration, line 22)
- `documentsUnder` (lexical_declaration, line 12)
- `executableDocuments` (lexical_declaration, line 35, exported)
- `full` (lexical_declaration, line 14)
- `root` (lexical_declaration, line 23)
- `prefix` (lexical_declaration, line 24)

## Contained in

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

## Linked from

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

## Source

```typescript
import {
    DOCUMENT_EXTENSION,
    DOCUMENT_ROOTS,
    PATH_SEPARATOR,
    WINDOWS_SEPARATOR,
} from "#configuration/constants/document.constants";
import type { DocumentKind, DocumentSource } from "#types/grammar.document.types";
import { absolutePath, relativePath } from "@ssot/paths";
import { join } from "node:path";
import { readdirSync } from "node:fs";

const documentsUnder = function documentsUnder(base: string): string[] {
    return readdirSync(base, { withFileTypes: true }).flatMap((entry) => {
        const full = join(base, entry.name);
        if (entry.isDirectory()) {
            return documentsUnder(full);
        }
        return entry.name.endsWith(DOCUMENT_EXTENSION) ? [full] : [];
    });
};

const sourcesOf = function sourcesOf(kind: DocumentKind, key: string): DocumentSource[] {
    const root = absolutePath(key);
    const prefix = relativePath(key);
    return documentsUnder(root).map((path) => ({
        kind,
        path,
        relative: `${prefix}${PATH_SEPARATOR}${path
            .slice(root.length + 1)
            .split(WINDOWS_SEPARATOR)
            .join(PATH_SEPARATOR)}`,
    }));
};

export const executableDocuments = function executableDocuments(): DocumentSource[] {
    return DOCUMENT_ROOTS.flatMap(({ key, kind }) => sourcesOf(kind, key));
};
```
