tailwind-typescript-plugin 1.3.1-beta.4 → 1.4.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +171 -0
  3. package/lib/core/types.d.ts +14 -0
  4. package/lib/core/types.d.ts.map +1 -1
  5. package/lib/extractors/CvaExtractor.d.ts.map +1 -1
  6. package/lib/extractors/CvaExtractor.js +44 -26
  7. package/lib/extractors/CvaExtractor.js.map +1 -1
  8. package/lib/extractors/ExpressionExtractor.d.ts +2 -1
  9. package/lib/extractors/ExpressionExtractor.d.ts.map +1 -1
  10. package/lib/extractors/ExpressionExtractor.js +46 -25
  11. package/lib/extractors/ExpressionExtractor.js.map +1 -1
  12. package/lib/extractors/JsxAttributeExtractor.d.ts.map +1 -1
  13. package/lib/extractors/JsxAttributeExtractor.js +13 -8
  14. package/lib/extractors/JsxAttributeExtractor.js.map +1 -1
  15. package/lib/extractors/TailwindVariantsExtractor.d.ts.map +1 -1
  16. package/lib/extractors/TailwindVariantsExtractor.js +50 -31
  17. package/lib/extractors/TailwindVariantsExtractor.js.map +1 -1
  18. package/lib/extractors/VariableReferenceExtractor.d.ts +1 -0
  19. package/lib/extractors/VariableReferenceExtractor.d.ts.map +1 -1
  20. package/lib/extractors/VariableReferenceExtractor.js +19 -14
  21. package/lib/extractors/VariableReferenceExtractor.js.map +1 -1
  22. package/lib/plugin/TailwindTypescriptPlugin.d.ts.map +1 -1
  23. package/lib/plugin/TailwindTypescriptPlugin.js +55 -18
  24. package/lib/plugin/TailwindTypescriptPlugin.js.map +1 -1
  25. package/lib/services/CodeActionService.d.ts +5 -0
  26. package/lib/services/CodeActionService.d.ts.map +1 -1
  27. package/lib/services/CodeActionService.js +37 -5
  28. package/lib/services/CodeActionService.js.map +1 -1
  29. package/lib/services/CodeActionService.spec.js +44 -0
  30. package/lib/services/CodeActionService.spec.js.map +1 -1
  31. package/lib/services/DiagnosticService.d.ts +26 -1
  32. package/lib/services/DiagnosticService.d.ts.map +1 -1
  33. package/lib/services/DiagnosticService.js +57 -2
  34. package/lib/services/DiagnosticService.js.map +1 -1
  35. package/lib/services/DuplicateClassDetection.spec.d.ts +2 -0
  36. package/lib/services/DuplicateClassDetection.spec.d.ts.map +1 -0
  37. package/lib/services/DuplicateClassDetection.spec.js +435 -0
  38. package/lib/services/DuplicateClassDetection.spec.js.map +1 -0
  39. package/lib/services/ValidationService.d.ts +4 -0
  40. package/lib/services/ValidationService.d.ts.map +1 -1
  41. package/lib/services/ValidationService.js +103 -6
  42. package/lib/services/ValidationService.js.map +1 -1
  43. package/package.json +1 -1
@@ -2,18 +2,43 @@ import * as ts from 'typescript/lib/tsserverlibrary';
2
2
  import { IDiagnosticService } from '../core/interfaces';
3
3
  import { ClassNameInfo } from '../core/types';
4
4
  /**
5
- * Diagnostic code for Tailwind plugin errors
5
+ * Diagnostic code for Tailwind plugin errors (invalid class)
6
6
  * Used to identify our diagnostics for code actions
7
7
  */
8
8
  export declare const TAILWIND_DIAGNOSTIC_CODE = 90001;
9
+ /**
10
+ * Diagnostic code for duplicate class warnings
11
+ */
12
+ export declare const TAILWIND_DUPLICATE_CODE = 90002;
13
+ /**
14
+ * Diagnostic code for extractable class suggestions (hint)
15
+ * Used when a class appears in all branches of a ternary but not at root level
16
+ */
17
+ export declare const TAILWIND_EXTRACTABLE_CLASS_CODE = 90003;
9
18
  /**
10
19
  * Service responsible for creating TypeScript diagnostics
11
20
  */
