Files
homepage/scripts/generate-loyalty-cards.ts
T
Alexander 0ab98690eb feat(shopping): loyalty-card modal with build-time barcodes
Adds a CreditCard button on the shopping list that opens a modal
showing the user's Coop Supercard (Data Matrix) and Migros Cumulus
(Code 128). Card numbers come from SHOPPING_COOP_SUPERCARD_NUMBER
and SHOPPING_MIGROS_CUMULUS_NUMBER env vars; a prebuild script
renders each to an SVG (~1-2 kB) in static/shopping/ so no barcode
library ships to the client. Cards missing their env var are
silently skipped, and the generated SVGs are gitignored to keep
personal numbers out of the repo.
2026-04-23 16:21:15 +02:00

57 lines
1.7 KiB
TypeScript

/**
* Build-time generation of loyalty-card barcode SVGs.
*
* Reads card numbers from env vars and writes static/shopping/supercard.svg
* + static/shopping/cumulus.svg. Skips cards whose env var is unset so the
* site still builds in environments without secrets.
*
* SHOPPING_COOP_SUPERCARD_NUMBER → Data Matrix (Coop Supercard)
* SHOPPING_MIGROS_CUMULUS_NUMBER → Code 128 (Migros Cumulus)
*
* Run: pnpm exec vite-node scripts/generate-loyalty-cards.ts
*/
import { mkdirSync, writeFileSync, rmSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { toSVG } from 'bwip-js/node';
const HERE = dirname(fileURLToPath(import.meta.url));
const OUT_DIR = resolve(HERE, '..', 'static', 'shopping');
type CardSpec = {
envVar: string;
filename: string;
bcid: 'datamatrix' | 'code128';
scale: number;
};
const cards: CardSpec[] = [
{ envVar: 'SHOPPING_COOP_SUPERCARD_NUMBER', filename: 'supercard.svg', bcid: 'datamatrix', scale: 6 },
{ envVar: 'SHOPPING_MIGROS_CUMULUS_NUMBER', filename: 'cumulus.svg', bcid: 'code128', scale: 3 }
];
mkdirSync(OUT_DIR, { recursive: true });
for (const card of cards) {
const value = process.env[card.envVar]?.trim();
const outPath = resolve(OUT_DIR, card.filename);
if (!value) {
try { rmSync(outPath); } catch { /* not present */ }
console.log(`[loyalty-cards] ${card.envVar} not set — skipped ${card.filename}`);
continue;
}
const svg = toSVG({
bcid: card.bcid,
text: value,
scale: card.scale,
includetext: false,
paddingwidth: 8,
paddingheight: 8
});
writeFileSync(outPath, svg, 'utf8');
console.log(`[loyalty-cards] wrote ${card.filename} (${card.bcid})`);
}