alpha release
update v0.8.0
This commit is contained in:
92
src/middlewares/queryHandler/metadataHandler.ts
Normal file
92
src/middlewares/queryHandler/metadataHandler.ts
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user