# core/loaders/coverage.loader.ts

> 38 lines of code and 10 definitions.

Tree: Bane's Lab Content
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/content#file-content-core-loaders-coverage-loader-ts
Source text: https://banes-lab.com/source/content/core/loaders/coverage.loader.ts.txt

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

## Definitions

- `isGraph` (lexical_declaration, line 14)
- `graphsOf` (lexical_declaration, line 18)
- `loadModule` (lexical_declaration, line 29)
- `constantsFolder` (lexical_declaration, line 24)
- `container` (lexical_declaration, line 25)
- `loadContentGraphs` (lexical_declaration, line 34, exported)
- `folder` (lexical_declaration, line 35, exported)
- `suffix` (lexical_declaration, line 36, exported)
- `files` (lexical_declaration, line 37, exported)
- `loaded` (lexical_declaration, line 41, exported)

## Contained in

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

## Uses

- [core/selectors/payload.selector.ts](https://banes-lab.com/source/content/core/selectors/payload.selector.ts.md)

## Linked from

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

## Source

```typescript
import {
    CONFIGURATION_CONTAINER,
    CONSTANTS_CONCERN,
    GRAPH_EXPORT_SUFFIX,
} from "#configuration/constants/coverage.constants";
import { absolutePath, relativePath } from "@ssot/paths";
import { concernSuffix, folderFor } from "@ssot/govlab/shared/manifests/taxonomy.manifest.ts";
import type { ContentGraph } from "#types/coverage.types";
import { containerPath } from "@ssot/govlab/shared/resolvers/container.resolver.ts";
import { isRecord } from "#core/selectors/payload.selector";
import { pathToFileURL } from "node:url";
import { readdirSync } from "node:fs";

const isGraph = function isGraph(value: unknown): value is ContentGraph {
    return isRecord(value) && typeof value["page"] === "string" && isRecord(value["sections"]);
};

const graphsOf = function graphsOf(module: Record<string, unknown>): ContentGraph[] {
    return Object.entries(module).flatMap(([name, value]) =>
        name.endsWith(GRAPH_EXPORT_SUFFIX) && isGraph(value) ? [value] : [],
    );
};

const constantsFolder = function constantsFolder(): string {
    const container = containerPath(CONFIGURATION_CONTAINER, relativePath("app.member"));
    return absolutePath("app.root", container, folderFor(CONSTANTS_CONCERN) ?? "");
};

const loadModule = async function loadModule(file: string): Promise<ContentGraph[]> {
    const loaded: unknown = await import(pathToFileURL(file).href);
    return isRecord(loaded) ? graphsOf(loaded) : [];
};

export const loadContentGraphs = async function loadContentGraphs(): Promise<ContentGraph[]> {
    const folder = constantsFolder();
    const suffix = concernSuffix(CONSTANTS_CONCERN);
    const files = readdirSync(folder)
        .filter((name) => name.endsWith(suffix))
        .sort((a, b) => a.localeCompare(b))
        .map((name) => `${folder}/${name}`);
    const loaded = await Promise.all(files.map(loadModule));
    return loaded.flat();
};
```
