@homebound/truss 2.17.0 → 2.19.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.
@@ -1424,6 +1424,248 @@ import _generate2 from "@babel/generator";
1424
1424
  import * as t4 from "@babel/types";
1425
1425
  import { basename } from "path";
1426
1426
 
1427
+ // src/plugin/ast-utils.ts
1428
+ import * as t2 from "@babel/types";
1429
+ function collectTopLevelBindings(ast) {
1430
+ const used = /* @__PURE__ */ new Set();
1431
+ for (const node of ast.program.body) {
1432
+ if (t2.isImportDeclaration(node)) {
1433
+ for (const spec of node.specifiers) {
1434
+ used.add(spec.local.name);
1435
+ }
1436
+ continue;
1437
+ }
1438
+ if (t2.isVariableDeclaration(node)) {
1439
+ for (const decl of node.declarations) {
1440
+ collectPatternBindings(decl.id, used);
1441
+ }
1442
+ continue;
1443
+ }
1444
+ if (t2.isFunctionDeclaration(node) && node.id) {
1445
+ used.add(node.id.name);
1446
+ continue;
1447
+ }
1448
+ if (t2.isClassDeclaration(node) && node.id) {
1449
+ used.add(node.id.name);
1450
+ continue;
1451
+ }
1452
+ if (t2.isExportNamedDeclaration(node) && node.declaration) {
1453
+ const decl = node.declaration;
1454
+ if (t2.isVariableDeclaration(decl)) {
1455
+ for (const varDecl of decl.declarations) {
1456
+ collectPatternBindings(varDecl.id, used);
1457
+ }
1458
+ } else if ((t2.isFunctionDeclaration(decl) || t2.isClassDeclaration(decl)) && decl.id) {
1459
+ used.add(decl.id.name);
1460
+ }
1461
+ continue;
1462
+ }
1463
+ if (t2.isExportDefaultDeclaration(node)) {
1464
+ const decl = node.declaration;
1465
+ if ((t2.isFunctionDeclaration(decl) || t2.isClassDeclaration(decl)) && decl.id) {
1466
+ used.add(decl.id.name);
1467
+ }
1468
+ }
1469
+ }
1470
+ return used;
1471
+ }
1472
+ function collectPatternBindings(pattern, used) {
1473
+ if (t2.isVoidPattern(pattern)) {
1474
+ return;
1475
+ }
1476
+ if (t2.isIdentifier(pattern)) {
1477
+ used.add(pattern.name);
1478
+ return;
1479
+ }
1480
+ if (t2.isAssignmentPattern(pattern)) {
1481
+ collectPatternBindings(pattern.left, used);
1482
+ return;
1483
+ }
1484
+ if (t2.isRestElement(pattern)) {
1485
+ collectPatternBindings(pattern.argument, used);
1486
+ return;
1487
+ }
1488
+ if (t2.isObjectPattern(pattern)) {
1489
+ for (const prop of pattern.properties) {
1490
+ if (t2.isObjectProperty(prop)) {
1491
+ collectPatternBindings(prop.value, used);
1492
+ } else if (t2.isRestElement(prop)) {
1493
+ collectPatternBindings(prop.argument, used);
1494
+ }
1495
+ }
1496
+ return;
1497
+ }
1498
+ if (t2.isArrayPattern(pattern)) {
1499
+ for (const el of pattern.elements) {
1500
+ if (!el) continue;
1501
+ if (t2.isIdentifier(el) || t2.isAssignmentPattern(el) || t2.isObjectPattern(el) || t2.isArrayPattern(el)) {
1502
+ collectPatternBindings(el, used);
1503
+ } else if (t2.isRestElement(el)) {
1504
+ collectPatternBindings(el.argument, used);
1505
+ }
1506
+ }
1507
+ }
1508
+ }
1509
+ function reservePreferredName(used, preferred, secondary) {
1510
+ if (!used.has(preferred)) {
1511
+ used.add(preferred);
1512
+ return preferred;
1513
+ }
1514
+ if (secondary && !used.has(secondary)) {
1515
+ used.add(secondary);
1516
+ return secondary;
1517
+ }
1518
+ const base = secondary ?? preferred;
1519
+ let i = 1;
1520
+ let candidate = `${base}_${i}`;
1521
+ while (used.has(candidate)) {
1522
+ i++;
1523
+ candidate = `${base}_${i}`;
1524
+ }
1525
+ used.add(candidate);
1526
+ return candidate;
1527
+ }
1528
+ function findCssImportBinding(ast) {
1529
+ for (const node of ast.program.body) {
1530
+ if (!t2.isImportDeclaration(node)) continue;
1531
+ for (const spec of node.specifiers) {
1532
+ if (t2.isImportSpecifier(spec) && t2.isIdentifier(spec.imported, { name: "Css" })) {
1533
+ return spec.local.name;
1534
+ }
1535
+ }
1536
+ }
1537
+ return null;
1538
+ }
1539
+ function findCssBuilderBinding(ast) {
1540
+ for (const node of ast.program.body) {
1541
+ if (!t2.isVariableDeclaration(node)) continue;
1542
+ for (const decl of node.declarations) {
1543
+ if (t2.isIdentifier(decl.id) && decl.init && t2.isNewExpression(decl.init) && t2.isIdentifier(decl.init.callee, { name: "CssBuilder" })) {
1544
+ return decl.id.name;
1545
+ }
1546
+ }
1547
+ }
1548
+ return null;
1549
+ }
1550
+ function removeCssImport(ast, cssBinding) {
1551
+ for (let i = 0; i < ast.program.body.length; i++) {
1552
+ const node = ast.program.body[i];
1553
+ if (!t2.isImportDeclaration(node)) continue;
1554
+ const cssSpecIndex = node.specifiers.findIndex((s) => t2.isImportSpecifier(s) && s.local.name === cssBinding);
1555
+ if (cssSpecIndex === -1) continue;
1556
+ if (node.specifiers.length === 1) {
1557
+ ast.program.body.splice(i, 1);
1558
+ } else {
1559
+ node.specifiers.splice(cssSpecIndex, 1);
1560
+ }
1561
+ return;
1562
+ }
1563
+ }
1564
+ function findLastImportIndex(ast) {
1565
+ let lastImportIndex = -1;
1566
+ for (let i = 0; i < ast.program.body.length; i++) {
1567
+ if (t2.isImportDeclaration(ast.program.body[i])) {
1568
+ lastImportIndex = i;
1569
+ }
1570
+ }
1571
+ return lastImportIndex;
1572
+ }
1573
+ function findNamedImportBinding(ast, source, importedName) {
1574
+ for (const node of ast.program.body) {
1575
+ if (!t2.isImportDeclaration(node) || node.source.value !== source) continue;
1576
+ for (const spec of node.specifiers) {
1577
+ if (t2.isImportSpecifier(spec) && t2.isIdentifier(spec.imported, { name: importedName })) {
1578
+ return spec.local.name;
1579
+ }
1580
+ }
1581
+ }
1582
+ return null;
1583
+ }
1584
+ function findImportDeclaration(ast, source) {
1585
+ for (const node of ast.program.body) {
1586
+ if (t2.isImportDeclaration(node) && node.source.value === source) {
1587
+ return node;
1588
+ }
1589
+ }
1590
+ return null;
1591
+ }
1592
+ function replaceCssImportWithNamedImports(ast, cssBinding, source, imports) {
1593
+ for (const node of ast.program.body) {
1594
+ if (!t2.isImportDeclaration(node)) continue;
1595
+ const cssSpecIndex = node.specifiers.findIndex((spec) => {
1596
+ return t2.isImportSpecifier(spec) && spec.local.name === cssBinding;
1597
+ });
1598
+ if (cssSpecIndex === -1 || node.specifiers.length !== 1) continue;
1599
+ node.source = t2.stringLiteral(source);
1600
+ node.specifiers = imports.map((entry) => {
1601
+ return t2.importSpecifier(t2.identifier(entry.localName), t2.identifier(entry.importedName));
1602
+ });
1603
+ return true;
1604
+ }
1605
+ return false;
1606
+ }
1607
+ function upsertNamedImports(ast, source, imports) {
1608
+ if (imports.length === 0) return;
1609
+ for (const node of ast.program.body) {
1610
+ if (!t2.isImportDeclaration(node) || node.source.value !== source) continue;
1611
+ for (const entry of imports) {
1612
+ const exists = node.specifiers.some((spec) => {
1613
+ return t2.isImportSpecifier(spec) && t2.isIdentifier(spec.imported, { name: entry.importedName });
1614
+ });
1615
+ if (exists) continue;
1616
+ node.specifiers.push(t2.importSpecifier(t2.identifier(entry.localName), t2.identifier(entry.importedName)));
1617
+ }
1618
+ return;
1619
+ }
1620
+ const importDecl = t2.importDeclaration(
1621
+ imports.map((entry) => {
1622
+ return t2.importSpecifier(t2.identifier(entry.localName), t2.identifier(entry.importedName));
1623
+ }),
1624
+ t2.stringLiteral(source)
1625
+ );
1626
+ const idx = findLastImportIndex(ast);
1627
+ ast.program.body.splice(idx + 1, 0, importDecl);
1628
+ }
1629
+ function extractChain(node, cssBinding) {
1630
+ const chain = [];
1631
+ let current = node;
1632
+ while (true) {
1633
+ if (t2.isIdentifier(current, { name: cssBinding })) {
1634
+ chain.reverse();
1635
+ return chain;
1636
+ }
1637
+ if (t2.isMemberExpression(current) && !current.computed && t2.isIdentifier(current.property)) {
1638
+ const name = current.property.name;
1639
+ if (name === "else") {
1640
+ chain.push({ type: "else" });
1641
+ } else {
1642
+ chain.push({ type: "getter", name });
1643
+ }
1644
+ current = current.object;
1645
+ continue;
1646
+ }
1647
+ if (t2.isCallExpression(current) && t2.isMemberExpression(current.callee) && !current.callee.computed && t2.isIdentifier(current.callee.property)) {
1648
+ const name = current.callee.property.name;
1649
+ if (name === "if") {
1650
+ chain.push({
1651
+ type: "if",
1652
+ conditionNode: current.arguments[0]
1653
+ });
1654
+ current = current.callee.object;
1655
+ continue;
1656
+ }
1657
+ chain.push({
1658
+ type: "call",
1659
+ name,
1660
+ args: current.arguments
1661
+ });
1662
+ current = current.callee.object;
1663
+ continue;
1664
+ }
1665
+ return null;
1666
+ }
1667
+ }
1668
+
1427
1669
  // src/plugin/resolve-chain.ts
