@bridge-ds/core 0.7.0 → 0.9.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.
- package/dist/audit/index.d.ts +1 -0
- package/dist/audit/index.js +269 -23
- package/dist/audit/index.js.map +1 -1
- package/dist/audit/missing-pieces.d.ts +43 -0
- package/dist/component-spec-BzfBkYRD.js +1122 -0
- package/dist/component-spec-BzfBkYRD.js.map +1 -0
- package/dist/docs-proposal.d.ts +73 -1
- package/dist/explorations-github.d.ts +2 -0
- package/dist/github-client.d.ts +9 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1744 -1418
- package/dist/index.js.map +1 -1
- package/dist/node/index.js +5 -3
- package/dist/node/index.js.map +1 -1
- package/dist/{component-spec-1z2ih4E3.js → pr-composer-D2SZm7cg.js} +826 -1443
- package/dist/pr-composer-D2SZm7cg.js.map +1 -0
- package/dist/prod-branch-D5Tl87Wf.js +266 -0
- package/dist/prod-branch-D5Tl87Wf.js.map +1 -0
- package/dist/prod-branch-github.d.ts +139 -0
- package/dist/prod-branch.d.ts +257 -0
- package/dist/products.d.ts +9 -0
- package/dist/{report-iPSnsjYi.js → report-DY_peRy4.js} +24 -24
- package/dist/{report-iPSnsjYi.js.map → report-DY_peRy4.js.map} +1 -1
- package/dist/token-proposal.d.ts +72 -0
- package/package.json +1 -1
- package/dist/component-spec-1z2ih4E3.js.map +0 -1
- package/dist/layered-BnbmToGs.js +0 -500
- package/dist/layered-BnbmToGs.js.map +0 -1
package/dist/layered-BnbmToGs.js
DELETED
|
@@ -1,500 +0,0 @@
|
|
|
1
|
-
const ALIAS_RE = /^\{([^{}]+)\}$/;
|
|
2
|
-
const isAlias = (v) => typeof v === "string" && ALIAS_RE.test(v);
|
|
3
|
-
const aliasTarget = (v) => ALIAS_RE.exec(v)?.[1] ?? v;
|
|
4
|
-
const toAlias = (path) => `{${path}}`;
|
|
5
|
-
function collectRefs(value, out = []) {
|
|
6
|
-
if (isAlias(value)) out.push(aliasTarget(value));
|
|
7
|
-
else if (Array.isArray(value)) value.forEach((v) => collectRefs(v, out));
|
|
8
|
-
else if (value && typeof value === "object") Object.values(value).forEach((v) => collectRefs(v, out));
|
|
9
|
-
return out;
|
|
10
|
-
}
|
|
11
|
-
const clamp01 = (n) => Math.min(1, Math.max(0, n));
|
|
12
|
-
const round = (n, digits) => {
|
|
13
|
-
const f = 10 ** digits;
|
|
14
|
-
return Math.round(n * f) / f;
|
|
15
|
-
};
|
|
16
|
-
function hexToRgba(hex) {
|
|
17
|
-
const m = /^#?([0-9a-f]{3,8})$/i.exec(hex.trim());
|
|
18
|
-
if (!m) return void 0;
|
|
19
|
-
let h = m[1];
|
|
20
|
-
if (h.length === 3 || h.length === 4) h = [...h].map((c) => c + c).join("");
|
|
21
|
-
if (h.length !== 6 && h.length !== 8) return void 0;
|
|
22
|
-
const n = (idx) => parseInt(h.slice(idx, idx + 2), 16) / 255;
|
|
23
|
-
return { r: n(0), g: n(2), b: n(4), a: h.length === 8 ? n(6) : 1 };
|
|
24
|
-
}
|
|
25
|
-
const to255 = (n) => Math.round(clamp01(n) * 255);
|
|
26
|
-
const rgbaToHex = (c) => "#" + [c.r, c.g, c.b].map((x) => to255(x).toString(16).padStart(2, "0")).join("");
|
|
27
|
-
function parseColor(value) {
|
|
28
|
-
if (typeof value === "string") return isAlias(value) ? void 0 : hexToRgba(value);
|
|
29
|
-
if (!value || typeof value !== "object") return void 0;
|
|
30
|
-
const v = value;
|
|
31
|
-
const alpha = typeof v.alpha === "number" ? v.alpha : 1;
|
|
32
|
-
if (v.colorSpace === "srgb" && Array.isArray(v.components) && v.components.length === 3) {
|
|
33
|
-
const [r, g, b] = v.components;
|
|
34
|
-
if ([r, g, b].every((x) => typeof x === "number")) return { r, g, b, a: alpha };
|
|
35
|
-
}
|
|
36
|
-
if (typeof v.hex === "string") {
|
|
37
|
-
const c = hexToRgba(v.hex);
|
|
38
|
-
if (c) return { ...c, a: alpha };
|
|
39
|
-
}
|
|
40
|
-
return void 0;
|
|
41
|
-
}
|
|
42
|
-
function rgbaToDtcg(c) {
|
|
43
|
-
const out = {
|
|
44
|
-
colorSpace: "srgb",
|
|
45
|
-
components: [round(clamp01(c.r), 3), round(clamp01(c.g), 3), round(clamp01(c.b), 3)]
|
|
46
|
-
};
|
|
47
|
-
if (c.a < 0.9995) out.alpha = round(clamp01(c.a), 3);
|
|
48
|
-
out.hex = rgbaToHex(c);
|
|
49
|
-
return out;
|
|
50
|
-
}
|
|
51
|
-
function colorsEqual(a, b) {
|
|
52
|
-
return rgbaToHex(a) === rgbaToHex(b) && Math.abs(a.a - b.a) < 2e-3;
|
|
53
|
-
}
|
|
54
|
-
function parseDimension(value) {
|
|
55
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
56
|
-
const v = value;
|
|
57
|
-
if (typeof v.value === "number" && typeof v.unit === "string") return { value: v.value, unit: v.unit };
|
|
58
|
-
}
|
|
59
|
-
if (typeof value === "string") {
|
|
60
|
-
const m = /^(-?\d+(?:\.\d+)?)(px|rem)$/.exec(value.trim());
|
|
61
|
-
if (m) return { value: Number(m[1]), unit: m[2] };
|
|
62
|
-
}
|
|
63
|
-
if (typeof value === "number") return { value, unit: "px" };
|
|
64
|
-
return void 0;
|
|
65
|
-
}
|
|
66
|
-
const numbersEqual = (a, b) => Math.abs(a - b) < 1e-4;
|
|
67
|
-
function deepEqual(a, b) {
|
|
68
|
-
if (a === b) return true;
|
|
69
|
-
if (typeof a === "number" && typeof b === "number") return numbersEqual(a, b);
|
|
70
|
-
if (typeof a !== typeof b || !a || !b || typeof a !== "object") return false;
|
|
71
|
-
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
72
|
-
if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((v, idx) => deepEqual(v, b[idx]));
|
|
73
|
-
const ka = Object.keys(a).filter((k) => a[k] !== void 0);
|
|
74
|
-
const kb = Object.keys(b).filter((k) => b[k] !== void 0);
|
|
75
|
-
if (ka.length !== kb.length) return false;
|
|
76
|
-
return ka.every((k) => deepEqual(a[k], b[k]));
|
|
77
|
-
}
|
|
78
|
-
function valuesEqual(type, a, b) {
|
|
79
|
-
if (a === void 0 || b === void 0) return a === b;
|
|
80
|
-
if (isAlias(a) || isAlias(b)) return isAlias(a) && isAlias(b) && aliasTarget(a) === aliasTarget(b);
|
|
81
|
-
if (type === "color") {
|
|
82
|
-
const ca = parseColor(a);
|
|
83
|
-
const cb = parseColor(b);
|
|
84
|
-
if (ca && cb) return colorsEqual(ca, cb);
|
|
85
|
-
}
|
|
86
|
-
if (type === "dimension") {
|
|
87
|
-
const da = parseDimension(a);
|
|
88
|
-
const db = parseDimension(b);
|
|
89
|
-
if (da && db) return da.unit === db.unit && numbersEqual(da.value, db.value);
|
|
90
|
-
}
|
|
91
|
-
return deepEqual(a, b);
|
|
92
|
-
}
|
|
93
|
-
function formatValue(type, value) {
|
|
94
|
-
if (value === void 0) return "none";
|
|
95
|
-
if (isAlias(value)) return aliasTarget(value);
|
|
96
|
-
if (type === "color") {
|
|
97
|
-
const c = parseColor(value);
|
|
98
|
-
const hex = value && typeof value === "object" && typeof value.hex === "string" ? value.hex.toLowerCase() : void 0;
|
|
99
|
-
if (c) return c.a < 0.9995 ? `${hex ?? rgbaToHex(c)} @ ${Math.round(c.a * 100)}%` : hex ?? rgbaToHex(c);
|
|
100
|
-
}
|
|
101
|
-
if (type === "dimension") {
|
|
102
|
-
const d = parseDimension(value);
|
|
103
|
-
if (d) return `${d.value}${d.unit}`;
|
|
104
|
-
}
|
|
105
|
-
if (Array.isArray(value)) return value.join(", ");
|
|
106
|
-
if (typeof value === "object" && value) return JSON.stringify(value);
|
|
107
|
-
return String(value);
|
|
108
|
-
}
|
|
109
|
-
const DTCG_TYPES = /* @__PURE__ */ new Set(["color", "dimension", "fontFamily", "fontWeight", "duration", "cubicBezier", "number", "strokeStyle", "border", "transition", "shadow", "gradient", "typography", "fontStyle", "string", "boolean"]);
|
|
110
|
-
const aliasOf = (v) => isAlias(v) ? aliasTarget(v) : null;
|
|
111
|
-
function globToRegExp(glob) {
|
|
112
|
-
let re = "";
|
|
113
|
-
for (let i = 0; i < glob.length; i++) {
|
|
114
|
-
const c = glob[i];
|
|
115
|
-
if (c === "*" && glob[i + 1] === "*") {
|
|
116
|
-
if (glob[i + 2] === "/") {
|
|
117
|
-
re += "(?:.*/)?";
|
|
118
|
-
i += 2;
|
|
119
|
-
} else {
|
|
120
|
-
re += ".*";
|
|
121
|
-
i += 1;
|
|
122
|
-
}
|
|
123
|
-
} else if (c === "*") re += "[^/]*";
|
|
124
|
-
else if (c === "?") re += "[^/]";
|
|
125
|
-
else re += c.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
126
|
-
}
|
|
127
|
-
return new RegExp(`^${re}$`);
|
|
128
|
-
}
|
|
129
|
-
const comboKey = (c) => Object.entries(c).map(([k, v]) => `${k}=${v}`).join(",") || "default";
|
|
130
|
-
function flattenLayerFile(json, file, issues) {
|
|
131
|
-
const out = [];
|
|
132
|
-
const walk = (node, path, inheritedType) => {
|
|
133
|
-
if (!node || typeof node !== "object" || Array.isArray(node)) return;
|
|
134
|
-
const n = node;
|
|
135
|
-
const type = typeof n.$type === "string" ? n.$type : inheritedType;
|
|
136
|
-
if ("$value" in n) {
|
|
137
|
-
out.push({
|
|
138
|
-
path: path.join("."),
|
|
139
|
-
...type ? { type } : {},
|
|
140
|
-
value: n.$value,
|
|
141
|
-
...typeof n.$description === "string" ? { description: n.$description } : {},
|
|
142
|
-
...n.$extensions && typeof n.$extensions === "object" ? { extensions: n.$extensions } : {},
|
|
143
|
-
...n.$deprecated !== void 0 ? { deprecated: n.$deprecated } : {},
|
|
144
|
-
file
|
|
145
|
-
});
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
for (const [k, v] of Object.entries(n)) {
|
|
149
|
-
if (k.startsWith("$")) continue;
|
|
150
|
-
const p = [...path, k].join(".");
|
|
151
|
-
if (/[{}.]/.test(k)) issues.push({ level: "error", code: "invalid-name", message: `Name "${k}" contains {, } or . which DTCG forbids.`, path: p, file });
|
|
152
|
-
if (v && typeof v === "object" && !Array.isArray(v)) walk(v, [...path, k], type);
|
|
153
|
-
else issues.push({ level: "error", code: "not-a-token", message: `"${p}" is neither a token (no $value) nor a group.`, path: p, file });
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
walk(json, []);
|
|
157
|
-
return out;
|
|
158
|
-
}
|
|
159
|
-
const toHex2 = (n) => Math.round(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, "0");
|
|
160
|
-
function compactJson(v) {
|
|
161
|
-
if (Array.isArray(v)) return `[${v.map(compactJson).join(", ")}]`;
|
|
162
|
-
if (v && typeof v === "object") {
|
|
163
|
-
const e = Object.entries(v);
|
|
164
|
-
return e.length ? `{ ${e.map(([k, x]) => `${JSON.stringify(k)}: ${compactJson(x)}`).join(", ")} }` : "{}";
|
|
165
|
-
}
|
|
166
|
-
return JSON.stringify(v);
|
|
167
|
-
}
|
|
168
|
-
function colorToCss(c) {
|
|
169
|
-
if (typeof c === "string") return c;
|
|
170
|
-
if (!c || typeof c !== "object") return String(c);
|
|
171
|
-
const o = c;
|
|
172
|
-
const [r, g, b] = (o.components ?? []).map((x) => typeof x === "number" ? x : 0);
|
|
173
|
-
const alpha = o.alpha ?? 1;
|
|
174
|
-
if (alpha < 1) return `rgb(${[r, g, b].map((x) => Math.round((x ?? 0) * 255)).join(" ")} / ${alpha})`;
|
|
175
|
-
return o.hex ?? `#${[r, g, b].map((x) => toHex2(x ?? 0)).join("")}`;
|
|
176
|
-
}
|
|
177
|
-
const dimToCss = (d) => d && typeof d === "object" && "value" in d ? `${d.value}${d.unit}` : String(d);
|
|
178
|
-
function valueToCss(type, v, ext) {
|
|
179
|
-
if (v === void 0 || v === null) return "";
|
|
180
|
-
switch (type) {
|
|
181
|
-
case "color":
|
|
182
|
-
return colorToCss(v);
|
|
183
|
-
case "dimension":
|
|
184
|
-
case "duration":
|
|
185
|
-
return dimToCss(v);
|
|
186
|
-
case "cubicBezier":
|
|
187
|
-
return Array.isArray(v) ? `cubic-bezier(${v.join(", ")})` : String(v);
|
|
188
|
-
case "fontFamily":
|
|
189
|
-
return Array.isArray(v) ? v.map((n) => /\s/.test(String(n)) ? `"${n}"` : String(n)).join(", ") : String(v);
|
|
190
|
-
case "shadow": {
|
|
191
|
-
if (typeof v === "string") return v;
|
|
192
|
-
const layers = Array.isArray(v) ? v : [v];
|
|
193
|
-
return layers.map((l) => [l.inset ? "inset" : "", dimToCss(l.offsetX), dimToCss(l.offsetY), dimToCss(l.blur), dimToCss(l.spread ?? { value: 0, unit: "px" }), colorToCss(l.color)].filter(Boolean).join(" ")).join(", ");
|
|
194
|
-
}
|
|
195
|
-
default: {
|
|
196
|
-
const unit = ext?.["dev.bridge.unit"];
|
|
197
|
-
if (typeof v === "number" && typeof unit === "string") return `${v}${unit}`;
|
|
198
|
-
return typeof v === "object" ? compactJson(v) : String(v);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
class LayeredTokenSet {
|
|
203
|
-
/** `files`: token file path relative to tokens.root -> file text. */
|
|
204
|
-
constructor(config, files) {
|
|
205
|
-
this.config = config;
|
|
206
|
-
this.files = files;
|
|
207
|
-
this.fileNames = [...files.keys()].sort();
|
|
208
|
-
for (const f of this.fileNames) {
|
|
209
|
-
let json;
|
|
210
|
-
try {
|
|
211
|
-
json = JSON.parse(files.get(f));
|
|
212
|
-
} catch (e) {
|
|
213
|
-
this.issues.push({ level: "error", code: "invalid-json", message: `Invalid JSON: ${e.message}`, file: f });
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
this.defs.push(...flattenLayerFile(json, f, this.issues));
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
config;
|
|
220
|
-
files;
|
|
221
|
-
defs = [];
|
|
222
|
-
issues = [];
|
|
223
|
-
fileNames;
|
|
224
|
-
views = /* @__PURE__ */ new Map();
|
|
225
|
-
get modeNames() {
|
|
226
|
-
return Object.keys(this.config.axes);
|
|
227
|
-
}
|
|
228
|
-
get defaultCombo() {
|
|
229
|
-
return Object.fromEntries(Object.entries(this.config.axes).map(([k, m]) => [k, m.default]));
|
|
230
|
-
}
|
|
231
|
-
/** Every combination of the given modes (all modes when omitted); other modes stay at default. */
|
|
232
|
-
combos(only) {
|
|
233
|
-
let out = [this.defaultCombo];
|
|
234
|
-
for (const [name, m] of Object.entries(this.config.axes)) {
|
|
235
|
-
if (only && !only.includes(name)) continue;
|
|
236
|
-
out = out.flatMap((c) => m.values.map((v) => ({ ...c, [name]: v })));
|
|
237
|
-
}
|
|
238
|
-
return out;
|
|
239
|
-
}
|
|
240
|
-
normalizeCombo(partial = {}) {
|
|
241
|
-
const c = { ...this.defaultCombo };
|
|
242
|
-
for (const [k, v] of Object.entries(partial)) {
|
|
243
|
-
if (v === void 0) continue;
|
|
244
|
-
const m = this.config.axes[k];
|
|
245
|
-
if (!m) throw new Error(`Unknown mode "${k}". Modes: ${this.modeNames.join(", ") || "none"}.`);
|
|
246
|
-
if (!m.values.includes(v)) throw new Error(`Unknown ${k} "${v}". Values: ${m.values.join(", ")}.`);
|
|
247
|
-
c[k] = v;
|
|
248
|
-
}
|
|
249
|
-
return c;
|
|
250
|
-
}
|
|
251
|
-
tierOfFile(file) {
|
|
252
|
-
for (const [tier, dirs] of Object.entries(this.config.tokens.tiers)) {
|
|
253
|
-
if (dirs.some((d) => file === d || file.startsWith(`${d.replace(/\/$/, "")}/`) || globToRegExp(d).test(file))) return tier;
|
|
254
|
-
}
|
|
255
|
-
return void 0;
|
|
256
|
-
}
|
|
257
|
-
/** Tier of a token: the lowest layer that defines it in the default mode (an override does not change its tier). */
|
|
258
|
-
tierOf(path) {
|
|
259
|
-
const d = this.view(this.defaultCombo).get(path)?.[0] ?? this.defs.find((x) => x.path === path);
|
|
260
|
-
return d ? this.tierOfFile(d.file) : void 0;
|
|
261
|
-
}
|
|
262
|
-
/** Files of each layer for a combo, in resolution order. */
|
|
263
|
-
layerFiles(combo) {
|
|
264
|
-
const files = [];
|
|
265
|
-
const missing = [];
|
|
266
|
-
for (const l of this.config.tokens.layers) {
|
|
267
|
-
const pattern = l.files.replace(/\{([^}]+)\}/g, (_, k) => combo[k] ?? `{${k}}`);
|
|
268
|
-
const re = globToRegExp(pattern);
|
|
269
|
-
const hit = this.fileNames.filter((f) => re.test(f));
|
|
270
|
-
if (!hit.length && !l.optional) missing.push(pattern);
|
|
271
|
-
for (const f of hit) if (!files.includes(f)) files.push(f);
|
|
272
|
-
}
|
|
273
|
-
return { files, missing };
|
|
274
|
-
}
|
|
275
|
-
/** path -> definitions in layer order (last one wins) for a combo. */
|
|
276
|
-
view(combo) {
|
|
277
|
-
const key = comboKey(combo);
|
|
278
|
-
let v = this.views.get(key);
|
|
279
|
-
if (!v) {
|
|
280
|
-
const { files, missing } = this.layerFiles(combo);
|
|
281
|
-
const map = /* @__PURE__ */ new Map();
|
|
282
|
-
const byFile = /* @__PURE__ */ new Map();
|
|
283
|
-
for (const d of this.defs) (byFile.get(d.file) ?? byFile.set(d.file, []).get(d.file)).push(d);
|
|
284
|
-
for (const f of files) for (const d of byFile.get(f) ?? []) (map.get(d.path) ?? map.set(d.path, []).get(d.path)).push(d);
|
|
285
|
-
v = { map, missing };
|
|
286
|
-
this.views.set(key, v);
|
|
287
|
-
}
|
|
288
|
-
return v.map;
|
|
289
|
-
}
|
|
290
|
-
missingLayers(combo) {
|
|
291
|
-
this.view(combo);
|
|
292
|
-
return this.views.get(comboKey(combo)).missing;
|
|
293
|
-
}
|
|
294
|
-
/** Every token path defined in any combo. */
|
|
295
|
-
allPaths() {
|
|
296
|
-
return [...new Set(this.defs.map((d) => d.path))].sort();
|
|
297
|
-
}
|
|
298
|
-
defsOf(path) {
|
|
299
|
-
return this.defs.filter((d) => d.path === path);
|
|
300
|
-
}
|
|
301
|
-
/** First combo whose layers include `file`, preferring the default. */
|
|
302
|
-
comboForFile(file) {
|
|
303
|
-
const all = [this.defaultCombo, ...this.combos()];
|
|
304
|
-
return all.find((c) => this.layerFiles(c).files.includes(file)) ?? this.defaultCombo;
|
|
305
|
-
}
|
|
306
|
-
resolve(path, combo) {
|
|
307
|
-
const view = this.view(combo);
|
|
308
|
-
const chain = [path];
|
|
309
|
-
const top = view.get(path);
|
|
310
|
-
if (!top) return { path, value: void 0, css: "", chain, definedIn: [], error: `"${path}" is not defined for ${comboKey(combo)}` };
|
|
311
|
-
const def = top[top.length - 1];
|
|
312
|
-
let type = def.type;
|
|
313
|
-
let error;
|
|
314
|
-
const deref = (target, stack) => {
|
|
315
|
-
if (stack.includes(target)) {
|
|
316
|
-
error = `circular alias: ${[...stack, target].join(" -> ")}`;
|
|
317
|
-
return void 0;
|
|
318
|
-
}
|
|
319
|
-
const t = view.get(target);
|
|
320
|
-
if (!t) {
|
|
321
|
-
error = `broken alias {${target}}`;
|
|
322
|
-
return void 0;
|
|
323
|
-
}
|
|
324
|
-
const td = t[t.length - 1];
|
|
325
|
-
type ??= td.type;
|
|
326
|
-
return walk(td.value, [...stack, target]);
|
|
327
|
-
};
|
|
328
|
-
const walk = (v, stack) => {
|
|
329
|
-
const a = aliasOf(v);
|
|
330
|
-
if (a) return deref(a, stack);
|
|
331
|
-
if (Array.isArray(v)) return v.map((x) => walk(x, stack));
|
|
332
|
-
if (v && typeof v === "object") return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, walk(x, stack)]));
|
|
333
|
-
return v;
|
|
334
|
-
};
|
|
335
|
-
let cur = def.value;
|
|
336
|
-
const seen = /* @__PURE__ */ new Set([path]);
|
|
337
|
-
for (let a = aliasOf(cur); a; a = aliasOf(cur)) {
|
|
338
|
-
chain.push(a);
|
|
339
|
-
if (seen.has(a)) break;
|
|
340
|
-
seen.add(a);
|
|
341
|
-
const t = view.get(a);
|
|
342
|
-
if (!t) break;
|
|
343
|
-
cur = t[t.length - 1].value;
|
|
344
|
-
}
|
|
345
|
-
const value = walk(def.value, [path]);
|
|
346
|
-
return { path, ...type ? { type } : {}, value, css: error ? "" : valueToCss(type, value, def.extensions), chain, definedIn: top.map((d) => d.file), ...error ? { error } : {} };
|
|
347
|
-
}
|
|
348
|
-
/** Tokens whose own value aliases `path` directly, across all files. */
|
|
349
|
-
referencedBy(path) {
|
|
350
|
-
const needle = `{${path}}`;
|
|
351
|
-
return this.defs.filter((d) => JSON.stringify(d.value).includes(needle)).map((d) => ({ path: d.path, file: d.file }));
|
|
352
|
-
}
|
|
353
|
-
cssVarName(path) {
|
|
354
|
-
return `${this.config.cssVar.prefix}${path.split(".").join(this.config.cssVar.separator)}`;
|
|
355
|
-
}
|
|
356
|
-
/** Repo-relative path of a token file. */
|
|
357
|
-
repoPath(file) {
|
|
358
|
-
const root = this.config.tokens.root;
|
|
359
|
-
return root === "." || !root ? file : `${root.replace(/\/$/, "")}/${file}`;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
function selectTokenFiles(config, repoFiles) {
|
|
363
|
-
const root = config.tokens.root.replace(/\/$/, "");
|
|
364
|
-
const rel = (f) => root === "." || !root ? f : f.startsWith(`${root}/`) ? f.slice(root.length + 1) : null;
|
|
365
|
-
const inc = config.tokens.include.map(globToRegExp);
|
|
366
|
-
const exc = config.tokens.exclude.map(globToRegExp);
|
|
367
|
-
return repoFiles.filter((f) => f !== config.contrast?.path).map(rel).filter((f) => f !== null && inc.some((r) => r.test(f)) && !exc.some((r) => r.test(f)));
|
|
368
|
-
}
|
|
369
|
-
function checkShape(type, v) {
|
|
370
|
-
if (aliasOf(v)) return null;
|
|
371
|
-
const isObj = (x) => Boolean(x) && typeof x === "object" && !Array.isArray(x);
|
|
372
|
-
switch (type) {
|
|
373
|
-
case "color":
|
|
374
|
-
if (typeof v === "string") return /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(v) ? "warn:color as a hex string: DTCG 2025.10 uses { colorSpace, components, hex }" : "color must be { colorSpace, components } (or a hex string)";
|
|
375
|
-
if (!isObj(v) || typeof v.colorSpace !== "string" || !Array.isArray(v.components)) return "color must be { colorSpace, components, alpha?, hex? }";
|
|
376
|
-
if (v.components.length !== 3 || !v.components.every((c) => typeof c === "number" || c === "none" || aliasOf(c))) return "color components must be 3 numbers";
|
|
377
|
-
if (v.alpha !== void 0 && (typeof v.alpha !== "number" || v.alpha < 0 || v.alpha > 1)) return "color alpha must be between 0 and 1";
|
|
378
|
-
if (v.hex !== void 0 && !/^#[0-9a-f]{6}$/i.test(String(v.hex))) return "color hex must be #rrggbb";
|
|
379
|
-
return null;
|
|
380
|
-
case "dimension":
|
|
381
|
-
if (typeof v === "string" || typeof v === "number") return "warn:dimension as a plain value: DTCG 2025.10 uses { value, unit }";
|
|
382
|
-
return isObj(v) && typeof v.value === "number" && ["px", "rem"].includes(String(v.unit)) ? null : 'dimension must be { value: number, unit: "px" | "rem" }';
|
|
383
|
-
case "duration":
|
|
384
|
-
if (typeof v === "string") return "warn:duration as a string: DTCG 2025.10 uses { value, unit }";
|
|
385
|
-
return isObj(v) && typeof v.value === "number" && ["ms", "s"].includes(String(v.unit)) ? null : 'duration must be { value: number, unit: "ms" | "s" }';
|
|
386
|
-
case "cubicBezier":
|
|
387
|
-
return Array.isArray(v) && v.length === 4 && v.every((x) => typeof x === "number") && v[0] >= 0 && v[0] <= 1 && v[2] >= 0 && v[2] <= 1 ? null : "cubicBezier must be [x1, y1, x2, y2] with x in 0..1";
|
|
388
|
-
case "fontFamily":
|
|
389
|
-
return typeof v === "string" || Array.isArray(v) && v.every((x) => typeof x === "string") ? null : "fontFamily must be a string or an array of strings";
|
|
390
|
-
case "fontWeight":
|
|
391
|
-
return typeof v === "number" && v >= 1 && v <= 1e3 || typeof v === "string" ? null : "fontWeight must be 1..1000 or a keyword";
|
|
392
|
-
case "number":
|
|
393
|
-
return typeof v === "number" ? null : "number must be a number";
|
|
394
|
-
case "shadow": {
|
|
395
|
-
const layers = Array.isArray(v) ? v : [v];
|
|
396
|
-
return layers.every((l) => isObj(l) && "color" in l && "offsetX" in l && "offsetY" in l && "blur" in l) ? null : "shadow must be { color, offsetX, offsetY, blur, spread? } or an array of them";
|
|
397
|
-
}
|
|
398
|
-
default:
|
|
399
|
-
return null;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
function validateLayered(set) {
|
|
403
|
-
const issues = [...set.issues];
|
|
404
|
-
for (const d of set.defs) {
|
|
405
|
-
if (d.type && !DTCG_TYPES.has(d.type)) issues.push({ level: "error", code: "unknown-type", message: `Unknown $type "${d.type}".`, path: d.path, file: d.file });
|
|
406
|
-
if (d.type) {
|
|
407
|
-
const s = checkShape(d.type, d.value);
|
|
408
|
-
if (s) issues.push({ level: s.startsWith("warn:") ? "warning" : "error", code: "invalid-value", message: s.replace(/^warn:/, ""), path: d.path, file: d.file });
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
const merged = /* @__PURE__ */ new Map();
|
|
412
|
-
const add = (i, combo) => {
|
|
413
|
-
const k = `${i.code}|${i.path}|${i.message}`;
|
|
414
|
-
const prev = merged.get(k);
|
|
415
|
-
if (prev) prev.modes.push(comboKey(combo));
|
|
416
|
-
else merged.set(k, { ...i, modes: [comboKey(combo)] });
|
|
417
|
-
};
|
|
418
|
-
for (const combo of set.combos()) {
|
|
419
|
-
for (const miss of set.missingLayers(combo)) add({ level: "error", code: "missing-layer", message: `No file matches layer "${miss}".` }, combo);
|
|
420
|
-
for (const [path, defs] of set.view(combo)) {
|
|
421
|
-
const r = set.resolve(path, combo);
|
|
422
|
-
const def = defs[defs.length - 1];
|
|
423
|
-
if (r.error) add({ level: "error", code: r.error.startsWith("circular") ? "circular-alias" : "broken-alias", message: r.error, path, file: def.file }, combo);
|
|
424
|
-
else if (!r.type) add({ level: "error", code: "missing-type", message: "No $type on the token, its groups or its alias target.", path, file: def.file }, combo);
|
|
425
|
-
else if (def.type && aliasOf(def.value)) {
|
|
426
|
-
const target = set.view(combo).get(aliasOf(def.value));
|
|
427
|
-
const tt = target?.[target.length - 1]?.type;
|
|
428
|
-
if (tt && tt !== def.type) add({ level: "error", code: "type-mismatch", message: `$type ${def.type} aliases a ${tt} token (${String(def.value)}).`, path, file: def.file }, combo);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
const total = set.combos().length;
|
|
433
|
-
for (const i of merged.values()) {
|
|
434
|
-
if (i.modes.length === total) delete i.modes;
|
|
435
|
-
issues.push(i);
|
|
436
|
-
}
|
|
437
|
-
issues.push(...layeredParityIssues(set));
|
|
438
|
-
return issues;
|
|
439
|
-
}
|
|
440
|
-
function layeredParityIssues(set) {
|
|
441
|
-
const out = [];
|
|
442
|
-
const pathsOf = (file) => new Set(set.defs.filter((d) => d.file === file).map((d) => d.path));
|
|
443
|
-
for (const [mode, m] of Object.entries(set.config.axes)) {
|
|
444
|
-
if (!m.parity) continue;
|
|
445
|
-
for (const layer of set.config.tokens.layers) {
|
|
446
|
-
if (!layer.files.includes(`{${mode}}`) || layer.optional) continue;
|
|
447
|
-
const others = (layer.files.match(/\{([^}]+)\}/g) ?? []).map((p) => p.slice(1, -1)).filter((k) => k !== mode);
|
|
448
|
-
let fixed = [{}];
|
|
449
|
-
for (const o of others) fixed = fixed.flatMap((c) => (set.config.axes[o]?.values ?? []).map((v) => ({ ...c, [o]: v })));
|
|
450
|
-
for (const c of fixed) {
|
|
451
|
-
const filesByValue = m.values.map((v) => {
|
|
452
|
-
const re = globToRegExp(layer.files.replace(/\{([^}]+)\}/g, (_, k) => k === mode ? v : c[k]));
|
|
453
|
-
return { v, files: set.fileNames.filter((f) => re.test(f)) };
|
|
454
|
-
});
|
|
455
|
-
const present = filesByValue.filter((x) => x.files.length);
|
|
456
|
-
if (!present.length) continue;
|
|
457
|
-
for (const x of filesByValue) {
|
|
458
|
-
if (!x.files.length) out.push({ level: "error", code: "mode-parity", message: `${mode} "${x.v}" has no file for layer "${layer.files}" while ${present.map((p) => p.v).join(", ")} do.` });
|
|
459
|
-
}
|
|
460
|
-
const sets = present.map((x) => ({ v: x.v, files: x.files, paths: new Set(x.files.flatMap((f) => [...pathsOf(f)])) }));
|
|
461
|
-
const union = new Set(sets.flatMap((s) => [...s.paths]));
|
|
462
|
-
for (const p of union) {
|
|
463
|
-
const lacking = sets.filter((s) => !s.paths.has(p));
|
|
464
|
-
if (lacking.length) {
|
|
465
|
-
const having = sets.find((s) => s.paths.has(p));
|
|
466
|
-
out.push({ level: "error", code: "mode-parity", message: `Defined for ${mode} ${sets.filter((s) => s.paths.has(p)).map((s) => s.v).join(", ")} but not ${lacking.map((s) => s.v).join(", ")} (${lacking.map((s) => s.files.join(", ")).join("; ")}).`, path: p, file: having.files[0] });
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
return out;
|
|
473
|
-
}
|
|
474
|
-
export {
|
|
475
|
-
DTCG_TYPES as D,
|
|
476
|
-
LayeredTokenSet as L,
|
|
477
|
-
collectRefs as a,
|
|
478
|
-
aliasTarget as b,
|
|
479
|
-
comboKey as c,
|
|
480
|
-
aliasOf as d,
|
|
481
|
-
rgbaToHex as e,
|
|
482
|
-
formatValue as f,
|
|
483
|
-
globToRegExp as g,
|
|
484
|
-
hexToRgba as h,
|
|
485
|
-
isAlias as i,
|
|
486
|
-
validateLayered as j,
|
|
487
|
-
colorToCss as k,
|
|
488
|
-
colorsEqual as l,
|
|
489
|
-
compactJson as m,
|
|
490
|
-
flattenLayerFile as n,
|
|
491
|
-
layeredParityIssues as o,
|
|
492
|
-
parseColor as p,
|
|
493
|
-
parseDimension as q,
|
|
494
|
-
rgbaToDtcg as r,
|
|
495
|
-
selectTokenFiles as s,
|
|
496
|
-
toAlias as t,
|
|
497
|
-
valueToCss as u,
|
|
498
|
-
valuesEqual as v
|
|
499
|
-
};
|
|
500
|
-
//# sourceMappingURL=layered-BnbmToGs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"layered-BnbmToGs.js","sources":["../src/values.ts","../src/layered.ts"],"sourcesContent":["// Value helpers: aliases, colors, equality with tolerance, display formatting.\n\nexport interface Rgba {\n r: number;\n g: number;\n b: number;\n a: number;\n}\n\nconst ALIAS_RE = /^\\{([^{}]+)\\}$/;\n\nexport const isAlias = (v: unknown): v is string => typeof v === 'string' && ALIAS_RE.test(v);\nexport const aliasTarget = (v: string): string => ALIAS_RE.exec(v)?.[1] ?? v;\nexport const toAlias = (path: string): string => `{${path}}`;\n\n/** All alias references inside a value, including nested ones in composite values. */\nexport function collectRefs(value: unknown, out: string[] = []): string[] {\n if (isAlias(value)) out.push(aliasTarget(value));\n else if (Array.isArray(value)) value.forEach((v) => collectRefs(v, out));\n else if (value && typeof value === 'object') Object.values(value).forEach((v) => collectRefs(v, out));\n return out;\n}\n\nconst clamp01 = (n: number) => Math.min(1, Math.max(0, n));\nconst round = (n: number, digits: number) => {\n const f = 10 ** digits;\n return Math.round(n * f) / f;\n};\n\nexport function hexToRgba(hex: string): Rgba | undefined {\n const m = /^#?([0-9a-f]{3,8})$/i.exec(hex.trim());\n if (!m) return undefined;\n let h = m[1]!;\n if (h.length === 3 || h.length === 4) h = [...h].map((c) => c + c).join('');\n if (h.length !== 6 && h.length !== 8) return undefined;\n const n = (idx: number) => parseInt(h.slice(idx, idx + 2), 16) / 255;\n return { r: n(0), g: n(2), b: n(4), a: h.length === 8 ? n(6) : 1 };\n}\n\nconst to255 = (n: number) => Math.round(clamp01(n) * 255);\nexport const rgbaToHex = (c: Rgba): string =>\n '#' + [c.r, c.g, c.b].map((x) => to255(x).toString(16).padStart(2, '0')).join('');\n\n/** Parse a DTCG color value (2025.10 object form or legacy hex string). Undefined for unsupported color spaces. */\nexport function parseColor(value: unknown): Rgba | undefined {\n if (typeof value === 'string') return isAlias(value) ? undefined : hexToRgba(value);\n if (!value || typeof value !== 'object') return undefined;\n const v = value as { colorSpace?: unknown; components?: unknown; alpha?: unknown; hex?: unknown };\n const alpha = typeof v.alpha === 'number' ? v.alpha : 1;\n if (v.colorSpace === 'srgb' && Array.isArray(v.components) && v.components.length === 3) {\n const [r, g, b] = v.components as unknown[];\n if ([r, g, b].every((x) => typeof x === 'number')) return { r: r as number, g: g as number, b: b as number, a: alpha };\n }\n if (typeof v.hex === 'string') {\n const c = hexToRgba(v.hex);\n if (c) return { ...c, a: alpha };\n }\n return undefined;\n}\n\n/** DTCG 2025.10 color object from RGBA floats. Components are rounded to 3 decimals like the repo files. */\nexport function rgbaToDtcg(c: Rgba): Record<string, unknown> {\n const out: Record<string, unknown> = {\n colorSpace: 'srgb',\n components: [round(clamp01(c.r), 3), round(clamp01(c.g), 3), round(clamp01(c.b), 3)],\n };\n if (c.a < 0.9995) out.alpha = round(clamp01(c.a), 3);\n out.hex = rgbaToHex(c);\n return out;\n}\n\nexport function colorsEqual(a: Rgba, b: Rgba): boolean {\n return rgbaToHex(a) === rgbaToHex(b) && Math.abs(a.a - b.a) < 0.002;\n}\n\nexport interface Dimension {\n value: number;\n unit: string;\n}\n\nexport function parseDimension(value: unknown): Dimension | undefined {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const v = value as { value?: unknown; unit?: unknown };\n if (typeof v.value === 'number' && typeof v.unit === 'string') return { value: v.value, unit: v.unit };\n }\n if (typeof value === 'string') {\n const m = /^(-?\\d+(?:\\.\\d+)?)(px|rem)$/.exec(value.trim());\n if (m) return { value: Number(m[1]), unit: m[2]! };\n }\n if (typeof value === 'number') return { value, unit: 'px' };\n return undefined;\n}\n\nconst numbersEqual = (a: number, b: number) => Math.abs(a - b) < 1e-4;\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a === 'number' && typeof b === 'number') return numbersEqual(a, b);\n if (typeof a !== typeof b || !a || !b || typeof a !== 'object') return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((v, idx) => deepEqual(v, b[idx]));\n const ka = Object.keys(a as object).filter((k) => (a as Record<string, unknown>)[k] !== undefined);\n const kb = Object.keys(b as object).filter((k) => (b as Record<string, unknown>)[k] !== undefined);\n if (ka.length !== kb.length) return false;\n return ka.every((k) => deepEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]));\n}\n\n/**\n * Semantic equality of two DTCG values of the same type. Tolerant to float noise coming back\n * from Figma (colors compare by 8-bit hex + alpha, numbers to 1e-4).\n */\nexport function valuesEqual(type: string, a: unknown, b: unknown): boolean {\n if (a === undefined || b === undefined) return a === b;\n if (isAlias(a) || isAlias(b)) return isAlias(a) && isAlias(b) && aliasTarget(a) === aliasTarget(b);\n if (type === 'color') {\n const ca = parseColor(a);\n const cb = parseColor(b);\n if (ca && cb) return colorsEqual(ca, cb);\n }\n if (type === 'dimension') {\n const da = parseDimension(a);\n const db = parseDimension(b);\n if (da && db) return da.unit === db.unit && numbersEqual(da.value, db.value);\n }\n return deepEqual(a, b);\n}\n\n/** Short human-readable form of a value for the UI and PR body. */\nexport function formatValue(type: string, value: unknown): string {\n if (value === undefined) return 'none';\n if (isAlias(value)) return aliasTarget(value);\n if (type === 'color') {\n const c = parseColor(value);\n // The file's hex is what tokens.css ships; components can round differently at 8 bits.\n const hex = value && typeof value === 'object' && typeof (value as { hex?: unknown }).hex === 'string' ? ((value as { hex: string }).hex.toLowerCase()) : undefined;\n if (c) return c.a < 0.9995 ? `${hex ?? rgbaToHex(c)} @ ${Math.round(c.a * 100)}%` : (hex ?? rgbaToHex(c));\n }\n if (type === 'dimension') {\n const d = parseDimension(value);\n if (d) return `${d.value}${d.unit}`;\n }\n if (Array.isArray(value)) return value.join(', ');\n if (typeof value === 'object' && value) return JSON.stringify(value);\n return String(value);\n}\n","// Layered token sets: any DTCG repo described by bridge.config.json \"tokens.layers\" and \"modes\".\n//\n// The tier model in token-set.ts maps the Bridge layout onto Figma collections (one collection per tier,\n// one Figma mode per brand, theme or density). Tools that only read and check tokens (the CLI and the MCP\n// server) need something more general: a repo with a core.json, a theme/ folder and no brands at all must\n// work too. A layered set resolves a token for a combination of mode values (\"combo\") by stacking the\n// layer files for that combo, lowest first, the last definition winning; aliases resolve inside the stack.\n//\n// Values are formatted for CSS exactly like packages/tokens/build.mjs, so a resolved value can be compared\n// with dist/resolved.json byte for byte.\n\nimport type { BridgeConfig } from './config';\nimport { isAlias, aliasTarget as targetOf } from './values';\n\nexport interface LayeredDef {\n path: string;\n type?: string;\n value: unknown;\n description?: string;\n extensions?: Record<string, unknown>;\n deprecated?: unknown;\n /** File relative to tokens.root. */\n file: string;\n}\n\nexport interface LayerIssue {\n level: 'error' | 'warning';\n code: string;\n message: string;\n path?: string;\n file?: string;\n /** Mode combinations the issue appears in; absent when it appears in all of them. */\n modes?: string[];\n}\n\n/** A value per mode name, e.g. { brand: \"ocean\", theme: \"dark\", density: \"compact\" }. */\nexport type Combo = Record<string, string>;\n\nexport interface LayeredResolution {\n path: string;\n type?: string;\n /** Raw DTCG value with every alias replaced. */\n value: unknown;\n /** CSS-ready string, the way the token build writes it. */\n css: string;\n /** Alias hops, starting with the token itself. */\n chain: string[];\n /** Files that define the token in this combo, highest layer last. */\n definedIn: string[];\n error?: string;\n}\n\nexport const DTCG_TYPES = new Set(['color', 'dimension', 'fontFamily', 'fontWeight', 'duration', 'cubicBezier', 'number', 'strokeStyle', 'border', 'transition', 'shadow', 'gradient', 'typography', 'fontStyle', 'string', 'boolean']);\n\n/** Alias target of a value, or null when it is not an alias. */\nexport const aliasOf = (v: unknown): string | null => (isAlias(v) ? targetOf(v) : null);\n\n/** `*` (one segment), `**` (any depth) and `?` globs, matched against the whole path. */\nexport function globToRegExp(glob: string): RegExp {\n let re = '';\n for (let i = 0; i < glob.length; i++) {\n const c = glob[i]!;\n if (c === '*' && glob[i + 1] === '*') {\n if (glob[i + 2] === '/') {\n re += '(?:.*/)?';\n i += 2;\n } else {\n re += '.*';\n i += 1;\n }\n } else if (c === '*') re += '[^/]*';\n else if (c === '?') re += '[^/]';\n else re += c.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n return new RegExp(`^${re}$`);\n}\n\nexport const comboKey = (c: Combo) => Object.entries(c).map(([k, v]) => `${k}=${v}`).join(',') || 'default';\n\n/** Tokens of one parsed file, with $type inherited from groups. Names DTCG forbids are reported. */\nexport function flattenLayerFile(json: unknown, file: string, issues: LayerIssue[]): LayeredDef[] {\n const out: LayeredDef[] = [];\n const walk = (node: unknown, path: string[], inheritedType?: string) => {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return;\n const n = node as Record<string, unknown>;\n const type = typeof n.$type === 'string' ? n.$type : inheritedType;\n if ('$value' in n) {\n out.push({\n path: path.join('.'),\n ...(type ? { type } : {}),\n value: n.$value,\n ...(typeof n.$description === 'string' ? { description: n.$description } : {}),\n ...(n.$extensions && typeof n.$extensions === 'object' ? { extensions: n.$extensions as Record<string, unknown> } : {}),\n ...(n.$deprecated !== undefined ? { deprecated: n.$deprecated } : {}),\n file,\n });\n return;\n }\n for (const [k, v] of Object.entries(n)) {\n if (k.startsWith('$')) continue;\n const p = [...path, k].join('.');\n if (/[{}.]/.test(k)) issues.push({ level: 'error', code: 'invalid-name', message: `Name \"${k}\" contains {, } or . which DTCG forbids.`, path: p, file });\n if (v && typeof v === 'object' && !Array.isArray(v)) walk(v, [...path, k], type);\n else issues.push({ level: 'error', code: 'not-a-token', message: `\"${p}\" is neither a token (no $value) nor a group.`, path: p, file });\n }\n };\n walk(json, []);\n return out;\n}\n\n// --- CSS formatting (matches packages/tokens/build.mjs) ---------------------------------------------------\n\nconst toHex2 = (n: number) => Math.round(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, '0');\n\n/** One-line JSON in the house style: `{ \"a\": 1, \"b\": [1, 2] }`. */\nexport function compactJson(v: unknown): string {\n if (Array.isArray(v)) return `[${v.map(compactJson).join(', ')}]`;\n if (v && typeof v === 'object') {\n const e = Object.entries(v);\n return e.length ? `{ ${e.map(([k, x]) => `${JSON.stringify(k)}: ${compactJson(x)}`).join(', ')} }` : '{}';\n }\n return JSON.stringify(v);\n}\n\nexport function colorToCss(c: unknown): string {\n if (typeof c === 'string') return c;\n if (!c || typeof c !== 'object') return String(c);\n const o = c as { components?: unknown[]; alpha?: number; hex?: string };\n const [r, g, b] = (o.components ?? []).map((x) => (typeof x === 'number' ? x : 0));\n const alpha = o.alpha ?? 1;\n if (alpha < 1) return `rgb(${[r, g, b].map((x) => Math.round((x ?? 0) * 255)).join(' ')} / ${alpha})`;\n return o.hex ?? `#${[r, g, b].map((x) => toHex2(x ?? 0)).join('')}`;\n}\nconst dimToCss = (d: unknown) => (d && typeof d === 'object' && 'value' in (d as object) ? `${(d as { value: number }).value}${(d as { unit: string }).unit}` : String(d));\n\nexport function valueToCss(type: string | undefined, v: unknown, ext?: Record<string, unknown>): string {\n if (v === undefined || v === null) return '';\n switch (type) {\n case 'color':\n return colorToCss(v);\n case 'dimension':\n case 'duration':\n return dimToCss(v);\n case 'cubicBezier':\n return Array.isArray(v) ? `cubic-bezier(${v.join(', ')})` : String(v);\n case 'fontFamily':\n return Array.isArray(v) ? v.map((n) => (/\\s/.test(String(n)) ? `\"${n}\"` : String(n))).join(', ') : String(v);\n case 'shadow': {\n if (typeof v === 'string') return v;\n const layers = (Array.isArray(v) ? v : [v]) as Record<string, unknown>[];\n return layers.map((l) => [l.inset ? 'inset' : '', dimToCss(l.offsetX), dimToCss(l.offsetY), dimToCss(l.blur), dimToCss(l.spread ?? { value: 0, unit: 'px' }), colorToCss(l.color)].filter(Boolean).join(' ')).join(', ');\n }\n default: {\n const unit = ext?.['dev.bridge.unit'];\n if (typeof v === 'number' && typeof unit === 'string') return `${v}${unit}`;\n return typeof v === 'object' ? compactJson(v) : String(v);\n }\n }\n}\n\n// --- the set ----------------------------------------------------------------------------------------------\n\nexport class LayeredTokenSet {\n readonly defs: LayeredDef[] = [];\n readonly issues: LayerIssue[] = [];\n readonly fileNames: string[];\n private readonly views = new Map<string, { map: Map<string, LayeredDef[]>; missing: string[] }>();\n\n /** `files`: token file path relative to tokens.root -> file text. */\n constructor(\n readonly config: BridgeConfig,\n readonly files: Map<string, string>,\n ) {\n this.fileNames = [...files.keys()].sort();\n for (const f of this.fileNames) {\n let json: unknown;\n try {\n json = JSON.parse(files.get(f)!);\n } catch (e) {\n this.issues.push({ level: 'error', code: 'invalid-json', message: `Invalid JSON: ${(e as Error).message}`, file: f });\n continue;\n }\n this.defs.push(...flattenLayerFile(json, f, this.issues));\n }\n }\n\n get modeNames() {\n return Object.keys(this.config.axes);\n }\n get defaultCombo(): Combo {\n return Object.fromEntries(Object.entries(this.config.axes).map(([k, m]) => [k, m.default]));\n }\n /** Every combination of the given modes (all modes when omitted); other modes stay at default. */\n combos(only?: string[]): Combo[] {\n let out: Combo[] = [this.defaultCombo];\n for (const [name, m] of Object.entries(this.config.axes)) {\n if (only && !only.includes(name)) continue;\n out = out.flatMap((c) => m.values.map((v) => ({ ...c, [name]: v })));\n }\n return out;\n }\n normalizeCombo(partial: Partial<Combo> = {}): Combo {\n const c = { ...this.defaultCombo };\n for (const [k, v] of Object.entries(partial)) {\n if (v === undefined) continue;\n const m = this.config.axes[k];\n if (!m) throw new Error(`Unknown mode \"${k}\". Modes: ${this.modeNames.join(', ') || 'none'}.`);\n if (!m.values.includes(v)) throw new Error(`Unknown ${k} \"${v}\". Values: ${m.values.join(', ')}.`);\n c[k] = v;\n }\n return c;\n }\n\n tierOfFile(file: string): string | undefined {\n for (const [tier, dirs] of Object.entries(this.config.tokens.tiers)) {\n if (dirs.some((d) => file === d || file.startsWith(`${d.replace(/\\/$/, '')}/`) || globToRegExp(d).test(file))) return tier;\n }\n return undefined;\n }\n\n /** Tier of a token: the lowest layer that defines it in the default mode (an override does not change its tier). */\n tierOf(path: string): string | undefined {\n const d = this.view(this.defaultCombo).get(path)?.[0] ?? this.defs.find((x) => x.path === path);\n return d ? this.tierOfFile(d.file) : undefined;\n }\n\n /** Files of each layer for a combo, in resolution order. */\n layerFiles(combo: Combo): { files: string[]; missing: string[] } {\n const files: string[] = [];\n const missing: string[] = [];\n for (const l of this.config.tokens.layers) {\n const pattern = l.files.replace(/\\{([^}]+)\\}/g, (_, k: string) => combo[k] ?? `{${k}}`);\n const re = globToRegExp(pattern);\n const hit = this.fileNames.filter((f) => re.test(f));\n if (!hit.length && !l.optional) missing.push(pattern);\n for (const f of hit) if (!files.includes(f)) files.push(f);\n }\n return { files, missing };\n }\n\n /** path -> definitions in layer order (last one wins) for a combo. */\n view(combo: Combo): Map<string, LayeredDef[]> {\n const key = comboKey(combo);\n let v = this.views.get(key);\n if (!v) {\n const { files, missing } = this.layerFiles(combo);\n const map = new Map<string, LayeredDef[]>();\n const byFile = new Map<string, LayeredDef[]>();\n for (const d of this.defs) (byFile.get(d.file) ?? byFile.set(d.file, []).get(d.file)!).push(d);\n for (const f of files) for (const d of byFile.get(f) ?? []) (map.get(d.path) ?? map.set(d.path, []).get(d.path)!).push(d);\n v = { map, missing };\n this.views.set(key, v);\n }\n return v.map;\n }\n missingLayers(combo: Combo): string[] {\n this.view(combo);\n return this.views.get(comboKey(combo))!.missing;\n }\n\n /** Every token path defined in any combo. */\n allPaths(): string[] {\n return [...new Set(this.defs.map((d) => d.path))].sort();\n }\n defsOf(path: string): LayeredDef[] {\n return this.defs.filter((d) => d.path === path);\n }\n\n /** First combo whose layers include `file`, preferring the default. */\n comboForFile(file: string): Combo {\n const all = [this.defaultCombo, ...this.combos()];\n return all.find((c) => this.layerFiles(c).files.includes(file)) ?? this.defaultCombo;\n }\n\n resolve(path: string, combo: Combo): LayeredResolution {\n const view = this.view(combo);\n const chain: string[] = [path];\n const top = view.get(path);\n if (!top) return { path, value: undefined, css: '', chain, definedIn: [], error: `\"${path}\" is not defined for ${comboKey(combo)}` };\n const def = top[top.length - 1]!;\n let type = def.type;\n let error: string | undefined;\n const deref = (target: string, stack: string[]): unknown => {\n if (stack.includes(target)) {\n error = `circular alias: ${[...stack, target].join(' -> ')}`;\n return undefined;\n }\n const t = view.get(target);\n if (!t) {\n error = `broken alias {${target}}`;\n return undefined;\n }\n const td = t[t.length - 1]!;\n type ??= td.type;\n return walk(td.value, [...stack, target]);\n };\n const walk = (v: unknown, stack: string[]): unknown => {\n const a = aliasOf(v);\n if (a) return deref(a, stack);\n if (Array.isArray(v)) return v.map((x) => walk(x, stack));\n if (v && typeof v === 'object') return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, walk(x, stack)]));\n return v;\n };\n // Top-level alias chain, for designers: color.text.muted -> palette.neutral.600 -> color.steel.600.\n let cur = def.value;\n const seen = new Set([path]);\n for (let a = aliasOf(cur); a; a = aliasOf(cur)) {\n chain.push(a);\n if (seen.has(a)) break;\n seen.add(a);\n const t = view.get(a);\n if (!t) break;\n cur = t[t.length - 1]!.value;\n }\n const value = walk(def.value, [path]);\n return { path, ...(type ? { type } : {}), value, css: error ? '' : valueToCss(type, value, def.extensions), chain, definedIn: top.map((d) => d.file), ...(error ? { error } : {}) };\n }\n\n /** Tokens whose own value aliases `path` directly, across all files. */\n referencedBy(path: string): { path: string; file: string }[] {\n const needle = `{${path}}`;\n return this.defs.filter((d) => JSON.stringify(d.value).includes(needle)).map((d) => ({ path: d.path, file: d.file }));\n }\n\n cssVarName(path: string): string {\n return `${this.config.cssVar.prefix}${path.split('.').join(this.config.cssVar.separator)}`;\n }\n\n /** Repo-relative path of a token file. */\n repoPath(file: string): string {\n const root = this.config.tokens.root;\n return root === '.' || !root ? file : `${root.replace(/\\/$/, '')}/${file}`;\n }\n}\n\n/** Token files of a repo listing: under tokens.root, matching include and not exclude, minus the contrast file. Paths relative to root. */\nexport function selectTokenFiles(config: BridgeConfig, repoFiles: string[]): string[] {\n const root = config.tokens.root.replace(/\\/$/, '');\n const rel = (f: string) => (root === '.' || !root ? f : f.startsWith(`${root}/`) ? f.slice(root.length + 1) : null);\n const inc = config.tokens.include.map(globToRegExp);\n const exc = config.tokens.exclude.map(globToRegExp);\n return repoFiles\n .filter((f) => f !== config.contrast?.path)\n .map(rel)\n .filter((f): f is string => f !== null && inc.some((r) => r.test(f)) && !exc.some((r) => r.test(f)));\n}\n\n// --- validation -------------------------------------------------------------------------------------------\n\nfunction checkShape(type: string, v: unknown): string | null {\n if (aliasOf(v)) return null;\n const isObj = (x: unknown): x is Record<string, unknown> => Boolean(x) && typeof x === 'object' && !Array.isArray(x);\n switch (type) {\n case 'color':\n if (typeof v === 'string') return /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(v) ? 'warn:color as a hex string: DTCG 2025.10 uses { colorSpace, components, hex }' : 'color must be { colorSpace, components } (or a hex string)';\n if (!isObj(v) || typeof v.colorSpace !== 'string' || !Array.isArray(v.components)) return 'color must be { colorSpace, components, alpha?, hex? }';\n if (v.components.length !== 3 || !v.components.every((c) => typeof c === 'number' || c === 'none' || aliasOf(c))) return 'color components must be 3 numbers';\n if (v.alpha !== undefined && (typeof v.alpha !== 'number' || v.alpha < 0 || v.alpha > 1)) return 'color alpha must be between 0 and 1';\n if (v.hex !== undefined && !/^#[0-9a-f]{6}$/i.test(String(v.hex))) return 'color hex must be #rrggbb';\n return null;\n case 'dimension':\n if (typeof v === 'string' || typeof v === 'number') return 'warn:dimension as a plain value: DTCG 2025.10 uses { value, unit }';\n return isObj(v) && typeof v.value === 'number' && ['px', 'rem'].includes(String(v.unit)) ? null : 'dimension must be { value: number, unit: \"px\" | \"rem\" }';\n case 'duration':\n if (typeof v === 'string') return 'warn:duration as a string: DTCG 2025.10 uses { value, unit }';\n return isObj(v) && typeof v.value === 'number' && ['ms', 's'].includes(String(v.unit)) ? null : 'duration must be { value: number, unit: \"ms\" | \"s\" }';\n case 'cubicBezier':\n return Array.isArray(v) && v.length === 4 && v.every((x) => typeof x === 'number') && (v[0] as number) >= 0 && (v[0] as number) <= 1 && (v[2] as number) >= 0 && (v[2] as number) <= 1 ? null : 'cubicBezier must be [x1, y1, x2, y2] with x in 0..1';\n case 'fontFamily':\n return typeof v === 'string' || (Array.isArray(v) && v.every((x) => typeof x === 'string')) ? null : 'fontFamily must be a string or an array of strings';\n case 'fontWeight':\n return (typeof v === 'number' && v >= 1 && v <= 1000) || typeof v === 'string' ? null : 'fontWeight must be 1..1000 or a keyword';\n case 'number':\n return typeof v === 'number' ? null : 'number must be a number';\n case 'shadow': {\n const layers = Array.isArray(v) ? v : [v];\n return layers.every((l) => isObj(l) && 'color' in l && 'offsetX' in l && 'offsetY' in l && 'blur' in l) ? null : 'shadow must be { color, offsetX, offsetY, blur, spread? } or an array of them';\n }\n default:\n return null;\n }\n}\n\n/** DTCG shapes, names, broken and circular aliases (in every mode combination), mode parity, missing layers. */\nexport function validateLayered(set: LayeredTokenSet): LayerIssue[] {\n const issues: LayerIssue[] = [...set.issues];\n for (const d of set.defs) {\n if (d.type && !DTCG_TYPES.has(d.type)) issues.push({ level: 'error', code: 'unknown-type', message: `Unknown $type \"${d.type}\".`, path: d.path, file: d.file });\n if (d.type) {\n const s = checkShape(d.type, d.value);\n if (s) issues.push({ level: s.startsWith('warn:') ? 'warning' : 'error', code: 'invalid-value', message: s.replace(/^warn:/, ''), path: d.path, file: d.file });\n }\n }\n // Aliases and types per combo, merged so one broken alias is reported once with the modes it breaks in.\n const merged = new Map<string, LayerIssue>();\n const add = (i: LayerIssue, combo: Combo) => {\n const k = `${i.code}|${i.path}|${i.message}`;\n const prev = merged.get(k);\n if (prev) prev.modes!.push(comboKey(combo));\n else merged.set(k, { ...i, modes: [comboKey(combo)] });\n };\n for (const combo of set.combos()) {\n for (const miss of set.missingLayers(combo)) add({ level: 'error', code: 'missing-layer', message: `No file matches layer \"${miss}\".` }, combo);\n for (const [path, defs] of set.view(combo)) {\n const r = set.resolve(path, combo);\n const def = defs[defs.length - 1]!;\n if (r.error) add({ level: 'error', code: r.error.startsWith('circular') ? 'circular-alias' : 'broken-alias', message: r.error, path, file: def.file }, combo);\n else if (!r.type) add({ level: 'error', code: 'missing-type', message: 'No $type on the token, its groups or its alias target.', path, file: def.file }, combo);\n else if (def.type && aliasOf(def.value)) {\n const target = set.view(combo).get(aliasOf(def.value)!);\n const tt = target?.[target.length - 1]?.type;\n if (tt && tt !== def.type) add({ level: 'error', code: 'type-mismatch', message: `$type ${def.type} aliases a ${tt} token (${String(def.value)}).`, path, file: def.file }, combo);\n }\n }\n }\n const total = set.combos().length;\n for (const i of merged.values()) {\n if (i.modes!.length === total) delete i.modes;\n issues.push(i);\n }\n issues.push(...layeredParityIssues(set));\n return issues;\n}\n\n/** For modes with parity, every layer file that varies by that mode must define the same token paths. */\nexport function layeredParityIssues(set: LayeredTokenSet): LayerIssue[] {\n const out: LayerIssue[] = [];\n const pathsOf = (file: string) => new Set(set.defs.filter((d) => d.file === file).map((d) => d.path));\n for (const [mode, m] of Object.entries(set.config.axes)) {\n if (!m.parity) continue;\n for (const layer of set.config.tokens.layers) {\n // Optional layers are partial overrides by design (a brand overriding a few light tokens only).\n if (!layer.files.includes(`{${mode}}`) || layer.optional) continue;\n // Hold the other placeholders fixed at each of their values.\n const others = (layer.files.match(/\\{([^}]+)\\}/g) ?? []).map((p) => p.slice(1, -1)).filter((k) => k !== mode);\n let fixed: Combo[] = [{}];\n for (const o of others) fixed = fixed.flatMap((c) => (set.config.axes[o]?.values ?? []).map((v) => ({ ...c, [o]: v })));\n for (const c of fixed) {\n const filesByValue = m.values.map((v) => {\n const re = globToRegExp(layer.files.replace(/\\{([^}]+)\\}/g, (_, k: string) => (k === mode ? v : c[k]!)));\n return { v, files: set.fileNames.filter((f) => re.test(f)) };\n });\n const present = filesByValue.filter((x) => x.files.length);\n if (!present.length) continue;\n for (const x of filesByValue) {\n if (!x.files.length) out.push({ level: 'error', code: 'mode-parity', message: `${mode} \"${x.v}\" has no file for layer \"${layer.files}\" while ${present.map((p) => p.v).join(', ')} do.` });\n }\n const sets = present.map((x) => ({ v: x.v, files: x.files, paths: new Set(x.files.flatMap((f) => [...pathsOf(f)])) }));\n const union = new Set(sets.flatMap((s) => [...s.paths]));\n for (const p of union) {\n const lacking = sets.filter((s) => !s.paths.has(p));\n if (lacking.length) {\n const having = sets.find((s) => s.paths.has(p))!;\n out.push({ level: 'error', code: 'mode-parity', message: `Defined for ${mode} ${sets.filter((s) => s.paths.has(p)).map((s) => s.v).join(', ')} but not ${lacking.map((s) => s.v).join(', ')} (${lacking.map((s) => s.files.join(', ')).join('; ')}).`, path: p, file: having.files[0]! });\n }\n }\n }\n }\n }\n return out;\n}\n"],"names":["targetOf"],"mappings":"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"}
|