# core/resolvers/tool.resolver.ts

> 50 lines of code and 16 definitions.

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

Listed in [core/resolvers](https://banes-lab.com/api/source/quality/core/resolvers.md), after [core/resolvers/surface.resolver.ts](https://banes-lab.com/source/quality/core/resolvers/surface.resolver.ts.md).

## Definitions

- `nativeToolConfig` (lexical_declaration, line 26, exported)
- `toolSection` (lexical_declaration, line 9, exported)
- `enabledToolRules` (lexical_declaration, line 37, exported)
- `toolSetting` (lexical_declaration, line 13, exported)
- `section` (lexical_declaration, line 18, exported)
- `resolved` (lexical_declaration, line 19, exported)
- `{ concerns, owners }` (lexical_declaration, line 31, exported)
- `files` (lexical_declaration, line 32, exported)
- `file` (lexical_declaration, line 33, exported)
- `{ concerns }` (lexical_declaration, line 42, exported)
- `resolveActiveSelectable` (lexical_declaration, line 46, exported)
- `owners` (lexical_declaration, line 47, exported)
- `selectable` (lexical_declaration, line 48, exported)
- `elected` (lexical_declaration, line 49, exported)
- `resolveActiveEcosystems` (lexical_declaration, line 53, exported)
- `ecosystems` (lexical_declaration, line 54, exported)

## Contained in

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

## Uses

- [core/loaders/config.loader.ts](https://banes-lab.com/source/quality/core/loaders/config.loader.ts.md)
- [core/resolvers/rule.resolver.ts](https://banes-lab.com/source/quality/core/resolvers/rule.resolver.ts.md)
- [core/selectors/config.selector.ts](https://banes-lab.com/source/quality/core/selectors/config.selector.ts.md)

## Used by

- [core/adapters/tool.perlcritic.adapter.ts](https://banes-lab.com/source/quality/core/adapters/tool.perlcritic.adapter.ts.md)
- [core/adapters/tool.swiftlint.adapter.ts](https://banes-lab.com/source/quality/core/adapters/tool.swiftlint.adapter.ts.md)

## Linked from

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

## Source

```typescript
import { enabledRuleIds } from "#core/resolvers/rule.resolver";
import { generateNativeConfigs } from "#core/coordinators/emitter.coordinator";
import { loadEmitInputs } from "#core/loaders/concern.loader";
import { loadGovlabConfig } from "#core/loaders/config.loader";
import { sectionOf } from "#core/selectors/config.selector";
import { selectableTools } from "#core/loaders/dependency.loader";
import { stringField } from "#core/selectors/record.selector";

export const toolSection = async function toolSection(root: string, key: string): Promise<Record<string, unknown>> {
    return sectionOf(await loadGovlabConfig(root), key);
};

export const toolSetting = async function toolSetting<Field extends string>(
    root: string,
    key: string,
    defaults: Readonly<Record<Field, string>>,
): Promise<Record<Field, string>> {
    const section = await toolSection(root, key);
    const resolved: Partial<Record<Field, string>> = {};
    for (const field of Object.keys(defaults).filter((name): name is Field => name in defaults)) {
        resolved[field] = stringField(section, field, defaults[field]);
    }
    return { ...defaults, ...resolved };
};

export const nativeToolConfig = async function nativeToolConfig(
    root: string,
    language: string,
    fileName: string,
): Promise<string> {
    const { concerns, owners } = await loadEmitInputs(root);
    const files = await generateNativeConfigs(concerns, [language], owners);
    const file = files.find((entry) => entry.path.endsWith(fileName));
    return file?.content ?? "";
};

export const enabledToolRules = async function enabledToolRules(
    root: string,
    language: string,
    tool: string,
): Promise<string[]> {
    const { concerns } = await loadEmitInputs(root);
    return enabledRuleIds(concerns, language, tool);
};

export const resolveActiveSelectable = async function resolveActiveSelectable(root: string): Promise<string[]> {
    const owners = (await loadGovlabConfig(root)).qualityMaster?.owners ?? {};
    const selectable = selectableTools();
    const elected = Object.values(owners).flatMap((languages) => Object.values(languages));
    return [...new Set(elected.filter((tool) => selectable.has(tool)))];
};

export const resolveActiveEcosystems = async function resolveActiveEcosystems(root: string): Promise<string[] | null> {
    const ecosystems = (await loadGovlabConfig(root)).qualityMaster?.ecosystems;
    return ecosystems && ecosystems.length > 0 ? ecosystems : null;
};
```