1428
1670
  function emptyConditionContext() {
1429
1671
  return {
@@ -1441,6 +1683,12 @@ function cloneConditionContext(context) {
1441
1683
  whenPseudo: context.whenPseudo ? { ...context.whenPseudo } : null
1442
1684
  };
1443
1685
  }
1686
+ function resetConditionContext(context) {
1687
+ context.mediaQuery = null;
1688
+ context.pseudoClass = null;
1689
+ context.pseudoElement = null;
1690
+ context.whenPseudo = null;
1691
+ }
1444
1692
  function segmentWithConditionContext(segment, context) {
1445
1693
  return {
1446
1694
  ...segment,
@@ -1456,6 +1704,10 @@ function applyModifierNodeToConditionContext(context, node, mapping) {
1456
1704
  return;
1457
1705
  }
1458
1706
  if (node.type === "getter") {
1707
+ if (node.name === "end") {
1708
+ resetConditionContext(context);
1709
+ return;
1710
+ }
1459
1711
  if (isPseudoMethod(node.name)) {
1460
1712
  context.pseudoClass = pseudoSelector(node.name);
1461
1713
  return;
@@ -1497,9 +1749,10 @@ function applyModifierNodeToConditionContext(context, node, mapping) {
1497
1749
  context.pseudoClass = pseudoSelector(node.name);
1498
1750
  }
1499
1751
  }
1500
- function resolveFullChain(chain, mapping) {
1752
+ function resolveFullChain(chain, mapping, cssBindingName, initialContext = emptyConditionContext()) {
1501
1753
  const parts = [];
1502
1754
  const markers = [];
1755
+ const nestedErrors = [];
1503
1756
  const filteredChain = [];
1504
1757
  const scanErrors = [];
1505
1758
  for (let j = 0; j < chain.length; j++) {
@@ -1518,15 +1771,15 @@ function resolveFullChain(chain, mapping) {
1518
1771
  }
1519
1772
  let i = 0;
1520
1773
  let currentNodes = [];
1521
- let currentContext = emptyConditionContext();
1522
- let currentNodesStartContext = emptyConditionContext();
1774
+ let currentContext = cloneConditionContext(initialContext);
1775
+ let currentNodesStartContext = cloneConditionContext(initialContext);
1523
1776
  function flushCurrentNodes() {
1524
1777
  if (currentNodes.length === 0) {
1525
1778
  return;
1526
1779
  }
1527
1780
  parts.push({
1528
1781
  type: "unconditional",
1529
- segments: resolveChain(currentNodes, mapping, currentNodesStartContext)
1782
+ segments: resolveChain(currentNodes, mapping, currentNodesStartContext, cssBindingName)
1530
1783
  });
1531
1784
  currentNodes = [];
1532
1785
  currentNodesStartContext = cloneConditionContext(currentContext);
@@ -1548,13 +1801,22 @@ function resolveFullChain(chain, mapping) {
1548
1801
  const branchContext = cloneConditionContext(currentContext);
1549
1802
  const thenNodes = mediaStart.thenNodes ? [...mediaStart.thenNodes, ...filteredChain.slice(i + 1, elseIndex)] : filteredChain.slice(i, elseIndex);
1550
1803
  const elseNodes = [makeMediaQueryNode(mediaStart.inverseMediaQuery), ...filteredChain.slice(elseIndex + 1)];
1551
- const thenSegs = resolveChain(thenNodes, mapping, branchContext);
1552
- const elseSegs = resolveChain(elseNodes, mapping, branchContext);
1804
+ const thenSegs = resolveChain(thenNodes, mapping, branchContext, cssBindingName);
1805
+ const elseSegs = resolveChain(elseNodes, mapping, branchContext, cssBindingName);
1553
1806
  parts.push({ type: "unconditional", segments: [...thenSegs, ...elseSegs] });
1554
1807
  i = filteredChain.length;
1555
1808
  break;
1556
1809
  }
1557
1810
  }
1811
+ if (isWhenObjectCall(node)) {
1812
+ flushCurrentNodes();
1813
+ const resolved = resolveWhenObjectSelectors(node, mapping, cssBindingName, currentContext);
1814
+ parts.push(...resolved.parts);
1815
+ markers.push(...resolved.markers);
1816
+ nestedErrors.push(...resolved.errors);
1817
+ i++;
1818
+ continue;
1819
+ }
1558
1820
  if (node.type === "if") {
1559
1821
  if (node.conditionNode.type === "StringLiteral") {
1560
1822
  const mediaQuery = node.conditionNode.value;
@@ -1584,8 +1846,8 @@ function resolveFullChain(chain, mapping) {
1584
1846
  }
1585
1847
  i++;
1586
1848
  }
1587
- const thenSegs = resolveChain(thenNodes, mapping, branchContext);
1588
- const elseSegs = resolveChain(elseNodes, mapping, branchContext);
1849
+ const thenSegs = resolveChain(thenNodes, mapping, branchContext, cssBindingName);
1850
+ const elseSegs = resolveChain(elseNodes, mapping, branchContext, cssBindingName);
1589
1851
  parts.push({
1590
1852
  type: "conditional",
1591
1853
  conditionNode: node.conditionNode,
@@ -1607,17 +1869,83 @@ function resolveFullChain(chain, mapping) {
1607
1869
  }
1608
1870
  }
1609
1871
  }
1610
- return { parts, markers, errors: [...scanErrors, ...segmentErrors] };
1872
+ return { parts, markers, errors: [.../* @__PURE__ */ new Set([...scanErrors, ...nestedErrors, ...segmentErrors])] };
1611
1873
  }
1612
- function getMediaConditionalStartNode(node, mapping) {
1613
- if (node.type === "if" && node.conditionNode.type === "StringLiteral") {
1874
+ function isWhenObjectCall(node) {
1875
+ return node.type === "call" && node.name === "when" && node.args.length === 1 && node.args[0].type === "ObjectExpression";
1876
+ }
1877
+ function resolveWhenObjectSelectors(node, mapping, cssBindingName, initialContext) {
1878
+ if (!cssBindingName) {
1614
1879
  return {
1615
- inverseMediaQuery: invertMediaQuery(node.conditionNode.value),
1616
- thenNodes: [makeMediaQueryNode(node.conditionNode.value)]
1880
+ parts: [],
1881
+ markers: [],
1882
+ errors: [new UnsupportedPatternError(`when({ ... }) requires a resolvable Css binding`).message]
1617
1883
  };
1618
1884
  }
1619
- if (node.type === "getter" && mapping.breakpoints && node.name in mapping.breakpoints) {
1620
- return { inverseMediaQuery: invertMediaQuery(mapping.breakpoints[node.name]) };
1885
+ const objectArg = node.args[0];
1886
+ if (objectArg.type !== "ObjectExpression") {
1887
+ throw new UnsupportedPatternError(`when({ ... }) requires an object literal argument`);
1888
+ }
1889
+ const parts = [];
1890
+ const markers = [];
1891
+ const errors = [];
1892
+ for (const property of objectArg.properties) {
1893
+ try {
1894
+ if (property.type === "SpreadElement") {
1895
+ throw new UnsupportedPatternError(`when({ ... }) does not support spread properties`);
1896
+ }
1897
+ if (property.type !== "ObjectProperty") {
1898
+ throw new UnsupportedPatternError(`when({ ... }) only supports plain object properties`);
1899
+ }
1900
+ if (property.computed || property.key.type !== "StringLiteral") {
1901
+ throw new UnsupportedPatternError(`when({ ... }) selector keys must be string literals`);
1902
+ }
1903
+ const value = unwrapExpression(property.value);
1904
+ if (value.type !== "MemberExpression" || value.computed || value.property.type !== "Identifier" || value.property.name !== "$") {
1905
+ throw new UnsupportedPatternError(`when({ ... }) values must be Css.*.$ expressions`);
1906
+ }
1907
+ const innerChain = extractChain(value.object, cssBindingName);
1908
+ if (!innerChain) {
1909
+ throw new UnsupportedPatternError(`when({ ... }) values must be Css.*.$ expressions`);
1910
+ }
1911
+ const selectorContext = cloneConditionContext(initialContext);
1912
+ selectorContext.pseudoClass = property.key.value;
1913
+ const resolved = resolveFullChain(innerChain, mapping, cssBindingName, selectorContext);
1914
+ parts.push(...resolved.parts);
1915
+ markers.push(...resolved.markers);
1916
+ errors.push(...resolved.errors);
1917
+ } catch (err) {
1918
+ if (err instanceof UnsupportedPatternError) {
1919
+ errors.push(err.message);
1920
+ } else {
1921
+ throw err;
1922
+ }
1923
+ }
1924
+ }
1925
+ return { parts, markers, errors: [...new Set(errors)] };
1926
+ }
1927
+ function flattenWhenObjectParts(resolved) {
1928
+ const segments = [];
1929
+ for (const part of resolved.parts) {
1930
+ if (part.type !== "unconditional") {
1931
+ throw new UnsupportedPatternError(`when({ ... }) values cannot use if()/else in this context`);
1932
+ }
1933
+ segments.push(...part.segments);
1934
+ }
1935
+ for (const err of resolved.errors) {
1936
+ segments.push({ abbr: "__error", defs: {}, error: err });
1937
+ }
1938
+ return segments;
1939
+ }
1940
+ function getMediaConditionalStartNode(node, mapping) {
1941
+ if (node.type === "if" && node.conditionNode.type === "StringLiteral") {
1942
+ return {
1943
+ inverseMediaQuery: invertMediaQuery(node.conditionNode.value),
1944
+ thenNodes: [makeMediaQueryNode(node.conditionNode.value)]
1945
+ };
1946
+ }
1947
+ if (node.type === "getter" && mapping.breakpoints && node.name in mapping.breakpoints) {
1948
+ return { inverseMediaQuery: invertMediaQuery(mapping.breakpoints[node.name]) };
1621
1949
  }
1622
1950
  return null;
1623
1951
  }
@@ -1656,7 +1984,7 @@ function invertMediaQuery(query) {
1656
1984
  }
1657
1985
  return query.replace("@media", "@media not");
1658
1986
  }
1659
- function resolveChain(chain, mapping, initialContext = emptyConditionContext()) {
1987
+ function resolveChain(chain, mapping, initialContext = emptyConditionContext(), cssBindingName) {
1660
1988
  const segments = [];
1661
1989
  const context = cloneConditionContext(initialContext);
1662
1990
  for (const node of chain) {
@@ -1667,6 +1995,10 @@ function resolveChain(chain, mapping, initialContext = emptyConditionContext())
1667
1995
  }
1668
1996
  if (node.type === "getter") {
1669
1997
  const abbr = node.name;
1998
+ if (abbr === "end") {
1999
+ resetConditionContext(context);
2000
+ continue;
2001
+ }
1670
2002
  if (isPseudoMethod(abbr)) {
1671
2003
  context.pseudoClass = pseudoSelector(abbr);
1672
2004
  continue;
@@ -1751,6 +2083,11 @@ function resolveChain(chain, mapping, initialContext = emptyConditionContext())
1751
2083
  continue;
1752
2084
  }
1753
2085
  if (abbr === "when") {
2086
+ if (isWhenObjectCall(node)) {
2087
+ const resolved2 = resolveWhenObjectSelectors(node, mapping, cssBindingName, context);
2088
+ segments.push(...flattenWhenObjectParts(resolved2));
2089
+ continue;
2090
+ }
1754
2091
  const resolved = resolveWhenCall(node);
1755
2092
  if (resolved.kind === "selector") {
1756
2093
  context.pseudoClass = resolved.pseudo;
@@ -2120,399 +2457,167 @@ function resolveWhenCall(node) {
2120
2457
  if (relationshipArg.type !== "StringLiteral") {
2121
2458
  throw new UnsupportedPatternError(`when() relationship argument must be a string literal`);
2122
2459
  }
2123
- const relationship = relationshipArg.value;
2124
- if (!WHEN_RELATIONSHIPS.has(relationship)) {
2125
- throw new UnsupportedPatternError(
2126
- `when() relationship must be one of: ${[...WHEN_RELATIONSHIPS].join(", ")} -- got "${relationship}"`
2127
- );
2128
- }
2129
- const pseudoArg = node.args[2];
2130
- if (pseudoArg.type !== "StringLiteral") {
2131
- throw new UnsupportedPatternError(`when() pseudo selector (3rd argument) must be a string literal`);
2132
- }
2133
- return { kind: "relationship", pseudo: pseudoArg.value, markerNode, relationship };
2134
- }
2135
- function resolveWhenMarker(node) {
2136
- if (isDefaultMarkerNode(node)) {
2137
- return void 0;
2138
- }
2139
- if (node.type === "Identifier") {
2140
- return node;
2141
- }
2142
- throw new UnsupportedPatternError(`when() marker must be a marker variable or marker`);
2143
- }
2144
- function isDefaultMarkerNode(node) {
2145
- if (node.type === "Identifier" && (node.name === "marker" || node.name === "defaultMarker")) {
2146
- return true;
2147
- }
2148
- return isLegacyDefaultMarkerExpression(node);
2149
- }
2150
- function isLegacyDefaultMarkerExpression(node) {
2151
- return node.type === "CallExpression" && node.arguments.length === 0 && node.callee.type === "MemberExpression" && !node.callee.computed && node.callee.property.type === "Identifier" && node.callee.property.name === "defaultMarker";
2152
- }
2153
- var PSEUDO_METHODS = {
2154
- onHover: ":hover",
2155
- onFocus: ":focus",
2156
- onFocusVisible: ":focus-visible",
2157
- onFocusWithin: ":focus-within",
2158
- onActive: ":active",
2159
- onDisabled: ":disabled",
2160
- ifFirstOfType: ":first-of-type",
2161
- ifLastOfType: ":last-of-type"
2162
- };
2163
- function isPseudoMethod(name) {
2164
- return name in PSEUDO_METHODS;
2165
- }
2166
- function pseudoSelector(name) {
2167
- return PSEUDO_METHODS[name];
2168
- }
2169
- function tryEvaluateLiteral(node, incremented, increment) {
2170
- if (node.type === "NumericLiteral") {
2171
- if (incremented) {
2172
- return `${node.value * increment}px`;
2173
- }
2174
- return String(node.value);
2175
- }
2176
- if (node.type === "StringLiteral") {
2177
- return node.value;
2178
- }
2179
- if (node.type === "UnaryExpression" && node.operator === "-" && node.argument.type === "NumericLiteral") {
2180
- const val = -node.argument.value;
2181
- if (incremented) {
2182
- return `${val * increment}px`;
2183
- }
2184
- return String(val);
2185
- }
2186
- return null;
2187
- }
2188
- function tryEvaluatePxLiteral(node) {
2189
- if (node.type === "NumericLiteral") {
2190
- return `${node.value}px`;
2191
- }
2192
- return null;
2193
- }
2194
- function containerSelectorFromCall(node) {
2195
- if (node.args.length !== 1) {
2196
- throw new UnsupportedPatternError(`ifContainer() expects exactly 1 argument, got ${node.args.length}`);
2197
- }
2198
- const arg = node.args[0];
2199
- if (!arg || arg.type !== "ObjectExpression") {
2200
- throw new UnsupportedPatternError("ifContainer() expects an object literal argument");
2201
- }
2202
- let lt;
2203
- let gt;
2204
- let name;
2205
- for (const prop of arg.properties) {
2206
- if (prop.type === "SpreadElement") {
2207
- throw new UnsupportedPatternError("ifContainer() does not support spread properties");
2208
- }
2209
- if (prop.type !== "ObjectProperty" || prop.computed) {
2210
- throw new UnsupportedPatternError("ifContainer() expects plain object properties");
2211
- }
2212
- const key = objectPropertyName(prop.key);
2213
- if (!key) {
2214
- throw new UnsupportedPatternError("ifContainer() only supports identifier/string keys");
2215
- }
2216
- const valueNode = prop.value;
2217
- if (key === "lt") {
2218
- lt = numericLiteralValue(valueNode, "ifContainer().lt must be a numeric literal");
2219
- continue;
2220
- }
2221
- if (key === "gt") {
2222
- gt = numericLiteralValue(valueNode, "ifContainer().gt must be a numeric literal");
2223
- continue;
2224
- }
2225
- if (key === "name") {
2226
- name = stringLiteralValue(valueNode, "ifContainer().name must be a string literal");
2227
- continue;
2228
- }
2229
- throw new UnsupportedPatternError(`ifContainer() does not support property "${key}"`);
2230
- }
2231
- if (lt === void 0 && gt === void 0) {
2232
- throw new UnsupportedPatternError('ifContainer() requires at least one of "lt" or "gt"');
2233
- }
2234
- const parts = [];
2235
- if (gt !== void 0) {
2236
- parts.push(`(min-width: ${gt + 1}px)`);
2237
- }
2238
- if (lt !== void 0) {
2239
- parts.push(`(max-width: ${lt}px)`);
2240
- }
2241
- const query = parts.join(" and ");
2242
- const namePrefix = name ? `${name} ` : "";
2243
- return `@container ${namePrefix}${query}`;
2244
- }
2245
- function objectPropertyName(node) {
2246
- if (node.type === "Identifier") return node.name;
2247
- if (node.type === "StringLiteral") return node.value;
2248
- return null;
2249
- }
2250
- function numericLiteralValue(node, errorMessage) {
2251
- if (node.type === "NumericLiteral") {
2252
- return node.value;
2253
- }
2254
- if (node.type === "UnaryExpression" && node.operator === "-" && node.argument.type === "NumericLiteral") {
2255
- return -node.argument.value;
2256
- }
2257
- throw new UnsupportedPatternError(errorMessage);
2258
- }
2259
- function stringLiteralValue(node, errorMessage) {
2260
- if (node.type === "StringLiteral") {
2261
- return node.value;
2262
- }
2263
- if (node.type === "TemplateLiteral" && node.expressions.length === 0 && node.quasis.length === 1) {
2264
- return node.quasis[0].value.cooked ?? "";
2265
- }
2266
- throw new UnsupportedPatternError(errorMessage);
2267
- }
2268
- var UnsupportedPatternError = class extends Error {
2269
- constructor(message) {
2270
- super(`[truss] Unsupported pattern: ${message}`);
2271
- this.name = "UnsupportedPatternError";
2272
- }
2273
- };
2274
-
2275
- // src/plugin/ast-utils.ts
2276
- import * as t2 from "@babel/types";
2277
- function collectTopLevelBindings(ast) {
2278
- const used = /* @__PURE__ */ new Set();
2279
- for (const node of ast.program.body) {
2280
- if (t2.isImportDeclaration(node)) {
2281
- for (const spec of node.specifiers) {
2282
- used.add(spec.local.name);
2283
- }
2284
- continue;
2285
- }
2286
- if (t2.isVariableDeclaration(node)) {
2287
- for (const decl of node.declarations) {
2288
- collectPatternBindings(decl.id, used);
2289
- }
2290
- continue;
2291
- }
2292
- if (t2.isFunctionDeclaration(node) && node.id) {
2293
- used.add(node.id.name);
2294
- continue;
2295
- }
2296
- if (t2.isClassDeclaration(node) && node.id) {
2297
- used.add(node.id.name);
2298
- continue;
2299
- }
2300
- if (t2.isExportNamedDeclaration(node) && node.declaration) {
2301
- const decl = node.declaration;
2302
- if (t2.isVariableDeclaration(decl)) {
2303
- for (const varDecl of decl.declarations) {
2304
- collectPatternBindings(varDecl.id, used);
2305
- }
2306
- } else if ((t2.isFunctionDeclaration(decl) || t2.isClassDeclaration(decl)) && decl.id) {
2307
- used.add(decl.id.name);
2308
- }
2309
- continue;
2310
- }
2311
- if (t2.isExportDefaultDeclaration(node)) {
2312
- const decl = node.declaration;
2313
- if ((t2.isFunctionDeclaration(decl) || t2.isClassDeclaration(decl)) && decl.id) {
2314
- used.add(decl.id.name);
2315
- }
2316
- }
2317
- }
2318
- return used;
2319
- }
2320
- function collectPatternBindings(pattern, used) {
2321
- if (t2.isVoidPattern(pattern)) {
2322
- return;
2323
- }
2324
- if (t2.isIdentifier(pattern)) {
2325
- used.add(pattern.name);
2326
- return;
2327
- }
2328
- if (t2.isAssignmentPattern(pattern)) {
2329
- collectPatternBindings(pattern.left, used);
2330
- return;
2331
- }
2332
- if (t2.isRestElement(pattern)) {
2333
- collectPatternBindings(pattern.argument, used);
2334
- return;
2335
- }
2336
- if (t2.isObjectPattern(pattern)) {
2337
- for (const prop of pattern.properties) {
2338
- if (t2.isObjectProperty(prop)) {
2339
- collectPatternBindings(prop.value, used);
2340
- } else if (t2.isRestElement(prop)) {
2341
- collectPatternBindings(prop.argument, used);
2342
- }
2343
- }
2344
- return;
2345
- }
2346
- if (t2.isArrayPattern(pattern)) {
2347
- for (const el of pattern.elements) {
2348
- if (!el) continue;
2349
- if (t2.isIdentifier(el) || t2.isAssignmentPattern(el) || t2.isObjectPattern(el) || t2.isArrayPattern(el)) {
2350
- collectPatternBindings(el, used);
2351
- } else if (t2.isRestElement(el)) {
2352
- collectPatternBindings(el.argument, used);
2353
- }
2354
- }
2355
- }
2356
- }
2357
- function reservePreferredName(used, preferred, secondary) {
2358
- if (!used.has(preferred)) {
2359
- used.add(preferred);
2360
- return preferred;
2361
- }
2362
- if (secondary && !used.has(secondary)) {
2363
- used.add(secondary);
2364
- return secondary;
2365
- }
2366
- const base = secondary ?? preferred;
2367
- let i = 1;
2368
- let candidate = `${base}_${i}`;
2369
- while (used.has(candidate)) {
2370
- i++;
2371
- candidate = `${base}_${i}`;
2372
- }
2373
- used.add(candidate);
2374
- return candidate;
2375
- }
2376
- function findCssImportBinding(ast) {
2377
- for (const node of ast.program.body) {
2378
- if (!t2.isImportDeclaration(node)) continue;
2379
- for (const spec of node.specifiers) {
2380
- if (t2.isImportSpecifier(spec) && t2.isIdentifier(spec.imported, { name: "Css" })) {
2381
- return spec.local.name;
2382
- }
2383
- }
2460
+ const relationship = relationshipArg.value;
2461
+ if (!WHEN_RELATIONSHIPS.has(relationship)) {
2462
+ throw new UnsupportedPatternError(
2463
+ `when() relationship must be one of: ${[...WHEN_RELATIONSHIPS].join(", ")} -- got "${relationship}"`
2464
+ );
2384
2465
  }
2385
- return null;
2466
+ const pseudoArg = node.args[2];
2467
+ if (pseudoArg.type !== "StringLiteral") {
2468
+ throw new UnsupportedPatternError(`when() pseudo selector (3rd argument) must be a string literal`);
2469
+ }
2470
+ return { kind: "relationship", pseudo: pseudoArg.value, markerNode, relationship };
2386
2471
  }
2387
- function findCssBuilderBinding(ast) {
2388
- for (const node of ast.program.body) {
2389
- if (!t2.isVariableDeclaration(node)) continue;
2390
- for (const decl of node.declarations) {
2391
- if (t2.isIdentifier(decl.id) && decl.init && t2.isNewExpression(decl.init) && t2.isIdentifier(decl.init.callee, { name: "CssBuilder" })) {
2392
- return decl.id.name;
2393
- }
2394
- }
2472
+ function resolveWhenMarker(node) {
2473
+ if (isDefaultMarkerNode(node)) {
2474
+ return void 0;
2395
2475
  }
2396
- return null;
2476
+ if (node.type === "Identifier") {
2477
+ return node;
2478
+ }
2479
+ throw new UnsupportedPatternError(`when() marker must be a marker variable or marker`);
2397
2480
  }
2398
- function removeCssImport(ast, cssBinding) {
2399
- for (let i = 0; i < ast.program.body.length; i++) {
2400
- const node = ast.program.body[i];
2401
- if (!t2.isImportDeclaration(node)) continue;
2402
- const cssSpecIndex = node.specifiers.findIndex((s) => t2.isImportSpecifier(s) && s.local.name === cssBinding);
2403
- if (cssSpecIndex === -1) continue;
2404
- if (node.specifiers.length === 1) {
2405
- ast.program.body.splice(i, 1);
2406
- } else {
2407
- node.specifiers.splice(cssSpecIndex, 1);
2408
- }
2409
- return;
2481
+ function isDefaultMarkerNode(node) {
2482
+ if (node.type === "Identifier" && (node.name === "marker" || node.name === "defaultMarker")) {
2483
+ return true;
2410
2484
  }
2485
+ return isLegacyDefaultMarkerExpression(node);
2411
2486
  }
2412
- function findLastImportIndex(ast) {
2413
- let lastImportIndex = -1;
2414
- for (let i = 0; i < ast.program.body.length; i++) {
2415
- if (t2.isImportDeclaration(ast.program.body[i])) {
2416
- lastImportIndex = i;
2487
+ function isLegacyDefaultMarkerExpression(node) {
2488
+ return node.type === "CallExpression" && node.arguments.length === 0 && node.callee.type === "MemberExpression" && !node.callee.computed && node.callee.property.type === "Identifier" && node.callee.property.name === "defaultMarker";
2489
+ }
2490
+ var PSEUDO_METHODS = {
2491
+ onHover: ":hover",
2492
+ onFocus: ":focus",
2493
+ onFocusVisible: ":focus-visible",
2494
+ onFocusWithin: ":focus-within",
2495
+ onActive: ":active",
2496
+ onDisabled: ":disabled",
2497
+ ifFirstOfType: ":first-of-type",
2498
+ ifLastOfType: ":last-of-type"
2499
+ };
2500
+ function isPseudoMethod(name) {
2501
+ return name in PSEUDO_METHODS;
2502
+ }
2503
+ function pseudoSelector(name) {
2504
+ return PSEUDO_METHODS[name];
2505
+ }
2506
+ function tryEvaluateLiteral(node, incremented, increment) {
2507
+ if (node.type === "NumericLiteral") {
2508
+ if (incremented) {
2509
+ return `${node.value * increment}px`;
2417
2510
  }
2511
+ return String(node.value);
2418
2512
  }
2419
- return lastImportIndex;
2420
- }
2421
- function findNamedImportBinding(ast, source, importedName) {
2422
- for (const node of ast.program.body) {
2423
- if (!t2.isImportDeclaration(node) || node.source.value !== source) continue;
2424
- for (const spec of node.specifiers) {
2425
- if (t2.isImportSpecifier(spec) && t2.isIdentifier(spec.imported, { name: importedName })) {
2426
- return spec.local.name;
2427
- }
2513
+ if (node.type === "StringLiteral") {
2514
+ return node.value;
2515
+ }
2516
+ if (node.type === "UnaryExpression" && node.operator === "-" && node.argument.type === "NumericLiteral") {
2517
+ const val = -node.argument.value;
2518
+ if (incremented) {
2519
+ return `${val * increment}px`;
2428
2520
  }
2521
+ return String(val);
2429
2522
  }
2430
2523
  return null;
2431
2524
  }
2432
- function findImportDeclaration(ast, source) {
2433
- for (const node of ast.program.body) {
2434
- if (t2.isImportDeclaration(node) && node.source.value === source) {
2435
- return node;
2436
- }
2525
+ function tryEvaluatePxLiteral(node) {
2526
+ if (node.type === "NumericLiteral") {
2527
+ return `${node.value}px`;
2437
2528
  }
2438
2529
  return null;
2439
2530
  }
2440
- function replaceCssImportWithNamedImports(ast, cssBinding, source, imports) {
2441
- for (const node of ast.program.body) {
2442
- if (!t2.isImportDeclaration(node)) continue;
2443
- const cssSpecIndex = node.specifiers.findIndex((spec) => {
2444
- return t2.isImportSpecifier(spec) && spec.local.name === cssBinding;
2445
- });
2446
- if (cssSpecIndex === -1 || node.specifiers.length !== 1) continue;
2447
- node.source = t2.stringLiteral(source);
2448
- node.specifiers = imports.map((entry) => {
2449
- return t2.importSpecifier(t2.identifier(entry.localName), t2.identifier(entry.importedName));
2450
- });
2451
- return true;
2531
+ function containerSelectorFromCall(node) {
2532
+ if (node.args.length !== 1) {
2533
+ throw new UnsupportedPatternError(`ifContainer() expects exactly 1 argument, got ${node.args.length}`);
2452
2534
  }
2453
- return false;
2454
- }
2455
- function upsertNamedImports(ast, source, imports) {
2456
- if (imports.length === 0) return;
2457
- for (const node of ast.program.body) {
2458
- if (!t2.isImportDeclaration(node) || node.source.value !== source) continue;
2459
- for (const entry of imports) {
2460
- const exists = node.specifiers.some((spec) => {
2461
- return t2.isImportSpecifier(spec) && t2.isIdentifier(spec.imported, { name: entry.importedName });
2462
- });
2463
- if (exists) continue;
2464
- node.specifiers.push(t2.importSpecifier(t2.identifier(entry.localName), t2.identifier(entry.importedName)));
2535
+ const arg = node.args[0];
2536
+ if (!arg || arg.type !== "ObjectExpression") {
2537
+ throw new UnsupportedPatternError("ifContainer() expects an object literal argument");
2538
+ }
2539
+ let lt;
2540
+ let gt;
2541
+ let name;
2542
+ for (const prop of arg.properties) {
2543
+ if (prop.type === "SpreadElement") {
2544
+ throw new UnsupportedPatternError("ifContainer() does not support spread properties");
2465
2545
  }
2466
- return;
2546
+ if (prop.type !== "ObjectProperty" || prop.computed) {
2547
+ throw new UnsupportedPatternError("ifContainer() expects plain object properties");
2548
+ }
2549
+ const key = objectPropertyName(prop.key);
2550
+ if (!key) {
2551
+ throw new UnsupportedPatternError("ifContainer() only supports identifier/string keys");
2552
+ }
2553
+ const valueNode = prop.value;
2554
+ if (key === "lt") {
2555
+ lt = numericLiteralValue(valueNode, "ifContainer().lt must be a numeric literal");
2556
+ continue;
2557
+ }
2558
+ if (key === "gt") {
2559
+ gt = numericLiteralValue(valueNode, "ifContainer().gt must be a numeric literal");
2560
+ continue;
2561
+ }
2562
+ if (key === "name") {
2563
+ name = stringLiteralValue(valueNode, "ifContainer().name must be a string literal");
2564
+ continue;
2565
+ }
2566
+ throw new UnsupportedPatternError(`ifContainer() does not support property "${key}"`);
2467
2567
  }
2468
- const importDecl = t2.importDeclaration(
2469
- imports.map((entry) => {
2470
- return t2.importSpecifier(t2.identifier(entry.localName), t2.identifier(entry.importedName));
2471
- }),
2472
- t2.stringLiteral(source)
2473
- );
2474
- const idx = findLastImportIndex(ast);
2475
- ast.program.body.splice(idx + 1, 0, importDecl);
2568
+ if (lt === void 0 && gt === void 0) {
2569
+ throw new UnsupportedPatternError('ifContainer() requires at least one of "lt" or "gt"');
2570
+ }
2571
+ const parts = [];
2572
+ if (gt !== void 0) {
2573
+ parts.push(`(min-width: ${gt + 1}px)`);
2574
+ }
2575
+ if (lt !== void 0) {
2576
+ parts.push(`(max-width: ${lt}px)`);
2577
+ }
2578
+ const query = parts.join(" and ");
2579
+ const namePrefix = name ? `${name} ` : "";
2580
+ return `@container ${namePrefix}${query}`;
2476
2581
  }
2477
- function extractChain(node, cssBinding) {
2478
- const chain = [];
2582
+ function objectPropertyName(node) {
2583
+ if (node.type === "Identifier") return node.name;
2584
+ if (node.type === "StringLiteral") return node.value;
2585
+ return null;
2586
+ }
2587
+ function unwrapExpression(node) {
2479
2588
  let current = node;
2480
2589
  while (true) {
2481
- if (t2.isIdentifier(current, { name: cssBinding })) {
2482
- chain.reverse();
2483
- return chain;
2484
- }
2485
- if (t2.isMemberExpression(current) && !current.computed && t2.isIdentifier(current.property)) {
2486
- const name = current.property.name;
2487
- if (name === "else") {
2488
- chain.push({ type: "else" });
2489
- } else {
2490
- chain.push({ type: "getter", name });
2491
- }
2492
- current = current.object;
2493
- continue;
2494
- }
2495
- if (t2.isCallExpression(current) && t2.isMemberExpression(current.callee) && !current.callee.computed && t2.isIdentifier(current.callee.property)) {
2496
- const name = current.callee.property.name;
2497
- if (name === "if") {
2498
- chain.push({
2499
- type: "if",
2500
- conditionNode: current.arguments[0]
2501
- });
2502
- current = current.callee.object;
2503
- continue;
2504
- }
2505
- chain.push({
2506
- type: "call",
2507
- name,
2508
- args: current.arguments
2509
- });
2510
- current = current.callee.object;
2590
+ if (current.type === "ParenthesizedExpression" || current.type === "TSAsExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression" || current.type === "TSSatisfiesExpression") {
2591
+ current = current.expression;
2511
2592
  continue;
2512
2593
  }
2513
- return null;
2594
+ return current;
2595
+ }
2596
+ }
2597
+ function numericLiteralValue(node, errorMessage) {
2598
+ if (node.type === "NumericLiteral") {
2599
+ return node.value;
2600
+ }
2601
+ if (node.type === "UnaryExpression" && node.operator === "-" && node.argument.type === "NumericLiteral") {
2602
+ return -node.argument.value;
2603
+ }
2604
+ throw new UnsupportedPatternError(errorMessage);
2605
+ }
2606
+ function stringLiteralValue(node, errorMessage) {
2607
+ if (node.type === "StringLiteral") {
2608
+ return node.value;
2609
+ }
2610
+ if (node.type === "TemplateLiteral" && node.expressions.length === 0 && node.quasis.length === 1) {
2611
+ return node.quasis[0].value.cooked ?? "";
2514
2612
  }
2613
+ throw new UnsupportedPatternError(errorMessage);
2515
2614
  }
2615
+ var UnsupportedPatternError = class extends Error {
2616
+ constructor(message) {
2617
+ super(`[truss] Unsupported pattern: ${message}`);
2618
+ this.name = "UnsupportedPatternError";
2619
+ }
2620
+ };
2516
2621
 
2517
2622
  // src/plugin/rewrite-sites.ts
2518
2623
  import _traverse from "@babel/traverse";
@@ -2552,6 +2657,20 @@ function getCssAttributePath(path) {
2552
2657
  function buildStyleHashFromChain(chain, options) {
2553
2658
  const members = [];
2554
2659
  const previousProperties = /* @__PURE__ */ new Map();
2660
+ const pendingUnconditionalSegments = [];
2661
+ function flushPendingUnconditionalSegments() {
2662
+ if (pendingUnconditionalSegments.length === 0) {
2663
+ return;
2664
+ }
2665
+ const partMembers = buildStyleHashMembers(pendingUnconditionalSegments, options);
2666
+ members.push(...partMembers);
2667
+ for (const member of partMembers) {
2668
+ if (t3.isObjectProperty(member)) {
2669
+ previousProperties.set(propertyName(member.key), member);
2670
+ }
2671
+ }
2672
+ pendingUnconditionalSegments.length = 0;
2673
+ }
2555
2674
  if (chain.markers.length > 0) {
2556
2675
  const markerClasses = chain.markers.map((marker) => {
2557
2676
  return markerClassName(marker.markerNode);
@@ -2560,14 +2679,9 @@ function buildStyleHashFromChain(chain, options) {
2560
2679
  }
2561
2680
  for (const part of chain.parts) {
2562
2681
  if (part.type === "unconditional") {
2563
- const partMembers = buildStyleHashMembers(part.segments, options);
2564
- members.push(...partMembers);
2565
- for (const member of partMembers) {
2566
- if (t3.isObjectProperty(member)) {
2567
- previousProperties.set(propertyName(member.key), member);
2568
- }
2569
- }
2682
+ pendingUnconditionalSegments.push(...part.segments);
2570
2683
  } else {
2684
+ flushPendingUnconditionalSegments();
2571
2685
  const thenMembers = mergeConditionalBranchMembers(
2572
2686
  buildStyleHashMembers(part.thenSegments, options),
2573
2687
  previousProperties,
@@ -2585,6 +2699,7 @@ function buildStyleHashFromChain(chain, options) {
2585
2699
  );
2586
2700
  }
2587
2701
  }
2702
+ flushPendingUnconditionalSegments();
2588
2703
  return t3.objectExpression(members);
2589
2704
  }
2590
2705
  function buildStyleHashMembers(segments, options) {
@@ -2976,11 +3091,14 @@ function transformTruss(code, filename, mapping, options = {}) {
2976
3091
  hasRuntimeStyleCssUsage = true;
2977
3092
  return;
2978
3093
  }
3094
+ if (isInsideWhenObjectValue(path, cssBindingName)) {
3095
+ return;
3096
+ }
2979
3097
  const parentPath = path.parentPath;
2980
3098
  if (parentPath && parentPath.isMemberExpression() && t4.isIdentifier(parentPath.node.property, { name: "$" })) {
2981
3099
  return;
2982
3100
  }
2983
- const resolvedChain = resolveFullChain(chain, mapping);
3101
+ const resolvedChain = resolveFullChain(chain, mapping, cssBindingName);
2984
3102
  sites.push({ path, resolvedChain });
2985
3103
  const line = path.node.loc?.start.line ?? null;
2986
3104
  for (const err of resolvedChain.errors) {
@@ -3124,6 +3242,19 @@ function isRuntimeStyleCssAttribute2(path) {
3124
3242
  if (!openingElementPath || !openingElementPath.isJSXOpeningElement()) return false;
3125
3243
  return t4.isJSXIdentifier(openingElementPath.node.name, { name: "RuntimeStyle" });
3126
3244
  }
3245
+ function isInsideWhenObjectValue(path, cssBindingName) {
3246
+ let current = path.parentPath;
3247
+ while (current) {
3248
+ if (current.isObjectExpression()) {
3249
+ const parent = current.parentPath;
3250
+ if (parent?.isCallExpression() && parent.node.arguments[0] === current.node && t4.isMemberExpression(parent.node.callee) && !parent.node.callee.computed && t4.isIdentifier(parent.node.callee.property, { name: "when" }) && extractChain(parent.node.callee.object, cssBindingName)) {
3251
+ return true;
3252
+ }
3253
+ }
3254
+ current = current.parentPath;
3255
+ }
3256
+ return false;
3257
+ }
3127
3258
  function collectRuntimeLookups(chains) {
3128
3259
  const lookups = /* @__PURE__ */ new Map();
3129
3260
  for (const chain of chains) {
@@ -3331,7 +3462,7 @@ function resolveCssExpression(node, cssBindingName, mapping, filename) {
3331
3462
  if (n.type === "if") return { error: "if() conditionals are not supported in .css.ts files" };
3332
3463
  if (n.type === "else") return { error: "else is not supported in .css.ts files" };
3333
3464
  }
3334
- const resolved = resolveFullChain(chain, mapping);
3465
+ const resolved = resolveFullChain(chain, mapping, cssBindingName);
3335
3466
  if (resolved.errors.length > 0) {
3336
3467
  return { error: resolved.errors[0] };
3337
3468
  }