pasika 0.10.115 → 0.10.116
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.d.ts +2 -0
- package/dist/eslint/pasika/index.js +248 -70
- package/package.json +1 -1
|
@@ -133,6 +133,7 @@ declare const tailwindRules: {
|
|
|
133
133
|
"global-stylesheet": _eslint_css.CSSRuleDefinition;
|
|
134
134
|
"unused-utility": _eslint_css.CSSRuleDefinition;
|
|
135
135
|
"unique-css-definition": _eslint_css.CSSRuleDefinition;
|
|
136
|
+
"unique-css-token-value": _eslint_css.CSSRuleDefinition;
|
|
136
137
|
"no-utility-alias": _eslint_css.CSSRuleDefinition;
|
|
137
138
|
"global-selector-styling": _eslint_css.CSSRuleDefinition;
|
|
138
139
|
};
|
|
@@ -172,6 +173,7 @@ declare const pasikaPlugin: {
|
|
|
172
173
|
"global-stylesheet": _eslint_css.CSSRuleDefinition;
|
|
173
174
|
"unused-utility": _eslint_css.CSSRuleDefinition;
|
|
174
175
|
"unique-css-definition": _eslint_css.CSSRuleDefinition;
|
|
176
|
+
"unique-css-token-value": _eslint_css.CSSRuleDefinition;
|
|
175
177
|
"no-utility-alias": _eslint_css.CSSRuleDefinition;
|
|
176
178
|
"global-selector-styling": _eslint_css.CSSRuleDefinition;
|
|
177
179
|
"doc-kind-suffix": _eslint_markdown.MarkdownRuleDefinition;
|
|
@@ -10156,7 +10156,7 @@ function buildCssDependencyGraph(options) {
|
|
|
10156
10156
|
} else if (node.name === "theme" && node.loc) {
|
|
10157
10157
|
const source = file.content.slice(node.loc.start.offset, node.loc.end.offset).replace(/\/\*[\s\S]*?\*\//gu, (comment) => comment.replace(/[^\r\n]/gu, " "));
|
|
10158
10158
|
for (const found of source.matchAll(
|
|
10159
|
-
/(?:^|[{;\r\n])\s*(?<name>--[a-z][\w-]*)\s*:\s*(?<value>[
|
|
10159
|
+
/(?:^|(?<=[{;\r\n]))\s*(?<name>--[a-z][\w-]*)\s*:\s*(?<value>[^;}\r\n]+)(?=;|[}])/gu
|
|
10160
10160
|
)) {
|
|
10161
10161
|
const name = found.groups?.name;
|
|
10162
10162
|
const value = found.groups?.value;
|
|
@@ -10912,48 +10912,129 @@ var uniqueCssDefinitionRule = {
|
|
|
10912
10912
|
schema: [],
|
|
10913
10913
|
type: "problem",
|
|
10914
10914
|
docs: {
|
|
10915
|
-
description: "Reject duplicate
|
|
10915
|
+
description: "Reject duplicate CSS definitions both within and across stylesheets while preserving scoped overrides."
|
|
10916
10916
|
}
|
|
10917
10917
|
},
|
|
10918
10918
|
create(context) {
|
|
10919
10919
|
const sourceRoot = sourceRootOf(context);
|
|
10920
|
+
const current = path74.normalize(path74.resolve(context.filename));
|
|
10920
10921
|
const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
10921
10922
|
if (cssFiles.length === 0) return {};
|
|
10922
10923
|
const textOf = cachedTextReader();
|
|
10923
10924
|
const graph = buildCssDependencyGraph({
|
|
10924
10925
|
sourceRoot,
|
|
10925
|
-
css: cssFiles.map((file) => ({
|
|
10926
|
+
css: cssFiles.map((file) => ({
|
|
10927
|
+
path: file,
|
|
10928
|
+
content: path74.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
10929
|
+
})),
|
|
10926
10930
|
modules: [],
|
|
10927
10931
|
includeReferences: false
|
|
10928
10932
|
});
|
|
10929
|
-
const
|
|
10933
|
+
const groups = /* @__PURE__ */ new Map();
|
|
10930
10934
|
for (const symbol of graph.definitions) {
|
|
10931
10935
|
const key = ownershipKey(symbol);
|
|
10932
10936
|
if (!key) continue;
|
|
10933
|
-
const
|
|
10934
|
-
|
|
10935
|
-
|
|
10937
|
+
const definitions = groups.get(key) ?? [];
|
|
10938
|
+
definitions.push(symbol);
|
|
10939
|
+
groups.set(key, definitions);
|
|
10936
10940
|
}
|
|
10937
10941
|
return {
|
|
10938
10942
|
"StyleSheet:exit"(node) {
|
|
10939
|
-
const
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10943
|
+
for (const definitions of groups.values()) {
|
|
10944
|
+
if (definitions.length < 2) continue;
|
|
10945
|
+
definitions.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
|
|
10946
|
+
const canonical = definitions[0];
|
|
10947
|
+
if (!canonical) continue;
|
|
10948
|
+
for (const symbol of definitions.slice(1)) {
|
|
10949
|
+
if (symbol.file !== current) continue;
|
|
10950
|
+
const message = symbol.file === canonical.file ? `${symbolLabel(symbol)} "${symbol.name}" is defined more than once in this CSS file; define it only once.` : `${symbolLabel(symbol)} "${symbol.name}" is also defined in ${path74.relative(sourceRoot, canonical.file)}; define it in only one CSS file.`;
|
|
10951
|
+
context.report({
|
|
10952
|
+
node,
|
|
10953
|
+
loc: {
|
|
10954
|
+
start: { line: symbol.line, column: 1 },
|
|
10955
|
+
end: { line: symbol.line, column: 2 }
|
|
10956
|
+
},
|
|
10957
|
+
message
|
|
10958
|
+
});
|
|
10959
|
+
}
|
|
10960
|
+
}
|
|
10961
|
+
}
|
|
10962
|
+
};
|
|
10963
|
+
}
|
|
10964
|
+
};
|
|
10965
|
+
|
|
10966
|
+
// eslint/rules/tailwind/unique-css-token-value.ts
|
|
10967
|
+
import path75 from "path";
|
|
10968
|
+
function valueIdentity(value) {
|
|
10969
|
+
const text = value.trim();
|
|
10970
|
+
const hex = /^#(?<digits>[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/iu.exec(text)?.groups?.digits;
|
|
10971
|
+
if (!hex) return text;
|
|
10972
|
+
const lower = hex.toLowerCase();
|
|
10973
|
+
const full = lower.length <= 4 ? Array.from(lower, (digit) => digit + digit).join("") : lower;
|
|
10974
|
+
return `#${full.length === 8 && full.endsWith("ff") ? full.slice(0, -2) : full}`;
|
|
10975
|
+
}
|
|
10976
|
+
function isComparable(symbol) {
|
|
10977
|
+
if (symbol.value === void 0 || symbol.value.trim() === "") return false;
|
|
10978
|
+
if (/\b(?:var|env|attr|calc|min|max|clamp|color-mix|light-dark)\s*\(/iu.test(symbol.value)) return false;
|
|
10979
|
+
return symbol.kind === "theme-token" || symbol.kind === "root-variable" && symbol.scope === "default";
|
|
10980
|
+
}
|
|
10981
|
+
function compareLocations(left, right) {
|
|
10982
|
+
const file = left.file.localeCompare(right.file);
|
|
10983
|
+
return file || left.line - right.line;
|
|
10984
|
+
}
|
|
10985
|
+
var uniqueCssTokenValueRule = {
|
|
10986
|
+
meta: {
|
|
10987
|
+
schema: [],
|
|
10988
|
+
type: "problem",
|
|
10989
|
+
docs: {
|
|
10990
|
+
description: "Reject distinct CSS design tokens with duplicate static values across the project."
|
|
10991
|
+
}
|
|
10992
|
+
},
|
|
10993
|
+
create(context) {
|
|
10994
|
+
const sourceRoot = sourceRootOf(context);
|
|
10995
|
+
const current = path75.normalize(path75.resolve(context.filename));
|
|
10996
|
+
const textOf = cachedTextReader();
|
|
10997
|
+
const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
10998
|
+
const graph = buildCssDependencyGraph({
|
|
10999
|
+
sourceRoot,
|
|
11000
|
+
css: cssFiles.map((file) => ({
|
|
11001
|
+
path: file,
|
|
11002
|
+
content: path75.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11003
|
+
})),
|
|
11004
|
+
modules: [],
|
|
11005
|
+
includeReferences: false
|
|
11006
|
+
});
|
|
11007
|
+
const byValue = /* @__PURE__ */ new Map();
|
|
11008
|
+
for (const definition of graph.definitions) {
|
|
11009
|
+
if (!isComparable(definition)) continue;
|
|
11010
|
+
const value = valueIdentity(definition.value ?? "");
|
|
11011
|
+
const group = byValue.get(value) ?? [];
|
|
11012
|
+
group.push(definition);
|
|
11013
|
+
byValue.set(value, group);
|
|
11014
|
+
}
|
|
11015
|
+
const redundant = /* @__PURE__ */ new Map();
|
|
11016
|
+
for (const group of byValue.values()) {
|
|
11017
|
+
group.sort(compareLocations);
|
|
11018
|
+
const first = group[0];
|
|
11019
|
+
if (!first) continue;
|
|
11020
|
+
for (const definition of group.slice(1)) {
|
|
11021
|
+
if (definition.name !== first.name) redundant.set(definition, first);
|
|
11022
|
+
}
|
|
11023
|
+
}
|
|
11024
|
+
return {
|
|
11025
|
+
"StyleSheet:exit"(node) {
|
|
11026
|
+
for (const [definition, original] of redundant) {
|
|
11027
|
+
if (definition.file !== current) continue;
|
|
10950
11028
|
context.report({
|
|
10951
11029
|
node,
|
|
10952
11030
|
loc: {
|
|
10953
|
-
start: { line:
|
|
10954
|
-
end: { line:
|
|
11031
|
+
start: { line: definition.line, column: 1 },
|
|
11032
|
+
end: { line: definition.line, column: 2 }
|
|
10955
11033
|
},
|
|
10956
|
-
message:
|
|
11034
|
+
message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${path75.relative(
|
|
11035
|
+
sourceRoot,
|
|
11036
|
+
original.file
|
|
11037
|
+
)}:${String(original.line)}; reuse one design token.`
|
|
10957
11038
|
});
|
|
10958
11039
|
}
|
|
10959
11040
|
}
|
|
@@ -10963,7 +11044,7 @@ var uniqueCssDefinitionRule = {
|
|
|
10963
11044
|
|
|
10964
11045
|
// eslint/rules/tailwind/unused-utility.ts
|
|
10965
11046
|
import { statSync as statSync5 } from "fs";
|
|
10966
|
-
import
|
|
11047
|
+
import path76 from "path";
|
|
10967
11048
|
var unusedUtilityRule = {
|
|
10968
11049
|
meta: {
|
|
10969
11050
|
schema: [],
|
|
@@ -10979,7 +11060,7 @@ var unusedUtilityRule = {
|
|
|
10979
11060
|
} catch {
|
|
10980
11061
|
return {};
|
|
10981
11062
|
}
|
|
10982
|
-
const current =
|
|
11063
|
+
const current = path76.normalize(path76.resolve(context.filename));
|
|
10983
11064
|
const textOf = cachedTextReader();
|
|
10984
11065
|
const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
10985
11066
|
const moduleFiles = findFiles(sourceRoot, MODULE_EXTENSIONS4);
|
|
@@ -10987,7 +11068,7 @@ var unusedUtilityRule = {
|
|
|
10987
11068
|
sourceRoot,
|
|
10988
11069
|
css: cssFiles.map((file) => ({
|
|
10989
11070
|
path: file,
|
|
10990
|
-
content:
|
|
11071
|
+
content: path76.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
10991
11072
|
})),
|
|
10992
11073
|
modules: moduleFiles.map((file) => ({ path: file, content: textOf(file) }))
|
|
10993
11074
|
});
|
|
@@ -11008,6 +11089,7 @@ var unusedUtilityRule = {
|
|
|
11008
11089
|
};
|
|
11009
11090
|
|
|
11010
11091
|
// eslint/rules/tailwind/utility-mapping.ts
|
|
11092
|
+
import path77 from "path";
|
|
11011
11093
|
function applyOperationCount(utility) {
|
|
11012
11094
|
let count = 0;
|
|
11013
11095
|
for (const apply of atrulesNamed(utility, "apply")) {
|
|
@@ -11023,30 +11105,79 @@ function applyOperationCount(utility) {
|
|
|
11023
11105
|
}
|
|
11024
11106
|
return count;
|
|
11025
11107
|
}
|
|
11108
|
+
var themeOperations = [
|
|
11109
|
+
{ property: "font-size", prefix: "text", namespace: "text" },
|
|
11110
|
+
{ property: "letter-spacing", prefix: "tracking", namespace: "tracking" },
|
|
11111
|
+
{ property: "line-height", prefix: "leading", namespace: "leading" },
|
|
11112
|
+
{ property: "font-family", prefix: "font", namespace: "font" },
|
|
11113
|
+
{ property: "font-weight", prefix: "font", namespace: "font-weight" },
|
|
11114
|
+
{ property: "tab-size", prefix: "tab", namespace: "tab-size" },
|
|
11115
|
+
{ property: "border-radius", prefix: "rounded", namespace: "radius" },
|
|
11116
|
+
{ property: "background-color", prefix: "bg", namespace: "color" },
|
|
11117
|
+
{ property: "color", prefix: "text", namespace: "color" },
|
|
11118
|
+
{ property: "border-color", prefix: "border", namespace: "color" },
|
|
11119
|
+
{ property: "outline-color", prefix: "outline", namespace: "color" },
|
|
11120
|
+
{ property: "fill", prefix: "fill", namespace: "color" },
|
|
11121
|
+
{ property: "stroke", prefix: "stroke", namespace: "color" },
|
|
11122
|
+
{ property: "caret-color", prefix: "caret", namespace: "color" },
|
|
11123
|
+
{ property: "text-decoration-color", prefix: "decoration", namespace: "color" },
|
|
11124
|
+
{ property: "padding", prefix: "p", namespace: "spacing" },
|
|
11125
|
+
{ property: "padding-top", prefix: "pt", namespace: "spacing" },
|
|
11126
|
+
{ property: "padding-right", prefix: "pr", namespace: "spacing" },
|
|
11127
|
+
{ property: "padding-bottom", prefix: "pb", namespace: "spacing" },
|
|
11128
|
+
{ property: "padding-left", prefix: "pl", namespace: "spacing" },
|
|
11129
|
+
{ property: "margin", prefix: "m", namespace: "spacing" },
|
|
11130
|
+
{ property: "margin-top", prefix: "mt", namespace: "spacing" },
|
|
11131
|
+
{ property: "margin-right", prefix: "mr", namespace: "spacing" },
|
|
11132
|
+
{ property: "margin-bottom", prefix: "mb", namespace: "spacing" },
|
|
11133
|
+
{ property: "margin-left", prefix: "ml", namespace: "spacing" },
|
|
11134
|
+
{ property: "gap", prefix: "gap", namespace: "spacing" },
|
|
11135
|
+
{ property: "width", prefix: "w", namespace: "spacing" },
|
|
11136
|
+
{ property: "height", prefix: "h", namespace: "spacing" },
|
|
11137
|
+
{ property: "aspect-ratio", prefix: "aspect", namespace: "aspect" },
|
|
11138
|
+
{ property: "transition-timing-function", prefix: "ease", namespace: "ease" },
|
|
11139
|
+
{ property: "zoom", prefix: "zoom", namespace: "zoom" },
|
|
11140
|
+
{ property: "perspective", prefix: "perspective", namespace: "perspective" },
|
|
11141
|
+
{ property: "animation", prefix: "animate", namespace: "animate" }
|
|
11142
|
+
];
|
|
11026
11143
|
function themeCandidate(name, utilityText) {
|
|
11027
11144
|
const source = utilityText.trim();
|
|
11028
|
-
const arbitrary = /^@utility\s+[\w-]+\s*\{\s*@apply\s+\[(?<property>
|
|
11145
|
+
const arbitrary = /^@utility\s+[\w-]+\s*\{\s*@apply\s+\[(?<property>[a-z-]+):(?<value>[^\]\r\n;{}]+)\];?\s*\}$/u.exec(
|
|
11029
11146
|
source
|
|
11030
11147
|
);
|
|
11031
|
-
const typed = /^@utility\s+[\w-]+\s*\{\s*@apply\s+(?<kind>
|
|
11148
|
+
const typed = /^@utility\s+[\w-]+\s*\{\s*@apply\s+(?<kind>[a-z]+)-\((?<hint>[a-z-]+:)?(?<variable>--[a-z][a-z0-9-]*)\);?\s*\}$/u.exec(
|
|
11032
11149
|
source
|
|
11033
11150
|
);
|
|
11034
|
-
const
|
|
11035
|
-
const
|
|
11036
|
-
|
|
11037
|
-
|
|
11038
|
-
|
|
11039
|
-
|
|
11040
|
-
|
|
11151
|
+
const property = arbitrary?.groups?.property;
|
|
11152
|
+
const matched = themeOperations.find((operation) => {
|
|
11153
|
+
if (!name.startsWith(`${operation.prefix}-`) || name.length <= operation.prefix.length + 1) return false;
|
|
11154
|
+
if (property) return property === operation.property;
|
|
11155
|
+
if (typed?.groups?.kind !== operation.prefix) return false;
|
|
11156
|
+
const hint = typed.groups.hint;
|
|
11157
|
+
if (operation.prefix === "text") return hint === (operation.property === "font-size" ? "length:" : "color:");
|
|
11158
|
+
if (operation.prefix === "font") {
|
|
11159
|
+
return hint === (operation.property === "font-family" ? "family-name:" : "number:");
|
|
11160
|
+
}
|
|
11161
|
+
return hint === void 0;
|
|
11162
|
+
});
|
|
11163
|
+
if (!matched) return void 0;
|
|
11041
11164
|
const value = arbitrary?.groups?.value?.trim() ?? (typed?.groups?.variable ? `var(${typed.groups.variable})` : void 0);
|
|
11042
|
-
if (!
|
|
11043
|
-
const
|
|
11044
|
-
if (!name.startsWith(prefix) || name.length === prefix.length) return void 0;
|
|
11045
|
-
const length = /^-?(?:\d+(?:\.\d+)?|\.\d+)(?:px|rem|em|%)$/u.test(value);
|
|
11165
|
+
if (!value) return void 0;
|
|
11166
|
+
const simple = /^-?(?:\d+(?:\.\d+)?|\.\d+)(?:px|rem|em|%|vh|vw|ch|deg)?$/u.test(value);
|
|
11046
11167
|
const variable = /^var\(--[a-z][a-z0-9-]*\)$/u.test(value);
|
|
11047
|
-
|
|
11048
|
-
|
|
11049
|
-
|
|
11168
|
+
const color = /^#[\da-f]{3,8}$/iu.test(value);
|
|
11169
|
+
const keyword = /^[a-z][a-z-]*$/u.test(value);
|
|
11170
|
+
const ratio = /^\d+\/\d+$/u.test(value);
|
|
11171
|
+
if (!simple && !variable && !color && !keyword && !ratio) return void 0;
|
|
11172
|
+
if (matched.property === "font-size" && value.startsWith("-")) return void 0;
|
|
11173
|
+
const stem = name.slice(matched.prefix.length + 1);
|
|
11174
|
+
return {
|
|
11175
|
+
token: `--${matched.namespace}-${stem}`,
|
|
11176
|
+
property: matched.property,
|
|
11177
|
+
value,
|
|
11178
|
+
prefix: matched.prefix,
|
|
11179
|
+
namespace: matched.namespace
|
|
11180
|
+
};
|
|
11050
11181
|
}
|
|
11051
11182
|
var builtInTextSizes = /* @__PURE__ */ new Set([
|
|
11052
11183
|
"xs",
|
|
@@ -11092,6 +11223,19 @@ var utilityMappingRule = {
|
|
|
11092
11223
|
}
|
|
11093
11224
|
},
|
|
11094
11225
|
create(context) {
|
|
11226
|
+
const sourceRoot = sourceRootOf(context);
|
|
11227
|
+
const current = path77.normalize(path77.resolve(context.filename));
|
|
11228
|
+
const textOf = cachedTextReader();
|
|
11229
|
+
const graph = buildCssDependencyGraph({
|
|
11230
|
+
sourceRoot,
|
|
11231
|
+
css: findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => ({
|
|
11232
|
+
path: file,
|
|
11233
|
+
content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11234
|
+
})),
|
|
11235
|
+
modules: [],
|
|
11236
|
+
includeReferences: false
|
|
11237
|
+
});
|
|
11238
|
+
const projectTokens = graph.definitions.filter((symbol) => symbol.kind === "theme-token");
|
|
11095
11239
|
return {
|
|
11096
11240
|
"StyleSheet:exit"(node) {
|
|
11097
11241
|
const utilities = atrulesNamed(node, "utility");
|
|
@@ -11180,7 +11324,38 @@ var utilityMappingRule = {
|
|
|
11180
11324
|
}
|
|
11181
11325
|
if (nameCounts.get(name) !== 1) continue;
|
|
11182
11326
|
const candidate = themeCandidate(name, context.sourceCode.getText(utility));
|
|
11183
|
-
if (!candidate
|
|
11327
|
+
if (!candidate) continue;
|
|
11328
|
+
const tokenAlreadyDefined = themeTokens.has(candidate.token) || projectTokens.some((token) => token.name === candidate.token);
|
|
11329
|
+
const namespacePrefix = `--${candidate.namespace}-`;
|
|
11330
|
+
const staticValue = !/\b(?:var|env|attr|calc|min|max|clamp|color-mix|light-dark)\s*\(/iu.test(
|
|
11331
|
+
candidate.value
|
|
11332
|
+
);
|
|
11333
|
+
const valueKey = (value) => {
|
|
11334
|
+
const input = value.trim();
|
|
11335
|
+
const digits = /^#(?<hex>[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/iu.exec(input)?.groups?.hex;
|
|
11336
|
+
if (digits) {
|
|
11337
|
+
const lower = digits.toLowerCase();
|
|
11338
|
+
return lower.length <= 4 ? Array.from(lower, (digit) => digit + digit).join("") : lower;
|
|
11339
|
+
}
|
|
11340
|
+
return input;
|
|
11341
|
+
};
|
|
11342
|
+
const sameOperation = (token, value) => token.startsWith(namespacePrefix) && !token.includes("--", 2) && valueKey(value) === valueKey(candidate.value) && (candidate.namespace !== "text" || !["--line-height", "--letter-spacing", "--font-weight"].some(
|
|
11343
|
+
(suffix) => themeDefinitions.has(`${token}${suffix}`) || projectTokens.some((definition) => definition.name === `${token}${suffix}`)
|
|
11344
|
+
));
|
|
11345
|
+
const equivalent = staticValue ? projectTokens.find((token) => token.value !== void 0 && sameOperation(token.name, token.value)) : void 0;
|
|
11346
|
+
const localEquivalent = staticValue ? [...themeDefinitions].find(
|
|
11347
|
+
([token, definitions]) => definitions.length === 1 && definitions[0]?.value !== void 0 && sameOperation(token, definitions[0].value)
|
|
11348
|
+
)?.[0] : void 0;
|
|
11349
|
+
const existingToken = equivalent?.name ?? localEquivalent;
|
|
11350
|
+
if (tokenAlreadyDefined && !existingToken) continue;
|
|
11351
|
+
if (existingToken) {
|
|
11352
|
+
const className = `${candidate.prefix}-${existingToken.slice(namespacePrefix.length)}`;
|
|
11353
|
+
context.report({
|
|
11354
|
+
node: utility,
|
|
11355
|
+
message: `Custom utility "${name}" duplicates theme-generated "${className}" (${candidate.property}: ${candidate.value}); reuse "${className}" instead.`
|
|
11356
|
+
});
|
|
11357
|
+
continue;
|
|
11358
|
+
}
|
|
11184
11359
|
if (candidate.property === "font-size" && themeTokens.has(`--color-${name.slice(5)}`)) continue;
|
|
11185
11360
|
context.report({
|
|
11186
11361
|
node: utility,
|
|
@@ -11207,12 +11382,13 @@ var tailwindRules = {
|
|
|
11207
11382
|
"global-stylesheet": globalStylesheetRule,
|
|
11208
11383
|
"unused-utility": unusedUtilityRule,
|
|
11209
11384
|
"unique-css-definition": uniqueCssDefinitionRule,
|
|
11385
|
+
"unique-css-token-value": uniqueCssTokenValueRule,
|
|
11210
11386
|
"no-utility-alias": noUtilityAliasRule,
|
|
11211
11387
|
"global-selector-styling": globalSelectorStylingRule
|
|
11212
11388
|
};
|
|
11213
11389
|
|
|
11214
11390
|
// eslint/rules/type-extraction.ts
|
|
11215
|
-
import
|
|
11391
|
+
import path78 from "path";
|
|
11216
11392
|
var typeExtractionRule = {
|
|
11217
11393
|
meta: {
|
|
11218
11394
|
schema: [],
|
|
@@ -11223,7 +11399,7 @@ var typeExtractionRule = {
|
|
|
11223
11399
|
},
|
|
11224
11400
|
create(context) {
|
|
11225
11401
|
const sourceRoot = sourceRootOf(context);
|
|
11226
|
-
const file =
|
|
11402
|
+
const file = path78.resolve(context.filename);
|
|
11227
11403
|
const segments = segmentsOf(file, sourceRoot);
|
|
11228
11404
|
if (segments.length === 0) return {};
|
|
11229
11405
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -11364,7 +11540,7 @@ var uiStateRule = {
|
|
|
11364
11540
|
// eslint/rules/unknown-utility.ts
|
|
11365
11541
|
import { existsSync as existsSync12, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
|
|
11366
11542
|
import { createRequire } from "module";
|
|
11367
|
-
import
|
|
11543
|
+
import path79 from "path";
|
|
11368
11544
|
var PREFIX_NAMESPACES = {
|
|
11369
11545
|
bg: ["color"],
|
|
11370
11546
|
text: ["color", "text"],
|
|
@@ -11604,7 +11780,7 @@ function stylesheetFiles(dir) {
|
|
|
11604
11780
|
}
|
|
11605
11781
|
return entries.flatMap((entry) => {
|
|
11606
11782
|
if (entry.startsWith(".") || entry === "node_modules") return [];
|
|
11607
|
-
const entryPath =
|
|
11783
|
+
const entryPath = path79.join(dir, entry);
|
|
11608
11784
|
let stats;
|
|
11609
11785
|
try {
|
|
11610
11786
|
stats = statSync6(entryPath);
|
|
@@ -11612,7 +11788,7 @@ function stylesheetFiles(dir) {
|
|
|
11612
11788
|
return [];
|
|
11613
11789
|
}
|
|
11614
11790
|
if (stats.isDirectory()) return stylesheetFiles(entryPath);
|
|
11615
|
-
return
|
|
11791
|
+
return path79.extname(entry) === ".css" ? [entryPath] : [];
|
|
11616
11792
|
});
|
|
11617
11793
|
}
|
|
11618
11794
|
function packageNameOf(specifier) {
|
|
@@ -11623,10 +11799,10 @@ function packageNameOf(specifier) {
|
|
|
11623
11799
|
function resolvePackageStylesheet(fromFile, specifier) {
|
|
11624
11800
|
const packageName = packageNameOf(specifier);
|
|
11625
11801
|
if (!packageName || packageName === "tailwindcss") return void 0;
|
|
11626
|
-
let directory =
|
|
11627
|
-
while (directory !==
|
|
11628
|
-
const packageRoot =
|
|
11629
|
-
const manifestPath =
|
|
11802
|
+
let directory = path79.dirname(fromFile);
|
|
11803
|
+
while (directory !== path79.dirname(directory)) {
|
|
11804
|
+
const packageRoot = path79.join(directory, "node_modules", packageName);
|
|
11805
|
+
const manifestPath = path79.join(packageRoot, "package.json");
|
|
11630
11806
|
if (existsSync12(manifestPath)) {
|
|
11631
11807
|
try {
|
|
11632
11808
|
const manifest = readFileSync15(manifestPath, "utf8");
|
|
@@ -11634,13 +11810,13 @@ function resolvePackageStylesheet(fromFile, specifier) {
|
|
|
11634
11810
|
const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
|
|
11635
11811
|
const target = stylesheet ?? main;
|
|
11636
11812
|
if (!target) return void 0;
|
|
11637
|
-
const resolved =
|
|
11813
|
+
const resolved = path79.resolve(packageRoot, target);
|
|
11638
11814
|
return existsSync12(resolved) ? resolved : void 0;
|
|
11639
11815
|
} catch {
|
|
11640
11816
|
return void 0;
|
|
11641
11817
|
}
|
|
11642
11818
|
}
|
|
11643
|
-
directory =
|
|
11819
|
+
directory = path79.dirname(directory);
|
|
11644
11820
|
}
|
|
11645
11821
|
return void 0;
|
|
11646
11822
|
}
|
|
@@ -11895,7 +12071,7 @@ var unknownUtilityRule = {
|
|
|
11895
12071
|
};
|
|
11896
12072
|
|
|
11897
12073
|
// eslint/rules/util-file-name.ts
|
|
11898
|
-
import
|
|
12074
|
+
import path80 from "path";
|
|
11899
12075
|
function toKebabCase2(value) {
|
|
11900
12076
|
return value.replace(/(?<lower>[a-z0-9])(?<upper>[A-Z])/g, "$<lower>-$<upper>").replace(/(?<first>[A-Z])(?<rest>[A-Z][a-z])/g, "$<first>-$<rest>").toLowerCase();
|
|
11901
12077
|
}
|
|
@@ -11908,7 +12084,7 @@ var utilFileNameRule = {
|
|
|
11908
12084
|
}
|
|
11909
12085
|
},
|
|
11910
12086
|
create(context) {
|
|
11911
|
-
const filename =
|
|
12087
|
+
const filename = path80.resolve(context.filename);
|
|
11912
12088
|
const segments = filename.replace(/\\/g, "/").split("/");
|
|
11913
12089
|
if (!segments.includes("utils")) return {};
|
|
11914
12090
|
let module;
|
|
@@ -11922,13 +12098,13 @@ var utilFileNameRule = {
|
|
|
11922
12098
|
const functionName = functions[0]?.name;
|
|
11923
12099
|
if (!functionName) return {};
|
|
11924
12100
|
const expected = toKebabCase2(functionName);
|
|
11925
|
-
const actual =
|
|
12101
|
+
const actual = path80.basename(filename, path80.extname(filename));
|
|
11926
12102
|
if (!expected || actual === expected) return {};
|
|
11927
12103
|
return {
|
|
11928
12104
|
Program(node) {
|
|
11929
12105
|
context.report({
|
|
11930
12106
|
node,
|
|
11931
|
-
message: `A utility file exporting ${functionName} must be named ${expected}.${
|
|
12107
|
+
message: `A utility file exporting ${functionName} must be named ${expected}.${path80.extname(filename).slice(1)}.`
|
|
11932
12108
|
});
|
|
11933
12109
|
}
|
|
11934
12110
|
};
|
|
@@ -11936,7 +12112,7 @@ var utilFileNameRule = {
|
|
|
11936
12112
|
};
|
|
11937
12113
|
|
|
11938
12114
|
// eslint/rules/value-extraction.ts
|
|
11939
|
-
import
|
|
12115
|
+
import path81 from "path";
|
|
11940
12116
|
var valueExtractionRule = {
|
|
11941
12117
|
meta: {
|
|
11942
12118
|
schema: [],
|
|
@@ -11947,7 +12123,7 @@ var valueExtractionRule = {
|
|
|
11947
12123
|
},
|
|
11948
12124
|
create(context) {
|
|
11949
12125
|
const sourceRoot = sourceRootOf(context);
|
|
11950
|
-
const file =
|
|
12126
|
+
const file = path81.resolve(context.filename);
|
|
11951
12127
|
const segments = segmentsOf(file, sourceRoot);
|
|
11952
12128
|
if (segments.length === 0 || segments[0] !== "app") return {};
|
|
11953
12129
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -11969,7 +12145,7 @@ var valueExtractionRule = {
|
|
|
11969
12145
|
|
|
11970
12146
|
// eslint/rules/vulyk/tracked-docs.ts
|
|
11971
12147
|
import { existsSync as existsSync13, readFileSync as readFileSync16 } from "fs";
|
|
11972
|
-
import
|
|
12148
|
+
import path82 from "path";
|
|
11973
12149
|
var PASIKA_REPO = "Bredansky/pasika";
|
|
11974
12150
|
var BASE_REQUIRED_TRACKED_DOCS = [
|
|
11975
12151
|
{ name: "documentation-guide", path: "docs/documentation-guide" },
|
|
@@ -12002,8 +12178,8 @@ var trackedDocsRule = {
|
|
|
12002
12178
|
if (!context.filename.endsWith("package.json")) return;
|
|
12003
12179
|
const root = node.body;
|
|
12004
12180
|
if (root.type !== "Object") return;
|
|
12005
|
-
const projectRoot =
|
|
12006
|
-
const configPath =
|
|
12181
|
+
const projectRoot = path82.dirname(path82.resolve(context.filename));
|
|
12182
|
+
const configPath = path82.join(projectRoot, "vulyk.config.ts");
|
|
12007
12183
|
if (!existsSync13(configPath)) {
|
|
12008
12184
|
context.report({
|
|
12009
12185
|
node,
|
|
@@ -12028,7 +12204,7 @@ var trackedDocsRule = {
|
|
|
12028
12204
|
});
|
|
12029
12205
|
}
|
|
12030
12206
|
}
|
|
12031
|
-
const agentsPath =
|
|
12207
|
+
const agentsPath = path82.join(projectRoot, "AGENTS.md");
|
|
12032
12208
|
if (!existsSync13(agentsPath)) {
|
|
12033
12209
|
context.report({
|
|
12034
12210
|
node,
|
|
@@ -12128,7 +12304,7 @@ var withResponseHelperRule = {
|
|
|
12128
12304
|
|
|
12129
12305
|
// eslint/rules/zirka-baseline.ts
|
|
12130
12306
|
import fs7 from "fs";
|
|
12131
|
-
import
|
|
12307
|
+
import path83 from "path";
|
|
12132
12308
|
var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
|
|
12133
12309
|
var PRETTIER_CONFIGS = [
|
|
12134
12310
|
"prettier.config.mjs",
|
|
@@ -12147,10 +12323,10 @@ var zirkaBaselineRule = {
|
|
|
12147
12323
|
}
|
|
12148
12324
|
},
|
|
12149
12325
|
create(context) {
|
|
12150
|
-
const filename =
|
|
12151
|
-
const basename =
|
|
12326
|
+
const filename = path83.resolve(context.filename);
|
|
12327
|
+
const basename = path83.basename(filename);
|
|
12152
12328
|
if (!ESLINT_CONFIG.test(basename)) return {};
|
|
12153
|
-
const projectRoot =
|
|
12329
|
+
const projectRoot = path83.dirname(filename);
|
|
12154
12330
|
const report3 = (message) => {
|
|
12155
12331
|
context.report({
|
|
12156
12332
|
node: context.sourceCode.ast,
|
|
@@ -12165,7 +12341,7 @@ var zirkaBaselineRule = {
|
|
|
12165
12341
|
'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
|
|
12166
12342
|
);
|
|
12167
12343
|
}
|
|
12168
|
-
const tsconfigPath =
|
|
12344
|
+
const tsconfigPath = path83.join(projectRoot, "tsconfig.json");
|
|
12169
12345
|
if (!fs7.existsSync(tsconfigPath)) {
|
|
12170
12346
|
report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
|
|
12171
12347
|
} else {
|
|
@@ -12183,13 +12359,13 @@ var zirkaBaselineRule = {
|
|
|
12183
12359
|
report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
|
|
12184
12360
|
}
|
|
12185
12361
|
}
|
|
12186
|
-
const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(
|
|
12362
|
+
const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path83.join(projectRoot, name)));
|
|
12187
12363
|
if (!prettierConfigFile) {
|
|
12188
12364
|
report3(
|
|
12189
12365
|
"No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
|
|
12190
12366
|
);
|
|
12191
12367
|
} else {
|
|
12192
|
-
const content = fs7.readFileSync(
|
|
12368
|
+
const content = fs7.readFileSync(path83.join(projectRoot, prettierConfigFile), "utf8");
|
|
12193
12369
|
if (!content.includes("zirka")) {
|
|
12194
12370
|
report3(
|
|
12195
12371
|
"The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
|
|
@@ -12525,7 +12701,7 @@ var tailwindStructureRules = {
|
|
|
12525
12701
|
languageOptions: { tolerant: true },
|
|
12526
12702
|
rules: Object.fromEntries(
|
|
12527
12703
|
tailwindRuleIds.filter(
|
|
12528
|
-
(id) => id !== "pasika/css-entry-point" && id !== "pasika/feature-css-placement" && id !== "pasika/unique-css-definition" && id !== "pasika/no-utility-alias" && id !== "pasika/root-variables" && id !== "pasika/color-role-usage"
|
|
12704
|
+
(id) => id !== "pasika/css-entry-point" && id !== "pasika/feature-css-placement" && id !== "pasika/unique-css-definition" && id !== "pasika/utility-mapping" && id !== "pasika/no-utility-alias" && id !== "pasika/root-variables" && id !== "pasika/color-role-usage"
|
|
12529
12705
|
).map((id) => [id, "error"])
|
|
12530
12706
|
)
|
|
12531
12707
|
};
|
|
@@ -12541,6 +12717,8 @@ var tailwindImportGraph = {
|
|
|
12541
12717
|
"pasika/css-entry-point": "error",
|
|
12542
12718
|
"pasika/feature-css-placement": "error",
|
|
12543
12719
|
"pasika/unique-css-definition": "error",
|
|
12720
|
+
"pasika/unique-css-token-value": "error",
|
|
12721
|
+
"pasika/utility-mapping": "error",
|
|
12544
12722
|
"pasika/no-utility-alias": "error",
|
|
12545
12723
|
"pasika/root-variables": "error",
|
|
12546
12724
|
"pasika/color-role-usage": "error"
|