From a5172ff84a26c09725717b899a9b252fa25ef0e0 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Thu, 20 Oct 2022 11:40:21 +0300 Subject: [PATCH] feat: option to disable icon sets list and search functionality --- src/config/app.ts | 9 +++++++ src/data/icon-set/store/storage.ts | 6 +++-- src/http/index.ts | 40 +++++++++++++++-------------- src/http/responses/collection-v1.ts | 18 ++++++++----- src/http/responses/collection-v2.ts | 5 ++++ src/types/config/app.ts | 9 +++++++ src/types/icon-set/storage.ts | 2 +- 7 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/config/app.ts b/src/config/app.ts index b382354..bb2a384 100644 --- a/src/config/app.ts +++ b/src/config/app.ts @@ -42,6 +42,15 @@ export const appConfig: AppConfig = { // Update check throttling // Delay to wait between successful update request and actual update updateThrottle: 60, + + // Enable icon sets and icon lists + // Disable this option if you need API to serve only icon data to save memory + enableIconLists: true, + + // Enable icon search + // Requires `enableIconLists` to be enabled + // Disable this option if you do not need search functionality + enableSearchEngine: true, }; /** diff --git a/src/data/icon-set/store/storage.ts b/src/data/icon-set/store/storage.ts index 39bdf1c..ce69b89 100644 --- a/src/data/icon-set/store/storage.ts +++ b/src/data/icon-set/store/storage.ts @@ -1,5 +1,5 @@ import type { IconifyIcons, IconifyJSON } from '@iconify/types'; -import { splitIconSetConfig, storageConfig } from '../../../config/app'; +import { appConfig, splitIconSetConfig, storageConfig } from '../../../config/app'; import type { SplitIconSetConfig } from '../../../types/config/split'; import type { StoredIconSet, StoredIconSetDone } from '../../../types/icon-set/storage'; import type { SplitRecord } from '../../../types/split'; @@ -79,11 +79,13 @@ export function storeLoadedIconSet( items: storedItems, tree, icons, - apiV2IconsCache: prepareAPIv2IconsList(iconSet, icons), }; if (iconSet.info) { result.info = iconSet.info; } + if (appConfig.enableIconLists) { + result.apiV2IconsCache = prepareAPIv2IconsList(iconSet, icons); + } done(result); } ); diff --git a/src/http/index.ts b/src/http/index.ts index e147a82..dfb34fc 100644 --- a/src/http/index.ts +++ b/src/http/index.ts @@ -109,31 +109,33 @@ export async function startHTTPServer() { }); }); - // Icon sets list - server.get('/collections', (req, res) => { - runWhenLoaded(() => { - generateCollectionsListResponse(req.query, res); + if (appConfig.enableIconLists) { + // Icon sets list + server.get('/collections', (req, res) => { + runWhenLoaded(() => { + generateCollectionsListResponse(req.query, res); + }); }); - }); - // Icons list, API v2 - server.get('/collection', (req, res) => { - runWhenLoaded(() => { - generateAPIv2CollectionResponse(req.query, res); + // Icons list, API v2 + server.get('/collection', (req, res) => { + runWhenLoaded(() => { + generateAPIv2CollectionResponse(req.query, res); + }); }); - }); - // Icons list, API v1 - server.get('/list-icons', (req, res) => { - runWhenLoaded(() => { - generateAPIv1IconsListResponse(req.query, res, false); + // Icons list, API v1 + server.get('/list-icons', (req, res) => { + runWhenLoaded(() => { + generateAPIv1IconsListResponse(req.query, res, false); + }); }); - }); - server.get('/list-icons-categorized', (req, res) => { - runWhenLoaded(() => { - generateAPIv1IconsListResponse(req.query, res, true); + server.get('/list-icons-categorized', (req, res) => { + runWhenLoaded(() => { + generateAPIv1IconsListResponse(req.query, res, true); + }); }); - }); + } // Update icon sets server.get('/update', (req, res) => { diff --git a/src/http/responses/collection-v1.ts b/src/http/responses/collection-v1.ts index dacbbb0..6e53273 100644 --- a/src/http/responses/collection-v1.ts +++ b/src/http/responses/collection-v1.ts @@ -1,5 +1,6 @@ import type { FastifyReply, FastifyRequest } from 'fastify'; import { getPrefixes, iconSets } from '../../data/icon-sets'; +import type { IconSetAPIv2IconsList } from '../../types/icon-set/extra'; import type { StoredIconSet } from '../../types/icon-set/storage'; import type { APIv1ListIconsBaseResponse, @@ -32,9 +33,12 @@ export function generateAPIv1IconsListResponse( return; } - function parse(prefix: string, iconSet: StoredIconSet): APIv1ListIconsResponse | APIv1ListIconsCategorisedResponse { + function parse( + prefix: string, + iconSet: StoredIconSet, + v2Cache: IconSetAPIv2IconsList + ): APIv1ListIconsResponse | APIv1ListIconsCategorisedResponse { const icons = iconSet.icons; - const v2Cache = iconSet.apiV2IconsCache; // Generate common data const base: APIv1ListIconsBaseResponse = { @@ -74,11 +78,11 @@ export function generateAPIv1IconsListResponse( if (q.prefix) { const prefix = q.prefix; const iconSet = iconSets[prefix]?.item; - if (!iconSet) { + if (!iconSet || !iconSet.apiV2IconsCache) { res.send(404); return; } - sendJSONResponse(parse(prefix, iconSet), q, wrap, res); + sendJSONResponse(parse(prefix, iconSet, iconSet.apiV2IconsCache), q, wrap, res); return; } @@ -95,15 +99,17 @@ export function generateAPIv1IconsListResponse( interface Item { prefix: string; iconSet: StoredIconSet; + v2Cache: IconSetAPIv2IconsList; } const items: Item[] = []; for (let i = 0; i < prefixes.length; i++) { const prefix = prefixes[i]; const iconSet = iconSets[prefix]?.item; - if (iconSet) { + if (iconSet?.apiV2IconsCache) { items.push({ prefix, iconSet, + v2Cache: iconSet.apiV2IconsCache, }); if (items.length > 10) { break; @@ -121,7 +127,7 @@ export function generateAPIv1IconsListResponse( const result = Object.create(null) as Record>; for (let i = 0; i < items.length; i++) { const item = items[i]; - result[item.prefix] = parse(item.prefix, item.iconSet); + result[item.prefix] = parse(item.prefix, item.iconSet, item.v2Cache); } sendJSONResponse(result, q, wrap, res); return; diff --git a/src/http/responses/collection-v2.ts b/src/http/responses/collection-v2.ts index 65008ed..9ca3ab9 100644 --- a/src/http/responses/collection-v2.ts +++ b/src/http/responses/collection-v2.ts @@ -31,6 +31,11 @@ export function generateAPIv2CollectionResponse(query: FastifyRequest['query'], const iconSet = iconSets[prefix].item; const apiV2IconsCache = iconSet.apiV2IconsCache; + if (!apiV2IconsCache) { + // Disabled + res.send(404); + return; + } // Filter prefixes const response: APIv2CollectionResponse = { diff --git a/src/types/config/app.ts b/src/types/config/app.ts index 8f8d303..c357196 100644 --- a/src/types/config/app.ts +++ b/src/types/config/app.ts @@ -32,4 +32,13 @@ export interface AppConfig { // Update check throttling updateThrottle: number; + + // Enable icon sets and icon lists + // Disable this option if you need API to serve only icon data to save memory + enableIconLists: boolean; + + // Enable icon search + // Requires `enableIconLists` to be enabled + // Disable this option if you do not need search functionality + enableSearchEngine: boolean; } diff --git a/src/types/icon-set/storage.ts b/src/types/icon-set/storage.ts index 7855897..c3849ac 100644 --- a/src/types/icon-set/storage.ts +++ b/src/types/icon-set/storage.ts @@ -23,7 +23,7 @@ export interface StoredIconSet { // Icons list icons: IconSetIconsListIcons; - apiV2IconsCache: IconSetAPIv2IconsList; + apiV2IconsCache?: IconSetAPIv2IconsList; // TODO: add properties for search data }