@master/eslint-plugin-css 2.0.0-rc.8 → 2.0.0-rc.80
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/LICENSE +21 -0
- package/README.md +228 -7
- package/dist/configs/base.d.ts +6 -0
- package/dist/configs/base.js +5 -0
- package/dist/configs/legacy.d.ts +6 -0
- package/dist/configs/legacy.js +9 -0
- package/dist/configs/recommended.d.ts +6 -14
- package/dist/configs/recommended.js +13 -1
- package/dist/configs/stylesheet.d.ts +6 -0
- package/dist/configs/stylesheet.js +11 -0
- package/dist/create-rule.d.ts +12 -0
- package/dist/create-rule.js +5 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.js +19 -1
- package/dist/plugin.d.ts +6 -3
- package/dist/plugin.js +26 -1
- package/dist/rules/no-conflicting-classes.d.ts +6 -0
- package/dist/rules/no-conflicting-classes.js +37 -0
- package/dist/rules/no-invalid-classes.d.ts +6 -0
- package/dist/rules/no-invalid-classes.js +42 -0
- package/dist/rules/no-unapproved-raw-values.d.ts +10 -0
- package/dist/rules/no-unapproved-raw-values.js +59 -0
- package/dist/rules/prefer-canonical-classes.d.ts +8 -0
- package/dist/rules/prefer-canonical-classes.js +95 -0
- package/dist/rules/sort-classes.d.ts +6 -0
- package/dist/rules/sort-classes.js +44 -0
- package/dist/settings-schema.d.ts +7 -0
- package/dist/settings-schema.js +27 -0
- package/dist/settings.d.ts +17 -5
- package/dist/settings.js +8 -1
- package/dist/stylesheet-parser.d.ts +31 -0
- package/dist/stylesheet-parser.js +33 -0
- package/dist/utils/define-source-visitors.d.ts +21 -0
- package/dist/utils/define-source-visitors.js +52 -0
- package/dist/utils/define-visitors.d.ts +15 -5
- package/dist/utils/define-visitors.js +107 -1
- package/dist/utils/is-same-or-child-path.d.ts +4 -0
- package/dist/utils/is-same-or-child-path.js +8 -0
- package/dist/utils/master-css.d.ts +7 -0
- package/dist/utils/master-css.js +6 -0
- package/dist/utils/report-lint-diagnostics.d.ts +20 -0
- package/dist/utils/report-lint-diagnostics.js +46 -0
- package/dist/utils/resolve-class-node.d.ts +24 -0
- package/dist/utils/resolve-class-node.js +85 -0
- package/dist/utils/resolve-compose-directive-class-nodes.d.ts +11 -0
- package/dist/utils/resolve-compose-directive-class-nodes.js +157 -0
- package/dist/utils/resolve-context.d.ts +16 -3
- package/dist/utils/resolve-context.js +69 -1
- package/dist/utils/with-visit-class-node.d.ts +8 -0
- package/dist/utils/with-visit-class-node.js +51 -0
- package/package.json +78 -1
- package/dist/configs/config.d.ts +0 -13
- package/dist/configs/config.js +0 -1
- package/dist/configs/config.mjs +0 -1
- package/dist/configs/flat.d.ts +0 -16
- package/dist/configs/flat.js +0 -1
- package/dist/configs/flat.mjs +0 -1
- package/dist/configs/recommended.mjs +0 -1
- package/dist/index.mjs +0 -1
- package/dist/plugin.mjs +0 -1
- package/dist/rules/class-collision.d.ts +0 -3
- package/dist/rules/class-collision.js +0 -1
- package/dist/rules/class-collision.mjs +0 -1
- package/dist/rules/class-order.d.ts +0 -3
- package/dist/rules/class-order.js +0 -1
- package/dist/rules/class-order.mjs +0 -1
- package/dist/rules/class-validation.d.ts +0 -3
- package/dist/rules/class-validation.js +0 -1
- package/dist/rules/class-validation.mjs +0 -1
- package/dist/settings.mjs +0 -1
- package/dist/utils/are-declarations-equal.d.ts +0 -1
- package/dist/utils/are-declarations-equal.js +0 -1
- package/dist/utils/are-declarations-equal.mjs +0 -1
- package/dist/utils/define-visitors.mjs +0 -1
- package/dist/utils/extract-classnames-from-value.d.ts +0 -6
- package/dist/utils/extract-classnames-from-value.js +0 -1
- package/dist/utils/extract-classnames-from-value.mjs +0 -1
- package/dist/utils/extract-range-from-node.d.ts +0 -1
- package/dist/utils/extract-range-from-node.js +0 -1
- package/dist/utils/extract-range-from-node.mjs +0 -1
- package/dist/utils/extract-value-from-node.d.ts +0 -1
- package/dist/utils/extract-value-from-node.js +0 -1
- package/dist/utils/extract-value-from-node.mjs +0 -1
- package/dist/utils/find-loc.d.ts +0 -7
- package/dist/utils/find-loc.js +0 -1
- package/dist/utils/find-loc.mjs +0 -1
- package/dist/utils/get-mastercss.d.ts +0 -2
- package/dist/utils/get-mastercss.js +0 -1
- package/dist/utils/get-mastercss.mjs +0 -1
- package/dist/utils/get-template-element-body.d.ts +0 -1
- package/dist/utils/get-template-element-body.js +0 -1
- package/dist/utils/get-template-element-body.mjs +0 -1
- package/dist/utils/get-template-element-prefix.d.ts +0 -1
- package/dist/utils/get-template-element-prefix.js +0 -1
- package/dist/utils/get-template-element-prefix.mjs +0 -1
- package/dist/utils/get-template-element-suffix.d.ts +0 -1
- package/dist/utils/get-template-element-suffix.js +0 -1
- package/dist/utils/get-template-element-suffix.mjs +0 -1
- package/dist/utils/parse-node-recursive.d.ts +0 -13
- package/dist/utils/parse-node-recursive.js +0 -1
- package/dist/utils/parse-node-recursive.mjs +0 -1
- package/dist/utils/reorder-valid-classes-action.d.ts +0 -3
- package/dist/utils/reorder-valid-classes-action.js +0 -1
- package/dist/utils/reorder-valid-classes-action.mjs +0 -1
- package/dist/utils/resolve-context.mjs +0 -1
- package/dist/utils/valid-rules-action.d.ts +0 -3
- package/dist/utils/valid-rules-action.js +0 -1
- package/dist/utils/valid-rules-action.mjs +0 -1
- package/dist/utils/validate-action.d.ts +0 -3
- package/dist/utils/validate-action.js +0 -1
- package/dist/utils/validate-action.mjs +0 -1
- package/dist/utils/workers/reorder-valid-classes.d.ts +0 -2
- package/dist/utils/workers/reorder-valid-classes.js +0 -1
- package/dist/utils/workers/reorder-valid-classes.mjs +0 -1
- package/dist/utils/workers/valid-rules.d.ts +0 -2
- package/dist/utils/workers/valid-rules.js +0 -1
- package/dist/utils/workers/valid-rules.mjs +0 -1
- package/dist/utils/workers/validate.d.ts +0 -5
- package/dist/utils/workers/validate.js +0 -1
- package/dist/utils/workers/validate.mjs +0 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { parseMasterCSSClassList } from "@master/css-lexer";
|
|
2
|
+
//#region src/utils/resolve-class-node.ts
|
|
3
|
+
function resolveClassNode(node, context) {
|
|
4
|
+
const { sourceCode } = context;
|
|
5
|
+
let value = null;
|
|
6
|
+
let raw = null;
|
|
7
|
+
let start = null;
|
|
8
|
+
let end = null;
|
|
9
|
+
let unescape = false;
|
|
10
|
+
switch (node.type) {
|
|
11
|
+
case "Literal":
|
|
12
|
+
value = node.value;
|
|
13
|
+
raw = node.raw;
|
|
14
|
+
start = node.range[0];
|
|
15
|
+
end = node.range[1];
|
|
16
|
+
break;
|
|
17
|
+
case "VLiteral":
|
|
18
|
+
value = node.value;
|
|
19
|
+
raw = sourceCode.getText(node);
|
|
20
|
+
start = node.range[0];
|
|
21
|
+
end = node.range[1];
|
|
22
|
+
break;
|
|
23
|
+
case "TextAttribute":
|
|
24
|
+
value = node.value;
|
|
25
|
+
start = node.valueSpan.fullStart.offset;
|
|
26
|
+
end = node.valueSpan.end.offset;
|
|
27
|
+
raw = sourceCode.getText({
|
|
28
|
+
...node,
|
|
29
|
+
range: [start, end]
|
|
30
|
+
});
|
|
31
|
+
break;
|
|
32
|
+
case "SvelteLiteral":
|
|
33
|
+
value = node.value;
|
|
34
|
+
raw = sourceCode.getText(node);
|
|
35
|
+
start = node.range[0];
|
|
36
|
+
end = node.range[1];
|
|
37
|
+
break;
|
|
38
|
+
case "TemplateElement":
|
|
39
|
+
if (node.parent.expressions.length) return;
|
|
40
|
+
value = node.value.cooked;
|
|
41
|
+
raw = node.value.raw;
|
|
42
|
+
start = node.range[0] + 1;
|
|
43
|
+
end = node.range[1] - 1;
|
|
44
|
+
unescape = "`";
|
|
45
|
+
break;
|
|
46
|
+
default: return;
|
|
47
|
+
}
|
|
48
|
+
if (typeof value !== "string") return;
|
|
49
|
+
if (/^(['"`])([\s\S]*)\1$/.test(raw)) {
|
|
50
|
+
unescape = raw[0];
|
|
51
|
+
raw = raw.slice(1, -1);
|
|
52
|
+
start = start + 1;
|
|
53
|
+
end = end - 1;
|
|
54
|
+
}
|
|
55
|
+
const nodes = parseMasterCSSClassList(raw, {
|
|
56
|
+
preserveSpaces: true,
|
|
57
|
+
unescape
|
|
58
|
+
}).map((item) => {
|
|
59
|
+
const startOffset = start + item.start;
|
|
60
|
+
const endOffset = start + item.end;
|
|
61
|
+
return {
|
|
62
|
+
type: item.type,
|
|
63
|
+
value: item.token,
|
|
64
|
+
raw: item.raw,
|
|
65
|
+
range: [startOffset, endOffset],
|
|
66
|
+
loc: {
|
|
67
|
+
start: sourceCode.getLocFromIndex(startOffset),
|
|
68
|
+
end: sourceCode.getLocFromIndex(endOffset)
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
const classNodes = nodes.filter((node) => node.type === "class");
|
|
73
|
+
return {
|
|
74
|
+
nodes,
|
|
75
|
+
start,
|
|
76
|
+
end,
|
|
77
|
+
raw,
|
|
78
|
+
value,
|
|
79
|
+
unescape,
|
|
80
|
+
classNodes,
|
|
81
|
+
classValues: classNodes.map((node) => node.value)
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { resolveClassNode as default };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RuleContext } from "@typescript-eslint/utils/ts-eslint";
|
|
2
|
+
import { ResolvedClassNode } from "./resolve-class-node.js";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/resolve-compose-directive-class-nodes.d.ts
|
|
5
|
+
interface ResolvedComposeDirectiveClassNode extends ResolvedClassNode {
|
|
6
|
+
directiveStart: number;
|
|
7
|
+
directiveEnd: number;
|
|
8
|
+
}
|
|
9
|
+
declare function resolveComposeDirectiveClassNodes(context: RuleContext<any, any[]>): ResolvedComposeDirectiveClassNode[];
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ResolvedComposeDirectiveClassNode, resolveComposeDirectiveClassNodes as default };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { collectCSSDirectiveRanges, parseMasterCSSClassList } from "@master/css-lexer";
|
|
2
|
+
//#region src/utils/resolve-compose-directive-class-nodes.ts
|
|
3
|
+
const CSS_LIKE_FILE_RE = /\.(?:css|scss|sass|less|pcss|postcss)$/i;
|
|
4
|
+
const CSS_LINE_COMMENT_FILE_RE = /\.(?:scss|sass|less)$/i;
|
|
5
|
+
const STYLE_CONTAINER_FILE_RE = /\.(?:vue|svelte|astro|html|htm|mdx)$/i;
|
|
6
|
+
const STYLE_LINE_COMMENT_RE = /\blang\s*=\s*(?:"(?:scss|sass|less)"|'(?:scss|sass|less)'|(?:scss|sass|less)\b)/i;
|
|
7
|
+
function getFilename(context) {
|
|
8
|
+
return (context.filename || context.getFilename?.() || "").split(/[?#]/)[0];
|
|
9
|
+
}
|
|
10
|
+
function isWhitespace(char) {
|
|
11
|
+
return char !== void 0 && /\s/.test(char);
|
|
12
|
+
}
|
|
13
|
+
function findHTMLTagEnd(source, start) {
|
|
14
|
+
let quote = "";
|
|
15
|
+
for (let index = start; index < source.length; index++) {
|
|
16
|
+
const char = source[index];
|
|
17
|
+
if (quote) {
|
|
18
|
+
if (char === quote) quote = "";
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (char === "\"" || char === "'") {
|
|
22
|
+
quote = char;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (char === ">") return index + 1;
|
|
26
|
+
}
|
|
27
|
+
return -1;
|
|
28
|
+
}
|
|
29
|
+
function collectStyleContentRanges(source) {
|
|
30
|
+
const ranges = [];
|
|
31
|
+
const openStylePattern = /<style\b/gi;
|
|
32
|
+
let match;
|
|
33
|
+
while (match = openStylePattern.exec(source)) {
|
|
34
|
+
const openStart = match.index;
|
|
35
|
+
const openEnd = findHTMLTagEnd(source, openStart);
|
|
36
|
+
if (openEnd === -1) break;
|
|
37
|
+
const openTag = source.slice(openStart, openEnd);
|
|
38
|
+
const closeMatch = /<\/style\s*>/i.exec(source.slice(openEnd));
|
|
39
|
+
const closeStart = closeMatch ? openEnd + closeMatch.index : source.length;
|
|
40
|
+
ranges.push({
|
|
41
|
+
start: openEnd,
|
|
42
|
+
end: closeStart,
|
|
43
|
+
lineComments: STYLE_LINE_COMMENT_RE.test(openTag)
|
|
44
|
+
});
|
|
45
|
+
openStylePattern.lastIndex = closeMatch ? closeStart + closeMatch[0].length : source.length;
|
|
46
|
+
}
|
|
47
|
+
return ranges;
|
|
48
|
+
}
|
|
49
|
+
function collectLineCommentRanges(source, start, end) {
|
|
50
|
+
const ranges = [];
|
|
51
|
+
let quote = "";
|
|
52
|
+
let blockComment = false;
|
|
53
|
+
for (let index = start; index < end; index++) {
|
|
54
|
+
const char = source[index];
|
|
55
|
+
const next = source[index + 1];
|
|
56
|
+
if (blockComment) {
|
|
57
|
+
if (char === "*" && next === "/") {
|
|
58
|
+
blockComment = false;
|
|
59
|
+
index++;
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (quote) {
|
|
64
|
+
if (char === "\\") index++;
|
|
65
|
+
else if (char === quote) quote = "";
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (char === "/" && next === "*") {
|
|
69
|
+
blockComment = true;
|
|
70
|
+
index++;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (char === "\"" || char === "'") {
|
|
74
|
+
quote = char;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (char === "/" && next === "/") {
|
|
78
|
+
const lineEnd = source.indexOf("\n", index + 2);
|
|
79
|
+
const commentEnd = lineEnd === -1 ? end : Math.min(lineEnd, end);
|
|
80
|
+
ranges.push({
|
|
81
|
+
start: index,
|
|
82
|
+
end: commentEnd
|
|
83
|
+
});
|
|
84
|
+
index = commentEnd;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return ranges;
|
|
88
|
+
}
|
|
89
|
+
function overlapsRange(start, end, ranges) {
|
|
90
|
+
return ranges.some((range) => start < range.end && end > range.start);
|
|
91
|
+
}
|
|
92
|
+
function collectCandidateRanges(source, filename) {
|
|
93
|
+
if (CSS_LIKE_FILE_RE.test(filename)) return [{
|
|
94
|
+
start: 0,
|
|
95
|
+
end: source.length,
|
|
96
|
+
lineComments: CSS_LINE_COMMENT_FILE_RE.test(filename)
|
|
97
|
+
}];
|
|
98
|
+
if (STYLE_CONTAINER_FILE_RE.test(filename)) return collectStyleContentRanges(source);
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
function resolveComposeDirectiveClassNode(source, sourceCode, start, end) {
|
|
102
|
+
while (start < end && isWhitespace(source[start])) start++;
|
|
103
|
+
while (end > start && isWhitespace(source[end - 1])) end--;
|
|
104
|
+
if (start >= end) return;
|
|
105
|
+
const raw = source.slice(start, end);
|
|
106
|
+
const nodes = parseMasterCSSClassList(raw, { preserveSpaces: true }).map((item) => {
|
|
107
|
+
const startOffset = start + item.start;
|
|
108
|
+
const endOffset = start + item.end;
|
|
109
|
+
return {
|
|
110
|
+
type: item.type,
|
|
111
|
+
value: item.token,
|
|
112
|
+
raw: item.raw,
|
|
113
|
+
range: [startOffset, endOffset],
|
|
114
|
+
loc: {
|
|
115
|
+
start: sourceCode.getLocFromIndex(startOffset),
|
|
116
|
+
end: sourceCode.getLocFromIndex(endOffset)
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
const classNodes = nodes.filter((node) => node.type === "class");
|
|
121
|
+
if (!classNodes.length) return;
|
|
122
|
+
return {
|
|
123
|
+
nodes,
|
|
124
|
+
start,
|
|
125
|
+
end,
|
|
126
|
+
raw,
|
|
127
|
+
value: raw,
|
|
128
|
+
unescape: false,
|
|
129
|
+
classNodes,
|
|
130
|
+
classValues: classNodes.map((node) => node.value)
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function resolveComposeDirectiveClassNodes(context) {
|
|
134
|
+
const filename = getFilename(context);
|
|
135
|
+
const source = context.sourceCode.getText();
|
|
136
|
+
const nodes = [];
|
|
137
|
+
for (const range of collectCandidateRanges(source, filename)) {
|
|
138
|
+
const lineCommentRanges = range.lineComments ? collectLineCommentRanges(source, range.start, range.end) : [];
|
|
139
|
+
const rangeSource = source.slice(range.start, range.end);
|
|
140
|
+
for (const directive of collectCSSDirectiveRanges(rangeSource)) {
|
|
141
|
+
if (directive.name !== "compose") continue;
|
|
142
|
+
if (directive.blockRange || directive.quotedStringRanges.length) continue;
|
|
143
|
+
if (overlapsRange(range.start + directive.keywordRange.start, range.start + directive.keywordRange.end, lineCommentRanges)) continue;
|
|
144
|
+
const classNode = resolveComposeDirectiveClassNode(source, context.sourceCode, range.start + directive.preludeRange.start, range.start + directive.preludeRange.end);
|
|
145
|
+
if (!classNode) continue;
|
|
146
|
+
if (overlapsRange(classNode.start, classNode.end, lineCommentRanges)) continue;
|
|
147
|
+
nodes.push({
|
|
148
|
+
...classNode,
|
|
149
|
+
directiveStart: range.start + directive.start,
|
|
150
|
+
directiveEnd: range.start + (directive.semicolonRange?.end ?? directive.end)
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return nodes;
|
|
155
|
+
}
|
|
156
|
+
//#endregion
|
|
157
|
+
export { resolveComposeDirectiveClassNodes as default };
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { MasterCSS } from "./master-css.js";
|
|
2
|
+
import { RuleContext } from "@typescript-eslint/utils/ts-eslint";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/resolve-context.d.ts
|
|
5
|
+
declare function resolveContext(context: RuleContext<any, any[]>): {
|
|
6
|
+
settings: {
|
|
7
|
+
manifest: any;
|
|
8
|
+
classAttributes: string[];
|
|
9
|
+
classFunctions: string[];
|
|
10
|
+
classDeclarations: string[];
|
|
11
|
+
ignoredKeys: string[];
|
|
12
|
+
};
|
|
13
|
+
options: any;
|
|
14
|
+
css: MasterCSS;
|
|
4
15
|
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { resolveContext as default };
|
|
@@ -1 +1,69 @@
|
|
|
1
|
-
|
|
1
|
+
import settings from "../settings.js";
|
|
2
|
+
import { createCSSWithNativeDeclarations, defaultManifest } from "./master-css.js";
|
|
3
|
+
import isSameOrChildPath from "./is-same-or-child-path.js";
|
|
4
|
+
import { findMasterCSSWorkspaceDirectoriesSync } from "@master/css-project/entries";
|
|
5
|
+
import { loadProjectManifestSync } from "@master/css-project/manifest-sync";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
//#region src/utils/resolve-context.ts
|
|
9
|
+
const cssCaches = [];
|
|
10
|
+
const workspaceDirectoriesByCwd = /* @__PURE__ */ new Map();
|
|
11
|
+
function getContextFilename(context) {
|
|
12
|
+
const filename = context.physicalFilename || context.filename;
|
|
13
|
+
if (!filename || filename.startsWith("<")) return;
|
|
14
|
+
const resolvedFilename = path.isAbsolute(filename) ? filename : path.resolve(context.cwd, filename);
|
|
15
|
+
return existsSync(resolvedFilename) ? resolvedFilename : void 0;
|
|
16
|
+
}
|
|
17
|
+
function getWorkspaceDirectories(cwd) {
|
|
18
|
+
let directories = workspaceDirectoriesByCwd.get(cwd);
|
|
19
|
+
if (!directories) {
|
|
20
|
+
directories = findMasterCSSWorkspaceDirectoriesSync(cwd);
|
|
21
|
+
workspaceDirectoriesByCwd.set(cwd, directories);
|
|
22
|
+
}
|
|
23
|
+
return directories;
|
|
24
|
+
}
|
|
25
|
+
function findNearestPackageDirectory(filename) {
|
|
26
|
+
let directory = path.dirname(filename);
|
|
27
|
+
const root = path.parse(directory).root;
|
|
28
|
+
while (directory !== root) {
|
|
29
|
+
if (existsSync(path.join(directory, "package.json"))) return directory;
|
|
30
|
+
directory = path.dirname(directory);
|
|
31
|
+
}
|
|
32
|
+
return path.dirname(filename);
|
|
33
|
+
}
|
|
34
|
+
function resolveSearchDirectory(context, filename) {
|
|
35
|
+
const cwd = path.resolve(context.cwd || process.cwd());
|
|
36
|
+
if (cwd !== path.parse(cwd).root && isSameOrChildPath(cwd, filename)) return cwd;
|
|
37
|
+
return findNearestPackageDirectory(filename);
|
|
38
|
+
}
|
|
39
|
+
function resolveWorkspaceDirectory(context, filename) {
|
|
40
|
+
const cwd = resolveSearchDirectory(context, filename);
|
|
41
|
+
let closestDirectory;
|
|
42
|
+
for (const directory of getWorkspaceDirectories(cwd)) if (isSameOrChildPath(directory, filename) && (!closestDirectory || directory.length > closestDirectory.length)) closestDirectory = directory;
|
|
43
|
+
return closestDirectory || cwd;
|
|
44
|
+
}
|
|
45
|
+
function resolvePlan(workspaceDir, manifest) {
|
|
46
|
+
const result = loadProjectManifestSync(workspaceDir);
|
|
47
|
+
return result.entries.length ? result.manifest : manifest;
|
|
48
|
+
}
|
|
49
|
+
function resolveContext(context) {
|
|
50
|
+
const resolvedSettings = Object.assign({}, settings, context.settings?.["@master/css"]);
|
|
51
|
+
const filename = getContextFilename(context);
|
|
52
|
+
const workspaceDir = filename ? resolveWorkspaceDirectory(context, filename) : context.cwd || process.cwd();
|
|
53
|
+
let css = cssCaches.find((cache) => cache.manifest === resolvedSettings.manifest && cache.cwd === workspaceDir)?.css;
|
|
54
|
+
if (!css) {
|
|
55
|
+
css = createCSSWithNativeDeclarations((filename ? resolvePlan(workspaceDir, resolvedSettings.manifest) : resolvedSettings.manifest) || defaultManifest);
|
|
56
|
+
cssCaches.push({
|
|
57
|
+
cwd: workspaceDir,
|
|
58
|
+
manifest: resolvedSettings.manifest,
|
|
59
|
+
css
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
settings: resolvedSettings,
|
|
64
|
+
options: context.options[0] || {},
|
|
65
|
+
css
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { resolveContext as default };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TSESTree } from "@typescript-eslint/utils";
|
|
2
|
+
import { RuleContext } from "@typescript-eslint/utils/ts-eslint";
|
|
3
|
+
import resolveClassNode from "./resolve-class-node.js";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/with-visit-class-node.d.ts
|
|
6
|
+
declare function withVisitClassNode(visit: (node: TSESTree.Node, resolved: ReturnType<typeof resolveClassNode>) => void, context: RuleContext<any, any[]>): (node: any) => void;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { withVisitClassNode as default };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import resolveClassNode from "./resolve-class-node.js";
|
|
2
|
+
//#region src/utils/with-visit-class-node.ts
|
|
3
|
+
function withVisitClassNode(visit, context) {
|
|
4
|
+
const visitNode = (node) => {
|
|
5
|
+
if (!node) return;
|
|
6
|
+
switch (node.type) {
|
|
7
|
+
case "BinaryExpression":
|
|
8
|
+
case "Identifier": return;
|
|
9
|
+
case "TemplateLiteral":
|
|
10
|
+
node.expressions?.forEach(visitNode);
|
|
11
|
+
node.quasis.forEach(visitNode);
|
|
12
|
+
return;
|
|
13
|
+
case "JSXExpressionContainer":
|
|
14
|
+
visitNode(node.expression);
|
|
15
|
+
return;
|
|
16
|
+
case "ConditionalExpression":
|
|
17
|
+
visitNode(node.consequent);
|
|
18
|
+
visitNode(node.alternate);
|
|
19
|
+
return;
|
|
20
|
+
case "ArrayExpression":
|
|
21
|
+
node.elements.forEach((el) => {
|
|
22
|
+
visitNode(el);
|
|
23
|
+
});
|
|
24
|
+
return;
|
|
25
|
+
case "LogicalExpression":
|
|
26
|
+
visitNode(node.right);
|
|
27
|
+
return;
|
|
28
|
+
case "ObjectExpression":
|
|
29
|
+
node.properties.forEach((prop) => {
|
|
30
|
+
visitNode(prop);
|
|
31
|
+
});
|
|
32
|
+
return;
|
|
33
|
+
case "Property":
|
|
34
|
+
if (node.shorthand) return;
|
|
35
|
+
if (node.value && [
|
|
36
|
+
"Literal",
|
|
37
|
+
"ArrayExpression",
|
|
38
|
+
"ObjectExpression"
|
|
39
|
+
].includes(node.value.type) && typeof node.value?.value !== "boolean") visitNode(node.value);
|
|
40
|
+
else if (node.key.type === "Literal") visitNode(node.key);
|
|
41
|
+
return;
|
|
42
|
+
default:
|
|
43
|
+
const resolved = resolveClassNode(node, context);
|
|
44
|
+
if (!resolved) return;
|
|
45
|
+
visit(node, resolved);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return visitNode;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { withVisitClassNode as default };
|
package/package.json
CHANGED
|
@@ -1 +1,78 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"name": "@master/eslint-plugin-css",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"mastercss",
|
|
6
|
+
"eslint",
|
|
7
|
+
"eslintplugin"
|
|
8
|
+
],
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"description": "Master CSS ESLint Plugin",
|
|
11
|
+
"author": "Aoyue Design LLC.",
|
|
12
|
+
"funding": "https://rc.css.master.co/sponsor",
|
|
13
|
+
"homepage": "https://css.master.co",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/master-co/css/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/master-co/css.git",
|
|
20
|
+
"directory": "packages/eslint-plugin"
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"module": "./dist/index.js",
|
|
25
|
+
"jsnext:main": "./dist/index.js",
|
|
26
|
+
"esnext": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./configs/*": {
|
|
35
|
+
"types": "./dist/configs/*.d.ts",
|
|
36
|
+
"import": "./dist/configs/*.js",
|
|
37
|
+
"default": "./dist/configs/*.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist"
|
|
42
|
+
],
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public",
|
|
45
|
+
"provenance": true
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@typescript-eslint/utils": "^8.61.1",
|
|
49
|
+
"typescript-eslint": "^8.61.1",
|
|
50
|
+
"@master/css": "^2.0.0-rc.80",
|
|
51
|
+
"@master/css-lexer": "^2.0.0-rc.80",
|
|
52
|
+
"@master/css-lint": "^2.0.0-rc.80",
|
|
53
|
+
"@master/css-preset": "^2.0.0-rc.80",
|
|
54
|
+
"@master/css-project": "^2.0.0-rc.80",
|
|
55
|
+
"@master/css-validator": "^2.0.0-rc.80"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@angular-eslint/template-parser": "^21.4.0",
|
|
59
|
+
"@angular/compiler": "^21.2.17",
|
|
60
|
+
"@typescript-eslint/rule-tester": "^8.61.1",
|
|
61
|
+
"eslint": "^10.5.0",
|
|
62
|
+
"eslint-mdx": "^3.8.1",
|
|
63
|
+
"eslint-plugin-markdown": "^5.1.0",
|
|
64
|
+
"eslint-plugin-mdx": "^3.8.1",
|
|
65
|
+
"svelte-eslint-parser": "^1.8.0",
|
|
66
|
+
"ts-node": "^10.9.2",
|
|
67
|
+
"vue-eslint-parser": "^10.4.1",
|
|
68
|
+
"@master/css-schema": "^2.0.0-rc.80"
|
|
69
|
+
},
|
|
70
|
+
"version": "2.0.0-rc.80",
|
|
71
|
+
"scripts": {
|
|
72
|
+
"build": "tsdown --config ../../shared/tsdown-package.config.ts",
|
|
73
|
+
"dev": "tsdown --config ../../shared/tsdown-package.config.ts --watch",
|
|
74
|
+
"test": "vitest",
|
|
75
|
+
"type-check": "tsc -b tsconfig.typecheck.json",
|
|
76
|
+
"lint": "eslint"
|
|
77
|
+
}
|
|
78
|
+
}
|
package/dist/configs/config.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
declare const config: {
|
|
2
|
-
readonly rules: {
|
|
3
|
-
readonly '@master/css/class-order': "warn";
|
|
4
|
-
readonly '@master/css/class-validation': "error";
|
|
5
|
-
readonly '@master/css/class-collision': "warn";
|
|
6
|
-
};
|
|
7
|
-
readonly parserOptions: {
|
|
8
|
-
readonly ecmaFeatures: {
|
|
9
|
-
readonly jsx: true;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
export default config;
|
package/dist/configs/config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var c=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var n=Object.prototype.hasOwnProperty;var i=(r,s)=>{for(var e in s)c(r,e,{get:s[e],enumerable:!0})},m=(r,s,e,t)=>{if(s&&typeof s=="object"||typeof s=="function")for(let a of l(s))!n.call(r,a)&&a!==e&&c(r,a,{get:()=>s[a],enumerable:!(t=o(s,a))||t.enumerable});return r};var u=r=>m(c({},"__esModule",{value:!0}),r);var f={};i(f,{default:()=>p});module.exports=u(f);const d={rules:{"@master/css/class-order":"warn","@master/css/class-validation":"error","@master/css/class-collision":"warn"},parserOptions:{ecmaFeatures:{jsx:!0}}};var p=d;
|
package/dist/configs/config.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const s={rules:{"@master/css/class-order":"warn","@master/css/class-validation":"error","@master/css/class-collision":"warn"},parserOptions:{ecmaFeatures:{jsx:!0}}};var r=s;export{r as default};
|
package/dist/configs/flat.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
rules: {
|
|
3
|
-
readonly '@master/css/class-order': "warn";
|
|
4
|
-
readonly '@master/css/class-validation': "error";
|
|
5
|
-
readonly '@master/css/class-collision': "warn";
|
|
6
|
-
};
|
|
7
|
-
parserOptions: {
|
|
8
|
-
readonly ecmaFeatures: {
|
|
9
|
-
readonly jsx: true;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
plugins: {
|
|
13
|
-
'@master/css': import("eslint").ESLint.Plugin;
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
export default _default;
|
package/dist/configs/flat.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var l=Object.create;var p=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var a=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty;var d=(o,r)=>{for(var i in r)p(o,i,{get:r[i],enumerable:!0})},f=(o,r,i,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let m of u(r))!c.call(o,m)&&m!==i&&p(o,m,{get:()=>r[m],enumerable:!(t=n(r,m))||t.enumerable});return o};var s=(o,r,i)=>(i=o!=null?l(a(o)):{},f(r||!o||!o.__esModule?p(i,"default",{value:o,enumerable:!0}):i,o)),x=o=>f(p({},"__esModule",{value:!0}),o);var h={};d(h,{default:()=>b});module.exports=x(h);var e=s(require("../plugin")),g=s(require("./config")),b={plugins:{"@master/css":e.default},...g.default};
|
package/dist/configs/flat.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import o from"../plugin.mjs";import r from"./config.mjs";var p={plugins:{"@master/css":o},...r};export{p as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import o from"./config.mjs";var s={plugins:["@master/css"],...o};export{s as default};
|
package/dist/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var i=(r,o)=>()=>(o||r((o={exports:{}}).exports,o),o.exports);import t from"./plugin.mjs";import f from"./settings.mjs";import p from"./configs/recommended.mjs";import e from"./configs/flat.mjs";var n=i((x,m)=>{m.exports={...t,configs:{recommended:p,flat:e},settings:f}});export default n();
|
package/dist/plugin.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import s from"./rules/class-collision.mjs";import i from"./rules/class-order.mjs";import l from"./rules/class-validation.mjs";const o={meta:{name:"@master/eslint-plugin-css"},rules:{"class-collision":s,"class-order":i,"class-validation":l}};var n=o;export{n as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var k=Object.create;var p=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var A=Object.getPrototypeOf,K=Object.prototype.hasOwnProperty;var D=(e,s)=>{for(var o in s)p(e,o,{get:s[o],enumerable:!0})},y=(e,s,o,m)=>{if(s&&typeof s=="object"||typeof s=="function")for(let i of w(s))!K.call(e,i)&&i!==o&&p(e,i,{get:()=>s[i],enumerable:!(m=q(s,i))||m.enumerable});return e};var c=(e,s,o)=>(o=e!=null?k(A(e)):{},y(s||!e||!e.__esModule?p(o,"default",{value:e,enumerable:!0}):o,e)),O=e=>y(p({},"__esModule",{value:!0}),e);var z={};D(z,{default:()=>V});module.exports=O(z);var R=c(require("../utils/are-declarations-equal")),S=c(require("../utils/define-visitors")),$=c(require("../utils/resolve-context")),v=c(require("../utils/find-loc")),L=require("../utils/parse-node-recursive"),j=c(require("../utils/valid-rules-action")),V={meta:{docs:{description:"Avoid applying classes with the same CSS declaration",category:"Stylistic Issues",recommended:!1,url:"https://rc.css.master.co/docs/code-linting#class-collision-detection"},messages:{collisionClass:"{{message}}"},fixable:"code",schema:[{type:"object",properties:{calleeMatching:{type:"string"},classMatching:{type:"string"},ignoredKeys:{type:"array",items:{type:"string",minLength:0},uniqueItems:!0},config:{type:["string","object"]}}}]},create(e){const{options:s,settings:o}=(0,$.default)(e);return(0,S.default)({context:e,settings:o},(i,x=null)=>{(0,L.parseNodeRecursive)(i,x,(a,u,M,N,b)=>{const E=e.sourceCode.lines,I=u.loc.start.line,T=u.loc.end.line,C=(0,j.default)(a,o.config);for(let l=0;l<a.length;l++){const f=a[l],g=C[f],d=[];if(g)for(let n=0;n<a.length;n++){const r=a[n],t=C[r];l!==n&&t&&(0,R.default)(g.declarations,t.declarations)&&g.stateToken===t.stateToken&&d.push(r)}if(d.length>0){const n=d.map(t=>`"${t}"`).join(" and ");let r=M;for(const t of d){const h=t.replace(/(\\|\.|\(|\)|\[|\]|\{|\}|\+|\*|\?|\^|\$|\||\/)/g,"\\$1");r=r.replace(new RegExp(`\\s+${h}|${h}\\s+`),"")}e.report({loc:(0,v.default)(f,E,I,T),messageId:"collisionClass",data:{message:`"${f}" applies the same CSS declarations as ${n}.`},fix:function(t){return t.replaceTextRange([N,b],r)}})}}},!1,!1,o.ignoredKeys,e)})}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import $ from"../utils/are-declarations-equal.mjs";import v from"../utils/define-visitors.mjs";import L from"../utils/resolve-context.mjs";import j from"../utils/find-loc.mjs";import{parseNodeRecursive as x}from"../utils/parse-node-recursive.mjs";import M from"../utils/valid-rules-action.mjs";var O={meta:{docs:{description:"Avoid applying classes with the same CSS declaration",category:"Stylistic Issues",recommended:!1,url:"https://rc.css.master.co/docs/code-linting#class-collision-detection"},messages:{collisionClass:"{{message}}"},fixable:"code",schema:[{type:"object",properties:{calleeMatching:{type:"string"},classMatching:{type:"string"},ignoredKeys:{type:"array",items:{type:"string",minLength:0},uniqueItems:!0},config:{type:["string","object"]}}}]},create(t){const{options:N,settings:a}=L(t);return v({context:t,settings:a},(f,g=null)=>{x(f,g,(i,d,u,C,h)=>{const y=t.sourceCode.lines,R=d.loc.start.line,S=d.loc.end.line,p=M(i,a.config);for(let n=0;n<i.length;n++){const c=i[n],l=p[c],r=[];if(l)for(let s=0;s<i.length;s++){const o=i[s],e=p[o];n!==s&&e&&$(l.declarations,e.declarations)&&l.stateToken===e.stateToken&&r.push(o)}if(r.length>0){const s=r.map(e=>`"${e}"`).join(" and ");let o=u;for(const e of r){const m=e.replace(/(\\|\.|\(|\)|\[|\]|\{|\}|\+|\*|\?|\^|\$|\||\/)/g,"\\$1");o=o.replace(new RegExp(`\\s+${m}|${m}\\s+`),"")}t.report({loc:j(c,y,R,S),messageId:"collisionClass",data:{message:`"${c}" applies the same CSS declarations as ${s}.`},fix:function(e){return e.replaceTextRange([C,h],o)}})}}},!1,!1,a.ignoredKeys,t)})}};export{O as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var U=Object.create;var E=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var F=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty;var X=(r,a)=>{for(var o in a)E(r,o,{get:a[o],enumerable:!0})},R=(r,a,o,h)=>{if(a&&typeof a=="object"||typeof a=="function")for(let i of A(a))!G.call(r,i)&&i!==o&&E(r,i,{get:()=>a[i],enumerable:!(h=j(a,i))||h.enumerable});return r};var m=(r,a,o)=>(o=r!=null?U(F(r)):{},R(a||!r||!r.__esModule?E(o,"default",{value:r,enumerable:!0}):o,r)),q=r=>R(E({},"__esModule",{value:!0}),r);var K={};X(K,{default:()=>B});module.exports=q(K);var I=m(require("../utils/define-visitors")),k=m(require("../utils/resolve-context")),L=m(require("../utils/get-template-element-body")),V=m(require("../utils/get-template-element-suffix")),_=m(require("../utils/get-template-element-prefix")),$=m(require("../utils/extract-value-from-node")),M=m(require("../utils/extract-range-from-node")),O=m(require("../utils/extract-classnames-from-value")),P=m(require("../utils/find-loc")),w=m(require("../utils/reorder-valid-classes-action")),B={meta:{docs:{description:"Enforce a consistent and logical order of classes",category:"Stylistic Issues",recommended:!1,url:"https://rc.css.master.co/docs/code-linting#consistent-class-order"},messages:{invalidClassOrder:"No consistent class order followed."},fixable:"code",schema:[{type:"object",properties:{calleeMatching:{type:"string"},classMatching:{type:"string"},ignoredKeys:{type:"array",items:{type:"string",minLength:0},uniqueItems:!0},config:{type:["string","object"]}}}]},create:function(r){const{options:a,settings:o}=(0,k.default)(r),h=r.sourceCode,i=(l,t=null)=>{let s=null,f=null,u=null,x="",N="",g=[];if(t===null){s=(0,$.default)(l);const e=(0,M.default)(l);l.type==="TextAttribute"?(f=e[0],u=e[1]):(f=e[0]+1,u=e[1]-1)}else switch(t.type){case"Identifier":return;case"TemplateLiteral":t.expressions.forEach(n=>{i(l,n)}),s=h.getText(t),s=s.substring(1,s.length-1),g=s.match(/\$\{(?:(?<!\\\\)(['"`]).*?(?<!\\\\)\1|[^}])*?\}/g)??[];for(let n=0;n<g.length;n++)s=s.replace(g[n],`EXPRESSION_STRING_NUM_${n}`);f=t.range[0]+1,u=t.range[1]-1;break;case"ConditionalExpression":i(l,t.consequent),i(l,t.alternate);return;case"LogicalExpression":i(l,t.right);return;case"ArrayExpression":t.elements.forEach(n=>{i(l,n)});return;case"ObjectExpression":const e=l.callee&&l.callee.name==="classnames",y=l.key&&l.key.type==="VDirectiveKey";t.properties.forEach(n=>{const T=e||y?n.key:n.value;i(l,T)});return;case"Property":i(l,t.key);break;case"Literal":s=t.value,f=t.range[0]+1,u=t.range[1]-1;break;case"SvelteLiteral":if(s=t.value,s==="")return;f=t.range[0],u=t.range[1];break;case"TemplateElement":if(s=t.value.raw,s==="")return;f=t.range[0],u=t.range[1];const p=r.sourceCode.getText(t);x=(0,_.default)(p,s),N=(0,V.default)(p,s),s=(0,L.default)(p,x,N);break}const{classNames:S,whitespaces:C,headSpace:b,tailSpace:v}=(0,O.default)(s);if(S.length<=1)return;let d=(0,w.default)(S,o.config);d=S.filter(e=>!d.includes(e)).concat(d).filter(e=>e.trim()!=="");let c="";for(let e=0;e<d.length;e++){const y=C[e]??"",p=d[e];c+=b?`${y}${p}`:`${p}${y}`,p&&(!v&&e===d.length-1&&(c=c.replace(/\s+$/,"")),b&&v&&e===d.length-1&&(c+=C[C.length-1]??""))}for(let e=0;e<g.length;e++)s=s.replace(`EXPRESSION_STRING_NUM_${e}`,g[e]),c=c.replace(`EXPRESSION_STRING_NUM_${e}`,g[e]);if(s!==c){c=x+c+N;const e=h.lines,y=l.loc.start.line,p=l.loc.end.line,n={loc:(0,P.default)(s,e,y,p),messageId:"invalidClassOrder",fix:function(T){return T.replaceTextRange([f,u],c)}};r.report(n)}};return(0,I.default)({context:r,settings:o},i)}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import T from"../utils/define-visitors.mjs";import b from"../utils/resolve-context.mjs";import v from"../utils/get-template-element-body.mjs";import R from"../utils/get-template-element-suffix.mjs";import I from"../utils/get-template-element-prefix.mjs";import k from"../utils/extract-value-from-node.mjs";import L from"../utils/extract-range-from-node.mjs";import V from"../utils/extract-classnames-from-value.mjs";import _ from"../utils/find-loc.mjs";import $ from"../utils/reorder-valid-classes-action.mjs";var D={meta:{docs:{description:"Enforce a consistent and logical order of classes",category:"Stylistic Issues",recommended:!1,url:"https://rc.css.master.co/docs/code-linting#consistent-class-order"},messages:{invalidClassOrder:"No consistent class order followed."},fixable:"code",schema:[{type:"object",properties:{calleeMatching:{type:"string"},classMatching:{type:"string"},ignoredKeys:{type:"array",items:{type:"string",minLength:0},uniqueItems:!0},config:{type:["string","object"]}}}]},create:function(u){const{options:M,settings:x}=b(u),N=u.sourceCode,a=(r,t=null)=>{let s=null,o=null,c=null,d="",g="",p=[];if(t===null){s=k(r);const e=L(r);r.type==="TextAttribute"?(o=e[0],c=e[1]):(o=e[0]+1,c=e[1]-1)}else switch(t.type){case"Identifier":return;case"TemplateLiteral":t.expressions.forEach(l=>{a(r,l)}),s=N.getText(t),s=s.substring(1,s.length-1),p=s.match(/\$\{(?:(?<!\\\\)(['"`]).*?(?<!\\\\)\1|[^}])*?\}/g)??[];for(let l=0;l<p.length;l++)s=s.replace(p[l],`EXPRESSION_STRING_NUM_${l}`);o=t.range[0]+1,c=t.range[1]-1;break;case"ConditionalExpression":a(r,t.consequent),a(r,t.alternate);return;case"LogicalExpression":a(r,t.right);return;case"ArrayExpression":t.elements.forEach(l=>{a(r,l)});return;case"ObjectExpression":const e=r.callee&&r.callee.name==="classnames",f=r.key&&r.key.type==="VDirectiveKey";t.properties.forEach(l=>{const E=e||f?l.key:l.value;a(r,E)});return;case"Property":a(r,t.key);break;case"Literal":s=t.value,o=t.range[0]+1,c=t.range[1]-1;break;case"SvelteLiteral":if(s=t.value,s==="")return;o=t.range[0],c=t.range[1];break;case"TemplateElement":if(s=t.value.raw,s==="")return;o=t.range[0],c=t.range[1];const n=u.sourceCode.getText(t);d=I(n,s),g=R(n,s),s=v(n,d,g);break}const{classNames:y,whitespaces:h,headSpace:S,tailSpace:C}=V(s);if(y.length<=1)return;let m=$(y,x.config);m=y.filter(e=>!m.includes(e)).concat(m).filter(e=>e.trim()!=="");let i="";for(let e=0;e<m.length;e++){const f=h[e]??"",n=m[e];i+=S?`${f}${n}`:`${n}${f}`,n&&(!C&&e===m.length-1&&(i=i.replace(/\s+$/,"")),S&&C&&e===m.length-1&&(i+=h[h.length-1]??""))}for(let e=0;e<p.length;e++)s=s.replace(`EXPRESSION_STRING_NUM_${e}`,p[e]),i=i.replace(`EXPRESSION_STRING_NUM_${e}`,p[e]);if(s!==i){i=d+i+g;const e=N.lines,f=r.loc.start.line,n=r.loc.end.line,l={loc:_(s,e,f,n),messageId:"invalidClassOrder",fix:function(E){return E.replaceTextRange([o,c],i)}};u.report(l)}};return T({context:u,settings:x},a)}};export{D as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var I=Object.create;var i=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var R=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty;var b=(e,s)=>{for(var o in s)i(e,o,{get:s[o],enumerable:!0})},p=(e,s,o,a)=>{if(s&&typeof s=="object"||typeof s=="function")for(let r of N(s))!S.call(e,r)&&r!==o&&i(e,r,{get:()=>s[r],enumerable:!(a=M(s,r))||a.enumerable});return e};var n=(e,s,o)=>(o=e!=null?I(R(e)):{},p(s||!e||!e.__esModule?i(o,"default",{value:e,enumerable:!0}):o,e)),U=e=>p(i({},"__esModule",{value:!0}),e);var K={};b(K,{default:()=>j});module.exports=U(K);var u=n(require("../utils/define-visitors")),y=n(require("../utils/resolve-context")),l=n(require("../utils/find-loc")),C=require("../utils/parse-node-recursive"),w=n(require("../utils/validate-action")),j={meta:{docs:{description:"Detect syntax errors early when writing classes",category:"Stylistic Issues",recommended:!1,url:"https://rc.css.master.co/docs/code-linting#syntax-error-checks"},messages:{invalidClass:"{{message}}",disallowUnknownClass:"{{message}}"},fixable:null,schema:[{type:"object",properties:{calleeMatching:{type:"string"},classMatching:{type:"string"},ignoredKeys:{type:"array",items:{type:"string",minLength:0},uniqueItems:!0},config:{type:["string","object"]}}}]},create:function(e){const{options:s,settings:o}=(0,y.default)(e);return(0,u.default)({context:e,settings:o},(r,h=null)=>{(0,C.parseNodeRecursive)(r,h,(v,c)=>{const d=e.sourceCode.lines,m=c.loc.start.line,g=c.loc.end.line;for(const t of v){const{isMasterCSS:k,errors:f}=(0,w.default)(t,o.config);if(f.length>0)for(const L of f)k?e.report({loc:(0,l.default)(t,d,m,g),messageId:"invalidClass",data:{message:L.message+"."}}):s.disallowUnknownClass&&e.report({loc:(0,l.default)(t,d,m,g),messageId:"disallowUnknownClass",data:{message:`"${t}" is not a valid or known class.`}})}},!1,!1,o.ignoredKeys,e)})}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import u from"../utils/define-visitors.mjs";import y from"../utils/resolve-context.mjs";import l from"../utils/find-loc.mjs";import{parseNodeRecursive as C}from"../utils/parse-node-recursive.mjs";import w from"../utils/validate-action.mjs";var b={meta:{docs:{description:"Detect syntax errors early when writing classes",category:"Stylistic Issues",recommended:!1,url:"https://rc.css.master.co/docs/code-linting#syntax-error-checks"},messages:{invalidClass:"{{message}}",disallowUnknownClass:"{{message}}"},fixable:null,schema:[{type:"object",properties:{calleeMatching:{type:"string"},classMatching:{type:"string"},ignoredKeys:{type:"array",items:{type:"string",minLength:0},uniqueItems:!0},config:{type:["string","object"]}}}]},create:function(e){const{options:c,settings:o}=y(e);return u({context:e,settings:o},(d,m=null)=>{C(d,m,(g,r)=>{const t=e.sourceCode.lines,i=r.loc.start.line,n=r.loc.end.line;for(const s of g){const{isMasterCSS:f,errors:a}=w(s,o.config);if(a.length>0)for(const p of a)f?e.report({loc:l(s,t,i,n),messageId:"invalidClass",data:{message:p.message+"."}}):c.disallowUnknownClass&&e.report({loc:l(s,t,i,n),messageId:"disallowUnknownClass",data:{message:`"${s}" is not a valid or known class.`}})}},!1,!1,o.ignoredKeys,e)})}};export{b as default};
|
package/dist/settings.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const s={calleeMatching:"^(classnames|clsx|ctl|cva|cv|classVariant|styled(?:\\.\\w+)?)",classMatching:"^class(Name)?$",ignoredKeys:["compoundVariants","defaultVariants"],config:"master.css.*"};var a=s;export{a as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function areDeclarationsEqual(aDeclarations: any, bDeclarations: any): boolean;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var s=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var u=(t,e)=>{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},y=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of f(e))!l.call(t,n)&&n!==r&&s(t,n,{get:()=>e[n],enumerable:!(o=c(e,n))||o.enumerable});return t};var p=t=>y(s({},"__esModule",{value:!0}),t);var O={};u(O,{default:()=>a});module.exports=p(O);function a(t,e){const r=Object.keys(t),o=Object.keys(e);if(r.length!==o.length)return!1;for(const n of r)if(!Object.prototype.hasOwnProperty.call(e,n))return!1;return!0}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function s(r,e){const t=Object.keys(r),n=Object.keys(e);if(t.length!==n.length)return!1;for(const o of t)if(!Object.prototype.hasOwnProperty.call(e,o))return!1;return!0}export{s as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function f({context:a,settings:l},r){const n=e=>{let t="";const s=e.callee||e.tag;return s.type==="Identifier"&&(t=s.name),s.type==="MemberExpression"&&(t=`${s.object.name}.${s.property.name}`),new RegExp(l.calleeMatching).test(t)},u=function(e){n(e)&&e.arguments.forEach(t=>{r(e,t)})},i=new RegExp(l.classMatching),p={CallExpression:u,JSXAttribute:function(e){!e.name||!i.test(e.name.name)||(e.value&&e.value.type==="Literal"?r(e):e.value&&e.value.type==="JSXExpressionContainer"&&r(e,e.value.expression))},SvelteAttribute:function(e){if(!(!e.key?.name||!i.test(e.key.name)))for(const t of e.value)r(e,t)},TextAttribute:function(e){!e.name||!i.test(e.name)||r(e)},TaggedTemplateExpression:function(e){if(n(e)){r(e,e.quasi);return}}},c={CallExpression:u,VAttribute:function(e){e.value&&e.value.type==="VLiteral"?r(e):e.value&&e.value.type==="VExpressionContainer"&&e.value.expression.type==="ArrayExpression"?e.value.expression.elements.forEach(t=>{r(e,t)}):e.value&&e.value.type==="VExpressionContainer"&&e.value.expression.type==="ObjectExpression"&&e.value.expression.properties.forEach(t=>{r(e,t)})}};return a.sourceCode.parserServices==null||a.sourceCode.parserServices.defineTemplateBodyVisitor==null?p:a.sourceCode.parserServices.defineTemplateBodyVisitor(c,p)}export{f as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var n=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var d=(e,s)=>{for(var t in s)n(e,t,{get:s[t],enumerable:!0})},g=(e,s,t,l)=>{if(s&&typeof s=="object"||typeof s=="function")for(let a of u(s))!S.call(e,a)&&a!==t&&n(e,a,{get:()=>s[a],enumerable:!(l=m(s,a))||l.enumerable});return e};var N=e=>g(n({},"__esModule",{value:!0}),e);var w={};d(w,{default:()=>i});module.exports=N(w);const p=/([\t\n\f\r ]+)/;function i(e){if(typeof e!="string")return{classNames:[],whitespaces:[],headSpace:!1,tailSpace:!1};const s=e.split(p);s[0]===""&&s.shift(),s[s.length-1]===""&&s.pop();const t=p.test(s[0]),l=p.test(s[s.length-1]),a=(h,c)=>t?c%2!==0:c%2===0,o=(h,c)=>t?c%2===0:c%2!==0,r=s.filter(a),f=s.filter(o);return{classNames:r,whitespaces:f,headSpace:t,tailSpace:l}}
|