# core/emitters/stylelint.emitter.ts

> 74 lines of code and 16 definitions.

Tree: GovLab Quality
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-emitters-stylelint-emitter-ts
Source text: https://banes-lab.com/source/quality/core/emitters/stylelint.emitter.ts.txt

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

## Definitions

- `resolvedStylelintValue` (lexical_declaration, line 21)
- `optionEntry` (lexical_declaration, line 13)
- `stylelintConceptValue` (lexical_declaration, line 34)
- `emitStylelintConfig` (lexical_declaration, line 61, exported)
- `[only]` (lexical_declaration, line 14)
- `hasLimitKnob` (lexical_declaration, line 38)
- `resolved` (lexical_declaration, line 39)
- `standardStylelintRules` (lexical_declaration, line 45)
- `emitted` (lexical_declaration, line 53)
- `exclude` (lexical_declaration, line 65, exported)
- `options` (lexical_declaration, line 66, exported)
- `concernMap` (lexical_declaration, line 67, exported)
- `catalogKeys` (lexical_declaration, line 68, exported)
- `keys` (lexical_declaration, line 72, exported)
- `out` (lexical_declaration, line 73, exported)
- `extra` (lexical_declaration, line 75, exported)

## Contained in

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

## Uses

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

## Linked from

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

## Source

```typescript
import {
    DEPRECATED_CATEGORY,
    GOVLAB_STYLELINT_TOOLS,
    STYLELINT_TOOL,
} from "#configuration/constants/stylelint.constants";
import type { QualityData, QualityRuleRecord } from "#types/catalog.types";
import type { StylelintEmitPolicy, StylelintPrimary, StylelintRuleEntry } from "#types/stylelint.types";
import type { ResolvedConcern } from "#types/concern.types";
import { excludedByConcept } from "#core/predicates/concept.predicate";
import { loadQualityData } from "#core/loaders/quality.loader";
import { resolveConcernMap } from "#core/converters/concern.converter";

const optionEntry = function optionEntry(optionValue: (number | string)[]): [StylelintPrimary] {
    const [only] = optionValue;
    if (optionValue.length === 0) {
        return [true];
    }
    return optionValue.length === 1 && only !== undefined ? [only] : [optionValue];
};

const resolvedStylelintValue = function resolvedStylelintValue(
    resolved: ResolvedConcern,
    hasLimitKnob: boolean,
): [StylelintPrimary] | null {
    if (resolved.exclude) {
        return null;
    }
    if (typeof resolved.value === "number") {
        return hasLimitKnob ? [resolved.value] : null;
    }
    return optionEntry(resolved.optionValue ?? []);
};

const stylelintConceptValue = function stylelintConceptValue(
    rule: QualityRuleRecord,
    concernMap: Map<string, ResolvedConcern>,
): StylelintRuleEntry | null {
    const hasLimitKnob = (rule.knobs ?? []).some((knob) => knob.threshold);
    const resolved = (rule.canonical ?? [])
        .map((concept) => concernMap.get(concept))
        .find((entry) => entry !== undefined);
    return resolved === undefined ? null : resolvedStylelintValue(resolved, hasLimitKnob);
};

const standardStylelintRules = function standardStylelintRules(
    data: QualityData,
    concernMap: Map<string, ResolvedConcern>,
): Record<string, StylelintRuleEntry> {
    const out: Record<string, StylelintRuleEntry> = {};
    for (const rule of data.rules.filter(
        (entry) => entry.tool === STYLELINT_TOOL && entry.category !== DEPRECATED_CATEGORY,
    )) {
        const emitted = stylelintConceptValue(rule, concernMap);
        if (emitted !== null) {
            out[rule.ruleId] = emitted;
        }
    }
    return out;
};

export const emitStylelintConfig = function emitStylelintConfig(
    policy: StylelintEmitPolicy = {},
    data: QualityData = loadQualityData(),
): Record<string, StylelintRuleEntry> {
    const exclude = new Set(policy.exclude);
    const options = policy.options ?? {};
    const concernMap = resolveConcernMap(policy.concerns ?? {});
    const catalogKeys = data.rules
        .filter((rule) => GOVLAB_STYLELINT_TOOLS.has(rule.tool) && rule.category !== DEPRECATED_CATEGORY)
        .filter((rule) => !excludedByConcept(rule.canonical ?? [], concernMap))
        .map((rule) => rule.ruleId);
    const keys = (policy.rules ?? catalogKeys).filter((key) => !exclude.has(key));
    const out = standardStylelintRules(data, concernMap);
    for (const key of keys) {
        const extra = options[key];
        out[key] = extra ? [true, extra] : true;
    }
    return out;
};
```
