Files
portfolio/server/api/resume/pdf.get.ts
T
mahdiarghyani 9c40914d6a feat(resume): complete Epic 4 - Resume Content Strategy and Guidelines
- Update resume data with comprehensive professional summary and optimized work experience highlights
- Add resume content tech-spec and strategy documentation for 2025 best practices
- Create resume guidelines reference document for content consistency
- Enhance PDF composable with openPdf preview function alongside downloadPdf
- Expand CSS banner hiding rules to block certificates.dev promotional content
- Add research documentation on resume best practices and ATS optimization
- Update i18n translations for resume content in English and Persian
- Include sample Ali Arghyani resume PDF template in design assets
- Refactor resume.en.ts with improved professional positioning and achievement metrics
- Update API route documentation for PDF generation story artifacts
- Establish foundation for Epic 4 sprint planning with tech specifications
2025-12-02 12:54:26 +03:30

76 lines
2.2 KiB
TypeScript

import puppeteer from 'puppeteer'
import type { Browser } from 'puppeteer'
export default defineEventHandler(async (event) => {
let browser: Browser | null = null
try {
const requestUrl = getRequestURL(event)
const host = requestUrl.host.includes('192.168') || requestUrl.host.includes('localhost')
? 'localhost:5000'
: requestUrl.host
const baseUrl = `http://${host}`
const resumeUrl = `${baseUrl}/resume?print=true`
console.log('[PDF API] Generating from:', resumeUrl)
const isDev = process.env.NODE_ENV === 'development'
if (isDev) {
browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
})
} else {
const chromium = await import('@sparticuz/chromium')
const puppeteerCore = await import('puppeteer-core')
browser = await puppeteerCore.default.launch({
args: chromium.default.args,
executablePath: await chromium.default.executablePath(),
headless: true,
})
}
const page = await browser.newPage()
await page.setViewport({ width: 794, height: 1123 })
const response = await page.goto(resumeUrl, {
waitUntil: 'networkidle0',
timeout: 30000,
})
if (!response || !response.ok()) {
throw new Error(`Failed to load: ${response?.status()}`)
}
const pdf = await page.pdf({
format: 'A4',
printBackground: true,
margin: { top: 0, right: 0, bottom: 0, left: 0 },
})
const query = getQuery(event)
const filename = (query.filename as string) || 'Ali_Arghyani_Resume.pdf'
const download = query.download === 'true'
setResponseHeaders(event, {
'Content-Type': 'application/pdf',
// inline = show in browser, attachment = force download
'Content-Disposition': `${download ? 'attachment' : 'inline'}; filename="${filename}"`,
})
return pdf
} catch (error) {
console.error('PDF generation failed:', error)
setResponseStatus(event, 500)
return {
error: 'PDF generation failed',
message: error instanceof Error ? error.message : 'Unknown error',
}
} finally {
if (browser) {
await browser.close()
}
}
})