@master/eslint-plugin-css 2.0.0-rc.70 → 2.0.0-rc.72

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 (47) hide show
  1. package/README.md +68 -11
  2. package/dist/configs/recommended.cjs +4 -3
  3. package/dist/configs/recommended.mjs +4 -3
  4. package/dist/plugin.cjs +10 -6
  5. package/dist/plugin.mjs +10 -6
  6. package/dist/rules/no-conflicting-classes.cjs +101 -0
  7. package/dist/rules/no-conflicting-classes.d.ts +4 -0
  8. package/dist/rules/no-conflicting-classes.mjs +99 -0
  9. package/dist/rules/no-invalid-classes.cjs +51 -0
  10. package/dist/rules/{class-validation.d.ts → no-invalid-classes.d.ts} +1 -1
  11. package/dist/rules/no-invalid-classes.mjs +49 -0
  12. package/dist/rules/no-unapproved-raw-values.cjs +77 -0
  13. package/dist/rules/no-unapproved-raw-values.d.ts +8 -0
  14. package/dist/rules/no-unapproved-raw-values.mjs +75 -0
  15. package/dist/rules/prefer-canonical-classes.cjs +112 -0
  16. package/dist/rules/prefer-canonical-classes.d.ts +5 -0
  17. package/dist/rules/prefer-canonical-classes.mjs +110 -0
  18. package/dist/rules/{class-order.cjs → sort-classes.cjs} +10 -21
  19. package/dist/rules/{class-order.mjs → sort-classes.mjs} +10 -21
  20. package/dist/settings-schema.cjs +29 -23
  21. package/dist/settings-schema.d.ts +3 -2
  22. package/dist/settings-schema.mjs +25 -23
  23. package/dist/settings.cjs +2 -8
  24. package/dist/settings.d.ts +2 -2
  25. package/dist/settings.mjs +2 -8
  26. package/dist/utils/define-visitors.cjs +1 -1
  27. package/dist/utils/define-visitors.mjs +1 -1
  28. package/dist/utils/master-css.cjs +2 -82
  29. package/dist/utils/master-css.d.ts +0 -16
  30. package/dist/utils/master-css.mjs +1 -75
  31. package/dist/utils/resolve-class-node.cjs +18 -67
  32. package/dist/utils/resolve-class-node.d.ts +15 -7
  33. package/dist/utils/resolve-class-node.mjs +18 -67
  34. package/dist/utils/resolve-context.d.ts +1 -1
  35. package/package.json +1 -1
  36. package/dist/common.cjs +0 -7
  37. package/dist/common.d.ts +0 -2
  38. package/dist/common.mjs +0 -4
  39. package/dist/functions/filter-collision-classes.cjs +0 -29
  40. package/dist/functions/filter-collision-classes.d.ts +0 -2
  41. package/dist/functions/filter-collision-classes.mjs +0 -27
  42. package/dist/rules/class-collision.cjs +0 -76
  43. package/dist/rules/class-collision.d.ts +0 -4
  44. package/dist/rules/class-collision.mjs +0 -74
  45. package/dist/rules/class-validation.cjs +0 -60
  46. package/dist/rules/class-validation.mjs +0 -58
  47. /package/dist/rules/{class-order.d.ts → sort-classes.d.ts} +0 -0
@@ -1,94 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var css = require('@master/css');
4
3
  var cssValidator = require('@master/css-validator');
5
4
  var node_module = require('node:module');
6
- var UtilityType = require('@master/css-schema/utility-type');
7
5
 
8
6
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
7
  const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('utils/master-css.cjs', document.baseURI).href)));
10
8
  const defaultManifest = require$1('@master/css-preset/default-manifest.json');
