// Standalone test of the BOM bundle-image compositor with synthetic product photos. // Usage: node --experimental-strip-types reference/test-scripts/bundle-image-compose.mts import sharp from 'sharp' import { writeFile } from 'node:fs/promises' import { composeBundleImage, expandTiles, layoutCells, normalizePlan, hasRealTransparency } from '../../server/utils/products/bundleImageCompose.ts' const out = process.argv[2] // synthetic "product photos": opaque studio shot (white bg + coloured object) and a transparent cut-out const studio = async (color: string, w = 900, h = 700) => sharp(Buffer.from(``)).jpeg().toBuffer() const cutout = async (color: string, s = 600) => sharp(Buffer.from(``)).png().toBuffer() const a = await studio('#d97706'), b = await studio('#2563eb', 700, 900), c = await cutout('#16a34a') console.log('transparency:', await hasRealTransparency(a), await hasRealTransparency(c)) const mk = (index, name, value, qty, buffer, opaque) => ({ index, name, value, qty, buffer, opaque }) // case 1: small bundle → repeated tiles (2+3+1 = 6) let r = await composeBundleImage([mk(1,'Tasse','TAS-1',2,a,true), mk(2,'Flasche','FLA-2',3,b,true), mk(3,'Ball','BAL-3',1,c,false)], null) await writeFile(out + '/case1.jpg', r.buffer); console.log('case1', r.tiles, r.repeated) // case 2: big quantities → badges, gradient plan, placeholder for a missing photo r = await composeBundleImage([mk(1,'Tasse','TAS-1',10,a,true), mk(2,'Flasche','FLA-2',24,b,true), mk(3,'Ball','BAL-3',1,c,false), mk(4,'Karton ohne Foto','KAR-4',2.5,null,true)], { background: { type: 'gradient', colors: ['#fde68a', '#f59e0b'], angle: 135 }, accent: '#7c2d12', arrangement: 'grid', tileCard: true, components: [] }) await writeFile(out + '/case2.jpg', r.buffer); console.log('case2', r.tiles, r.repeated) // case 3: single component qty 1 and a row of 3 r = await composeBundleImage([mk(1,'Ball','BAL-3',1,c,false)], { background: { type: 'solid', colors: ['#0f172a'] }, accent: '#38bdf8', tileCard: false, components: [] }) await writeFile(out + '/case3.jpg', r.buffer); console.log('case3', r.tiles) r = await composeBundleImage([mk(1,'A','A',1,a,true), mk(2,'B','B',1,b,true), mk(3,'C','C',1,c,false)], { arrangement: 'row', components: [] }) await writeFile(out + '/case4.jpg', r.buffer); console.log('case4', r.tiles) console.log('layout 7:', layoutCells(7, 'grid').map(c => `${c.x},${c.y}:${c.size}`).join(' ')) console.log('plan norm:', JSON.stringify(normalizePlan({ accent: 'red', background: { colors: ['#FFFFFF'] }, components: [{ index: 2, trim: false }] }, 2)))