Files
portfolio-generator-app/scripts/dev-raw-pdf.mjs
Valentin Le Moign 59dfbe4155 Générateur de portfolios PDF Figures Libres (app Nuxt autonome)
App Nuxt 3 + Nuxt UI qui lit les projets du CMS Grav et compose des portfolios
A3 paysage exportés en PDF (gabarit book_v3) : composeur WYSIWYG, templates
cover/toc/projet/grille/page libre, pipeline Playwright + Ghostscript, gel du
contenu à la génération, partage public opt-in.

Dépôt autonome : Dockerfile (base Playwright + Ghostscript + ffmpeg + rsync) inclus.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 18:37:09 +02:00

51 lines
2.2 KiB
JavaScript

// Capture le PDF brut Chromium de /print/<id> (avant Ghostscript) pour diagnostic.
import { chromium } from 'playwright'
const [, , id, out = '/app/data/cache/raw-debug.pdf'] = process.argv
const token = process.env.NUXT_INTERNAL_TOKEN ?? 'dev-internal-token'
const browser = await chromium.launch()
const page = await browser.newPage({
viewportSize: { width: 1280, height: 720 },
extraHTTPHeaders: { 'x-internal-token': token },
})
page.on('console', m => console.log('[console]', m.type(), m.text()))
page.on('requestfailed', r => console.log('[failed]', r.url(), r.failure()?.errorText))
page.on('response', (r) => { if (!r.ok()) console.log('[http]', r.status(), r.url()) })
const url = `http://localhost:3000/print/${id}?internal-token=${encodeURIComponent(token)}`
const response = await page.goto(url, { waitUntil: 'networkidle', timeout: 120_000 })
console.log('goto:', response?.status())
await page.evaluate(async () => {
await Promise.all(Array.from(document.fonts).map(f => f.load().catch(() => {})))
await document.fonts.ready
const images = Array.from(document.querySelectorAll('img'))
await Promise.all(images.map(img => img.complete
? Promise.resolve()
: new Promise((resolve) => { img.onload = img.onerror = resolve })))
})
// État des fontes + présence de texte dans le DOM
const info = await page.evaluate(() => ({
fonts: Array.from(document.fonts).map(f => `${f.family} ${f.weight} ${f.style}: ${f.status}`),
h2: Array.from(document.querySelectorAll('h2')).map(el => el.textContent?.slice(0, 40)),
bodyTextLen: document.body.innerText.length,
}))
console.log(JSON.stringify(info, null, 2))
await page.emulateMedia({ media: 'print' })
// Bug Chromium : texte en webfonts absent du PDF sans réinvalidation des
// styles (cf. pdf-pipeline.ts)
await page.evaluate(async () => {
for (const sheet of document.styleSheets) sheet.disabled = true
void document.body.offsetHeight
for (const sheet of document.styleSheets) sheet.disabled = false
void document.body.offsetHeight
await document.fonts.ready
await new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r)))
})
await page.pdf({ path: out, printBackground: true, preferCSSPageSize: true, timeout: 120_000 })
console.log('raw pdf →', out)
await browser.close()