Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

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

at 999e52ed2d5a2c8b2f7b8747dfcfd0e2017e5eb0 54 lines 1.6 kB view raw
1import assert from 'node:assert' 2 3import {DAY, SECOND} from '@atproto/common' 4import {Express} from 'express' 5 6import {AppContext} from '../context.js' 7import {handler} from './util.js' 8 9export default function (ctx: AppContext, app: Express) { 10 return app.get( 11 '/:linkId', 12 handler(async (req, res) => { 13 const linkId = req.params.linkId 14 const contentType = req.accepts(['html', 'json']) 15 assert( 16 typeof linkId === 'string', 17 'express guarantees id parameter is a string', 18 ) 19 const found = await ctx.db.db 20 .selectFrom('link') 21 .selectAll() 22 .where('id', '=', linkId) 23 .executeTakeFirst() 24 if (!found) { 25 // potentially broken or mistyped link 26 res.setHeader('Cache-Control', 'no-store') 27 if (contentType === 'json') { 28 return res 29 .status(404) 30 .json({ 31 error: 'NotFound', 32 message: 'Link not found', 33 }) 34 .end() 35 } 36 // send the user to the app 37 res.setHeader('Location', `https://${ctx.cfg.service.appHostname}`) 38 return res.status(302).end() 39 } 40 // build url from original url in order to preserve query params 41 const url = new URL( 42 req.originalUrl, 43 `https://${ctx.cfg.service.appHostname}`, 44 ) 45 url.pathname = found.path 46 res.setHeader('Cache-Control', `max-age=${(7 * DAY) / SECOND}`) 47 if (contentType === 'json') { 48 return res.json({url: url.href}).end() 49 } 50 res.setHeader('Location', url.href) 51 return res.status(301).end() 52 }), 53 ) 54}