11
- const CLASS_ATTRIBUTES = [
12
- 'class',
13
- 'className'
14
- ];
15
- const CLASS_DECLARATIONS = [];
16
- const CLASS_FUNCTIONS = [
17
- 'clsx',
18
- 'cva',
19
- 'ctl',
20
- 'cv',
21
- 'class',
22
- 'classnames',
23
- 'classVariant',
24
- 'styled(?:\\s+)?(?:\\.\\w+)?',
25
- 'classList(?:\\s+)?\\.(?:add|remove|toggle|replace)'
26
- ];
27
- const LAYER_ORDER = [
28
- 'theme',
29
- 'base',
30
- 'defaults',
31
- 'components',
32
- 'utilities'
33
- ];
34
- function stable(value) {
35
- if (!value || typeof value !== 'object') return JSON.stringify(value);
36
- if (Array.isArray(value)) return `[${value.map(stable).join(',')}]`;
37
- return `{${Object.entries(value).sort(([a], [b])=>a.localeCompare(b)).map(([key, item])=>`${JSON.stringify(key)}:${stable(item)}`).join(',')}}`;
38
- }
39
- function equalDeclarations(a, b) {
40
- if (!a || !b || typeof a !== 'object' || typeof b !== 'object') return stable(a) === stable(b);
41
- const aKeys = Object.keys(a).sort();
42
- const bKeys = Object.keys(b).sort();
43
- return stable(aKeys) === stable(bKeys);
44
- }
45
- function equalVariants(a, b) {
46
- const branchA = a.variantBranchKey;
47
- const branchB = b.variantBranchKey;
48
- return (branchA !== undefined || branchB !== undefined ? branchA === branchB : a.selectorText === b.selectorText) && a.layerName === b.layerName && stable(a.atRules) === stable(b.atRules);
49
- }
50
- function getLayerOrder(layerName) {
51
- const index = LAYER_ORDER.indexOf(layerName || 'utilities');
52
- return index === -1 ? LAYER_ORDER.length : index;
53
- }
54
- function getReadableGroupOrder(rule) {
55
- if (rule.atRules) return 3;
56
- if (rule.mode) return 2;
57
- if (rule.selectorNodes?.length) return 1;
58
- return 0;
59
- }
60
- function getReadableTypeOrder(rule) {
61
- if (rule.fixedClass) return 0;
62
- if (rule.type === UtilityType.Semantic) return 1;
63
- return 2;
64
- }
65
- function sortReadableClasses(classNames, css$1) {
66
- return [
67
- ...new Set(classNames)
68
- ].sort((a, b)=>{
69
- const ruleA = css$1.generate(a)[0];
70
- const ruleB = css$1.generate(b)[0];
71
- if (!ruleA && !ruleB) return a.localeCompare(b);
72
- if (!ruleA) return 1;
73
- if (!ruleB) return -1;
74
- const layerCmp = getLayerOrder(ruleA.layerName) - getLayerOrder(ruleB.layerName);
75
- if (layerCmp !== 0) return layerCmp;
76
- const groupCmp = getReadableGroupOrder(ruleA) - getReadableGroupOrder(ruleB);
77
- if (groupCmp !== 0) return groupCmp;
78
- const typeCmp = getReadableTypeOrder(ruleA) - getReadableTypeOrder(ruleB);
79
- if (typeCmp !== 0) return typeCmp;
80
- return css.compareRulePriority(ruleA, ruleB) || a.localeCompare(b);
81
- });
82
- }
83
9
 
84
10
  Object.defineProperty(exports, "createCSSWithNativeDeclarations", {
85
- enumerable: true,
86
- get: function () { return cssValidator.createCSSWithNativeDeclarations; }
11
+ enumerable: true,
12
+ get: function () { return cssValidator.createCSSWithNativeDeclarations; }
87
13
  });
88
- exports.CLASS_ATTRIBUTES = CLASS_ATTRIBUTES;
89
- exports.CLASS_DECLARATIONS = CLASS_DECLARATIONS;
90
- exports.CLASS_FUNCTIONS = CLASS_FUNCTIONS;
91
14
  exports.defaultManifest = defaultManifest;
92
- exports.equalDeclarations = equalDeclarations;
93
- exports.equalVariants = equalVariants;
94
- exports.sortReadableClasses = sortReadableClasses;
@@ -3,19 +3,3 @@ import { createCSSWithNativeDeclarations } from '@master/css-validator';
3
3
  export type { MasterCSS, MasterCSSManifest };
4
4
  declare const defaultManifest: MasterCSSManifest;
5
5
  export { createCSSWithNativeDeclarations, defaultManifest };
6
- export declare const CLASS_ATTRIBUTES: string[];
7
- export declare const CLASS_DECLARATIONS: string[];
8
- export declare const CLASS_FUNCTIONS: string[];
9
- export declare function equalDeclarations(a: unknown, b: unknown): boolean;
10
- export declare function equalVariants(a: {
11
- selectorText?: string;
12
- atRules?: unknown;
13
- layerName?: string;
14
- variantBranchKey?: string;
15
- }, b: {
16
- selectorText?: string;
17
- atRules?: unknown;
18
- layerName?: string;
19
- variantBranchKey?: string;
20
- }): boolean;
21
- export declare function sortReadableClasses(classNames: string[], css: MasterCSS): string[];
@@ -1,81 +1,7 @@
1
- import { compareRulePriority } from '@master/css';
2
1
  export { createCSSWithNativeDeclarations } from '@master/css-validator';
