Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 

59 righe
1.6 KiB

  1. import { NextResponse } from 'next/server';
  2. import fs from 'fs';
  3. import path from 'path';
  4. export const dynamic = 'force-dynamic';
  5. const MIME: Record<string, string> = {
  6. '.woff2': 'font/woff2',
  7. '.woff': 'font/woff',
  8. '.ttf': 'font/ttf',
  9. '.otf': 'font/otf',
  10. };
  11. const FONTS_DIR = path.join(process.cwd(), 'data', 'fonts');
  12. function ensureFontsDir() {
  13. try { fs.mkdirSync(FONTS_DIR, { recursive: true }); } catch {}
  14. }
  15. export async function GET(request: Request) {
  16. const { searchParams } = new URL(request.url);
  17. const name = searchParams.get('name');
  18. if (name) {
  19. // Serve un singolo file font
  20. const safeName = path.basename(name); // protezione path traversal
  21. const ext = path.extname(safeName).toLowerCase();
  22. const mimeType = MIME[ext];
  23. if (!mimeType) return new NextResponse('Unsupported format', { status: 400 });
  24. const filePath = path.join(FONTS_DIR, safeName);
  25. try {
  26. const buffer = fs.readFileSync(filePath);
  27. return new NextResponse(buffer, {
  28. headers: {
  29. 'Content-Type': mimeType,
  30. 'Cache-Control': 'public, max-age=31536000, immutable',
  31. 'Access-Control-Allow-Origin': '*',
  32. },
  33. });
  34. } catch {
  35. return new NextResponse('Font not found', { status: 404 });
  36. }
  37. }
  38. // List mode: ritorna i font "regular" (non-italic) presenti
  39. ensureFontsDir();
  40. try {
  41. const files = fs.readdirSync(FONTS_DIR);
  42. const list = files
  43. .filter(f => /\.(woff2?|ttf|otf)$/i.test(f))
  44. .filter(f => !/italic/i.test(f))
  45. .sort();
  46. return NextResponse.json(list);
  47. } catch {
  48. return NextResponse.json([]);
  49. }
  50. }