core/producers/stylelint.producer.ts
core/producers/stylelint.producer.ts is a file in GovLab Quality. 67 lines of code and 15 definitions.
import type { CatalogProduct, CatalogRule } from "#types/catalog.types";
import { isRecord, recordAt, stringField } from "#core/selectors/record.selector";
import { byRuleId } from "#core/comparators/rule.comparator";
import { defineProducer } from "#core/registries/producer.registry";
const STYLELINT_MODULE = "stylelint";
const STYLELINT_MANIFEST = "stylelint/package.json";
const RULE_DOCS = "https://stylelint.io/user-guide/rules";
const AVOID_CATEGORY = "avoid";
const OTHER_CATEGORY = "other";
const PREFIX_CATEGORY: readonly [string, string][] = [
["color-", "color"],
["font-", "font"],
["selector-", "selector"],
["declaration-", "declaration"],
["function-", "function"],
["at-rule-", "at-rule"],
["media-", "media"],
["value-", "value"],
["unit-", "value"],
["length-", "value"],
];
const rulesOf = function rulesOf(loaded: unknown): Record<string, unknown> {
if (!isRecord(loaded)) {
return {};
}
const fallback = loaded["default"];
return isRecord(fallback) && isRecord(fallback["rules"]) ? fallback["rules"] : recordAt(loaded, "rules");
};
const categoryOf = function categoryOf(name: string): string {
if (name.startsWith("no-") || name.includes("-no-")) {
return AVOID_CATEGORY;
}
return PREFIX_CATEGORY.find(([prefix]) => name.startsWith(prefix))?.[1] ?? OTHER_CATEGORY;
};
const produce = async function produce(): Promise<CatalogProduct[]> {
const manifest: unknown = await import(STYLELINT_MANIFEST, { with: { type: "json" } });
const version =
isRecord(manifest) && isRecord(manifest["default"])
? stringField(manifest["default"], "version", "unknown")
: "unknown";
const rules = Object.keys(rulesOf(await import(STYLELINT_MODULE)))
.map((name): CatalogRule => ({
canonical: null,
category: categoryOf(name),
description: null,
ecosystem: "css",
name,
ruleId: name,
tool: "stylelint",
toolVersion: version,
url: `${RULE_DOCS}/${name}`,
}))
.toSorted(byRuleId);
const byCategory: Record<string, number> = {};
for (const rule of rules) {
const category = String(rule["category"]);
byCategory[category] = (byCategory[category] ?? 0) + 1;
}
return [
{
rules,
source: "stylelint",
summary: { byCategory, tool: "stylelint", toolVersion: version, total: rules.length },
},
];
};
defineProducer({ name: "stylelint", produce, refresh: "manual" });