tailwind-typescript-plugin 0.0.2-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 (88) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +21 -0
  3. package/README.md +538 -0
  4. package/lib/core/interfaces.d.ts +45 -0
  5. package/lib/core/interfaces.d.ts.map +1 -0
  6. package/lib/core/interfaces.js +3 -0
  7. package/lib/core/interfaces.js.map +1 -0
  8. package/lib/core/types.d.ts +27 -0
  9. package/lib/core/types.d.ts.map +1 -0
  10. package/lib/core/types.js +3 -0
  11. package/lib/core/types.js.map +1 -0
  12. package/lib/extractors/BaseExtractor.d.ts +20 -0
  13. package/lib/extractors/BaseExtractor.d.ts.map +1 -0
  14. package/lib/extractors/BaseExtractor.js +83 -0
  15. package/lib/extractors/BaseExtractor.js.map +1 -0
  16. package/lib/extractors/CvaExtractor.d.ts +88 -0
  17. package/lib/extractors/CvaExtractor.d.ts.map +1 -0
  18. package/lib/extractors/CvaExtractor.js +425 -0
  19. package/lib/extractors/CvaExtractor.js.map +1 -0
  20. package/lib/extractors/ExpressionExtractor.d.ts +16 -0
  21. package/lib/extractors/ExpressionExtractor.d.ts.map +1 -0
  22. package/lib/extractors/ExpressionExtractor.js +132 -0
  23. package/lib/extractors/ExpressionExtractor.js.map +1 -0
  24. package/lib/extractors/JsxAttributeExtractor.d.ts +20 -0
  25. package/lib/extractors/JsxAttributeExtractor.d.ts.map +1 -0
  26. package/lib/extractors/JsxAttributeExtractor.js +107 -0
  27. package/lib/extractors/JsxAttributeExtractor.js.map +1 -0
  28. package/lib/extractors/JsxAttributeExtractor.original.d.ts +15 -0
  29. package/lib/extractors/JsxAttributeExtractor.original.d.ts.map +1 -0
  30. package/lib/extractors/JsxAttributeExtractor.original.js +84 -0
  31. package/lib/extractors/JsxAttributeExtractor.original.js.map +1 -0
  32. package/lib/extractors/StringLiteralExtractor.d.ts +12 -0
  33. package/lib/extractors/StringLiteralExtractor.d.ts.map +1 -0
  34. package/lib/extractors/StringLiteralExtractor.js +21 -0
  35. package/lib/extractors/StringLiteralExtractor.js.map +1 -0
  36. package/lib/extractors/TailwindVariantsExtractor.d.ts +87 -0
  37. package/lib/extractors/TailwindVariantsExtractor.d.ts.map +1 -0
  38. package/lib/extractors/TailwindVariantsExtractor.js +447 -0
  39. package/lib/extractors/TailwindVariantsExtractor.js.map +1 -0
  40. package/lib/extractors/TemplateExpressionExtractor.d.ts +14 -0
  41. package/lib/extractors/TemplateExpressionExtractor.d.ts.map +1 -0
  42. package/lib/extractors/TemplateExpressionExtractor.js +66 -0
  43. package/lib/extractors/TemplateExpressionExtractor.js.map +1 -0
  44. package/lib/index.d.ts +65 -0
  45. package/lib/index.d.ts.map +1 -0
  46. package/lib/index.js +4 -0
  47. package/lib/index.js.map +1 -0
  48. package/lib/infrastructure/TailwindValidator.d.ts +42 -0
  49. package/lib/infrastructure/TailwindValidator.d.ts.map +1 -0
  50. package/lib/infrastructure/TailwindValidator.js +152 -0
  51. package/lib/infrastructure/TailwindValidator.js.map +1 -0
  52. package/lib/infrastructure/TailwindValidator.spec.d.ts +2 -0
  53. package/lib/infrastructure/TailwindValidator.spec.d.ts.map +1 -0
  54. package/lib/infrastructure/TailwindValidator.spec.js +219 -0
  55. package/lib/infrastructure/TailwindValidator.spec.js.map +1 -0
  56. package/lib/plugin/TailwindTypescriptPlugin.d.ts +52 -0
  57. package/lib/plugin/TailwindTypescriptPlugin.d.ts.map +1 -0
  58. package/lib/plugin/TailwindTypescriptPlugin.js +142 -0
  59. package/lib/plugin/TailwindTypescriptPlugin.js.map +1 -0
  60. package/lib/services/ClassNameExtractionService.d.ts +37 -0
  61. package/lib/services/ClassNameExtractionService.d.ts.map +1 -0
  62. package/lib/services/ClassNameExtractionService.js +98 -0
  63. package/lib/services/ClassNameExtractionService.js.map +1 -0
  64. package/lib/services/ClassNameExtractionService.original.d.ts +20 -0
  65. package/lib/services/ClassNameExtractionService.original.d.ts.map +1 -0
  66. package/lib/services/ClassNameExtractionService.original.js +48 -0
  67. package/lib/services/ClassNameExtractionService.original.js.map +1 -0
  68. package/lib/services/DiagnosticService.d.ts +14 -0
  69. package/lib/services/DiagnosticService.d.ts.map +1 -0
  70. package/lib/services/DiagnosticService.js +61 -0
  71. package/lib/services/DiagnosticService.js.map +1 -0
  72. package/lib/services/PerformanceCache.d.ts +15 -0
  73. package/lib/services/PerformanceCache.d.ts.map +1 -0
  74. package/lib/services/PerformanceCache.js +44 -0
  75. package/lib/services/PerformanceCache.js.map +1 -0
  76. package/lib/services/PluginConfigService.d.ts +22 -0
  77. package/lib/services/PluginConfigService.d.ts.map +1 -0
  78. package/lib/services/PluginConfigService.js +86 -0
  79. package/lib/services/PluginConfigService.js.map +1 -0
  80. package/lib/services/ValidationService.d.ts +25 -0
  81. package/lib/services/ValidationService.d.ts.map +1 -0
  82. package/lib/services/ValidationService.js +50 -0
  83. package/lib/services/ValidationService.js.map +1 -0
  84. package/lib/utils/Logger.d.ts +10 -0
  85. package/lib/utils/Logger.d.ts.map +1 -0
  86. package/lib/utils/Logger.js +13 -0
  87. package/lib/utils/Logger.js.map +1 -0
  88. package/package.json +84 -0