12
21
  export declare class DiagnosticService implements IDiagnosticService {
13
22
  createDiagnostic(classInfo: ClassNameInfo, sourceFile: ts.SourceFile): ts.Diagnostic;
23
+ /**
24
+ * Create a warning diagnostic for duplicate class
25
+ */
26
+ createDuplicateDiagnostic(classInfo: ClassNameInfo, sourceFile: ts.SourceFile): ts.Diagnostic;
14
27
  /**
15
28
  * Create multiple diagnostics from class info array
16
29
  */
17
30
  createDiagnostics(classInfos: ClassNameInfo[], sourceFile: ts.SourceFile): ts.Diagnostic[];
31
+ /**
32
+ * Create multiple duplicate warning diagnostics
33
+ */
34
+ createDuplicateDiagnostics(classInfos: ClassNameInfo[], sourceFile: ts.SourceFile): ts.Diagnostic[];
35
+ /**
36
+ * Create a warning diagnostic for extractable class (appears in all ternary branches)
37
+ */
38
+ createExtractableClassDiagnostic(classInfo: ClassNameInfo, sourceFile: ts.SourceFile): ts.Diagnostic;
39
+ /**
40
+ * Create multiple extractable class hint diagnostics
41
+ */
42
+ createExtractableClassDiagnostics(classInfos: ClassNameInfo[], sourceFile: ts.SourceFile): ts.Diagnostic[];
18
43
  }
19
44
  //# sourceMappingURL=DiagnosticService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DiagnosticService.d.ts","sourceRoot":"","sources":["../../src/services/DiagnosticService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAErD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,wBAAwB,QAAQ,CAAC;AAE9C;;GAEG;AACH,qBAAa,iBAAkB,YAAW,kBAAkB;IAC3D,gBAAgB,CAAC,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU;IAmBpF;;OAEG;IACH,iBAAiB,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU,EAAE;CAG1F"}
1
+ {"version":3,"file":"DiagnosticService.d.ts","sourceRoot":"","sources":["../../src/services/DiagnosticService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAErD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,wBAAwB,QAAQ,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,uBAAuB,QAAQ,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,+BAA+B,QAAQ,CAAC;AAErD;;GAEG;AACH,qBAAa,iBAAkB,YAAW,kBAAkB;IAC3D,gBAAgB,CAAC,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU;IAmBpF;;OAEG;IACH,yBAAyB,CAAC,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU;IAmB7F;;OAEG;IACH,iBAAiB,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU,EAAE;IAI1F;;OAEG;IACH,0BAA0B,CACzB,UAAU,EAAE,aAAa,EAAE,EAC3B,UAAU,EAAE,EAAE,CAAC,UAAU,GACvB,EAAE,CAAC,UAAU,EAAE;IAIlB;;OAEG;IACH,gCAAgC,CAC/B,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,EAAE,CAAC,UAAU,GACvB,EAAE,CAAC,UAAU;IAchB;;OAEG;IACH,iCAAiC,CAChC,UAAU,EAAE,aAAa,EAAE,EAC3B,UAAU,EAAE,EAAE,CAAC,UAAU,GACvB,EAAE,CAAC,UAAU,EAAE;CAKlB"}
@@ -33,13 +33,22 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.DiagnosticService = exports.TAILWIND_DIAGNOSTIC_CODE = void 0;
36
+ exports.DiagnosticService = exports.TAILWIND_EXTRACTABLE_CLASS_CODE = exports.TAILWIND_DUPLICATE_CODE = exports.TAILWIND_DIAGNOSTIC_CODE = void 0;
37
37
  const ts = __importStar(require("typescript/lib/tsserverlibrary"));
38
38
  /**
39
- * Diagnostic code for Tailwind plugin errors
39
+ * Diagnostic code for Tailwind plugin errors (invalid class)
40
40
  * Used to identify our diagnostics for code actions
41
41
  */
42
42
  exports.TAILWIND_DIAGNOSTIC_CODE = 90001;
43
+ /**
44
+ * Diagnostic code for duplicate class warnings
45
+ */
46
+ exports.TAILWIND_DUPLICATE_CODE = 90002;
47
+ /**
48
+ * Diagnostic code for extractable class suggestions (hint)
49
+ * Used when a class appears in all branches of a ternary but not at root level
50
+ */
51
+ exports.TAILWIND_EXTRACTABLE_CLASS_CODE = 90003;
43
52
  /**
44
53
  * Service responsible for creating TypeScript diagnostics
45
54
  */
@@ -60,12 +69,58 @@ class DiagnosticService {
60
69
  source: 'tw-plugin'
61
70
  };
62
71
  }
