import type { Request, Response } from 'express'; import type { Metadata, Twt } from 'twtxt-lib'; import { generateEtag, getQueryParameterArray, getValueOrFirstEntry, } from '../../lib/utils.js'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc.js'; import NodeCache from '@cacheable/node-cache'; import { QueryParameters } from '../../types.js'; dayjs.extend(utc); /** * * @param req * @param res * @param twts * @param twtParameter * @param twtsParameter * @returns */ export default function twtHandler( req: Request, res: Response, twts: Twt[] = [], twtParameter: QueryParameters['twt'], twtsParameter: QueryParameters['twts'] ) { const twtsToMatch = getQueryParameterArray(req.query[twtsParameter]); const showLastTwt = getQueryParameterArray(req.query[twtParameter]); const hashesToMatch = getQueryParameterArray(req.query.hash); const searchTermsToMatch = [ ...getQueryParameterArray(req.query.search), ...getQueryParameterArray(req.query.s), ]; const createdDatesToMatch = getQueryParameterArray(req.query.created_date); const createdUTCStartDatesToMatch = getQueryParameterArray( req.query.created_date_start ).map((val) => dayjs.utc(val)); const createdUTCEndDatesToMatch = getQueryParameterArray( req.query.created_date_end ).map((val) => dayjs.utc(val)); 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'); if (showLastTwt.length === 1 && showLastTwt[0] === '') { const lastTwt = twts.reduce((matched, curr) => matched?.createdUTC > curr.createdUTC ? matched : curr ); let result = 'No results'; if (lastTwt) { result = wantsJson ? JSON.stringify(lastTwt) : `${lastTwt?.created || ''}\t${lastTwt?.content || ''}\n`; } res.set('etag', generateEtag(result)).send(result); return; } const matchedTwts = twts.filter(({ content, created, createdUTC, hash }) => { return ( (!twtsToMatch.length || (twtsToMatch.length === 1 && twtsToMatch[0] === '') || twtsToMatch.includes(created) || (hash && (twtsToMatch.includes(hash) || twtsToMatch.includes(`#${hash}`)))) && (!hashesToMatch.length || (hash && (hashesToMatch.includes(hash) || hashesToMatch.includes(`#${hash}`)))) && (!createdDatesToMatch.length || createdDatesToMatch.some((date) => created.includes(date))) && (!createdUTCStartDatesToMatch.length || createdUTCStartDatesToMatch.some( (date) => date.diff(createdUTC) < 0 )) && (!createdUTCEndDatesToMatch.length || createdUTCEndDatesToMatch.some((date) => date.diff(createdUTC) > 0)) && (!searchTermsToMatch.length || searchTermsToMatch.some((term) => content.includes(term))) ); }); const result = wantsJson ? JSON.stringify(matchedTwts) : matchedTwts .map(({ content, created }) => `${created}\t${content}`) .join('\n'); res.set('etag', generateEtag(result)).send(result); }