import type { ResumeData } from "@reactive-resume/schema/resume/data"; import type { Template } from "@reactive-resume/schema/templates"; import type { SectionTitleResolver } from "./section-title"; import type { ResolvedResumeRuntime, ResumePdfRenderResult } from "./semantic"; import { createElement } from "react"; import { parseResumeData } from "@reactive-resume/schema/resume/data"; import { renderToBuffer } from "#react-pdf-renderer"; import { ResumeDocument } from "./document"; import { hasSemanticErrors, inspectResumePdf } from "./semantic"; export type { PdfPreflightFailure, PdfPreflightPageLimits, PdfPreflightResult, RenderPreflightPdfResult, StylesheetPreflightInput, StylesheetPreflightRunner, } from "./semantic/preflight-core"; export { renderPreflightPdf } from "./semantic/preflight-core"; export type CreateResumePdfFileOptions = { data: ResumeData; filename: string; template?: Template | undefined; resolveSectionTitle?: SectionTitleResolver | undefined; }; export type CreateResumePdfFileResultOptions = CreateResumePdfFileOptions & { inspection?: ResolvedResumeRuntime | undefined; }; const renderResumePdfFile = async ({ data, filename, template, resolveSectionTitle }: CreateResumePdfFileOptions) => { const document = createElement(ResumeDocument, { data, template: template ?? data.metadata.template, resolveSectionTitle, }) as Parameters[0]; const buffer = await renderToBuffer(document); const bytes = new Uint8Array(new ArrayBuffer(buffer.byteLength)); bytes.set(buffer); return new File([bytes], filename, { type: "application/pdf" }); }; export const createResumePdfFileResult = async ({ inspection, ...options }: CreateResumePdfFileResultOptions): Promise> => { const normalizedOptions = { ...options, data: parseResumeData(options.data) }; const resolvedInspection = inspection ?? inspectResumePdf(normalizedOptions); if (hasSemanticErrors(resolvedInspection)) { return { ok: false, diagnostics: resolvedInspection.diagnostics }; } return { ok: true, value: await renderResumePdfFile(normalizedOptions), diagnostics: resolvedInspection.diagnostics, }; }; export const createResumePdfFile = async (options: CreateResumePdfFileOptions): Promise => { const result = await createResumePdfFileResult(options); if (!result.ok) { throw new Error("The semantic stylesheet could not be rendered.", { cause: result.diagnostics }); } return result.value; };