• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

antebudimir / eslint-plugin-vanilla-extract / 15881936212

25 Jun 2025 04:31PM UTC coverage: 91.396% (-7.9%) from 99.254%
15881936212

Pull #4

github

web-flow
Merge 1e0afd84e into 35875fbb3
Pull Request #4: Add Wrapper Function Support with Reference Tracking

503 of 534 branches covered (94.19%)

Branch coverage included in aggregate %.

416 of 604 new or added lines in 6 files covered. (68.87%)

18 existing lines in 4 files now uncovered.

2057 of 2267 relevant lines covered (90.74%)

545.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.98
/src/css-rules/shared-utils/reference-based-visitor-creator.ts
1
import type { Rule } from 'eslint';
1✔
NEW
2
import { TSESTree } from '@typescript-eslint/utils';
×
NEW
3
import { enforceAlphabeticalCSSOrderInRecipe } from '../alphabetical-order/recipe-order-enforcer.js';
×
NEW
4
import { enforceAlphabeticalCSSOrderInStyleObject } from '../alphabetical-order/style-object-processor.js';
×
NEW
5
import { enforceConcentricCSSOrderInRecipe } from '../concentric-order/recipe-order-enforcer.js';
×
NEW
6
import { enforceConcentricCSSOrderInStyleObject } from '../concentric-order/style-object-processor.js';
×
NEW
7
import { enforceUserDefinedGroupOrderInRecipe } from '../custom-order/recipe-order-enforcer.js';
×
NEW
8
import { enforceUserDefinedGroupOrderInStyleObject } from '../custom-order/style-object-processor.js';
×
NEW
9
import { enforceFontFaceOrder } from './font-face-property-order-enforcer.js';
×
NEW
10
import { ReferenceTracker, createReferenceTrackingVisitor } from './reference-tracker.js';
×
NEW
11
import { processStyleNode } from './style-node-processor.js';
×
12
import type { SortRemainingProperties } from '../concentric-order/types.js';
13
import type { OrderingStrategy } from '../types.js';
14

15
/**
16
 * Creates an ESLint rule listener with visitors for style-related function calls using reference tracking.
17
 * This automatically detects vanilla-extract functions based on their import statements.
18
 *
19
 * @param ruleContext The ESLint rule context.
20
 * @param orderingStrategy The strategy to use for ordering CSS properties.
21
 * @param userDefinedGroupOrder An optional array of property groups for the 'userDefinedGroupOrder' strategy.
22
 * @param sortRemainingProperties An optional strategy for sorting properties not in user-defined groups.
23
 * @returns An object with visitor functions for the ESLint rule.
24
 */