3
2
  import { createRequire } from 'node:module';
4
- import UtilityType from '@master/css-schema/utility-type';
5
3
 
6
4
  const require$1 = createRequire(import.meta.url);
7
5
  const defaultManifest = require$1('@master/css-preset/default-manifest.json');
8
- const CLASS_ATTRIBUTES = [
9
- 'class',
10
- 'className'
11
- ];
12
- const CLASS_DECLARATIONS = [];
13
- const CLASS_FUNCTIONS = [
14
- 'clsx',
15
- 'cva',
16
- 'ctl',
17
- 'cv',
18
- 'class',
19
- 'classnames',
20
- 'classVariant',
21
- 'styled(?:\\s+)?(?:\\.\\w+)?',
22
- 'classList(?:\\s+)?\\.(?:add|remove|toggle|replace)'
23
- ];
24
- const LAYER_ORDER = [
25
- 'theme',
26
- 'base',
27
- 'defaults',
28
- 'components',
29
- 'utilities'
30
- ];
31
- function stable(value) {
32
- if (!value || typeof value !== 'object') return JSON.stringify(value);
33
- if (Array.isArray(value)) return `[${value.map(stable).join(',')}]`;
34
- return `{${Object.entries(value).sort(([a], [b])=>a.localeCompare(b)).map(([key, item])=>`${JSON.stringify(key)}:${stable(item)}`).join(',')}}`;
35
- }
36
- function equalDeclarations(a, b) {
37
- if (!a || !b || typeof a !== 'object' || typeof b !== 'object') return stable(a) === stable(b);
38
- const aKeys = Object.keys(a).sort();
39
- const bKeys = Object.keys(b).sort();
40
- return stable(aKeys) === stable(bKeys);
41
- }
42
- function equalVariants(a, b) {
43
- const branchA = a.variantBranchKey;
44
- const branchB = b.variantBranchKey;
45
- return (branchA !== undefined || branchB !== undefined ? branchA === branchB : a.selectorText === b.selectorText) && a.layerName === b.layerName && stable(a.atRules) === stable(b.atRules);
46
- }
47
- function getLayerOrder(layerName) {
48
- const index = LAYER_ORDER.indexOf(layerName || 'utilities');
49
- return index === -1 ? LAYER_ORDER.length : index;
50
- }
51
- function getReadableGroupOrder(rule) {
52
- if (rule.atRules) return 3;
53
- if (rule.mode) return 2;
54
- if (rule.selectorNodes?.length) return 1;
55
- return 0;
56
- }
57
- function getReadableTypeOrder(rule) {
58
- if (rule.fixedClass) return 0;
59
- if (rule.type === UtilityType.Semantic) return 1;
60
- return 2;
61
- }
62
- function sortReadableClasses(classNames, css) {
63
- return [
64
- ...new Set(classNames)
65
- ].sort((a, b)=>{
66
- const ruleA = css.generate(a)[0];
67
- const ruleB = css.generate(b)[0];
68
- if (!ruleA && !ruleB) return a.localeCompare(b);
69
- if (!ruleA) return 1;
70
- if (!ruleB) return -1;
71
- const layerCmp = getLayerOrder(ruleA.layerName) - getLayerOrder(ruleB.layerName);
72
- if (layerCmp !== 0) return layerCmp;
73
- const groupCmp = getReadableGroupOrder(ruleA) - getReadableGroupOrder(ruleB);
74
- if (groupCmp !== 0) return groupCmp;
75
- const typeCmp = getReadableTypeOrder(ruleA) - getReadableTypeOrder(ruleB);
76
- if (typeCmp !== 0) return typeCmp;
77
- return compareRulePriority(ruleA, ruleB) || a.localeCompare(b);
78
- });
79
- }
80
6
 
81
- export { CLASS_ATTRIBUTES, CLASS_DECLARATIONS, CLASS_FUNCTIONS, defaultManifest, equalDeclarations, equalVariants, sortReadableClasses };
7
+ export { defaultManifest };
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var common = require('../common.cjs');
3
+ var cssLexer = require('@master/css-lexer');
4
4
 
