#!/usr/bin/env node /** * Extrae el texto del PDF de términos y condiciones y lo convierte en un * módulo TypeScript para que el frontend lo renderice sin tener que parsear * el PDF en runtime. * * Además copia el PDF original a `apps/web/public/legal/` para servirlo como * descarga. * * Uso: * pnpm legal:sync * * Cuando se actualiza el documento legal: * 1. Reemplazar `docs/legal/Terminos y condiciones.pdf` por la nueva versión * (mismo nombre de archivo). * 2. Correr `pnpm legal:sync`. * 3. Commit de los cambios (PDF, terminos.ts, PDF copy). */ import { readFileSync, writeFileSync, copyFileSync, mkdirSync } from 'node:fs'; import { resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { PDFParse } from 'pdf-parse'; const __dirname = dirname(fileURLToPath(import.meta.url)); const ROOT = resolve(__dirname, '../../../'); const SRC_PDF = resolve(ROOT, 'docs/legal/Terminos y condiciones.pdf'); const DEST_PDF = resolve(ROOT, 'apps/web/public/legal/terminos-y-condiciones.pdf'); const DEST_TS = resolve(ROOT, 'apps/web/content/terminos.ts'); async function main() { console.log('[legal:sync] Leyendo:', SRC_PDF); const buf = readFileSync(SRC_PDF); const parser = new PDFParse({ data: buf }); const textResult = await parser.getText(); await parser.destroy(); const rawText = (textResult.text ?? '').trim(); const pages = textResult.total ?? textResult.pages?.length ?? 0; if (!rawText) { console.error('[legal:sync] ERROR: el PDF no contiene texto extraíble (¿escaneado sin OCR?).'); process.exit(1); } // Copia el PDF a public/ para que sea descargable mkdirSync(dirname(DEST_PDF), { recursive: true }); copyFileSync(SRC_PDF, DEST_PDF); // Escribe el texto como módulo TypeScript. Escapa backticks para que el // template literal no rompa si el PDF los contiene. const escaped = rawText.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${'); const extractedAt = new Date().toISOString(); const content = `// AUTO-GENERADO por \`pnpm legal:sync\`. NO editar a mano. // Fuente: docs/legal/Terminos y condiciones.pdf // Regenerar tras actualizar el PDF. export const TERMINOS_TEXT = \`${escaped}\`; export const TERMINOS_META = { extractedAt: '${extractedAt}', pages: ${pages}, chars: ${rawText.length}, } as const; `; mkdirSync(dirname(DEST_TS), { recursive: true }); writeFileSync(DEST_TS, content, 'utf8'); console.log(`[legal:sync] OK: ${rawText.length} chars extraídos, ${pages} páginas.`); console.log(`[legal:sync] → ${DEST_PDF}`); console.log(`[legal:sync] → ${DEST_TS}`); } main().catch(err => { console.error('[legal:sync] FAIL:', err); process.exit(1); });