@master/eslint-plugin-css 2.0.0-rc.72 → 2.0.0-rc.74
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/dist/configs/base.d.ts +5 -2
- package/dist/configs/base.js +5 -0
- package/dist/configs/legacy.d.ts +5 -2
- package/dist/configs/legacy.js +9 -0
- package/dist/configs/recommended.d.ts +5 -2
- package/dist/configs/recommended.js +13 -0
- package/dist/create-rule.d.ts +11 -4
- package/dist/create-rule.js +5 -0
- package/dist/index.d.ts +13 -10
- package/dist/index.js +17 -0
- package/dist/plugin.d.ts +5 -2
- package/dist/plugin.js +26 -0
- package/dist/rules/no-conflicting-classes.d.ts +4 -2
- package/dist/rules/no-conflicting-classes.js +76 -0
- package/dist/rules/no-invalid-classes.d.ts +5 -3
- package/dist/rules/no-invalid-classes.js +41 -0
- package/dist/rules/no-unapproved-raw-values.d.ts +7 -5
- package/dist/rules/no-unapproved-raw-values.js +61 -0
- package/dist/rules/prefer-canonical-classes.d.ts +6 -3
- package/dist/rules/prefer-canonical-classes.js +79 -0
- package/dist/rules/sort-classes.d.ts +4 -2
- package/dist/rules/sort-classes.js +40 -0
- package/dist/settings-schema.d.ts +7 -4
- package/dist/settings-schema.js +27 -0
- package/dist/settings.d.ts +16 -13
- package/dist/settings.js +8 -0
- package/dist/utils/define-visitors.d.ts +14 -7
- package/dist/utils/define-visitors.js +107 -0
- package/dist/utils/is-same-or-child-path.d.ts +4 -1
- package/dist/utils/is-same-or-child-path.js +8 -0
- package/dist/utils/master-css.d.ts +6 -4
- package/dist/utils/master-css.js +6 -0
- package/dist/utils/resolve-class-node.d.ts +22 -18
- package/dist/utils/resolve-class-node.js +85 -0
- package/dist/utils/resolve-context.d.ts +16 -12
- package/dist/utils/resolve-context.js +69 -0
- package/dist/utils/with-visit-class-node.d.ts +8 -4
- package/dist/utils/with-visit-class-node.js +51 -0
- package/package.json +78 -1
- package/dist/configs/base.cjs +0 -11
- package/dist/configs/base.mjs +0 -9
- package/dist/configs/legacy.cjs +0 -17
- package/dist/configs/legacy.mjs +0 -15
- package/dist/configs/recommended.cjs +0 -15
- package/dist/configs/recommended.mjs +0 -13
- package/dist/create-rule.cjs +0 -7
- package/dist/create-rule.mjs +0 -5
- package/dist/index.cjs +0 -19
- package/dist/index.mjs +0 -17
- package/dist/plugin.cjs +0 -30
- package/dist/plugin.mjs +0 -27
- package/dist/rules/no-conflicting-classes.cjs +0 -101
- package/dist/rules/no-conflicting-classes.mjs +0 -99
- package/dist/rules/no-invalid-classes.cjs +0 -51
- package/dist/rules/no-invalid-classes.mjs +0 -49
- package/dist/rules/no-unapproved-raw-values.cjs +0 -77
- package/dist/rules/no-unapproved-raw-values.mjs +0 -75
- package/dist/rules/prefer-canonical-classes.cjs +0 -112
- package/dist/rules/prefer-canonical-classes.mjs +0 -110
- package/dist/rules/sort-classes.cjs +0 -53
- package/dist/rules/sort-classes.mjs +0 -51
- package/dist/settings-schema.cjs +0 -38
- package/dist/settings-schema.mjs +0 -32
- package/dist/settings.cjs +0 -10
- package/dist/settings.mjs +0 -8
- package/dist/utils/define-visitors.cjs +0 -125
- package/dist/utils/define-visitors.mjs +0 -123
- package/dist/utils/is-same-or-child-path.cjs +0 -10
- package/dist/utils/is-same-or-child-path.mjs +0 -8
- package/dist/utils/master-css.cjs +0 -14
- package/dist/utils/master-css.mjs +0 -7
- package/dist/utils/resolve-class-node.cjs +0 -98
- package/dist/utils/resolve-class-node.mjs +0 -96
- package/dist/utils/resolve-context.cjs +0 -78
- package/dist/utils/resolve-context.mjs +0 -76
- package/dist/utils/with-visit-class-node.cjs +0 -57
- package/dist/utils/with-visit-class-node.mjs +0 -55
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import { TSESTree } from
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import resolveClassNode from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { TSESTree } from "@typescript-eslint/utils";
|
|
2
|
+
import { Settings } from "../settings.js";
|
|
3
|
+
import { RuleContext, RuleListener } from "@typescript-eslint/utils/ts-eslint";
|
|
4
|
+
import resolveClassNode from "./resolve-class-node.js";
|
|
5
|
+
|
|
6
|
+
//#region src/utils/define-visitors.d.ts
|
|
7
|
+
declare function defineVisitors({
|
|
8
|
+
context,
|
|
9
|
+
settings
|
|
10
|
+
}: {
|
|
11
|
+
context: RuleContext<any, any[]>;
|
|
12
|
+
settings: Settings;
|
|
8
13
|
}, visitNode: (node: TSESTree.Node, resolved: ReturnType<typeof resolveClassNode>) => void): RuleListener;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { defineVisitors as default };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import withVisitClassNode from "./with-visit-class-node.js";
|
|
2
|
+
//#region src/utils/define-visitors.ts
|
|
3
|
+
function defineVisitors({ context, settings }, visitNode) {
|
|
4
|
+
const classAttributeRegex = new RegExp(`^(?:${settings.classAttributes.join("|")})$`);
|
|
5
|
+
const classFunctionsRegex = new RegExp(`^(?:${settings.classFunctions.join("|")})$`);
|
|
6
|
+
const classDeclarationsRegex = new RegExp(`^(?:${settings.classDeclarations.join("|")})$`);
|
|
7
|
+
const visitClassNode = withVisitClassNode(visitNode, context);
|
|
8
|
+
const getStaticName = (node) => {
|
|
9
|
+
if (!node) return;
|
|
10
|
+
if (node.type === "Identifier") return node.name;
|
|
11
|
+
if (node.type === "Literal" && typeof node.value === "string") return node.value;
|
|
12
|
+
};
|
|
13
|
+
const getMemberExpressionName = (node) => {
|
|
14
|
+
if (!node || node.type !== "MemberExpression") return;
|
|
15
|
+
const objectName = getStaticName(node.object);
|
|
16
|
+
const propertyName = getStaticName(node.property);
|
|
17
|
+
if (!objectName || !propertyName) return;
|
|
18
|
+
return `${objectName}.${propertyName}`;
|
|
19
|
+
};
|
|
20
|
+
const getCalleeName = (node) => {
|
|
21
|
+
const calleeNode = node.callee || node.tag;
|
|
22
|
+
return getStaticName(calleeNode) || getMemberExpressionName(calleeNode);
|
|
23
|
+
};
|
|
24
|
+
const allowCalleeNode = (node) => {
|
|
25
|
+
const calleeName = getCalleeName(node);
|
|
26
|
+
return calleeName ? classFunctionsRegex.test(calleeName) : false;
|
|
27
|
+
};
|
|
28
|
+
const getPropertyName = (prop) => getStaticName(prop.key);
|
|
29
|
+
const visitUtilityDefinitions = (node) => {
|
|
30
|
+
if (!node) return;
|
|
31
|
+
if (node.type === "ArrayExpression") {
|
|
32
|
+
node.elements.forEach((element) => {
|
|
33
|
+
if (!element || element.type === "ObjectExpression") return;
|
|
34
|
+
visitClassNode(element);
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (node.type !== "ObjectExpression") {
|
|
39
|
+
visitClassNode(node);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const visitClassDeclarationNode = (name, node) => {
|
|
44
|
+
if (name !== "utilities") {
|
|
45
|
+
visitClassNode(node);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
visitUtilityDefinitions(node);
|
|
49
|
+
};
|
|
50
|
+
const CallExpression = function(node) {
|
|
51
|
+
if (!allowCalleeNode(node)) return;
|
|
52
|
+
node.arguments.forEach((node) => {
|
|
53
|
+
visitClassNode(node);
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
const scriptVisitor = {
|
|
57
|
+
CallExpression,
|
|
58
|
+
JSXAttribute: function(node) {
|
|
59
|
+
if (!node.name || !classAttributeRegex.test(node.name.name)) return;
|
|
60
|
+
if (node.value) visitClassNode(node.value);
|
|
61
|
+
},
|
|
62
|
+
SvelteAttribute: function(node) {
|
|
63
|
+
if (!node.key?.name || !classAttributeRegex.test(node.key.name)) return;
|
|
64
|
+
for (const eachValue of node.value) visitClassNode(eachValue);
|
|
65
|
+
},
|
|
66
|
+
TextAttribute: function(node) {
|
|
67
|
+
if (!node.name || !classAttributeRegex.test(node.name)) return;
|
|
68
|
+
visitClassNode(node);
|
|
69
|
+
},
|
|
70
|
+
TaggedTemplateExpression: function(node) {
|
|
71
|
+
if (allowCalleeNode(node)) {
|
|
72
|
+
visitClassNode(node.quasi);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
VariableDeclaration: function(node) {
|
|
77
|
+
node.declarations.forEach((decl) => {
|
|
78
|
+
if (decl.id.type === "Identifier" && classDeclarationsRegex.test(decl.id.name)) visitClassDeclarationNode(decl.id.name, decl.init);
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
ObjectExpression: function(node) {
|
|
82
|
+
node.properties.forEach((prop) => {
|
|
83
|
+
if (prop.type === "Property") {
|
|
84
|
+
const propName = getPropertyName(prop);
|
|
85
|
+
if (typeof propName === "string" && classDeclarationsRegex.test(propName)) visitClassDeclarationNode(propName, prop.value);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const templateBodyVisitor = {
|
|
91
|
+
CallExpression,
|
|
92
|
+
VAttribute: function(node) {
|
|
93
|
+
const name = node.key?.argument?.name || node.key?.name;
|
|
94
|
+
if (!name || !classAttributeRegex.test(name)) return;
|
|
95
|
+
if (node.value && node.value.type === "VLiteral") visitClassNode(node.value);
|
|
96
|
+
else if (node.value) {
|
|
97
|
+
if (node.value.type === "VExpressionContainer") {
|
|
98
|
+
if (node.value.expression?.type === "ArrayExpression" || node.value.expression?.type === "ObjectExpression") visitClassNode(node.value.expression);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
if (context.sourceCode.parserServices == null || context.sourceCode.parserServices.defineTemplateBodyVisitor == null) return scriptVisitor;
|
|
104
|
+
else return context.sourceCode.parserServices.defineTemplateBodyVisitor(templateBodyVisitor, scriptVisitor);
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
export { defineVisitors as default };
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/utils/is-same-or-child-path.d.ts
|
|
2
|
+
declare function isSameOrChildPath(parentPath: string, childPath: string): boolean;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { isSameOrChildPath as default };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
//#region src/utils/is-same-or-child-path.ts
|
|
3
|
+
function isSameOrChildPath(parentPath, childPath) {
|
|
4
|
+
const relativePath = path.relative(parentPath, childPath);
|
|
5
|
+
return relativePath === "" || !!relativePath && relativePath !== ".." && !relativePath.startsWith(`..${path.sep}`) && !path.isAbsolute(relativePath);
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { isSameOrChildPath as default };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { createCSSWithNativeDeclarations } from "@master/css-validator";
|
|
2
|
+
import { MasterCSS, MasterCSSManifest } from "@master/css";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/master-css.d.ts
|
|
4
5
|
declare const defaultManifest: MasterCSSManifest;
|
|
5
|
-
|
|
6
|
+
//#endregion
|
|
7
|
+
export { type MasterCSS, type MasterCSSManifest, createCSSWithNativeDeclarations, defaultManifest };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { createCSSWithNativeDeclarations } from "@master/css-validator";
|
|
3
|
+
//#region src/utils/master-css.ts
|
|
4
|
+
const defaultManifest = createRequire(import.meta.url)("@master/css-preset/default-manifest.json");
|
|
5
|
+
//#endregion
|
|
6
|
+
export { createCSSWithNativeDeclarations, defaultManifest };
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
import { RuleContext } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { RuleContext } from "@typescript-eslint/utils/ts-eslint";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/resolve-class-node.d.ts
|
|
4
|
+
type ResolvedClassListUnescape = string | false;
|
|
5
|
+
interface ResolvedClassListNode {
|
|
6
|
+
type: 'class' | 'space';
|
|
7
|
+
value: string;
|
|
8
|
+
raw: string;
|
|
9
|
+
range: [number, number];
|
|
10
|
+
loc: any;
|
|
9
11
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
interface ResolvedClassNode {
|
|
13
|
+
nodes: ResolvedClassListNode[];
|
|
14
|
+
start: number;
|
|
15
|
+
end: number;
|
|
16
|
+
raw: string;
|
|
17
|
+
value: string;
|
|
18
|
+
unescape: ResolvedClassListUnescape;
|
|
19
|
+
classNodes: ResolvedClassListNode[];
|
|
20
|
+
classValues: string[];
|
|
19
21
|
}
|
|
20
|
-
|
|
22
|
+
declare function resolveClassNode(node: any, context: RuleContext<any, any[]>): ResolvedClassNode | undefined;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ResolvedClassListNode, ResolvedClassListUnescape, ResolvedClassNode, resolveClassNode as default };
|
|
@@ -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 };
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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;
|
|
13
15
|
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { resolveContext as default };
|
|
@@ -0,0 +1,69 @@
|
|
|
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 };
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
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.74",
|
|
51
|
+
"@master/css-lexer": "^2.0.0-rc.74",
|
|
52
|
+
"@master/css-lint": "^2.0.0-rc.74",
|
|
53
|
+
"@master/css-project": "^2.0.0-rc.74",
|
|
54
|
+
"@master/css-preset": "^2.0.0-rc.74",
|
|
55
|
+
"@master/css-validator": "^2.0.0-rc.74"
|
|
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.74"
|
|
69
|
+
},
|
|
70
|
+
"version": "2.0.0-rc.74",
|
|
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/base.cjs
DELETED
package/dist/configs/base.mjs
DELETED
package/dist/configs/legacy.cjs
DELETED
package/dist/configs/legacy.mjs
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var base = require('./base.cjs');
|
|
4
|
-
|
|
5
|
-
var recommended = {
|
|
6
|
-
...base,
|
|
7
|
-
rules: {
|
|
8
|
-
'@master/css/sort-classes': 'warn',
|
|
9
|
-
'@master/css/no-invalid-classes': 'error',
|
|
10
|
-
'@master/css/no-conflicting-classes': 'warn',
|
|
11
|
-
'@master/css/prefer-canonical-classes': 'warn'
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
module.exports = recommended;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import base from './base.mjs';
|
|
2
|
-
|
|
3
|
-
var recommended = {
|
|
4
|
-
...base,
|
|
5
|
-
rules: {
|
|
6
|
-
'@master/css/sort-classes': 'warn',
|
|
7
|
-
'@master/css/no-invalid-classes': 'error',
|
|
8
|
-
'@master/css/no-conflicting-classes': 'warn',
|
|
9
|
-
'@master/css/prefer-canonical-classes': 'warn'
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export { recommended as default };
|
package/dist/create-rule.cjs
DELETED