Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

ogcard: ensure we use jpeg images for satori compat (#10023)

authored by

devin ivy and committed by
GitHub
18d7e775 b8aae166

+11 -4
+1
bskyogcard/src/components/Img.tsx
··· 1 1 import React from 'react' 2 2 3 + // @NOTE satori does not currently support webp, see vercel/satori#273 3 4 function detectMime(buf: Buffer): string { 4 5 if (buf[0] === 0xff && buf[1] === 0xd8) return 'image/jpeg' 5 6 if (buf[0] === 0x89 && buf[1] === 0x50) return 'image/png'
+10 -4
bskyogcard/src/routes/starter-pack.tsx
··· 1 1 import assert from 'node:assert' 2 2 3 3 import React from 'react' 4 - import {AppBskyGraphDefs, AtUri} from '@atproto/api' 4 + import {type AppBskyGraphDefs, AtUri} from '@atproto/api' 5 5 import resvg from '@resvg/resvg-js' 6 - import {Express} from 'express' 6 + import {type Express} from 'express' 7 7 import satori from 'satori' 8 8 9 9 import { ··· 11 11 STARTERPACK_HEIGHT, 12 12 STARTERPACK_WIDTH, 13 13 } from '../components/StarterPack.js' 14 - import {AppContext} from '../context.js' 14 + import {type AppContext} from '../context.js' 15 15 import {httpLogger} from '../logger.js' 16 16 import {loadEmojiAsSvg} from '../util.js' 17 17 import {handler, originVerifyMiddleware} from './util.js' ··· 83 83 } 84 84 85 85 async function getImage(url: string) { 86 - const response = await fetch(url) 86 + const response = await fetch(ensureJpeg(url)) 87 87 const arrayBuf = await response.arrayBuffer() // must drain body even if it will be discarded 88 88 if (response.status !== 200) return null 89 89 return Buffer.from(arrayBuf) 90 + } 91 + 92 + // CDN URLs end with @jpeg, @webp, or no extension (which may default to webp). 93 + // We want to ensure the image URLs we use are for jpegs, required for compat with satori. 94 + function ensureJpeg(url: string) { 95 + return url.replace(/(@[a-z]{3,5})?$/, '@jpeg') 90 96 } 91 97 92 98 const hideAvatarLabels = new Set([