72
+ /**
73
+ * Create a warning diagnostic for duplicate class
74
+ */
75
+ createDuplicateDiagnostic(classInfo, sourceFile) {
76
+ let messageText = `Duplicate class "${classInfo.className}"`;
77
+ // Add context for variable references
78
+ if (classInfo.variableUsage) {
79
+ messageText += `. This value comes from variable "${classInfo.variableUsage.variableName}" used on line ${classInfo.variableUsage.usageLine}`;
80
+ }
81
+ return {
82
+ file: sourceFile,
83
+ start: classInfo.absoluteStart,
84
+ length: classInfo.length,
85
+ messageText,
86
+ category: ts.DiagnosticCategory.Warning,
87
+ code: exports.TAILWIND_DUPLICATE_CODE,
88
+ source: 'tw-plugin'
89
+ };
90
+ }
63
91
  /**
64
92
  * Create multiple diagnostics from class info array
65
93
  */
66
94
  createDiagnostics(classInfos, sourceFile) {
67
95
  return classInfos.map(classInfo => this.createDiagnostic(classInfo, sourceFile));
68
96
  }
97
+ /**
98
+ * Create multiple duplicate warning diagnostics
99
+ */
100
+ createDuplicateDiagnostics(classInfos, sourceFile) {
101
+ return classInfos.map(classInfo => this.createDuplicateDiagnostic(classInfo, sourceFile));
102
+ }
103
+ /**
104
+ * Create a warning diagnostic for extractable class (appears in all ternary branches)
105
+ */
106
+ createExtractableClassDiagnostic(classInfo, sourceFile) {
107
+ const messageText = `Class "${classInfo.className}" is repeated in both branches. Consider moving it outside the conditional.`;
108
+ return {
109
+ file: sourceFile,
110
+ start: classInfo.absoluteStart,
111
+ length: classInfo.length,
112
+ messageText,
113
+ category: ts.DiagnosticCategory.Warning,
114
+ code: exports.TAILWIND_EXTRACTABLE_CLASS_CODE,
115
+ source: 'tw-plugin'
116
+ };
117
+ }
118
+ /**
119
+ * Create multiple extractable class hint diagnostics
120
+ */
121
+ createExtractableClassDiagnostics(classInfos, sourceFile) {
122
+ return classInfos.map(classInfo => this.createExtractableClassDiagnostic(classInfo, sourceFile));
123
+ }
69
124
  }
70
125
  exports.DiagnosticService = DiagnosticService;
71
126
  //# sourceMappingURL=DiagnosticService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DiagnosticService.js","sourceRoot":"","sources":["../../src/services/DiagnosticService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mEAAqD;AAKrD;;;GAGG;AACU,QAAA,wBAAwB,GAAG,KAAK,CAAC;AAE9C;;GAEG;AACH,MAAa,iBAAiB;IAC7B,gBAAgB,CAAC,SAAwB,EAAE,UAAyB;QACnE,IAAI,WAAW,GAAG,cAAc,SAAS,CAAC,SAAS,iCAAiC,CAAC;QAErF,sCAAsC;QACtC,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;YAC7B,WAAW,IAAI,mDAAmD,SAAS,CAAC,aAAa,CAAC,YAAY,aAAa,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;QACxJ,CAAC;QAED,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,SAAS,CAAC,aAAa;YAC9B,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,WAAW;YACX,QAAQ,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK;YACrC,IAAI,EAAE,gCAAwB;YAC9B,MAAM,EAAE,WAAW;SACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,UAA2B,EAAE,UAAyB;QACvE,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAClF,CAAC;CACD;AA1BD,8CA0BC"}
