# core/loaders/config.loader.ts

> 35 lines of code and 6 definitions.

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

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

## Definitions

- `collectTypescript` (lexical_declaration, line 25, exported)
- `memberConfigOf` (lexical_declaration, line 16)
- `member` (lexical_declaration, line 17)
- `file` (lexical_declaration, line 18)
- `members` (lexical_declaration, line 26, exported)
- `options` (lexical_declaration, line 27, exported)

## Contained in

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

## Uses

- [core/loaders/data.loader.ts](https://banes-lab.com/source/stats/core/loaders/data.loader.ts.md)
- [core/predicates/record.predicate.ts](https://banes-lab.com/source/stats/core/predicates/record.predicate.ts.md)
- [core/selectors/field.selector.ts](https://banes-lab.com/source/stats/core/selectors/field.selector.ts.md)

## Linked from

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

## Source

```typescript
import {
    BASE_CONFIG,
    MEMBER_CONFIG,
    STRICT_FLAGS,
    UNSPECIFIED_TARGET,
} from "#configuration/constants/config.constants";
import type { MemberConfig, TypescriptStats } from "#types/config.types";
import { field, stringField } from "#core/selectors/field.selector";
import { existsSync } from "node:fs";
import { isRecord } from "#core/predicates/record.predicate";
import path from "node:path";
import { posixOf } from "#core/selectors/source.selector";
import { readJson } from "#core/loaders/data.loader";
import { workspaceMembers } from "#core/resolvers/package.resolver";

const memberConfigOf = function memberConfigOf(root: string, abs: string): MemberConfig {
    const member = posixOf(path.relative(root, abs));
    const file = path.join(abs, MEMBER_CONFIG);
    if (!existsSync(file)) {
        return { extendsBase: false, member, present: false };
    }
    return { extendsBase: stringField(readJson(file), "extends").includes(BASE_CONFIG), member, present: true };
};

export const collectTypescript = function collectTypescript(root: string): TypescriptStats {
    const members = workspaceMembers(root).map((abs) => memberConfigOf(root, abs));
    const options = field(readJson(path.join(root, BASE_CONFIG)), "compilerOptions");
    return {
        baseOptions: isRecord(options) ? Object.keys(options).length : 0,
        covered: members.filter((entry) => entry.present).length,
        members,
        strictFlags: STRICT_FLAGS.map((flag): [string, boolean] => [flag, field(options, flag) === true]),
        target: stringField(options, "target") || UNSPECIFIED_TARGET,
        total: members.length,
        uncovered: members.filter((entry) => !entry.present).map((entry) => entry.member),
    };
};
```
