diff --git a/api/languages.ts b/api/languages.ts index 207f637..3bb51c8 100644 --- a/api/languages.ts +++ b/api/languages.ts @@ -36,6 +36,6 @@ export default async (req: VercelRequest, res: VercelResponse): Promise => res.send(renderLangPercent(data, color ?? "")); } catch { res.setHeader("Content-Type", "image/svg+xml"); - res.status(500).send(renderErrorCard("Could not fetch data")); + res.status(500).send(await renderErrorCard("Could not fetch data")); } }; diff --git a/api/stats.ts b/api/stats.ts index fdacf53..cf3e6d4 100644 --- a/api/stats.ts +++ b/api/stats.ts @@ -31,6 +31,6 @@ export default async (req: VercelRequest, res: VercelResponse): Promise => res.send(renderStatCard(data, color ?? "", peng)); } catch { res.setHeader("Content-Type", "image/svg+xml"); - res.status(500).send(renderErrorCard("Could not fetch data")); + res.status(500).send(await renderErrorCard("Could not fetch data")); } }; diff --git a/scripts/assets/fonts/inter-400.woff b/scripts/assets/fonts/inter-400.woff new file mode 100644 index 0000000..2f21ed4 Binary files /dev/null and b/scripts/assets/fonts/inter-400.woff differ diff --git a/scripts/assets/fonts/inter-600.woff b/scripts/assets/fonts/inter-600.woff new file mode 100644 index 0000000..323fa67 Binary files /dev/null and b/scripts/assets/fonts/inter-600.woff differ diff --git a/scripts/renderers/ErrorCard.tsx b/scripts/renderers/ErrorCard.tsx new file mode 100644 index 0000000..78af10f --- /dev/null +++ b/scripts/renderers/ErrorCard.tsx @@ -0,0 +1,72 @@ +import { CARD_WIDTH, CARD_HEIGHT, ERROR_DIVIDER_Y, COLOR_DARK, COLOR_SUBTLE } from '../utils/constants'; + +const DIVIDER_WIDTH = CARD_WIDTH - 2 * Math.round(CARD_WIDTH / 10); + +interface ErrorCardProps { + message: string; +} + +const ErrorCard = ({ message }: ErrorCardProps) => ( +
+
+ + Error + +
+
+
+ + {message} + +
+
+); + +export { ErrorCard }; diff --git a/scripts/renderers/renderErrorCard.test.ts b/scripts/renderers/renderErrorCard.test.ts index 466e80d..647f538 100644 --- a/scripts/renderers/renderErrorCard.test.ts +++ b/scripts/renderers/renderErrorCard.test.ts @@ -2,21 +2,21 @@ import { renderErrorCard } from './renderErrorCard'; import { CARD_WIDTH, CARD_HEIGHT } from '../utils/constants'; describe('renderErrorCard', () => { - test('returns an SVG string', () => { - const result = renderErrorCard('Test error'); + test('returns an SVG string', async () => { + const result = await renderErrorCard('Test error'); expect(result).toContain(''); }); - test('includes the error message', () => { - const message = 'Could not fetch data'; - const result = renderErrorCard(message); - expect(result).toContain(message); + test('renders different output for different messages', async () => { + const result1 = await renderErrorCard('Could not fetch data'); + const result2 = await renderErrorCard('Invalid username'); + expect(result1).not.toBe(result2); }); - test('uses the correct card dimensions', () => { - const result = renderErrorCard('Test'); - expect(result).toContain(`width="${ CARD_WIDTH }"`); - expect(result).toContain(`height="${ CARD_HEIGHT }"`); + test('uses the correct card dimensions', async () => { + const result = await renderErrorCard('Test'); + expect(result).toContain(`width="${CARD_WIDTH}"`); + expect(result).toContain(`height="${CARD_HEIGHT}"`); }); }); diff --git a/scripts/renderers/renderErrorCard.ts b/scripts/renderers/renderErrorCard.ts index ba4e627..afebae3 100644 --- a/scripts/renderers/renderErrorCard.ts +++ b/scripts/renderers/renderErrorCard.ts @@ -1,19 +1,32 @@ -import { CARD_WIDTH, CARD_HEIGHT, ERROR_DIVIDER_Y } from "../utils/constants"; +import satori from 'satori'; +import { readFileSync } from 'fs'; +import { join } from 'path'; +import React from 'react'; +import { ErrorCard } from './ErrorCard'; +import { CARD_WIDTH, CARD_HEIGHT } from '../utils/constants'; -const renderErrorCard = (message: string): string => { - return ` - - Error - - ${message} - `; +const fontRegular = readFileSync(join(__dirname, '../assets/fonts/inter-400.woff')); +const fontBold = readFileSync(join(__dirname, '../assets/fonts/inter-600.woff')); + +const renderErrorCard = async (message: string): Promise => { + return satori(React.createElement(ErrorCard, { message }), { + width: CARD_WIDTH, + height: CARD_HEIGHT, + fonts: [ + { + name: 'Inter', + data: fontRegular, + weight: 400, + style: 'normal', + }, + { + name: 'Inter', + data: fontBold, + weight: 600, + style: 'normal', + }, + ], + }); }; export { renderErrorCard };