1
+ {"version":3,"file":"DiagnosticService.js","sourceRoot":"","sources":["../../src/services/DiagnosticService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mEAAqD;AAKrD;;;GAGG;AACU,QAAA,wBAAwB,GAAG,KAAK,CAAC;AAE9C;;GAEG;AACU,QAAA,uBAAuB,GAAG,KAAK,CAAC;AAE7C;;;GAGG;AACU,QAAA,+BAA+B,GAAG,KAAK,CAAC;AAErD;;GAEG;AACH,MAAa,iBAAiB;IAC7B,gBAAgB,CAAC,SAAwB,EAAE,UAAyB;QACnE,IAAI,WAAW,GAAG,cAAc,SAAS,CAAC,SAAS,iCAAiC,CAAC;QAErF,sCAAsC;QACtC,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;YAC7B,WAAW,IAAI,mDAAmD,SAAS,CAAC,aAAa,CAAC,YAAY,aAAa,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;QACxJ,CAAC;QAED,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,SAAS,CAAC,aAAa;YAC9B,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,WAAW;YACX,QAAQ,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK;YACrC,IAAI,EAAE,gCAAwB;YAC9B,MAAM,EAAE,WAAW;SACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,yBAAyB,CAAC,SAAwB,EAAE,UAAyB;QAC5E,IAAI,WAAW,GAAG,oBAAoB,SAAS,CAAC,SAAS,GAAG,CAAC;QAE7D,sCAAsC;QACtC,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;YAC7B,WAAW,IAAI,qCAAqC,SAAS,CAAC,aAAa,CAAC,YAAY,kBAAkB,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;QAC/I,CAAC;QAED,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,SAAS,CAAC,aAAa;YAC9B,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,WAAW;YACX,QAAQ,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAO;YACvC,IAAI,EAAE,+BAAuB;YAC7B,MAAM,EAAE,WAAW;SACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,UAA2B,EAAE,UAAyB;QACvE,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAClF,CAAC;IAED;;OAEG;IACH,0BAA0B,CACzB,UAA2B,EAC3B,UAAyB;QAEzB,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED;;OAEG;IACH,gCAAgC,CAC/B,SAAwB,EACxB,UAAyB;QAEzB,MAAM,WAAW,GAAG,UAAU,SAAS,CAAC,SAAS,6EAA6E,CAAC;QAE/H,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,SAAS,CAAC,aAAa;YAC9B,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,WAAW;YACX,QAAQ,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAO;YACvC,IAAI,EAAE,uCAA+B;YACrC,MAAM,EAAE,WAAW;SACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,iCAAiC,CAChC,UAA2B,EAC3B,UAAyB;QAEzB,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CACjC,IAAI,CAAC,gCAAgC,CAAC,SAAS,EAAE,UAAU,CAAC,CAC5D,CAAC;IACH,CAAC;CACD;AA1FD,8CA0FC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=DuplicateClassDetection.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DuplicateClassDetection.spec.d.ts","sourceRoot":"","sources":["../../src/services/DuplicateClassDetection.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,435 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const ts = __importStar(require("typescript/lib/tsserverlibrary"));
37
+ const Logger_1 = require("../utils/Logger");
38
+ const ClassNameExtractionService_1 = require("./ClassNameExtractionService");
39
+ const DiagnosticService_1 = require("./DiagnosticService");
40
+ const ValidationService_1 = require("./ValidationService");
41
+ // Mock validator that considers all classes valid (for testing duplicates only)
42
+ class MockValidator {
43
+ isInitialized() {
44
+ return true;
45
+ }
46
+ isValidClass() {
47
+ return true;
48
+ }
49
+ getInvalidClasses() {
50
+ return [];
51
+ }
52
+ setAllowedClasses() {
53
+ // No-op for testing
54
+ }
55
+ }
56
+ describe('Duplicate Class Detection', () => {
57
+ let validationService;
58
+ let diagnosticService;
59
+ let extractionService;
60
+ let mockValidator;
61
+ let logger;
62
+ beforeEach(() => {
63
+ diagnosticService = new DiagnosticService_1.DiagnosticService();
64
+ extractionService = new ClassNameExtractionService_1.ClassNameExtractionService();
65
+ mockValidator = new MockValidator();
66
+ logger = new Logger_1.NoOpLogger();
67
+ validationService = new ValidationService_1.ValidationService(extractionService, diagnosticService, mockValidator, logger);
68
+ });
69
+ describe('simple string literals', () => {
70
+ it('should detect duplicate classes in className string', () => {
71
+ const sourceCode = '<div className="flex flex items-center">Hello</div>';
72
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
73
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
74
+ // Should have 1 duplicate diagnostic for the second "flex"
75
+ expect(diagnostics.length).toBe(1);
76
+ expect(diagnostics[0].code).toBe(DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
77
+ expect(diagnostics[0].category).toBe(ts.DiagnosticCategory.Warning);
78
+ expect(diagnostics[0].messageText).toContain('Duplicate class "flex"');
79
+ });
80
+ it('should detect multiple duplicate classes', () => {
81
+ const sourceCode = '<div className="flex flex items-center items-center p-4">Hello</div>';
82
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
83
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
84
+ // Should have 2 duplicate diagnostics
85
+ expect(diagnostics.length).toBe(2);
86
+ expect(diagnostics.every(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE)).toBe(true);
87
+ });
88
+ it('should not flag same class in different elements', () => {
89
+ const sourceCode = `
90
+ <div className="flex">
91
+ <span className="flex">Hello</span>
92
+ </div>
93
+ `;
94
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
95
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
96
+ // Should have no duplicates - each "flex" is in a different attribute
97
+ expect(diagnostics.length).toBe(0);
98
+ });
99
+ it('should flag only second and subsequent occurrences', () => {
100
+ const sourceCode = '<div className="flex flex flex items-center">Hello</div>';
101
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
102
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
103
+ // Should have 2 duplicate diagnostics (for 2nd and 3rd "flex")
104
+ expect(diagnostics.length).toBe(2);
105
+ // Find positions of all "flex" occurrences
106
+ const flexPositions = [];
107
+ let pos = sourceCode.indexOf('flex');
108
+ while (pos !== -1) {
109
+ flexPositions.push(pos);
110
+ pos = sourceCode.indexOf('flex', pos + 1);
111
+ }
112
+ // Diagnostics should NOT point to the first "flex"
113
+ const firstFlexPosition = flexPositions[0];
114
+ expect(diagnostics.every(d => d.start !== firstFlexPosition)).toBe(true);
115
+ });
116
+ });
117
+ describe('JSX expressions', () => {
118
+ it('should detect duplicates in JSX expression with string literal', () => {
119
+ const sourceCode = "<div className={'flex flex items-center'}>Hello</div>";
120
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
121
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
122
+ expect(diagnostics.length).toBe(1);
123
+ expect(diagnostics[0].code).toBe(DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
124
+ });
125
+ it('should detect duplicates in template literals', () => {
126
+ const sourceCode = '<div className={`flex flex items-center`}>Hello</div>';
127
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
128
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
129
+ expect(diagnostics.length).toBe(1);
130
+ expect(diagnostics[0].code).toBe(DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
131
+ });
132
+ });
133
+ describe('utility function calls', () => {
134
+ it('should detect duplicates in clsx arguments', () => {
135
+ const sourceCode = "<div className={clsx('flex', 'flex', 'items-center')}>Hello</div>";
136
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
137
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['clsx']);
138
+ expect(diagnostics.length).toBe(1);
139
+ expect(diagnostics[0].code).toBe(DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
140
+ });
141
+ it('should detect duplicates in cn function arguments', () => {
142
+ const sourceCode = "<div className={cn('p-4 p-4 m-2')}>Hello</div>";
143
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
144
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['cn']);
145
+ expect(diagnostics.length).toBe(1);
146
+ expect(diagnostics[0].code).toBe(DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
147
+ });
148
+ });
149
+ describe('diagnostic message format', () => {
150
+ it('should have correct warning message', () => {
151
+ const sourceCode = '<div className="bg-red-500 bg-red-500">Hello</div>';
152
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
153
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
154
+ expect(diagnostics[0].messageText).toBe('Duplicate class "bg-red-500"');
155
+ });
156
+ it('should have source set to tw-plugin', () => {
157
+ const sourceCode = '<div className="flex flex">Hello</div>';
158
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
159
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
160
+ expect(diagnostics[0].source).toBe('tw-plugin');
161
+ });
162
+ });
163
+ describe('no false positives', () => {
164
+ it('should not flag unique classes', () => {
165
+ const sourceCode = '<div className="flex items-center justify-between p-4 bg-white">Hello</div>';
166
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
167
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
168
+ expect(diagnostics.length).toBe(0);
169
+ });
170
+ it('should not flag similar but different classes', () => {
171
+ const sourceCode = '<div className="p-4 pt-4 px-4 py-4">Hello</div>';
172
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
173
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
174
+ expect(diagnostics.length).toBe(0);
175
+ });
176
+ });
177
+ describe('ternary conditional expressions', () => {
178
+ it('should flag duplicate when class is at root AND in ternary branches', () => {
179
+ // Case: clsx('flex', isActive ? 'flex bg-blue-500' : 'flex bg-gray-500')
180
+ // The root 'flex' + branch 'flex' = true duplicate
181
+ const sourceCode = "<div className={clsx('flex', isActive ? 'flex bg-blue-500' : 'flex bg-gray-500')}>Hello</div>";
182
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
183
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['clsx']);
184
+ // Should have 2 duplicate warnings (one for each branch's 'flex')
185
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
186
+ expect(duplicates.length).toBe(2);
187
+ expect(duplicates.every(d => d.category === ts.DiagnosticCategory.Warning)).toBe(true);
188
+ });
189
+ it('should show hint when class appears in both branches but NOT at root', () => {
190
+ // Case: clsx('mt-4', isActive ? 'flex bg-blue-500' : 'flex bg-gray-500')
191
+ // No root 'flex', but 'flex' in both branches = extractable hint
192
+ const sourceCode = "<div className={clsx('mt-4', isActive ? 'flex bg-blue-500' : 'flex bg-gray-500')}>Hello</div>";
193
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
194
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['clsx']);
195
+ // Should have 2 extractable warnings (one for each 'flex' in both branches)
196
+ const hints = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_EXTRACTABLE_CLASS_CODE);
197
+ expect(hints.length).toBe(2);
198
+ expect(hints.every(h => h.category === ts.DiagnosticCategory.Warning)).toBe(true);
199
+ expect(hints.every(h => h.messageText.includes('repeated in both branches'))).toBe(true);
200
+ });
201
+ it('should not flag class in only one ternary branch', () => {
202
+ // Case: clsx('mt-4', isActive ? 'flex bg-blue-500' : 'bg-gray-500')
203
+ // 'flex' only in true branch = no issue
204
+ const sourceCode = "<div className={clsx('mt-4', isActive ? 'flex bg-blue-500' : 'bg-gray-500')}>Hello</div>";
205
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
206
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['clsx']);
207
+ expect(diagnostics.length).toBe(0);
208
+ });
209
+ it('should flag duplicate within same ternary branch', () => {
210
+ // Case: clsx('mt-4', isActive ? 'flex flex bg-blue-500' : 'bg-gray-500')
211
+ // 'flex' twice in true branch = true duplicate
212
+ const sourceCode = "<div className={clsx('mt-4', isActive ? 'flex flex bg-blue-500' : 'bg-gray-500')}>Hello</div>";
213
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
214
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['clsx']);
215
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
216
+ expect(duplicates.length).toBe(1);
217
+ expect(duplicates[0].category).toBe(ts.DiagnosticCategory.Warning);
218
+ });
219
+ it('should handle simple ternary without utility function', () => {
220
+ // Case: className={isActive ? 'flex bg-blue-500' : 'flex bg-gray-500'}
221
+ const sourceCode = "<div className={isActive ? 'flex bg-blue-500' : 'flex bg-gray-500'}>Hello</div>";
222
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
223
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
224
+ // Should have 2 extractable hints (one for each branch)
225
+ const hints = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_EXTRACTABLE_CLASS_CODE);
226
+ expect(hints.length).toBe(2);
227
+ expect(hints.every(h => h.messageText.includes('flex'))).toBe(true);
228
+ });
229
+ it('should handle multiple extractable classes in ternary', () => {
230
+ // Case: className={isActive ? 'flex items-center p-4' : 'flex items-center m-4'}
231
+ // Both 'flex' and 'items-center' appear in both branches
232
+ const sourceCode = "<div className={isActive ? 'flex items-center p-4' : 'flex items-center m-4'}>Hello</div>";
233
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
234
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
235
+ const hints = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_EXTRACTABLE_CLASS_CODE);
236
+ // 2 classes (flex, items-center) × 2 branches = 4 hints
237
+ expect(hints.length).toBe(4);
238
+ });
239
+ });
240
+ describe('binary expressions (&&)', () => {
241
+ it('should flag duplicate when class is at root AND in binary && branch', () => {
242
+ // Case: clsx('flex', isError && 'flex text-red-500')
243
+ // Root 'flex' + conditional 'flex' = duplicate when condition is true
244
+ const sourceCode = "<div className={clsx('flex', isError && 'flex text-red-500')}>Hello</div>";
245
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
246
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['clsx']);
247
+ // Should warn - if isError is true, 'flex' would be duplicated
248
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
249
+ expect(duplicates.length).toBe(1);
250
+ });
251
+ it('should NOT flag class only in binary && branch (no root duplicate)', () => {
252
+ // Case: clsx('mt-4', isError && 'flex text-red-500')
253
+ // No root 'flex', just conditional = no duplicate
254
+ const sourceCode = "<div className={clsx('mt-4', isError && 'flex text-red-500')}>Hello</div>";
255
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
256
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['clsx']);
257
+ expect(diagnostics.length).toBe(0);
258
+ });
259
+ });
260
+ describe('variables with conditional content', () => {
261
+ it.skip('should flag duplicate when variable contains ternary with same class as root', () => {
262
+ // NOTE: This test requires a TypeChecker which is not available in unit tests.
263
+ // Variable resolution is tested via e2e tests in example/src/duplicate-classes.tsx
264
+ //
265
+ // Case: const dynamicClasses = isActive ? 'flex bg-blue-500' : 'flex bg-gray-500';
266
+ // clsx('flex', dynamicClasses)
267
+ // Should detect that 'flex' is in root AND in both branches of the variable
268
+ });
269
+ });
270
+ describe('arrays with conditionals', () => {
271
+ it('should flag duplicate when array contains conditional with same class', () => {
272
+ // Case: ['flex', isActive && 'flex']
273
+ const sourceCode = "<div className={clsx(['flex', isActive && 'flex'])}>Hello</div>";
274
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
275
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['clsx']);
276
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
277
+ expect(duplicates.length).toBe(1);
278
+ });
279
+ it('should NOT flag when array conditional has different class', () => {
280
+ // Case: ['flex', isActive && 'items-center']
281
+ const sourceCode = "<div className={clsx(['flex', isActive && 'items-center'])}>Hello</div>";
282
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
283
+ const diagnostics = validationService.validateFile(ts, sourceFile, ['clsx']);
284
+ expect(diagnostics.length).toBe(0);
285
+ });
286
+ });
287
+ describe('tailwind-variants tv() duplicate detection', () => {
288
+ it('should detect duplicates in tv() base property', () => {
289
+ const sourceCode = `
290
+ import { tv } from 'tailwind-variants';
291
+ const button = tv({
292
+ base: 'flex flex items-center'
293
+ });
294
+ `;
295
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
296
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
297
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
298
+ expect(duplicates.length).toBe(1);
299
+ expect(duplicates[0].messageText).toContain('flex');
300
+ });
301
+ it('should detect duplicates across tv() base and variants', () => {
302
+ const sourceCode = `
303
+ import { tv } from 'tailwind-variants';
304
+ const button = tv({
305
+ base: 'flex items-center',
306
+ variants: {
307
+ size: {
308
+ sm: 'flex text-sm'
309
+ }
310
+ }
311
+ });
312
+ `;
313
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
314
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
315
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
316
+ expect(duplicates.length).toBe(1);
317
+ expect(duplicates[0].messageText).toContain('flex');
318
+ });
319
+ it('should detect duplicates in tv() compoundVariants', () => {
320
+ const sourceCode = `
321
+ import { tv } from 'tailwind-variants';
322
+ const button = tv({
323
+ base: 'flex items-center',
324
+ compoundVariants: [
325
+ { size: 'sm', class: 'flex font-bold' }
326
+ ]
327
+ });
328
+ `;
329
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
330
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
331
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
332
+ expect(duplicates.length).toBe(1);
333
+ expect(duplicates[0].messageText).toContain('flex');
334
+ });
335
+ it('should NOT flag duplicates between different tv() calls', () => {
336
+ const sourceCode = `
337
+ import { tv } from 'tailwind-variants';
338
+ const button = tv({
339
+ base: 'flex items-center'
340
+ });
341
+ const card = tv({
342
+ base: 'flex justify-center'
343
+ });
344
+ `;
345
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
346
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
347
+ // Each tv() call has its own scope, so no duplicates
348
+ expect(diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE).length).toBe(0);
349
+ });
350
+ it('should detect duplicates in tv() slots', () => {
351
+ const sourceCode = `
352
+ import { tv } from 'tailwind-variants';
353
+ const card = tv({
354
+ slots: {
355
+ base: 'flex flex items-center',
356
+ content: 'p-4'
357
+ }
358
+ });
359
+ `;
360
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
361
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
362
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
363
+ expect(duplicates.length).toBe(1);
364
+ expect(duplicates[0].messageText).toContain('flex');
365
+ });
366
+ });
367
+ describe('class-variance-authority cva() duplicate detection', () => {
368
+ it('should detect duplicates in cva() base array', () => {
369
+ const sourceCode = `
370
+ import { cva } from 'class-variance-authority';
371
+ const button = cva(['flex', 'flex', 'items-center']);
372
+ `;
373
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
374
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
375
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
376
+ expect(duplicates.length).toBe(1);
377
+ expect(duplicates[0].messageText).toContain('flex');
378
+ });
379
+ it('should detect duplicates across cva() base and variants', () => {
380
+ const sourceCode = `
381
+ import { cva } from 'class-variance-authority';
382
+ const button = cva(['flex', 'items-center'], {
383
+ variants: {
384
+ intent: {
385
+ primary: ['flex', 'bg-blue-500']
386
+ }
387
+ }
388
+ });
389
+ `;
390
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
391
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
392
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
393
+ expect(duplicates.length).toBe(1);
394
+ expect(duplicates[0].messageText).toContain('flex');
395
+ });
396
+ it('should detect duplicates in cva() compoundVariants', () => {
397
+ const sourceCode = `
398
+ import { cva } from 'class-variance-authority';
399
+ const button = cva(['flex', 'items-center'], {
400
+ compoundVariants: [
401
+ { intent: 'primary', class: 'flex font-bold' }
402
+ ]
403
+ });
404
+ `;
405
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
406
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
407
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
408
+ expect(duplicates.length).toBe(1);
409
+ expect(duplicates[0].messageText).toContain('flex');
410
+ });
411
+ it('should NOT flag duplicates between different cva() calls', () => {
412
+ const sourceCode = `
413
+ import { cva } from 'class-variance-authority';
414
+ const button = cva(['flex', 'items-center']);
415
+ const card = cva(['flex', 'justify-center']);
416
+ `;
417
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
418
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
419
+ // Each cva() call has its own scope, so no duplicates
420
+ expect(diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE).length).toBe(0);
421
+ });
422
+ it('should detect duplicates in cva() string base', () => {
423
+ const sourceCode = `
424
+ import { cva } from 'class-variance-authority';
425
+ const button = cva('flex flex items-center');
426
+ `;
427
+ const sourceFile = ts.createSourceFile('test.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
428
+ const diagnostics = validationService.validateFile(ts, sourceFile, []);
429
+ const duplicates = diagnostics.filter(d => d.code === DiagnosticService_1.TAILWIND_DUPLICATE_CODE);
430
+ expect(duplicates.length).toBe(1);
431
+ expect(duplicates[0].messageText).toContain('flex');
432
+ });
433
+ });
434
+ });
435
+ //# sourceMappingURL=DuplicateClassDetection.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DuplicateClassDetection.spec.js","sourceRoot":"","sources":["../../src/services/DuplicateClassDetection.spec.ts"],"names":[],"mappings":"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"}
@@ -23,5 +23,9 @@ export declare class ValidationService {
23
23
  * PERFORMANCE OPTIMIZED: No logging in hot path
24
24
  */
25
25
  private filterInvalidClasses;
26
+ /**
27
+ * Result of duplicate detection with separate categories
28
+ */
29
+ private findDuplicateClasses;
26
30
  }
27
31
  //# sourceMappingURL=ValidationService.d.ts.map