NEW
25
export const createReferenceBasedNodeVisitors = (
×
NEW
26
  ruleContext: Rule.RuleContext,
×
NEW
27
  orderingStrategy: OrderingStrategy,
×
NEW
28
  userDefinedGroupOrder?: string[],
×
NEW
29
  sortRemainingProperties?: SortRemainingProperties,
×
NEW
30
): Rule.RuleListener => {
×
NEW
31
  const tracker = new ReferenceTracker();
×
NEW
32
  const trackingVisitor = createReferenceTrackingVisitor(tracker);
×
33

34
  // Select the appropriate property processing function based on the ordering strategy
NEW
35
  const processProperty = (() => {
×
NEW
36
    switch (orderingStrategy) {
×
NEW
37
      case 'alphabetical':
×
NEW
38
        return enforceAlphabeticalCSSOrderInStyleObject;
×
NEW
39
      case 'concentric':
×
NEW
40
        return enforceConcentricCSSOrderInStyleObject;
×
NEW
41
      case 'userDefinedGroupOrder':
×
NEW
42
        if (!userDefinedGroupOrder || userDefinedGroupOrder.length === 0) {
×
NEW
43
          return enforceAlphabeticalCSSOrderInStyleObject;
×
NEW
44
        }
×
NEW
45
        return (ruleContext: Rule.RuleContext, node: TSESTree.ObjectExpression) =>
×
NEW
46
          enforceUserDefinedGroupOrderInStyleObject(ruleContext, node, userDefinedGroupOrder, sortRemainingProperties);
×
NEW
47
      default:
×
NEW
48
        return enforceAlphabeticalCSSOrderInStyleObject;
×
NEW
49
    }
×
NEW
50
  })();
×
51

NEW
52
  return {
×
53
    // Include the reference tracking visitors
NEW
54
    ...trackingVisitor,
×
55

NEW
56
    CallExpression(callExpression) {
×
NEW
57
      if (callExpression.callee.type !== 'Identifier') {
×
NEW
58
        return;
×
NEW
59
      }
×
60

NEW
61
      const functionName = callExpression.callee.name;
×
62

63
      // Check if this function is tracked as a vanilla-extract function
NEW
64
      if (!tracker.isTrackedFunction(functionName)) {
×
NEW
65
        return;
×
NEW
66
      }
×
67

NEW
68
      const originalName = tracker.getOriginalName(functionName);
×
NEW
69
      if (!originalName) {
×
NEW
70
        return;
×
NEW
71
      }
×
72

73
      // Handle different function types based on their original imported name
NEW
74
      switch (originalName) {
×
NEW
75
        case 'fontFace':
×
NEW
76
          if (callExpression.arguments.length > 0) {
×
NEW
77
            const styleArguments = callExpression.arguments[0];
×
NEW
78
            enforceFontFaceOrder(ruleContext, styleArguments as TSESTree.ObjectExpression);
×
NEW
79
          }
×
NEW
80
          break;
×
81

NEW
82
        case 'globalFontFace':
×
NEW
83
          if (callExpression.arguments.length > 1) {
×
NEW
84
            const styleArguments = callExpression.arguments[1];
×
NEW
85
            enforceFontFaceOrder(ruleContext, styleArguments as TSESTree.ObjectExpression);
×
NEW
86
          }
×
NEW
87
          break;
×
88

NEW
89
        case 'style':
×
NEW
90
        case 'styleVariants':
×
NEW
91
        case 'keyframes':
×
NEW
92
          if (callExpression.arguments.length > 0) {
×
NEW
93
            const styleArguments = callExpression.arguments[0];
×
NEW
94
            processStyleNode(ruleContext, styleArguments as TSESTree.Node, processProperty);
×
NEW
95
          }
×
NEW
96
          break;
×
97

NEW
98
        case 'globalStyle':
×
NEW
99
        case 'globalKeyframes':
×
NEW
100
          if (callExpression.arguments.length > 1) {
×
NEW
101
            const styleArguments = callExpression.arguments[1];
×
NEW
102
            processStyleNode(ruleContext, styleArguments as TSESTree.Node, processProperty);
×
NEW
103
          }
×
NEW
104
          break;
×
105

NEW
106
        case 'recipe':
×
NEW
107
          switch (orderingStrategy) {
×
NEW
108
            case 'alphabetical':
×
NEW
109
              enforceAlphabeticalCSSOrderInRecipe(callExpression as TSESTree.CallExpression, ruleContext);
×
NEW
110
              break;
×
NEW
111
            case 'concentric':
×
NEW
112
              enforceConcentricCSSOrderInRecipe(ruleContext, callExpression as TSESTree.CallExpression);
×
NEW
113
              break;
×
NEW
114
            case 'userDefinedGroupOrder':
×
NEW
115
              if (userDefinedGroupOrder) {
×
NEW
116
                enforceUserDefinedGroupOrderInRecipe(
×
NEW
117
                  ruleContext,
×
NEW
118
                  callExpression as TSESTree.CallExpression,
×
NEW
119
                  userDefinedGroupOrder,
×
NEW
120
                  sortRemainingProperties,
×
NEW
121
                );
×
NEW
122
              }
×
NEW
123
              break;
×
NEW
124
          }
×
NEW
125
          break;
×
NEW
126
      }
×
NEW
127
    },
×
NEW
128
  };
×
NEW
129
};
×
130

131
/**
132
 * Backwards-compatible alias that maintains the original API.
133
 * Uses reference tracking internally for automatic detection of vanilla-extract functions.
134
 */
NEW
135
export const createNodeVisitors = createReferenceBasedNodeVisitors;
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc