@master/eslint-plugin-css 2.0.0-rc.73 → 2.0.0-rc.75

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.
Files changed (78) hide show
  1. package/LICENSE +21 -0
  2. package/dist/configs/base.d.ts +5 -2
  3. package/dist/configs/base.js +5 -0
  4. package/dist/configs/legacy.d.ts +5 -2
  5. package/dist/configs/legacy.js +9 -0
  6. package/dist/configs/recommended.d.ts +5 -2
  7. package/dist/configs/recommended.js +13 -0
  8. package/dist/create-rule.d.ts +11 -4
  9. package/dist/create-rule.js +5 -0
  10. package/dist/index.d.ts +13 -10
  11. package/dist/index.js +17 -0
  12. package/dist/plugin.d.ts +5 -2
  13. package/dist/plugin.js +26 -0
  14. package/dist/rules/no-conflicting-classes.d.ts +4 -2
  15. package/dist/rules/no-conflicting-classes.js +76 -0
  16. package/dist/rules/no-invalid-classes.d.ts +5 -3
  17. package/dist/rules/no-invalid-classes.js +41 -0
  18. package/dist/rules/no-unapproved-raw-values.d.ts +7 -5
  19. package/dist/rules/no-unapproved-raw-values.js +61 -0
  20. package/dist/rules/prefer-canonical-classes.d.ts +6 -3
  21. package/dist/rules/prefer-canonical-classes.js +79 -0
  22. package/dist/rules/sort-classes.d.ts +4 -2
  23. package/dist/rules/sort-classes.js +40 -0
  24. package/dist/settings-schema.d.ts +7 -4
  25. package/dist/settings-schema.js +27 -0
  26. package/dist/settings.d.ts +16 -13
  27. package/dist/settings.js +8 -0
  28. package/dist/utils/define-visitors.d.ts +14 -7
  29. package/dist/utils/define-visitors.js +107 -0
  30. package/dist/utils/is-same-or-child-path.d.ts +4 -1
  31. package/dist/utils/is-same-or-child-path.js +8 -0
  32. package/dist/utils/master-css.d.ts +6 -4
  33. package/dist/utils/master-css.js +6 -0
  34. package/dist/utils/resolve-class-node.d.ts +22 -18
  35. package/dist/utils/resolve-class-node.js +85 -0
  36. package/dist/utils/resolve-context.d.ts +16 -12
  37. package/dist/utils/resolve-context.js +69 -0
  38. package/dist/utils/with-visit-class-node.d.ts +8 -4
  39. package/dist/utils/with-visit-class-node.js +51 -0
  40. package/package.json +78 -1
  41. package/dist/configs/base.cjs +0 -11
  42. package/dist/configs/base.mjs +0 -9
  43. package/dist/configs/legacy.cjs +0 -17
  44. package/dist/configs/legacy.mjs +0 -15
  45. package/dist/configs/recommended.cjs +0 -15
  46. package/dist/configs/recommended.mjs +0 -13
  47. package/dist/create-rule.cjs +0 -7
  48. package/dist/create-rule.mjs +0 -5
  49. package/dist/index.cjs +0 -19
  50. package/dist/index.mjs +0 -17
  51. package/dist/plugin.cjs +0 -30
  52. package/dist/plugin.mjs +0 -27
  53. package/dist/rules/no-conflicting-classes.cjs +0 -101
  54. package/dist/rules/no-conflicting-classes.mjs +0 -99
  55. package/dist/rules/no-invalid-classes.cjs +0 -51
  56. package/dist/rules/no-invalid-classes.mjs +0 -49
  57. package/dist/rules/no-unapproved-raw-values.cjs +0 -77
  58. package/dist/rules/no-unapproved-raw-values.mjs +0 -75
  59. package/dist/rules/prefer-canonical-classes.cjs +0 -112
  60. package/dist/rules/prefer-canonical-classes.mjs +0 -110
  61. package/dist/rules/sort-classes.cjs +0 -53
  62. package/dist/rules/sort-classes.mjs +0 -51
  63. package/dist/settings-schema.cjs +0 -38
  64. package/dist/settings-schema.mjs +0 -32
  65. package/dist/settings.cjs +0 -10
  66. package/dist/settings.mjs +0 -8
  67. package/dist/utils/define-visitors.cjs +0 -125
  68. package/dist/utils/define-visitors.mjs +0 -123
  69. package/dist/utils/is-same-or-child-path.cjs +0 -10
  70. package/dist/utils/is-same-or-child-path.mjs +0 -8
  71. package/dist/utils/master-css.cjs +0 -14
  72. package/dist/utils/master-css.mjs +0 -7
  73. package/dist/utils/resolve-class-node.cjs +0 -98
  74. package/dist/utils/resolve-class-node.mjs +0 -96
  75. package/dist/utils/resolve-context.cjs +0 -78
  76. package/dist/utils/resolve-context.mjs +0 -76
  77. package/dist/utils/with-visit-class-node.cjs +0 -57
  78. 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.
