(manifest: { format_id?: FormatID; creative_id?: string; assets?: Record<string, unknown> })
| 3266 | const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); |
| 3267 | |
| 3268 | function buildPreview(manifest: { format_id?: FormatID; creative_id?: string; assets?: Record<string, unknown> }) { |
| 3269 | // Resolve format |
| 3270 | let formatId = manifest.format_id; |
| 3271 | let creativeName = 'Preview'; |
| 3272 | |
| 3273 | // If creative_id provided, look up from library |
| 3274 | if (manifest.creative_id) { |
| 3275 | const creative = session.creatives.get(manifest.creative_id); |
| 3276 | if (creative) { |
| 3277 | formatId = creative.formatId; |
| 3278 | creativeName = creative.name || manifest.creative_id; |
| 3279 | } |
| 3280 | } |
| 3281 | |
| 3282 | const fmtId = formatId?.id || 'display_300x250'; |
| 3283 | const format = validFormatIds.get(fmtId); |
| 3284 | if (!format && formatId?.id) { |
| 3285 | return null; // Signal invalid format to caller |
| 3286 | } |
| 3287 | const { w, h } = getDimensions(format); |
| 3288 | |
| 3289 | const previewHtml = `<!DOCTYPE html><html><head><meta charset="utf-8"><title>Preview: ${escapeHtmlAttr(fmtId)}</title><style>body{margin:0;display:flex;align-items:center;justify-content:center;min-height:100vh;background:#fafafa;font-family:sans-serif;}</style></head><body><div style="width:${w}px;height:${h}px;background:linear-gradient(135deg,#1B5E20,#FF6F00);display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:8px;color:#fff;"><div style="font-size:16px;font-weight:600;">${escapeHtmlAttr(creativeName)}</div><div style="font-size:12px;opacity:0.8;margin-top:4px;">${escapeHtmlAttr(fmtId)} (${w}x${h})</div><div style="font-size:10px;opacity:0.6;margin-top:8px;">AdCP Training Agent Preview</div></div></body></html>`; |
| 3290 | |
| 3291 | const render: Record<string, unknown> = { |
| 3292 | render_id: `preview_${fmtId}`, |
| 3293 | output_format: outputFormat, |
| 3294 | role: 'primary', |
| 3295 | dimensions: { width: w, height: h }, |
| 3296 | }; |
| 3297 | |
| 3298 | if (outputFormat === 'url' || outputFormat === 'both') { |
| 3299 | render.preview_url = `data:text/html;base64,${Buffer.from(previewHtml).toString('base64')}`; |
| 3300 | } |
| 3301 | if (outputFormat === 'html' || outputFormat === 'both') { |
| 3302 | render.preview_html = previewHtml; |
| 3303 | } |
| 3304 | |
| 3305 | return { |
| 3306 | preview_id: `preview_${fmtId}`, |
| 3307 | renders: [render], |
| 3308 | input: { name: creativeName }, |
| 3309 | }; |
| 3310 | } |
| 3311 | |
| 3312 | // Variant mode |
| 3313 | if (req.request_type === 'variant') { |
no test coverage detected