# core/loaders/plugin.loader.ts

> 27 lines of code and 8 definitions.

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

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

## Definitions

- `MODULE_SUFFIXES` (lexical_declaration, line 6)
- `DECLARATION_SUFFIX` (lexical_declaration, line 7)
- `isModuleFile` (lexical_declaration, line 9)
- `importModule` (lexical_declaration, line 13)
- `loadExports` (lexical_declaration, line 17, exported)
- `files` (lexical_declaration, line 22, exported)
- `modules` (lexical_declaration, line 26, exported)
- `candidate` (lexical_declaration, line 28, exported)

## Contained in

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

## Source

```typescript
import { isRecord } from "#core/predicates/record.predicate";
import { join } from "node:path";
import { pathToFileURL } from "node:url";
import { readDirSafe } from "#core/loaders/base.loader";

const MODULE_SUFFIXES: readonly string[] = [".ts", ".mts", ".cts", ".mjs", ".js", ".cjs"];
const DECLARATION_SUFFIX = ".d.ts";

const isModuleFile = function isModuleFile(name: string): boolean {
    return !name.endsWith(DECLARATION_SUFFIX) && MODULE_SUFFIXES.some((suffix) => name.endsWith(suffix));
};

const importModule = async function importModule(file: string): Promise<unknown> {
    return import(pathToFileURL(file).href);
};

export const loadExports = async function loadExports<T>(
    dir: string,
    key: string,
    guard: (value: unknown) => value is T,
): Promise<T[]> {
    const files = readDirSafe(dir)
        .filter((entry) => entry.isFile() && isModuleFile(entry.name))
        .map((entry) => join(dir, entry.name))
        .toSorted((left, right) => left.localeCompare(right));
    const modules = await Promise.all(files.map(importModule));
    return modules.flatMap((module): T[] => {
        const candidate = isRecord(module) ? module[key] : null;
        return guard(candidate) ? [candidate] : [];
    });
};
```