5
5
  function resolveClassNode(node, context) {
6
6
  const { sourceCode } = context;
@@ -8,6 +8,7 @@ function resolveClassNode(node, context) {
8
8
  let raw = null;
9
9
  let start = null;
10
10
  let end = null;
11
+ let unescape = false;
11
12
  switch(node.type){
12
13
  case 'Literal':
13
14
  value = node.value;
@@ -47,6 +48,7 @@ function resolveClassNode(node, context) {
47
48
  raw = node.value.raw;
48
49
  start = node.range[0] + 1;
49
50
  end = node.range[1] - 1;
51
+ unescape = '`';
50
52
  break;
51
53
  default:
52
54
  return;
@@ -54,72 +56,22 @@ function resolveClassNode(node, context) {
54
56
  if (typeof value !== 'string') {
55
57
  return;
56
58
  }
57
- if (/^(['"`])(.*)\1$/.test(raw)) {
59
+ if (/^(['"`])([\s\S]*)\1$/.test(raw)) {
60
+ unescape = raw[0];
58
61
  raw = raw.slice(1, -1);
59
62
  start = start + 1;
60
63
  end = end - 1;
61
64
  }
62
- const nodes = [];
63
- const classValues = value.split(common.HALF_WIDTH_WHITESPACE_REGEX);
64
- const classRaws = raw.split(common.HALF_WIDTH_WHITESPACE_REGEX);
65
- const classValueRawMap = new Map();
66
- const classRawValueMap = new Map();
67
- for(let i = 0; i < classRaws.length; i++){
68
- classValueRawMap.set(classValues[i], classRaws[i]);
69
- classRawValueMap.set(classRaws[i], classValues[i]);
70
- }
71
- let lastIndex = 0;
72
- let match;
73
- while((match = common.HALF_WIDTH_WHITESPACE_GLOBAL_REGEX.exec(raw)) !== null){
74
- const spaceRaw = match[0];
75
- const spaceStart = match.index;
76
- const spaceEnd = spaceStart + spaceRaw.length;
77
- if (spaceStart > lastIndex) {
78
- const classRaw = raw.slice(lastIndex, spaceStart);
79
- const classValue = classRawValueMap.get(classRaw);
80
- if (!classValue) return;
81
- const startOffset = start + lastIndex;
82
- const endOffset = start + spaceStart;
83
- nodes.push({
84
- type: 'class',
85
- value: classValue,
86
- raw: classRaw,
87
- range: [
88
- startOffset,
89
- endOffset
90
- ],
91
- loc: {
92
- start: sourceCode.getLocFromIndex(startOffset),
93
- end: sourceCode.getLocFromIndex(endOffset)
94
- }
95
- });
96
- }
97
- const spaceStartOffset = start + spaceStart;
98
- const spaceEndOffset = start + spaceEnd;
99
- nodes.push({
100
- type: 'space',
101
- raw: spaceRaw,
102
- range: [
103
- spaceStartOffset,
104
- spaceEndOffset
105
- ],
106
- loc: {
107
- start: sourceCode.getLocFromIndex(spaceStartOffset),
108
- end: sourceCode.getLocFromIndex(spaceEndOffset)
109
- }
110
- });
111
- lastIndex = spaceEnd;
112
- }
113
- if (lastIndex < raw.length) {
114
- const classRaw = raw.slice(lastIndex);
115
- const classValue = classRawValueMap.get(classRaw);
116
- if (!classValue) return;
117
- const startOffset = start + lastIndex;
118
- const endOffset = start + raw.length;
119
- nodes.push({
120
- type: 'class',
121
- value: classValue,
122
- raw: classRaw,
65
+ const nodes = cssLexer.parseMasterCSSClassList(raw, {
66
+ preserveSpaces: true,
67
+ unescape
68
+ }).map((item)=>{
69
+ const startOffset = start + item.start;
70
+ const endOffset = start + item.end;
71
+ return {
72
+ type: item.type,
73
+ value: item.token,
74
+ raw: item.raw,
123
75
  range: [
124
76
  startOffset,
125
77
  endOffset
@@ -128,8 +80,8 @@ function resolveClassNode(node, context) {
128
80
  start: sourceCode.getLocFromIndex(startOffset),
129
81
  end: sourceCode.getLocFromIndex(endOffset)
130
82
  }
131
- });
132
- }
83
+ };
84
+ });
133
85
  const classNodes = nodes.filter((node)=>node.type === 'class');
134
86
  return {
135
87
  nodes,
@@ -137,8 +89,7 @@ function resolveClassNode(node, context) {
137
89
  end,
138
90
  raw,
139
91
  value,
140
- classRawValueMap,
141
- classValueRawMap,
92
+ unescape,
142
93
  classNodes,
143
94
  classValues: classNodes.map((node)=>node.value)
144
95
  };
@@ -1,12 +1,20 @@
1
1
  import { RuleContext } from '@typescript-eslint/utils/ts-eslint';
2
- export default function resolveClassNode(node: any, context: RuleContext<any, any[]>): {
3
- nodes: any[];
2
+ export type ResolvedClassListUnescape = string | false;
3
+ export interface ResolvedClassListNode {
4
+ type: 'class' | 'space';
5
+ value: string;
6
+ raw: string;
7
+ range: [number, number];
8
+ loc: any;
9
+ }
10
+ export interface ResolvedClassNode {
11
+ nodes: ResolvedClassListNode[];
4
12
  start: number;
5
13
  end: number;
6
14
  raw: string;
7
15
  value: string;
8
- classRawValueMap: Map<any, any>;
9
- classValueRawMap: Map<any, any>;
10
- classNodes: any[];
11
- classValues: any[];
12
- };
16
+ unescape: ResolvedClassListUnescape;
17
+ classNodes: ResolvedClassListNode[];
18
+ classValues: string[];
19
+ }
20
+ export default function resolveClassNode(node: any, context: RuleContext<any, any[]>): ResolvedClassNode | undefined;
@@ -1,4 +1,4 @@
1
- import { HALF_WIDTH_WHITESPACE_REGEX, HALF_WIDTH_WHITESPACE_GLOBAL_REGEX } from '../common.mjs';
1
+ import { parseMasterCSSClassList } from '@master/css-lexer';
2
2
 
3
3
  function resolveClassNode(node, context) {
4
4
  const { sourceCode } = context;
@@ -6,6 +6,7 @@ function resolveClassNode(node, context) {
6
6
  let raw = null;
7
7
  let start = null;
8
8
  let end = null;
9
+ let unescape = false;
9
10
  switch(node.type){
10
11
  case 'Literal':
11
12
  value = node.value;
@@ -45,6 +46,7 @@ function resolveClassNode(node, context) {
45
46
  raw = node.value.raw;
46
47
  start = node.range[0] + 1;
47
48
  end = node.range[1] - 1;
49
+ unescape = '`';
48
50
  break;
49
51
  default:
50
52
  return;
@@ -52,72 +54,22 @@ function resolveClassNode(node, context) {
52
54
  if (typeof value !== 'string') {
53
55
  return;
54
56
  }
55
- if (/^(['"`])(.*)\1$/.test(raw)) {
57
+ if (/^(['"`])([\s\S]*)\1$/.test(raw)) {
58
+ unescape = raw[0];
56
59
  raw = raw.slice(1, -1);
57
60
  start = start + 1;
58
61
  end = end - 1;
59
62
  }
60
- const nodes = [];
61
- const classValues = value.split(HALF_WIDTH_WHITESPACE_REGEX);
62
- const classRaws = raw.split(HALF_WIDTH_WHITESPACE_REGEX);
63
- const classValueRawMap = new Map();
64
- const classRawValueMap = new Map();
65
- for(let i = 0; i < classRaws.length; i++){
66
- classValueRawMap.set(classValues[i], classRaws[i]);
67
- classRawValueMap.set(classRaws[i], classValues[i]);
68
- }
69
- let lastIndex = 0;
70
- let match;
71
- while((match = HALF_WIDTH_WHITESPACE_GLOBAL_REGEX.exec(raw)) !== null){
72
- const spaceRaw = match[0];
73
- const spaceStart = match.index;
74
- const spaceEnd = spaceStart + spaceRaw.length;
75
- if (spaceStart > lastIndex) {
76
- const classRaw = raw.slice(lastIndex, spaceStart);
77
- const classValue = classRawValueMap.get(classRaw);
78
- if (!classValue) return;
79
- const startOffset = start + lastIndex;
80
- const endOffset = start + spaceStart;
81
- nodes.push({
82
- type: 'class',
83
- value: classValue,
84
- raw: classRaw,
85
- range: [
86
- startOffset,
87
- endOffset
88
- ],
89
- loc: {
90
- start: sourceCode.getLocFromIndex(startOffset),
91
- end: sourceCode.getLocFromIndex(endOffset)
92
- }
93
- });
94
- }
95
- const spaceStartOffset = start + spaceStart;
96
- const spaceEndOffset = start + spaceEnd;
97
- nodes.push({
98
- type: 'space',
99
- raw: spaceRaw,
100
- range: [
101
- spaceStartOffset,
102
- spaceEndOffset
103
- ],
104
- loc: {
105
- start: sourceCode.getLocFromIndex(spaceStartOffset),
106
- end: sourceCode.getLocFromIndex(spaceEndOffset)
107
- }
108
- });
109
- lastIndex = spaceEnd;
110
- }
111
- if (lastIndex < raw.length) {
112
- const classRaw = raw.slice(lastIndex);
113
- const classValue = classRawValueMap.get(classRaw);
114
- if (!classValue) return;
115
- const startOffset = start + lastIndex;
116
- const endOffset = start + raw.length;
117
- nodes.push({
118
- type: 'class',
119
- value: classValue,
120
- raw: classRaw,
63
+ const nodes = parseMasterCSSClassList(raw, {
64
+ preserveSpaces: true,
65
+ unescape
66
+ }).map((item)=>{
67
+ const startOffset = start + item.start;
68
+ const endOffset = start + item.end;
69
+ return {
70
+ type: item.type,
71
+ value: item.token,
72
+ raw: item.raw,
121
73
  range: [
122
74
  startOffset,
123
75
  endOffset
@@ -126,8 +78,8 @@ function resolveClassNode(node, context) {
126
78
  start: sourceCode.getLocFromIndex(startOffset),
127
79
  end: sourceCode.getLocFromIndex(endOffset)
128
80
  }
129
- });
130
- }
81
+ };
82
+ });
131
83
  const classNodes = nodes.filter((node)=>node.type === 'class');
132
84
  return {
133
85
  nodes,
@@ -135,8 +87,7 @@ function resolveClassNode(node, context) {
135
87
  end,
136
88
  raw,
137
89
  value,
138
- classRawValueMap,
139
- classValueRawMap,
90
+ unescape,
140
91
  classNodes,
141
92
  classValues: classNodes.map((node)=>node.value)
142
93
  };
@@ -2,11 +2,11 @@ import type { RuleContext } from '@typescript-eslint/utils/ts-eslint';
2
2
  import { MasterCSS } from './master-css';
3
3
  export default function resolveContext(context: RuleContext<any, any[]>): {
4
4
  settings: {
5
+ manifest: any;
5
6
  classAttributes: string[];
6
7
  classFunctions: string[];
7
8
  classDeclarations: string[];
8
9
  ignoredKeys: string[];
9
- manifest: any;
10
10
  };
11
11
  options: any;
12
12
  css: MasterCSS;
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@master/eslint-plugin-css","type":"module","scripts":{"build":"techor build \"src/**/*.{js,ts}\"","dev":"pnpm build --watch","test":"vitest","type-check":"tsc --noEmit","lint":"eslint"},"keywords":["mastercss","eslint","eslintplugin"],"license":"MIT","description":"Master CSS ESLint Plugin","author":"Aoyue Design LLC.","funding":"https://rc.css.master.co/sponsor","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/eslint-plugin"},"sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.mjs","jsnext:main":"./dist/index.mjs","esnext":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./configs/*":{"types":"./dist/configs/*.d.ts","import":"./dist/configs/*.mjs","require":"./dist/configs/*.cjs"}},"files":["dist"],"publishConfig":{"access":"public","provenance":true},"dependencies":{"@master/css":"^2.0.0-rc.70","@master/css-project":"^2.0.0-rc.70","@master/css-preset":"^2.0.0-rc.70","@master/css-validator":"^2.0.0-rc.70","@typescript-eslint/utils":"^8.61.1","typescript-eslint":"^8.61.1","@master/css-schema":"^2.0.0-rc.70"},"devDependencies":{"@angular-eslint/template-parser":"^21.4.0","@angular/compiler":"^21.2.17","@typescript-eslint/rule-tester":"^8.61.1","eslint":"^10.5.0","eslint-plugin-markdown":"^5.1.0","eslint-plugin-mdx":"^3.8.1","svelte-eslint-parser":"^1.8.0","ts-node":"^10.9.2","vue-eslint-parser":"^10.4.1"},"version":"2.0.0-rc.70"}
1
+ {"name":"@master/eslint-plugin-css","type":"module","scripts":{"build":"techor build \"src/**/*.{js,ts}\"","dev":"pnpm build --watch","test":"vitest","type-check":"tsc --noEmit","lint":"eslint"},"keywords":["mastercss","eslint","eslintplugin"],"license":"MIT","description":"Master CSS ESLint Plugin","author":"Aoyue Design LLC.","funding":"https://rc.css.master.co/sponsor","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/eslint-plugin"},"sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.mjs","jsnext:main":"./dist/index.mjs","esnext":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./configs/*":{"types":"./dist/configs/*.d.ts","import":"./dist/configs/*.mjs","require":"./dist/configs/*.cjs"}},"files":["dist"],"publishConfig":{"access":"public","provenance":true},"dependencies":{"@master/css":"^2.0.0-rc.72","@master/css-lexer":"^2.0.0-rc.72","@master/css-lint":"^2.0.0-rc.72","@master/css-project":"^2.0.0-rc.72","@master/css-preset":"^2.0.0-rc.72","@master/css-validator":"^2.0.0-rc.72","@typescript-eslint/utils":"^8.61.1","typescript-eslint":"^8.61.1"},"devDependencies":{"@angular-eslint/template-parser":"^21.4.0","@master/css-schema":"^2.0.0-rc.72","@angular/compiler":"^21.2.17","@typescript-eslint/rule-tester":"^8.61.1","eslint":"^10.5.0","eslint-mdx":"^3.8.1","eslint-plugin-markdown":"^5.1.0","eslint-plugin-mdx":"^3.8.1","svelte-eslint-parser":"^1.8.0","ts-node":"^10.9.2","vue-eslint-parser":"^10.4.1"},"version":"2.0.0-rc.72"}
package/dist/common.cjs DELETED
@@ -1,7 +0,0 @@
1
- 'use strict';
2
-
3
- const HALF_WIDTH_WHITESPACE_REGEX = /([\t\n\f\r ]+)/;
4
- const HALF_WIDTH_WHITESPACE_GLOBAL_REGEX = /([\t\n\f\r ]+)/g;
5
-
6
- exports.HALF_WIDTH_WHITESPACE_GLOBAL_REGEX = HALF_WIDTH_WHITESPACE_GLOBAL_REGEX;
7
- exports.HALF_WIDTH_WHITESPACE_REGEX = HALF_WIDTH_WHITESPACE_REGEX;
package/dist/common.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare const HALF_WIDTH_WHITESPACE_REGEX: RegExp;
2
- export declare const HALF_WIDTH_WHITESPACE_GLOBAL_REGEX: RegExp;
package/dist/common.mjs DELETED
@@ -1,4 +0,0 @@
1
- const HALF_WIDTH_WHITESPACE_REGEX = /([\t\n\f\r ]+)/;
2
- const HALF_WIDTH_WHITESPACE_GLOBAL_REGEX = /([\t\n\f\r ]+)/g;
3
-
4
- export { HALF_WIDTH_WHITESPACE_GLOBAL_REGEX, HALF_WIDTH_WHITESPACE_REGEX };
@@ -1,29 +0,0 @@
1
- 'use strict';
2
-
3
- var cssValidator = require('@master/css-validator');
4
- var masterCss = require('../utils/master-css.cjs');
5
-
6
- function filterCollisionClasses(classNames, css) {
7
- const validRules = classNames.map((eachClassName)=>cssValidator.generateValidRules(eachClassName, css)[0]).filter(Boolean);
8
- const collisionClassesRecord = {};
9
- for(let i = 0; i < classNames.length; i++){
10
- const className = classNames[i];
11
- const rule = validRules.find((eachValidRule)=>eachValidRule.name === className);
12
- const collisionClasses = [];
13
- if (rule) {
14
- for(let j = 0; j < classNames.length; j++){
15
- const compareClassName = classNames[j];
16
- const compareRule = validRules.find((eachValidRule)=>eachValidRule.name === compareClassName);
17
- if (i !== j && compareRule && masterCss.equalDeclarations(rule.declarations, compareRule.declarations) && masterCss.equalVariants(rule, compareRule)) {
18
- collisionClasses.push(compareClassName);
19
- }
20
- }
21
- if (collisionClasses.length > 0) {
22
- collisionClassesRecord[className] = collisionClasses;
23
- }
24
- }
25
- }
26
- return collisionClassesRecord;
27
- }
28
-
29
- module.exports = filterCollisionClasses;
@@ -1,2 +0,0 @@
1
- import { MasterCSS } from '@master/css';
2
- export default function filterCollisionClasses(classNames: string[], css: MasterCSS): Record<string, string[]>;
@@ -1,27 +0,0 @@
1
- import { generateValidRules } from '@master/css-validator';
2
- import { equalDeclarations, equalVariants } from '../utils/master-css.mjs';
3
-
4
- function filterCollisionClasses(classNames, css) {
5
- const validRules = classNames.map((eachClassName)=>generateValidRules(eachClassName, css)[0]).filter(Boolean);
6
- const collisionClassesRecord = {};
7
- for(let i = 0; i < classNames.length; i++){
8
- const className = classNames[i];
9
- const rule = validRules.find((eachValidRule)=>eachValidRule.name === className);
10
- const collisionClasses = [];
11
- if (rule) {
12
- for(let j = 0; j < classNames.length; j++){
13
- const compareClassName = classNames[j];
14
- const compareRule = validRules.find((eachValidRule)=>eachValidRule.name === compareClassName);
15
- if (i !== j && compareRule && equalDeclarations(rule.declarations, compareRule.declarations) && equalVariants(rule, compareRule)) {
16
- collisionClasses.push(compareClassName);
17
- }
18
- }
19
- if (collisionClasses.length > 0) {
20
- collisionClassesRecord[className] = collisionClasses;
21
- }
22
- }
23
- }
24
- return collisionClassesRecord;
25
- }
26
-
27
- export { filterCollisionClasses as default };
@@ -1,76 +0,0 @@
1
- 'use strict';
2
-
3
- var defineVisitors = require('../utils/define-visitors.cjs');
4
- var resolveContext = require('../utils/resolve-context.cjs');
5
- var filterCollisionClasses = require('../functions/filter-collision-classes.cjs');
6
- var createRule = require('../create-rule.cjs');
7
- var settingsSchema = require('../settings-schema.cjs');
8
-
9
- var classCollision = createRule({
10
- name: 'class-collision-detection',
11
- meta: {
12
- type: 'layout',
13
- docs: {
14
- description: 'Avoid applying classes with the same declarations'
15
- },
16
- messages: {
17
- collisionClass: '{{message}}'
18
- },
19
- fixable: 'code',
20
- schema: [
21
- settingsSchema
22
- ]
23
- },
24
- defaultOptions: [],
25
- create (context) {
26
- const { settings, css } = resolveContext(context);
27
- return defineVisitors({
28
- context,
29
- settings
30
- }, (node, { raw, start, end, nodes, classNodes, classValues })=>{
31
- const collisionClassesRecord = filterCollisionClasses(classValues, css);
32
- for(const className in collisionClassesRecord){
33
- const collisionClasses = collisionClassesRecord[className];
34
- const collisionClassNamesMsg = collisionClasses.map((x)=>`"${x}"`).join(' and ');
35
- const classNode = classNodes.find((node)=>node.value === className);
36
- const fixedNodes = [
37
- ...nodes
38
- ];
39
- const removeCollision = (removedClassNode)=>{
40
- for(let i = 0; i < fixedNodes.length; i++){
41
- const fixedNode = fixedNodes[i];
42
- const target = fixedNode === removedClassNode;
43
- if (target) {
44
- const prev = fixedNodes[i - 1];
45
- const isSpaceBefore = prev && prev.type === 'space';
46
- fixedNodes.splice(i, 1);
47
- if (isSpaceBefore) {
48
- fixedNodes.splice(i - 1, 1);
49
- }
50
- }
51
- }
52
- };
53
- collisionClasses.forEach((collisionClass)=>{
54
- const collisionNode = classNodes.find((node)=>node.value === collisionClass);
55
- removeCollision(collisionNode);
56
- });
57
- const fixedRaw = fixedNodes.map((node)=>node.raw).join('');
58
- context.report({
59
- loc: classNode.loc,
60
- messageId: 'collisionClass',
61
- data: {
62
- message: `"${className}" applies the same declarations as ${collisionClassNamesMsg}.`
63
- },
64
- fix: function(fixer) {
65
- return fixer.replaceTextRange([
66
- start,
67
- end
68
- ], fixedRaw);
69
- }
70
- });
71
- }
72
- });
73
- }
74
- });
75
-
76
- module.exports = classCollision;