core/adapters/stylelint.adapter.ts
core/adapters/stylelint.adapter.ts is a file in GovLab Quality. 66 lines of code and 16 definitions.
import { arrayField, isRecord, stringArrayField } from "#core/selectors/record.selector";
import type { RunResult } from "#types/finding.types";
import type { RunnerContext } from "#types/tool.types";
import { axisPluginsFor } from "#core/factories/axis.factory";
import { defineTool } from "#core/registries/tool.registry";
import { emitStylelintConfig } from "#core/emitters/stylelint.emitter";
import govlabStylelintPlugins from "#core/plugins/stylelint.plugin";
import { loadGovlabConfig } from "#core/loaders/config.loader";
import { loadUserPlugins } from "#core/loaders/plugin.loader";
import process from "node:process";
import { registerCanon } from "#core/registries/stylelint.registry";
import { sectionOf } from "#core/selectors/config.selector";
import stylelint from "stylelint";
import { toolFinding } from "#core/factories/finding.factory";
import { typeSystemRuleOptions } from "#core/converters/stylelint.converter";
import { validConcepts } from "#core/selectors/concept.selector";
import { validateConcerns } from "#core/validators/concern.validator";
import { withMasterExclude } from "#core/selectors/exclusions.selector";
const SECTION = "stylelint";
export const govlabStylelintConfig = async (consumerRoot: string = process.cwd()): Promise<Record<string, unknown>> => {
const config = await loadGovlabConfig(consumerRoot);
const section = sectionOf(config, SECTION);
const base = isRecord(section["base"]) ? section["base"] : {};
const ownRules = isRecord(section["rules"]) ? section["rules"] : {};
const typeSystem = config.eslint?.layout?.typeSystem;
const concerns = validateConcerns(config.qualityMaster?.concerns ?? {}, validConcepts());
const emitted = emitStylelintConfig({ concerns, exclude: stringArrayField(section, "exclude") });
const axes = axisPluginsFor(typeSystem);
for (const meta of axes.meta) {
registerCanon(meta);
}
const userPlugins = await loadUserPlugins(consumerRoot, { allowGlobal: config.extensions?.global ?? false });
const rules = { ...emitted, ...ownRules };
const basePlugins = arrayField(base, "plugins");
return {
...base,
ignoreFiles: withMasterExclude(config, stringArrayField(base, "ignoreFiles")),
plugins: [...basePlugins, ...govlabStylelintPlugins, ...axes.plugins, ...userPlugins.stylelint],
rules: { ...rules, ...typeSystemRuleOptions(typeSystem, rules), ...axes.rules },
};
};
const runStylelint = async function runStylelint(context: RunnerContext): Promise<RunResult> {
const result = await stylelint.lint({
allowEmptyInput: true,
config: await govlabStylelintConfig(context.root),
cwd: context.root,
files: context.paths,
fix: context.fix,
formatter: "string",
});
const findings = result.results.flatMap((fileResult) =>
fileResult.warnings.map((warning) =>
toolFinding({
column: warning.column,
ecosystem: context.ecosystem,
file: fileResult.source ?? "",
line: warning.line,
message: warning.text,
ruleId: warning.rule,
tool: SECTION,
}),
),
);
return { findings, fixedCount: 0, output: result.report };
};
defineTool({ ecosystems: ["css"], run: runStylelint, tool: SECTION });