alpha release

update v0.8.0
This commit is contained in:
2026-03-17 22:49:38 -04:00
commit 63a91931da
157 changed files with 10951 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
import type { Request, Response } from 'express';
import type { Metadata } from 'twtxt-lib';
import { env } from '../../lib/env.js';
import twtxtCache from '../../lib/twtxtCache.js';
import {
generateEtag,
getQueryParameterArray,
getValueOrFirstEntry,
} from '../../lib/utils.js';
import NodeCache from '@cacheable/node-cache';
import { QueryParameters } from '../../types.js';
export interface MetadataHandler {
cache: NodeCache<unknown>;
metadataParameter: QueryParameters['metadata'];
req: Request;
res: Response;
}
/**
*
* @param req
* @param res
* @param cache
* @param metadataParameter
*/
export default function metadataHandler(
req: Request,
res: Response,
cache: NodeCache<unknown>,
metadataParameter: QueryParameters['metadata']
) {
const metadataToMatch = getQueryParameterArray(req.query[metadataParameter]);
const searchTermsToMatch = [
...getQueryParameterArray(req.query.search),
...getQueryParameterArray(req.query.s),
];
const metadata = (cache.get('metadata') as Metadata) ?? {};
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 matchedMetadata = Object.keys(metadata)
.filter(
(key) =>
(!metadataToMatch.length ||
(metadataToMatch.length === 1 && metadataToMatch[0] === '') ||
metadataToMatch.includes(key)) &&
(!searchTermsToMatch.length ||
searchTermsToMatch.some((term) =>
key.includes(term) || Array.isArray(metadata[key])
? (metadata[key] as string[]).some((val) => val.includes(term))
: metadata[key].includes(term)
))
)
.reduce(
(acc, key) => {
const value = metadata[key as keyof typeof metadata];
acc[key] = Array.isArray(value)
? value.filter(
(value) =>
!searchTermsToMatch.length ||
searchTermsToMatch.some(
(term) => key.includes(term) || value.includes(term)
)
)
: value;
return acc;
},
{} as Record<string, string | string[]>
);
const result = wantsJson
? JSON.stringify(matchedMetadata)
: Object.keys(matchedMetadata)
.map((key) => {
const value = matchedMetadata[key as keyof typeof matchedMetadata];
return Array.isArray(value)
? value.map((rowVal) => `${key}: ${rowVal}`).join('\n')
: `${key}: ${value}`;
})
.join('\n');
res.set('etag', generateEtag(result)).send(result);
}