Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | // API route for generating addition worksheets import { NextResponse } from 'next/server' import { execSync } from 'child_process' import { validateWorksheetConfig } from '@/app/create/worksheets/validation' import { generateProblems, generateSubtractionProblems, generateMixedProblems, } from '@/app/create/worksheets/problemGenerator' import { generateTypstSource } from '@/app/create/worksheets/typstGenerator' import type { WorksheetFormState, WorksheetProblem } from '@/app/create/worksheets/types' import { withAuth } from '@/lib/auth/withAuth' export const POST = withAuth(async (request) => { try { const body: WorksheetFormState = await request.json() // Validate configuration const validation = validateWorksheetConfig(body) if (!validation.isValid || !validation.config) { return NextResponse.json( { error: 'Invalid configuration', errors: validation.errors }, { status: 400 } ) } const config = validation.config // Generate problems based on operator type let problems: WorksheetProblem[] if (config.operator === 'addition') { problems = generateProblems( config.total, config.pAnyStart, config.pAllStart, config.interpolate, config.seed, config.digitRange ) } else if (config.operator === 'subtraction') { problems = generateSubtractionProblems( config.total, config.digitRange, config.pAnyStart, config.pAllStart, config.interpolate, config.seed ) } else { // mixed problems = generateMixedProblems( config.total, config.digitRange, config.pAnyStart, config.pAllStart, config.interpolate, config.seed ) } // Generate Typst sources (one per page) const typstSources = await generateTypstSource(config, problems) // Join pages with pagebreak for PDF const typstSource = typstSources.join('\n\n#pagebreak()\n\n') // Compile with Typst: stdin → stdout let pdfBuffer: Buffer try { pdfBuffer = execSync('typst compile --format pdf - -', { input: typstSource, maxBuffer: 10 * 1024 * 1024, // 10MB limit }) } catch (error) { console.error('Typst compilation error:', error) // Extract the actual Typst error message const stderr = error instanceof Error && 'stderr' in error ? String((error as any).stderr) : 'Unknown compilation error' return NextResponse.json( { error: 'Failed to compile worksheet PDF', details: stderr, ...(process.env.NODE_ENV === 'development' && { typstSource: typstSource.split('\n').slice(0, 20).join('\n') + '\n...', }), }, { status: 500 } ) } // Return binary PDF directly return new Response(pdfBuffer as unknown as BodyInit, { headers: { 'Content-Type': 'application/pdf', 'Content-Disposition': `attachment; filename="addition-worksheet-${Date.now()}.pdf"`, }, }) } catch (error) { console.error('Error generating worksheet:', error) const errorMessage = error instanceof Error ? error.message : String(error) const errorStack = error instanceof Error ? error.stack : undefined return NextResponse.json( { error: 'Failed to generate worksheet', message: errorMessage, ...(process.env.NODE_ENV === 'development' && { stack: errorStack }), }, { status: 500 } ) } }) |