@buoy-design/plugin-tailwind 0.1.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.
- package/dist/arbitrary-detector.d.ts +26 -0
- package/dist/arbitrary-detector.d.ts.map +1 -0
- package/dist/arbitrary-detector.js +194 -0
- package/dist/arbitrary-detector.js.map +1 -0
- package/dist/config-parser.d.ts +29 -0
- package/dist/config-parser.d.ts.map +1 -0
- package/dist/config-parser.js +227 -0
- package/dist/config-parser.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/scanner.d.ts +26 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +49 -0
- package/dist/scanner.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DriftSignal } from '@buoy-design/core';
|
|
2
|
+
export interface ArbitraryValue {
|
|
3
|
+
type: 'color' | 'spacing' | 'size' | 'other';
|
|
4
|
+
value: string;
|
|
5
|
+
fullClass: string;
|
|
6
|
+
file: string;
|
|
7
|
+
line: number;
|
|
8
|
+
column: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ArbitraryDetectorConfig {
|
|
11
|
+
projectRoot: string;
|
|
12
|
+
include?: string[];
|
|
13
|
+
exclude?: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare class ArbitraryValueDetector {
|
|
16
|
+
private config;
|
|
17
|
+
constructor(config: ArbitraryDetectorConfig);
|
|
18
|
+
detect(): Promise<ArbitraryValue[]>;
|
|
19
|
+
detectAsDriftSignals(): Promise<DriftSignal[]>;
|
|
20
|
+
private findSourceFiles;
|
|
21
|
+
private scanFile;
|
|
22
|
+
private isHardcodedColor;
|
|
23
|
+
private valuesToDriftSignals;
|
|
24
|
+
private createDriftSignal;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=arbitrary-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arbitrary-detector.d.ts","sourceRoot":"","sources":["../src/arbitrary-detector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,mBAAmB,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAoBD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAA0B;gBAE5B,MAAM,EAAE,uBAAuB;IAIrC,MAAM,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAYnC,oBAAoB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAKtC,eAAe;IAqC7B,OAAO,CAAC,QAAQ;IA+DhB,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,oBAAoB;IAgD5B,OAAO,CAAC,iBAAiB;CAsC1B"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { glob } from 'glob';
|
|
3
|
+
import { relative } from 'path';
|
|
4
|
+
// Patterns for arbitrary values in Tailwind classes
|
|
5
|
+
const ARBITRARY_PATTERNS = {
|
|
6
|
+
// Colors: text-[#fff], bg-[#ff6b6b], border-[rgb(...)], etc.
|
|
7
|
+
color: /\b(?:text|bg|border|ring|fill|stroke|from|via|to|accent|caret|decoration|outline|shadow)-\[([#\w(),.%\s]+)\]/g,
|
|
8
|
+
// Spacing: p-[17px], m-[2rem], gap-[10px], etc.
|
|
9
|
+
spacing: /\b(?:p|px|py|pt|pr|pb|pl|m|mx|my|mt|mr|mb|ml|gap|gap-x|gap-y|space-x|space-y|inset|top|right|bottom|left)-\[([^\]]+)\]/g,
|
|
10
|
+
// Sizing: w-[100px], h-[50vh], min-w-[300px], etc.
|
|
11
|
+
size: /\b(?:w|h|min-w|max-w|min-h|max-h|size)-\[([^\]]+)\]/g,
|
|
12
|
+
// Font size: text-[14px], text-[1.5rem]
|
|
13
|
+
fontSize: /\btext-\[(\d+(?:\.\d+)?(?:px|rem|em))\]/g,
|
|
14
|
+
// Other arbitrary values
|
|
15
|
+
other: /\b[\w-]+-\[([^\]]+)\]/g,
|
|
16
|
+
};
|
|
17
|
+
export class ArbitraryValueDetector {
|
|
18
|
+
config;
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
}
|
|
22
|
+
async detect() {
|
|
23
|
+
const files = await this.findSourceFiles();
|
|
24
|
+
const arbitraryValues = [];
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
const values = this.scanFile(file);
|
|
27
|
+
arbitraryValues.push(...values);
|
|
28
|
+
}
|
|
29
|
+
return arbitraryValues;
|
|
30
|
+
}
|
|
31
|
+
async detectAsDriftSignals() {
|
|
32
|
+
const values = await this.detect();
|
|
33
|
+
return this.valuesToDriftSignals(values);
|
|
34
|
+
}
|
|
35
|
+
async findSourceFiles() {
|
|
36
|
+
const patterns = this.config.include || [
|
|
37
|
+
'**/*.html',
|
|
38
|
+
'**/*.jsx',
|
|
39
|
+
'**/*.tsx',
|
|
40
|
+
'**/*.vue',
|
|
41
|
+
'**/*.svelte',
|
|
42
|
+
'**/*.astro',
|
|
43
|
+
'**/*.php',
|
|
44
|
+
'**/*.blade.php',
|
|
45
|
+
'**/*.erb',
|
|
46
|
+
'**/*.twig',
|
|
47
|
+
'**/*.cshtml',
|
|
48
|
+
];
|
|
49
|
+
const ignore = this.config.exclude || [
|
|
50
|
+
'**/node_modules/**',
|
|
51
|
+
'**/dist/**',
|
|
52
|
+
'**/build/**',
|
|
53
|
+
'**/.next/**',
|
|
54
|
+
'**/vendor/**',
|
|
55
|
+
];
|
|
56
|
+
const allFiles = [];
|
|
57
|
+
for (const pattern of patterns) {
|
|
58
|
+
const matches = await glob(pattern, {
|
|
59
|
+
cwd: this.config.projectRoot,
|
|
60
|
+
ignore,
|
|
61
|
+
absolute: true,
|
|
62
|
+
});
|
|
63
|
+
allFiles.push(...matches);
|
|
64
|
+
}
|
|
65
|
+
return [...new Set(allFiles)];
|
|
66
|
+
}
|
|
67
|
+
scanFile(filePath) {
|
|
68
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
69
|
+
const lines = content.split('\n');
|
|
70
|
+
const values = [];
|
|
71
|
+
const relativePath = relative(this.config.projectRoot, filePath);
|
|
72
|
+
for (let lineNum = 0; lineNum < lines.length; lineNum++) {
|
|
73
|
+
const line = lines[lineNum];
|
|
74
|
+
// Check for color arbitrary values
|
|
75
|
+
for (const match of line.matchAll(ARBITRARY_PATTERNS.color)) {
|
|
76
|
+
if (this.isHardcodedColor(match[1])) {
|
|
77
|
+
values.push({
|
|
78
|
+
type: 'color',
|
|
79
|
+
value: match[1],
|
|
80
|
+
fullClass: match[0],
|
|
81
|
+
file: relativePath,
|
|
82
|
+
line: lineNum + 1,
|
|
83
|
+
column: match.index + 1,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Check for spacing arbitrary values
|
|
88
|
+
for (const match of line.matchAll(ARBITRARY_PATTERNS.spacing)) {
|
|
89
|
+
values.push({
|
|
90
|
+
type: 'spacing',
|
|
91
|
+
value: match[1],
|
|
92
|
+
fullClass: match[0],
|
|
93
|
+
file: relativePath,
|
|
94
|
+
line: lineNum + 1,
|
|
95
|
+
column: match.index + 1,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// Check for size arbitrary values
|
|
99
|
+
for (const match of line.matchAll(ARBITRARY_PATTERNS.size)) {
|
|
100
|
+
values.push({
|
|
101
|
+
type: 'size',
|
|
102
|
+
value: match[1],
|
|
103
|
+
fullClass: match[0],
|
|
104
|
+
file: relativePath,
|
|
105
|
+
line: lineNum + 1,
|
|
106
|
+
column: match.index + 1,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// Check for font size arbitrary values
|
|
110
|
+
for (const match of line.matchAll(ARBITRARY_PATTERNS.fontSize)) {
|
|
111
|
+
values.push({
|
|
112
|
+
type: 'size',
|
|
113
|
+
value: match[1],
|
|
114
|
+
fullClass: match[0],
|
|
115
|
+
file: relativePath,
|
|
116
|
+
line: lineNum + 1,
|
|
117
|
+
column: match.index + 1,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return values;
|
|
122
|
+
}
|
|
123
|
+
isHardcodedColor(value) {
|
|
124
|
+
// Check if it's a hex color
|
|
125
|
+
if (/^#[0-9a-fA-F]{3,8}$/.test(value)) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
// Check if it's rgb/rgba/hsl/hsla
|
|
129
|
+
if (/^(?:rgb|rgba|hsl|hsla)\s*\(/.test(value)) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
// CSS variable references are OK (var(--color-primary))
|
|
133
|
+
if (/^var\(/.test(value)) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
valuesToDriftSignals(values) {
|
|
139
|
+
// Group by file for better reporting
|
|
140
|
+
const byFile = new Map();
|
|
141
|
+
for (const value of values) {
|
|
142
|
+
const existing = byFile.get(value.file) || [];
|
|
143
|
+
existing.push(value);
|
|
144
|
+
byFile.set(value.file, existing);
|
|
145
|
+
}
|
|
146
|
+
const signals = [];
|
|
147
|
+
for (const [file, fileValues] of byFile) {
|
|
148
|
+
// Group by type within file
|
|
149
|
+
const colors = fileValues.filter(v => v.type === 'color');
|
|
150
|
+
const spacing = fileValues.filter(v => v.type === 'spacing');
|
|
151
|
+
const sizes = fileValues.filter(v => v.type === 'size');
|
|
152
|
+
if (colors.length > 0) {
|
|
153
|
+
signals.push(this.createDriftSignal('color', file, colors, `${colors.length} hardcoded color${colors.length > 1 ? 's' : ''} found. Use theme colors instead.`));
|
|
154
|
+
}
|
|
155
|
+
if (spacing.length > 0) {
|
|
156
|
+
signals.push(this.createDriftSignal('spacing', file, spacing, `${spacing.length} arbitrary spacing value${spacing.length > 1 ? 's' : ''} found. Use theme spacing instead.`));
|
|
157
|
+
}
|
|
158
|
+
if (sizes.length > 0) {
|
|
159
|
+
signals.push(this.createDriftSignal('size', file, sizes, `${sizes.length} arbitrary size value${sizes.length > 1 ? 's' : ''} found. Consider using theme values.`));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return signals;
|
|
163
|
+
}
|
|
164
|
+
createDriftSignal(valueType, file, values, message) {
|
|
165
|
+
const source = {
|
|
166
|
+
entityType: 'component', // Use component as closest match for file-level issues
|
|
167
|
+
entityId: `tailwind:${file}`,
|
|
168
|
+
entityName: file,
|
|
169
|
+
location: `${file}:${values[0].line}`,
|
|
170
|
+
};
|
|
171
|
+
const examples = values.slice(0, 5).map(v => `${v.fullClass} at line ${v.line}`);
|
|
172
|
+
return {
|
|
173
|
+
id: `drift:hardcoded-value:tailwind:${file}:${valueType}`,
|
|
174
|
+
type: 'hardcoded-value',
|
|
175
|
+
severity: valueType === 'color' ? 'warning' : 'info',
|
|
176
|
+
source,
|
|
177
|
+
message,
|
|
178
|
+
details: {
|
|
179
|
+
expected: 'Use Tailwind theme tokens',
|
|
180
|
+
actual: `${values.length} arbitrary ${valueType} values`,
|
|
181
|
+
affectedFiles: [file],
|
|
182
|
+
suggestions: [
|
|
183
|
+
valueType === 'color'
|
|
184
|
+
? 'Replace arbitrary colors with theme colors: text-primary, bg-secondary, etc.'
|
|
185
|
+
: 'Replace arbitrary values with theme tokens: p-4, gap-2, w-full, etc.',
|
|
186
|
+
'Add missing values to tailwind.config.js theme.extend if needed',
|
|
187
|
+
`Examples: ${examples.slice(0, 3).join(', ')}`,
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
detectedAt: new Date(),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=arbitrary-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arbitrary-detector.js","sourceRoot":"","sources":["../src/arbitrary-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAkBhC,oDAAoD;AACpD,MAAM,kBAAkB,GAAG;IACzB,6DAA6D;IAC7D,KAAK,EAAE,+GAA+G;IAEtH,gDAAgD;IAChD,OAAO,EAAE,yHAAyH;IAElI,mDAAmD;IACnD,IAAI,EAAE,sDAAsD;IAE5D,wCAAwC;IACxC,QAAQ,EAAE,0CAA0C;IAEpD,yBAAyB;IACzB,KAAK,EAAE,wBAAwB;CAChC,CAAC;AAEF,MAAM,OAAO,sBAAsB;IACzB,MAAM,CAA0B;IAExC,YAAY,MAA+B;QACzC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC3C,MAAM,eAAe,GAAqB,EAAE,CAAC;QAE7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACnC,eAAe,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAClC,CAAC;QAED,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,oBAAoB;QACxB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI;YACtC,WAAW;YACX,UAAU;YACV,UAAU;YACV,UAAU;YACV,aAAa;YACb,YAAY;YACZ,UAAU;YACV,gBAAgB;YAChB,UAAU;YACV,WAAW;YACX,aAAa;SACd,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI;YACpC,oBAAoB;YACpB,YAAY;YACZ,aAAa;YACb,aAAa;YACb,cAAc;SACf,CAAC;QAEF,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;gBAClC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;gBAC5B,MAAM;gBACN,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YACH,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChC,CAAC;IAEO,QAAQ,CAAC,QAAgB;QAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,MAAM,GAAqB,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAEjE,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC;YACxD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAE,CAAC;YAE7B,mCAAmC;YACnC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5D,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;oBACrC,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,KAAK,CAAC,CAAC,CAAE;wBAChB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;wBACnB,IAAI,EAAE,YAAY;wBAClB,IAAI,EAAE,OAAO,GAAG,CAAC;wBACjB,MAAM,EAAE,KAAK,CAAC,KAAM,GAAG,CAAC;qBACzB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,qCAAqC;YACrC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9D,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,SAAS;oBACf,KAAK,EAAE,KAAK,CAAC,CAAC,CAAE;oBAChB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;oBACnB,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,OAAO,GAAG,CAAC;oBACjB,MAAM,EAAE,KAAK,CAAC,KAAM,GAAG,CAAC;iBACzB,CAAC,CAAC;YACL,CAAC;YAED,kCAAkC;YAClC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3D,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE,KAAK,CAAC,CAAC,CAAE;oBAChB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;oBACnB,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,OAAO,GAAG,CAAC;oBACjB,MAAM,EAAE,KAAK,CAAC,KAAM,GAAG,CAAC;iBACzB,CAAC,CAAC;YACL,CAAC;YAED,uCAAuC;YACvC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC/D,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE,KAAK,CAAC,CAAC,CAAE;oBAChB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;oBACnB,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,OAAO,GAAG,CAAC;oBACjB,MAAM,EAAE,KAAK,CAAC,KAAM,GAAG,CAAC;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,gBAAgB,CAAC,KAAa;QACpC,4BAA4B;QAC5B,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kCAAkC;QAClC,IAAI,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,wDAAwD;QACxD,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,oBAAoB,CAAC,MAAwB;QACnD,qCAAqC;QACrC,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;QACnD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,OAAO,GAAkB,EAAE,CAAC;QAElC,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,EAAE,CAAC;YACxC,4BAA4B;YAC5B,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;YAC7D,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;YAExD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CACjC,OAAO,EACP,IAAI,EACJ,MAAM,EACN,GAAG,MAAM,CAAC,MAAM,mBAAmB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,mCAAmC,CACnG,CAAC,CAAC;YACL,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CACjC,SAAS,EACT,IAAI,EACJ,OAAO,EACP,GAAG,OAAO,CAAC,MAAM,2BAA2B,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,oCAAoC,CAC9G,CAAC,CAAC;YACL,CAAC;YAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CACjC,MAAM,EACN,IAAI,EACJ,KAAK,EACL,GAAG,KAAK,CAAC,MAAM,wBAAwB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,sCAAsC,CACzG,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,iBAAiB,CACvB,SAAiB,EACjB,IAAY,EACZ,MAAwB,EACxB,OAAe;QAEf,MAAM,MAAM,GAAgB;YAC1B,UAAU,EAAE,WAAW,EAAE,uDAAuD;YAChF,QAAQ,EAAE,YAAY,IAAI,EAAE;YAC5B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,GAAG,IAAI,IAAI,MAAM,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE;SACvC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAC1C,GAAG,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,IAAI,EAAE,CACnC,CAAC;QAEF,OAAO;YACL,EAAE,EAAE,kCAAkC,IAAI,IAAI,SAAS,EAAE;YACzD,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;YACpD,MAAM;YACN,OAAO;YACP,OAAO,EAAE;gBACP,QAAQ,EAAE,2BAA2B;gBACrC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,cAAc,SAAS,SAAS;gBACxD,aAAa,EAAE,CAAC,IAAI,CAAC;gBACrB,WAAW,EAAE;oBACX,SAAS,KAAK,OAAO;wBACnB,CAAC,CAAC,8EAA8E;wBAChF,CAAC,CAAC,sEAAsE;oBAC1E,iEAAiE;oBACjE,aAAa,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBAC/C;aACF;YACD,UAAU,EAAE,IAAI,IAAI,EAAE;SACvB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { DesignToken } from '@buoy-design/core';
|
|
2
|
+
export interface TailwindTheme {
|
|
3
|
+
colors: Record<string, string | Record<string, string>>;
|
|
4
|
+
spacing: Record<string, string>;
|
|
5
|
+
fontSize: Record<string, string | [string, Record<string, string>]>;
|
|
6
|
+
fontFamily: Record<string, string[]>;
|
|
7
|
+
borderRadius: Record<string, string>;
|
|
8
|
+
boxShadow: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
export interface ParsedTailwindConfig {
|
|
11
|
+
theme: Partial<TailwindTheme>;
|
|
12
|
+
tokens: DesignToken[];
|
|
13
|
+
configPath: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class TailwindConfigParser {
|
|
16
|
+
private projectRoot;
|
|
17
|
+
constructor(projectRoot: string);
|
|
18
|
+
parse(): Promise<ParsedTailwindConfig | null>;
|
|
19
|
+
private findConfigFile;
|
|
20
|
+
private extractTheme;
|
|
21
|
+
private extractObjectFromConfig;
|
|
22
|
+
private parseObjectLiteral;
|
|
23
|
+
private themeToTokens;
|
|
24
|
+
private createColorToken;
|
|
25
|
+
private createSpacingToken;
|
|
26
|
+
private createShadowToken;
|
|
27
|
+
private createRawToken;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=config-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-parser.d.ts","sourceRoot":"","sources":["../src/config-parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,mBAAmB,CAAC;AAGlE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACpE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAEnC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,WAAW,CAAS;gBAEhB,WAAW,EAAE,MAAM;IAIzB,KAAK,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAqBnD,OAAO,CAAC,cAAc;YAkBR,YAAY;IAqD1B,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,kBAAkB;IA8B1B,OAAO,CAAC,aAAa;IA+CrB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,cAAc;CAkBvB"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import { createTokenId } from '@buoy-design/core';
|
|
4
|
+
export class TailwindConfigParser {
|
|
5
|
+
projectRoot;
|
|
6
|
+
constructor(projectRoot) {
|
|
7
|
+
this.projectRoot = projectRoot;
|
|
8
|
+
}
|
|
9
|
+
async parse() {
|
|
10
|
+
const configPath = this.findConfigFile();
|
|
11
|
+
if (!configPath) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const theme = await this.extractTheme(configPath);
|
|
16
|
+
const tokens = this.themeToTokens(theme, configPath);
|
|
17
|
+
return {
|
|
18
|
+
theme,
|
|
19
|
+
tokens,
|
|
20
|
+
configPath,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
console.error('Failed to parse Tailwind config:', err);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
findConfigFile() {
|
|
29
|
+
const configNames = [
|
|
30
|
+
'tailwind.config.js',
|
|
31
|
+
'tailwind.config.ts',
|
|
32
|
+
'tailwind.config.mjs',
|
|
33
|
+
'tailwind.config.cjs',
|
|
34
|
+
];
|
|
35
|
+
for (const name of configNames) {
|
|
36
|
+
const path = resolve(this.projectRoot, name);
|
|
37
|
+
if (existsSync(path)) {
|
|
38
|
+
return path;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
async extractTheme(configPath) {
|
|
44
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
45
|
+
// Try to extract theme object using regex (basic parsing)
|
|
46
|
+
// For full support, we'd need to actually evaluate the config
|
|
47
|
+
const theme = {
|
|
48
|
+
colors: {},
|
|
49
|
+
spacing: {},
|
|
50
|
+
fontSize: {},
|
|
51
|
+
fontFamily: {},
|
|
52
|
+
borderRadius: {},
|
|
53
|
+
boxShadow: {},
|
|
54
|
+
};
|
|
55
|
+
// Extract colors from theme.extend.colors or theme.colors
|
|
56
|
+
const colorMatches = this.extractObjectFromConfig(content, 'colors');
|
|
57
|
+
if (colorMatches) {
|
|
58
|
+
theme.colors = this.parseObjectLiteral(colorMatches);
|
|
59
|
+
}
|
|
60
|
+
// Extract spacing
|
|
61
|
+
const spacingMatches = this.extractObjectFromConfig(content, 'spacing');
|
|
62
|
+
if (spacingMatches) {
|
|
63
|
+
theme.spacing = this.parseObjectLiteral(spacingMatches);
|
|
64
|
+
}
|
|
65
|
+
// Extract fontSize
|
|
66
|
+
const fontSizeMatches = this.extractObjectFromConfig(content, 'fontSize');
|
|
67
|
+
if (fontSizeMatches) {
|
|
68
|
+
theme.fontSize = this.parseObjectLiteral(fontSizeMatches);
|
|
69
|
+
}
|
|
70
|
+
// Extract fontFamily
|
|
71
|
+
const fontFamilyMatches = this.extractObjectFromConfig(content, 'fontFamily');
|
|
72
|
+
if (fontFamilyMatches) {
|
|
73
|
+
theme.fontFamily = this.parseObjectLiteral(fontFamilyMatches);
|
|
74
|
+
}
|
|
75
|
+
// Extract borderRadius
|
|
76
|
+
const borderRadiusMatches = this.extractObjectFromConfig(content, 'borderRadius');
|
|
77
|
+
if (borderRadiusMatches) {
|
|
78
|
+
theme.borderRadius = this.parseObjectLiteral(borderRadiusMatches);
|
|
79
|
+
}
|
|
80
|
+
// Extract boxShadow
|
|
81
|
+
const boxShadowMatches = this.extractObjectFromConfig(content, 'boxShadow');
|
|
82
|
+
if (boxShadowMatches) {
|
|
83
|
+
theme.boxShadow = this.parseObjectLiteral(boxShadowMatches);
|
|
84
|
+
}
|
|
85
|
+
return theme;
|
|
86
|
+
}
|
|
87
|
+
extractObjectFromConfig(content, key) {
|
|
88
|
+
// Match patterns like: colors: { ... } or colors: { ... },
|
|
89
|
+
const patterns = [
|
|
90
|
+
new RegExp(`${key}:\\s*\\{([^{}]*(?:\\{[^{}]*\\}[^{}]*)*)\\}`, 's'),
|
|
91
|
+
new RegExp(`['"]${key}['"]:\\s*\\{([^{}]*(?:\\{[^{}]*\\}[^{}]*)*)\\}`, 's'),
|
|
92
|
+
];
|
|
93
|
+
for (const pattern of patterns) {
|
|
94
|
+
const match = content.match(pattern);
|
|
95
|
+
if (match) {
|
|
96
|
+
return match[1] || null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
parseObjectLiteral(content) {
|
|
102
|
+
const result = {};
|
|
103
|
+
// Simple key-value extraction
|
|
104
|
+
// Matches: key: 'value' or key: "value" or 'key': 'value'
|
|
105
|
+
const kvPattern = /['"]?(\w+[-\w]*)['"]?\s*:\s*['"]([^'"]+)['"]/g;
|
|
106
|
+
let match;
|
|
107
|
+
while ((match = kvPattern.exec(content)) !== null) {
|
|
108
|
+
result[match[1]] = match[2];
|
|
109
|
+
}
|
|
110
|
+
// Also try to match nested objects for color scales
|
|
111
|
+
const nestedPattern = /['"]?(\w+[-\w]*)['"]?\s*:\s*\{([^{}]+)\}/g;
|
|
112
|
+
while ((match = nestedPattern.exec(content)) !== null) {
|
|
113
|
+
const nestedObj = {};
|
|
114
|
+
const nestedContent = match[2];
|
|
115
|
+
const nestedKv = /['"]?(\w+[-\w]*)['"]?\s*:\s*['"]([^'"]+)['"]/g;
|
|
116
|
+
let nestedMatch;
|
|
117
|
+
while ((nestedMatch = nestedKv.exec(nestedContent)) !== null) {
|
|
118
|
+
nestedObj[nestedMatch[1]] = nestedMatch[2];
|
|
119
|
+
}
|
|
120
|
+
if (Object.keys(nestedObj).length > 0) {
|
|
121
|
+
result[match[1]] = nestedObj;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
themeToTokens(theme, configPath) {
|
|
127
|
+
const tokens = [];
|
|
128
|
+
const relativePath = configPath.replace(this.projectRoot + '/', '');
|
|
129
|
+
const source = {
|
|
130
|
+
type: 'json', // Closest match for config file
|
|
131
|
+
path: relativePath,
|
|
132
|
+
};
|
|
133
|
+
// Convert colors to tokens
|
|
134
|
+
if (theme.colors) {
|
|
135
|
+
for (const [name, value] of Object.entries(theme.colors)) {
|
|
136
|
+
if (typeof value === 'string') {
|
|
137
|
+
tokens.push(this.createColorToken(name, value, source));
|
|
138
|
+
}
|
|
139
|
+
else if (typeof value === 'object') {
|
|
140
|
+
// Color scale (e.g., gray: { 100: '#...', 200: '#...' })
|
|
141
|
+
for (const [shade, color] of Object.entries(value)) {
|
|
142
|
+
tokens.push(this.createColorToken(`${name}-${shade}`, color, source));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Convert spacing to tokens
|
|
148
|
+
if (theme.spacing) {
|
|
149
|
+
for (const [name, value] of Object.entries(theme.spacing)) {
|
|
150
|
+
tokens.push(this.createSpacingToken(name, value, source));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Convert boxShadow to tokens
|
|
154
|
+
if (theme.boxShadow) {
|
|
155
|
+
for (const [name, value] of Object.entries(theme.boxShadow)) {
|
|
156
|
+
tokens.push(this.createShadowToken(name, value, source));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Convert borderRadius to tokens
|
|
160
|
+
if (theme.borderRadius) {
|
|
161
|
+
for (const [name, value] of Object.entries(theme.borderRadius)) {
|
|
162
|
+
tokens.push(this.createRawToken(`radius-${name}`, value, 'border', source));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return tokens;
|
|
166
|
+
}
|
|
167
|
+
createColorToken(name, hex, source) {
|
|
168
|
+
return {
|
|
169
|
+
id: createTokenId(source, `tw-${name}`),
|
|
170
|
+
name: `tw-${name}`,
|
|
171
|
+
category: 'color',
|
|
172
|
+
value: { type: 'color', hex },
|
|
173
|
+
source,
|
|
174
|
+
aliases: [name],
|
|
175
|
+
usedBy: [],
|
|
176
|
+
metadata: { tags: ['tailwind'] },
|
|
177
|
+
scannedAt: new Date(),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
createSpacingToken(name, value, source) {
|
|
181
|
+
// Parse spacing value (e.g., '1rem', '4px')
|
|
182
|
+
const numMatch = value.match(/^([\d.]+)(rem|px|em)?$/);
|
|
183
|
+
if (numMatch) {
|
|
184
|
+
const num = parseFloat(numMatch[1]);
|
|
185
|
+
const unit = numMatch[2] || 'px';
|
|
186
|
+
return {
|
|
187
|
+
id: createTokenId(source, `tw-spacing-${name}`),
|
|
188
|
+
name: `tw-spacing-${name}`,
|
|
189
|
+
category: 'spacing',
|
|
190
|
+
value: { type: 'spacing', value: num, unit },
|
|
191
|
+
source,
|
|
192
|
+
aliases: [name],
|
|
193
|
+
usedBy: [],
|
|
194
|
+
metadata: { tags: ['tailwind'] },
|
|
195
|
+
scannedAt: new Date(),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return this.createRawToken(`spacing-${name}`, value, 'spacing', source);
|
|
199
|
+
}
|
|
200
|
+
createShadowToken(name, value, source) {
|
|
201
|
+
return {
|
|
202
|
+
id: createTokenId(source, `tw-shadow-${name}`),
|
|
203
|
+
name: `tw-shadow-${name}`,
|
|
204
|
+
category: 'shadow',
|
|
205
|
+
value: { type: 'raw', value },
|
|
206
|
+
source,
|
|
207
|
+
aliases: [name],
|
|
208
|
+
usedBy: [],
|
|
209
|
+
metadata: { tags: ['tailwind'] },
|
|
210
|
+
scannedAt: new Date(),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
createRawToken(name, value, category, source) {
|
|
214
|
+
return {
|
|
215
|
+
id: createTokenId(source, `tw-${name}`),
|
|
216
|
+
name: `tw-${name}`,
|
|
217
|
+
category,
|
|
218
|
+
value: { type: 'raw', value },
|
|
219
|
+
source,
|
|
220
|
+
aliases: [],
|
|
221
|
+
usedBy: [],
|
|
222
|
+
metadata: { tags: ['tailwind'] },
|
|
223
|
+
scannedAt: new Date(),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=config-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-parser.js","sourceRoot":"","sources":["../src/config-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { TailwindScanner, type TailwindScannerConfig } from './scanner.js';
|
|
2
|
+
export { TailwindConfigParser, type TailwindTheme } from './config-parser.js';
|
|
3
|
+
export { ArbitraryValueDetector, type ArbitraryValue } from './arbitrary-detector.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAA8B,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAsB,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAuB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DesignToken, DriftSignal } from '@buoy-design/core';
|
|
2
|
+
export interface TailwindScannerConfig {
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
include?: string[];
|
|
5
|
+
exclude?: string[];
|
|
6
|
+
/** Whether to scan for arbitrary values (default: true) */
|
|
7
|
+
detectArbitraryValues?: boolean;
|
|
8
|
+
/** Whether to extract theme tokens from config (default: true) */
|
|
9
|
+
extractThemeTokens?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface TailwindScanResult {
|
|
12
|
+
tokens: DesignToken[];
|
|
13
|
+
drifts: DriftSignal[];
|
|
14
|
+
configPath: string | null;
|
|
15
|
+
stats: {
|
|
16
|
+
filesScanned: number;
|
|
17
|
+
arbitraryValuesFound: number;
|
|
18
|
+
tokensExtracted: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare class TailwindScanner {
|
|
22
|
+
private config;
|
|
23
|
+
constructor(config: TailwindScannerConfig);
|
|
24
|
+
scan(): Promise<TailwindScanResult>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIlE,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,2DAA2D;IAC3D,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAwB;gBAE1B,MAAM,EAAE,qBAAqB;IAQnC,IAAI,IAAI,OAAO,CAAC,kBAAkB,CAAC;CA0C1C"}
|
package/dist/scanner.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { TailwindConfigParser } from './config-parser.js';
|
|
2
|
+
import { ArbitraryValueDetector } from './arbitrary-detector.js';
|
|
3
|
+
export class TailwindScanner {
|
|
4
|
+
config;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = {
|
|
7
|
+
detectArbitraryValues: true,
|
|
8
|
+
extractThemeTokens: true,
|
|
9
|
+
...config,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
async scan() {
|
|
13
|
+
const result = {
|
|
14
|
+
tokens: [],
|
|
15
|
+
drifts: [],
|
|
16
|
+
configPath: null,
|
|
17
|
+
stats: {
|
|
18
|
+
filesScanned: 0,
|
|
19
|
+
arbitraryValuesFound: 0,
|
|
20
|
+
tokensExtracted: 0,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
// Extract theme tokens from tailwind.config.js
|
|
24
|
+
if (this.config.extractThemeTokens) {
|
|
25
|
+
const parser = new TailwindConfigParser(this.config.projectRoot);
|
|
26
|
+
const parsed = await parser.parse();
|
|
27
|
+
if (parsed) {
|
|
28
|
+
result.tokens = parsed.tokens;
|
|
29
|
+
result.configPath = parsed.configPath;
|
|
30
|
+
result.stats.tokensExtracted = parsed.tokens.length;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Detect arbitrary values in source files
|
|
34
|
+
if (this.config.detectArbitraryValues) {
|
|
35
|
+
const detector = new ArbitraryValueDetector({
|
|
36
|
+
projectRoot: this.config.projectRoot,
|
|
37
|
+
include: this.config.include,
|
|
38
|
+
exclude: this.config.exclude,
|
|
39
|
+
});
|
|
40
|
+
const arbitraryValues = await detector.detect();
|
|
41
|
+
const driftSignals = await detector.detectAsDriftSignals();
|
|
42
|
+
result.drifts = driftSignals;
|
|
43
|
+
result.stats.arbitraryValuesFound = arbitraryValues.length;
|
|
44
|
+
result.stats.filesScanned = new Set(arbitraryValues.map(v => v.file)).size;
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAuBjE,MAAM,OAAO,eAAe;IAClB,MAAM,CAAwB;IAEtC,YAAY,MAA6B;QACvC,IAAI,CAAC,MAAM,GAAG;YACZ,qBAAqB,EAAE,IAAI;YAC3B,kBAAkB,EAAE,IAAI;YACxB,GAAG,MAAM;SACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,MAAM,GAAuB;YACjC,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,EAAE;YACV,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE;gBACL,YAAY,EAAE,CAAC;gBACf,oBAAoB,EAAE,CAAC;gBACvB,eAAe,EAAE,CAAC;aACnB;SACF,CAAC;QAEF,+CAA+C;QAC/C,IAAI,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACjE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YAEpC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;gBAC9B,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;gBACtC,MAAM,CAAC,KAAK,CAAC,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YACtD,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,IAAI,sBAAsB,CAAC;gBAC1C,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;gBACpC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;gBAC5B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;aAC7B,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;YAChD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,CAAC;YAE3D,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,oBAAoB,GAAG,eAAe,CAAC,MAAM,CAAC;YAC3D,MAAM,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7E,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@buoy-design/plugin-tailwind",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Buoy plugin for Tailwind CSS design drift detection",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Buoy <hello@buoy.design>",
|
|
8
|
+
"homepage": "https://buoy.design",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/dylantarre/buoy-design.git",
|
|
12
|
+
"directory": "packages/plugin-tailwind"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/dylantarre/buoy-design/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": ["buoy", "tailwind", "tailwindcss", "design-system", "drift-detection", "arbitrary-values"],
|
|
18
|
+
"files": ["dist", "README.md"],
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"dev": "tsc --watch",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"clean": "rm -rf dist",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"test:watch": "vitest"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@buoy-design/core": "workspace:*",
|
|
37
|
+
"glob": "^10.3.10"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"typescript": "^5.3.3",
|
|
41
|
+
"vitest": "^2.1.9"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"tailwindcss": ">=3.0.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependenciesMeta": {
|
|
47
|
+
"tailwindcss": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|