@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Aoyue Design LLC.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/dist/configs/base.d.ts
CHANGED
package/dist/configs/legacy.d.ts
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import recommended_default from "./recommended.js";
|
|
2
|
+
//#region src/configs/legacy.ts
|
|
3
|
+
var legacy_default = {
|
|
4
|
+
plugins: ["@master/css"],
|
|
5
|
+
rules: recommended_default.rules,
|
|
6
|
+
parserOptions: { ecmaFeatures: { jsx: true } }
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { legacy_default as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import base_default from "./base.js";
|
|
2
|
+
//#region src/configs/recommended.ts
|
|
3
|
+
var recommended_default = {
|
|
4
|
+
...base_default,
|
|
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
|
+
//#endregion
|
|
13
|
+
export { recommended_default as default };
|
package/dist/create-rule.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import { ESLintUtils } from
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
2
|
+
|
|
3
|
+
//#region src/create-rule.d.ts
|
|
4
|
+
declare const _default: <Options extends readonly unknown[], MessageIds extends string>({
|
|
5
|
+
meta,
|
|
6
|
+
name,
|
|
7
|
+
...rule
|
|
8
|
+
}: Readonly<ESLintUtils.RuleWithMetaAndName<Options, MessageIds, unknown>>) => ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener> & {
|
|
9
|
+
name: string;
|
|
4
10
|
};
|
|
5
|
-
|
|
11
|
+
//#endregion
|
|
12
|
+
export { _default as default };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
2
|
+
//#region src/create-rule.ts
|
|
3
|
+
var create_rule_default = ESLintUtils.RuleCreator((name) => new URL(`/guide/code-linting#${name}`, "https://rc.css.master.co").href);
|
|
4
|
+
//#endregion
|
|
5
|
+
export { create_rule_default as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { TSESLint } from "@typescript-eslint/utils";
|
|
2
|
+
import { Linter } from "eslint";
|
|
3
|
+
import settings from "./settings.js";
|
|
4
|
+
|
|
5
|
+
//#region src/index.d.ts
|
|
4
6
|
declare const masterCSSPlugin: Omit<TSESLint.Linter.Plugin, 'configs'> & {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
configs: {
|
|
8
|
+
legacy: unknown;
|
|
9
|
+
base: Linter.Config;
|
|
10
|
+
recommended: Linter.Config;
|
|
11
|
+
};
|
|
12
|
+
settings: typeof settings;
|
|
11
13
|
};
|
|
12
|
-
|
|
14
|
+
//#endregion
|
|
15
|
+
export { masterCSSPlugin as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import settings from "./settings.js";
|
|
2
|
+
import plugin from "./plugin.js";
|
|
3
|
+
import base_default from "./configs/base.js";
|
|
4
|
+
import recommended_default from "./configs/recommended.js";
|
|
5
|
+
import legacy_default from "./configs/legacy.js";
|
|
6
|
+
//#region src/index.ts
|
|
7
|
+
const masterCSSPlugin = {
|
|
8
|
+
...plugin,
|
|
9
|
+
configs: {
|
|
10
|
+
legacy: legacy_default,
|
|
11
|
+
base: base_default,
|
|
12
|
+
recommended: recommended_default
|
|
13
|
+
},
|
|
14
|
+
settings
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { masterCSSPlugin as default };
|
package/dist/plugin.d.ts
CHANGED
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import no_conflicting_classes_default from "./rules/no-conflicting-classes.js";
|
|
2
|
+
import no_invalid_classes_default from "./rules/no-invalid-classes.js";
|
|
3
|
+
import no_unapproved_raw_values_default from "./rules/no-unapproved-raw-values.js";
|
|
4
|
+
import prefer_canonical_classes_default from "./rules/prefer-canonical-classes.js";
|
|
5
|
+
import sort_classes_default from "./rules/sort-classes.js";
|
|
6
|
+
import { readFileSync } from "fs";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
import { dirname, resolve } from "path";
|
|
9
|
+
//#region src/plugin.ts
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const pkg = JSON.parse(readFileSync(resolve(__dirname, "..", "package.json"), "utf-8"));
|
|
12
|
+
const plugin = {
|
|
13
|
+
meta: {
|
|
14
|
+
name: pkg.name,
|
|
15
|
+
version: pkg.version
|
|
16
|
+
},
|
|
17
|
+
rules: {
|
|
18
|
+
"no-conflicting-classes": no_conflicting_classes_default,
|
|
19
|
+
"no-invalid-classes": no_invalid_classes_default,
|
|
20
|
+
"no-unapproved-raw-values": no_unapproved_raw_values_default,
|
|
21
|
+
"prefer-canonical-classes": prefer_canonical_classes_default,
|
|
22
|
+
"sort-classes": sort_classes_default
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
export { plugin as default };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
//#region src/rules/no-conflicting-classes.d.ts
|
|
1
2
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"collisionClass" | "partialCollisionClass", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
2
|
-
|
|
3
|
+
name: string;
|
|
3
4
|
};
|
|
4
|
-
|
|
5
|
+
//#endregion
|
|
6
|
+
export { _default as default };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import create_rule_default from "../create-rule.js";
|
|
2
|
+
import defineVisitors from "../utils/define-visitors.js";
|
|
3
|
+
import resolveContext from "../utils/resolve-context.js";
|
|
4
|
+
import { findClassConflicts, findPartialClassConflicts, removeClassNamesFromClassList, replaceClassNameInClassList } from "@master/css-lint";
|
|
5
|
+
//#region src/rules/no-conflicting-classes.ts
|
|
6
|
+
var no_conflicting_classes_default = create_rule_default({
|
|
7
|
+
name: "no-conflicting-classes",
|
|
8
|
+
meta: {
|
|
9
|
+
type: "layout",
|
|
10
|
+
docs: { description: "Disallow conflicting Master CSS classes" },
|
|
11
|
+
messages: {
|
|
12
|
+
collisionClass: "{{message}}",
|
|
13
|
+
partialCollisionClass: "Prefer \"{{replacement}}\" over \"{{actual}}\" because \"{{conflict}}\" overrides part of it."
|
|
14
|
+
},
|
|
15
|
+
fixable: "code",
|
|
16
|
+
schema: []
|
|
17
|
+
},
|
|
18
|
+
defaultOptions: [],
|
|
19
|
+
create(context) {
|
|
20
|
+
const { settings, css } = resolveContext(context);
|
|
21
|
+
return defineVisitors({
|
|
22
|
+
context,
|
|
23
|
+
settings
|
|
24
|
+
}, (_, { raw, start, end, unescape, classNodes, classValues }) => {
|
|
25
|
+
const conflicts = findClassConflicts(classValues, css);
|
|
26
|
+
if (conflicts.length) {
|
|
27
|
+
const classNamesToRemove = conflicts.map(({ className }) => className);
|
|
28
|
+
const keptClassNames = [...new Set(conflicts.flatMap(({ conflicts }) => conflicts))];
|
|
29
|
+
const formatClassName = (className) => `"${className}"`;
|
|
30
|
+
const formatClassList = (classNames) => {
|
|
31
|
+
if (classNames.length <= 2) return classNames.map(formatClassName).join(" and ");
|
|
32
|
+
return `${classNames.slice(0, -1).map(formatClassName).join(", ")}, and ${formatClassName(classNames[classNames.length - 1])}`;
|
|
33
|
+
};
|
|
34
|
+
const fixedRaw = removeClassNamesFromClassList(raw, classNamesToRemove, { unescape });
|
|
35
|
+
const firstClassNode = classNodes.find((node) => node.value === classNamesToRemove[0]);
|
|
36
|
+
context.report({
|
|
37
|
+
loc: firstClassNode.loc,
|
|
38
|
+
messageId: "collisionClass",
|
|
39
|
+
data: { message: `${formatClassList(classNamesToRemove)} ${classNamesToRemove.length === 1 ? "is" : "are"} overridden by ${formatClassList(keptClassNames)}.` },
|
|
40
|
+
fix: function(fixer) {
|
|
41
|
+
return fixer.replaceTextRange([start, end], fixedRaw);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const partialConflicts = findPartialClassConflicts(classValues, css);
|
|
47
|
+
if (!partialConflicts.length) return;
|
|
48
|
+
let fixedRaw = raw;
|
|
49
|
+
for (const conflict of partialConflicts) fixedRaw = replaceClassNameInClassList(fixedRaw, conflict.className, conflict.replacement, { unescape });
|
|
50
|
+
const classNodeQueues = /* @__PURE__ */ new Map();
|
|
51
|
+
for (const classNode of classNodes) {
|
|
52
|
+
const queue = classNodeQueues.get(classNode.value);
|
|
53
|
+
if (queue) queue.push(classNode);
|
|
54
|
+
else classNodeQueues.set(classNode.value, [classNode]);
|
|
55
|
+
}
|
|
56
|
+
for (const conflict of partialConflicts) {
|
|
57
|
+
const classNode = classNodeQueues.get(conflict.className)?.shift();
|
|
58
|
+
if (!classNode) continue;
|
|
59
|
+
context.report({
|
|
60
|
+
loc: classNode.loc,
|
|
61
|
+
messageId: "partialCollisionClass",
|
|
62
|
+
data: {
|
|
63
|
+
actual: conflict.className,
|
|
64
|
+
replacement: conflict.replacement,
|
|
65
|
+
conflict: conflict.conflict
|
|
66
|
+
},
|
|
67
|
+
fix(fixer) {
|
|
68
|
+
return fixer.replaceTextRange([start, end], fixedRaw);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
//#endregion
|
|
76
|
+
export { no_conflicting_classes_default as default };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/rules/no-invalid-classes.d.ts
|
|
2
|
+
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidClass" | "disallowUnknownClass", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
3
|
+
name: string;
|
|
3
4
|
};
|
|
4
|
-
|
|
5
|
+
//#endregion
|
|
6
|
+
export { _default as default };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import create_rule_default from "../create-rule.js";
|
|
2
|
+
import defineVisitors from "../utils/define-visitors.js";
|
|
3
|
+
import resolveContext from "../utils/resolve-context.js";
|
|
4
|
+
import { noInvalidClassesOptionsSchema } from "../settings-schema.js";
|
|
5
|
+
import { getClassValidationIssues } from "@master/css-lint";
|
|
6
|
+
//#region src/rules/no-invalid-classes.ts
|
|
7
|
+
var no_invalid_classes_default = create_rule_default({
|
|
8
|
+
name: "no-invalid-classes",
|
|
9
|
+
meta: {
|
|
10
|
+
type: "problem",
|
|
11
|
+
docs: { description: "Disallow invalid Master CSS classes" },
|
|
12
|
+
messages: {
|
|
13
|
+
invalidClass: "{{message}}",
|
|
14
|
+
disallowUnknownClass: "{{message}}"
|
|
15
|
+
},
|
|
16
|
+
fixable: null,
|
|
17
|
+
schema: [noInvalidClassesOptionsSchema]
|
|
18
|
+
},
|
|
19
|
+
defaultOptions: [],
|
|
20
|
+
create: function(context) {
|
|
21
|
+
const { options, settings, css } = resolveContext(context);
|
|
22
|
+
return defineVisitors({
|
|
23
|
+
context,
|
|
24
|
+
settings
|
|
25
|
+
}, (_, { classNodes }) => {
|
|
26
|
+
for (const node of classNodes) {
|
|
27
|
+
const issues = getClassValidationIssues(node.value, css, {
|
|
28
|
+
disallowUnknownClass: options.disallowUnknownClass,
|
|
29
|
+
displayClassName: node.raw
|
|
30
|
+
});
|
|
31
|
+
for (const issue of issues) context.report({
|
|
32
|
+
loc: node.loc,
|
|
33
|
+
messageId: issue.kind === "invalid" ? "invalidClass" : "disallowUnknownClass",
|
|
34
|
+
data: { message: issue.message }
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
//#endregion
|
|
41
|
+
export { no_invalid_classes_default as default };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
//#region src/rules/no-unapproved-raw-values.d.ts
|
|
1
2
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"unapprovedRawValue", [{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
allowRawValues: boolean;
|
|
4
|
+
allowProperties: any[];
|
|
5
|
+
allowedPatterns: any[];
|
|
5
6
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
6
|
-
|
|
7
|
+
name: string;
|
|
7
8
|
};
|
|
8
|
-
|
|
9
|
+
//#endregion
|
|
10
|
+
export { _default as default };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import create_rule_default from "../create-rule.js";
|
|
2
|
+
import defineVisitors from "../utils/define-visitors.js";
|
|
3
|
+
import resolveContext from "../utils/resolve-context.js";
|
|
4
|
+
import { findUnapprovedRawValueClasses } from "@master/css-lint";
|
|
5
|
+
//#region src/rules/no-unapproved-raw-values.ts
|
|
6
|
+
var no_unapproved_raw_values_default = create_rule_default({
|
|
7
|
+
name: "no-unapproved-raw-values",
|
|
8
|
+
meta: {
|
|
9
|
+
type: "suggestion",
|
|
10
|
+
docs: { description: "Disallow unapproved raw values in token-backed Master CSS classes" },
|
|
11
|
+
messages: { unapprovedRawValue: "Unexpected raw value \"{{value}}\" in \"{{className}}\". Use a token or allow it explicitly." },
|
|
12
|
+
fixable: null,
|
|
13
|
+
schema: [{
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {
|
|
16
|
+
allowRawValues: { type: "boolean" },
|
|
17
|
+
allowProperties: {
|
|
18
|
+
type: "array",
|
|
19
|
+
items: { type: "string" },
|
|
20
|
+
uniqueItems: true
|
|
21
|
+
},
|
|
22
|
+
allowedPatterns: {
|
|
23
|
+
type: "array",
|
|
24
|
+
items: { type: "string" },
|
|
25
|
+
uniqueItems: true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
additionalProperties: false
|
|
29
|
+
}]
|
|
30
|
+
},
|
|
31
|
+
defaultOptions: [{
|
|
32
|
+
allowRawValues: false,
|
|
33
|
+
allowProperties: [],
|
|
34
|
+
allowedPatterns: []
|
|
35
|
+
}],
|
|
36
|
+
create(context) {
|
|
37
|
+
const { settings, css } = resolveContext(context);
|
|
38
|
+
const options = context.options[0] || {};
|
|
39
|
+
return defineVisitors({
|
|
40
|
+
context,
|
|
41
|
+
settings
|
|
42
|
+
}, (node, { classNodes, classValues }) => {
|
|
43
|
+
const issues = findUnapprovedRawValueClasses(classValues, css, options);
|
|
44
|
+
for (const issue of issues) {
|
|
45
|
+
const classNode = classNodes.find((node) => node.value === issue.className);
|
|
46
|
+
if (!classNode) continue;
|
|
47
|
+
context.report({
|
|
48
|
+
node,
|
|
49
|
+
loc: classNode.loc,
|
|
50
|
+
messageId: "unapprovedRawValue",
|
|
51
|
+
data: {
|
|
52
|
+
className: issue.className,
|
|
53
|
+
value: issue.value
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
//#endregion
|
|
61
|
+
export { no_unapproved_raw_values_default as default };
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CanonicalClassNameOptions } from "@master/css-lint";
|
|
2
|
+
|
|
3
|
+
//#region src/rules/prefer-canonical-classes.d.ts
|
|
2
4
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferClass", [Required<CanonicalClassNameOptions>], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
3
|
-
|
|
5
|
+
name: string;
|
|
4
6
|
};
|
|
5
|
-
|
|
7
|
+
//#endregion
|
|
8
|
+
export { _default as default };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import create_rule_default from "../create-rule.js";
|
|
2
|
+
import defineVisitors from "../utils/define-visitors.js";
|
|
3
|
+
import resolveContext from "../utils/resolve-context.js";
|
|
4
|
+
import { defaultCanonicalClassNameOptions, replaceClassGroupInClassList, replaceClassNameInClassList, suggestCanonicalClassGroups, suggestCanonicalClassName } from "@master/css-lint";
|
|
5
|
+
//#region src/rules/prefer-canonical-classes.ts
|
|
6
|
+
var prefer_canonical_classes_default = create_rule_default({
|
|
7
|
+
name: "prefer-canonical-classes",
|
|
8
|
+
meta: {
|
|
9
|
+
type: "suggestion",
|
|
10
|
+
docs: { description: "Prefer canonical Master CSS classes" },
|
|
11
|
+
messages: { preferClass: "Prefer \"{{recommended}}\" over \"{{actual}}\"." },
|
|
12
|
+
fixable: "code",
|
|
13
|
+
schema: [{
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {
|
|
16
|
+
preferStaticUtilities: { type: "boolean" },
|
|
17
|
+
preferThemeTokens: { type: "boolean" },
|
|
18
|
+
preferPropertyAliases: { type: "boolean" },
|
|
19
|
+
preferVariableReferences: { type: "boolean" },
|
|
20
|
+
preferMultiValueTokens: { type: "boolean" },
|
|
21
|
+
preferCompositionUtilities: { type: "boolean" },
|
|
22
|
+
preferConditionOrder: { type: "boolean" }
|
|
23
|
+
},
|
|
24
|
+
additionalProperties: false
|
|
25
|
+
}]
|
|
26
|
+
},
|
|
27
|
+
defaultOptions: [defaultCanonicalClassNameOptions],
|
|
28
|
+
create(context) {
|
|
29
|
+
const { settings, css } = resolveContext(context);
|
|
30
|
+
const options = {
|
|
31
|
+
...defaultCanonicalClassNameOptions,
|
|
32
|
+
...context.options[0] || {}
|
|
33
|
+
};
|
|
34
|
+
return defineVisitors({
|
|
35
|
+
context,
|
|
36
|
+
settings
|
|
37
|
+
}, (node, { raw, start, end, unescape, classNodes, classValues }) => {
|
|
38
|
+
const groupSuggestions = suggestCanonicalClassGroups(classValues, css, options);
|
|
39
|
+
const coveredClassNames = new Set(groupSuggestions.flatMap((suggestion) => suggestion.classNames));
|
|
40
|
+
const reports = [];
|
|
41
|
+
let fixedRaw = raw;
|
|
42
|
+
for (const suggestion of groupSuggestions) {
|
|
43
|
+
const firstClassNode = classNodes.find((node) => node.value === suggestion.classNames[0]);
|
|
44
|
+
if (!firstClassNode) continue;
|
|
45
|
+
fixedRaw = replaceClassGroupInClassList(fixedRaw, suggestion.classNames, suggestion.recommended, { unescape });
|
|
46
|
+
reports.push({
|
|
47
|
+
loc: firstClassNode.loc,
|
|
48
|
+
actual: suggestion.classNames.join(" "),
|
|
49
|
+
recommended: suggestion.recommended
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
for (const classNode of classNodes) {
|
|
53
|
+
if (coveredClassNames.has(classNode.value)) continue;
|
|
54
|
+
const recommended = suggestCanonicalClassName(classNode.value, css, options);
|
|
55
|
+
if (!recommended) continue;
|
|
56
|
+
fixedRaw = replaceClassNameInClassList(fixedRaw, classNode.value, recommended, { unescape });
|
|
57
|
+
reports.push({
|
|
58
|
+
loc: classNode.loc,
|
|
59
|
+
actual: classNode.value,
|
|
60
|
+
recommended
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
for (const report of reports) context.report({
|
|
64
|
+
node,
|
|
65
|
+
loc: report.loc,
|
|
66
|
+
messageId: "preferClass",
|
|
67
|
+
data: {
|
|
68
|
+
actual: report.actual,
|
|
69
|
+
recommended: report.recommended
|
|
70
|
+
},
|
|
71
|
+
fix(fixer) {
|
|
72
|
+
return fixer.replaceTextRange([start, end], fixedRaw);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
//#endregion
|
|
79
|
+
export { prefer_canonical_classes_default as default };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
//#region src/rules/sort-classes.d.ts
|
|
1
2
|
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidClassOrder", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
2
|
-
|
|
3
|
+
name: string;
|
|
3
4
|
};
|
|
4
|
-
|
|
5
|
+
//#endregion
|
|
6
|
+
export { _default as default };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import create_rule_default from "../create-rule.js";
|
|
2
|
+
import defineVisitors from "../utils/define-visitors.js";
|
|
3
|
+
import resolveContext from "../utils/resolve-context.js";
|
|
4
|
+
import { sortClassList } from "@master/css-lint";
|
|
5
|
+
//#region src/rules/sort-classes.ts
|
|
6
|
+
var sort_classes_default = create_rule_default({
|
|
7
|
+
name: "sort-classes",
|
|
8
|
+
meta: {
|
|
9
|
+
type: "layout",
|
|
10
|
+
fixable: "code",
|
|
11
|
+
docs: { description: "Sort Master CSS classes" },
|
|
12
|
+
messages: { invalidClassOrder: "No consistent class order followed." },
|
|
13
|
+
schema: []
|
|
14
|
+
},
|
|
15
|
+
defaultOptions: [],
|
|
16
|
+
create: function(context) {
|
|
17
|
+
const { settings, css } = resolveContext(context);
|
|
18
|
+
const { sourceCode } = context;
|
|
19
|
+
return defineVisitors({
|
|
20
|
+
context,
|
|
21
|
+
settings
|
|
22
|
+
}, (node, { raw, start, end, nodes, unescape }) => {
|
|
23
|
+
if (nodes.length <= 1) return;
|
|
24
|
+
const orderedRaw = sortClassList(raw, css, { unescape });
|
|
25
|
+
if (raw !== orderedRaw) context.report({
|
|
26
|
+
node,
|
|
27
|
+
loc: {
|
|
28
|
+
start: sourceCode.getLocFromIndex(start),
|
|
29
|
+
end: sourceCode.getLocFromIndex(end)
|
|
30
|
+
},
|
|
31
|
+
messageId: "invalidClassOrder",
|
|
32
|
+
fix: function(fixer) {
|
|
33
|
+
return fixer.replaceTextRange([start, end], orderedRaw);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
//#endregion
|
|
40
|
+
export { sort_classes_default as default };
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { JSONSchema4 } from "@typescript-eslint/utils/json-schema";
|
|
2
|
+
|
|
3
|
+
//#region src/settings-schema.d.ts
|
|
4
|
+
declare const masterCSSSettingsSchema: JSONSchema4;
|
|
5
|
+
declare const noInvalidClassesOptionsSchema: JSONSchema4;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { masterCSSSettingsSchema as default, masterCSSSettingsSchema, noInvalidClassesOptionsSchema };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/settings-schema.ts
|
|
2
|
+
const sourceMatcherSchema = {
|
|
3
|
+
type: "array",
|
|
4
|
+
items: {
|
|
5
|
+
type: "string",
|
|
6
|
+
minLength: 1
|
|
7
|
+
},
|
|
8
|
+
uniqueItems: true
|
|
9
|
+
};
|
|
10
|
+
const masterCSSSettingsSchema = {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
classAttributes: sourceMatcherSchema,
|
|
14
|
+
classFunctions: sourceMatcherSchema,
|
|
15
|
+
classDeclarations: sourceMatcherSchema,
|
|
16
|
+
ignoredKeys: sourceMatcherSchema,
|
|
17
|
+
manifest: { type: "object" }
|
|
18
|
+
},
|
|
19
|
+
additionalProperties: false
|
|
20
|
+
};
|
|
21
|
+
const noInvalidClassesOptionsSchema = {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: { disallowUnknownClass: { type: "boolean" } },
|
|
24
|
+
additionalProperties: false
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { masterCSSSettingsSchema as default, masterCSSSettingsSchema, noInvalidClassesOptionsSchema };
|
package/dist/settings.d.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { MasterCSSManifest } from "./utils/master-css.js";
|
|
2
|
+
|
|
3
|
+
//#region src/settings.d.ts
|
|
2
4
|
declare const settings: {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
manifest: any;
|
|
6
|
+
classAttributes: string[];
|
|
7
|
+
classFunctions: string[];
|
|
8
|
+
classDeclarations: string[];
|
|
9
|
+
ignoredKeys: string[];
|
|
8
10
|
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
manifest?: MasterCSSManifest;
|
|
11
|
+
interface Settings {
|
|
12
|
+
classAttributes?: string[];
|
|
13
|
+
classFunctions?: string[];
|
|
14
|
+
classDeclarations?: string[];
|
|
15
|
+
ignoredKeys: string[];
|
|
16
|
+
manifest?: MasterCSSManifest;
|
|
16
17
|
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { Settings, settings as default };
|