@@ -0,0 +1,447 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TailwindVariantsExtractor = void 0;
4
+ const BaseExtractor_1 = require("./BaseExtractor");
5
+ /**
6
+ * Extracts class names from tailwind-variants tv() function calls
7
+ *
8
+ * Supports:
9
+ * - base: string with classes or array of strings
10
+ * - variants: nested object with string values containing classes
11
+ * - compoundVariants: array of objects with class/className properties
12
+ * - slots: object where values contain classes
13
+ * - Import aliasing: import { tv as myTv } from 'tailwind-variants'
14
+ * - class property overrides: button({ color: 'primary', class: 'bg-pink-500' })
15
+ *
16
+ * PERFORMANCE OPTIMIZATIONS:
17
+ * - ✅ Import detection cached per file (one-time AST scan)
18
+ * - ✅ Early exits for non-tv calls (fast path)
19
+ * - ✅ Direct property access (no unnecessary traversal)
20
+ * - ✅ Inline hot paths (string literal extraction)
21
+ * - ✅ Short-circuit evaluation (skip work when possible)
22
+ * - ✅ TypeChecker-based origin tracking (cached per symbol)
23
+ */
24
+ class TailwindVariantsExtractor extends BaseExtractor_1.BaseExtractor {
25
+ constructor() {
26
+ super(...arguments);
27
+ this.tvImportCache = new Map();
28
+ this.tvVariableCache = new Map();
29
+ }
30
+ canHandle(node, context) {
31
+ return context.typescript.isCallExpression(node);
32
+ }
33
+ extract(node, context) {
34
+ // OPTIMIZATION: Type guard first (fastest check)
35
+ if (!context.typescript.isCallExpression(node)) {
36
+ return [];
37
+ }
38
+ const callExpression = node;
39
+ // OPTIMIZATION: Check if this is a tv() definition call
40
+ if (this.isTvCall(callExpression, context)) {
41
+ // OPTIMIZATION: Early exit for empty arguments
42
+ if (callExpression.arguments.length === 0) {
43
+ return [];
44
+ }
45
+ const configArg = callExpression.arguments[0];
46
+ // OPTIMIZATION: Early exit if not an object literal
47
+ if (!context.typescript.isObjectLiteralExpression(configArg)) {
48
+ return [];
49
+ }
50
+ // Extract class names from the tv() configuration object
51
+ return this.extractFromTvConfig(configArg, context);
52
+ }
53
+ // Check if this is a call to a function created by tv() (e.g., button({ class: '...' }))
54
+ // IMPORTANT: Only validate if NOT a utility function
55
+ if (this.isTvCreatedFunctionCall(callExpression, context)) {
56
+ return this.extractFromTvFunctionCall(callExpression, context);
57
+ }
58
+ return [];
59
+ }
60
+ /**
61
+ * Check if this call expression is a tv() call from tailwind-variants
62
+ * Supports import aliasing: import { tv as myTv } from 'tailwind-variants'
63
+ */
64
+ isTvCall(callExpression, context) {
65
+ const expr = callExpression.expression;
66
+ const tvNames = this.getTvImportNames(context);
67
+ // No tv imports found
68
+ if (tvNames.size === 0) {
69
+ return false;
70
+ }
71
+ // Handle simple calls: tv(...) or myTv(...)
72
+ if (context.typescript.isIdentifier(expr)) {
73
+ return tvNames.has(expr.text);
74
+ }
75
+ // Handle member expressions: variants.tv(...), utils.myTv(...)
76
+ if (context.typescript.isPropertyAccessExpression(expr)) {
77
+ return tvNames.has(expr.name.text);
78
+ }
79
+ return false;
80
+ }
81
+ /**
82
+ * Get all local names for tv imports from tailwind-variants
83
+ * Supports aliasing: import { tv as myTv } -> returns Set(['myTv'])
84
+ * Caches result per file for performance
85
+ */
86
+ getTvImportNames(context) {
87
+ const fileName = context.sourceFile.fileName;
88
+ // Check cache first
89
+ if (this.tvImportCache.has(fileName)) {
90
+ return this.tvImportCache.get(fileName);
91
+ }
92
+ // Search for import statement
93
+ const tvNames = new Set();
94
+ for (const statement of context.sourceFile.statements) {
95
+ if (!context.typescript.isImportDeclaration(statement)) {
96
+ continue;
97
+ }
98
+ const moduleSpecifier = statement.moduleSpecifier;
99
+ if (!context.typescript.isStringLiteral(moduleSpecifier) ||
100
+ moduleSpecifier.text !== 'tailwind-variants') {
101
+ continue;
102
+ }
103
+ const importClause = statement.importClause;
104
+ if (!importClause) {
105
+ continue;
106
+ }
107
+ // Check named imports: import { tv } or import { tv as myTv }
108
+ const namedBindings = importClause.namedBindings;
109
+ if (namedBindings && context.typescript.isNamedImports(namedBindings)) {
110
+ for (const element of namedBindings.elements) {
111
+ // Check if the original export name is 'tv'
112
+ // For: import { tv } -> propertyName is undefined, name is 'tv'
113
+ // For: import { tv as myTv } -> propertyName is 'tv', name is 'myTv'
114
+ const originalName = element.propertyName?.text || element.name.text;
115
+ if (originalName === 'tv') {
116
+ // Add the local name (what it's called in this file)
117
+ tvNames.add(element.name.text);
118
+ }
119
+ }
120
+ }
121
+ }
122
+ // Cache the result
123
+ this.tvImportCache.set(fileName, tvNames);
124
+ return tvNames;
125
+ }
126
+ /**
127
+ * Extract class names from tv() configuration object
128
+ */
129
+ extractFromTvConfig(config, context) {
130
+ const classNames = [];
131
+ for (const property of config.properties) {
132
+ if (!context.typescript.isPropertyAssignment(property)) {
133
+ continue;
134
+ }
135
+ const propertyName = this.getPropertyName(property, context);
136
+ if (!propertyName) {
137
+ continue;
138
+ }
139
+ // Handle different tv() properties
140
+ switch (propertyName) {
141
+ case 'base':
142
+ // base: 'flex items-center' or base: ['flex', 'items-center']
143
+ classNames.push(...this.extractFromValue(property.initializer, context));
144
+ break;
145
+ case 'variants':
146
+ // variants: { size: { sm: 'text-sm', lg: 'text-lg' } }
147
+ classNames.push(...this.extractFromVariants(property.initializer, context));
148
+ break;
149
+ case 'compoundVariants':
150
+ // compoundVariants: [{ size: 'sm', color: 'primary', class: 'font-bold' }]
151
+ classNames.push(...this.extractFromCompoundVariants(property.initializer, context));
152
+ break;
153
+ case 'slots':
154
+ // slots: { base: 'flex', item: 'p-2' }
155
+ classNames.push(...this.extractFromSlots(property.initializer, context));
156
+ break;
157
+ case 'defaultVariants':
158
+ // defaultVariants doesn't contain classes, skip
159
+ break;
160
+ default:
161
+ // Other properties might contain classes, try to extract
162
+ classNames.push(...this.extractFromValue(property.initializer, context));
163
+ break;
164
+ }
165
+ }
166
+ return classNames;
167
+ }
168
+ /**
169
+ * Extract class names from the variants object
170
+ * Structure: { variantName: { optionName: 'classes' } }
171
+ */
172
+ extractFromVariants(node, context) {
173
+ if (!context.typescript.isObjectLiteralExpression(node)) {
174
+ return [];
175
+ }
176
+ const classNames = [];
177
+ // Iterate through each variant (e.g., size, color)
178
+ for (const variantProp of node.properties) {
179
+ if (!context.typescript.isPropertyAssignment(variantProp)) {
180
+ continue;
181
+ }
182
+ // Each variant value should be an object with options
183
+ if (context.typescript.isObjectLiteralExpression(variantProp.initializer)) {
184
+ // Iterate through each option (e.g., sm, lg, primary, secondary)
185
+ for (const optionProp of variantProp.initializer.properties) {
186
+ if (!context.typescript.isPropertyAssignment(optionProp)) {
187
+ continue;
188
+ }
189
+ // Extract classes from the option value
190
+ classNames.push(...this.extractFromValue(optionProp.initializer, context));
191
+ }
192
+ }
193
+ }
194
+ return classNames;
195
+ }
196
+ /**
197
+ * Extract class names from compoundVariants array
198
+ * Structure: [{ condition: value, class: 'classes' or className: 'classes' }]
199
+ */
200
+ extractFromCompoundVariants(node, context) {
201
+ if (!context.typescript.isArrayLiteralExpression(node)) {
202
+ return [];
203
+ }
204
+ const classNames = [];
205
+ // Iterate through each compound variant object
206
+ for (const element of node.elements) {
207
+ if (!context.typescript.isObjectLiteralExpression(element)) {
208
+ continue;
209
+ }
210
+ // Look for 'class' or 'className' property
211
+ for (const prop of element.properties) {
212
+ if (!context.typescript.isPropertyAssignment(prop)) {
213
+ continue;
214
+ }
215
+ const propName = this.getPropertyName(prop, context);
216
+ if (propName === 'class' || propName === 'className') {
217
+ classNames.push(...this.extractFromValue(prop.initializer, context));
218
+ }
219
+ }
220
+ }
221
+ return classNames;
222
+ }
223
+ /**
224
+ * Extract class names from slots object
225
+ * Structure: { slotName: 'classes' } or { slotName: { base: 'classes', variants: {...} } }
226
+ */
227
+ extractFromSlots(node, context) {
228
+ if (!context.typescript.isObjectLiteralExpression(node)) {
229
+ return [];
230
+ }
231
+ const classNames = [];
232
+ for (const slotProp of node.properties) {
233
+ if (!context.typescript.isPropertyAssignment(slotProp)) {
234
+ continue;
235
+ }
236
+ const slotValue = slotProp.initializer;
237
+ // If slot value is a string, extract classes
238
+ if (context.typescript.isStringLiteral(slotValue)) {
239
+ classNames.push(...this.extractFromStringLiteral(slotValue, context));
240
+ }
241
+ // If slot value is an object with base/variants, recurse
242
+ else if (context.typescript.isObjectLiteralExpression(slotValue)) {
243
+ classNames.push(...this.extractFromTvConfig(slotValue, context));
244
+ }
245
+ // Handle arrays and other expressions
246
+ else {
247
+ classNames.push(...this.extractFromValue(slotValue, context));
248
+ }
249
+ }
250
+ return classNames;
251
+ }
252
+ /**
253
+ * Extract class names from any expression value
254
+ */
255
+ extractFromValue(node, context) {
256
+ // String literal: 'flex items-center'
257
+ if (context.typescript.isStringLiteral(node)) {
258
+ return this.extractFromStringLiteral(node, context);
259
+ }
260
+ // No-substitution template literal: `flex items-center`
261
+ if (context.typescript.isNoSubstitutionTemplateLiteral(node)) {
262
+ return this.extractFromStringLiteral(node, context);
263
+ }
264
+ // Array: ['flex', 'items-center']
265
+ if (context.typescript.isArrayLiteralExpression(node)) {
266
+ const classNames = [];
267
+ for (const element of node.elements) {
268
+ if (context.typescript.isStringLiteral(element)) {
269
+ classNames.push(...this.extractFromStringLiteral(element, context));
270
+ }
271
+ }
272
+ return classNames;
273
+ }
274
+ // Template expression with variables: `flex ${something}`
275
+ // For now, we extract only the static parts
276
+ if (context.typescript.isTemplateExpression(node)) {
277
+ const classNames = [];
278
+ const lineNumber = context.sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
279
+ // Extract from head
280
+ if (node.head.text) {
281
+ const headText = node.head.text;
282
+ const headStart = node.head.getStart() + 1; // +1 to skip backtick
283
+ let offset = 0;
284
+ headText.split(' ').forEach(className => {
285
+ if (className) {
286
+ classNames.push({
287
+ className,
288
+ absoluteStart: headStart + offset,
289
+ length: className.length,
290
+ line: lineNumber,
291
+ file: context.sourceFile.fileName
292
+ });
293
+ }
294
+ offset += className.length + 1;
295
+ });
296
+ }
297
+ // Extract from template spans
298
+ for (const span of node.templateSpans) {
299
+ if (span.literal.text) {
300
+ const spanText = span.literal.text;
301
+ const spanStart = span.literal.getStart() + 1; // +1 to skip template literal quote
302
+ let offset = 0;
303
+ spanText.split(' ').forEach(className => {
304
+ if (className) {
305
+ classNames.push({
306
+ className,
307
+ absoluteStart: spanStart + offset,
308
+ length: className.length,
309
+ line: lineNumber,
310
+ file: context.sourceFile.fileName
311
+ });
312
+ }
313
+ offset += className.length + 1;
314
+ });
315
+ }
316
+ }
317
+ return classNames;
318
+ }
319
+ return [];
320
+ }
321
+ /**
322
+ * Get property name from a property assignment
323
+ */
324
+ getPropertyName(property, context) {
325
+ const name = property.name;
326
+ if (context.typescript.isIdentifier(name)) {
327
+ return name.text;
328
+ }
329
+ if (context.typescript.isStringLiteral(name)) {
330
+ return name.text;
331
+ }
332
+ return null;
333
+ }
334
+ /**
335
+ * Check if this call expression is calling a function created by tv()
336
+ * Uses TypeChecker for accurate origin tracking
337
+ * IMPORTANT: Returns false for utility functions
338
+ */
339
+ isTvCreatedFunctionCall(callExpression, context) {
340
+ // OPTIMIZATION: Early exit if no type checker available
341
+ if (!context.typeChecker) {
342
+ return false;
343
+ }
344
+ const expr = callExpression.expression;
345
+ // OPTIMIZATION: Only handle simple identifiers and property access
346
+ // This covers: button(...), variants.button(...), etc.
347
+ if (!context.typescript.isIdentifier(expr) &&
348
+ !context.typescript.isPropertyAccessExpression(expr)) {
349
+ return false;
350
+ }
351
+ // OPTIMIZATION: Check if this is a utility function (exclude from validation)
352
+ const functionName = context.typescript.isIdentifier(expr)
353
+ ? expr.text
354
+ : context.typescript.isPropertyAccessExpression(expr)
355
+ ? expr.name.text
356
+ : null;
357
+ if (functionName && context.utilityFunctions.includes(functionName)) {
358
+ // Debug: log when skipping utility function
359
+ // console.log(`[TV] Skipping utility function: ${functionName}`);
360
+ return false;
361
+ }
362
+ // Debug: log function being checked
363
+ // console.log(`[TV] Checking if ${functionName} is tv-created, utility functions:`, context.utilityFunctions);
364
+ // Get the symbol for the called function
365
+ const symbol = context.typeChecker.getSymbolAtLocation(expr);
366
+ if (!symbol) {
367
+ return false;
368
+ }
369
+ // OPTIMIZATION: Check cache first
370
+ if (this.tvVariableCache.has(symbol)) {
371
+ return this.tvVariableCache.get(symbol);
372
+ }
373
+ // Check if this symbol's declaration is assigned from a tv() call
374
+ const isTvCreated = this.isSymbolFromTvCall(symbol, context);
375
+ this.tvVariableCache.set(symbol, isTvCreated);
376
+ return isTvCreated;
377
+ }
378
+ /**
379
+ * Check if a symbol's declaration is from a tv() call
380
+ * Handles: const button = tv(...), export const button = tv(...), etc.
381
+ */
382
+ isSymbolFromTvCall(symbol, context) {
383
+ const declarations = symbol.getDeclarations();
384
+ if (!declarations || declarations.length === 0) {
385
+ return false;
386
+ }
387
+ // Check each declaration to see if it's assigned from tv()
388
+ for (const declaration of declarations) {
389
+ // Handle: const button = tv(...)
390
+ if (context.typescript.isVariableDeclaration(declaration)) {
391
+ const initializer = declaration.initializer;
392
+ if (initializer && context.typescript.isCallExpression(initializer)) {
393
+ if (this.isTvCall(initializer, context)) {
394
+ return true;
395
+ }
396
+ }
397
+ }
398
+ // Handle: export default tv(...) or similar patterns
399
+ else if (context.typescript.isExportAssignment(declaration)) {
400
+ const expr = declaration.expression;
401
+ if (context.typescript.isCallExpression(expr)) {
402
+ if (this.isTvCall(expr, context)) {
403
+ return true;
404
+ }
405
+ }
406
+ }
407
+ }
408
+ return false;
409
+ }
410
+ /**
411
+ * Extract class names from a tv() function call
412
+ * Example: button({ color: 'primary', class: 'bg-pink-500' })
413
+ */
414
+ extractFromTvFunctionCall(callExpression, context) {
415
+ // OPTIMIZATION: Early exit for empty arguments
416
+ if (callExpression.arguments.length === 0) {
417
+ return [];
418
+ }
419
+ const arg = callExpression.arguments[0];
420
+ // The argument should be an object literal with properties like { color: 'primary', class: '...' }
421
+ if (!context.typescript.isObjectLiteralExpression(arg)) {
422
+ return [];
423
+ }
424
+ const classNames = [];
425
+ // Look for 'class' or 'className' properties
426
+ for (const property of arg.properties) {
427
+ if (!context.typescript.isPropertyAssignment(property)) {
428
+ continue;
429
+ }
430
+ const propName = this.getPropertyName(property, context);
431
+ if (propName === 'class' || propName === 'className') {
432
+ // Extract classes from the value
433
+ classNames.push(...this.extractFromValue(property.initializer, context));
434
+ }
435
+ }
436
+ return classNames;
437
+ }
438
+ /**
439
+ * Clear the import cache (useful for testing or when files change)
440
+ */
441
+ clearCache() {
442
+ this.tvImportCache.clear();
443
+ this.tvVariableCache.clear();
444
+ }
445
+ }
446
+ exports.TailwindVariantsExtractor = TailwindVariantsExtractor;
447
+ //# sourceMappingURL=TailwindVariantsExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TailwindVariantsExtractor.js","sourceRoot":"","sources":["../../src/extractors/TailwindVariantsExtractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import * as ts from 'typescript/lib/tsserverlibrary';
2
+ import { ClassNameInfo, ExtractionContext } from '../core/types';
3
+ import { BaseExtractor } from './BaseExtractor';
4
+ /**
5
+ * Extracts class names from template expressions
6
+ * Example: `flex ${condition ? 'hidden' : 'block'}`
7
+ */
8
+ export declare class TemplateExpressionExtractor extends BaseExtractor {
9
+ private expressionExtractor;
10
+ constructor();
11
+ canHandle(node: ts.Node, context: ExtractionContext): boolean;
12
+ extract(node: ts.Node, context: ExtractionContext): ClassNameInfo[];
13
+ }
14
+ //# sourceMappingURL=TemplateExpressionExtractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateExpressionExtractor.d.ts","sourceRoot":"","sources":["../../src/extractors/TemplateExpressionExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;GAGG;AACH,qBAAa,2BAA4B,SAAQ,aAAa;IAC7D,OAAO,CAAC,mBAAmB,CAAsB;;IAOjD,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO;IAO7D,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,iBAAiB,GAAG,aAAa,EAAE;CAwDnE"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TemplateExpressionExtractor = void 0;
4
+ const BaseExtractor_1 = require("./BaseExtractor");
5
+ const ExpressionExtractor_1 = require("./ExpressionExtractor");
6
+ /**
7
+ * Extracts class names from template expressions
8
+ * Example: `flex ${condition ? 'hidden' : 'block'}`
9
+ */
10
+ class TemplateExpressionExtractor extends BaseExtractor_1.BaseExtractor {
11
+ constructor() {
12
+ super();
13
+ this.expressionExtractor = new ExpressionExtractor_1.ExpressionExtractor();
14
+ }
15
+ canHandle(node, context) {
16
+ return (context.typescript.isTemplateExpression(node) ||
17
+ context.typescript.isNoSubstitutionTemplateLiteral(node));
18
+ }
19
+ extract(node, context) {
20
+ const classNames = [];
21
+ // Handle no-substitution template literal: `flex items-center`
22
+ if (context.typescript.isNoSubstitutionTemplateLiteral(node)) {
23
+ return this.extractFromStringLiteral(node, context);
24
+ }
25
+ // Handle template expression with substitutions
26
+ if (context.typescript.isTemplateExpression(node)) {
27
+ const parts = [];
28
+ // Add the head (the part before the first ${})
29
+ parts.push({
30
+ text: node.head.text,
31
+ start: node.head.getStart() + 1
32
+ });
33
+ // Add each template span's literal part
34
+ node.templateSpans.forEach(span => {
35
+ // Extract from the interpolated expression
36
+ const expressionClasses = this.expressionExtractor.extractFromExpression(span.expression, context);
37
+ classNames.push(...expressionClasses);
38
+ // Add the literal part after the interpolation
39
+ parts.push({
40
+ text: span.literal.text,
41
+ start: span.literal.getStart() + 1
42
+ });
43
+ });
44
+ // Process each static part for class names
45
+ parts.forEach(part => {
46
+ let offset = 0;
47
+ const lineNumber = context.sourceFile.getLineAndCharacterOfPosition(part.start).line + 1;
48
+ part.text.split(' ').forEach(className => {
49
+ if (className) {
50
+ classNames.push({
51
+ className: className,
52
+ absoluteStart: part.start + offset,
53
+ length: className.length,
54
+ line: lineNumber,
55
+ file: context.sourceFile.fileName
56
+ });
57
+ }
58
+ offset += className.length + 1;
59
+ });
60
+ });
61
+ }
62
+ return classNames;
63
+ }
64
+ }
65
+ exports.TemplateExpressionExtractor = TemplateExpressionExtractor;
66
+ //# sourceMappingURL=TemplateExpressionExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateExpressionExtractor.js","sourceRoot":"","sources":["../../src/extractors/TemplateExpressionExtractor.ts"],"names":[],"mappings":";;;AAGA,mDAAgD;AAChD,+DAA4D;AAE5D;;;GAGG;AACH,MAAa,2BAA4B,SAAQ,6BAAa;IAG7D;QACC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,mBAAmB,GAAG,IAAI,yCAAmB,EAAE,CAAC;IACtD,CAAC;IAED,SAAS,CAAC,IAAa,EAAE,OAA0B;QAClD,OAAO,CACN,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,IAAI,CAAC;YAC7C,OAAO,CAAC,UAAU,CAAC,+BAA+B,CAAC,IAAI,CAAC,CACxD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAa,EAAE,OAA0B;QAChD,MAAM,UAAU,GAAoB,EAAE,CAAC;QAEvC,+DAA+D;QAC/D,IAAI,OAAO,CAAC,UAAU,CAAC,+BAA+B,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9D,OAAO,IAAI,CAAC,wBAAwB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;QAED,gDAAgD;QAChD,IAAI,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,KAAK,GAA2C,EAAE,CAAC;YAEzD,+CAA+C;YAC/C,KAAK,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;gBACpB,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;aAC/B,CAAC,CAAC;YAEH,wCAAwC;YACxC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBACjC,2CAA2C;gBAC3C,MAAM,iBAAiB,GAAG,IAAI,CAAC,mBAAmB,CAAC,qBAAqB,CACvE,IAAI,CAAC,UAAU,EACf,OAAO,CACP,CAAC;gBACF,UAAU,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,CAAC;gBAEtC,+CAA+C;gBAC/C,KAAK,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;oBACvB,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;iBAClC,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,2CAA2C;YAC3C,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBACpB,IAAI,MAAM,GAAG,CAAC,CAAC;gBACf,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;gBAEzF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;oBACxC,IAAI,SAAS,EAAE,CAAC;wBACf,UAAU,CAAC,IAAI,CAAC;4BACf,SAAS,EAAE,SAAS;4BACpB,aAAa,EAAE,IAAI,CAAC,KAAK,GAAG,MAAM;4BAClC,MAAM,EAAE,SAAS,CAAC,MAAM;4BACxB,IAAI,EAAE,UAAU;4BAChB,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ;yBACjC,CAAC,CAAC;oBACJ,CAAC;oBACD,MAAM,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,UAAU,CAAC;IACnB,CAAC;CACD;AAvED,kEAuEC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,65 @@
1
+ import * as ts from 'typescript/lib/tsserverlibrary';
2
+ import { TailwindTypescriptPlugin } from './plugin/TailwindTypescriptPlugin';
3
+ /**
4
+ * Main entry point for the TypeScript Language Service Plugin
5
+ *
6
+ * REFACTORED ARCHITECTURE:
7
+ *
8
+ * This plugin now follows Clean Architecture and SOLID principles:
9
+ *
10
+ * 1. Core Layer (src/core/):
11
+ * - types.ts: Domain types (ClassNameInfo, ExtractionContext, etc.)
12
+ * - interfaces.ts: Contracts (IClassNameExtractor, IClassNameValidator, etc.)
13
+ *
14
+ * 2. Extractors Layer (src/extractors/):
15
+ * - BaseExtractor: Abstract base with common functionality
16
+ * - StringLiteralExtractor: Handles string literals
17
+ * - TemplateExpressionExtractor: Handles template strings
18
+ * - ExpressionExtractor: Handles all expression types (ternary, binary, etc.)
19
+ * - JsxAttributeExtractor: Main orchestrator for JSX className attributes
20
+ *
21
+ * 3. Services Layer (src/services/):
22
+ * - ClassNameExtractionService: Orchestrates AST traversal and extraction
23
+ * - DiagnosticService: Creates TypeScript diagnostics
24
+ * - ValidationService: Validates classes and creates diagnostics
25
+ * - PluginConfigService: Manages plugin configuration
26
+ * - PerformanceCache: LRU cache for performance optimization
27
+ *
28
+ * 4. Plugin Layer (src/plugin/):
29
+ * - TailwindTypescriptPlugin: Thin adapter to TypeScript API
30
+ *
31
+ * 5. Infrastructure Layer:
32
+ * - TailwindValidator: Validates against Tailwind CSS design system
33
+ * - Logger: Logging abstraction
34
+ *
35
+ * SOLID PRINCIPLES APPLIED:
36
+ *
37
+ * - Single Responsibility: Each class has one clear purpose
38
+ * - Open/Closed: Easy to add new extractors without modifying existing code
39
+ * - Liskov Substitution: All extractors implement the same interface
40
+ * - Interface Segregation: Small, focused interfaces
41
+ * - Dependency Inversion: Depends on abstractions (IClassNameValidator, etc.)
42
+ *
43
+ * EXTENSIBILITY:
44
+ *
45
+ * To add a new extraction pattern:
46
+ * 1. Create a new extractor class extending BaseExtractor
47
+ * 2. Implement canHandle() and extract() methods
48
+ * 3. Add it to ClassNameExtractionService.extractors array
49
+ *
50
+ * To use the TypeScript type checker:
51
+ * The type checker is obtained fresh for each file validation from the current program.
52
+ * It's available in the ExtractionContext passed to extractors for type-based features.
53
+ *
54
+ * PERFORMANCE OPTIMIZATIONS:
55
+ *
56
+ * - LRU cache for validation results (2000 entries)
57
+ * - Lazy initialization of design system
58
+ * - Fresh type checker per-file (always accurate, no staleness)
59
+ * - Fast path for static class validation
60
+ */
61
+ declare const _default: (mod: {
62
+ typescript: typeof ts;
63
+ }) => TailwindTypescriptPlugin;
64
+ export = _default;
65
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAErD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;yBACO,KAAK;IAAE,UAAU,EAAE,OAAO,EAAE,CAAA;CAAE;AAAxC,kBAA0F"}
package/lib/index.js ADDED
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ const TailwindTypescriptPlugin_1 = require("./plugin/TailwindTypescriptPlugin");
3
+ module.exports = (mod) => new TailwindTypescriptPlugin_1.TailwindTypescriptPlugin(mod.typescript);
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,gFAA6E;AA4D7E,iBAAS,CAAC,GAA8B,EAAE,EAAE,CAAC,IAAI,mDAAwB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC"}