api.js/src/http/responses/keywords.ts

79 lines
2.2 KiB
TypeScript

import { matchIconName } from '@iconify/utils';
import type { FastifyReply, FastifyRequest } from 'fastify';
import { getPrefixes, iconSets } from '../../data/icon-sets';
import { searchIndex } from '../../data/search';
import { getPartialKeywords } from '../../data/search/partial';
import type { APIv3KeywordsQuery, APIv3KeywordsResponse } from '../../types/server/keywords';
import type { APIv3LastModifiedResponse } from '../../types/server/modified';
import { checkJSONPQuery, sendJSONResponse } from '../helpers/json';
import { filterPrefixesByPrefix } from '../helpers/prefixes';
/**
* Generate icons data
*/
export function generateKeywordsResponse(query: FastifyRequest['query'], res: FastifyReply) {
const q = (query || {}) as Record<string, string>;
const wrap = checkJSONPQuery(q);
if (!wrap) {
// Invalid JSONP callback
res.send(400);
return;
}
// Check if search data is available
const searchIndexData = searchIndex.data;
if (!searchIndexData) {
res.send(404);
return;
}
const keywords = searchIndexData.keywords;
// Get params
let test: string;
let suffixes: boolean;
let invalid: true | undefined;
let failed = false;
if (typeof q.prefix === 'string') {
test = q.prefix;
suffixes = false;
} else if (typeof q.keyword === 'string') {
test = q.keyword;
suffixes = true;
} else {
// Invalid query
res.send(400);
return;
}
test = test.toLowerCase().trim();
// Check if keyword is invalid
if (!matchIconName.test(test)) {
invalid = true;
} else {
// Get only last part of complex keyword
// Testing complex keywords is not recommended, first part is not checked
const parts = test.split('-');
if (parts.length > 1) {
test = parts.pop() as string;
suffixes = false;
for (let i = 0; i < parts.length; i++) {
if (keywords[parts[i]] === void 0) {
// One of keywords is missing
failed = true;
}
}
}
}
// Generate result
const response: APIv3KeywordsResponse = {
...(q as unknown as APIv3KeywordsQuery),
invalid,
exists: failed ? false : keywords[test] !== void 0,
matches: failed || invalid ? [] : getPartialKeywords(test, suffixes, searchIndexData)?.slice(0) || [],
};
sendJSONResponse(response, q, wrap, res);
}