#!/usr/bin/env node // Prints the image-edit request for the ad art. It calls no API. // Usage: node scripts/build-input.mjs --image https://... --product "amber glass dropper bottle, cream label HALDEN" \ // (--scene "describe the backdrop and props" | --preset skincare|food-pack|tech|apparel|home|supplements) [--format 4:5|1:1|9:16] import { readFileSync } from 'node:fs' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' function parseArgs(argv, known) { const out = {} for (let i = 0; i < argv.length; i += 1) { const k = argv[i] if (!k.startsWith('--')) fail(`Unexpected argument '${k}'.`) const name = k.slice(2) if (!known.includes(name)) fail(`Unknown flag --${name}. Known: ${known.map((x) => '--' + x).join(', ')}`) const v = argv[i + 1] if (v === undefined || v.startsWith('--')) fail(`Flag --${name} needs a value.`) out[name] = v i += 1 } return out } function fail(message) { console.error(message); process.exit(1) } function checkImage(value) { if (!/^https:\/\//.test(value) && !/^data:image\//.test(value)) fail('--image must be a public https URL or an image data URI.') } const root = join(dirname(fileURLToPath(import.meta.url)), '..') const o = parseArgs(process.argv.slice(2), ['image', 'product', 'scene', 'preset', 'format']) if (!o.image || !o.product || (!o.scene && !o.preset)) fail('Usage: node scripts/build-input.mjs --image https://... --product "what it is, label text" (--scene "backdrop and props" | --preset skincare|food-pack|tech|apparel|home|supplements) [--format 4:5|1:1|9:16]') checkImage(o.image) const settings = JSON.parse(readFileSync(join(root, 'assets/generation-input.json'), 'utf8')) const format = o.format ?? '4:5' const size = settings.sizes[format] if (!size) fail('--format must be 1:1, 4:5 or 9:16') const composition = settings.composition[format] if (o.preset && !settings.presets[o.preset]) fail('--preset must be one of: ' + Object.keys(settings.presets).join(', ')) const scene = o.scene ?? settings.presets[o.preset] const template = readFileSync(join(root, 'assets/prompt-template.md'), 'utf8').trim() const prompt = template .replace('{{product}}', () => o.product) .replace('{{scene}}', () => scene) .replace('{{composition}}', () => composition) console.log(JSON.stringify({ model: settings.model, input: { ...settings.input, image_size: size, image_urls: [o.image], prompt }, }, null, 2))