diff --git a/nuxt.config.ts b/nuxt.config.ts index 45eeb2c..a3e20aa 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -45,4 +45,12 @@ export default defineNuxtConfig({ }, }, + nitro: { + externals: { + traceInclude: [ + 'node_modules/pdfjs-dist/legacy/build/pdf.worker.mjs', + ], + }, + }, + }) diff --git a/server/api/admin/pdf-outline.get.ts b/server/api/admin/pdf-outline.get.ts index 4d128f2..989a4c1 100644 --- a/server/api/admin/pdf-outline.get.ts +++ b/server/api/admin/pdf-outline.get.ts @@ -1,28 +1,63 @@ import { join } from 'node:path' import { readFileSync, existsSync } from 'node:fs' +// Polyfills nécessaires pour pdfjs-dist en Node.js pur (pas de DOM) +// On n'a besoin que du parsing, pas du rendu +if (typeof globalThis.DOMMatrix === 'undefined') { + // @ts-expect-error polyfill minimal pour pdfjs + globalThis.DOMMatrix = class DOMMatrix { + constructor() { return Object.assign(this, { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }) } + isIdentity = true + translate() { return new DOMMatrix() } + scale() { return new DOMMatrix() } + inverse() { return new DOMMatrix() } + multiply() { return new DOMMatrix() } + } +} +if (typeof globalThis.Path2D === 'undefined') { + // @ts-expect-error polyfill stub + globalThis.Path2D = class Path2D { constructor() {} } +} +if (typeof globalThis.ImageData === 'undefined') { + // @ts-expect-error polyfill stub + globalThis.ImageData = class ImageData { constructor(w: number, h: number) { this.width = w; this.height = h; this.data = new Uint8ClampedArray(w * h * 4) } } +} + export default defineEventHandler(async () => { const config = await readYaml('bookplayer.config.yml') const pdfFile = config?.book?.pdfFile || '/pdf/une-economie-du-don.pdf' - // En dev : public/, en prod : .output/public/ + // Résolution du chemin PDF : dev (public/) et prod (.output/public/) const cwd = process.cwd() const candidates = [ join(cwd, 'public', pdfFile), join(cwd, '.output', 'public', pdfFile), ] const pdfPath = candidates.find(p => existsSync(p)) - if (!pdfPath) return [] + + if (!pdfPath) { + console.warn('[pdf-outline] PDF non trouvé. cwd:', cwd, 'candidats:', candidates) + return [] + } let data: Uint8Array try { data = new Uint8Array(readFileSync(pdfPath)) - } catch { + } catch (err) { + console.warn('[pdf-outline] Erreur lecture PDF:', err) return [] } const pdfjsLib = await import('pdfjs-dist/legacy/build/pdf.mjs') - const doc = await pdfjsLib.getDocument({ data, useSystemFonts: true }).promise + + let doc + try { + doc = await pdfjsLib.getDocument({ data, useSystemFonts: true }).promise + } catch (err) { + console.warn('[pdf-outline] Erreur getDocument:', err) + return [] + } + const outline = await doc.getOutline() if (!outline || outline.length === 0) {