@hyperframes/core 0.7.27 → 0.7.29
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/compiler/compositionScoping.d.ts.map +1 -1
- package/dist/compiler/compositionScoping.js +13 -0
- package/dist/compiler/compositionScoping.js.map +1 -1
- package/dist/compiler/inlineSubCompositions.d.ts.map +1 -1
- package/dist/compiler/inlineSubCompositions.js +10 -0
- package/dist/compiler/inlineSubCompositions.js.map +1 -1
- package/dist/figma/assetSnippet.d.ts +3 -0
- package/dist/figma/assetSnippet.d.ts.map +1 -0
- package/dist/figma/assetSnippet.js +18 -0
- package/dist/figma/assetSnippet.js.map +1 -0
- package/dist/figma/bindings.d.ts +38 -0
- package/dist/figma/bindings.d.ts.map +1 -0
- package/dist/figma/bindings.js +84 -0
- package/dist/figma/bindings.js.map +1 -0
- package/dist/figma/client.d.ts +67 -0
- package/dist/figma/client.d.ts.map +1 -0
- package/dist/figma/client.js +134 -0
- package/dist/figma/client.js.map +1 -0
- package/dist/figma/color.d.ts +3 -0
- package/dist/figma/color.d.ts.map +1 -0
- package/dist/figma/color.js +23 -0
- package/dist/figma/color.js.map +1 -0
- package/dist/figma/emitTimelineScript.d.ts +3 -0
- package/dist/figma/emitTimelineScript.d.ts.map +1 -0
- package/dist/figma/emitTimelineScript.js +42 -0
- package/dist/figma/emitTimelineScript.js.map +1 -0
- package/dist/figma/freeze.d.ts +16 -0
- package/dist/figma/freeze.d.ts.map +1 -0
- package/dist/figma/freeze.js +67 -0
- package/dist/figma/freeze.js.map +1 -0
- package/dist/figma/index.d.ts +21 -0
- package/dist/figma/index.d.ts.map +1 -0
- package/dist/figma/index.js +15 -0
- package/dist/figma/index.js.map +1 -0
- package/dist/figma/jsonl.d.ts +3 -0
- package/dist/figma/jsonl.d.ts.map +1 -0
- package/dist/figma/jsonl.js +22 -0
- package/dist/figma/jsonl.js.map +1 -0
- package/dist/figma/manifest.d.ts +17 -0
- package/dist/figma/manifest.d.ts.map +1 -0
- package/dist/figma/manifest.js +96 -0
- package/dist/figma/manifest.js.map +1 -0
- package/dist/figma/motionEase.d.ts +3 -0
- package/dist/figma/motionEase.d.ts.map +1 -0
- package/dist/figma/motionEase.js +45 -0
- package/dist/figma/motionEase.js.map +1 -0
- package/dist/figma/motionToGsap.d.ts +3 -0
- package/dist/figma/motionToGsap.d.ts.map +1 -0
- package/dist/figma/motionToGsap.js +61 -0
- package/dist/figma/motionToGsap.js.map +1 -0
- package/dist/figma/nodeDocument.d.ts +4 -0
- package/dist/figma/nodeDocument.d.ts.map +1 -0
- package/dist/figma/nodeDocument.js +26 -0
- package/dist/figma/nodeDocument.js.map +1 -0
- package/dist/figma/nodeToHtml.d.ts +31 -0
- package/dist/figma/nodeToHtml.d.ts.map +1 -0
- package/dist/figma/nodeToHtml.js +244 -0
- package/dist/figma/nodeToHtml.js.map +1 -0
- package/dist/figma/parseFigmaRef.d.ts +3 -0
- package/dist/figma/parseFigmaRef.d.ts.map +1 -0
- package/dist/figma/parseFigmaRef.js +31 -0
- package/dist/figma/parseFigmaRef.js.map +1 -0
- package/dist/figma/resolveBindings.d.ts +31 -0
- package/dist/figma/resolveBindings.d.ts.map +1 -0
- package/dist/figma/resolveBindings.js +77 -0
- package/dist/figma/resolveBindings.js.map +1 -0
- package/dist/figma/sanitizeSvg.d.ts +18 -0
- package/dist/figma/sanitizeSvg.d.ts.map +1 -0
- package/dist/figma/sanitizeSvg.js +52 -0
- package/dist/figma/sanitizeSvg.js.map +1 -0
- package/dist/figma/tokensToVariables.d.ts +40 -0
- package/dist/figma/tokensToVariables.d.ts.map +1 -0
- package/dist/figma/tokensToVariables.js +118 -0
- package/dist/figma/tokensToVariables.js.map +1 -0
- package/dist/figma/types.d.ts +81 -0
- package/dist/figma/types.d.ts.map +1 -0
- package/dist/figma/types.js +2 -0
- package/dist/figma/types.js.map +1 -0
- package/dist/generated/runtime-inline.js +1 -1
- package/dist/generated/runtime-inline.js.map +1 -1
- package/dist/hyperframe.runtime.iife.js +19 -19
- package/package.json +8 -4
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 3 mapper: figma node tree → editable HTML with inline styles
|
|
3
|
+
* (design spec §7, hybrid fidelity routing).
|
|
4
|
+
*
|
|
5
|
+
* - Geometry is exact for free: absolute positioning at figma bounds inside
|
|
6
|
+
* a fixed-size root — no responsive reflow, no drift.
|
|
7
|
+
* - CSS where CSS is faithful: solid/linear-gradient fills, corner radius,
|
|
8
|
+
* opacity, drop shadow, blur, text styles.
|
|
9
|
+
* - Everything CSS can't match faithfully (vectors, boolean ops, exotic
|
|
10
|
+
* paint) routes to the rasterize list — the caller exports those nodes as
|
|
11
|
+
* images (Phase 1) and fills in the placeholder src.
|
|
12
|
+
* - Bindings (§7.1): resolved sites emit var(--slug, literal) so a brand
|
|
13
|
+
* refresh propagates; unresolved sites bake the literal and carry a
|
|
14
|
+
* data-figma-unresolved flag. Never a dangling var().
|
|
15
|
+
* - visible:false nodes and fills are skipped — figma's own renderer
|
|
16
|
+
* semantics, not ours.
|
|
17
|
+
*/
|
|
18
|
+
import { figmaColorToCss } from "./color.js";
|
|
19
|
+
import { childDocuments } from "./nodeDocument.js";
|
|
20
|
+
const RASTERIZE_TYPES = new Set([
|
|
21
|
+
"VECTOR",
|
|
22
|
+
"BOOLEAN_OPERATION",
|
|
23
|
+
"STAR",
|
|
24
|
+
"LINE",
|
|
25
|
+
"POLYGON",
|
|
26
|
+
"REGULAR_POLYGON",
|
|
27
|
+
]);
|
|
28
|
+
function isRecord(value) {
|
|
29
|
+
return typeof value === "object" && value !== null;
|
|
30
|
+
}
|
|
31
|
+
function boxOf(node) {
|
|
32
|
+
const b = node.absoluteBoundingBox;
|
|
33
|
+
if (isRecord(b) &&
|
|
34
|
+
typeof b.x === "number" &&
|
|
35
|
+
typeof b.y === "number" &&
|
|
36
|
+
typeof b.width === "number" &&
|
|
37
|
+
typeof b.height === "number")
|
|
38
|
+
return { x: b.x, y: b.y, width: b.width, height: b.height };
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
export function slugify(name) {
|
|
42
|
+
const slug = name
|
|
43
|
+
.toLowerCase()
|
|
44
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
45
|
+
.replace(/^-+|-+$/g, "");
|
|
46
|
+
return slug.length > 0 ? slug : "node";
|
|
47
|
+
}
|
|
48
|
+
function cssVarName(compositionVariableId) {
|
|
49
|
+
return `--${slugify(compositionVariableId)}`;
|
|
50
|
+
}
|
|
51
|
+
function escapeHtml(text) {
|
|
52
|
+
return text
|
|
53
|
+
.replace(/&/g, "&")
|
|
54
|
+
.replace(/</g, "<")
|
|
55
|
+
.replace(/>/g, ">")
|
|
56
|
+
.replace(/"/g, """);
|
|
57
|
+
}
|
|
58
|
+
function round(n) {
|
|
59
|
+
return Math.round(n * 100) / 100;
|
|
60
|
+
}
|
|
61
|
+
function firstVisibleFill(node) {
|
|
62
|
+
const fills = node.fills;
|
|
63
|
+
if (!Array.isArray(fills))
|
|
64
|
+
return null;
|
|
65
|
+
for (const fill of fills) {
|
|
66
|
+
if (isRecord(fill) && fill.visible !== false)
|
|
67
|
+
return fill;
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
function gradientCss(fill) {
|
|
72
|
+
const stops = fill.gradientStops;
|
|
73
|
+
if (!Array.isArray(stops))
|
|
74
|
+
return null;
|
|
75
|
+
const parts = [];
|
|
76
|
+
for (const stop of stops) {
|
|
77
|
+
if (!isRecord(stop) || typeof stop.position !== "number")
|
|
78
|
+
return null;
|
|
79
|
+
const color = figmaColorToCss(stop.color);
|
|
80
|
+
if (color === null)
|
|
81
|
+
return null;
|
|
82
|
+
parts.push(`${color} ${round(stop.position * 100)}%`);
|
|
83
|
+
}
|
|
84
|
+
if (parts.length === 0)
|
|
85
|
+
return null;
|
|
86
|
+
// ponytail: fixed 180deg; exact angle from gradientHandlePositions when the
|
|
87
|
+
// probe confirms the handle-space math (spec §7.1 probe list).
|
|
88
|
+
return `linear-gradient(180deg, ${parts.join(", ")})`;
|
|
89
|
+
}
|
|
90
|
+
function fillCss(node) {
|
|
91
|
+
const fill = firstVisibleFill(node);
|
|
92
|
+
if (fill === null)
|
|
93
|
+
return null;
|
|
94
|
+
if (fill.type === "SOLID")
|
|
95
|
+
return figmaColorToCss(fill.color);
|
|
96
|
+
if (fill.type === "GRADIENT_LINEAR")
|
|
97
|
+
return gradientCss(fill);
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
function dropShadowCss(effect) {
|
|
101
|
+
if (!isRecord(effect.offset))
|
|
102
|
+
return null;
|
|
103
|
+
const color = figmaColorToCss(effect.color);
|
|
104
|
+
const { x, y } = effect.offset;
|
|
105
|
+
if (color === null || typeof x !== "number" || typeof y !== "number")
|
|
106
|
+
return null;
|
|
107
|
+
const radius = typeof effect.radius === "number" ? effect.radius : 0;
|
|
108
|
+
return `box-shadow: ${round(x)}px ${round(y)}px ${round(radius)}px ${color}`;
|
|
109
|
+
}
|
|
110
|
+
function effectCss(effect) {
|
|
111
|
+
if (!isRecord(effect) || effect.visible === false)
|
|
112
|
+
return null;
|
|
113
|
+
if (effect.type === "DROP_SHADOW")
|
|
114
|
+
return dropShadowCss(effect);
|
|
115
|
+
if (effect.type === "LAYER_BLUR" && typeof effect.radius === "number")
|
|
116
|
+
return `filter: blur(${round(effect.radius)}px)`;
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
function effectsCss(node, styles) {
|
|
120
|
+
const effects = node.effects;
|
|
121
|
+
if (!Array.isArray(effects))
|
|
122
|
+
return;
|
|
123
|
+
for (const effect of effects) {
|
|
124
|
+
const css = effectCss(effect);
|
|
125
|
+
if (css !== null)
|
|
126
|
+
styles.push(css);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function textCss(node, styles) {
|
|
130
|
+
const s = node.style;
|
|
131
|
+
if (!isRecord(s))
|
|
132
|
+
return;
|
|
133
|
+
// fontFamily is the one content-controlled string that reaches CSS — strip
|
|
134
|
+
// quote/escape chars so it can't break out of the font-family value (the
|
|
135
|
+
// whole style attribute is additionally HTML-escaped at emission).
|
|
136
|
+
if (typeof s.fontFamily === "string")
|
|
137
|
+
styles.push(`font-family: '${s.fontFamily.replace(/['"\\;]/g, "")}'`);
|
|
138
|
+
if (typeof s.fontWeight === "number")
|
|
139
|
+
styles.push(`font-weight: ${s.fontWeight}`);
|
|
140
|
+
if (typeof s.fontSize === "number")
|
|
141
|
+
styles.push(`font-size: ${round(s.fontSize)}px`);
|
|
142
|
+
if (typeof s.lineHeightPx === "number")
|
|
143
|
+
styles.push(`line-height: ${round(s.lineHeightPx)}px`);
|
|
144
|
+
if (typeof s.letterSpacing === "number" && s.letterSpacing !== 0)
|
|
145
|
+
styles.push(`letter-spacing: ${round(s.letterSpacing)}px`);
|
|
146
|
+
}
|
|
147
|
+
function uniqueSlug(ctx, name) {
|
|
148
|
+
const base = slugify(name);
|
|
149
|
+
let slug = base;
|
|
150
|
+
let n = 2;
|
|
151
|
+
while (ctx.usedSlugs.has(slug))
|
|
152
|
+
slug = `${base}-${n++}`;
|
|
153
|
+
ctx.usedSlugs.add(slug);
|
|
154
|
+
return slug;
|
|
155
|
+
}
|
|
156
|
+
function backgroundValue(node, ctx) {
|
|
157
|
+
const literal = fillCss(node);
|
|
158
|
+
if (literal === null)
|
|
159
|
+
return null;
|
|
160
|
+
const resolved = ctx.bindings.resolved.find((r) => r.nodeId === node.id && r.property === "fills");
|
|
161
|
+
if (resolved)
|
|
162
|
+
return `var(${cssVarName(resolved.compositionVariableId)}, ${literal})`;
|
|
163
|
+
return literal;
|
|
164
|
+
}
|
|
165
|
+
function unresolvedAttr(node, ctx) {
|
|
166
|
+
const props = ctx.bindings.unresolved.filter((u) => u.nodeId === node.id).map((u) => u.property);
|
|
167
|
+
if (props.length === 0)
|
|
168
|
+
return "";
|
|
169
|
+
return ` data-figma-unresolved="${escapeHtml(props.join(" "))}"`;
|
|
170
|
+
}
|
|
171
|
+
function geometryCss(node, ctx, isRoot) {
|
|
172
|
+
const box = boxOf(node);
|
|
173
|
+
const styles = [];
|
|
174
|
+
if (!box)
|
|
175
|
+
return styles;
|
|
176
|
+
if (isRoot) {
|
|
177
|
+
styles.push("position: relative", `width: ${round(box.width)}px`, `height: ${round(box.height)}px`);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
styles.push("position: absolute", `left: ${round(box.x - ctx.origin.x)}px`, `top: ${round(box.y - ctx.origin.y)}px`, `width: ${round(box.width)}px`, `height: ${round(box.height)}px`);
|
|
181
|
+
}
|
|
182
|
+
return styles;
|
|
183
|
+
}
|
|
184
|
+
function decorationCss(node, ctx) {
|
|
185
|
+
const styles = [];
|
|
186
|
+
// backgroundValue is the binding-aware path (var(--slug, literal)) — TEXT
|
|
187
|
+
// color goes through it too, so a token-bound text fill keeps its link.
|
|
188
|
+
const bg = backgroundValue(node, ctx);
|
|
189
|
+
if (node.type === "TEXT") {
|
|
190
|
+
if (bg !== null)
|
|
191
|
+
styles.push(`color: ${bg}`);
|
|
192
|
+
textCss(node, styles);
|
|
193
|
+
}
|
|
194
|
+
else if (bg !== null) {
|
|
195
|
+
styles.push(`background: ${bg}`);
|
|
196
|
+
}
|
|
197
|
+
if (node.type === "ELLIPSE") {
|
|
198
|
+
styles.push("border-radius: 50%");
|
|
199
|
+
}
|
|
200
|
+
else if (typeof node.cornerRadius === "number" && node.cornerRadius > 0) {
|
|
201
|
+
styles.push(`border-radius: ${round(node.cornerRadius)}px`);
|
|
202
|
+
}
|
|
203
|
+
if (node.clipsContent === true)
|
|
204
|
+
styles.push("overflow: hidden");
|
|
205
|
+
if (typeof node.opacity === "number" && node.opacity < 1)
|
|
206
|
+
styles.push(`opacity: ${round(node.opacity)}`);
|
|
207
|
+
effectsCss(node, styles);
|
|
208
|
+
return styles;
|
|
209
|
+
}
|
|
210
|
+
// ponytail: depth cap so a runaway auto-generated tree degrades to a skip
|
|
211
|
+
// instead of a RangeError; real figma frames are nowhere near this deep.
|
|
212
|
+
const MAX_DEPTH = 500;
|
|
213
|
+
function renderChildren(node, ctx, depth) {
|
|
214
|
+
const childHtml = [];
|
|
215
|
+
for (const child of childDocuments(node)) {
|
|
216
|
+
const rendered = renderNodeHtml(child, ctx, false, depth + 1);
|
|
217
|
+
if (rendered.length > 0)
|
|
218
|
+
childHtml.push(rendered);
|
|
219
|
+
}
|
|
220
|
+
return childHtml.length > 0 ? `\n${childHtml.join("\n")}\n` : "";
|
|
221
|
+
}
|
|
222
|
+
function renderNodeHtml(node, ctx, isRoot, depth = 0) {
|
|
223
|
+
if (node.visible === false || depth > MAX_DEPTH)
|
|
224
|
+
return "";
|
|
225
|
+
const slug = uniqueSlug(ctx, node.name);
|
|
226
|
+
const style = escapeHtml([...geometryCss(node, ctx, isRoot), ...decorationCss(node, ctx)].join("; "));
|
|
227
|
+
const idAttrs = `id="${slug}" data-figma-id="${escapeHtml(node.id)}"${unresolvedAttr(node, ctx)}`;
|
|
228
|
+
if (RASTERIZE_TYPES.has(node.type)) {
|
|
229
|
+
ctx.rasterize.push({ nodeId: node.id, name: node.name, slug });
|
|
230
|
+
return `<img ${idAttrs} data-figma-rasterize="${escapeHtml(node.id)}" alt="${escapeHtml(node.name)}" style="${style}" />`;
|
|
231
|
+
}
|
|
232
|
+
if (node.type === "TEXT") {
|
|
233
|
+
const text = typeof node.characters === "string" ? escapeHtml(node.characters) : "";
|
|
234
|
+
return `<div ${idAttrs} style="${style}">${text}</div>`;
|
|
235
|
+
}
|
|
236
|
+
return `<div ${idAttrs} style="${style}">${renderChildren(node, ctx, depth)}</div>`;
|
|
237
|
+
}
|
|
238
|
+
export function nodeToHtml(root, bindings) {
|
|
239
|
+
const origin = boxOf(root) ?? { x: 0, y: 0, width: 0, height: 0 };
|
|
240
|
+
const ctx = { origin, bindings, rasterize: [], usedSlugs: new Set() };
|
|
241
|
+
const html = renderNodeHtml(root, ctx, true);
|
|
242
|
+
return { html, rasterize: ctx.rasterize };
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=nodeToHtml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeToHtml.js","sourceRoot":"","sources":["../../src/figma/nodeToHtml.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseFigmaRef.d.ts","sourceRoot":"","sources":["../../src/figma/parseFigmaRef.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQxC,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAuBrD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const FILE_KEY_RE = /\/(?:design|file|proto)\/([A-Za-z0-9]+)/;
|
|
2
|
+
function normalizeNodeId(raw) {
|
|
3
|
+
return raw.replaceAll("-", ":");
|
|
4
|
+
}
|
|
5
|
+
export function parseFigmaRef(input) {
|
|
6
|
+
const trimmed = input.trim();
|
|
7
|
+
if (trimmed.length === 0)
|
|
8
|
+
throw new Error("parseFigmaRef: empty input");
|
|
9
|
+
if (!trimmed.includes("/")) {
|
|
10
|
+
const colon = trimmed.indexOf(":");
|
|
11
|
+
if (colon === -1)
|
|
12
|
+
return { fileKey: trimmed };
|
|
13
|
+
const fileKey = trimmed.slice(0, colon);
|
|
14
|
+
const node = trimmed.slice(colon + 1);
|
|
15
|
+
if (fileKey.length === 0)
|
|
16
|
+
throw new Error(`parseFigmaRef: invalid ref "${input}"`);
|
|
17
|
+
return node.length > 0 ? { fileKey, nodeId: normalizeNodeId(node) } : { fileKey };
|
|
18
|
+
}
|
|
19
|
+
const keyMatch = trimmed.match(FILE_KEY_RE);
|
|
20
|
+
const fileKey = keyMatch?.[1];
|
|
21
|
+
if (fileKey === undefined)
|
|
22
|
+
throw new Error(`parseFigmaRef: no fileKey in "${input}"`);
|
|
23
|
+
const q = trimmed.indexOf("?");
|
|
24
|
+
if (q !== -1) {
|
|
25
|
+
const raw = new URLSearchParams(trimmed.slice(q + 1)).get("node-id");
|
|
26
|
+
if (raw !== null && raw.length > 0)
|
|
27
|
+
return { fileKey, nodeId: normalizeNodeId(raw) };
|
|
28
|
+
}
|
|
29
|
+
return { fileKey };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=parseFigmaRef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseFigmaRef.js","sourceRoot":"","sources":["../../src/figma/parseFigmaRef.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,yCAAyC,CAAC;AAE9D,SAAS,eAAe,CAAC,GAAW;IAClC,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAExE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,GAAG,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;IACpF,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,GAAG,CAAC,CAAC;IAEtF,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACrE,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;IACvF,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binding resolution pass (design spec §7.1): scan a node tree's complete
|
|
3
|
+
* binding set — boundVariables and style ids, alias chains honored — and
|
|
4
|
+
* partition against the binding index BEFORE any CSS is emitted.
|
|
5
|
+
*
|
|
6
|
+
* Exact-ID matching only. A missed link bakes a visually-correct literal;
|
|
7
|
+
* a wrong link silently changes color at the next brand refresh. Never
|
|
8
|
+
* match by value or name.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: the consumer-side boundVariables shape is probe-flagged in the spec
|
|
11
|
+
* (§7.1 pre-build probes). Extraction here is tolerant: single alias objects
|
|
12
|
+
* and arrays of alias objects both count; unknown shapes are ignored rather
|
|
13
|
+
* than guessed at.
|
|
14
|
+
*/
|
|
15
|
+
import type { FigmaBindingRecord } from "./bindings";
|
|
16
|
+
import type { FigmaNodeDocument } from "./client";
|
|
17
|
+
export interface BindingSite {
|
|
18
|
+
nodeId: string;
|
|
19
|
+
/** boundVariables property ("fills") or style slot prefixed "style:" ("style:text") */
|
|
20
|
+
property: string;
|
|
21
|
+
figmaId: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ResolvedBindingSite extends BindingSite {
|
|
24
|
+
compositionVariableId: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ResolveBindingsResult {
|
|
27
|
+
resolved: ResolvedBindingSite[];
|
|
28
|
+
unresolved: BindingSite[];
|
|
29
|
+
}
|
|
30
|
+
export declare function resolveBindings(node: FigmaNodeDocument, index: FigmaBindingRecord[]): ResolveBindingsResult;
|
|
31
|
+
//# sourceMappingURL=resolveBindings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveBindings.d.ts","sourceRoot":"","sources":["../../src/figma/resolveBindings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGlD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,UAAU,EAAE,WAAW,EAAE,CAAC;CAC3B;AAgDD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,kBAAkB,EAAE,GAC1B,qBAAqB,CAYvB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binding resolution pass (design spec §7.1): scan a node tree's complete
|
|
3
|
+
* binding set — boundVariables and style ids, alias chains honored — and
|
|
4
|
+
* partition against the binding index BEFORE any CSS is emitted.
|
|
5
|
+
*
|
|
6
|
+
* Exact-ID matching only. A missed link bakes a visually-correct literal;
|
|
7
|
+
* a wrong link silently changes color at the next brand refresh. Never
|
|
8
|
+
* match by value or name.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: the consumer-side boundVariables shape is probe-flagged in the spec
|
|
11
|
+
* (§7.1 pre-build probes). Extraction here is tolerant: single alias objects
|
|
12
|
+
* and arrays of alias objects both count; unknown shapes are ignored rather
|
|
13
|
+
* than guessed at.
|
|
14
|
+
*/
|
|
15
|
+
import { childDocuments } from "./nodeDocument.js";
|
|
16
|
+
function isRecord(value) {
|
|
17
|
+
return typeof value === "object" && value !== null;
|
|
18
|
+
}
|
|
19
|
+
function aliasId(value) {
|
|
20
|
+
if (isRecord(value) && value.type === "VARIABLE_ALIAS" && typeof value.id === "string")
|
|
21
|
+
return value.id;
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
function boundVariableSites(node, out) {
|
|
25
|
+
const bound = node.boundVariables;
|
|
26
|
+
if (!isRecord(bound))
|
|
27
|
+
return;
|
|
28
|
+
for (const [property, value] of Object.entries(bound)) {
|
|
29
|
+
const candidates = Array.isArray(value) ? value : [value];
|
|
30
|
+
for (const item of candidates) {
|
|
31
|
+
const id = aliasId(item);
|
|
32
|
+
if (id)
|
|
33
|
+
out.push({ nodeId: node.id, property, figmaId: id });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function styleSites(node, out) {
|
|
38
|
+
const styles = node.styles;
|
|
39
|
+
if (!isRecord(styles))
|
|
40
|
+
return;
|
|
41
|
+
for (const [slot, styleId] of Object.entries(styles)) {
|
|
42
|
+
if (typeof styleId === "string" && styleId.length > 0)
|
|
43
|
+
out.push({ nodeId: node.id, property: `style:${slot}`, figmaId: styleId });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function collectSites(node, out) {
|
|
47
|
+
boundVariableSites(node, out);
|
|
48
|
+
styleSites(node, out);
|
|
49
|
+
for (const child of childDocuments(node))
|
|
50
|
+
collectSites(child, out);
|
|
51
|
+
}
|
|
52
|
+
function findInIndex(index, figmaId) {
|
|
53
|
+
for (const b of index) {
|
|
54
|
+
if (b.figmaId === figmaId)
|
|
55
|
+
return b;
|
|
56
|
+
if (b.aliasChain?.includes(figmaId))
|
|
57
|
+
return b;
|
|
58
|
+
if (b.key !== undefined && b.key === figmaId)
|
|
59
|
+
return b;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
export function resolveBindings(node, index) {
|
|
64
|
+
const sites = [];
|
|
65
|
+
collectSites(node, sites);
|
|
66
|
+
const resolved = [];
|
|
67
|
+
const unresolved = [];
|
|
68
|
+
for (const site of sites) {
|
|
69
|
+
const match = findInIndex(index, site.figmaId);
|
|
70
|
+
if (match)
|
|
71
|
+
resolved.push({ ...site, compositionVariableId: match.compositionVariableId });
|
|
72
|
+
else
|
|
73
|
+
unresolved.push(site);
|
|
74
|
+
}
|
|
75
|
+
return { resolved, unresolved };
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=resolveBindings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveBindings.js","sourceRoot":"","sources":["../../src/figma/resolveBindings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAkBhD,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QACpF,OAAO,KAAK,CAAC,EAAE,CAAC;IAClB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAuB,EAAE,GAAkB;IACrE,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC;IAClC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO;IAC7B,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC1D,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,EAAE;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAuB,EAAE,GAAkB;IAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO;IAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACrD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YACnD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAAuB,EAAE,GAAkB;IAC/D,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC9B,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACtB,KAAK,MAAM,KAAK,IAAI,cAAc,CAAC,IAAI,CAAC;QAAE,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,WAAW,CAAC,KAA2B,EAAE,OAAe;IAC/D,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO;YAAE,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO;YAAE,OAAO,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,IAAuB,EACvB,KAA2B;IAE3B,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE1B,MAAM,QAAQ,GAA0B,EAAE,CAAC;IAC3C,MAAM,UAAU,GAAkB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,KAAK;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,qBAAqB,EAAE,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;;YACrF,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitize a figma-exported SVG before it touches disk (design spec §5).
|
|
3
|
+
*
|
|
4
|
+
* Threat model: figma-SHAPED exports, hardened against the cheap adversarial
|
|
5
|
+
* variants (nesting, unquoted attrs, scheme smuggling). This is a lexical
|
|
6
|
+
* pass, not a general-purpose HTML sanitizer — content from arbitrary
|
|
7
|
+
* untrusted sources should go through a real sanitizer (DOMPurify) instead.
|
|
8
|
+
* Strips:
|
|
9
|
+
* - <script> elements (with content) and <style> blocks (@import exfil)
|
|
10
|
+
* - <foreignObject> subtrees (arbitrary embedded HTML)
|
|
11
|
+
* - on* event-handler attributes (quoted and unquoted)
|
|
12
|
+
* - href/xlink:href values unless local fragment (#id) or data:image/
|
|
13
|
+
*
|
|
14
|
+
* Keeps local fragment refs (#id) and data:image embeds, which figma uses
|
|
15
|
+
* for clip paths and embedded rasters.
|
|
16
|
+
*/
|
|
17
|
+
export declare function sanitizeSvg(svg: string): string;
|
|
18
|
+
//# sourceMappingURL=sanitizeSvg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitizeSvg.d.ts","sourceRoot":"","sources":["../../src/figma/sanitizeSvg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAaH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAwB/C"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitize a figma-exported SVG before it touches disk (design spec §5).
|
|
3
|
+
*
|
|
4
|
+
* Threat model: figma-SHAPED exports, hardened against the cheap adversarial
|
|
5
|
+
* variants (nesting, unquoted attrs, scheme smuggling). This is a lexical
|
|
6
|
+
* pass, not a general-purpose HTML sanitizer — content from arbitrary
|
|
7
|
+
* untrusted sources should go through a real sanitizer (DOMPurify) instead.
|
|
8
|
+
* Strips:
|
|
9
|
+
* - <script> elements (with content) and <style> blocks (@import exfil)
|
|
10
|
+
* - <foreignObject> subtrees (arbitrary embedded HTML)
|
|
11
|
+
* - on* event-handler attributes (quoted and unquoted)
|
|
12
|
+
* - href/xlink:href values unless local fragment (#id) or data:image/
|
|
13
|
+
*
|
|
14
|
+
* Keeps local fragment refs (#id) and data:image embeds, which figma uses
|
|
15
|
+
* for clip paths and embedded rasters.
|
|
16
|
+
*/
|
|
17
|
+
/** Apply a replacement until the output stops changing (defeats nesting). */
|
|
18
|
+
function replaceStable(input, pattern, replacement) {
|
|
19
|
+
let out = input;
|
|
20
|
+
let prev;
|
|
21
|
+
do {
|
|
22
|
+
prev = out;
|
|
23
|
+
out = out.replace(pattern, replacement);
|
|
24
|
+
} while (out !== prev);
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
export function sanitizeSvg(svg) {
|
|
28
|
+
let out = svg;
|
|
29
|
+
out = replaceStable(out, /<script\b[\s\S]*?<\/script\b[^>]*>/gi, "");
|
|
30
|
+
out = replaceStable(out, /<script\b[^>]*\/>/gi, "");
|
|
31
|
+
out = replaceStable(out, /<style\b[\s\S]*?<\/style\b[^>]*>/gi, "");
|
|
32
|
+
out = replaceStable(out, /<foreignObject\b[\s\S]*?<\/foreignObject\b[^>]*>/gi, "");
|
|
33
|
+
out = replaceStable(out, /<foreignObject\b[^>]*\/>/gi, "");
|
|
34
|
+
// Nesting leaves inert orphan close tags after the stable pass — drop them.
|
|
35
|
+
out = out.replace(/<\/(?:script|style|foreignObject)\b[^>]*>/gi, "");
|
|
36
|
+
// on* handler attributes: quoted and unquoted forms.
|
|
37
|
+
out = replaceStable(out, /\son[a-z]+\s*=\s*"[^"]*"/gi, "");
|
|
38
|
+
out = replaceStable(out, /\son[a-z]+\s*=\s*'[^']*'/gi, "");
|
|
39
|
+
out = replaceStable(out, /\son[a-z]+\s*=\s*[^\s>'"]+/gi, "");
|
|
40
|
+
// href-like attributes: POSITIVE allowlist — keep only local fragments and
|
|
41
|
+
// data:image embeds; drop everything else (javascript:, https?:, blob:,
|
|
42
|
+
// vbscript:, data:text/html, protocol-relative, …).
|
|
43
|
+
// xmlns declarations are attribute *names*, not href values — untouched.
|
|
44
|
+
out = out.replace(/\s(href|xlink:href)\s*=\s*"([^"]*)"/gi, (m, attr, value) => isAllowedHref(value) ? m : "");
|
|
45
|
+
out = out.replace(/\s(href|xlink:href)\s*=\s*'([^']*)'/gi, (m, attr, value) => isAllowedHref(value) ? m : "");
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
function isAllowedHref(value) {
|
|
49
|
+
const v = value.trim().toLowerCase();
|
|
50
|
+
return v.startsWith("#") || v.startsWith("data:image/");
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=sanitizeSvg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitizeSvg.js","sourceRoot":"","sources":["../../src/figma/sanitizeSvg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,6EAA6E;AAC7E,SAAS,aAAa,CAAC,KAAa,EAAE,OAAe,EAAE,WAAmB;IACxE,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,IAAI,IAAI,CAAC;IACT,GAAG,CAAC;QACF,IAAI,GAAG,GAAG,CAAC;QACX,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC1C,CAAC,QAAQ,GAAG,KAAK,IAAI,EAAE;IACvB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,sCAAsC,EAAE,EAAE,CAAC,CAAC;IACrE,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;IACpD,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,oCAAoC,EAAE,EAAE,CAAC,CAAC;IACnE,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,oDAAoD,EAAE,EAAE,CAAC,CAAC;IACnF,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,4BAA4B,EAAE,EAAE,CAAC,CAAC;IAC3D,4EAA4E;IAC5E,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,6CAA6C,EAAE,EAAE,CAAC,CAAC;IACrE,qDAAqD;IACrD,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,4BAA4B,EAAE,EAAE,CAAC,CAAC;IAC3D,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,4BAA4B,EAAE,EAAE,CAAC,CAAC;IAC3D,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,8BAA8B,EAAE,EAAE,CAAC,CAAC;IAC7D,2EAA2E;IAC3E,wEAAwE;IACxE,oDAAoD;IACpD,yEAAyE;IACzE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,uCAAuC,EAAE,CAAC,CAAC,EAAE,IAAY,EAAE,KAAa,EAAE,EAAE,CAC5F,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAC9B,CAAC;IACF,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,uCAAuC,EAAE,CAAC,CAAC,EAAE,IAAY,EAAE,KAAa,EAAE,EAAE,CAC5F,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAC9B,CAAC;IACF,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 2 translator: figma variables → composition brand-variable entries,
|
|
3
|
+
* a human-readable sidecar, and binding-index records (design spec §6, §7.1).
|
|
4
|
+
*
|
|
5
|
+
* Pure — REST payload in, artifacts out. Alias chains are walked to the leaf
|
|
6
|
+
* value (cycle-safe) but the binding records the semantic id the designer
|
|
7
|
+
* bound, so a swapped primitive doesn't orphan the link.
|
|
8
|
+
*/
|
|
9
|
+
import type { FigmaVariablesResult } from "./client";
|
|
10
|
+
import type { FigmaBindingRecord } from "./bindings";
|
|
11
|
+
/** data-composition-variables entry (runtime getVariables contract). */
|
|
12
|
+
export interface CompositionVariableEntry {
|
|
13
|
+
id: string;
|
|
14
|
+
type: "string" | "number" | "color" | "boolean";
|
|
15
|
+
label: string;
|
|
16
|
+
default: string | number | boolean;
|
|
17
|
+
brandRole?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface FigmaTokenSidecarEntry {
|
|
20
|
+
name: string;
|
|
21
|
+
type: string;
|
|
22
|
+
figmaId: string;
|
|
23
|
+
key?: string;
|
|
24
|
+
value: string | number | boolean | null;
|
|
25
|
+
}
|
|
26
|
+
export interface FigmaTokensSidecar {
|
|
27
|
+
source: TokenSource;
|
|
28
|
+
tokens: FigmaTokenSidecarEntry[];
|
|
29
|
+
}
|
|
30
|
+
export interface TokenSource {
|
|
31
|
+
fileKey: string;
|
|
32
|
+
version: string;
|
|
33
|
+
}
|
|
34
|
+
export interface TokensToVariablesResult {
|
|
35
|
+
entries: CompositionVariableEntry[];
|
|
36
|
+
bindings: FigmaBindingRecord[];
|
|
37
|
+
sidecar: FigmaTokensSidecar;
|
|
38
|
+
}
|
|
39
|
+
export declare function tokensToVariables(vars: FigmaVariablesResult, source: TokenSource): TokensToVariablesResult;
|
|
40
|
+
//# sourceMappingURL=tokensToVariables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokensToVariables.d.ts","sourceRoot":"","sources":["../../src/figma/tokensToVariables.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAwB,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD,wEAAwE;AACxE,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,sBAAsB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,OAAO,EAAE,kBAAkB,CAAC;CAC7B;AA4ED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,WAAW,GAClB,uBAAuB,CAgDzB"}
|