fix(api): Rename route.ts to route.tsx for safe JSX processing in next/og and expose specific error details

This commit is contained in:
AI Bot 2026-08-23 17:06:31 -05:00
parent 58025866be
commit 0685fcfe59

View File

@ -117,45 +117,44 @@ export async function GET(request: Request) {
const plainTextResumen = (post.resumen_redes || post.contenido || '').replace(/<[^>]*>?/gm, ' ').replace(/\s+/g, ' ').trim(); const plainTextResumen = (post.resumen_redes || post.contenido || '').replace(/<[^>]*>?/gm, ' ').replace(/\s+/g, ' ').trim();
const safeResumen = plainTextResumen.length > 120 ? plainTextResumen.substring(0, 120) + '...' : plainTextResumen; const safeResumen = plainTextResumen.length > 120 ? plainTextResumen.substring(0, 120) + '...' : plainTextResumen;
// WAIT! This file is route.ts, JSX is not supported in .ts unless it's .tsx! // Use native JSX now that the file is renamed to route.tsx
// Let's use react.createElement const cardImage = new ImageResponse(
const React = require('react'); (
const cardNode = React.createElement('div', { <div style={{
style: { display: 'flex', flexDirection: 'column', width: 600, height: 600,
display: 'flex', flexDirection: 'column', width: 600, height: 600, backgroundColor: '#0f172a', borderRadius: 24,
backgroundColor: '#0f172a', borderRadius: 24, overflow: 'hidden', border: '1px solid rgba(255,255,255,0.1)', fontFamily: 'sans-serif'
overflow: 'hidden', border: '1px solid rgba(255,255,255,0.1)', fontFamily: 'sans-serif' }}>
} <div style={{ display: 'flex', width: 600, height: 337, backgroundColor: '#1e293b', position: 'relative' }}>
}, {imageUrl ? (
React.createElement('div', { <img src={imageUrl} style={{ width: 600, height: 337, objectFit: 'cover' }} />
style: { display: 'flex', width: 600, height: 337, backgroundColor: '#1e293b', position: 'relative' } ) : (
}, <div style={{ width: 600, height: 337, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
imageUrl <span style={{ color: '#475569', fontSize: 24, fontWeight: 900, textTransform: 'uppercase', letterSpacing: 4 }}>Almeira Web</span>
? React.createElement('img', { src: imageUrl, style: { width: 600, height: 337, objectFit: 'cover' } }) </div>
: React.createElement('div', { style: { width: 600, height: 337, display: 'flex', alignItems: 'center', justifyContent: 'center' } }, )}
React.createElement('span', { style: { color: '#475569', fontSize: 24, fontWeight: 900, textTransform: 'uppercase', letterSpacing: 4 } }, 'Almeira Web') <div style={{ position: 'absolute', top: 16, left: 16, display: 'flex' }}>
), <span style={{ padding: '6px 12px', borderRadius: 9999, fontSize: 12, fontWeight: 'bold', letterSpacing: 1, backgroundColor: 'rgba(0,0,0,0.6)', color: '#67e8f9', border: '1px solid rgba(255,255,255,0.2)' }}>
React.createElement('div', { style: { position: 'absolute', top: 16, left: 16, display: 'flex' } }, NOTICIA
React.createElement('span', { </span>
style: { padding: '6px 12px', borderRadius: 9999, fontSize: 12, fontWeight: 'bold', letterSpacing: 1, backgroundColor: 'rgba(0,0,0,0.6)', color: '#67e8f9', border: '1px solid rgba(255,255,255,0.2)' } </div>
}, 'NOTICIA') </div>
) <div style={{ display: 'flex', flexDirection: 'column', padding: 32, flexGrow: 1 }}>
<h3 style={{ fontSize: 26, fontWeight: 'bold', margin: '0 0 16px 0', lineHeight: 1.3, color: 'white' }}>{post.titulo || 'Sin título'}</h3>
<p style={{ fontSize: 16, color: '#94a3b8', margin: '0 0 32px 0', lineHeight: 1.6 }}>{safeResumen}</p>
<div style={{ marginTop: 'auto', paddingTop: 20, borderTop: '1px solid rgba(255,255,255,0.1)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<span style={{ color: '#06b6d4', fontSize: 13, fontWeight: 'bold', textTransform: 'uppercase', letterSpacing: 1, marginRight: 8 }}>ESTADO:</span>
<span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 'bold', textTransform: 'uppercase', letterSpacing: 1 }}>{post.estado || 'Borrador'}</span>
</div>
<span style={{ color: '#06b6d4', fontSize: 13, fontWeight: 'bold', textTransform: 'uppercase', letterSpacing: 1 }}>{fechaFormat}</span>
</div>
</div>
</div>
), ),
React.createElement('div', { style: { display: 'flex', flexDirection: 'column', padding: 32, flexGrow: 1 } }, { width: 600, height: 600 }
React.createElement('h3', { style: { fontSize: 26, fontWeight: 'bold', margin: '0 0 16px 0', lineHeight: 1.3, color: 'white' } }, post.titulo || 'Sin título'),
React.createElement('p', { style: { fontSize: 16, color: '#94a3b8', margin: '0 0 32px 0', lineHeight: 1.6 } }, safeResumen),
React.createElement('div', { style: { marginTop: 'auto', paddingTop: 20, borderTop: '1px solid rgba(255,255,255,0.1)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
React.createElement('div', { style: { display: 'flex', alignItems: 'center' } },
React.createElement('span', { style: { color: '#06b6d4', fontSize: 13, fontWeight: 'bold', textTransform: 'uppercase', letterSpacing: 1, marginRight: 8 } }, 'ESTADO:'),
React.createElement('span', { style: { color: '#94a3b8', fontSize: 13, fontWeight: 'bold', textTransform: 'uppercase', letterSpacing: 1 } }, post.estado || 'Borrador')
),
React.createElement('span', { style: { color: '#06b6d4', fontSize: 13, fontWeight: 'bold', textTransform: 'uppercase', letterSpacing: 1 } }, fechaFormat)
)
)
); );
const cardImage = new ImageResponse(cardNode, { width: 600, height: 600 });
const imgBuffer = await cardImage.arrayBuffer(); const imgBuffer = await cardImage.arrayBuffer();
docChildren.push( docChildren.push(
new Paragraph({ new Paragraph({
@ -228,8 +227,8 @@ export async function GET(request: Request) {
'Content-Disposition': `attachment; filename=reporte_publicaciones_${new Date().toISOString().split('T')[0]}.docx`, 'Content-Disposition': `attachment; filename=reporte_publicaciones_${new Date().toISOString().split('T')[0]}.docx`,
}, },
}); });
} catch (error) { } catch (error: any) {
console.error('General error Word API:', error); console.error('General error Word API:', error);
return NextResponse.json({ error: 'Error al generar el documento' }, { status: 500 }); return NextResponse.json({ error: 'Error al generar el documento', details: error?.message || 'Error desconocido' }, { status: 500 });
} }
} }