@@ -1,3 +1,6 @@
1
- import type { Linter } from 'eslint';
1
+ import { Linter } from "eslint";
2
+
3
+ //#region src/configs/base.d.ts
2
4
  declare const _default: Linter.Config;
3
- export default _default;
5
+ //#endregion
6
+ export { _default as default };
@@ -0,0 +1,5 @@
1
+ import plugin from "../plugin.js";
2
+ //#region src/configs/base.ts
3
+ var base_default = { plugins: { "@master/css": plugin } };
4
+ //#endregion
5
+ export { base_default as default };
@@ -1,3 +1,6 @@
1
- import type { Linter } from 'eslint';
1
+ import { Linter } from "eslint";
2
+
3
+ //#region src/configs/legacy.d.ts
2
4
  declare const _default: Linter.LegacyConfig;
3
- export default _default;
5
+ //#endregion
6
+ export { _default as default };
@@ -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 };
@@ -1,3 +1,6 @@
1
- import type { Linter } from 'eslint';
1
+ import { Linter } from "eslint";
2
+
3
+ //#region src/configs/recommended.d.ts
2
4
  declare const _default: Linter.Config;
3
- export default _default;
5
+ //#endregion
6
+ export { _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 };
@@ -1,5 +1,12 @@
1
- import { ESLintUtils } from '@typescript-eslint/utils';
2
- declare const _default: <Options extends readonly unknown[], MessageIds extends string>({ meta, name, ...rule }: Readonly<ESLintUtils.RuleWithMetaAndName<Options, MessageIds, unknown>>) => ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener> & {
3
- name: string;
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
- export default _default;
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 settings from './settings';
2
- import type { Linter } from 'eslint';
3
- import type { TSESLint } from '@typescript-eslint/utils';
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
- configs: {
6
- legacy: unknown;
7
- base: Linter.Config;
8
- recommended: Linter.Config;
9
- };
10
- settings: typeof settings;
7
+ configs: {
8
+ legacy: unknown;
9
+ base: Linter.Config;
10
+ recommended: Linter.Config;
11
+ };
12
+ settings: typeof settings;
11
13
  };
12
- export default masterCSSPlugin;
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
@@ -1,3 +1,6 @@
1
- import type { TSESLint } from '@typescript-eslint/utils';
1
+ import { TSESLint } from "@typescript-eslint/utils";
2
+
3
+ //#region src/plugin.d.ts
2
4
  declare const plugin: TSESLint.Linter.Plugin;
3
- export default plugin;
5
+ //#endregion
6
+ export { plugin as default };
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
- name: string;
3
+ name: string;
3
4
  };
4
- export default _default;
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
- declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"disallowUnknownClass" | "invalidClass", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
2
- name: string;
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
- export default _default;
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
- allowRawValues: boolean;
3
- allowProperties: any[];
4
- allowedPatterns: any[];
3
+ allowRawValues: boolean;
4
+ allowProperties: any[];
5
+ allowedPatterns: any[];
5
6
  }], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
6
- name: string;
7
+ name: string;
7
8
  };
8
- export default _default;
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 { type CanonicalClassNameOptions } from '@master/css-lint';
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
- name: string;
5
+ name: string;
4
6
  };
5
- export default _default;
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
- name: string;
3
+ name: string;
3
4
  };
4
- export default _default;
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 type { JSONSchema4 } from '@typescript-eslint/utils/json-schema';
2
- export declare const masterCSSSettingsSchema: JSONSchema4;
3
- export declare const noInvalidClassesOptionsSchema: JSONSchema4;
4
- export default masterCSSSettingsSchema;
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 };
@@ -1,16 +1,19 @@
1
- import type { MasterCSSManifest } from './utils/master-css';
1
+ import { MasterCSSManifest } from "./utils/master-css.js";
2
+
3
+ //#region src/settings.d.ts
2
4
  declare const settings: {
3
- manifest: any;
4
- classAttributes: string[];
5
- classFunctions: string[];
6
- classDeclarations: string[];
7
- ignoredKeys: string[];
5
+ manifest: any;
6
+ classAttributes: string[];
7
+ classFunctions: string[];
8
+ classDeclarations: string[];
9
+ ignoredKeys: string[];
8
10
  };
9
- export default settings;
10
- export interface Settings {
11
- classAttributes?: string[];
12
- classFunctions?: string[];
13
- classDeclarations?: string[];
14
- ignoredKeys: string[];
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 };
@@ -0,0 +1,8 @@
1
+ import { defaultClassLintSettings } from "@master/css-lint";
2
+ //#region src/settings.ts
3
+ const settings = {
4
+ ...defaultClassLintSettings,
5
+ manifest: void 0
6
+ };
7
+ //#endregion
8
+ export { settings as default };