import type { Request, Response } from 'express'; import type { Twttr } from 'twtxt-lib'; import { generateEtag, getQueryParameterArray, getValueOrFirstEntry, } from '../../lib/utils.js'; import { QueryParameters } from '../../types.js'; import NodeCache from '@cacheable/node-cache'; /** * * @param req * @param res * @param cache * @param followingParameter */ export default function followingHandler( req: Request, res: Response, following: Twttr[], followingParameter: QueryParameters['following'] ) { const followingsToMatch = getQueryParameterArray( req.query[followingParameter] ); const nicksToMatch = getQueryParameterArray(req.query.nick); const urlsToMatch = getQueryParameterArray(req.query.url); const searchTermsToMatch = [ ...getQueryParameterArray(req.query.search), ...getQueryParameterArray(req.query.s), ]; const wantsJson = req.is('json') || getValueOrFirstEntry(getQueryParameterArray(req.query.format)) === 'json'; if (wantsJson) res.set('content-type', 'application/json'); else res.set('content-type', 'text/plain'); const matchedFollowing = following.filter( ({ nick, url }) => (!followingsToMatch.length || (followingsToMatch.length === 1 && followingsToMatch[0] === '') || followingsToMatch.includes(nick) || followingsToMatch.includes(`@${nick}`) || followingsToMatch.includes(url)) && (!nicksToMatch.length || nicksToMatch.includes(nick) || nicksToMatch.includes(`@${nick}`)) && (!urlsToMatch.length || urlsToMatch.includes(url)) && (!searchTermsToMatch.length || searchTermsToMatch.some( (term) => nick.includes(term) || url.includes(term) )) ); const result = wantsJson ? JSON.stringify(matchedFollowing) : matchedFollowing.map(({ nick, url }) => `@${nick} ${url}`).join('\n'); res.set('etag', generateEtag(result)).send(result); }