Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,6 @@ Thumbs.db

# local scratch files
plan.md
dummy.png
dummy.png

rules/
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ function parseIgnore(spec: string | undefined): IgnoreRegion {
if (parts.length !== 4 || parts.some((n) => !Number.isFinite(n))) {
fail(`--ignore expects x,y,w,h (got "${spec ?? ""}")`);
}
// SAFETY: the guard above proves parts holds exactly four finite numbers.
const [x, y, width, height] = parts as [number, number, number, number];
return { x, y, width, height };
}
Expand Down
15 changes: 8 additions & 7 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,19 @@ export async function designDiff(opts: DesignDiffOptions): Promise<DesignDiffRes
const metricsPath = join(runDir, "metrics.json");

let box: Geometry;
if (pngPath) {
if (isFigmaSource(opts.design)) {
const { fileKey, frameId } = opts.design;
({ box } = await exportDesignFrame(fileKey, frameId, scale, designPng));
} else {
const localPng = opts.design;
let png: PNG;
try {
png = PNG.sync.read(readFileSync(pngPath));
png = PNG.sync.read(readFileSync(localPng));
} catch {
throw new Error(`${pngPath} is not a readable PNG`);
throw new Error(`${localPng} is not a readable PNG`);
}
copyFileSync(pngPath, designPng);
copyFileSync(localPng, designPng);
box = { x: 0, y: 0, w: png.width / scale, h: png.height / scale };
} else {
const src = opts.design as FigmaSource;
({ box } = await exportDesignFrame(src.fileKey, src.frameId, scale, designPng));
}

let pageWidth: number;
Expand Down
2 changes: 2 additions & 0 deletions src/fetch/figma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ function backoffMs(res: Response, attempt: number): number {
async function figmaGet<T>(path: string, token: string): Promise<T> {
for (let attempt = 0; ; attempt++) {
const res = await fetch(`${FIGMA_API}${path}`, { headers: { "X-Figma-Token": token } });
// SAFETY: these Figma REST endpoints return the fields declared by the caller's response
// type (FigmaNodesResponse / FigmaImagesResponse); every accessed field is guarded downstream.
if (res.ok) return (await res.json()) as T;
const retryable = res.status === 429 || res.status >= 500;
if (!retryable || attempt >= MAX_RETRIES) {
Expand Down
Loading