@master/eslint-plugin-css 2.0.0-rc.15 → 2.0.0-rc.16

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 (83) hide show
  1. package/dist/configs/config.cjs +16 -0
  2. package/dist/configs/config.mjs +14 -1
  3. package/dist/configs/flat.cjs +13 -0
  4. package/dist/configs/flat.mjs +11 -1
  5. package/dist/configs/recommended.cjs +12 -0
  6. package/dist/configs/recommended.mjs +10 -1
  7. package/dist/index.cjs +15 -0
  8. package/dist/index.mjs +13 -1
  9. package/dist/plugin.cjs +18 -0
  10. package/dist/plugin.mjs +16 -1
  11. package/dist/rules/class-collision.cjs +103 -0
  12. package/dist/rules/class-collision.mjs +101 -1
  13. package/dist/rules/class-order.cjs +196 -0
  14. package/dist/rules/class-order.mjs +194 -1
  15. package/dist/rules/class-validation.cjs +91 -0
  16. package/dist/rules/class-validation.mjs +89 -1
  17. package/dist/settings.cjs +13 -0
  18. package/dist/settings.mjs +11 -1
  19. package/dist/utils/are-declarations-equal.cjs +21 -0
  20. package/dist/utils/are-declarations-equal.mjs +19 -1
  21. package/dist/utils/define-visitors.cjs +74 -0
  22. package/dist/utils/define-visitors.mjs +72 -1
  23. package/dist/utils/extract-classnames-from-value.cjs +34 -0
  24. package/dist/utils/extract-classnames-from-value.mjs +32 -1
  25. package/dist/utils/extract-range-from-node.cjs +18 -0
  26. package/dist/utils/extract-range-from-node.mjs +16 -1
  27. package/dist/utils/extract-value-from-node.cjs +23 -0
  28. package/dist/utils/extract-value-from-node.mjs +21 -1
  29. package/dist/utils/find-loc.cjs +40 -0
  30. package/dist/utils/find-loc.mjs +38 -1
  31. package/dist/utils/get-mastercss.cjs +16 -0
  32. package/dist/utils/get-mastercss.d.ts +1 -1
  33. package/dist/utils/get-mastercss.mjs +14 -1
  34. package/dist/utils/get-template-element-body.cjs +12 -0
  35. package/dist/utils/get-template-element-body.mjs +10 -1
  36. package/dist/utils/get-template-element-prefix.cjs +11 -0
  37. package/dist/utils/get-template-element-prefix.mjs +9 -1
  38. package/dist/utils/get-template-element-suffix.cjs +10 -0
  39. package/dist/utils/get-template-element-suffix.mjs +8 -1
  40. package/dist/utils/parse-node-recursive.cjs +122 -0
  41. package/dist/utils/parse-node-recursive.mjs +120 -1
  42. package/dist/utils/reorder-valid-classes-action.cjs +9 -0
  43. package/dist/utils/reorder-valid-classes-action.mjs +7 -1
  44. package/dist/utils/resolve-context.cjs +13 -0
  45. package/dist/utils/resolve-context.mjs +11 -1
  46. package/dist/utils/valid-rules-action.cjs +9 -0
  47. package/dist/utils/valid-rules-action.mjs +7 -1
  48. package/dist/utils/validate-action.cjs +9 -0
  49. package/dist/utils/validate-action.mjs +7 -1
  50. package/dist/utils/workers/reorder-valid-classes.cjs +15 -0
  51. package/dist/utils/workers/reorder-valid-classes.mjs +13 -1
  52. package/dist/utils/workers/valid-rules.cjs +23 -0
  53. package/dist/utils/workers/valid-rules.mjs +21 -1
  54. package/dist/utils/workers/validate.cjs +15 -0
  55. package/dist/utils/workers/validate.mjs +13 -1
  56. package/package.json +1 -1
  57. package/dist/configs/config.js +0 -1
  58. package/dist/configs/flat.js +0 -1
  59. package/dist/configs/recommended.js +0 -1
  60. package/dist/index.js +0 -1
  61. package/dist/plugin.js +0 -1
  62. package/dist/rules/class-collision.js +0 -1
  63. package/dist/rules/class-order.js +0 -1
  64. package/dist/rules/class-validation.js +0 -1
  65. package/dist/settings.js +0 -1
  66. package/dist/utils/are-declarations-equal.js +0 -1
  67. package/dist/utils/define-visitors.js +0 -1
  68. package/dist/utils/extract-classnames-from-value.js +0 -1
  69. package/dist/utils/extract-range-from-node.js +0 -1
  70. package/dist/utils/extract-value-from-node.js +0 -1
  71. package/dist/utils/find-loc.js +0 -1
  72. package/dist/utils/get-mastercss.js +0 -1
  73. package/dist/utils/get-template-element-body.js +0 -1
  74. package/dist/utils/get-template-element-prefix.js +0 -1
  75. package/dist/utils/get-template-element-suffix.js +0 -1
  76. package/dist/utils/parse-node-recursive.js +0 -1
  77. package/dist/utils/reorder-valid-classes-action.js +0 -1
  78. package/dist/utils/resolve-context.js +0 -1
  79. package/dist/utils/valid-rules-action.js +0 -1
  80. package/dist/utils/validate-action.js +0 -1
  81. package/dist/utils/workers/reorder-valid-classes.js +0 -1
  82. package/dist/utils/workers/valid-rules.js +0 -1
  83. package/dist/utils/workers/validate.js +0 -1
