Skip to content

Commit 5cfbdab

Browse files
willwadeclaude
andcommitted
fix: browser base64 encoding for Snap image data
When loading TD Snap (.sps) files client-side in browser, sql.js returns image data as Uint8Array not Node.js Buffer. Uint8Array's toString() method doesn't accept 'base64' encoding parameter like Buffer does, so it was converting bytes to comma-separated decimal values instead of proper base64 encoding. Added arrayBufferToBase64() helper that works in both Node.js and browser environments using the appropriate method for each. Fixes image loading error: src: data:image/png;base64,137,80,78,71,13,10,26... Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 09c1d6b commit 5cfbdab

1 file changed

Lines changed: 22 additions & 1 deletion

File tree

src/processors/snapProcessor.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,27 @@ import { ValidationResult } from '../validation/validationTypes';
2020
import { ProcessorInput, getFs, getNodeRequire, getPath, isNodeRuntime } from '../utils/io';
2121
import { openSqliteDatabase, requireBetterSqlite3 } from '../utils/sqlite';
2222

23+
/**
24+
* Convert a Buffer or Uint8Array to base64 string (browser and Node compatible)
25+
* Node.js Buffers support toString('base64'), but Uint8Arrays in browser do not.
26+
* This function works in both environments.
27+
*/
28+
function arrayBufferToBase64(data: Buffer | Uint8Array): string {
29+
// Node.js environment - Buffer has built-in base64 encoding
30+
if (typeof Buffer !== 'undefined' && data instanceof Buffer) {
31+
return data.toString('base64');
32+
}
33+
34+
// Browser environment - use btoa with binary string conversion
35+
const bytes = new Uint8Array(data);
36+
let binary = '';
37+
const len = bytes.byteLength;
38+
for (let i = 0; i < len; i++) {
39+
binary += String.fromCharCode(bytes[i]);
40+
}
41+
return btoa(binary);
42+
}
43+
2344
interface SnapButton {
2445
Id: number;
2546
Label: string;
@@ -556,7 +577,7 @@ class SnapProcessor extends BaseProcessor {
556577
if (isPng || isJpeg) {
557578
// Actual PNG/JPEG image - can be displayed
558579
const mimeType = isPng ? 'image/png' : 'image/jpeg';
559-
const base64 = data.toString('base64');
580+
const base64 = arrayBufferToBase64(data);
560581
buttonImage = `data:${mimeType};base64,${base64}`;
561582
buttonParameters.image_id = imageData.Identifier;
562583
} else {

0 commit comments

Comments
 (0)