tailwind-canonical 0.1.3 → 0.2.0

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 (42) hide show
  1. package/README.md +252 -23
  2. package/dist/cli/index.js +253 -23
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/core/analyzer.d.ts.map +1 -1
  5. package/dist/core/analyzer.js +17 -11
  6. package/dist/core/analyzer.js.map +1 -1
  7. package/dist/core/class-strings.d.ts +14 -0
  8. package/dist/core/class-strings.d.ts.map +1 -0
  9. package/dist/core/class-strings.js +127 -0
  10. package/dist/core/class-strings.js.map +1 -0
  11. package/dist/core/consistency.d.ts +46 -0
  12. package/dist/core/consistency.d.ts.map +1 -0
  13. package/dist/core/consistency.js +252 -0
  14. package/dist/core/consistency.js.map +1 -0
  15. package/dist/core/deduplicator.d.ts +2 -1
  16. package/dist/core/deduplicator.d.ts.map +1 -1
  17. package/dist/core/deduplicator.js +341 -75
  18. package/dist/core/deduplicator.js.map +1 -1
  19. package/dist/core/fixer.d.ts.map +1 -1
  20. package/dist/core/fixer.js +14 -18
  21. package/dist/core/fixer.js.map +1 -1
  22. package/dist/core/merger.d.ts +2 -1
  23. package/dist/core/merger.d.ts.map +1 -1
  24. package/dist/core/merger.js +5 -14
  25. package/dist/core/merger.js.map +1 -1
  26. package/dist/core/rules.d.ts +4 -0
  27. package/dist/core/rules.d.ts.map +1 -1
  28. package/dist/core/rules.js +43 -55
  29. package/dist/core/rules.js.map +1 -1
  30. package/dist/core/scanner.d.ts +2 -1
  31. package/dist/core/scanner.d.ts.map +1 -1
  32. package/dist/core/scanner.js +105 -6
  33. package/dist/core/scanner.js.map +1 -1
  34. package/dist/core/sorter.d.ts +6 -0
  35. package/dist/core/sorter.d.ts.map +1 -0
  36. package/dist/core/sorter.js +166 -0
  37. package/dist/core/sorter.js.map +1 -0
  38. package/dist/index.d.ts +7 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +4 -1
  41. package/dist/index.js.map +1 -1
  42. package/package.json +5 -3
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/core/analyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,UAAU,EAAoB,MAAM,YAAY,CAAC;AAE5E,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AA6CF,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,MAAW,GAAG,OAAO,EAAE,CAY5E"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/core/analyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,UAAU,EAAoB,MAAM,YAAY,CAAC;AAE5E,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AA4CF,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,MAAW,GAAG,OAAO,EAAE,CAe5E"}
@@ -1,18 +1,21 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { suggestCanonical } from './rules.js';
3
- const CLASS_REGEX = /className(?:Name)?\s*=\s*(?:"([^"]+)"|'([^']+)'|`([^`]+)`|\{([^}]+)\})/g;
3
+ const DEFAULT_ATTR_NAMES = ['className'];
4
4
  const SINGLE_CLASS_REGEX = /[^\s"'`{}]+/g;
5
- function extractClasses(content) {
5
+ function escapeRegex(s) {
6
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
7
+ }
8
+ function buildClassRegex(attrNames) {
9
+ const alts = attrNames.map(escapeRegex).join('|');
10
+ return new RegExp(`(?:${alts})\\s*=\\s*(?:"([^"]+)"|'([^']+)'|\`([^\`]+)\`|\\{([^}]+)\\})`, 'g');
11
+ }
12
+ function extractClasses(content, attrNames) {
6
13
  const found = [];
7
- CLASS_REGEX.lastIndex = 0;
8
- for (let match = CLASS_REGEX.exec(content); match !== null; match = CLASS_REGEX.exec(content)) {
14
+ for (const match of content.matchAll(buildClassRegex(attrNames))) {
9
15
  const raw = match[1] ?? match[2] ?? match[3] ?? match[4] ?? '';
10
- SINGLE_CLASS_REGEX.lastIndex = 0;
11
- for (let clsMatch = SINGLE_CLASS_REGEX.exec(raw); clsMatch !== null; clsMatch = SINGLE_CLASS_REGEX.exec(raw)) {
12
- found.push({
13
- cls: clsMatch[0],
14
- index: match.index + match[0].indexOf(raw) + clsMatch.index,
15
- });
16
+ const rawStart = (match.index ?? 0) + match[0].indexOf(raw);
17
+ for (const clsMatch of raw.matchAll(SINGLE_CLASS_REGEX)) {
18
+ found.push({ cls: clsMatch[0], index: rawStart + (clsMatch.index ?? 0) });
16
19
  }
17
20
  }
18
21
  return found;
@@ -26,7 +29,10 @@ function indexToLineCol(content, index) {
26
29
  export function analyzeFile(filePath, config = {}) {
27
30
  const content = readFileSync(filePath, 'utf8');
28
31
  const findings = [];
29
- for (const { cls, index } of extractClasses(content)) {
32
+ const attrNames = config.attributeNames?.length
33
+ ? config.attributeNames
34
+ : DEFAULT_ATTR_NAMES;
35
+ for (const { cls, index } of extractClasses(content, attrNames)) {
30
36
  const suggestion = suggestCanonical(cls, config);
31
37
  if (!suggestion)
32
38
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/core/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAgC,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAS5E,MAAM,WAAW,GACf,yEAAyE,CAAC;AAC5E,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAE1C,SAAS,cAAc,CACrB,OAAe;IAEf,MAAM,KAAK,GAA0C,EAAE,CAAC;IAExD,WAAW,CAAC,SAAS,GAAG,CAAC,CAAC;IAE1B,KACE,IAAI,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EACrC,KAAK,KAAK,IAAI,EACd,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EACjC,CAAC;QACD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/D,kBAAkB,CAAC,SAAS,GAAG,CAAC,CAAC;QACjC,KACE,IAAI,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAC3C,QAAQ,KAAK,IAAI,EACjB,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EACvC,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACT,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;gBAChB,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK;aAC5D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CACrB,OAAe,EACf,KAAa;IAEb,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACvC,MAAM,GAAG,GAAG,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7C,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,SAAiB,EAAE;IAC/D,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAc,EAAE,CAAC;IAE/B,KAAK,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/core/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAgC,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAS5E,MAAM,kBAAkB,GAAG,CAAC,WAAW,CAAC,CAAC;AACzC,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAE1C,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,eAAe,CAAC,SAAmB;IAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,OAAO,IAAI,MAAM,CACf,MAAM,IAAI,8DAA8D,EACxE,GAAG,CACJ,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,OAAe,EACf,SAAmB;IAEnB,MAAM,KAAK,GAA0C,EAAE,CAAC;IAExD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5D,KAAK,MAAM,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACxD,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CACrB,OAAe,EACf,KAAa;IAEb,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACvC,MAAM,GAAG,GAAG,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7C,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,SAAiB,EAAE;IAC/D,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM;QAC7C,CAAC,CAAC,MAAM,CAAC,cAAc;QACvB,CAAC,CAAC,kBAAkB,CAAC;IAEvB,KAAK,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;QAChE,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type ClassStringOpts = {
2
+ functionNames?: string[];
3
+ attributeNames?: string[];
4
+ };
5
+ export declare function replaceClassStrings(content: string, transform: (s: string) => string, opts?: ClassStringOpts): {
6
+ result: string;
7
+ count: number;
8
+ };
9
+ export declare function extractClassStrings(content: string, opts?: ClassStringOpts): Array<{
10
+ value: string;
11
+ start: number;
12
+ end: number;
13
+ }>;
14
+ //# sourceMappingURL=class-strings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-strings.d.ts","sourceRoot":"","sources":["../../src/core/class-strings.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAyDF,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAChC,IAAI,GAAE,eAAoB,GACzB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA6CnC;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,eAAoB,GACzB,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CA+CtD"}
@@ -0,0 +1,127 @@
1
+ const DEFAULT_ATTR_NAMES = ['className'];
2
+ function escapeRegex(s) {
3
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
4
+ }
5
+ function buildAttrRegex(names) {
6
+ const alts = names.map(escapeRegex).join('|');
7
+ return new RegExp(`(${alts})\\s*=\\s*(?:"([^"]+)"|'([^']+)'|\`([^\`]+)\`)`, 'g');
8
+ }
9
+ function transformCallContent(content, start, transform) {
10
+ const parts = [];
11
+ let i = start;
12
+ let depth = 1;
13
+ let count = 0;
14
+ while (i < content.length && depth > 0) {
15
+ const ch = content[i];
16
+ if (ch === '(' || ch === '[' || ch === '{') {
17
+ depth++;
18
+ parts.push(ch);
19
+ i++;
20
+ }
21
+ else if (ch === ')' || ch === ']' || ch === '}') {
22
+ depth--;
23
+ parts.push(ch);
24
+ i++;
25
+ }
26
+ else if (ch === '"' || ch === "'") {
27
+ const q = ch;
28
+ let j = i + 1;
29
+ while (j < content.length && content[j] !== q) {
30
+ if (content[j] === '\\')
31
+ j++;
32
+ j++;
33
+ }
34
+ const raw = content.slice(i + 1, j);
35
+ const out = transform(raw);
36
+ if (out !== raw)
37
+ count++;
38
+ parts.push(`${q}${out}${q}`);
39
+ i = j + 1;
40
+ }
41
+ else {
42
+ parts.push(ch);
43
+ i++;
44
+ }
45
+ }
46
+ return { processed: parts.join(''), consumed: i - start, count };
47
+ }
48
+ export function replaceClassStrings(content, transform, opts = {}) {
49
+ const attrNames = opts.attributeNames?.length
50
+ ? opts.attributeNames
51
+ : DEFAULT_ATTR_NAMES;
52
+ let result = content;
53
+ let count = 0;
54
+ result = result.replace(buildAttrRegex(attrNames), (_full, attr, dq, sq, bt) => {
55
+ const raw = dq ?? sq ?? bt ?? '';
56
+ const q = dq !== undefined ? '"' : sq !== undefined ? "'" : '`';
57
+ const out = transform(raw);
58
+ if (out !== raw)
59
+ count++;
60
+ return `${attr}=${q}${out}${q}`;
61
+ });
62
+ const funcNames = opts.functionNames;
63
+ if (!funcNames?.length)
64
+ return { result, count };
65
+ const funcRe = new RegExp(`\\b(?:${funcNames.map(escapeRegex).join('|')})\\s*\\(`, 'g');
66
+ const buf = [];
67
+ let pos = 0;
68
+ for (const m of result.matchAll(funcRe)) {
69
+ const callStart = (m.index ?? 0) + m[0].length;
70
+ if (callStart < pos)
71
+ continue;
72
+ buf.push(result.slice(pos, callStart));
73
+ const { processed, consumed, count: c, } = transformCallContent(result, callStart, transform);
74
+ buf.push(processed);
75
+ pos = callStart + consumed;
76
+ count += c;
77
+ funcRe.lastIndex = pos;
78
+ }
79
+ buf.push(result.slice(pos));
80
+ return { result: buf.join(''), count };
81
+ }
82
+ export function extractClassStrings(content, opts = {}) {
83
+ const attrNames = opts.attributeNames?.length
84
+ ? opts.attributeNames
85
+ : DEFAULT_ATTR_NAMES;
86
+ const results = [];
87
+ for (const m of content.matchAll(buildAttrRegex(attrNames))) {
88
+ const raw = m[2] ?? m[3] ?? m[4] ?? '';
89
+ const start = (m.index ?? 0) + m[0].length - raw.length - 1;
90
+ results.push({ value: raw, start, end: start + raw.length });
91
+ }
92
+ const funcNames = opts.functionNames;
93
+ if (!funcNames?.length)
94
+ return results;
95
+ const funcRe = new RegExp(`\\b(?:${funcNames.map(escapeRegex).join('|')})\\s*\\(`, 'g');
96
+ for (const m of content.matchAll(funcRe)) {
97
+ let i = (m.index ?? 0) + m[0].length;
98
+ let depth = 1;
99
+ while (i < content.length && depth > 0) {
100
+ const ch = content[i];
101
+ if (ch === '(' || ch === '[' || ch === '{') {
102
+ depth++;
103
+ i++;
104
+ }
105
+ else if (ch === ')' || ch === ']' || ch === '}') {
106
+ depth--;
107
+ i++;
108
+ }
109
+ else if (ch === '"' || ch === "'") {
110
+ const q = ch;
111
+ let j = i + 1;
112
+ while (j < content.length && content[j] !== q) {
113
+ if (content[j] === '\\')
114
+ j++;
115
+ j++;
116
+ }
117
+ results.push({ value: content.slice(i + 1, j), start: i + 1, end: j });
118
+ i = j + 1;
119
+ }
120
+ else {
121
+ i++;
122
+ }
123
+ }
124
+ }
125
+ return results;
126
+ }
127
+ //# sourceMappingURL=class-strings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-strings.js","sourceRoot":"","sources":["../../src/core/class-strings.ts"],"names":[],"mappings":"AAKA,MAAM,kBAAkB,GAAG,CAAC,WAAW,CAAC,CAAC;AAEzC,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,KAAe;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9C,OAAO,IAAI,MAAM,CACf,IAAI,IAAI,gDAAgD,EACxD,GAAG,CACJ,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,OAAe,EACf,KAAa,EACb,SAAgC;IAEhC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,GAAG,KAAK,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAC3C,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAClD,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACpC,MAAM,CAAC,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9C,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;oBAAE,CAAC,EAAE,CAAC;gBAC7B,CAAC,EAAE,CAAC;YACN,CAAC;YACD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,GAAG,KAAK,GAAG;gBAAE,KAAK,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,SAAgC,EAChC,OAAwB,EAAE;IAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM;QAC3C,CAAC,CAAC,IAAI,CAAC,cAAc;QACrB,CAAC,CAAC,kBAAkB,CAAC;IACvB,IAAI,MAAM,GAAG,OAAO,CAAC;IACrB,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,cAAc,CAAC,SAAS,CAAC,EACzB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAChE,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,GAAG,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;IAClC,CAAC,CACF,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC;IACrC,IAAI,CAAC,SAAS,EAAE,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAEjD,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,SAAS,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EACvD,GAAG,CACJ,CAAC;IACF,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/C,IAAI,SAAS,GAAG,GAAG;YAAE,SAAS;QAC9B,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;QACvC,MAAM,EACJ,SAAS,EACT,QAAQ,EACR,KAAK,EAAE,CAAC,GACT,GAAG,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpB,GAAG,GAAG,SAAS,GAAG,QAAQ,CAAC;QAC3B,KAAK,IAAI,CAAC,CAAC;QACX,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC;IACzB,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5B,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,OAAwB,EAAE;IAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM;QAC3C,CAAC,CAAC,IAAI,CAAC,cAAc;QACrB,CAAC,CAAC,kBAAkB,CAAC;IACvB,MAAM,OAAO,GAAyD,EAAE,CAAC;IAEzE,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC;IACrC,IAAI,CAAC,SAAS,EAAE,MAAM;QAAE,OAAO,OAAO,CAAC;IAEvC,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,SAAS,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EACvD,GAAG,CACJ,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACrC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACvC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBAC3C,KAAK,EAAE,CAAC;gBACR,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBAClD,KAAK,EAAE,CAAC;gBACR,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACpC,MAAM,CAAC,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACd,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC9C,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;wBAAE,CAAC,EAAE,CAAC;oBAC7B,CAAC,EAAE,CAAC;gBACN,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBACvE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,CAAC,EAAE,CAAC;YACN,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { type ClassStringOpts } from './class-strings.js';
2
+ import type { Config } from './rules.js';
3
+ export type FileClasses = {
4
+ file: string;
5
+ classes: string[];
6
+ };
7
+ export type ColorVariant = {
8
+ token: string;
9
+ count: number;
10
+ files: string[];
11
+ };
12
+ export type ColorVariantGroup = {
13
+ property: string;
14
+ family: string;
15
+ variants: ColorVariant[];
16
+ };
17
+ export type ScaleValue = {
18
+ value: string;
19
+ count: number;
20
+ files: string[];
21
+ };
22
+ export type ScaleInconsistency = {
23
+ property: string;
24
+ values: ScaleValue[];
25
+ };
26
+ export type ClassCombination = {
27
+ classes: string[];
28
+ count: number;
29
+ files: string[];
30
+ };
31
+ export type ConsistencyReport = {
32
+ filesAnalyzed: number;
33
+ colorVariants: ColorVariantGroup[];
34
+ scaleInconsistencies: ScaleInconsistency[];
35
+ combinations: ClassCombination[];
36
+ };
37
+ export type ConsistencyOptions = {
38
+ minCombinationSize?: number;
39
+ minCombinationFiles?: number;
40
+ maxCombinations?: number;
41
+ minScaleOccurrences?: number;
42
+ };
43
+ export declare function analyzeConsistency(input: FileClasses[], options?: ConsistencyOptions): ConsistencyReport;
44
+ export declare function collectClasses(content: string, opts?: ClassStringOpts): string[];
45
+ export declare function analyzeConsistencyFiles(filePaths: string[], config?: Config, options?: ConsistencyOptions): ConsistencyReport;
46
+ //# sourceMappingURL=consistency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistency.d.ts","sourceRoot":"","sources":["../../src/core/consistency.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,eAAe,EAAuB,MAAM,oBAAoB,CAAC;AAC/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE9D,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,oBAAoB,EAAE,kBAAkB,EAAE,CAAC;IAC3C,YAAY,EAAE,gBAAgB,EAAE,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AA+PF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAoBnB;AAID,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,eAAoB,GACzB,MAAM,EAAE,CAQV;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,GAAE,MAAW,EACnB,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAUnB"}
@@ -0,0 +1,252 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { extractClassStrings } from './class-strings.js';
3
+ const COLOR_PROPERTIES = new Set([
4
+ 'text',
5
+ 'bg',
6
+ 'border',
7
+ 'ring',
8
+ 'divide',
9
+ 'outline',
10
+ 'fill',
11
+ 'stroke',
12
+ 'from',
13
+ 'via',
14
+ 'to',
15
+ 'decoration',
16
+ 'accent',
17
+ 'caret',
18
+ 'shadow',
19
+ 'placeholder',
20
+ ]);
21
+ const COLOR_FAMILIES = {
22
+ red: 'red',
23
+ rose: 'red',
24
+ pink: 'red',
25
+ orange: 'orange',
26
+ amber: 'orange',
27
+ yellow: 'yellow',
28
+ lime: 'yellow',
29
+ green: 'green',
30
+ emerald: 'green',
31
+ teal: 'green',
32
+ blue: 'blue',
33
+ sky: 'blue',
34
+ cyan: 'blue',
35
+ indigo: 'blue',
36
+ purple: 'purple',
37
+ violet: 'purple',
38
+ fuchsia: 'purple',
39
+ gray: 'gray',
40
+ slate: 'gray',
41
+ zinc: 'gray',
42
+ neutral: 'gray',
43
+ stone: 'gray',
44
+ };
45
+ const SCALE_PROPERTIES = new Set([
46
+ 'p',
47
+ 'px',
48
+ 'py',
49
+ 'pt',
50
+ 'pr',
51
+ 'pb',
52
+ 'pl',
53
+ 'ps',
54
+ 'pe',
55
+ 'm',
56
+ 'mx',
57
+ 'my',
58
+ 'mt',
59
+ 'mr',
60
+ 'mb',
61
+ 'ml',
62
+ 'ms',
63
+ 'me',
64
+ 'gap',
65
+ 'gap-x',
66
+ 'gap-y',
67
+ 'space-x',
68
+ 'space-y',
69
+ 'z',
70
+ ]);
71
+ function stripVariants(cls) {
72
+ const idx = cls.lastIndexOf(':');
73
+ return idx === -1 ? cls : cls.slice(idx + 1);
74
+ }
75
+ function parseColor(cls) {
76
+ const base = stripVariants(cls);
77
+ const dash = base.indexOf('-');
78
+ if (dash === -1)
79
+ return null;
80
+ const property = base.slice(0, dash);
81
+ if (!COLOR_PROPERTIES.has(property))
82
+ return null;
83
+ const rest = base.slice(dash + 1);
84
+ const restDash = rest.indexOf('-');
85
+ if (restDash === -1)
86
+ return null;
87
+ const color = rest.slice(0, restDash);
88
+ const shade = rest.slice(restDash + 1);
89
+ const family = COLOR_FAMILIES[color];
90
+ if (!(family && /^\d+$/.test(shade)))
91
+ return null;
92
+ return { property, family, token: `${color}-${shade}` };
93
+ }
94
+ function parseScale(cls) {
95
+ const base = stripVariants(cls);
96
+ const negative = base.startsWith('-');
97
+ const body = negative ? base.slice(1) : base;
98
+ const dash = body.lastIndexOf('-');
99
+ if (dash === -1)
100
+ return null;
101
+ const property = body.slice(0, dash);
102
+ if (!SCALE_PROPERTIES.has(property))
103
+ return null;
104
+ const value = body.slice(dash + 1);
105
+ if (!value)
106
+ return null;
107
+ return { property, value: negative ? `-${value}` : value };
108
+ }
109
+ function addUsage(map, key, file) {
110
+ let entry = map.get(key);
111
+ if (!entry) {
112
+ entry = { count: 0, files: new Set() };
113
+ map.set(key, entry);
114
+ }
115
+ entry.count++;
116
+ entry.files.add(file);
117
+ }
118
+ function detectColorVariants(input) {
119
+ const groups = new Map();
120
+ for (const { file, classes } of input) {
121
+ for (const cls of classes) {
122
+ const parsed = parseColor(cls);
123
+ if (!parsed)
124
+ continue;
125
+ const groupKey = `${parsed.property}|${parsed.family}`;
126
+ let group = groups.get(groupKey);
127
+ if (!group) {
128
+ group = {
129
+ property: parsed.property,
130
+ family: parsed.family,
131
+ tokens: new Map(),
132
+ };
133
+ groups.set(groupKey, group);
134
+ }
135
+ addUsage(group.tokens, parsed.token, file);
136
+ }
137
+ }
138
+ const result = [];
139
+ for (const group of groups.values()) {
140
+ if (group.tokens.size < 2)
141
+ continue;
142
+ const variants = [...group.tokens.entries()]
143
+ .map(([token, usage]) => ({
144
+ token,
145
+ count: usage.count,
146
+ files: [...usage.files].sort(),
147
+ }))
148
+ .sort((a, b) => b.count - a.count || a.token.localeCompare(b.token));
149
+ result.push({
150
+ property: group.property,
151
+ family: group.family,
152
+ variants,
153
+ });
154
+ }
155
+ return result.sort((a, b) => a.property.localeCompare(b.property) || a.family.localeCompare(b.family));
156
+ }
157
+ function detectScaleInconsistencies(input, minOccurrences) {
158
+ const props = new Map();
159
+ for (const { file, classes } of input) {
160
+ for (const cls of classes) {
161
+ const parsed = parseScale(cls);
162
+ if (!parsed)
163
+ continue;
164
+ let values = props.get(parsed.property);
165
+ if (!values) {
166
+ values = new Map();
167
+ props.set(parsed.property, values);
168
+ }
169
+ addUsage(values, parsed.value, file);
170
+ }
171
+ }
172
+ const result = [];
173
+ for (const [property, values] of props) {
174
+ if (values.size < 2)
175
+ continue;
176
+ const total = [...values.values()].reduce((s, v) => s + v.count, 0);
177
+ if (total < minOccurrences)
178
+ continue;
179
+ const sorted = [...values.entries()]
180
+ .map(([value, usage]) => ({
181
+ value,
182
+ count: usage.count,
183
+ files: [...usage.files].sort(),
184
+ }))
185
+ .sort((a, b) => b.count - a.count || a.value.localeCompare(b.value));
186
+ result.push({ property, values: sorted });
187
+ }
188
+ return result.sort((a, b) => a.property.localeCompare(b.property));
189
+ }
190
+ function detectCombinations(input, minSize, minFiles, max) {
191
+ const combos = new Map();
192
+ for (const { file, classes } of input) {
193
+ if (classes.length < minSize)
194
+ continue;
195
+ const unique = [...new Set(classes)].sort();
196
+ if (unique.length < minSize)
197
+ continue;
198
+ const key = unique.join(' ');
199
+ let entry = combos.get(key);
200
+ if (!entry) {
201
+ entry = { classes: unique, count: 0, files: new Set() };
202
+ combos.set(key, entry);
203
+ }
204
+ entry.count++;
205
+ entry.files.add(file);
206
+ }
207
+ return [...combos.values()]
208
+ .filter((c) => c.files.size >= minFiles)
209
+ .map((c) => ({
210
+ classes: c.classes,
211
+ count: c.count,
212
+ files: [...c.files].sort(),
213
+ }))
214
+ .sort((a, b) => b.files.length - a.files.length ||
215
+ b.count - a.count ||
216
+ a.classes.join(' ').localeCompare(b.classes.join(' ')))
217
+ .slice(0, max);
218
+ }
219
+ export function analyzeConsistency(input, options = {}) {
220
+ const minCombinationSize = options.minCombinationSize ?? 2;
221
+ const minCombinationFiles = options.minCombinationFiles ?? 3;
222
+ const maxCombinations = options.maxCombinations ?? 20;
223
+ const minScaleOccurrences = options.minScaleOccurrences ?? 3;
224
+ return {
225
+ filesAnalyzed: input.length,
226
+ colorVariants: detectColorVariants(input),
227
+ scaleInconsistencies: detectScaleInconsistencies(input, minScaleOccurrences),
228
+ combinations: detectCombinations(input, minCombinationSize, minCombinationFiles, maxCombinations),
229
+ };
230
+ }
231
+ const SINGLE_CLASS_REGEX = /[^\s"'`{}]+/g;
232
+ export function collectClasses(content, opts = {}) {
233
+ const classes = [];
234
+ for (const { value } of extractClassStrings(content, opts)) {
235
+ for (const match of value.matchAll(SINGLE_CLASS_REGEX)) {
236
+ classes.push(match[0]);
237
+ }
238
+ }
239
+ return classes;
240
+ }
241
+ export function analyzeConsistencyFiles(filePaths, config = {}, options = {}) {
242
+ const opts = {
243
+ functionNames: config.functionNames,
244
+ attributeNames: config.attributeNames,
245
+ };
246
+ const input = filePaths.map((file) => ({
247
+ file,
248
+ classes: collectClasses(readFileSync(file, 'utf8'), opts),
249
+ }));
250
+ return analyzeConsistency(input, options);
251
+ }
252
+ //# sourceMappingURL=consistency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistency.js","sourceRoot":"","sources":["../../src/core/consistency.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type ClassStringOpts } from './class-strings.js';
1
2
  export declare function deduplicateClasses(classStr: string): string;
2
- export declare function dedupeFile(filePath: string): number;
3
+ export declare function dedupeFile(filePath: string, opts?: ClassStringOpts): number;
3
4
  //# sourceMappingURL=deduplicator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deduplicator.d.ts","sourceRoot":"","sources":["../../src/core/deduplicator.ts"],"names":[],"mappings":"AA+FA,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoD3D;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiBnD"}
1
+ {"version":3,"file":"deduplicator.d.ts","sourceRoot":"","sources":["../../src/core/deduplicator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,eAAe,EAAuB,MAAM,oBAAoB,CAAC;AA2Y/E,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2E3D;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,eAAoB,GACzB,MAAM,CASR"}