# rules/plugins/stylelint.plugin.ts

> 35 lines of code and 9 definitions.

Tree: Governance tree
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/governance#file-governance-rules-plugins-stylelint-plugin-ts
Source text: https://banes-lab.com/source/governance/rules/plugins/stylelint.plugin.ts.txt

Listed in [rules/plugins](https://banes-lab.com/api/source/governance/rules/plugins.md), after [rules/plugins/rule.plugin.ts](https://banes-lab.com/source/governance/rules/plugins/rule.plugin.ts.md).

## Definitions

- `isPlugin` (lexical_declaration, line 14)
- `isRecord` (lexical_declaration, line 10)
- `scopeToProject` (lexical_declaration, line 18)
- `RULE_NAMESPACE` (lexical_declaration, line 8)
- `ruleName` (lexical_declaration, line 19)
- `inner` (lexical_declaration, line 23)
- `scoped` (lexical_declaration, line 24)
- `file` (lexical_declaration, line 27)
- `stylesheetPlugins` (lexical_declaration, line 37)

## Uses

- [shared/strings/rule.strings.ts](https://banes-lab.com/source/governance/shared/strings/rule.strings.ts.md)

## Source

```typescript
import type { Plugin, PostcssResult, Rule, RuleContext } from "stylelint";
import { LOCAL_STYLELINT_RULES } from "../../shared/generated/stylelint-index.generated.ts";
import type { Root } from "postcss";
import { isGovernedFile } from "../../shared/resolvers/anchor.resolver.ts";
import stylelint from "stylelint";
import { stylesheetRuleUnnamed } from "../../shared/strings/rule.strings.ts";

const RULE_NAMESPACE = "local/";

const isRecord = function isRecord(value: unknown): value is Record<string, unknown> {
    return typeof value === "object" && value !== null;
};

const isPlugin = function isPlugin(value: unknown): value is Plugin & { ruleName: string; rule: Rule } {
    return isRecord(value) && typeof value["ruleName"] === "string" && typeof value["rule"] === "function";
};

const scopeToProject = function scopeToProject(label: string, plugin: unknown): Plugin {
    const ruleName = RULE_NAMESPACE + label;
    if (!isPlugin(plugin) || plugin.ruleName !== ruleName) {
        throw new Error(stylesheetRuleUnnamed(label, ruleName));
    }
    const inner = plugin.rule;
    const scoped: Rule = Object.assign(
        (primary: unknown, secondary: unknown, context: RuleContext) =>
            (root: Root, result: PostcssResult): void => {
                const file = root.source?.input.file;
                if (file !== undefined && isGovernedFile(file)) {
                    void inner(primary, secondary, context)(root, result);
                }
            },
        { messages: inner.messages, ruleName, ...(inner.meta === undefined ? {} : { meta: inner.meta }) },
    );
    return stylelint.createPlugin(ruleName, scoped);
};

const stylesheetPlugins = Object.entries(LOCAL_STYLELINT_RULES).map(([label, plugin]) =>
    scopeToProject(label, plugin),
);

export default { plugins: stylesheetPlugins, tool: "stylelint" };
```