@@ -1 +1,194 @@
1
- import T from"../utils/define-visitors.mjs";import b from"../utils/resolve-context.mjs";import v from"../utils/get-template-element-body.mjs";import R from"../utils/get-template-element-suffix.mjs";import I from"../utils/get-template-element-prefix.mjs";import k from"../utils/extract-value-from-node.mjs";import L from"../utils/extract-range-from-node.mjs";import V from"../utils/extract-classnames-from-value.mjs";import _ from"../utils/find-loc.mjs";import $ from"../utils/reorder-valid-classes-action.mjs";var D={meta:{docs:{description:"Enforce a consistent and logical order of classes",category:"Stylistic Issues",recommended:!1,url:"https://rc.css.master.co/docs/code-linting#consistent-class-order"},messages:{invalidClassOrder:"No consistent class order followed."},fixable:"code",schema:[{type:"object",properties:{calleeMatching:{type:"string"},classMatching:{type:"string"},ignoredKeys:{type:"array",items:{type:"string",minLength:0},uniqueItems:!0},config:{type:["string","object"]}}}]},create:function(u){const{options:M,settings:x}=b(u),N=u.sourceCode,a=(r,t=null)=>{let s=null,o=null,c=null,d="",g="",p=[];if(t===null){s=k(r);const e=L(r);r.type==="TextAttribute"?(o=e[0],c=e[1]):(o=e[0]+1,c=e[1]-1)}else switch(t.type){case"Identifier":return;case"TemplateLiteral":t.expressions.forEach(l=>{a(r,l)}),s=N.getText(t),s=s.substring(1,s.length-1),p=s.match(/\$\{(?:(?<!\\\\)(['"`]).*?(?<!\\\\)\1|[^}])*?\}/g)??[];for(let l=0;l<p.length;l++)s=s.replace(p[l],`EXPRESSION_STRING_NUM_${l}`);o=t.range[0]+1,c=t.range[1]-1;break;case"ConditionalExpression":a(r,t.consequent),a(r,t.alternate);return;case"LogicalExpression":a(r,t.right);return;case"ArrayExpression":t.elements.forEach(l=>{a(r,l)});return;case"ObjectExpression":const e=r.callee&&r.callee.name==="classnames",f=r.key&&r.key.type==="VDirectiveKey";t.properties.forEach(l=>{const E=e||f?l.key:l.value;a(r,E)});return;case"Property":a(r,t.key);break;case"Literal":s=t.value,o=t.range[0]+1,c=t.range[1]-1;break;case"SvelteLiteral":if(s=t.value,s==="")return;o=t.range[0],c=t.range[1];break;case"TemplateElement":if(s=t.value.raw,s==="")return;o=t.range[0],c=t.range[1];const n=u.sourceCode.getText(t);d=I(n,s),g=R(n,s),s=v(n,d,g);break}const{classNames:y,whitespaces:h,headSpace:S,tailSpace:C}=V(s);if(y.length<=1)return;let m=$(y,x.config);m=y.filter(e=>!m.includes(e)).concat(m).filter(e=>e.trim()!=="");let i="";for(let e=0;e<m.length;e++){const f=h[e]??"",n=m[e];i+=S?`${f}${n}`:`${n}${f}`,n&&(!C&&e===m.length-1&&(i=i.replace(/\s+$/,"")),S&&C&&e===m.length-1&&(i+=h[h.length-1]??""))}for(let e=0;e<p.length;e++)s=s.replace(`EXPRESSION_STRING_NUM_${e}`,p[e]),i=i.replace(`EXPRESSION_STRING_NUM_${e}`,p[e]);if(s!==i){i=d+i+g;const e=N.lines,f=r.loc.start.line,n=r.loc.end.line,l={loc:_(s,e,f,n),messageId:"invalidClassOrder",fix:function(E){return E.replaceTextRange([o,c],i)}};u.report(l)}};return T({context:u,settings:x},a)}};export{D as default};
1
+ import defineVisitors from '../utils/define-visitors.mjs';
2
+ import resolveContext from '../utils/resolve-context.mjs';
3
+ import getTemplateElementBody from '../utils/get-template-element-body.mjs';
4
+ import getTemplateElementSuffix from '../utils/get-template-element-suffix.mjs';
5
+ import getTemplateElementPrefix from '../utils/get-template-element-prefix.mjs';
6
+ import extractValueFromNode from '../utils/extract-value-from-node.mjs';
7
+ import extractRangeFromNode from '../utils/extract-range-from-node.mjs';
8
+ import extractClassnamesFromValue from '../utils/extract-classnames-from-value.mjs';
9
+ import findLoc from '../utils/find-loc.mjs';
10
+ import reorderValidClassesAction from '../utils/reorder-valid-classes-action.mjs';
11
+
12
+ var classOrder = {
13
+ meta: {
14
+ docs: {
15
+ description: 'Enforce a consistent and logical order of classes',
16
+ category: 'Stylistic Issues',
17
+ recommended: false,
18
+ url: 'https://rc.css.master.co/docs/code-linting#consistent-class-order'
19
+ },
20
+ messages: {
21
+ invalidClassOrder: 'No consistent class order followed.'
22
+ },
23
+ fixable: 'code',
24
+ schema: [
25
+ {
26
+ type: 'object',
27
+ properties: {
28
+ calleeMatching: {
29
+ type: 'string'
30
+ },
31
+ classMatching: {
32
+ type: 'string'
33
+ },
34
+ ignoredKeys: {
35
+ type: 'array',
36
+ items: {
37
+ type: 'string',
38
+ minLength: 0
39
+ },
40
+ uniqueItems: true
41
+ },
42
+ config: {
43
+ type: [
44
+ 'string',
45
+ 'object'
46
+ ]
47
+ }
48
+ }
49
+ }
50
+ ]
51
+ },
52
+ create: function(context) {
53
+ const { options, settings } = resolveContext(context);
54
+ const sourceCode = context.sourceCode;
55
+ const visitNode = (node, arg = null)=>{
56
+ let originalClassNamesValue = null;
57
+ let start = null;
58
+ let end = null;
59
+ let prefix = '';
60
+ let suffix = '';
61
+ let expStrings = [];
62
+ if (arg === null) {
63
+ originalClassNamesValue = extractValueFromNode(node);
64
+ const range = extractRangeFromNode(node);
65
+ if (node.type === 'TextAttribute') {
66
+ start = range[0];
67
+ end = range[1];
68
+ } else {
69
+ start = range[0] + 1;
70
+ end = range[1] - 1;
71
+ }
72
+ } else {
73
+ switch(arg.type){
74
+ case 'Identifier':
75
+ return;
76
+ case 'TemplateLiteral':
77
+ arg.expressions.forEach((exp)=>{
78
+ visitNode(node, exp);
79
+ });
80
+ originalClassNamesValue = sourceCode.getText(arg);
81
+ originalClassNamesValue = originalClassNamesValue.substring(1, originalClassNamesValue.length - 1);
82
+ expStrings = originalClassNamesValue.match(/\$\{(?:(?<!\\\\)(['"`]).*?(?<!\\\\)\1|[^}])*?\}/g) ?? [];
83
+ for(let i = 0; i < expStrings.length; i++){
84
+ originalClassNamesValue = originalClassNamesValue.replace(expStrings[i], `EXPRESSION_STRING_NUM_${i}`);
85
+ }
86
+ start = arg.range[0] + 1;
87
+ end = arg.range[1] - 1;
88
+ break;
89
+ case 'ConditionalExpression':
90
+ visitNode(node, arg.consequent);
91
+ visitNode(node, arg.alternate);
92
+ return;
93
+ case 'LogicalExpression':
94
+ visitNode(node, arg.right);
95
+ return;
96
+ case 'ArrayExpression':
97
+ arg.elements.forEach((el)=>{
98
+ visitNode(node, el);
99
+ });
100
+ return;
101
+ case 'ObjectExpression':
102
+ const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
103
+ const isVue = node.key && node.key.type === 'VDirectiveKey';
104
+ arg.properties.forEach((prop)=>{
105
+ const propVal = isUsedByClassNamesPlugin || isVue ? prop.key : prop.value;
106
+ visitNode(node, propVal);
107
+ });
108
+ return;
109
+ case 'Property':
110
+ visitNode(node, arg.key);
111
+ break;
112
+ case 'Literal':
113
+ originalClassNamesValue = arg.value;
114
+ start = arg.range[0] + 1;
115
+ end = arg.range[1] - 1;
116
+ break;
117
+ case 'SvelteLiteral':
118
+ originalClassNamesValue = arg.value;
119
+ if (originalClassNamesValue === '') {
120
+ return;
121
+ }
122
+ start = arg.range[0];
123
+ end = arg.range[1];
124
+ break;
125
+ case 'TemplateElement':
126
+ originalClassNamesValue = arg.value.raw;
127
+ if (originalClassNamesValue === '') {
128
+ return;
129
+ }
130
+ start = arg.range[0];
131
+ end = arg.range[1];
132
+ // https://github.com/eslint/eslint/issues/13360
133
+ // The problem is that range computation includes the backticks (`test`)
134
+ // but value.raw does not include them, so there is a mismatch.
135
+ // start/end does not include the backticks, therefore it matches value.raw.
136
+ const txt = context.sourceCode.getText(arg);
137
+ prefix = getTemplateElementPrefix(txt, originalClassNamesValue);
138
+ suffix = getTemplateElementSuffix(txt, originalClassNamesValue);
139
+ originalClassNamesValue = getTemplateElementBody(txt, prefix, suffix);
140
+ break;
141
+ }
142
+ }
143
+ const { classNames, whitespaces, headSpace, tailSpace } = extractClassnamesFromValue(originalClassNamesValue);
144
+ if (classNames.length <= 1) {
145
+ // Don't run sorting for a single or empty className
146
+ return;
147
+ }
148
+ let orderedClassNames = reorderValidClassesAction(classNames, settings.config);
149
+ orderedClassNames = classNames.filter((x)=>!orderedClassNames.includes(x)).concat(orderedClassNames).filter((x)=>x.trim() !== '');
150
+ // Generates the validated/sorted attribute value
151
+ let validatedClassNamesValue = '';
152
+ for(let i = 0; i < orderedClassNames.length; i++){
153
+ const w = whitespaces[i] ?? '';
154
+ const cls = orderedClassNames[i];
155
+ validatedClassNamesValue += headSpace ? `${w}${cls}` : `${cls}${w}`;
156
+ if (cls) {
157
+ if (!tailSpace && i === orderedClassNames.length - 1) {
158
+ validatedClassNamesValue = validatedClassNamesValue.replace(/\s+$/, '');
159
+ }
160
+ if (headSpace && tailSpace && i === orderedClassNames.length - 1) {
161
+ validatedClassNamesValue += whitespaces[whitespaces.length - 1] ?? '';
162
+ }
163
+ }
164
+ }
165
+ for(let i = 0; i < expStrings.length; i++){
166
+ originalClassNamesValue = originalClassNamesValue.replace(`EXPRESSION_STRING_NUM_${i}`, expStrings[i]);
167
+ validatedClassNamesValue = validatedClassNamesValue.replace(`EXPRESSION_STRING_NUM_${i}`, expStrings[i]);
168
+ }
169
+ if (originalClassNamesValue !== validatedClassNamesValue) {
170
+ validatedClassNamesValue = prefix + validatedClassNamesValue + suffix;
171
+ const sourceCodeLines = sourceCode.lines;
172
+ const nodeStartLine = node.loc.start.line;
173
+ const nodeEndLine = node.loc.end.line;
174
+ const descriptor = {
175
+ loc: findLoc(originalClassNamesValue, sourceCodeLines, nodeStartLine, nodeEndLine),
176
+ messageId: 'invalidClassOrder',
177
+ fix: function(fixer) {
178
+ return fixer.replaceTextRange([
179
+ start,
180
+ end
181
+ ], validatedClassNamesValue);
182
+ }
183
+ };
184
+ context.report(descriptor);
185
+ }
186
+ };
187
+ return defineVisitors({
188
+ context,
189
+ settings
190
+ }, visitNode);
191
+ }
192
+ };
193
+
194
+ export { classOrder as default };
@@ -0,0 +1,91 @@
1
+ 'use strict';
2
+
3
+ var defineVisitors = require('../utils/define-visitors.cjs');
4
+ var resolveContext = require('../utils/resolve-context.cjs');
5
+ var findLoc = require('../utils/find-loc.cjs');
6
+ var parseNodeRecursive = require('../utils/parse-node-recursive.cjs');
7
+ var validateAction = require('../utils/validate-action.cjs');
8
+
9
+ var classValidation = {
10
+ meta: {
11
+ docs: {
12
+ description: 'Detect syntax errors early when writing classes',
13
+ category: 'Stylistic Issues',
14
+ recommended: false,
15
+ url: 'https://rc.css.master.co/docs/code-linting#syntax-error-checks'
16
+ },
17
+ messages: {
18
+ invalidClass: '{{message}}',
19
+ disallowUnknownClass: '{{message}}'
20
+ },
21
+ fixable: null,
22
+ schema: [
23
+ {
24
+ type: 'object',
25
+ properties: {
26
+ calleeMatching: {
27
+ type: 'string'
28
+ },
29
+ classMatching: {
30
+ type: 'string'
31
+ },
32
+ ignoredKeys: {
33
+ type: 'array',
34
+ items: {
35
+ type: 'string',
36
+ minLength: 0
37
+ },
38
+ uniqueItems: true
39
+ },
40
+ config: {
41
+ type: [
42
+ 'string',
43
+ 'object'
44
+ ]
45
+ }
46
+ }
47
+ }
48
+ ]
49
+ },
50
+ create: function(context) {
51
+ const { options, settings } = resolveContext(context);
52
+ const visitNode = (node, arg = null)=>{
53
+ parseNodeRecursive.parseNodeRecursive(node, arg, (classNames, node)=>{
54
+ const sourceCode = context.sourceCode;
55
+ const sourceCodeLines = sourceCode.lines;
56
+ const nodeStartLine = node.loc.start.line;
57
+ const nodeEndLine = node.loc.end.line;
58
+ for (const className of classNames){
59
+ const { isMasterCSS, errors } = validateAction(className, settings.config);
60
+ if (errors.length > 0) {
61
+ for (const error of errors){
62
+ if (isMasterCSS) {
63
+ context.report({
64
+ loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeEndLine),
65
+ messageId: 'invalidClass',
66
+ data: {
67
+ message: error.message + '.'
68
+ }
69
+ });
70
+ } else if (options.disallowUnknownClass) {
71
+ context.report({
72
+ loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeEndLine),
73
+ messageId: 'disallowUnknownClass',
74
+ data: {
75
+ message: `"${className}" is not a valid or known class.`
76
+ }
77
+ });
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }, false, false, settings.ignoredKeys, context);
83
+ };
84
+ return defineVisitors({
85
+ context,
86
+ settings
87
+ }, visitNode);
88
+ }
89
+ };
90
+
91
+ module.exports = classValidation;
@@ -1 +1,89 @@
1
- import u from"../utils/define-visitors.mjs";import y from"../utils/resolve-context.mjs";import l from"../utils/find-loc.mjs";import{parseNodeRecursive as C}from"../utils/parse-node-recursive.mjs";import w from"../utils/validate-action.mjs";var b={meta:{docs:{description:"Detect syntax errors early when writing classes",category:"Stylistic Issues",recommended:!1,url:"https://rc.css.master.co/docs/code-linting#syntax-error-checks"},messages:{invalidClass:"{{message}}",disallowUnknownClass:"{{message}}"},fixable:null,schema:[{type:"object",properties:{calleeMatching:{type:"string"},classMatching:{type:"string"},ignoredKeys:{type:"array",items:{type:"string",minLength:0},uniqueItems:!0},config:{type:["string","object"]}}}]},create:function(e){const{options:c,settings:o}=y(e);return u({context:e,settings:o},(d,m=null)=>{C(d,m,(g,r)=>{const t=e.sourceCode.lines,i=r.loc.start.line,n=r.loc.end.line;for(const s of g){const{isMasterCSS:f,errors:a}=w(s,o.config);if(a.length>0)for(const p of a)f?e.report({loc:l(s,t,i,n),messageId:"invalidClass",data:{message:p.message+"."}}):c.disallowUnknownClass&&e.report({loc:l(s,t,i,n),messageId:"disallowUnknownClass",data:{message:`"${s}" is not a valid or known class.`}})}},!1,!1,o.ignoredKeys,e)})}};export{b as default};
1
+ import defineVisitors from '../utils/define-visitors.mjs';
2
+ import resolveContext from '../utils/resolve-context.mjs';
3
+ import findLoc from '../utils/find-loc.mjs';
4
+ import { parseNodeRecursive } from '../utils/parse-node-recursive.mjs';
5
+ import validateAction from '../utils/validate-action.mjs';
6
+
7
+ var classValidation = {
8
+ meta: {
9
+ docs: {
10
+ description: 'Detect syntax errors early when writing classes',
11
+ category: 'Stylistic Issues',
12
+ recommended: false,
13
+ url: 'https://rc.css.master.co/docs/code-linting#syntax-error-checks'
14
+ },
15
+ messages: {
16
+ invalidClass: '{{message}}',
17
+ disallowUnknownClass: '{{message}}'
18
+ },
19
+ fixable: null,
20
+ schema: [
21
+ {
22
+ type: 'object',
23
+ properties: {
24
+ calleeMatching: {
25
+ type: 'string'
26
+ },
27
+ classMatching: {
28
+ type: 'string'
29
+ },
30
+ ignoredKeys: {
31
+ type: 'array',
32
+ items: {
33
+ type: 'string',
34
+ minLength: 0
35
+ },
36
+ uniqueItems: true
37
+ },
38
+ config: {
39
+ type: [
40
+ 'string',
41
+ 'object'
42
+ ]
43
+ }
44
+ }
45
+ }
46
+ ]
47
+ },
48
+ create: function(context) {
49
+ const { options, settings } = resolveContext(context);
50
+ const visitNode = (node, arg = null)=>{
51
+ parseNodeRecursive(node, arg, (classNames, node)=>{
52
+ const sourceCode = context.sourceCode;
53
+ const sourceCodeLines = sourceCode.lines;
54
+ const nodeStartLine = node.loc.start.line;
55
+ const nodeEndLine = node.loc.end.line;
56
+ for (const className of classNames){
57
+ const { isMasterCSS, errors } = validateAction(className, settings.config);
58
+ if (errors.length > 0) {
59
+ for (const error of errors){
60
+ if (isMasterCSS) {
61
+ context.report({
62
+ loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeEndLine),
63
+ messageId: 'invalidClass',
64
+ data: {
65
+ message: error.message + '.'
66
+ }
67
+ });
68
+ } else if (options.disallowUnknownClass) {
69
+ context.report({
70
+ loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeEndLine),
71
+ messageId: 'disallowUnknownClass',
72
+ data: {
73
+ message: `"${className}" is not a valid or known class.`
74
+ }
75
+ });
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }, false, false, settings.ignoredKeys, context);
81
+ };
82
+ return defineVisitors({
83
+ context,
84
+ settings
85
+ }, visitNode);
86
+ }
87
+ };
88
+
89
+ export { classValidation as default };
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const settings = {
4
+ calleeMatching: '^(classnames|clsx|ctl|cva|cv|classVariant|styled(?:\\.\\w+)?)',
5
+ classMatching: '^class(Name)?$',
6
+ ignoredKeys: [
7
+ 'compoundVariants',
8
+ 'defaultVariants'
9
+ ],
10
+ config: 'master.css'
11
+ };
12
+
13
+ module.exports = settings;
package/dist/settings.mjs CHANGED
@@ -1 +1,11 @@
1
- const s={calleeMatching:"^(classnames|clsx|ctl|cva|cv|classVariant|styled(?:\\.\\w+)?)",classMatching:"^class(Name)?$",ignoredKeys:["compoundVariants","defaultVariants"],config:"master.css.*"};var a=s;export{a as default};
1
+ const settings = {
2
+ calleeMatching: '^(classnames|clsx|ctl|cva|cv|classVariant|styled(?:\\.\\w+)?)',
3
+ classMatching: '^class(Name)?$',
4
+ ignoredKeys: [
5
+ 'compoundVariants',
6
+ 'defaultVariants'
7
+ ],
8
+ config: 'master.css'
9
+ };
10
+
11
+ export { settings as default };
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ function areDeclarationsEqual(aDeclarations, bDeclarations) {
4
+ // 获取对象A和B的所有属性名
5
+ const aKeys = Object.keys(aDeclarations);
6
+ const bKeys = Object.keys(bDeclarations);
7
+ // 如果属性数量不相等,返回false
8
+ if (aKeys.length !== bKeys.length) {
9
+ return false;
10
+ }
11
+ // 检查对象A的属性是否都存在于对象B中
12
+ for (const key of aKeys){
13
+ if (!Object.prototype.hasOwnProperty.call(bDeclarations, key)) {
14
+ return false;
15
+ }
16
+ }
17
+ // 如果所有属性都匹配,返回true
18
+ return true;
19
+ }
20
+
21
+ module.exports = areDeclarationsEqual;
@@ -1 +1,19 @@
1
- function s(r,e){const t=Object.keys(r),n=Object.keys(e);if(t.length!==n.length)return!1;for(const o of t)if(!Object.prototype.hasOwnProperty.call(e,o))return!1;return!0}export{s as default};
1
+ function areDeclarationsEqual(aDeclarations, bDeclarations) {
2
+ // 获取对象A和B的所有属性名
3
+ const aKeys = Object.keys(aDeclarations);
4
+ const bKeys = Object.keys(bDeclarations);
5
+ // 如果属性数量不相等,返回false
6
+ if (aKeys.length !== bKeys.length) {
7
+ return false;
8
+ }
9
+ // 检查对象A的属性是否都存在于对象B中
10
+ for (const key of aKeys){
11
+ if (!Object.prototype.hasOwnProperty.call(bDeclarations, key)) {
12
+ return false;
13
+ }
14
+ }
15
+ // 如果所有属性都匹配,返回true
16
+ return true;
17
+ }
18
+
19
+ export { areDeclarationsEqual as default };
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ function defineVisitors({ context, settings }, visitNode) {
4
+ const isFnNode = (node)=>{
5
+ let calleeName = '';
6
+ const calleeNode = node.callee || node.tag;
7
+ if (calleeNode.type === 'Identifier') {
8
+ calleeName = calleeNode.name;
9
+ }
10
+ if (calleeNode.type === 'MemberExpression') {
11
+ calleeName = `${calleeNode.object.name}.${calleeNode.property.name}`;
12
+ }
13
+ return new RegExp(settings.calleeMatching).test(calleeName);
14
+ };
15
+ const CallExpression = function(node) {
16
+ if (!isFnNode(node)) {
17
+ return;
18
+ }
19
+ node.arguments.forEach((arg)=>{
20
+ visitNode(node, arg);
21
+ });
22
+ };
23
+ const classMatchingRegex = new RegExp(settings.classMatching);
24
+ const scriptVisitor = {
25
+ CallExpression,
26
+ JSXAttribute: function(node) {
27
+ if (!node.name || !classMatchingRegex.test(node.name.name)) return;
28
+ if (node.value && node.value.type === 'Literal') {
29
+ visitNode(node);
30
+ } else if (node.value && node.value.type === 'JSXExpressionContainer') {
31
+ visitNode(node, node.value.expression);
32
+ }
33
+ },
34
+ SvelteAttribute: function(node) {
35
+ if (!node.key?.name || !classMatchingRegex.test(node.key.name)) return;
36
+ for (const eachValue of node.value){
37
+ visitNode(node, eachValue);
38
+ }
39
+ },
40
+ TextAttribute: function(node) {
41
+ if (!node.name || !classMatchingRegex.test(node.name)) return;
42
+ visitNode(node);
43
+ },
44
+ TaggedTemplateExpression: function(node) {
45
+ if (isFnNode(node)) {
46
+ visitNode(node, node.quasi);
47
+ return;
48
+ }
49
+ }
50
+ };
51
+ const templateBodyVisitor = {
52
+ CallExpression,
53
+ VAttribute: function(node) {
54
+ if (node.value && node.value.type === 'VLiteral') {
55
+ visitNode(node);
56
+ } else if (node.value && node.value.type === 'VExpressionContainer' && node.value.expression.type === 'ArrayExpression') {
57
+ node.value.expression.elements.forEach((arg)=>{
58
+ visitNode(node, arg);
59
+ });
60
+ } else if (node.value && node.value.type === 'VExpressionContainer' && node.value.expression.type === 'ObjectExpression') {
61
+ node.value.expression.properties.forEach((prop)=>{
62
+ visitNode(node, prop);
63
+ });
64
+ }
65
+ }
66
+ };
67
+ if (context.sourceCode.parserServices == null || context.sourceCode.parserServices.defineTemplateBodyVisitor == null) {
68
+ return scriptVisitor;
69
+ } else {
70
+ return context.sourceCode.parserServices.defineTemplateBodyVisitor(templateBodyVisitor, scriptVisitor);
71
+ }
72
+ }
73
+
74
+ module.exports = defineVisitors;
@@ -1 +1,72 @@
1
- function f({context:a,settings:l},r){const n=e=>{let t="";const s=e.callee||e.tag;return s.type==="Identifier"&&(t=s.name),s.type==="MemberExpression"&&(t=`${s.object.name}.${s.property.name}`),new RegExp(l.calleeMatching).test(t)},u=function(e){n(e)&&e.arguments.forEach(t=>{r(e,t)})},i=new RegExp(l.classMatching),p={CallExpression:u,JSXAttribute:function(e){!e.name||!i.test(e.name.name)||(e.value&&e.value.type==="Literal"?r(e):e.value&&e.value.type==="JSXExpressionContainer"&&r(e,e.value.expression))},SvelteAttribute:function(e){if(!(!e.key?.name||!i.test(e.key.name)))for(const t of e.value)r(e,t)},TextAttribute:function(e){!e.name||!i.test(e.name)||r(e)},TaggedTemplateExpression:function(e){if(n(e)){r(e,e.quasi);return}}},c={CallExpression:u,VAttribute:function(e){e.value&&e.value.type==="VLiteral"?r(e):e.value&&e.value.type==="VExpressionContainer"&&e.value.expression.type==="ArrayExpression"?e.value.expression.elements.forEach(t=>{r(e,t)}):e.value&&e.value.type==="VExpressionContainer"&&e.value.expression.type==="ObjectExpression"&&e.value.expression.properties.forEach(t=>{r(e,t)})}};return a.sourceCode.parserServices==null||a.sourceCode.parserServices.defineTemplateBodyVisitor==null?p:a.sourceCode.parserServices.defineTemplateBodyVisitor(c,p)}export{f as default};
1
+ function defineVisitors({ context, settings }, visitNode) {
2
+ const isFnNode = (node)=>{
3
+ let calleeName = '';
4
+ const calleeNode = node.callee || node.tag;
5
+ if (calleeNode.type === 'Identifier') {
6
+ calleeName = calleeNode.name;
7
+ }
8
+ if (calleeNode.type === 'MemberExpression') {
9
+ calleeName = `${calleeNode.object.name}.${calleeNode.property.name}`;
10
+ }
11
+ return new RegExp(settings.calleeMatching).test(calleeName);
12
+ };
13
+ const CallExpression = function(node) {
14
+ if (!isFnNode(node)) {
15
+ return;
16
+ }
17
+ node.arguments.forEach((arg)=>{
18
+ visitNode(node, arg);
19
+ });
20
+ };
21
+ const classMatchingRegex = new RegExp(settings.classMatching);
22
+ const scriptVisitor = {
23
+ CallExpression,
24
+ JSXAttribute: function(node) {
25
+ if (!node.name || !classMatchingRegex.test(node.name.name)) return;
26
+ if (node.value && node.value.type === 'Literal') {
27
+ visitNode(node);
28
+ } else if (node.value && node.value.type === 'JSXExpressionContainer') {
29
+ visitNode(node, node.value.expression);
30
+ }
31
+ },
32
+ SvelteAttribute: function(node) {
33
+ if (!node.key?.name || !classMatchingRegex.test(node.key.name)) return;
34
+ for (const eachValue of node.value){
35
+ visitNode(node, eachValue);
36
+ }
37
+ },
38
+ TextAttribute: function(node) {
39
+ if (!node.name || !classMatchingRegex.test(node.name)) return;
40
+ visitNode(node);
41
+ },
42
+ TaggedTemplateExpression: function(node) {
43
+ if (isFnNode(node)) {
44
+ visitNode(node, node.quasi);
45
+ return;
46
+ }
47
+ }
48
+ };
49
+ const templateBodyVisitor = {
50
+ CallExpression,
51
+ VAttribute: function(node) {
52
+ if (node.value && node.value.type === 'VLiteral') {
53
+ visitNode(node);
54
+ } else if (node.value && node.value.type === 'VExpressionContainer' && node.value.expression.type === 'ArrayExpression') {
55
+ node.value.expression.elements.forEach((arg)=>{
56
+ visitNode(node, arg);
57
+ });
58
+ } else if (node.value && node.value.type === 'VExpressionContainer' && node.value.expression.type === 'ObjectExpression') {
59
+ node.value.expression.properties.forEach((prop)=>{
60
+ visitNode(node, prop);
61
+ });
62
+ }
63
+ }
64
+ };
65
+ if (context.sourceCode.parserServices == null || context.sourceCode.parserServices.defineTemplateBodyVisitor == null) {
66
+ return scriptVisitor;
67
+ } else {
68
+ return context.sourceCode.parserServices.defineTemplateBodyVisitor(templateBodyVisitor, scriptVisitor);
69
+ }
70
+ }
71
+
72
+ export { defineVisitors as default };
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ const separatorRegEx = /([\t\n\f\r ]+)/;
4
+ function extractClassnamesFromValue(classStr) {
5
+ if (typeof classStr !== 'string') {
6
+ return {
7
+ classNames: [],
8
+ whitespaces: [],
9
+ headSpace: false,
10
+ tailSpace: false
11
+ };
12
+ }
13
+ const parts = classStr.split(separatorRegEx);
14
+ if (parts[0] === '') {
15
+ parts.shift();
16
+ }
17
+ if (parts[parts.length - 1] === '') {
18
+ parts.pop();
19
+ }
20
+ const headSpace = separatorRegEx.test(parts[0]);
21
+ const tailSpace = separatorRegEx.test(parts[parts.length - 1]);
22
+ const isClass = (_, i)=>headSpace ? i % 2 !== 0 : i % 2 === 0;
23
+ const isNotClass = (_, i)=>headSpace ? i % 2 === 0 : i % 2 !== 0;
24
+ const classNames = parts.filter(isClass);
25
+ const whitespaces = parts.filter(isNotClass);
26
+ return {
27
+ classNames: classNames,
28
+ whitespaces: whitespaces,
29
+ headSpace: headSpace,
30
+ tailSpace: tailSpace
31
+ };
32
+ }
33
+
34
+ module.exports = extractClassnamesFromValue;