pasika 0.10.143 → 0.10.145
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/eslint/pasika/index.js +111 -101
- package/package.json +1 -1
|
@@ -11512,128 +11512,138 @@ var themeResetRule = {
|
|
|
11512
11512
|
|
|
11513
11513
|
// eslint/rules/tailwind/theme-token-order.ts
|
|
11514
11514
|
import path77 from "path";
|
|
11515
|
-
var
|
|
11516
|
-
|
|
11517
|
-
|
|
11518
|
-
|
|
11519
|
-
"
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
"
|
|
11524
|
-
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
|
|
11535
|
-
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
"
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
function themeGroupName(name, value) {
|
|
11549
|
-
if (primitiveColors.has(name)) return "Color primitives";
|
|
11550
|
-
if (name.startsWith("--color-")) {
|
|
11551
|
-
return value.includes("var(") ? "Semantic colors" : "Fixed and brand colors";
|
|
11552
|
-
}
|
|
11553
|
-
if (name.startsWith("--font-") && !name.startsWith("--font-weight-")) return "Font families";
|
|
11554
|
-
if (/^--(?:font-weight|text-|tracking-|leading-)/u.test(name)) return "Typography";
|
|
11555
|
-
if (name.startsWith("--spacing")) return "Spacing and sizing";
|
|
11556
|
-
if (/^--(?:breakpoint|container|aspect)-/u.test(name)) return "Breakpoints, containers, and aspect ratios";
|
|
11557
|
-
if (name.startsWith("--radius")) return "Border radii";
|
|
11558
|
-
if (/^--(?:shadow|inset-shadow|drop-shadow|text-shadow)-/u.test(name)) return "Shadows and visual effects";
|
|
11559
|
-
if (name.startsWith("--background-image-")) return "Background images";
|
|
11560
|
-
if (/^--(?:default-transition|transition|ease)-/u.test(name)) return "Transitions and easing";
|
|
11561
|
-
if (name.startsWith("--animate-")) return "Animations";
|
|
11562
|
-
if (name.startsWith("--blur-")) return "Blur";
|
|
11563
|
-
return "Other tokens";
|
|
11515
|
+
var GROUP_RE = /^\s*\/\*\s*(?:Group:\s*)?(?<paths>(?:global|src\/[\w./-]+\.(?:tsx?|jsx?))(?:\s*,\s*src\/[\w./-]+\.(?:tsx?|jsx?))*)\s*\*\/\s*$/u;
|
|
11516
|
+
var PATH_RE = /^src\/[\w./-]+\.(?:tsx?|jsx?)$/u;
|
|
11517
|
+
function normalizeGroup(label) {
|
|
11518
|
+
if (label === "global") return "global";
|
|
11519
|
+
return [...new Set(label.split(",").map((name) => name.trim()))].sort().join(", ");
|
|
11520
|
+
}
|
|
11521
|
+
function sectionOf(symbol) {
|
|
11522
|
+
if (symbol.kind === "theme-token") return "theme";
|
|
11523
|
+
if (symbol.kind === "utility") return "utility";
|
|
11524
|
+
if (symbol.kind === "keyframes") return "keyframes";
|
|
11525
|
+
return symbol.kind;
|
|
11526
|
+
}
|
|
11527
|
+
function ownerOf(symbol, graph, root) {
|
|
11528
|
+
const references = graph.references.filter((ref) => {
|
|
11529
|
+
if (ref.source !== "module" || !/\.(?:tsx|jsx)$/u.test(ref.file) || /\.(?:test|spec|stories)\.(?:tsx|jsx)$/u.test(ref.file)) {
|
|
11530
|
+
return false;
|
|
11531
|
+
}
|
|
11532
|
+
if (symbol.kind === "theme-token") {
|
|
11533
|
+
return ref.kind === "theme-class" && ref.token === symbol.name || ref.kind === "variable" && ref.name === symbol.name;
|
|
11534
|
+
}
|
|
11535
|
+
if (symbol.kind === "utility" || symbol.kind === "keyframes" || symbol.kind === "selector") {
|
|
11536
|
+
return ref.name === symbol.name;
|
|
11537
|
+
}
|
|
11538
|
+
return ref.kind === "variable" && ref.name === symbol.name;
|
|
11539
|
+
});
|
|
11540
|
+
const indirect = graph.references.some(
|
|
11541
|
+
(ref) => ref.source === "css" && ref.file !== symbol.file && (symbol.kind === "theme-token" && ref.kind === "variable" && ref.name === symbol.name || symbol.kind === "utility" && ref.kind === "utility" && ref.name === symbol.name || symbol.kind === "keyframes" && ref.kind === "keyframes" && ref.name === symbol.name)
|
|
11542
|
+
);
|
|
11543
|
+
if (indirect) return "global";
|
|
11544
|
+
const owners = [
|
|
11545
|
+
...new Set(references.map((ref) => path77.relative(path77.dirname(root), ref.file).split(path77.sep).join("/")))
|
|
11546
|
+
].filter((name) => PATH_RE.test(name)).sort();
|
|
11547
|
+
return owners.length > 0 ? owners.join(", ") : "global";
|
|
11564
11548
|
}
|
|
11565
11549
|
var themeTokenOrderRule = {
|
|
11566
11550
|
meta: {
|
|
11567
11551
|
schema: [],
|
|
11568
11552
|
type: "problem",
|
|
11553
|
+
fixable: "code",
|
|
11569
11554
|
docs: {
|
|
11570
|
-
description: "
|
|
11555
|
+
description: "Group CSS definitions by consuming component paths in alphabetical order."
|
|
11571
11556
|
}
|
|
11572
11557
|
},
|
|
11573
11558
|
create(context) {
|
|
11574
11559
|
const root = sourceRootOf(context);
|
|
11575
|
-
const
|
|
11576
|
-
|
|
11560
|
+
const current = path77.normalize(path77.resolve(context.filename));
|
|
11561
|
+
const textOf = cachedTextReader();
|
|
11562
|
+
const cssFiles = /* @__PURE__ */ new Set([...findFiles(root, CSS_EXTENSIONS).map((file) => path77.normalize(file)), current]);
|
|
11563
|
+
const graph = buildCssDependencyGraph({
|
|
11564
|
+
sourceRoot: root,
|
|
11565
|
+
css: [...cssFiles].map((file) => ({
|
|
11566
|
+
path: file,
|
|
11567
|
+
content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11568
|
+
})),
|
|
11569
|
+
modules: findFiles(root, MODULE_EXTENSIONS4).map((file) => ({ path: file, content: textOf(file) }))
|
|
11570
|
+
});
|
|
11571
|
+
const lines = context.sourceCode.text.split(/\r?\n/u);
|
|
11572
|
+
const groups = [];
|
|
11573
|
+
for (const [index, line] of lines.entries()) {
|
|
11574
|
+
const match = GROUP_RE.exec(line);
|
|
11575
|
+
if (match?.groups?.paths) groups.push({ label: normalizeGroup(match.groups.paths), line: index + 1 });
|
|
11576
|
+
}
|
|
11577
|
+
const items = graph.definitions.filter((symbol) => symbol.file === current && symbol.name !== "--*").filter(
|
|
11578
|
+
(symbol) => ["theme-token", "utility", "keyframes", "root-variable", "selector", "font-face"].includes(symbol.kind)
|
|
11579
|
+
).map((symbol) => ({
|
|
11580
|
+
symbol,
|
|
11581
|
+
owner: ownerOf(symbol, graph, root),
|
|
11582
|
+
section: sectionOf(symbol)
|
|
11583
|
+
})).sort((a, b) => a.symbol.line - b.symbol.line);
|
|
11584
|
+
let activeGroup;
|
|
11585
|
+
let previousItem;
|
|
11586
|
+
for (const item of items) {
|
|
11587
|
+
const previousLine = previousItem?.symbol.line ?? 0;
|
|
11588
|
+
const intervening = groups.filter((group) => group.line > previousLine && group.line < item.symbol.line).at(-1);
|
|
11589
|
+
if (item.section !== previousItem?.section) activeGroup = intervening;
|
|
11590
|
+
else if (intervening) activeGroup = intervening;
|
|
11591
|
+
item.group = activeGroup;
|
|
11592
|
+
previousItem = item;
|
|
11593
|
+
}
|
|
11577
11594
|
return {
|
|
11578
|
-
"StyleSheet:exit"(
|
|
11579
|
-
const
|
|
11580
|
-
(child) => child.type === "Atrule" && child.name === "theme" && child.loc
|
|
11581
|
-
);
|
|
11582
|
-
if (!theme?.loc) return;
|
|
11583
|
-
const raw = context.sourceCode.text.slice(theme.loc.start.offset, theme.loc.end.offset);
|
|
11584
|
-
const opening = raw.indexOf("{");
|
|
11585
|
-
const closing = raw.lastIndexOf("}");
|
|
11586
|
-
if (opening === -1 || closing <= opening) return;
|
|
11587
|
-
const lines = raw.slice(opening + 1, closing).split(/\r?\n/u);
|
|
11588
|
-
const firstLine = theme.loc.start.line + (raw.slice(0, opening + 1).match(/\n/gu)?.length ?? 0);
|
|
11589
|
-
const tokens = [];
|
|
11590
|
-
let activeHeading;
|
|
11591
|
-
let hasGroupHeadings = false;
|
|
11592
|
-
for (const [index, line] of lines.entries()) {
|
|
11593
|
-
const heading = /^\s*\/\*\s*(?<heading>.*?)\s*\*\/\s*$/u.exec(line)?.groups?.heading;
|
|
11594
|
-
if (heading && THEME_GROUPS.includes(heading)) {
|
|
11595
|
-
activeHeading = heading;
|
|
11596
|
-
hasGroupHeadings = true;
|
|
11597
|
-
}
|
|
11598
|
-
const declaration = /^ {2}(?<name>--[a-z][a-z0-9-]*)\s*:\s*(?<value>.*)$/u.exec(line);
|
|
11599
|
-
const { name, value } = declaration?.groups ?? {};
|
|
11600
|
-
if (!name || value === void 0) continue;
|
|
11601
|
-
tokens.push({
|
|
11602
|
-
name,
|
|
11603
|
-
group: themeGroupName(name, value),
|
|
11604
|
-
activeHeading,
|
|
11605
|
-
line: firstLine + index
|
|
11606
|
-
});
|
|
11607
|
-
}
|
|
11608
|
-
if (tokens.length > 1 && !hasGroupHeadings) {
|
|
11595
|
+
"StyleSheet:exit"(node) {
|
|
11596
|
+
for (const group of groups.filter((entry) => entry.label === "global")) {
|
|
11609
11597
|
context.report({
|
|
11610
|
-
node
|
|
11611
|
-
|
|
11598
|
+
node,
|
|
11599
|
+
loc: { start: { line: group.line, column: 1 }, end: { line: group.line, column: 2 } },
|
|
11600
|
+
message: "Global CSS definitions must not have a group comment.",
|
|
11601
|
+
fix(fixer) {
|
|
11602
|
+
const start = context.sourceCode.getIndexFromLoc({ line: group.line, column: 1 });
|
|
11603
|
+
const end = start + (lines[group.line - 1] ?? "").length;
|
|
11604
|
+
const remaining = context.sourceCode.text.slice(end);
|
|
11605
|
+
let newline = 0;
|
|
11606
|
+
if (remaining.startsWith("\r\n")) newline = 2;
|
|
11607
|
+
else if (remaining.startsWith("\n")) newline = 1;
|
|
11608
|
+
return fixer.removeRange([start, end + newline]);
|
|
11609
|
+
}
|
|
11612
11610
|
});
|
|
11613
11611
|
}
|
|
11614
11612
|
let previous;
|
|
11615
|
-
for (const
|
|
11613
|
+
for (const item of items) {
|
|
11614
|
+
const currentGroup = item.group;
|
|
11615
|
+
const actual = currentGroup?.label;
|
|
11616
|
+
const reportedGroup = actual ?? "none";
|
|
11616
11617
|
let message;
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
if (
|
|
11620
|
-
message = `
|
|
11621
|
-
} else if (
|
|
11622
|
-
message = `
|
|
11623
|
-
} else if (
|
|
11624
|
-
|
|
11618
|
+
if (item.owner === "global" && currentGroup && currentGroup.label !== "global") {
|
|
11619
|
+
message = "Global definitions must be ungrouped.";
|
|
11620
|
+
} else if (item.owner !== "global" && !currentGroup) {
|
|
11621
|
+
message = `CSS definition "${item.symbol.name}" requires a component-path group comment.`;
|
|
11622
|
+
} else if (item.owner !== "global" && actual !== item.owner) {
|
|
11623
|
+
message = `CSS definition "${item.symbol.name}" belongs to group "${item.owner}", not "${reportedGroup}".`;
|
|
11624
|
+
} else if (previous?.section === item.section) {
|
|
11625
|
+
if (previous.owner !== item.owner && previous.owner.localeCompare(item.owner) > 0) {
|
|
11626
|
+
message = `CSS consumer groups in ${item.section} must be ordered alphabetically by path.`;
|
|
11627
|
+
} else if (previous.owner === item.owner && previous.symbol.name.localeCompare(item.symbol.name) > 0) {
|
|
11628
|
+
message = `CSS definitions in group "${item.owner}" must be alphabetical: "${item.symbol.name}" comes before "${previous.symbol.name}".`;
|
|
11629
|
+
}
|
|
11625
11630
|
}
|
|
11626
11631
|
if (message) {
|
|
11632
|
+
const line = item.symbol.line;
|
|
11627
11633
|
context.report({
|
|
11628
|
-
node
|
|
11629
|
-
loc: {
|
|
11630
|
-
|
|
11631
|
-
|
|
11632
|
-
|
|
11633
|
-
|
|
11634
|
+
node,
|
|
11635
|
+
loc: { start: { line, column: 1 }, end: { line, column: 2 } },
|
|
11636
|
+
message,
|
|
11637
|
+
...item.owner !== "global" && currentGroup && actual !== item.owner && items.filter((candidate) => candidate.group === currentGroup).length === 1 ? {
|
|
11638
|
+
fix(fixer) {
|
|
11639
|
+
const start = context.sourceCode.getIndexFromLoc({ line: currentGroup.line, column: 1 });
|
|
11640
|
+
const end = start + (lines[currentGroup.line - 1] ?? "").length;
|
|
11641
|
+
return fixer.replaceTextRange([start, end], `/* Group: ${item.owner} */`);
|
|
11642
|
+
}
|
|
11643
|
+
} : {}
|
|
11634
11644
|
});
|
|
11635
11645
|
}
|
|
11636
|
-
previous =
|
|
11646
|
+
previous = item;
|
|
11637
11647
|
}
|
|
11638
11648
|
}
|
|
11639
11649
|
};
|