pasika 0.10.130 → 0.10.132
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 +310 -120
- package/package.json +1 -1
|
@@ -121,6 +121,7 @@ declare const nextjsPackageJsonRules: {
|
|
|
121
121
|
|
|
122
122
|
declare const tailwindRules: {
|
|
123
123
|
"theme-reset": _eslint_css.CSSRuleDefinition;
|
|
124
|
+
"theme-mode": _eslint_css.CSSRuleDefinition;
|
|
124
125
|
"color-role-usage": _eslint_css.CSSRuleDefinition;
|
|
125
126
|
"root-variables": _eslint_css.CSSRuleDefinition;
|
|
126
127
|
"apply-usage": _eslint_css.CSSRuleDefinition;
|
|
@@ -161,6 +162,7 @@ declare const pasikaPlugin: {
|
|
|
161
162
|
"lint-setup": _eslint_json.JSONRuleDefinition;
|
|
162
163
|
"vitest-coverage": _eslint_json.JSONRuleDefinition;
|
|
163
164
|
"theme-reset": _eslint_css.CSSRuleDefinition;
|
|
165
|
+
"theme-mode": _eslint_css.CSSRuleDefinition;
|
|
164
166
|
"color-role-usage": _eslint_css.CSSRuleDefinition;
|
|
165
167
|
"root-variables": _eslint_css.CSSRuleDefinition;
|
|
166
168
|
"apply-usage": _eslint_css.CSSRuleDefinition;
|
|
@@ -2866,6 +2866,16 @@ var rulePairedExamplesRule = {
|
|
|
2866
2866
|
node,
|
|
2867
2867
|
message: `${String(incorrect.length)} Incorrect and ${String(correct.length)} Correct examples`
|
|
2868
2868
|
});
|
|
2869
|
+
} else {
|
|
2870
|
+
const misplaced = exampleHeadings.find(
|
|
2871
|
+
(heading, index) => !heading.text.startsWith(index % 2 === 0 ? "Incorrect" : "Correct")
|
|
2872
|
+
);
|
|
2873
|
+
if (misplaced) {
|
|
2874
|
+
context.report({
|
|
2875
|
+
node,
|
|
2876
|
+
message: `Rule examples must alternate Incorrect then Correct; found "${misplaced.text}" at line ${String(misplaced.line)}.`
|
|
2877
|
+
});
|
|
2878
|
+
}
|
|
2869
2879
|
}
|
|
2870
2880
|
}
|
|
2871
2881
|
};
|
|
@@ -10829,19 +10839,16 @@ var rootVariablesRule = {
|
|
|
10829
10839
|
return;
|
|
10830
10840
|
}
|
|
10831
10841
|
const isConditional = conditional || currentNode.type === "Atrule" && currentNode.name !== "layer";
|
|
10832
|
-
|
|
10833
|
-
|
|
10834
|
-
const
|
|
10835
|
-
|
|
10836
|
-
|
|
10837
|
-
|
|
10838
|
-
|
|
10839
|
-
|
|
10840
|
-
|
|
10841
|
-
|
|
10842
|
-
message: `Tailwind token "${declaration.property}" must not be redeclared outside @theme; map it through @theme inline to its same-named runtime variable instead.`
|
|
10843
|
-
});
|
|
10844
|
-
}
|
|
10842
|
+
const isDefaultRoot = currentNode.type === "Rule" && context.sourceCode.getText(currentNode.prelude).trim() === ":root" && !isConditional;
|
|
10843
|
+
if (currentNode.type === "Rule" && !isDefaultRoot || currentNode.type === "Atrule" && currentNode.name === "variant") {
|
|
10844
|
+
for (const declaration of blockChildren2(currentNode)) {
|
|
10845
|
+
if (declaration.type !== "Declaration") continue;
|
|
10846
|
+
if (mirroredTokens.has(declaration.property)) continue;
|
|
10847
|
+
if (!names.has(declaration.property) && !declaration.property.startsWith("--color-")) continue;
|
|
10848
|
+
context.report({
|
|
10849
|
+
node: declaration,
|
|
10850
|
+
message: `Tailwind token "${declaration.property}" must not be redeclared outside @theme; map it through @theme inline to its same-named runtime variable instead.`
|
|
10851
|
+
});
|
|
10845
10852
|
}
|
|
10846
10853
|
}
|
|
10847
10854
|
const children = currentNode.type === "StyleSheet" ? currentNode.children : blockChildren2(currentNode);
|
|
@@ -10869,7 +10876,27 @@ var rootVariablesRule = {
|
|
|
10869
10876
|
|
|
10870
10877
|
// eslint/rules/tailwind/stylesheet-ordering.ts
|
|
10871
10878
|
import path73 from "path";
|
|
10879
|
+
import { generate as generate4 } from "@eslint/css-tree";
|
|
10872
10880
|
var SECTION_ORDER = ["imports", "custom-variant", "root", "theme", "utility", "base styles", "keyframes"];
|
|
10881
|
+
var LATE_RESET_ERROR = "The global --*: initial theme reset must precede feature stylesheet imports, or it will erase their theme tokens.";
|
|
10882
|
+
function themeBody(node, source) {
|
|
10883
|
+
if (node.type !== "Atrule" || node.name !== "theme" || !node.loc) return void 0;
|
|
10884
|
+
const raw = source.slice(node.loc.start.offset, node.loc.end.offset);
|
|
10885
|
+
const start = raw.indexOf("{");
|
|
10886
|
+
const end = raw.lastIndexOf("}");
|
|
10887
|
+
if (start < 0 || end <= start) return void 0;
|
|
10888
|
+
return raw.slice(start + 1, end).replace(/\/\*[\s\S]*?\*\//gu, "").trim();
|
|
10889
|
+
}
|
|
10890
|
+
function containsThemeReset(body) {
|
|
10891
|
+
return body !== void 0 && /(?:^|[;{])\s*--\*\s*:\s*initial\s*(?:;|$)/u.test(body);
|
|
10892
|
+
}
|
|
10893
|
+
function isStandaloneThemeReset(body) {
|
|
10894
|
+
return body !== void 0 && /^--\*\s*:\s*initial\s*;?$/u.test(body);
|
|
10895
|
+
}
|
|
10896
|
+
function isTailwindImport(node) {
|
|
10897
|
+
if (node.type !== "Atrule" || node.name !== "import" || !node.prelude) return false;
|
|
10898
|
+
return /^["']tailwindcss["'](?:\s|$)/u.test(generate4(node.prelude).trim());
|
|
10899
|
+
}
|
|
10873
10900
|
function scopesCustomProperties(node) {
|
|
10874
10901
|
if (node.type === "Declaration") return node.property.startsWith("--");
|
|
10875
10902
|
if (node.type === "Atrule" && !["media", "supports", "container"].includes(node.name)) return false;
|
|
@@ -10892,9 +10919,24 @@ var stylesheetOrderingRule = {
|
|
|
10892
10919
|
"StyleSheet:exit"(node) {
|
|
10893
10920
|
const sections = [];
|
|
10894
10921
|
let index = 0;
|
|
10922
|
+
let sawTailwindImport = false;
|
|
10923
|
+
let sawFeatureImport = false;
|
|
10924
|
+
let sawNonImport = false;
|
|
10925
|
+
let sawEarlyReset = false;
|
|
10895
10926
|
for (const child of node.children) {
|
|
10927
|
+
const body = themeBody(child, context.sourceCode.text);
|
|
10928
|
+
let isEarlyReset = false;
|
|
10929
|
+
if (containsThemeReset(body) && sawFeatureImport) {
|
|
10930
|
+
context.report({ node: child, message: LATE_RESET_ERROR });
|
|
10931
|
+
return;
|
|
10932
|
+
}
|
|
10896
10933
|
if (child.type === "Atrule" && child.name === "import") {
|
|
10897
10934
|
sections.push({ name: "imports", at: index });
|
|
10935
|
+
if (isTailwindImport(child)) sawTailwindImport = true;
|
|
10936
|
+
else sawFeatureImport = true;
|
|
10937
|
+
} else if (isStandaloneThemeReset(body) && sawTailwindImport && !sawFeatureImport && !sawNonImport && !sawEarlyReset) {
|
|
10938
|
+
sawEarlyReset = true;
|
|
10939
|
+
isEarlyReset = true;
|
|
10898
10940
|
} else if (child.type === "Atrule" && child.name === "custom-variant") {
|
|
10899
10941
|
sections.push({ name: "custom-variant", at: index });
|
|
10900
10942
|
} else if (child.type === "Atrule" && child.name === "theme") {
|
|
@@ -10912,6 +10954,9 @@ var stylesheetOrderingRule = {
|
|
|
10912
10954
|
} else if (child.type === "Atrule" && scopesCustomProperties(child)) {
|
|
10913
10955
|
sections.push({ name: "root", at: index });
|
|
10914
10956
|
}
|
|
10957
|
+
if (child.type !== "Comment" && !(child.type === "Atrule" && child.name === "import") && !isEarlyReset) {
|
|
10958
|
+
sawNonImport = true;
|
|
10959
|
+
}
|
|
10915
10960
|
index += 1;
|
|
10916
10961
|
}
|
|
10917
10962
|
const firstAt = /* @__PURE__ */ new Map();
|
|
@@ -10952,14 +10997,135 @@ var stylesheetOrderingRule = {
|
|
|
10952
10997
|
}
|
|
10953
10998
|
};
|
|
10954
10999
|
|
|
10955
|
-
// eslint/rules/tailwind/theme-
|
|
10956
|
-
import { existsSync as existsSync12 } from "fs";
|
|
11000
|
+
// eslint/rules/tailwind/theme-mode.ts
|
|
10957
11001
|
import path74 from "path";
|
|
10958
|
-
import { generate as
|
|
11002
|
+
import { generate as generate5 } from "@eslint/css-tree";
|
|
11003
|
+
var MODE_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
11004
|
+
var MODE_REFERENCE = /(?:^|[^a-z0-9-])(?<name>[a-z][a-z0-9]*(?:-[a-z0-9]+)*):(?=[a-z[(])/gu;
|
|
11005
|
+
var MODE_ATTRIBUTE = /data-theme\s*=\s*["'](?<name>[a-z][a-z0-9]*(?:-[a-z0-9]+)*)["']/gu;
|
|
11006
|
+
var CUSTOM_REGISTRATION = /@custom-variant\s+(?<name>[a-z][a-z0-9-]*)\b(?<selector>[^;]*);/gu;
|
|
11007
|
+
var MODE_SELECTOR = /\[\s*data-theme\s*=\s*["']?(?<mode>[a-z][a-z0-9-]*)["']?\s*\]/u;
|
|
11008
|
+
var SELECTOR_OVERRIDE = "Use a data-theme @custom-variant for mode-specific styles; direct [data-theme] selectors are not allowed.";
|
|
11009
|
+
var CLASS_OVERRIDE = "Use the data-theme @custom-variant instead of a .dark CSS selector.";
|
|
11010
|
+
var SYSTEM_OVERRIDE = "Use data-theme with @custom-variant for mode styling; resolve system preferences in application code, not a prefers-color-scheme CSS media query.";
|
|
11011
|
+
var MODE_LOCATION = "Declare appearance-mode @custom-variant definitions in globals.css only.";
|
|
11012
|
+
var MISSING_CSS_VARIANT = (name) => `CSS @variant "${name}" requires a matching @custom-variant declaration in globals.css.`;
|
|
11013
|
+
function variantName(prelude) {
|
|
11014
|
+
return /^(?<name>[a-z][a-z0-9-]*)\b/u.exec(prelude.trim())?.groups?.name;
|
|
11015
|
+
}
|
|
11016
|
+
function isModeVariant(name, prelude) {
|
|
11017
|
+
return name === "dark" || name.startsWith("theme-") || /\[\s*data-theme\b/u.test(prelude);
|
|
11018
|
+
}
|
|
11019
|
+
function canonicalModePrelude(name, source) {
|
|
11020
|
+
if (!MODE_NAME.test(name)) return false;
|
|
11021
|
+
const normalized = source.replace(/\/\*[\s\S]*?\*\//gu, "").replace(/["']/gu, "").replace(/\s+/gu, "");
|
|
11022
|
+
return normalized === `${name}(&:where([data-theme=${name}],[data-theme=${name}]*))`;
|
|
11023
|
+
}
|
|
11024
|
+
function registeredModes(source) {
|
|
11025
|
+
const result = /* @__PURE__ */ new Set();
|
|
11026
|
+
for (const match of source.replace(/\/\*[\s\S]*?\*\//gu, "").matchAll(CUSTOM_REGISTRATION)) {
|
|
11027
|
+
const name = match.groups?.name;
|
|
11028
|
+
if (name && isModeVariant(name, `${name}${match.groups?.selector ?? ""}`)) result.add(name);
|
|
11029
|
+
}
|
|
11030
|
+
return result;
|
|
11031
|
+
}
|
|
11032
|
+
var themeModeRule = {
|
|
11033
|
+
meta: {
|
|
11034
|
+
schema: [],
|
|
11035
|
+
type: "problem",
|
|
11036
|
+
docs: { description: "Require a single data-theme/@custom-variant strategy for appearance modes." }
|
|
11037
|
+
},
|
|
11038
|
+
create(context) {
|
|
11039
|
+
const sourceRoot = sourceRootOf(context);
|
|
11040
|
+
const current = path74.normalize(path74.resolve(context.filename));
|
|
11041
|
+
const globalFile = path74.normalize(path74.join(sourceRoot, "app", "styles", "globals.css"));
|
|
11042
|
+
if (path74.dirname(current) !== path74.dirname(globalFile)) return {};
|
|
11043
|
+
const read = cachedTextReader();
|
|
11044
|
+
return {
|
|
11045
|
+
"StyleSheet:exit"(node) {
|
|
11046
|
+
const registered = /* @__PURE__ */ new Set();
|
|
11047
|
+
for (const variant of atrulesNamed(node, "custom-variant")) {
|
|
11048
|
+
if (variant.type !== "Atrule") continue;
|
|
11049
|
+
const prelude = variant.prelude ? generate5(variant.prelude) : "";
|
|
11050
|
+
const name = variantName(prelude);
|
|
11051
|
+
if (!name) continue;
|
|
11052
|
+
if (!isModeVariant(name, prelude)) continue;
|
|
11053
|
+
if (current !== globalFile) {
|
|
11054
|
+
context.report({ node: variant, message: MODE_LOCATION });
|
|
11055
|
+
continue;
|
|
11056
|
+
}
|
|
11057
|
+
if (!canonicalModePrelude(name, prelude)) {
|
|
11058
|
+
const selected = MODE_SELECTOR.exec(prelude)?.groups?.mode;
|
|
11059
|
+
context.report({
|
|
11060
|
+
node: variant,
|
|
11061
|
+
message: selected && selected !== name ? `Theme variant "${name}" must be named "${selected}" to match its data-theme selector.` : `Theme variant "${name}" must match both [data-theme="${name}"] and its descendants with &:where(...).`
|
|
11062
|
+
});
|
|
11063
|
+
}
|
|
11064
|
+
if (registered.has(name)) {
|
|
11065
|
+
context.report({ node: variant, message: `Theme variant "${name}" is already defined in globals.css.` });
|
|
11066
|
+
}
|
|
11067
|
+
registered.add(name);
|
|
11068
|
+
}
|
|
11069
|
+
const modeHints = /* @__PURE__ */ new Set();
|
|
11070
|
+
for (const file of findFiles(sourceRoot, MODULE_EXTENSIONS4)) {
|
|
11071
|
+
for (const match of read(file).matchAll(MODE_ATTRIBUTE)) {
|
|
11072
|
+
if (match.groups?.name) modeHints.add(match.groups.name);
|
|
11073
|
+
}
|
|
11074
|
+
}
|
|
11075
|
+
const globalRegistrations = current === globalFile ? registered : registeredModes(read(globalFile));
|
|
11076
|
+
for (const variant of atrulesNamed(node, "variant")) {
|
|
11077
|
+
if (variant.type !== "Atrule" || !variant.prelude) continue;
|
|
11078
|
+
const name = variantName(generate5(variant.prelude));
|
|
11079
|
+
if (name && (name === "dark" || name.startsWith("theme-") || globalRegistrations.has(name) || modeHints.has(name)) && !globalRegistrations.has(name)) {
|
|
11080
|
+
context.report({ node: variant, message: MISSING_CSS_VARIANT(name) });
|
|
11081
|
+
}
|
|
11082
|
+
}
|
|
11083
|
+
for (const rule of rules(node)) {
|
|
11084
|
+
if (rule.type !== "Rule") continue;
|
|
11085
|
+
const selector = generate5(rule.prelude);
|
|
11086
|
+
if (/\[\s*data-theme(?:\s*[~|^$*]?=|\s*\])/u.test(selector)) {
|
|
11087
|
+
context.report({ node: rule, message: SELECTOR_OVERRIDE });
|
|
11088
|
+
} else if (/\.dark(?![\w-])/u.test(selector)) {
|
|
11089
|
+
context.report({ node: rule, message: CLASS_OVERRIDE });
|
|
11090
|
+
}
|
|
11091
|
+
}
|
|
11092
|
+
walkNodes(node, (child) => {
|
|
11093
|
+
if (child.type !== "Atrule" || child.name !== "media" || !child.prelude) return;
|
|
11094
|
+
if (/\bprefers-color-scheme\b/u.test(generate5(child.prelude))) {
|
|
11095
|
+
context.report({ node: child, message: SYSTEM_OVERRIDE });
|
|
11096
|
+
}
|
|
11097
|
+
});
|
|
11098
|
+
if (current !== globalFile) return;
|
|
11099
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
11100
|
+
for (const file of findFiles(sourceRoot, MODULE_EXTENSIONS4)) {
|
|
11101
|
+
for (const match of read(file).matchAll(MODE_REFERENCE)) {
|
|
11102
|
+
const name = match.groups?.name;
|
|
11103
|
+
if (!name) continue;
|
|
11104
|
+
if (name === "dark" || name.startsWith("theme-") || registered.has(name) || modeHints.has(name)) {
|
|
11105
|
+
referenced.add(name);
|
|
11106
|
+
}
|
|
11107
|
+
}
|
|
11108
|
+
}
|
|
11109
|
+
for (const name of referenced) {
|
|
11110
|
+
if (!registered.has(name)) {
|
|
11111
|
+
context.report({
|
|
11112
|
+
node,
|
|
11113
|
+
message: `Theme utility prefix "${name}:" requires a matching @custom-variant in globals.css; Tailwind's default media-based dark mode is not allowed.`
|
|
11114
|
+
});
|
|
11115
|
+
}
|
|
11116
|
+
}
|
|
11117
|
+
}
|
|
11118
|
+
};
|
|
11119
|
+
}
|
|
11120
|
+
};
|
|
11121
|
+
|
|
11122
|
+
// eslint/rules/tailwind/theme-reset.ts
|
|
11123
|
+
import path75 from "path";
|
|
11124
|
+
import { generate as generate6 } from "@eslint/css-tree";
|
|
10959
11125
|
function isThemeReset(node) {
|
|
10960
11126
|
if (!node) return false;
|
|
10961
|
-
if (node.type === "Declaration") return node.property === "--*" &&
|
|
10962
|
-
if (node.type === "Raw") return
|
|
11127
|
+
if (node.type === "Declaration") return node.property === "--*" && generate6(node.value).trim() === "initial";
|
|
11128
|
+
if (node.type === "Raw") return /(?:^|[;{])\s*--\*\s*:\s*initial\s*(?:;|$)/u.test(node.value);
|
|
10963
11129
|
return false;
|
|
10964
11130
|
}
|
|
10965
11131
|
function hasThemeReset(node) {
|
|
@@ -10977,46 +11143,39 @@ var themeResetRule = {
|
|
|
10977
11143
|
schema: [],
|
|
10978
11144
|
type: "problem",
|
|
10979
11145
|
docs: {
|
|
10980
|
-
description: "Require the
|
|
11146
|
+
description: "Require the default-theme reset in globals.css, never in feature stylesheets."
|
|
10981
11147
|
}
|
|
10982
11148
|
},
|
|
10983
11149
|
create(context) {
|
|
10984
11150
|
const sourceRoot = sourceRootOf(context);
|
|
10985
|
-
const current =
|
|
10986
|
-
const entryPoint =
|
|
10987
|
-
if (current !== entryPoint) return {};
|
|
11151
|
+
const current = path75.normalize(path75.resolve(context.filename));
|
|
11152
|
+
const entryPoint = path75.normalize(path75.join(sourceRoot, "app", "styles", "globals.css"));
|
|
11153
|
+
if (path75.dirname(current) !== path75.dirname(entryPoint)) return {};
|
|
10988
11154
|
return {
|
|
10989
11155
|
"StyleSheet:exit"(node) {
|
|
10990
|
-
|
|
10991
|
-
|
|
10992
|
-
|
|
10993
|
-
|
|
10994
|
-
|
|
10995
|
-
|
|
10996
|
-
|
|
10997
|
-
for (const specifier of importedSpecifiers(from.source)) {
|
|
10998
|
-
const target = resolveSpecifier2(from.file, specifier, sourceRoot);
|
|
10999
|
-
if (!target || path74.extname(target) !== ".css") continue;
|
|
11000
|
-
const filename = path74.normalize(target);
|
|
11001
|
-
if (seen.has(filename) || !existsSync12(filename)) continue;
|
|
11002
|
-
seen.add(filename);
|
|
11003
|
-
const source = textOf(filename);
|
|
11004
|
-
const parsed = toPlainObject2(parse7(source, { parseAtrulePrelude: false }));
|
|
11005
|
-
if (parsed.type === "StyleSheet" && hasThemeReset(parsed)) return;
|
|
11006
|
-
queue.push({ file: filename, source });
|
|
11156
|
+
const hasReset = hasThemeReset(node);
|
|
11157
|
+
if (current !== entryPoint) {
|
|
11158
|
+
if (hasReset) {
|
|
11159
|
+
context.report({
|
|
11160
|
+
node,
|
|
11161
|
+
message: "Only globals.css may reset Tailwind's default theme with --*: initial; remove it from feature stylesheets."
|
|
11162
|
+
});
|
|
11007
11163
|
}
|
|
11164
|
+
return;
|
|
11165
|
+
}
|
|
11166
|
+
if (!hasReset) {
|
|
11167
|
+
context.report({
|
|
11168
|
+
node,
|
|
11169
|
+
message: "globals.css must reset Tailwind's default theme with --*: initial inside @theme or @theme inline."
|
|
11170
|
+
});
|
|
11008
11171
|
}
|
|
11009
|
-
context.report({
|
|
11010
|
-
node,
|
|
11011
|
-
message: "The global stylesheet must reset Tailwind's default theme with --*: initial inside an @theme block."
|
|
11012
|
-
});
|
|
11013
11172
|
}
|
|
11014
11173
|
};
|
|
11015
11174
|
}
|
|
11016
11175
|
};
|
|
11017
11176
|
|
|
11018
11177
|
// eslint/rules/tailwind/unique-css-definition.ts
|
|
11019
|
-
import
|
|
11178
|
+
import path76 from "path";
|
|
11020
11179
|
function ownershipKey(symbol) {
|
|
11021
11180
|
if (symbol.kind === "selector") return void 0;
|
|
11022
11181
|
if (symbol.kind === "root-variable" && symbol.scope !== "default") return void 0;
|
|
@@ -11048,7 +11207,7 @@ var uniqueCssDefinitionRule = {
|
|
|
11048
11207
|
},
|
|
11049
11208
|
create(context) {
|
|
11050
11209
|
const sourceRoot = sourceRootOf(context);
|
|
11051
|
-
const current =
|
|
11210
|
+
const current = path76.normalize(path76.resolve(context.filename));
|
|
11052
11211
|
const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
11053
11212
|
if (cssFiles.length === 0) return {};
|
|
11054
11213
|
const textOf = cachedTextReader();
|
|
@@ -11056,7 +11215,7 @@ var uniqueCssDefinitionRule = {
|
|
|
11056
11215
|
sourceRoot,
|
|
11057
11216
|
css: cssFiles.map((file) => ({
|
|
11058
11217
|
path: file,
|
|
11059
|
-
content:
|
|
11218
|
+
content: path76.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11060
11219
|
})),
|
|
11061
11220
|
modules: [],
|
|
11062
11221
|
includeReferences: false
|
|
@@ -11078,7 +11237,7 @@ var uniqueCssDefinitionRule = {
|
|
|
11078
11237
|
if (!canonical) continue;
|
|
11079
11238
|
for (const symbol of definitions.slice(1)) {
|
|
11080
11239
|
if (symbol.file !== current) continue;
|
|
11081
|
-
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 ${
|
|
11240
|
+
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 ${path76.relative(sourceRoot, canonical.file)}; define it in only one CSS file.`;
|
|
11082
11241
|
context.report({
|
|
11083
11242
|
node,
|
|
11084
11243
|
loc: {
|
|
@@ -11095,7 +11254,7 @@ var uniqueCssDefinitionRule = {
|
|
|
11095
11254
|
};
|
|
11096
11255
|
|
|
11097
11256
|
// eslint/rules/tailwind/unique-css-token-value.ts
|
|
11098
|
-
import
|
|
11257
|
+
import path77 from "path";
|
|
11099
11258
|
function valueIdentity(value) {
|
|
11100
11259
|
const text = value.trim();
|
|
11101
11260
|
const hex = /^#(?<digits>[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/iu.exec(text)?.groups?.digits;
|
|
@@ -11123,14 +11282,14 @@ var uniqueCssTokenValueRule = {
|
|
|
11123
11282
|
},
|
|
11124
11283
|
create(context) {
|
|
11125
11284
|
const sourceRoot = sourceRootOf(context);
|
|
11126
|
-
const current =
|
|
11285
|
+
const current = path77.normalize(path77.resolve(context.filename));
|
|
11127
11286
|
const textOf = cachedTextReader();
|
|
11128
11287
|
const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
11129
11288
|
const graph = buildCssDependencyGraph({
|
|
11130
11289
|
sourceRoot,
|
|
11131
11290
|
css: cssFiles.map((file) => ({
|
|
11132
11291
|
path: file,
|
|
11133
|
-
content:
|
|
11292
|
+
content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11134
11293
|
})),
|
|
11135
11294
|
modules: [],
|
|
11136
11295
|
includeReferences: false
|
|
@@ -11162,7 +11321,7 @@ var uniqueCssTokenValueRule = {
|
|
|
11162
11321
|
start: { line: definition.line, column: 1 },
|
|
11163
11322
|
end: { line: definition.line, column: 2 }
|
|
11164
11323
|
},
|
|
11165
|
-
message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${
|
|
11324
|
+
message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${path77.relative(
|
|
11166
11325
|
sourceRoot,
|
|
11167
11326
|
original.file
|
|
11168
11327
|
)}:${String(original.line)}; reuse one design token.`
|
|
@@ -11175,7 +11334,7 @@ var uniqueCssTokenValueRule = {
|
|
|
11175
11334
|
|
|
11176
11335
|
// eslint/rules/tailwind/unused-utility.ts
|
|
11177
11336
|
import { statSync as statSync5 } from "fs";
|
|
11178
|
-
import
|
|
11337
|
+
import path78 from "path";
|
|
11179
11338
|
var unusedUtilityRule = {
|
|
11180
11339
|
meta: {
|
|
11181
11340
|
schema: [],
|
|
@@ -11191,7 +11350,7 @@ var unusedUtilityRule = {
|
|
|
11191
11350
|
} catch {
|
|
11192
11351
|
return {};
|
|
11193
11352
|
}
|
|
11194
|
-
const current =
|
|
11353
|
+
const current = path78.normalize(path78.resolve(context.filename));
|
|
11195
11354
|
const textOf = cachedTextReader();
|
|
11196
11355
|
const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
11197
11356
|
const moduleFiles = findFiles(sourceRoot, MODULE_EXTENSIONS4);
|
|
@@ -11199,7 +11358,7 @@ var unusedUtilityRule = {
|
|
|
11199
11358
|
sourceRoot,
|
|
11200
11359
|
css: cssFiles.map((file) => ({
|
|
11201
11360
|
path: file,
|
|
11202
|
-
content:
|
|
11361
|
+
content: path78.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11203
11362
|
})),
|
|
11204
11363
|
modules: moduleFiles.map((file) => ({ path: file, content: textOf(file) }))
|
|
11205
11364
|
});
|
|
@@ -11221,8 +11380,8 @@ var unusedUtilityRule = {
|
|
|
11221
11380
|
|
|
11222
11381
|
// eslint/rules/tailwind/utility-mapping.ts
|
|
11223
11382
|
import { spawnSync } from "child_process";
|
|
11224
|
-
import { existsSync as
|
|
11225
|
-
import
|
|
11383
|
+
import { existsSync as existsSync12 } from "fs";
|
|
11384
|
+
import path79 from "path";
|
|
11226
11385
|
function applyOperationCount(utility, textOf) {
|
|
11227
11386
|
let count = 0;
|
|
11228
11387
|
for (const apply of atrulesNamed(utility, "apply")) {
|
|
@@ -11383,6 +11542,27 @@ function singleCssFunction(value) {
|
|
|
11383
11542
|
const args = value.slice(match[0].length, -1).trim();
|
|
11384
11543
|
return args ? { name, args } : void 0;
|
|
11385
11544
|
}
|
|
11545
|
+
function gradientOnlyBackground(value) {
|
|
11546
|
+
if (!value || /[;{}'"\\]/u.test(value)) return false;
|
|
11547
|
+
const layers = [];
|
|
11548
|
+
let depth = 0;
|
|
11549
|
+
let start = 0;
|
|
11550
|
+
for (let index = 0; index < value.length; index++) {
|
|
11551
|
+
if (value[index] === "(") depth++;
|
|
11552
|
+
if (value[index] === ")") depth--;
|
|
11553
|
+
if (depth < 0) return false;
|
|
11554
|
+
if (value[index] === "," && depth === 0) {
|
|
11555
|
+
layers.push(value.slice(start, index).trim());
|
|
11556
|
+
start = index + 1;
|
|
11557
|
+
}
|
|
11558
|
+
}
|
|
11559
|
+
if (depth !== 0) return false;
|
|
11560
|
+
layers.push(value.slice(start).trim());
|
|
11561
|
+
return layers.every((layer) => {
|
|
11562
|
+
const fn = singleCssFunction(layer);
|
|
11563
|
+
return fn !== void 0 && /^(?:repeating-)?(?:linear|radial|conic)-gradient$/u.test(fn.name);
|
|
11564
|
+
});
|
|
11565
|
+
}
|
|
11386
11566
|
function boxShadowNamespace(value) {
|
|
11387
11567
|
const layers = [];
|
|
11388
11568
|
let depth = 0;
|
|
@@ -11445,7 +11625,9 @@ function themeCandidate(name, utilityText) {
|
|
|
11445
11625
|
if (!cssValue) return void 0;
|
|
11446
11626
|
const namedOperation = arbitraryApply?.groups?.prefix ? arbitraryApplyOperation(arbitraryApply.groups.prefix, cssValue) : void 0;
|
|
11447
11627
|
if (arbitraryApply && !namedOperation) return void 0;
|
|
11448
|
-
const
|
|
11628
|
+
const declaredProperty = arbitrary?.groups?.property ?? direct?.groups?.property ?? namedOperation?.property;
|
|
11629
|
+
const gradientShorthand = declaredProperty === "background" && gradientOnlyBackground(cssValue);
|
|
11630
|
+
const property = gradientShorthand ? "background-image" : declaredProperty;
|
|
11449
11631
|
const functionValue = property === "filter" || property === "backdrop-filter" ? singleCssFunction(cssValue) : void 0;
|
|
11450
11632
|
const shadowNamespace = property === "box-shadow" ? boxShadowNamespace(cssValue) : void 0;
|
|
11451
11633
|
if (property === "box-shadow" && !shadowNamespace) return void 0;
|
|
@@ -11481,7 +11663,8 @@ function themeCandidate(name, utilityText) {
|
|
|
11481
11663
|
value,
|
|
11482
11664
|
prefix: matched.prefix,
|
|
11483
11665
|
namespace: matched.namespace,
|
|
11484
|
-
probe: Boolean(arbitraryApply) || matched.property === "transition-property"
|
|
11666
|
+
probe: Boolean(arbitraryApply) || matched.property === "transition-property",
|
|
11667
|
+
gradientShorthand
|
|
11485
11668
|
};
|
|
11486
11669
|
}
|
|
11487
11670
|
var builtInTextSizes = /* @__PURE__ */ new Set([
|
|
@@ -11520,6 +11703,9 @@ function isTypographySize(name) {
|
|
|
11520
11703
|
return /^--text-(?!.*--)(?:[a-z0-9]+-)*[a-z0-9]+$/u.test(name);
|
|
11521
11704
|
}
|
|
11522
11705
|
function suggestedThemeToken(candidate) {
|
|
11706
|
+
if (candidate.namespace === "background-image") {
|
|
11707
|
+
return candidate.token.endsWith("-canvas") ? candidate.token : `${candidate.token}-canvas`;
|
|
11708
|
+
}
|
|
11523
11709
|
if (candidate.namespace !== "color") return candidate.token;
|
|
11524
11710
|
let role = "edge";
|
|
11525
11711
|
if (["bg", "fill"].includes(candidate.prefix)) {
|
|
@@ -11537,7 +11723,8 @@ function themeMigrationGuidance(candidate, utilityName) {
|
|
|
11537
11723
|
const runtimeDependent = /\bvar\s*\(/iu.test(candidate.value);
|
|
11538
11724
|
const action = runtimeDependent ? `only use a self-named @theme inline token "${token}" with an unconditional :root default and a detected runtime override; otherwise resolve the fixed value directly in @theme. ` : `define a direct @theme token "${token}" with value "${candidate.value}" rather than adding a :root bridge. `;
|
|
11539
11725
|
const classGuidance = generatedClass === utilityName ? "Preserve the generated class name" : `Update class usages to "${generatedClass}"`;
|
|
11540
|
-
|
|
11726
|
+
const resetWarning = candidate.gradientShorthand ? " Replacing the background shorthand with background-image stops resetting other background properties; verify cascade and rendering." : "";
|
|
11727
|
+
return `${action}${classGuidance} and compare compiled CSS before removing the utility.${resetWarning}`;
|
|
11541
11728
|
}
|
|
11542
11729
|
var utilityMappingRule = {
|
|
11543
11730
|
meta: {
|
|
@@ -11549,13 +11736,13 @@ var utilityMappingRule = {
|
|
|
11549
11736
|
},
|
|
11550
11737
|
create(context) {
|
|
11551
11738
|
const sourceRoot = sourceRootOf(context);
|
|
11552
|
-
const current =
|
|
11739
|
+
const current = path79.normalize(path79.resolve(context.filename));
|
|
11553
11740
|
const textOf = cachedTextReader();
|
|
11554
11741
|
const graph = buildCssDependencyGraph({
|
|
11555
11742
|
sourceRoot,
|
|
11556
11743
|
css: findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => ({
|
|
11557
11744
|
path: file,
|
|
11558
|
-
content:
|
|
11745
|
+
content: path79.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11559
11746
|
})),
|
|
11560
11747
|
modules: [],
|
|
11561
11748
|
includeReferences: false
|
|
@@ -11703,8 +11890,8 @@ var utilityMappingRule = {
|
|
|
11703
11890
|
const generatorCandidates = utilities.map(
|
|
11704
11891
|
(utility) => themeCandidate(preludeIdentifiers(utility)[0] ?? "unknown", context.sourceCode.getText(utility))
|
|
11705
11892
|
).filter((candidate) => Boolean(candidate && requiresGeneratorProbe(candidate)));
|
|
11706
|
-
const physicalDir =
|
|
11707
|
-
const tailwindCwd =
|
|
11893
|
+
const physicalDir = path79.dirname(context.physicalFilename);
|
|
11894
|
+
const tailwindCwd = path79.isAbsolute(physicalDir) && existsSync12(physicalDir) ? physicalDir : context.cwd;
|
|
11708
11895
|
const themeGenerators = themeSupportedGenerators(generatorCandidates, tailwindCwd);
|
|
11709
11896
|
for (const utility of utilities) {
|
|
11710
11897
|
const name = preludeIdentifiers(utility)[0] ?? "unknown";
|
|
@@ -11730,7 +11917,7 @@ var utilityMappingRule = {
|
|
|
11730
11917
|
if (candidate && equivalent && nameCounts.get(name) === 1) {
|
|
11731
11918
|
context.report({
|
|
11732
11919
|
node: utility,
|
|
11733
|
-
message: `Custom utility "${name}" duplicates theme-generated "${equivalent}" (${candidate.property}: ${candidate.value}); reuse "${equivalent}" instead
|
|
11920
|
+
message: `Custom utility "${name}" duplicates theme-generated "${equivalent}" (${candidate.property}: ${candidate.value}); reuse "${equivalent}" instead.${candidate.gradientShorthand ? " Check background shorthand reset behavior before switching to background-image." : ""}`
|
|
11734
11921
|
});
|
|
11735
11922
|
continue;
|
|
11736
11923
|
}
|
|
@@ -11746,7 +11933,7 @@ var utilityMappingRule = {
|
|
|
11746
11933
|
if (!candidate.token) {
|
|
11747
11934
|
context.report({
|
|
11748
11935
|
node: utility,
|
|
11749
|
-
message: `Custom utility "${name}" only maps ${candidate.property} (${candidate.value}); define an @theme token in the "--${candidate.namespace}
|
|
11936
|
+
message: `Custom utility "${name}" only maps ${candidate.property} (${candidate.value}); define ${candidate.gradientShorthand ? "a semantic" : "an"} @theme token in the "--${candidate.namespace}-*${candidate.gradientShorthand ? "-canvas" : ""}" namespace and use its generated "${candidate.prefix}-*" class instead.${candidate.property === "box-shadow" ? " Compare compiled CSS and ring/inset-shadow composition before migration." : ""}${candidate.gradientShorthand ? " Check background shorthand reset behavior before switching to background-image." : ""}`
|
|
11750
11937
|
});
|
|
11751
11938
|
continue;
|
|
11752
11939
|
}
|
|
@@ -11813,10 +12000,9 @@ var utilityMappingRule = {
|
|
|
11813
12000
|
|
|
11814
12001
|
// eslint/rules/tailwind/utility-name-parity.ts
|
|
11815
12002
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
11816
|
-
import {
|
|
11817
|
-
import
|
|
11818
|
-
import
|
|
11819
|
-
import { generate as generate5, parse as parse8, toPlainObject as toPlainObject3 } from "@eslint/css-tree";
|
|
12003
|
+
import { existsSync as existsSync13 } from "fs";
|
|
12004
|
+
import path80 from "path";
|
|
12005
|
+
import { generate as generate7, parse as parse7, toPlainObject as toPlainObject2 } from "@eslint/css-tree";
|
|
11820
12006
|
function numericPart(value) {
|
|
11821
12007
|
const match = /^(?<negative>-?)(?<number>(?:\d+(?:\.\d+)?|\.\d+))(?<unit>%|px|rem|em|vw|vh|dvw|dvh|ch|fr|s|ms|deg|turn)?$/u.exec(
|
|
11822
12008
|
value
|
|
@@ -11855,14 +12041,6 @@ function readableValue(value) {
|
|
|
11855
12041
|
const slug = parts.join("-");
|
|
11856
12042
|
return slug.length <= 70 ? slug : void 0;
|
|
11857
12043
|
}
|
|
11858
|
-
function compoundValue(value) {
|
|
11859
|
-
const readable = readableValue(value);
|
|
11860
|
-
if (readable) return readable;
|
|
11861
|
-
const candidate = /^(?<fn>[a-z][a-z0-9-]*)\(/iu.exec(value.trim())?.groups?.fn?.toLowerCase();
|
|
11862
|
-
const hint = candidate?.endsWith("-") ? void 0 : candidate;
|
|
11863
|
-
const digest = createHash("sha256").update(value.trim()).digest("hex").slice(0, 12);
|
|
11864
|
-
return [hint, "hash", digest].filter(Boolean).join("-");
|
|
11865
|
-
}
|
|
11866
12044
|
var TAILWIND_WORKER = String.raw`
|
|
11867
12045
|
import { readFileSync } from "node:fs";
|
|
11868
12046
|
import { compile } from "tailwindcss";
|
|
@@ -11916,7 +12094,7 @@ function compileApplies(applies, cwd) {
|
|
|
11916
12094
|
}
|
|
11917
12095
|
function compiledOperation(compiled, index) {
|
|
11918
12096
|
if (!compiled.css) return void 0;
|
|
11919
|
-
const sheet =
|
|
12097
|
+
const sheet = toPlainObject2(parse7(compiled.css, { parseValue: false }));
|
|
11920
12098
|
const probe = rules(sheet).find((candidate) => selectorNames(candidate).includes(`pasika-probe-${String(index)}`));
|
|
11921
12099
|
if (!probe) return void 0;
|
|
11922
12100
|
const declarations = blockChildren2(probe).filter(
|
|
@@ -11930,13 +12108,14 @@ function compiledOperation(compiled, index) {
|
|
|
11930
12108
|
(child) => child.type === "Declaration" && child.property === "--tw-shadow"
|
|
11931
12109
|
);
|
|
11932
12110
|
if (shadow?.type === "Declaration") {
|
|
11933
|
-
return { property: "box-shadow", value:
|
|
12111
|
+
return { property: "box-shadow", value: generate7(shadow.value).trim() };
|
|
11934
12112
|
}
|
|
11935
12113
|
}
|
|
11936
|
-
return { property: declaration.property, value:
|
|
12114
|
+
return { property: declaration.property, value: generate7(declaration.value).trim() };
|
|
11937
12115
|
}
|
|
11938
12116
|
function expectedName(operation) {
|
|
11939
|
-
const value =
|
|
12117
|
+
const value = readableValue(operation.value);
|
|
12118
|
+
if (!value) return void 0;
|
|
11940
12119
|
const property = operation.property.replace(/^-+/u, "").replace(/^background-/u, "bg-");
|
|
11941
12120
|
return `${property}-${value}`;
|
|
11942
12121
|
}
|
|
@@ -11952,7 +12131,7 @@ var utilityNameParityRule = {
|
|
|
11952
12131
|
schema: [],
|
|
11953
12132
|
type: "problem",
|
|
11954
12133
|
docs: {
|
|
11955
|
-
description: "
|
|
12134
|
+
description: "Use property/value-derived names for readable values and semantic names for complex values."
|
|
11956
12135
|
}
|
|
11957
12136
|
},
|
|
11958
12137
|
create(context) {
|
|
@@ -11965,8 +12144,8 @@ var utilityNameParityRule = {
|
|
|
11965
12144
|
return apply ? [{ utility, name, apply }] : [];
|
|
11966
12145
|
});
|
|
11967
12146
|
if (candidates.length === 0) return;
|
|
11968
|
-
const physicalDir =
|
|
11969
|
-
const cwd =
|
|
12147
|
+
const physicalDir = path80.dirname(context.physicalFilename);
|
|
12148
|
+
const cwd = path80.isAbsolute(physicalDir) && existsSync13(physicalDir) ? physicalDir : context.cwd;
|
|
11970
12149
|
const compiled = compileApplies(
|
|
11971
12150
|
candidates.map((candidate) => candidate.apply),
|
|
11972
12151
|
cwd
|
|
@@ -11982,6 +12161,15 @@ var utilityNameParityRule = {
|
|
|
11982
12161
|
continue;
|
|
11983
12162
|
}
|
|
11984
12163
|
const expected = expectedName(operation);
|
|
12164
|
+
if (!expected) {
|
|
12165
|
+
if (/-hash-[a-f0-9]{12}$/u.test(candidate.name)) {
|
|
12166
|
+
context.report({
|
|
12167
|
+
node: candidate.utility,
|
|
12168
|
+
message: `Custom utility "${candidate.name}" uses an opaque hash for a complex ${operation.property} value; use a semantic name, or prefer a theme-generated utility where supported.`
|
|
12169
|
+
});
|
|
12170
|
+
}
|
|
12171
|
+
continue;
|
|
12172
|
+
}
|
|
11985
12173
|
if (candidate.name === expected) continue;
|
|
11986
12174
|
context.report({
|
|
11987
12175
|
node: candidate.utility,
|
|
@@ -11996,6 +12184,7 @@ var utilityNameParityRule = {
|
|
|
11996
12184
|
// eslint/rules/tailwind/index.ts
|
|
11997
12185
|
var tailwindRules = {
|
|
11998
12186
|
"theme-reset": themeResetRule,
|
|
12187
|
+
"theme-mode": themeModeRule,
|
|
11999
12188
|
"color-role-usage": colorRoleUsageRule,
|
|
12000
12189
|
"root-variables": rootVariablesRule,
|
|
12001
12190
|
"apply-usage": applyUsageRule,
|
|
@@ -12014,7 +12203,7 @@ var tailwindRules = {
|
|
|
12014
12203
|
};
|
|
12015
12204
|
|
|
12016
12205
|
// eslint/rules/type-extraction.ts
|
|
12017
|
-
import
|
|
12206
|
+
import path81 from "path";
|
|
12018
12207
|
var typeExtractionRule = {
|
|
12019
12208
|
meta: {
|
|
12020
12209
|
schema: [],
|
|
@@ -12025,7 +12214,7 @@ var typeExtractionRule = {
|
|
|
12025
12214
|
},
|
|
12026
12215
|
create(context) {
|
|
12027
12216
|
const sourceRoot = sourceRootOf(context);
|
|
12028
|
-
const file =
|
|
12217
|
+
const file = path81.resolve(context.filename);
|
|
12029
12218
|
const segments = segmentsOf(file, sourceRoot);
|
|
12030
12219
|
if (segments.length === 0) return {};
|
|
12031
12220
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -12164,9 +12353,9 @@ var uiStateRule = {
|
|
|
12164
12353
|
};
|
|
12165
12354
|
|
|
12166
12355
|
// eslint/rules/unknown-utility.ts
|
|
12167
|
-
import { existsSync as
|
|
12356
|
+
import { existsSync as existsSync14, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
|
|
12168
12357
|
import { createRequire } from "module";
|
|
12169
|
-
import
|
|
12358
|
+
import path82 from "path";
|
|
12170
12359
|
var PREFIX_NAMESPACES = {
|
|
12171
12360
|
bg: ["color", "background-image"],
|
|
12172
12361
|
text: ["color", "text"],
|
|
@@ -12452,7 +12641,7 @@ function stylesheetFiles(dir) {
|
|
|
12452
12641
|
}
|
|
12453
12642
|
return entries.flatMap((entry) => {
|
|
12454
12643
|
if (entry.startsWith(".") || entry === "node_modules") return [];
|
|
12455
|
-
const entryPath =
|
|
12644
|
+
const entryPath = path82.join(dir, entry);
|
|
12456
12645
|
let stats;
|
|
12457
12646
|
try {
|
|
12458
12647
|
stats = statSync6(entryPath);
|
|
@@ -12460,7 +12649,7 @@ function stylesheetFiles(dir) {
|
|
|
12460
12649
|
return [];
|
|
12461
12650
|
}
|
|
12462
12651
|
if (stats.isDirectory()) return stylesheetFiles(entryPath);
|
|
12463
|
-
return
|
|
12652
|
+
return path82.extname(entry) === ".css" ? [entryPath] : [];
|
|
12464
12653
|
});
|
|
12465
12654
|
}
|
|
12466
12655
|
function packageNameOf(specifier) {
|
|
@@ -12471,24 +12660,24 @@ function packageNameOf(specifier) {
|
|
|
12471
12660
|
function resolvePackageStylesheet(fromFile, specifier) {
|
|
12472
12661
|
const packageName = packageNameOf(specifier);
|
|
12473
12662
|
if (!packageName || packageName === "tailwindcss") return void 0;
|
|
12474
|
-
let directory =
|
|
12475
|
-
while (directory !==
|
|
12476
|
-
const packageRoot =
|
|
12477
|
-
const manifestPath =
|
|
12478
|
-
if (
|
|
12663
|
+
let directory = path82.dirname(fromFile);
|
|
12664
|
+
while (directory !== path82.dirname(directory)) {
|
|
12665
|
+
const packageRoot = path82.join(directory, "node_modules", packageName);
|
|
12666
|
+
const manifestPath = path82.join(packageRoot, "package.json");
|
|
12667
|
+
if (existsSync14(manifestPath)) {
|
|
12479
12668
|
try {
|
|
12480
12669
|
const manifest = readFileSync15(manifestPath, "utf8");
|
|
12481
12670
|
const stylesheet = /"style"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
|
|
12482
12671
|
const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
|
|
12483
12672
|
const target = stylesheet ?? main;
|
|
12484
12673
|
if (!target) return void 0;
|
|
12485
|
-
const resolved =
|
|
12486
|
-
return
|
|
12674
|
+
const resolved = path82.resolve(packageRoot, target);
|
|
12675
|
+
return existsSync14(resolved) ? resolved : void 0;
|
|
12487
12676
|
} catch {
|
|
12488
12677
|
return void 0;
|
|
12489
12678
|
}
|
|
12490
12679
|
}
|
|
12491
|
-
directory =
|
|
12680
|
+
directory = path82.dirname(directory);
|
|
12492
12681
|
}
|
|
12493
12682
|
return void 0;
|
|
12494
12683
|
}
|
|
@@ -12760,7 +12949,7 @@ var unknownUtilityRule = {
|
|
|
12760
12949
|
};
|
|
12761
12950
|
|
|
12762
12951
|
// eslint/rules/util-file-name.ts
|
|
12763
|
-
import
|
|
12952
|
+
import path83 from "path";
|
|
12764
12953
|
function toKebabCase2(value) {
|
|
12765
12954
|
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();
|
|
12766
12955
|
}
|
|
@@ -12773,7 +12962,7 @@ var utilFileNameRule = {
|
|
|
12773
12962
|
}
|
|
12774
12963
|
},
|
|
12775
12964
|
create(context) {
|
|
12776
|
-
const filename =
|
|
12965
|
+
const filename = path83.resolve(context.filename);
|
|
12777
12966
|
const segments = filename.replace(/\\/g, "/").split("/");
|
|
12778
12967
|
if (!segments.includes("utils")) return {};
|
|
12779
12968
|
let module;
|
|
@@ -12787,13 +12976,13 @@ var utilFileNameRule = {
|
|
|
12787
12976
|
const functionName = functions[0]?.name;
|
|
12788
12977
|
if (!functionName) return {};
|
|
12789
12978
|
const expected = toKebabCase2(functionName);
|
|
12790
|
-
const actual =
|
|
12979
|
+
const actual = path83.basename(filename, path83.extname(filename));
|
|
12791
12980
|
if (!expected || actual === expected) return {};
|
|
12792
12981
|
return {
|
|
12793
12982
|
Program(node) {
|
|
12794
12983
|
context.report({
|
|
12795
12984
|
node,
|
|
12796
|
-
message: `A utility file exporting ${functionName} must be named ${expected}.${
|
|
12985
|
+
message: `A utility file exporting ${functionName} must be named ${expected}.${path83.extname(filename).slice(1)}.`
|
|
12797
12986
|
});
|
|
12798
12987
|
}
|
|
12799
12988
|
};
|
|
@@ -12801,7 +12990,7 @@ var utilFileNameRule = {
|
|
|
12801
12990
|
};
|
|
12802
12991
|
|
|
12803
12992
|
// eslint/rules/value-extraction.ts
|
|
12804
|
-
import
|
|
12993
|
+
import path84 from "path";
|
|
12805
12994
|
var valueExtractionRule = {
|
|
12806
12995
|
meta: {
|
|
12807
12996
|
schema: [],
|
|
@@ -12812,7 +13001,7 @@ var valueExtractionRule = {
|
|
|
12812
13001
|
},
|
|
12813
13002
|
create(context) {
|
|
12814
13003
|
const sourceRoot = sourceRootOf(context);
|
|
12815
|
-
const file =
|
|
13004
|
+
const file = path84.resolve(context.filename);
|
|
12816
13005
|
const segments = segmentsOf(file, sourceRoot);
|
|
12817
13006
|
if (segments.length === 0 || segments[0] !== "app") return {};
|
|
12818
13007
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -12833,8 +13022,8 @@ var valueExtractionRule = {
|
|
|
12833
13022
|
};
|
|
12834
13023
|
|
|
12835
13024
|
// eslint/rules/vulyk/tracked-docs.ts
|
|
12836
|
-
import { existsSync as
|
|
12837
|
-
import
|
|
13025
|
+
import { existsSync as existsSync15, readFileSync as readFileSync16 } from "fs";
|
|
13026
|
+
import path85 from "path";
|
|
12838
13027
|
var PASIKA_REPO = "Bredansky/pasika";
|
|
12839
13028
|
var BASE_REQUIRED_TRACKED_DOCS = [
|
|
12840
13029
|
{ name: "documentation-guide", path: "docs/documentation-guide" },
|
|
@@ -12867,9 +13056,9 @@ var trackedDocsRule = {
|
|
|
12867
13056
|
if (!context.filename.endsWith("package.json")) return;
|
|
12868
13057
|
const root = node.body;
|
|
12869
13058
|
if (root.type !== "Object") return;
|
|
12870
|
-
const projectRoot =
|
|
12871
|
-
const configPath =
|
|
12872
|
-
if (!
|
|
13059
|
+
const projectRoot = path85.dirname(path85.resolve(context.filename));
|
|
13060
|
+
const configPath = path85.join(projectRoot, "vulyk.config.ts");
|
|
13061
|
+
if (!existsSync15(configPath)) {
|
|
12873
13062
|
context.report({
|
|
12874
13063
|
node,
|
|
12875
13064
|
message: "No vulyk.config.ts found. Run npx vulyk init to create one that tracks the framework's required tracked docs."
|
|
@@ -12893,8 +13082,8 @@ var trackedDocsRule = {
|
|
|
12893
13082
|
});
|
|
12894
13083
|
}
|
|
12895
13084
|
}
|
|
12896
|
-
const agentsPath =
|
|
12897
|
-
if (!
|
|
13085
|
+
const agentsPath = path85.join(projectRoot, "AGENTS.md");
|
|
13086
|
+
if (!existsSync15(agentsPath)) {
|
|
12898
13087
|
context.report({
|
|
12899
13088
|
node,
|
|
12900
13089
|
message: "No AGENTS.md found. Run npx vulyk agents to generate the agent file that routes to the tracked docs."
|
|
@@ -12993,7 +13182,7 @@ var withResponseHelperRule = {
|
|
|
12993
13182
|
|
|
12994
13183
|
// eslint/rules/zirka-baseline.ts
|
|
12995
13184
|
import fs7 from "fs";
|
|
12996
|
-
import
|
|
13185
|
+
import path86 from "path";
|
|
12997
13186
|
var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
|
|
12998
13187
|
var PRETTIER_CONFIGS = [
|
|
12999
13188
|
"prettier.config.mjs",
|
|
@@ -13012,10 +13201,10 @@ var zirkaBaselineRule = {
|
|
|
13012
13201
|
}
|
|
13013
13202
|
},
|
|
13014
13203
|
create(context) {
|
|
13015
|
-
const filename =
|
|
13016
|
-
const basename =
|
|
13204
|
+
const filename = path86.resolve(context.filename);
|
|
13205
|
+
const basename = path86.basename(filename);
|
|
13017
13206
|
if (!ESLINT_CONFIG.test(basename)) return {};
|
|
13018
|
-
const projectRoot =
|
|
13207
|
+
const projectRoot = path86.dirname(filename);
|
|
13019
13208
|
const report3 = (message) => {
|
|
13020
13209
|
context.report({
|
|
13021
13210
|
node: context.sourceCode.ast,
|
|
@@ -13030,7 +13219,7 @@ var zirkaBaselineRule = {
|
|
|
13030
13219
|
'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
|
|
13031
13220
|
);
|
|
13032
13221
|
}
|
|
13033
|
-
const tsconfigPath =
|
|
13222
|
+
const tsconfigPath = path86.join(projectRoot, "tsconfig.json");
|
|
13034
13223
|
if (!fs7.existsSync(tsconfigPath)) {
|
|
13035
13224
|
report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
|
|
13036
13225
|
} else {
|
|
@@ -13048,13 +13237,13 @@ var zirkaBaselineRule = {
|
|
|
13048
13237
|
report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
|
|
13049
13238
|
}
|
|
13050
13239
|
}
|
|
13051
|
-
const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(
|
|
13240
|
+
const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path86.join(projectRoot, name)));
|
|
13052
13241
|
if (!prettierConfigFile) {
|
|
13053
13242
|
report3(
|
|
13054
13243
|
"No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
|
|
13055
13244
|
);
|
|
13056
13245
|
} else {
|
|
13057
|
-
const content = fs7.readFileSync(
|
|
13246
|
+
const content = fs7.readFileSync(path86.join(projectRoot, prettierConfigFile), "utf8");
|
|
13058
13247
|
if (!content.includes("zirka")) {
|
|
13059
13248
|
report3(
|
|
13060
13249
|
"The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
|
|
@@ -13390,7 +13579,7 @@ var tailwindStructureRules = {
|
|
|
13390
13579
|
languageOptions: { tolerant: true },
|
|
13391
13580
|
rules: Object.fromEntries(
|
|
13392
13581
|
tailwindRuleIds.filter(
|
|
13393
|
-
(id) => id !== "pasika/css-entry-point" && id !== "pasika/feature-css-placement" && id !== "pasika/unique-css-definition" && id !== "pasika/utility-mapping" && id !== "pasika/utility-name-parity" && id !== "pasika/no-utility-alias" && id !== "pasika/root-variables" && id !== "pasika/color-role-usage"
|
|
13582
|
+
(id) => id !== "pasika/css-entry-point" && id !== "pasika/feature-css-placement" && id !== "pasika/unique-css-definition" && id !== "pasika/utility-mapping" && id !== "pasika/utility-name-parity" && id !== "pasika/no-utility-alias" && id !== "pasika/root-variables" && id !== "pasika/color-role-usage" && id !== "pasika/theme-mode"
|
|
13394
13583
|
).map((id) => [id, "error"])
|
|
13395
13584
|
)
|
|
13396
13585
|
};
|
|
@@ -13411,7 +13600,8 @@ var tailwindImportGraph = {
|
|
|
13411
13600
|
"pasika/utility-name-parity": "error",
|
|
13412
13601
|
"pasika/no-utility-alias": "error",
|
|
13413
13602
|
"pasika/root-variables": "error",
|
|
13414
|
-
"pasika/color-role-usage": "error"
|
|
13603
|
+
"pasika/color-role-usage": "error",
|
|
13604
|
+
"pasika/theme-mode": "error"
|
|
13415
13605
|
}
|
|
13416
13606
|
};
|
|
13417
13607
|
var pasikaAppPackageJsonConfig = {
|