# core/loaders/comment.loader.ts

> 44 lines of code and 15 definitions.

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

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

## Definitions

- `preload` (lexical_declaration, line 47, exported)
- `collectFiles` (lexical_declaration, line 31, exported)
- `GRAMMAR_FILE` (lexical_declaration, line 11)
- `toGrammar` (lexical_declaration, line 13)
- `{ directivePrefixes, lang }` (lexical_declaration, line 14)
- `commentGrammars` (lexical_declaration, line 21, exported)
- `text` (lexical_declaration, line 22, exported)
- `records` (lexical_declaration, line 23, exported)
- `langOf` (lexical_declaration, line 27, exported)
- `out` (lexical_declaration, line 32, exported)
- `stack` (lexical_declaration, line 33, exported)
- `dir` (lexical_declaration, line 35, exported)
- `full` (lexical_declaration, line 37, exported)
- `wanted` (lexical_declaration, line 38, exported)
- `langs` (lexical_declaration, line 48, exported)

## Contained in

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

## Uses

- [core/loaders/source.loader.ts](https://banes-lab.com/source/quality/core/loaders/source.loader.ts.md)

## Used by

- [core/coordinators/comment.coordinator.ts](https://banes-lab.com/source/quality/core/coordinators/comment.coordinator.ts.md)

## Linked from

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

## Source

```typescript
import { detectLanguage, ensureLanguages } from "@govlab/code-parse";
import type { CommentGrammar } from "#types/comment.types";
import type { PathExclusion } from "#types/exclusions.types";
import { absolutePath } from "@ssot/paths";
import { jsonRecord } from "#core/parsers/record.parser";
import path from "node:path";
import { readFileSync } from "node:fs";
import { recordsAt } from "#core/selectors/record.selector";
import { safeReaddir } from "#core/loaders/source.loader";

const GRAMMAR_FILE = "comment.data.json";

const toGrammar = function toGrammar(record: Record<string, unknown>): CommentGrammar[] {
    const { directivePrefixes, lang } = record;
    if (typeof lang !== "string" || !Array.isArray(directivePrefixes)) {
        return [];
    }
    return [{ directivePrefixes: directivePrefixes.filter((prefix) => typeof prefix === "string"), lang }];
};

export const commentGrammars = function commentGrammars(): Map<string, CommentGrammar> {
    const text = readFileSync(absolutePath("govlab.quality.data", GRAMMAR_FILE), "utf8");
    const records = recordsAt(jsonRecord(text), "grammars");
    return new Map(records.flatMap(toGrammar).map((grammar): [string, CommentGrammar] => [grammar.lang, grammar]));
};

export const langOf = function langOf(filePath: string): string | null {
    return detectLanguage(path.basename(filePath));
};

export const collectFiles = function collectFiles(root: string, excluded: PathExclusion): string[] {
    const out: string[] = [];
    const stack: string[] = [root];
    while (stack.length > 0) {
        const dir = stack.pop() ?? root;
        for (const entry of safeReaddir(dir)) {
            const full = path.join(dir, entry.name);
            const wanted = !excluded(full) && (entry.isDirectory() || langOf(entry.name) !== null);
            if (wanted) {
                (entry.isDirectory() ? stack : out).push(full);
            }
        }
    }
    return out;
};

export const preload = async function preload(files: readonly string[]): Promise<void> {
    const langs = files.map(langOf).filter((lang): lang is string => lang !== null);
    await ensureLanguages([...new Set(langs)]);
};
```
