# core/loaders/rule.loader.ts

> 17 lines of code and 4 definitions.

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

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

## Definitions

- `loadRuleFolder` (lexical_declaration, line 7, exported)
- `names` (lexical_declaration, line 8, exported)
- `file` (lexical_declaration, line 13, exported)
- `loaded` (lexical_declaration, line 14, exported)

## Contained in

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

## Source

```typescript
import type { RuleFile } from "#types/rule.types";
import { isRecord } from "#core/selectors/record.selector";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { readdirSync } from "node:fs";

export const loadRuleFolder = async function loadRuleFolder(dir: string, suffix: string): Promise<RuleFile[]> {
    const names = readdirSync(dir)
        .filter((name) => name.endsWith(suffix))
        .toSorted((a, b) => a.localeCompare(b));
    return Promise.all(
        names.map(async (name): Promise<RuleFile> => {
            const file = path.join(dir, name);
            const loaded: unknown = await import(pathToFileURL(file).href);
            return { file, id: name.slice(0, -suffix.length), module: isRecord(loaded) ? loaded : {} };
        }),
    );
};
```
