142637653SEvan Baconimport { ExpoMiddleware } from './ExpoMiddleware'; 242637653SEvan Baconimport { ServerNext, ServerRequest, ServerResponse } from './server.types'; 3*8a424bebSJames Ideimport { getFaviconFromExpoConfigAsync } from '../../../export/favicon'; 442637653SEvan Bacon 542637653SEvan Baconconst debug = require('debug')('expo:start:server:middleware:favicon') as typeof console.log; 642637653SEvan Bacon 742637653SEvan Bacon/** 842637653SEvan Bacon * Middleware for generating a favicon.ico file for the current project if one doesn't exist. 942637653SEvan Bacon * 1042637653SEvan Bacon * Test by making a get request with: 1142637653SEvan Bacon * curl -v http://localhost:8081/favicon.ico 1242637653SEvan Bacon */ 1342637653SEvan Baconexport class FaviconMiddleware extends ExpoMiddleware { 1442637653SEvan Bacon constructor(protected projectRoot: string) { 1542637653SEvan Bacon super(projectRoot, ['/favicon.ico']); 1642637653SEvan Bacon } 1742637653SEvan Bacon 1842637653SEvan Bacon async handleRequestAsync( 1942637653SEvan Bacon req: ServerRequest, 2042637653SEvan Bacon res: ServerResponse, 2142637653SEvan Bacon next: ServerNext 2242637653SEvan Bacon ): Promise<void> { 2342637653SEvan Bacon if (!['GET', 'HEAD'].includes(req.method || '')) { 2442637653SEvan Bacon return next(); 2542637653SEvan Bacon } 2642637653SEvan Bacon 2742637653SEvan Bacon let faviconImageData: Buffer | null; 2842637653SEvan Bacon try { 2942637653SEvan Bacon const data = await getFaviconFromExpoConfigAsync(this.projectRoot); 3042637653SEvan Bacon if (!data) { 3142637653SEvan Bacon debug('No favicon defined in the Expo Config, skipping generation.'); 3242637653SEvan Bacon return next(); 3342637653SEvan Bacon } 3442637653SEvan Bacon faviconImageData = data.source; 3542637653SEvan Bacon debug('✅ Generated favicon successfully.'); 3642637653SEvan Bacon } catch (error: any) { 3742637653SEvan Bacon debug('Failed to generate favicon from Expo config:', error); 3842637653SEvan Bacon return next(error); 3942637653SEvan Bacon } 4042637653SEvan Bacon // Respond with the generated favicon file 4142637653SEvan Bacon res.setHeader('Content-Type', 'image/x-icon'); 4242637653SEvan Bacon res.end(faviconImageData); 4342637653SEvan Bacon } 4442637653SEvan Bacon} 45