@usefragments/core 1.10.1 → 1.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usefragments/core",
3
- "version": "1.10.1",
3
+ "version": "1.10.2",
4
4
  "license": "MIT",
5
5
  "description": "Core types, schemas, and runtime API for Fragments component definitions",
6
6
  "author": "Conan McNicholl",
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
 
3
3
  import { normalizeTokenGroupComment } from "./categories.js";
4
- import { parseScssTokens } from "./scss.js";
4
+ import { parseScssTokens, parseScssVariables } from "./scss.js";
5
5
 
6
6
  /**
7
7
  * FRICTION #7d — stop prose SCSS comments from being slugified into token
@@ -92,3 +92,34 @@ describe("parseScssTokens category derivation (#7d)", () => {
92
92
  expect(out.categories.colors?.some((t) => t.name === "--fui-color-accent")).toBe(true);
93
93
  });
94
94
  });
95
+
96
+ describe("parseScssVariables", () => {
97
+ it("retains multiline generated adapter expressions as one variable value", () => {
98
+ const variables = parseScssVariables(`
99
+ $fui-font-weight-normal: map.get(
100
+ measurements.$legacy,
101
+ "typography",
102
+ "fontWeight",
103
+ "normal"
104
+ ) !default;
105
+ `);
106
+
107
+ expect(variables.get("$fui-font-weight-normal")).toBe(
108
+ 'map.get( measurements.$legacy, "typography", "fontWeight", "normal" )'
109
+ );
110
+ });
111
+
112
+ it("keeps Sass maps available for resolution without emitting the map container as a token", () => {
113
+ const scss = `
114
+ $spacing: (
115
+ xs: 4px,
116
+ sm: 8px,
117
+ );
118
+ `;
119
+
120
+ expect(parseScssVariables(scss).get("$spacing")).toBe("( xs: 4px, sm: 8px, )");
121
+
122
+ const tokens = Object.values(parseScssTokens(scss).categories).flat();
123
+ expect(tokens.map((token) => token.name)).not.toContain("$spacing");
124
+ });
125
+ });
@@ -27,12 +27,15 @@ export function detectTokenPrefix(names: string[]): string {
27
27
 
28
28
  export function parseScssVariables(content: string): Map<string, string> {
29
29
  const vars = new Map<string, string>();
30
- const scssVarRegex = /^\s*(\$[\w-]+)\s*:\s*(.+?)\s*(?:!default\s*)?;/gm;
30
+ const scssVarRegex = /^\s*(\$[\w-]+)\s*:\s*([\s\S]*?)\s*(?:!default\s*)?;/gm;
31
31
 
32
32
  let match: RegExpExecArray | null;
33
33
  while ((match = scssVarRegex.exec(content)) !== null) {
34
34
  const name = match[1];
35
- const value = match[2].replace(/\s*\/\/.*$/, "").trim();
35
+ const value = match[2]
36
+ .replace(/\s*\/\/[^\n]*$/gm, "")
37
+ .replace(/\s+/g, " ")
38
+ .trim();
36
39
  if (!vars.has(name)) {
37
40
  vars.set(name, value);
38
41
  }
@@ -45,7 +48,7 @@ export function resolveTokenValue(
45
48
  rawValue: string,
46
49
  scssVars: Map<string, string>,
47
50
  cssVarValues: Map<string, string>,
48
- depth = 0,
51
+ depth = 0
49
52
  ): string {
50
53
  if (depth > 5) return rawValue;
51
54
 
@@ -60,9 +63,7 @@ export function resolveTokenValue(
60
63
 
61
64
  resolved = resolved.replace(/(?<![#\{])(\$[\w-]+)/g, (_, varName) => {
62
65
  const val = scssVars.get(varName);
63
- return val !== undefined
64
- ? resolveTokenValue(val, scssVars, cssVarValues, depth + 1)
65
- : varName;
66
+ return val !== undefined ? resolveTokenValue(val, scssVars, cssVarValues, depth + 1) : varName;
66
67
  });
67
68
 
68
69
  resolved = resolved.replace(
@@ -76,7 +77,7 @@ export function resolveTokenValue(
76
77
  return resolveTokenValue(fallback.trim(), scssVars, cssVarValues, depth + 1);
77
78
  }
78
79
  return original;
79
- },
80
+ }
80
81
  );
81
82
 
82
83
  return resolved;
@@ -134,6 +135,10 @@ export function parseScssTokens(content: string, filePath = "tokens.scss"): Toke
134
135
 
135
136
  for (const [name, value] of scssVars) {
136
137
  if (seenNames.has(name)) continue;
138
+ // Parenthesized Sass maps are containers, not addressable token values.
139
+ // Keep them in `scssVars` for reference resolution, but let the dedicated
140
+ // map-entry parser expose their individual members.
141
+ if (value.startsWith("(")) continue;
137
142
  seenNames.add(name);
138
143
  tokens.push({
139
144
  name,