tailwind-unwind 0.1.1 → 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.
- package/README.md +64 -1
- package/dist/{chunk-N7HD4T2I.js → chunk-FASYIEVZ.js} +583 -46
- package/dist/chunk-FASYIEVZ.js.map +1 -0
- package/dist/cli/index.js +171 -26
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +66 -2
- package/dist/index.js +7 -1
- package/package.json +3 -2
- package/tailwind-unwind.config.example.json +24 -0
- package/dist/chunk-N7HD4T2I.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
import { Expression, JSXAttribute, Node } from '@babel/types';
|
|
2
2
|
|
|
3
|
+
type CliCommand = 'analyze' | 'generate' | 'apply';
|
|
4
|
+
interface CommandConfig {
|
|
5
|
+
minOccurrences?: number;
|
|
6
|
+
minSize?: number;
|
|
7
|
+
maxSize?: number;
|
|
8
|
+
top?: number;
|
|
9
|
+
prefix?: string;
|
|
10
|
+
output?: string;
|
|
11
|
+
dedupeSubsets?: boolean;
|
|
12
|
+
dryRun?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Keys are space-separated utility strings; values are base class names (without prefix). */
|
|
15
|
+
type CustomNamesConfig = Record<string, string>;
|
|
16
|
+
interface TailwindUnwindConfigFile extends CommandConfig {
|
|
17
|
+
include?: string[];
|
|
18
|
+
exclude?: string[];
|
|
19
|
+
names?: CustomNamesConfig;
|
|
20
|
+
analyze?: CommandConfig;
|
|
21
|
+
generate?: CommandConfig;
|
|
22
|
+
apply?: CommandConfig;
|
|
23
|
+
}
|
|
24
|
+
interface TailwindUnwindConfig extends CommandConfig {
|
|
25
|
+
include?: string[];
|
|
26
|
+
exclude?: string[];
|
|
27
|
+
names?: CustomNamesConfig;
|
|
28
|
+
}
|
|
29
|
+
interface ResolvedCommandOptions extends TailwindUnwindConfig {
|
|
30
|
+
configPath?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Load tailwind-unwind config for a command and merge CLI overrides on top.
|
|
35
|
+
*/
|
|
36
|
+
declare function loadCommandOptions(command: CliCommand, cliOptions: ResolvedCommandOptions, options?: {
|
|
37
|
+
cwd?: string;
|
|
38
|
+
targetPath?: string;
|
|
39
|
+
}): Promise<ResolvedCommandOptions>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Validate a parsed config object and throw with all errors at once.
|
|
43
|
+
*/
|
|
44
|
+
declare function validateConfigFile(raw: unknown, configPath: string): void;
|
|
45
|
+
declare function normalizeNamesConfig(names: CustomNamesConfig | undefined): Map<string, string>;
|
|
46
|
+
|
|
3
47
|
interface ClassNameExtraction {
|
|
4
48
|
classes: string[];
|
|
5
49
|
isDynamic: boolean;
|
|
@@ -25,6 +69,8 @@ interface ClassCombination {
|
|
|
25
69
|
occurrences: number;
|
|
26
70
|
suggestion: string;
|
|
27
71
|
locations: CombinationLocation[];
|
|
72
|
+
/** True when generate/apply can extract this exact class set */
|
|
73
|
+
extractable?: boolean;
|
|
28
74
|
}
|
|
29
75
|
interface AnalysisStats {
|
|
30
76
|
filesScanned: number;
|
|
@@ -48,6 +94,11 @@ interface AnalyzeOptions {
|
|
|
48
94
|
dedupeSubsets?: boolean;
|
|
49
95
|
/** Namespace prefix for generated component classes (default: twu-) */
|
|
50
96
|
prefix?: string;
|
|
97
|
+
include?: string[];
|
|
98
|
+
exclude?: string[];
|
|
99
|
+
configPath?: string;
|
|
100
|
+
/** Custom base class names keyed by space-separated utility strings */
|
|
101
|
+
names?: Record<string, string>;
|
|
51
102
|
}
|
|
52
103
|
|
|
53
104
|
/**
|
|
@@ -95,6 +146,10 @@ declare function calculatePotentialReduction(occurrences: ClassNameOccurrence[],
|
|
|
95
146
|
|
|
96
147
|
interface ScanProjectOptions extends PatternFinderOptions {
|
|
97
148
|
targetPath: string;
|
|
149
|
+
include?: string[];
|
|
150
|
+
exclude?: string[];
|
|
151
|
+
/** Threshold used to mark combinations as extractable by generate/apply */
|
|
152
|
+
extractableMinOccurrences?: number;
|
|
98
153
|
}
|
|
99
154
|
interface ScanProjectResult {
|
|
100
155
|
resolvedPath: string;
|
|
@@ -130,6 +185,7 @@ interface CssGeneratorOptions {
|
|
|
130
185
|
sourcePath: string;
|
|
131
186
|
combinations: ClassCombination[];
|
|
132
187
|
prefix?: string;
|
|
188
|
+
names?: CustomNamesConfig;
|
|
133
189
|
}
|
|
134
190
|
interface CssGeneratorResult {
|
|
135
191
|
css: string;
|
|
@@ -137,6 +193,7 @@ interface CssGeneratorResult {
|
|
|
137
193
|
}
|
|
138
194
|
interface AssignClassNamesOptions {
|
|
139
195
|
prefix?: string;
|
|
196
|
+
names?: CustomNamesConfig;
|
|
140
197
|
}
|
|
141
198
|
/** Assign unique, prefixed component class names. */
|
|
142
199
|
declare function assignComponentClassNames(combinations: ClassCombination[], options?: AssignClassNamesOptions): GeneratedComponent[];
|
|
@@ -149,6 +206,7 @@ declare function generateComponentCss(options: CssGeneratorOptions): CssGenerato
|
|
|
149
206
|
interface BuildComponentsOptions extends PatternFinderOptions {
|
|
150
207
|
sourcePath: string;
|
|
151
208
|
prefix?: string;
|
|
209
|
+
names?: Record<string, string>;
|
|
152
210
|
}
|
|
153
211
|
interface BuildComponentsResult {
|
|
154
212
|
components: GeneratedComponent[];
|
|
@@ -163,6 +221,7 @@ interface ClassReplacement {
|
|
|
163
221
|
line?: number;
|
|
164
222
|
from: string;
|
|
165
223
|
to: string;
|
|
224
|
+
partial?: boolean;
|
|
166
225
|
}
|
|
167
226
|
interface SkippedReplacement {
|
|
168
227
|
filePath: string;
|
|
@@ -178,6 +237,7 @@ interface ReplaceClassNamesResult {
|
|
|
178
237
|
}
|
|
179
238
|
/**
|
|
180
239
|
* Replace exact matching className/class values with generated component classes.
|
|
240
|
+
* Supports partial replacement inside cn()/clsx() when dynamic args are present.
|
|
181
241
|
*/
|
|
182
242
|
declare function replaceClassNamesInSource(source: string, replacementMap: Map<string, string>, filePath: string): ReplaceClassNamesResult;
|
|
183
243
|
|
|
@@ -241,10 +301,14 @@ declare function parseSource(source: string, filePath?: string): ParseResult;
|
|
|
241
301
|
*/
|
|
242
302
|
declare function parseFile(filePath: string): Promise<ParseResult>;
|
|
243
303
|
|
|
304
|
+
interface WalkSourceFilesOptions {
|
|
305
|
+
include?: string[];
|
|
306
|
+
exclude?: string[];
|
|
307
|
+
}
|
|
244
308
|
/**
|
|
245
309
|
* Recursively collect source files under `targetPath`, skipping common build/cache dirs.
|
|
246
310
|
*/
|
|
247
|
-
declare function walkSourceFiles(targetPath: string): Promise<string[]>;
|
|
311
|
+
declare function walkSourceFiles(targetPath: string, options?: WalkSourceFilesOptions): Promise<string[]>;
|
|
248
312
|
|
|
249
313
|
interface ConsoleReportOptions {
|
|
250
314
|
topLimit?: number;
|
|
@@ -262,4 +326,4 @@ declare const IGNORED_DIRECTORIES: readonly ["node_modules", ".next", "dist", "b
|
|
|
262
326
|
/** fast-glob ignore patterns — match directories at any depth. */
|
|
263
327
|
declare const IGNORE_PATTERNS: string[];
|
|
264
328
|
|
|
265
|
-
export { type AnalysisReport, type AnalysisStats, type AnalyzeOptions, type ApplyOptions, type ApplyResult, CLASS_MERGE_CALLEES, type ClassCombination, type ClassNameExtraction, type ClassNameOccurrence, type ClassReplacement, type CombinationLocation, type CssGeneratorOptions, type CssGeneratorResult, DEFAULT_CLASS_PREFIX, type GenerateOptions, type GenerateResult, type GeneratedComponent, IGNORED_DIRECTORIES, IGNORE_PATTERNS, type ParseResult, type ReplaceClassNamesResult, type SkippedReplacement, analyzeCommand, applyCommand, assignComponentClassNames, buildComponents, calculatePotentialReduction, dedupeSubsetCombinations, extractClassesFromExpression, extractFromJSXAttribute, findFrequentPatterns, findRepeatedClassSets, generateCombinations, generateCommand, generateComponentCss, isClassAttribute, isStrictSubset, normalizeClassPrefix, normalizeClasses, parseFile, parseSource, parseSourceToAst, printConsoleReport, printJsonReport, replaceClassNamesInSource, scanProject, splitClassString, suggestClassName, walkSourceFiles, withClassPrefix };
|
|
329
|
+
export { type AnalysisReport, type AnalysisStats, type AnalyzeOptions, type ApplyOptions, type ApplyResult, CLASS_MERGE_CALLEES, type ClassCombination, type ClassNameExtraction, type ClassNameOccurrence, type ClassReplacement, type CliCommand, type CombinationLocation, type CommandConfig, type CssGeneratorOptions, type CssGeneratorResult, type CustomNamesConfig, DEFAULT_CLASS_PREFIX, type GenerateOptions, type GenerateResult, type GeneratedComponent, IGNORED_DIRECTORIES, IGNORE_PATTERNS, type ParseResult, type ReplaceClassNamesResult, type SkippedReplacement, type TailwindUnwindConfig, type TailwindUnwindConfigFile, analyzeCommand, applyCommand, assignComponentClassNames, buildComponents, calculatePotentialReduction, dedupeSubsetCombinations, extractClassesFromExpression, extractFromJSXAttribute, findFrequentPatterns, findRepeatedClassSets, generateCombinations, generateCommand, generateComponentCss, isClassAttribute, isStrictSubset, loadCommandOptions, normalizeClassPrefix, normalizeClasses, normalizeNamesConfig, parseFile, parseSource, parseSourceToAst, printConsoleReport, printJsonReport, replaceClassNamesInSource, scanProject, splitClassString, suggestClassName, validateConfigFile, walkSourceFiles, withClassPrefix };
|
package/dist/index.js
CHANGED
|
@@ -18,8 +18,10 @@ import {
|
|
|
18
18
|
generateComponentCss,
|
|
19
19
|
isClassAttribute,
|
|
20
20
|
isStrictSubset,
|
|
21
|
+
loadCommandOptions,
|
|
21
22
|
normalizeClassPrefix,
|
|
22
23
|
normalizeClasses,
|
|
24
|
+
normalizeNamesConfig,
|
|
23
25
|
parseFile,
|
|
24
26
|
parseSource,
|
|
25
27
|
parseSourceToAst,
|
|
@@ -29,9 +31,10 @@ import {
|
|
|
29
31
|
scanProject,
|
|
30
32
|
splitClassString,
|
|
31
33
|
suggestClassName,
|
|
34
|
+
validateConfigFile,
|
|
32
35
|
walkSourceFiles,
|
|
33
36
|
withClassPrefix
|
|
34
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-FASYIEVZ.js";
|
|
35
38
|
export {
|
|
36
39
|
CLASS_MERGE_CALLEES,
|
|
37
40
|
DEFAULT_CLASS_PREFIX,
|
|
@@ -52,8 +55,10 @@ export {
|
|
|
52
55
|
generateComponentCss,
|
|
53
56
|
isClassAttribute,
|
|
54
57
|
isStrictSubset,
|
|
58
|
+
loadCommandOptions,
|
|
55
59
|
normalizeClassPrefix,
|
|
56
60
|
normalizeClasses,
|
|
61
|
+
normalizeNamesConfig,
|
|
57
62
|
parseFile,
|
|
58
63
|
parseSource,
|
|
59
64
|
parseSourceToAst,
|
|
@@ -63,6 +68,7 @@ export {
|
|
|
63
68
|
scanProject,
|
|
64
69
|
splitClassString,
|
|
65
70
|
suggestClassName,
|
|
71
|
+
validateConfigFile,
|
|
66
72
|
walkSourceFiles,
|
|
67
73
|
withClassPrefix
|
|
68
74
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwind-unwind",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Analyze Tailwind CSS class usage patterns in React/Next.js projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"bin",
|
|
13
13
|
"dist",
|
|
14
|
-
"LICENSE"
|
|
14
|
+
"LICENSE",
|
|
15
|
+
"tailwind-unwind.config.example.json"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
|
17
18
|
"build": "tsup",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": ["src/**/*.tsx", "src/**/*.jsx"],
|
|
3
|
+
"exclude": ["**/*.test.tsx", "**/*.stories.tsx"],
|
|
4
|
+
"names": {
|
|
5
|
+
"flex items-center justify-between p-4": "page-header",
|
|
6
|
+
"w-full h-auto object-cover rounded-lg": "media-cover"
|
|
7
|
+
},
|
|
8
|
+
"analyze": {
|
|
9
|
+
"minOccurrences": 5,
|
|
10
|
+
"top": 10,
|
|
11
|
+
"dedupeSubsets": true
|
|
12
|
+
},
|
|
13
|
+
"generate": {
|
|
14
|
+
"minOccurrences": 3,
|
|
15
|
+
"prefix": "twu-",
|
|
16
|
+
"output": "src/styles/components.css",
|
|
17
|
+
"top": 20
|
|
18
|
+
},
|
|
19
|
+
"apply": {
|
|
20
|
+
"minOccurrences": 3,
|
|
21
|
+
"prefix": "twu-",
|
|
22
|
+
"output": "src/styles/components.css"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/analyzer/suggestions.ts","../src/analyzer/dedupe.ts","../src/analyzer/combiner.ts","../src/analyzer/patternFinder.ts","../src/parser/classHelpers.ts","../src/parser/ast.ts","../src/parser/jsxParser.ts","../src/scanner/ignore.ts","../src/scanner/fileWalker.ts","../src/core/scanProject.ts","../src/reporters/consoleReporter.ts","../src/reporters/jsonReporter.ts","../src/commands/analyze.ts","../src/codemod/replaceClassNames.ts","../src/generator/classPrefix.ts","../src/generator/cssGenerator.ts","../src/core/buildComponents.ts","../src/commands/apply.ts","../src/commands/generate.ts"],"sourcesContent":["const BREAKPOINT_PREFIX = /^(sm|md|lg|xl|2xl):/;\n\nfunction baseClass(cls: string): string {\n return cls.replace(BREAKPOINT_PREFIX, '');\n}\n\nfunction has(classes: string[], name: string): boolean {\n return classes.some((cls) => baseClass(cls) === name);\n}\n\nfunction hasPrefix(classes: string[], prefix: string): boolean {\n return classes.some((cls) => baseClass(cls).startsWith(prefix));\n}\n\nfunction hasAll(classes: string[], names: string[]): boolean {\n return names.every((name) => has(classes, name));\n}\n\nfunction hasAny(classes: string[], names: string[]): boolean {\n return names.some((name) => has(classes, name));\n}\n\nfunction hasAnyPrefix(classes: string[], prefixes: string[]): boolean {\n return prefixes.some((prefix) => hasPrefix(classes, prefix));\n}\n\nfunction hasPadding(classes: string[]): boolean {\n return hasAnyPrefix(classes, ['p-', 'px-', 'py-', 'pt-', 'pb-', 'pl-', 'pr-']);\n}\n\nfunction hasMargin(classes: string[]): boolean {\n return hasAnyPrefix(classes, ['m-', 'mx-', 'my-', 'mt-', 'mb-', 'ml-', 'mr-']);\n}\n\nfunction hasGap(classes: string[]): boolean {\n return hasPrefix(classes, 'gap-') || hasPrefix(classes, 'gap-x-') || hasPrefix(classes, 'gap-y-');\n}\n\nfunction hasShadow(classes: string[]): boolean {\n return hasPrefix(classes, 'shadow-');\n}\n\nfunction hasRing(classes: string[]): boolean {\n return hasPrefix(classes, 'ring-');\n}\n\nfunction isFullWidth(classes: string[]): boolean {\n return has(classes, 'w-full');\n}\n\nfunction gridColumnCount(classes: string[]): string | null {\n const colClass = classes.find((cls) => baseClass(cls).startsWith('grid-cols-'));\n if (!colClass) return null;\n return baseClass(colClass).replace('grid-cols-', '');\n}\n\nfunction iconSize(classes: string[]): boolean {\n return hasAny(classes, ['w-4', 'h-4', 'w-5', 'h-5', 'w-6', 'h-6', 'size-4', 'size-5', 'size-6']);\n}\n\ninterface NamingRule {\n name: string;\n match: (classes: string[]) => boolean;\n}\n\n/**\n * Ordered from most specific to general — first match wins.\n * Names describe UI intent, not utility lists.\n */\nconst SEMANTIC_RULES: NamingRule[] = [\n // ── Navigation & chrome ──────────────────────────────────────────\n {\n name: 'page-header',\n match: (c) =>\n hasAll(c, ['flex', 'items-center', 'justify-between']) &&\n (hasPadding(c) || hasPrefix(c, 'border-b')),\n },\n {\n name: 'toolbar',\n match: (c) => hasAll(c, ['flex', 'items-center', 'justify-between']),\n },\n {\n name: 'footer-bar',\n match: (c) =>\n has(c, 'flex') && hasPrefix(c, 'border-t') && hasPadding(c),\n },\n {\n name: 'action-bar',\n match: (c) =>\n hasAll(c, ['flex', 'items-center', 'justify-end']) && hasPadding(c),\n },\n {\n name: 'breadcrumb',\n match: (c) =>\n hasAll(c, ['flex', 'items-center']) &&\n hasGap(c) &&\n hasAny(c, ['text-sm', 'text-xs']),\n },\n {\n name: 'nav-item',\n match: (c) =>\n hasAll(c, ['flex', 'items-center']) && hasGap(c) && hasPadding(c),\n },\n {\n name: 'sidebar',\n match: (c) =>\n hasAll(c, ['flex', 'flex-col']) &&\n (has(c, 'h-full') || has(c, 'h-screen') || hasPrefix(c, 'w-')),\n },\n {\n name: 'tab-bar',\n match: (c) =>\n has(c, 'flex') && hasPrefix(c, 'border-b') && hasGap(c),\n },\n\n // ── Flex layout ──────────────────────────────────────────────────\n {\n name: 'centered-row',\n match: (c) => hasAll(c, ['flex', 'items-center', 'justify-center']),\n },\n {\n name: 'spread-row',\n match: (c) => has(c, 'flex') && has(c, 'justify-between'),\n },\n {\n name: 'aligned-row',\n match: (c) => hasAll(c, ['flex', 'items-center']),\n },\n {\n name: 'inline-actions',\n match: (c) => has(c, 'inline-flex') && has(c, 'items-center'),\n },\n {\n name: 'wrap-row',\n match: (c) => has(c, 'flex') && has(c, 'flex-wrap'),\n },\n {\n name: 'form-row',\n match: (c) => hasAll(c, ['flex', 'flex-col']) && hasGap(c),\n },\n {\n name: 'stack',\n match: (c) => hasAll(c, ['flex', 'flex-col']),\n },\n {\n name: 'row',\n match: (c) => has(c, 'flex'),\n },\n\n // ── Grid layout ──────────────────────────────────────────────────\n {\n name: 'photo-grid',\n match: (c) => has(c, 'grid') && hasPrefix(c, 'grid-cols-') && has(c, 'object-cover'),\n },\n {\n name: 'card-grid',\n match: (c) => has(c, 'grid') && hasGap(c) && hasPrefix(c, 'grid-cols-'),\n },\n {\n name: 'grid',\n match: (c) => has(c, 'grid'),\n },\n\n // ── Media & images ───────────────────────────────────────────────\n {\n name: 'media-cover',\n match: (c) => has(c, 'object-cover') && isFullWidth(c),\n },\n {\n name: 'media-contain',\n match: (c) => has(c, 'object-contain') && isFullWidth(c),\n },\n {\n name: 'aspect-video',\n match: (c) => has(c, 'aspect-video'),\n },\n {\n name: 'aspect-square',\n match: (c) => has(c, 'aspect-square'),\n },\n {\n name: 'avatar',\n match: (c) =>\n has(c, 'rounded-full') &&\n (hasPrefix(c, 'w-') || hasPrefix(c, 'h-') || hasPrefix(c, 'size-')) &&\n hasPrefix(c, 'object-'),\n },\n {\n name: 'thumbnail',\n match: (c) =>\n has(c, 'object-cover') &&\n hasAnyPrefix(c, ['w-16', 'w-12', 'w-20', 'h-16', 'h-12', 'h-20']),\n },\n {\n name: 'icon',\n match: (c) => iconSize(c) && !has(c, 'flex'),\n },\n {\n name: 'logo',\n match: (c) => hasAny(c, ['h-8', 'h-6', 'h-10']) && has(c, 'w-auto'),\n },\n {\n name: 'media-frame',\n match: (c) => isFullWidth(c) && has(c, 'h-auto'),\n },\n\n // ── Interactive (before surfaces — shares bg-/rounded-/px-) ─────\n {\n name: 'badge',\n match: (c) =>\n has(c, 'rounded-full') &&\n hasAnyPrefix(c, ['px-', 'py-']) &&\n hasAny(c, ['text-xs', 'text-sm']),\n },\n {\n name: 'chip',\n match: (c) =>\n hasAnyPrefix(c, ['px-', 'py-']) &&\n !has(c, 'rounded-full') &&\n hasPrefix(c, 'rounded-') &&\n hasAny(c, ['text-xs', 'text-sm']),\n },\n {\n name: 'tag',\n match: (c) =>\n hasAnyPrefix(c, ['px-2', 'px-3']) &&\n hasAnyPrefix(c, ['py-0', 'py-1']) &&\n hasPrefix(c, 'rounded-md'),\n },\n {\n name: 'icon-button',\n match: (c) =>\n hasAnyPrefix(c, ['p-1', 'p-1.5', 'p-2', 'p-3']) &&\n hasPrefix(c, 'rounded-') &&\n !hasAnyPrefix(c, ['px-4', 'px-5', 'px-6', 'px-8']),\n },\n {\n name: 'primary-button',\n match: (c) =>\n hasAnyPrefix(c, ['px-', 'py-']) &&\n hasPrefix(c, 'rounded-') &&\n hasAnyPrefix(c, ['bg-blue', 'bg-indigo', 'bg-primary', 'bg-violet']),\n },\n {\n name: 'danger-button',\n match: (c) =>\n hasAnyPrefix(c, ['px-', 'py-']) &&\n hasPrefix(c, 'rounded-') &&\n hasAnyPrefix(c, ['bg-red', 'bg-rose', 'bg-destructive']),\n },\n {\n name: 'ghost-button',\n match: (c) =>\n hasAnyPrefix(c, ['px-', 'py-']) &&\n hasPrefix(c, 'rounded-') &&\n hasAnyPrefix(c, ['hover:bg-', 'bg-transparent']),\n },\n {\n name: 'input',\n match: (c) =>\n hasAnyPrefix(c, ['px-', 'py-']) &&\n hasPrefix(c, 'border') &&\n hasPrefix(c, 'rounded-'),\n },\n {\n name: 'textarea',\n match: (c) =>\n hasPrefix(c, 'border') &&\n hasPrefix(c, 'rounded-') &&\n hasAny(c, ['resize-none', 'min-h-']),\n },\n {\n name: 'select',\n match: (c) =>\n hasPrefix(c, 'border') &&\n hasPrefix(c, 'rounded-') &&\n has(c, 'appearance-none'),\n },\n {\n name: 'checkbox-row',\n match: (c) =>\n hasAll(c, ['flex', 'items-center']) && hasGap(c) && hasAny(c, ['text-sm', 'text-base']),\n },\n {\n name: 'button',\n match: (c) =>\n hasAnyPrefix(c, ['px-', 'py-']) && hasPrefix(c, 'rounded-'),\n },\n\n // ── Surfaces & containers ────────────────────────────────────────\n {\n name: 'page-container',\n match: (c) => has(c, 'mx-auto') && hasPrefix(c, 'max-w-'),\n },\n {\n name: 'section',\n match: (c) => hasPadding(c) && hasMargin(c) && !has(c, 'flex') && !has(c, 'grid'),\n },\n {\n name: 'hero',\n match: (c) =>\n hasPadding(c) &&\n hasAny(c, ['text-center', 'justify-center']) &&\n hasAnyPrefix(c, ['text-3xl', 'text-4xl', 'text-5xl']),\n },\n {\n name: 'alert',\n match: (c) =>\n hasAnyPrefix(c, ['border-l-4', 'border-l-2']) &&\n hasPadding(c) &&\n hasPrefix(c, 'bg-'),\n },\n {\n name: 'callout',\n match: (c) =>\n hasPrefix(c, 'bg-') && hasPadding(c) && hasPrefix(c, 'border') && hasPrefix(c, 'rounded-'),\n },\n {\n name: 'panel',\n match: (c) =>\n hasPrefix(c, 'rounded-') && hasPadding(c) && hasPrefix(c, 'border'),\n },\n {\n name: 'card',\n match: (c) =>\n hasPrefix(c, 'rounded-') && hasPadding(c) && hasPrefix(c, 'bg-'),\n },\n {\n name: 'elevated-card',\n match: (c) =>\n hasShadow(c) && hasPrefix(c, 'rounded-') && hasPadding(c),\n },\n {\n name: 'surface',\n match: (c) => hasPrefix(c, 'bg-') && hasPadding(c),\n },\n\n // ── Overlays & positioning ───────────────────────────────────────\n {\n name: 'backdrop',\n match: (c) =>\n has(c, 'fixed') && has(c, 'inset-0') && hasAnyPrefix(c, ['bg-black', 'bg-white', 'bg-gray']),\n },\n {\n name: 'overlay',\n match: (c) => has(c, 'fixed') && has(c, 'inset-0'),\n },\n {\n name: 'modal-shell',\n match: (c) =>\n has(c, 'fixed') && hasAll(c, ['flex', 'items-center', 'justify-center']),\n },\n {\n name: 'drawer',\n match: (c) =>\n has(c, 'fixed') &&\n hasAny(c, ['inset-y-0', 'top-0', 'bottom-0']) &&\n hasPrefix(c, 'w-'),\n },\n {\n name: 'sticky-header',\n match: (c) =>\n has(c, 'sticky') && hasPrefix(c, 'top-') && hasPrefix(c, 'z-'),\n },\n {\n name: 'dropdown',\n match: (c) =>\n has(c, 'absolute') && hasPrefix(c, 'z-') && hasPrefix(c, 'rounded-') && hasShadow(c),\n },\n\n // ── Typography ───────────────────────────────────────────────────\n {\n name: 'prose',\n match: (c) => hasPrefix(c, 'prose'),\n },\n {\n name: 'heading',\n match: (c) =>\n hasAnyPrefix(c, ['text-xl', 'text-2xl', 'text-3xl', 'text-4xl', 'text-5xl']) &&\n hasPrefix(c, 'font-'),\n },\n {\n name: 'title',\n match: (c) =>\n hasAnyPrefix(c, ['text-lg', 'text-xl', 'text-2xl']) && hasPrefix(c, 'font-semibold'),\n },\n {\n name: 'subtitle',\n match: (c) =>\n hasAnyPrefix(c, ['text-base', 'text-lg']) && hasPrefix(c, 'text-gray'),\n },\n {\n name: 'label',\n match: (c) =>\n hasAny(c, ['text-xs', 'text-sm']) && hasAnyPrefix(c, ['font-medium', 'font-semibold']),\n },\n {\n name: 'caption',\n match: (c) =>\n hasAny(c, ['text-sm', 'text-xs']) &&\n hasPrefix(c, 'font-') &&\n !hasAnyPrefix(c, ['font-medium', 'font-semibold']),\n },\n {\n name: 'muted',\n match: (c) =>\n hasAnyPrefix(c, ['text-gray', 'text-slate', 'text-zinc', 'text-neutral']),\n },\n {\n name: 'error-text',\n match: (c) => hasAnyPrefix(c, ['text-red', 'text-rose', 'text-destructive']),\n },\n {\n name: 'link',\n match: (c) =>\n has(c, 'underline') ||\n hasAnyPrefix(c, ['text-blue', 'text-indigo', 'text-primary']),\n },\n {\n name: 'truncate',\n match: (c) => has(c, 'truncate') || has(c, 'line-clamp-1'),\n },\n\n // ── Lists & tables ───────────────────────────────────────────────\n {\n name: 'table-header',\n match: (c) =>\n hasAnyPrefix(c, ['text-xs', 'uppercase']) &&\n hasAnyPrefix(c, ['font-medium', 'font-semibold', 'tracking-']),\n },\n {\n name: 'table-row',\n match: (c) => hasPrefix(c, 'border-b') && hasAll(c, ['flex', 'items-center']),\n },\n {\n name: 'list-item',\n match: (c) =>\n hasAll(c, ['flex', 'items-center']) && hasGap(c) && hasPadding(c),\n },\n {\n name: 'menu-item',\n match: (c) =>\n hasAll(c, ['flex', 'items-center']) &&\n hasGap(c) &&\n hasAnyPrefix(c, ['px-', 'py-']) &&\n hasAnyPrefix(c, ['hover:bg-', 'rounded-']),\n },\n {\n name: 'divider',\n match: (c) =>\n hasPrefix(c, 'border-') && (isFullWidth(c) || hasMargin(c)),\n },\n\n // ── States & effects ─────────────────────────────────────────────\n {\n name: 'skeleton',\n match: (c) => has(c, 'animate-pulse') && hasPrefix(c, 'bg-'),\n },\n {\n name: 'loading',\n match: (c) => has(c, 'animate-spin') || has(c, 'animate-pulse'),\n },\n {\n name: 'disabled',\n match: (c) => has(c, 'opacity-50') || has(c, 'cursor-not-allowed'),\n },\n {\n name: 'focus-ring',\n match: (c) => hasRing(c) || hasAnyPrefix(c, ['focus:ring-', 'focus-visible:ring-']),\n },\n {\n name: 'hover-lift',\n match: (c) =>\n hasAnyPrefix(c, ['hover:shadow-', 'hover:-translate-y-']) && hasPrefix(c, 'transition'),\n },\n\n // ── Scroll & overflow ────────────────────────────────────────────\n {\n name: 'scroll-panel',\n match: (c) =>\n hasAny(c, ['overflow-y-auto', 'overflow-auto', 'overflow-x-auto', 'overflow-hidden']),\n },\n\n // ── Visual fallbacks ─────────────────────────────────────────────\n {\n name: 'shadow-box',\n match: (c) => hasShadow(c) && hasPrefix(c, 'rounded-'),\n },\n {\n name: 'bordered',\n match: (c) => hasPrefix(c, 'border') && hasPadding(c),\n },\n {\n name: 'rounded-box',\n match: (c) => hasPrefix(c, 'rounded-'),\n },\n {\n name: 'padded',\n match: (c) => hasPadding(c),\n },\n];\n\n/** Build a short compositional name from layout + traits. */\nfunction buildCompositionalName(classes: string[]): string {\n const parts: string[] = [];\n\n if (has(classes, 'flex')) {\n if (has(classes, 'flex-col')) parts.push('stack');\n else if (has(classes, 'flex-wrap')) parts.push('wrap');\n else if (has(classes, 'justify-between')) parts.push('between');\n else if (has(classes, 'justify-center')) parts.push('centered');\n else if (has(classes, 'items-center')) parts.push('aligned');\n else parts.push('row');\n } else if (has(classes, 'grid')) {\n const cols = gridColumnCount(classes);\n parts.push(cols ? `grid-${cols}` : 'grid');\n } else if (has(classes, 'inline-flex')) {\n parts.push('inline-row');\n } else if (has(classes, 'inline-block')) {\n parts.push('inline');\n } else if (has(classes, 'block')) {\n parts.push('block');\n }\n\n if (has(classes, 'fixed')) parts.push('fixed');\n else if (has(classes, 'absolute')) parts.push('absolute');\n else if (has(classes, 'sticky')) parts.push('sticky');\n else if (has(classes, 'relative')) parts.push('relative');\n\n if (has(classes, 'object-cover')) parts.push('cover');\n else if (has(classes, 'object-contain')) parts.push('contain');\n else if (has(classes, 'aspect-video')) parts.push('video');\n else if (has(classes, 'rounded-full')) parts.push('circle');\n else if (hasPrefix(classes, 'rounded-')) parts.push('rounded');\n\n if (hasShadow(classes)) parts.push('shadow');\n else if (hasRing(classes)) parts.push('ring');\n else if (hasPrefix(classes, 'border')) parts.push('bordered');\n\n if (hasPrefix(classes, 'bg-')) parts.push('surface');\n else if (hasPrefix(classes, 'text-')) parts.push('text');\n\n if (has(classes, 'truncate')) parts.push('truncate');\n if (has(classes, 'animate-pulse')) parts.push('pulse');\n if (has(classes, 'transition')) parts.push('transition');\n\n if (parts.length === 0 && hasPadding(classes)) parts.push('padded');\n if (parts.length === 0 && hasMargin(classes)) parts.push('spaced');\n\n const unique = [...new Set(parts)];\n return unique.slice(0, 2).join('-') || 'component';\n}\n\n/**\n * Suggest a short, human-readable component class name from a utility list.\n * Prefers semantic names (toolbar, media-cover) over utility concatenation.\n */\nexport function suggestClassName(classes: string[]): string {\n if (classes.length === 0) {\n return 'component';\n }\n\n for (const rule of SEMANTIC_RULES) {\n if (rule.match(classes)) {\n return rule.name;\n }\n }\n\n return buildCompositionalName(classes);\n}\n","import type { ClassCombination } from '../parser/types.js';\n\n/** True when every class in `smaller` is also present in `larger`. */\nexport function isStrictSubset(smaller: string[], larger: string[]): boolean {\n if (smaller.length >= larger.length) {\n return false;\n }\n\n const largerSet = new Set(larger);\n return smaller.every((cls) => largerSet.has(cls));\n}\n\n/**\n * Drop subset combinations when a strict superset is already in the list\n * (e.g. drop \"flex p-4\" when \"flex items-center p-4\" is present).\n */\nexport function dedupeSubsetCombinations(\n combinations: ClassCombination[],\n): ClassCombination[] {\n return combinations.filter((combo) => {\n return !combinations.some(\n (other) =>\n other.normalized !== combo.normalized &&\n isStrictSubset(combo.classes, other.classes),\n );\n });\n}\n","/**\n * Normalize a class list so order does not affect identity.\n * \"flex p-4\" and \"p-4 flex\" produce the same key.\n */\nexport function normalizeClasses(classes: string[]): string {\n return [...classes].sort().join(' ');\n}\n\n/** Split a className string into individual Tailwind tokens. */\nexport function splitClassString(classString: string): string[] {\n return classString\n .trim()\n .split(/\\s+/)\n .filter((token) => token.length > 0);\n}\n\n/**\n * Generate every combination of size `size` from `classes` (order preserved in output,\n * but callers should normalize before counting).\n */\nexport function generateCombinations(\n classes: string[],\n size: number,\n): string[][] {\n if (size < 1 || size > classes.length) {\n return [];\n }\n\n const results: string[][] = [];\n\n const backtrack = (start: number, current: string[]): void => {\n if (current.length === size) {\n results.push([...current]);\n return;\n }\n\n for (let i = start; i <= classes.length - (size - current.length); i += 1) {\n const item = classes[i];\n if (item !== undefined) {\n current.push(item);\n backtrack(i + 1, current);\n current.pop();\n }\n }\n };\n\n backtrack(0, []);\n return results;\n}\n","import type {\n ClassCombination,\n ClassNameOccurrence,\n CombinationLocation,\n} from '../parser/types.js';\nimport { suggestClassName } from './suggestions.js';\nimport { dedupeSubsetCombinations } from './dedupe.js';\nimport { generateCombinations, normalizeClasses } from './combiner.js';\n\nconst DEFAULT_MIN_COMBINATION_SIZE = 2;\nconst DEFAULT_MAX_COMBINATION_SIZE = 5;\nconst DEFAULT_MIN_OCCURRENCES = 5;\nconst DEFAULT_TOP_LIMIT = 10;\n\nexport interface PatternFinderOptions {\n minOccurrences?: number;\n minSize?: number;\n maxSize?: number;\n topLimit?: number;\n dedupeSubsets?: boolean;\n}\n\ninterface FrequencyEntry {\n classes: string[];\n count: number;\n locations: CombinationLocation[];\n}\n\nfunction locationKey(location: CombinationLocation): string {\n return `${location.filePath}:${location.line ?? 0}`;\n}\n\n/**\n * From every className occurrence, enumerate class subsets,\n * count normalized combinations, and return the most frequent ones.\n */\nexport function findFrequentPatterns(\n occurrences: ClassNameOccurrence[],\n options: PatternFinderOptions = {},\n): ClassCombination[] {\n const minOccurrences = options.minOccurrences ?? DEFAULT_MIN_OCCURRENCES;\n const minSize = options.minSize ?? DEFAULT_MIN_COMBINATION_SIZE;\n const maxSize = options.maxSize ?? DEFAULT_MAX_COMBINATION_SIZE;\n const topLimit = options.topLimit ?? DEFAULT_TOP_LIMIT;\n const dedupeSubsets = options.dedupeSubsets ?? true;\n\n const frequency = new Map<string, FrequencyEntry>();\n\n for (const occurrence of occurrences) {\n const uniqueInElement = [...new Set(occurrence.classes)];\n\n if (uniqueInElement.length < minSize) {\n continue;\n }\n\n const location: CombinationLocation = {\n filePath: occurrence.filePath,\n line: occurrence.line,\n };\n\n const cappedMaxSize = Math.min(maxSize, uniqueInElement.length);\n\n for (let size = minSize; size <= cappedMaxSize; size += 1) {\n const combos = generateCombinations(uniqueInElement, size);\n\n for (const combo of combos) {\n const normalized = normalizeClasses(combo);\n const existing = frequency.get(normalized);\n\n if (existing) {\n existing.count += 1;\n const key = locationKey(location);\n if (!existing.locations.some((loc) => locationKey(loc) === key)) {\n existing.locations.push(location);\n }\n } else {\n frequency.set(normalized, {\n classes: [...combo].sort(),\n count: 1,\n locations: [location],\n });\n }\n }\n }\n }\n\n let frequent = [...frequency.entries()]\n .filter(([, value]) => value.count > minOccurrences)\n .map(([normalized, value]) => ({\n normalized,\n classes: value.classes,\n occurrences: value.count,\n suggestion: `.${suggestClassName(value.classes)}`,\n locations: value.locations,\n }))\n .sort((a, b) => {\n if (b.occurrences !== a.occurrences) {\n return b.occurrences - a.occurrences;\n }\n return b.classes.length - a.classes.length;\n });\n\n if (dedupeSubsets) {\n frequent = dedupeSubsetCombinations(frequent);\n }\n\n return frequent.slice(0, topLimit);\n}\n\n/**\n * Find exact duplicate className sets (full class lists per element).\n * Better suited for CSS generation than combinatorial subset search.\n */\nexport function findRepeatedClassSets(\n occurrences: ClassNameOccurrence[],\n options: PatternFinderOptions = {},\n): ClassCombination[] {\n const minOccurrences = options.minOccurrences ?? 3;\n const minSize = options.minSize ?? 2;\n const maxSize = options.maxSize ?? DEFAULT_MAX_COMBINATION_SIZE;\n const topLimit = options.topLimit ?? DEFAULT_TOP_LIMIT;\n\n const frequency = new Map<string, FrequencyEntry>();\n\n for (const occurrence of occurrences) {\n const uniqueInElement = [...new Set(occurrence.classes)];\n\n if (uniqueInElement.length < minSize || uniqueInElement.length > maxSize) {\n continue;\n }\n\n const normalized = normalizeClasses(uniqueInElement);\n const location: CombinationLocation = {\n filePath: occurrence.filePath,\n line: occurrence.line,\n };\n\n const existing = frequency.get(normalized);\n\n if (existing) {\n existing.count += 1;\n const key = locationKey(location);\n if (!existing.locations.some((loc) => locationKey(loc) === key)) {\n existing.locations.push(location);\n }\n } else {\n frequency.set(normalized, {\n classes: [...uniqueInElement].sort(),\n count: 1,\n locations: [location],\n });\n }\n }\n\n return [...frequency.entries()]\n .filter(([, value]) => value.count >= minOccurrences)\n .map(([normalized, value]) => ({\n normalized,\n classes: value.classes,\n occurrences: value.count,\n suggestion: `.${suggestClassName(value.classes)}`,\n locations: value.locations,\n }))\n .sort((a, b) => {\n if (b.occurrences !== a.occurrences) {\n return b.occurrences - a.occurrences;\n }\n return b.classes.length - a.classes.length;\n })\n .slice(0, topLimit);\n}\n\n/**\n * Estimate how much repeated utility usage could be collapsed into components.\n * Uses the best full combination: each redundant instance could replace N utilities with 1.\n */\nexport function calculatePotentialReduction(\n occurrences: ClassNameOccurrence[],\n topCombinations: ClassCombination[],\n): number {\n const totalClassUsages = occurrences.reduce(\n (sum, occurrence) => sum + occurrence.classes.length,\n 0,\n );\n\n if (totalClassUsages === 0 || topCombinations.length === 0) {\n return 0;\n }\n\n const best = [...topCombinations].sort((a, b) => {\n if (b.classes.length !== a.classes.length) {\n return b.classes.length - a.classes.length;\n }\n return b.occurrences - a.occurrences;\n })[0];\n\n if (!best || best.occurrences <= 1 || best.classes.length < 2) {\n return 0;\n }\n\n const redundantInstances = best.occurrences - 1;\n const utilitiesSavedPerInstance = best.classes.length - 1;\n const savable = redundantInstances * utilitiesSavedPerInstance;\n\n return Math.min(100, Math.round((savable / totalClassUsages) * 100));\n}\n","import type {\n ArrayExpression,\n CallExpression,\n ConditionalExpression,\n Expression,\n LogicalExpression,\n TemplateLiteral,\n} from '@babel/types';\nimport { splitClassString } from '../analyzer/combiner.js';\n\n/** Utilities commonly used to merge Tailwind class strings. */\nexport const CLASS_MERGE_CALLEES = new Set([\n 'cn',\n 'clsx',\n 'classnames',\n 'classNames',\n 'twMerge',\n 'cx',\n]);\n\nexport interface ExtractedClasses {\n classes: string[];\n isDynamic: boolean;\n}\n\nfunction mergeExtractions(parts: ExtractedClasses[]): ExtractedClasses {\n const classes = [...new Set(parts.flatMap((part) => part.classes))];\n const isDynamic = parts.some((part) => part.isDynamic);\n\n return { classes, isDynamic };\n}\n\nfunction extractFromStringLiteral(value: string): ExtractedClasses {\n return {\n classes: splitClassString(value),\n isDynamic: false,\n };\n}\n\nfunction extractFromTemplateLiteral(node: TemplateLiteral): ExtractedClasses {\n const parts: string[] = [];\n\n for (const quasi of node.quasis) {\n if (quasi.value.cooked) {\n parts.push(quasi.value.cooked);\n }\n }\n\n const combined = parts.join(' ').trim();\n\n return {\n classes: combined ? splitClassString(combined) : [],\n isDynamic: node.expressions.length > 0,\n };\n}\n\nfunction isClassMergeCallee(expression: Expression): boolean {\n if (expression.type === 'Identifier') {\n return CLASS_MERGE_CALLEES.has(expression.name);\n }\n\n if (\n expression.type === 'MemberExpression' &&\n expression.property.type === 'Identifier'\n ) {\n return CLASS_MERGE_CALLEES.has(expression.property.name);\n }\n\n return false;\n}\n\nfunction extractFromCallArguments(\n args: CallExpression['arguments'],\n): ExtractedClasses {\n const parts: ExtractedClasses[] = [];\n\n for (const arg of args) {\n if (arg.type === 'SpreadElement' || arg.type === 'ArgumentPlaceholder') {\n parts.push({ classes: [], isDynamic: true });\n continue;\n }\n\n parts.push(extractClassesFromExpression(arg));\n }\n\n return mergeExtractions(parts);\n}\n\n/**\n * Recursively pull static Tailwind tokens from JSX className expressions.\n * Unknown/dynamic fragments set `isDynamic: true` but may still yield partial classes.\n */\nexport function extractClassesFromExpression(\n expression: Expression,\n): ExtractedClasses {\n switch (expression.type) {\n case 'StringLiteral':\n return extractFromStringLiteral(expression.value);\n\n case 'TemplateLiteral':\n return extractFromTemplateLiteral(expression);\n\n case 'CallExpression': {\n const { callee } = expression;\n if (callee.type !== 'V8IntrinsicIdentifier' && isClassMergeCallee(callee)) {\n return extractFromCallArguments(expression.arguments);\n }\n return { classes: [], isDynamic: true };\n }\n\n case 'ConditionalExpression': {\n const merged = mergeExtractions([\n extractClassesFromExpression(expression.consequent),\n extractClassesFromExpression(expression.alternate),\n ]);\n return { ...merged, isDynamic: true };\n }\n\n case 'LogicalExpression': {\n const merged = mergeExtractions([\n extractClassesFromExpression(expression.left),\n extractClassesFromExpression(expression.right),\n ]);\n return { ...merged, isDynamic: true };\n }\n\n case 'ArrayExpression':\n return extractFromArrayExpression(expression);\n\n case 'ObjectExpression':\n // clsx object form: { 'p-4': isActive } — keys are potential classes\n return extractFromObjectExpression(expression);\n\n default:\n return { classes: [], isDynamic: true };\n }\n}\n\nfunction extractFromArrayExpression(node: ArrayExpression): ExtractedClasses {\n const parts: ExtractedClasses[] = [];\n\n for (const element of node.elements) {\n if (element === null || element.type === 'SpreadElement') {\n parts.push({ classes: [], isDynamic: true });\n continue;\n }\n\n parts.push(extractClassesFromExpression(element));\n }\n\n return mergeExtractions(parts);\n}\n\nfunction extractFromObjectExpression(\n node: import('@babel/types').ObjectExpression,\n): ExtractedClasses {\n const classes: string[] = [];\n let isDynamic = false;\n\n for (const prop of node.properties) {\n if (prop.type === 'SpreadElement') {\n isDynamic = true;\n continue;\n }\n\n if (prop.type !== 'ObjectProperty') {\n isDynamic = true;\n continue;\n }\n\n const key = prop.key;\n if (key.type === 'StringLiteral') {\n classes.push(...splitClassString(key.value));\n } else if (key.type === 'Identifier') {\n classes.push(...splitClassString(key.name));\n }\n\n if (prop.value.type !== 'BooleanLiteral' || prop.value.value !== true) {\n isDynamic = true;\n }\n }\n\n return {\n classes: [...new Set(classes)],\n isDynamic,\n };\n}\n","import { parse } from '@babel/parser';\nimport type { JSXAttribute, Node } from '@babel/types';\nimport type { ClassNameExtraction } from './types.js';\nimport { extractClassesFromExpression } from './classHelpers.js';\n\nexport const PARSER_PLUGINS = [\n 'jsx',\n 'typescript',\n 'decorators-legacy',\n 'classProperties',\n 'classPrivateProperties',\n 'classPrivateMethods',\n 'dynamicImport',\n 'importMeta',\n] as const;\n\nconst CLASS_ATTRIBUTES = new Set(['className', 'class']);\n\nfunction getAttributeName(attr: JSXAttribute): string | null {\n if (attr.name.type === 'JSXIdentifier') {\n return attr.name.name;\n }\n return null;\n}\n\nexport function isClassAttribute(attr: JSXAttribute): boolean {\n const name = getAttributeName(attr);\n return name !== null && CLASS_ATTRIBUTES.has(name);\n}\n\n/** Extract Tailwind classes from a className/class JSX attribute. */\nexport function extractFromJSXAttribute(\n attr: JSXAttribute,\n): ClassNameExtraction | null {\n if (!isClassAttribute(attr)) {\n return null;\n }\n\n const line = attr.loc?.start.line;\n const value = attr.value;\n\n if (value == null) {\n return { classes: [], isDynamic: true, line };\n }\n\n if (value.type === 'StringLiteral') {\n const result = extractClassesFromExpression(value);\n return { classes: result.classes, isDynamic: result.isDynamic, line };\n }\n\n if (value.type === 'JSXExpressionContainer') {\n const expr = value.expression;\n\n if (expr.type === 'JSXEmptyExpression') {\n return { classes: [], isDynamic: true, line };\n }\n\n const result = extractClassesFromExpression(expr);\n return { classes: result.classes, isDynamic: result.isDynamic, line };\n }\n\n return { classes: [], isDynamic: true, line };\n}\n\nexport function parseSourceToAst(source: string): Node {\n return parse(source, {\n sourceType: 'module',\n plugins: [...PARSER_PLUGINS],\n errorRecovery: true,\n allowReturnOutsideFunction: true,\n ranges: false,\n tokens: false,\n });\n}\n","import babelTraverse from '@babel/traverse';\nimport type { NodePath } from '@babel/traverse';\nimport type { JSXAttribute, JSXElement, Node } from '@babel/types';\nimport fs from 'node:fs/promises';\nimport type { ClassNameExtraction, ParseResult } from './types.js';\nimport {\n extractFromJSXAttribute,\n isClassAttribute,\n parseSourceToAst,\n} from './ast.js';\n\ntype TraverseFn = (\n ast: Node,\n visitors: { JSXElement?: (path: NodePath<JSXElement>) => void },\n) => void;\n\nfunction resolveTraverse(module: unknown): TraverseFn {\n if (typeof module === 'function') {\n return module as TraverseFn;\n }\n\n const withDefault = module as { default?: unknown };\n if (typeof withDefault.default === 'function') {\n return withDefault.default as TraverseFn;\n }\n\n throw new Error('Failed to load @babel/traverse');\n}\n\nconst traverse = resolveTraverse(babelTraverse);\n\nfunction isJSXElementWithClassAttribute(path: NodePath<JSXElement>): boolean {\n const opening = path.node.openingElement;\n return opening.attributes.some(\n (attr) => attr.type === 'JSXAttribute' && isClassAttribute(attr),\n );\n}\n\nfunction collectExtractionsFromAst(\n ast: Node,\n filePath: string,\n): { extractions: ClassNameExtraction[]; warnings: string[] } {\n const extractions: ClassNameExtraction[] = [];\n const warnings: string[] = [];\n\n traverse(ast, {\n JSXElement(path: NodePath<JSXElement>) {\n if (!isJSXElementWithClassAttribute(path)) {\n return;\n }\n\n const opening = path.node.openingElement;\n\n for (const attr of opening.attributes) {\n if (attr.type !== 'JSXAttribute') continue;\n\n const extraction = extractFromJSXAttribute(attr);\n if (!extraction) continue;\n\n if (extraction.isDynamic && extraction.classes.length === 0) {\n const lineInfo = extraction.line ? `:${extraction.line}` : '';\n warnings.push(\n `Dynamic className skipped in ${filePath}${lineInfo}`,\n );\n continue;\n }\n\n if (extraction.classes.length > 0) {\n extractions.push(extraction);\n }\n }\n },\n });\n\n return { extractions, warnings };\n}\n\n/**\n * Parse in-memory source (used by tests and parseFile).\n */\nexport function parseSource(\n source: string,\n filePath = 'unknown',\n): ParseResult {\n const extractions: ClassNameExtraction[] = [];\n const warnings: string[] = [];\n\n try {\n const ast = parseSourceToAst(source);\n const collected = collectExtractionsFromAst(ast, filePath);\n extractions.push(...collected.extractions);\n warnings.push(...collected.warnings);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`Failed to parse ${filePath}: ${message}`);\n }\n\n return { filePath, extractions, warnings };\n}\n\n/**\n * Parse a single source file and collect all className/class values from JSX.\n */\nexport async function parseFile(filePath: string): Promise<ParseResult> {\n const source = await fs.readFile(filePath, 'utf-8');\n return parseSource(source, filePath);\n}\n","/** Directories excluded from recursive file scanning. */\nexport const IGNORED_DIRECTORIES = [\n 'node_modules',\n '.next',\n 'dist',\n 'build',\n '.git',\n] as const;\n\n/** fast-glob ignore patterns — match directories at any depth. */\nexport const IGNORE_PATTERNS: string[] = IGNORED_DIRECTORIES.map(\n (dir) => `**/${dir}/**`,\n);\n","import fg from 'fast-glob';\nimport path from 'node:path';\nimport { IGNORE_PATTERNS } from './ignore.js';\n\nconst SOURCE_EXTENSIONS = ['tsx', 'jsx', 'ts', 'js'] as const;\n\n/**\n * Recursively collect source files under `targetPath`, skipping common build/cache dirs.\n */\nexport async function walkSourceFiles(targetPath: string): Promise<string[]> {\n const absolutePath = path.resolve(targetPath);\n\n const patterns = SOURCE_EXTENSIONS.map((ext) =>\n path.join(absolutePath, `**/*.${ext}`).replace(/\\\\/g, '/'),\n );\n\n const files = await fg(patterns, {\n absolute: true,\n onlyFiles: true,\n unique: true,\n ignore: IGNORE_PATTERNS,\n dot: false,\n });\n\n return files.sort();\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport {\n calculatePotentialReduction,\n findFrequentPatterns,\n type PatternFinderOptions,\n} from '../analyzer/patternFinder.js';\nimport { normalizeClasses } from '../analyzer/combiner.js';\nimport { parseFile } from '../parser/jsxParser.js';\nimport type {\n AnalysisReport,\n ClassNameOccurrence,\n} from '../parser/types.js';\nimport { walkSourceFiles } from '../scanner/fileWalker.js';\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n try {\n await fs.access(targetPath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport interface ScanProjectOptions extends PatternFinderOptions {\n targetPath: string;\n}\n\nexport interface ScanProjectResult {\n resolvedPath: string;\n files: string[];\n occurrences: ClassNameOccurrence[];\n warnings: string[];\n report: AnalysisReport;\n}\n\n/**\n * Scan a directory, parse className usage, and build an analysis report.\n */\nexport async function scanProject(\n options: ScanProjectOptions,\n): Promise<ScanProjectResult> {\n const resolvedPath = path.resolve(options.targetPath);\n\n if (!(await pathExists(resolvedPath))) {\n throw new Error(`Path does not exist: ${resolvedPath}`);\n }\n\n const files = await walkSourceFiles(resolvedPath);\n\n if (files.length === 0) {\n throw new Error(\n `No source files (.tsx, .jsx, .ts, .js) found in: ${resolvedPath}`,\n );\n }\n\n const occurrences: ClassNameOccurrence[] = [];\n const warnings: string[] = [];\n\n for (const file of files) {\n const result = await parseFile(file);\n warnings.push(...result.warnings);\n\n for (const extraction of result.extractions) {\n if (extraction.classes.length > 0) {\n occurrences.push({\n classes: extraction.classes,\n filePath: file,\n line: extraction.line,\n });\n }\n }\n }\n\n const uniqueCombinationKeys = new Set(\n occurrences.map((occurrence) =>\n normalizeClasses([...new Set(occurrence.classes)]),\n ),\n );\n\n const topCombinations = findFrequentPatterns(occurrences, {\n minOccurrences: options.minOccurrences,\n minSize: options.minSize,\n maxSize: options.maxSize,\n topLimit: options.topLimit,\n dedupeSubsets: options.dedupeSubsets,\n });\n\n const potentialReductionPercent = calculatePotentialReduction(\n occurrences,\n topCombinations,\n );\n\n const report: AnalysisReport = {\n targetPath: resolvedPath,\n stats: {\n filesScanned: files.length,\n componentsWithClassName: occurrences.length,\n uniqueCombinations: uniqueCombinationKeys.size,\n totalClassUsages: occurrences.reduce(\n (sum, occurrence) => sum + occurrence.classes.length,\n 0,\n ),\n topCombinations,\n potentialReductionPercent,\n },\n parseWarnings: warnings,\n };\n\n return {\n resolvedPath,\n files,\n occurrences,\n warnings,\n report,\n };\n}\n","import chalk from 'chalk';\nimport type { AnalysisReport } from '../parser/types.js';\nimport { normalizeClasses } from '../analyzer/combiner.js';\n\nfunction formatNumber(value: number): string {\n return value.toLocaleString('en-US');\n}\n\nfunction formatLocations(\n locations: AnalysisReport['stats']['topCombinations'][number]['locations'],\n): string {\n const preview = locations.slice(0, 3).map((loc) => {\n const line = loc.line ? `:${loc.line}` : '';\n return `${loc.filePath}${line}`;\n });\n\n const suffix =\n locations.length > 3 ? ` (+${locations.length - 3} more)` : '';\n\n return preview.join(', ') + suffix;\n}\n\ninterface ConsoleReportOptions {\n topLimit?: number;\n}\n\n/**\n * Render the analysis report to stdout with colors and the layout from the spec.\n */\nexport function printConsoleReport(\n report: AnalysisReport,\n options: ConsoleReportOptions = {},\n): void {\n const { stats } = report;\n const topLimit = options.topLimit ?? 10;\n\n console.log('');\n console.log(chalk.bold.cyan('📊 Tailwind Analysis Report'));\n console.log(chalk.cyan('━'.repeat(41)));\n console.log(`Files scanned: ${chalk.white(formatNumber(stats.filesScanned))}`);\n console.log(\n `Components with className: ${chalk.white(formatNumber(stats.componentsWithClassName))}`,\n );\n console.log(\n `Unique class combinations: ${chalk.white(formatNumber(stats.uniqueCombinations))}`,\n );\n console.log('');\n\n if (stats.topCombinations.length === 0) {\n console.log(\n chalk.yellow(\n 'No frequent class combinations found matching the current filters.',\n ),\n );\n } else {\n console.log(\n chalk.bold.green(`🏆 Top ${Math.min(topLimit, stats.topCombinations.length)} most frequent combinations:`),\n );\n console.log('');\n\n stats.topCombinations.forEach((combo, index) => {\n const displayClasses = normalizeClasses(combo.classes);\n console.log(\n chalk.white(`${index + 1}. `) +\n chalk.yellow(`\"${displayClasses}\"`),\n );\n console.log(\n chalk.gray(` Occurrences: `) + chalk.white(String(combo.occurrences)),\n );\n console.log(\n chalk.gray(` Suggestion: `) + chalk.green(combo.suggestion),\n );\n console.log(\n chalk.gray(` Found in: `) + chalk.dim(formatLocations(combo.locations)),\n );\n console.log('');\n });\n }\n\n console.log(\n chalk.magenta(\n `💡 Potential code reduction: ${stats.potentialReductionPercent}%`,\n ),\n );\n console.log(\n chalk.magenta(\n '💡 Generate CSS: npx tailwind-unwind generate <path> --output styles.css',\n ),\n );\n console.log(\n chalk.magenta(\n '💡 Apply classes: npx tailwind-unwind apply <path> --output styles.css',\n ),\n );\n console.log('');\n}\n","import type { AnalysisReport } from '../parser/types.js';\n\n/** Serialize the analysis report as formatted JSON. */\nexport function printJsonReport(report: AnalysisReport): void {\n console.log(JSON.stringify(report, null, 2));\n}\n","import chalk from 'chalk';\nimport { scanProject } from '../core/scanProject.js';\nimport type { AnalysisReport, AnalyzeOptions } from '../parser/types.js';\nimport { printConsoleReport } from '../reporters/consoleReporter.js';\nimport { printJsonReport } from '../reporters/jsonReporter.js';\n\n/**\n * Run the full analyze pipeline: scan → parse → find patterns → report.\n */\nexport async function analyzeCommand(\n targetPath: string,\n options: AnalyzeOptions = {},\n): Promise<AnalysisReport> {\n let scanResult;\n\n try {\n scanResult = await scanProject({\n targetPath,\n minOccurrences: options.minOccurrences,\n minSize: options.minSize,\n maxSize: options.maxSize,\n topLimit: options.top,\n dedupeSubsets: options.dedupeSubsets,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(chalk.red(`Error: ${message}`));\n process.exit(1);\n }\n\n if (options.format !== 'json') {\n for (const warning of scanResult.warnings) {\n console.warn(chalk.yellow(`⚠ ${warning}`));\n }\n }\n\n const report = scanResult.report;\n\n if (options.format === 'json') {\n printJsonReport(report);\n } else {\n printConsoleReport(report, { topLimit: options.top });\n }\n\n return report;\n}\n","import babelGenerate from '@babel/generator';\nimport babelTraverse from '@babel/traverse';\nimport * as t from '@babel/types';\nimport type { NodePath } from '@babel/traverse';\nimport type { JSXAttribute, JSXElement, Node } from '@babel/types';\nimport { normalizeClasses } from '../analyzer/combiner.js';\nimport {\n extractFromJSXAttribute,\n isClassAttribute,\n parseSourceToAst,\n} from '../parser/ast.js';\n\ntype TraverseFn = (\n ast: Node,\n visitors: { JSXElement?: (path: NodePath<JSXElement>) => void },\n) => void;\n\ntype GenerateFn = (\n ast: Node,\n options?: { retainLines?: boolean },\n source?: string,\n) => { code: string };\n\nfunction resolveTraverse(module: unknown): TraverseFn {\n if (typeof module === 'function') {\n return module as TraverseFn;\n }\n\n const withDefault = module as { default?: unknown };\n if (typeof withDefault.default === 'function') {\n return withDefault.default as TraverseFn;\n }\n\n throw new Error('Failed to load @babel/traverse');\n}\n\nfunction resolveGenerator(module: unknown): GenerateFn {\n if (typeof module === 'function') {\n return module as GenerateFn;\n }\n\n const withDefault = module as { default?: unknown };\n if (typeof withDefault.default === 'function') {\n return withDefault.default as GenerateFn;\n }\n\n throw new Error('Failed to load @babel/generator');\n}\n\nconst traverse = resolveTraverse(babelTraverse);\nconst generate = resolveGenerator(babelGenerate);\n\nexport interface ClassReplacement {\n filePath: string;\n line?: number;\n from: string;\n to: string;\n}\n\nexport interface SkippedReplacement {\n filePath: string;\n line?: number;\n reason: string;\n classes: string[];\n}\n\nexport interface ReplaceClassNamesResult {\n source: string;\n replacements: ClassReplacement[];\n skipped: SkippedReplacement[];\n changed: boolean;\n}\n\nfunction lookupReplacement(\n extraction: { classes: string[]; isDynamic: boolean },\n replacementMap: Map<string, string>,\n): string | null {\n if (extraction.isDynamic || extraction.classes.length === 0) {\n return null;\n }\n\n const key = normalizeClasses([...new Set(extraction.classes)]);\n return replacementMap.get(key) ?? null;\n}\n\nfunction setStringClassAttribute(\n attr: JSXAttribute,\n className: string,\n): void {\n attr.value = t.stringLiteral(className);\n}\n\n/**\n * Replace exact matching className/class values with generated component classes.\n */\nexport function replaceClassNamesInSource(\n source: string,\n replacementMap: Map<string, string>,\n filePath: string,\n): ReplaceClassNamesResult {\n const replacements: ClassReplacement[] = [];\n const skipped: SkippedReplacement[] = [];\n\n if (replacementMap.size === 0) {\n return { source, replacements, skipped, changed: false };\n }\n\n let ast: Node;\n\n try {\n ast = parseSourceToAst(source);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to parse ${filePath}: ${message}`);\n }\n\n traverse(ast, {\n JSXElement(path: NodePath<JSXElement>) {\n const opening = path.node.openingElement;\n\n for (const attr of opening.attributes) {\n if (attr.type !== 'JSXAttribute' || !isClassAttribute(attr)) {\n continue;\n }\n\n const extraction = extractFromJSXAttribute(attr);\n if (!extraction) continue;\n\n const replacement = lookupReplacement(extraction, replacementMap);\n\n if (!replacement) {\n if (extraction.classes.length > 0) {\n const key = normalizeClasses([...new Set(extraction.classes)]);\n if (replacementMap.size > 0 && !replacementMap.has(key)) {\n if (extraction.isDynamic) {\n skipped.push({\n filePath,\n line: extraction.line,\n reason: 'dynamic className',\n classes: extraction.classes,\n });\n }\n }\n }\n continue;\n }\n\n const from = normalizeClasses([...new Set(extraction.classes)]);\n setStringClassAttribute(attr, replacement);\n\n replacements.push({\n filePath,\n line: extraction.line,\n from,\n to: replacement,\n });\n }\n },\n });\n\n if (replacements.length === 0) {\n return { source, replacements, skipped, changed: false };\n }\n\n const output = generate(ast, { retainLines: true }, source);\n return {\n source: output.code,\n replacements,\n skipped,\n changed: true,\n };\n}\n","/** Default namespace for generated component classes. */\nexport const DEFAULT_CLASS_PREFIX = 'twu-';\n\n/** Normalize prefix so generated classes are clearly namespaced. */\nexport function normalizeClassPrefix(prefix?: string): string {\n if (!prefix || prefix.trim().length === 0) {\n return DEFAULT_CLASS_PREFIX;\n }\n\n const trimmed = prefix.trim();\n return trimmed.endsWith('-') ? trimmed : `${trimmed}-`;\n}\n\n/** Attach a namespace prefix to a base component class name. */\nexport function withClassPrefix(baseName: string, prefix?: string): string {\n const normalizedPrefix = normalizeClassPrefix(prefix);\n\n if (baseName.startsWith(normalizedPrefix)) {\n return baseName;\n }\n\n return `${normalizedPrefix}${baseName}`;\n}\n","import { suggestClassName } from '../analyzer/suggestions.js';\nimport type { ClassCombination } from '../parser/types.js';\nimport { normalizeClassPrefix, withClassPrefix } from './classPrefix.js';\n\nexport interface GeneratedComponent {\n className: string;\n classes: string[];\n occurrences: number;\n}\n\nexport interface CssGeneratorOptions {\n sourcePath: string;\n combinations: ClassCombination[];\n prefix?: string;\n}\n\nexport interface CssGeneratorResult {\n css: string;\n components: GeneratedComponent[];\n}\n\nexport interface AssignClassNamesOptions {\n prefix?: string;\n}\n\n/** Assign unique, prefixed component class names. */\nexport function assignComponentClassNames(\n combinations: ClassCombination[],\n options: AssignClassNamesOptions = {},\n): GeneratedComponent[] {\n const used = new Set<string>();\n\n return combinations.map((combo) => {\n const base = suggestClassName(combo.classes);\n let className = withClassPrefix(base, options.prefix);\n let suffix = 2;\n\n while (used.has(className)) {\n className = withClassPrefix(`${base}-${suffix}`, options.prefix);\n suffix += 1;\n }\n\n used.add(className);\n\n return {\n className,\n classes: combo.classes,\n occurrences: combo.occurrences,\n };\n });\n}\n\n/**\n * Build a Tailwind CSS file with @layer components and @apply rules\n * for the most frequent class combinations.\n */\nexport function generateComponentCss(\n options: CssGeneratorOptions,\n): CssGeneratorResult {\n const components = assignComponentClassNames(options.combinations, {\n prefix: options.prefix,\n });\n const timestamp = new Date().toISOString();\n const classPrefix = normalizeClassPrefix(options.prefix);\n\n const header = [\n '/**',\n ' * Generated by tailwind-unwind',\n ` * Source: ${options.sourcePath}`,\n ` * Generated at: ${timestamp}`,\n ` * Class prefix: ${classPrefix}`,\n ' */',\n '',\n ].join('\\n');\n\n if (components.length === 0) {\n return {\n css: `${header}\\n/* No frequent class combinations found. Try lowering --min-occurrences. */\\n`,\n components: [],\n };\n }\n\n const rules = components\n .map((component) => {\n const applyClasses = component.classes.join(' ');\n return ` .${component.className} {\\n @apply ${applyClasses};\\n }`;\n })\n .join('\\n\\n');\n\n const css = `${header}\\n@layer components {\\n${rules}\\n}\\n`;\n\n return { css, components };\n}\n","import { findRepeatedClassSets } from '../analyzer/patternFinder.js';\nimport {\n assignComponentClassNames,\n generateComponentCss,\n type GeneratedComponent,\n} from '../generator/cssGenerator.js';\nimport type { ClassNameOccurrence } from '../parser/types.js';\nimport type { PatternFinderOptions } from '../analyzer/patternFinder.js';\n\nexport interface BuildComponentsOptions extends PatternFinderOptions {\n sourcePath: string;\n prefix?: string;\n}\n\nexport interface BuildComponentsResult {\n components: GeneratedComponent[];\n css: string;\n replacementMap: Map<string, string>;\n}\n\n/** Build component classes, CSS, and a normalized-class → name lookup map. */\nexport function buildComponents(\n occurrences: ClassNameOccurrence[],\n options: BuildComponentsOptions,\n): BuildComponentsResult {\n const combinations = findRepeatedClassSets(occurrences, {\n minOccurrences: options.minOccurrences,\n minSize: options.minSize,\n maxSize: options.maxSize,\n topLimit: options.topLimit,\n });\n\n const { css, components } = generateComponentCss({\n sourcePath: options.sourcePath,\n combinations,\n prefix: options.prefix,\n });\n\n const replacementMap = new Map<string, string>();\n\n for (const component of components) {\n const key = [...component.classes].sort().join(' ');\n replacementMap.set(key, component.className);\n }\n\n return { components, css, replacementMap };\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport { replaceClassNamesInSource } from '../codemod/replaceClassNames.js';\nimport { buildComponents } from '../core/buildComponents.js';\nimport { scanProject } from '../core/scanProject.js';\nimport type { AnalyzeOptions } from '../parser/types.js';\n\nexport interface ApplyOptions extends AnalyzeOptions {\n output: string;\n dryRun?: boolean;\n}\n\nexport interface ApplyResult {\n filesModified: number;\n replacementsTotal: number;\n outputPath: string;\n componentsGenerated: number;\n}\n\n/**\n * Generate component CSS and replace matching className strings in source files.\n */\nexport async function applyCommand(\n targetPath: string,\n options: ApplyOptions,\n): Promise<ApplyResult> {\n let scanResult;\n\n try {\n scanResult = await scanProject({ targetPath });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(chalk.red(`Error: ${message}`));\n process.exit(1);\n }\n\n for (const warning of scanResult.warnings) {\n console.warn(chalk.yellow(`⚠ ${warning}`));\n }\n\n const { components, css, replacementMap } = buildComponents(\n scanResult.occurrences,\n {\n sourcePath: scanResult.resolvedPath,\n minOccurrences: options.minOccurrences ?? 3,\n minSize: options.minSize,\n maxSize: options.maxSize,\n topLimit: options.top,\n prefix: options.prefix,\n },\n );\n\n if (components.length === 0) {\n console.error(\n chalk.yellow(\n 'No repeated className sets found. Try lowering --min-occurrences.',\n ),\n );\n process.exit(1);\n }\n\n const outputPath = path.resolve(options.output);\n let filesModified = 0;\n let replacementsTotal = 0;\n const allReplacements: Array<{\n filePath: string;\n line?: number;\n from: string;\n to: string;\n }> = [];\n\n for (const file of scanResult.files) {\n const original = await fs.readFile(file, 'utf-8');\n const result = replaceClassNamesInSource(\n original,\n replacementMap,\n file,\n );\n\n replacementsTotal += result.replacements.length;\n allReplacements.push(...result.replacements);\n\n if (result.changed) {\n filesModified += 1;\n if (!options.dryRun) {\n await fs.writeFile(file, result.source, 'utf-8');\n }\n }\n }\n\n if (!options.dryRun) {\n await fs.mkdir(path.dirname(outputPath), { recursive: true });\n await fs.writeFile(outputPath, css, 'utf-8');\n }\n\n console.log('');\n if (options.dryRun) {\n console.log(chalk.bold.yellow('🔍 Dry run — no files were modified'));\n } else {\n console.log(chalk.bold.green('✅ Classes applied successfully'));\n }\n\n console.log(chalk.gray(` CSS output: `) + chalk.white(outputPath));\n console.log(\n chalk.gray(` Component classes: `) + chalk.white(String(components.length)),\n );\n console.log(\n chalk.gray(` Files modified: `) + chalk.white(String(filesModified)),\n );\n console.log(\n chalk.gray(` Replacements: `) + chalk.white(String(replacementsTotal)),\n );\n\n if (allReplacements.length > 0) {\n console.log('');\n console.log(chalk.bold('Replacements:'));\n for (const item of allReplacements) {\n const line = item.line ? `:${item.line}` : '';\n console.log(\n chalk.gray(` ${item.filePath}${line}`) +\n chalk.white(` \"${item.from}\" `) +\n chalk.cyan('→') +\n chalk.green(` \"${item.to}\"`),\n );\n }\n }\n\n console.log('');\n if (!options.dryRun) {\n console.log(\n chalk.cyan(\n `Import ${path.basename(outputPath)} in your global CSS if you haven't already.`,\n ),\n );\n console.log('');\n }\n\n return {\n filesModified,\n replacementsTotal,\n outputPath,\n componentsGenerated: components.length,\n };\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport { buildComponents } from '../core/buildComponents.js';\nimport { scanProject } from '../core/scanProject.js';\nimport type { AnalyzeOptions } from '../parser/types.js';\n\nexport interface GenerateOptions extends AnalyzeOptions {\n output: string;\n}\n\nexport interface GenerateResult {\n outputPath: string;\n componentsGenerated: number;\n report: Awaited<ReturnType<typeof scanProject>>['report'];\n}\n\n/**\n * Analyze a project and write @layer components CSS to the output file.\n */\nexport async function generateCommand(\n targetPath: string,\n options: GenerateOptions,\n): Promise<GenerateResult> {\n let scanResult;\n\n try {\n scanResult = await scanProject({ targetPath });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(chalk.red(`Error: ${message}`));\n process.exit(1);\n }\n\n for (const warning of scanResult.warnings) {\n console.warn(chalk.yellow(`⚠ ${warning}`));\n }\n\n const { css, components } = buildComponents(scanResult.occurrences, {\n sourcePath: scanResult.resolvedPath,\n minOccurrences: options.minOccurrences ?? 3,\n minSize: options.minSize,\n maxSize: options.maxSize,\n topLimit: options.top,\n prefix: options.prefix,\n });\n\n const outputPath = path.resolve(options.output);\n await fs.mkdir(path.dirname(outputPath), { recursive: true });\n await fs.writeFile(outputPath, css, 'utf-8');\n\n console.log('');\n console.log(chalk.bold.green('✅ CSS generated successfully'));\n console.log(chalk.gray(` Output: `) + chalk.white(outputPath));\n console.log(\n chalk.gray(` Components: `) + chalk.white(String(components.length)),\n );\n\n if (components.length > 0) {\n console.log('');\n console.log(chalk.bold('Generated classes:'));\n for (const component of components) {\n console.log(\n chalk.green(` .${component.className}`) +\n chalk.gray(` — ${component.occurrences} occurrences, `) +\n chalk.dim(component.classes.join(' ')),\n );\n }\n console.log('');\n console.log(\n chalk.cyan(\n 'Run apply to replace className strings: npx tailwind-unwind apply <path> --output styles.css',\n ),\n );\n } else {\n console.log(\n chalk.yellow(\n '\\nNo repeated className sets matched the filters. Try lowering --min-occurrences.',\n ),\n );\n }\n\n console.log('');\n\n return {\n outputPath,\n componentsGenerated: components.length,\n report: scanResult.report,\n };\n}\n"],"mappings":"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","names":["path","fs","path","fs","path","chalk","chalk","babelTraverse","resolveTraverse","traverse","babelTraverse","path","fs","path","chalk","chalk","path","fs","fs","path","chalk","chalk","path","fs"]}
|