diff --git a/src/data/icon-sets.ts b/src/data/icon-sets.ts index 68c0d80..8217e7b 100644 --- a/src/data/icon-sets.ts +++ b/src/data/icon-sets.ts @@ -16,13 +16,25 @@ export function setImporters(items: Importer[]) { /** * All prefixes, sorted */ -let prefixes: string[] = []; +let allPrefixes: string[] = []; +let prefixesWithInfo: string[] = []; +let visiblePrefixes: string[] = []; /** * Get all prefixes */ -export function getPrefixes(): string[] { - return prefixes; +type GetPrefixes = 'all' | 'info' | 'visible'; +export function getPrefixes(type: GetPrefixes = 'all'): string[] { + switch (type) { + case 'all': + return allPrefixes; + + case 'info': + return prefixesWithInfo; + + case 'visible': + return visiblePrefixes; + } } /** @@ -45,6 +57,8 @@ export function updateIconSets(): number { const newLoadedIconSets: Set = new Set(); const newPrefixes: Set = new Set(); + const newPrefixesWithInfo: Set = new Set(); + const newVisiblePrefixes: Set = new Set(); importers.forEach((importer, importerIndex) => { const data = importer.data; @@ -63,7 +77,16 @@ export function updateIconSets(): number { // Add prefix, but delete it first to keep order newPrefixes.delete(prefix); + newPrefixesWithInfo.delete(prefix); + newVisiblePrefixes.delete(prefix); + newPrefixes.add(prefix); + if (item.info) { + newPrefixesWithInfo.add(prefix); + if (!item.info.hidden) { + newVisiblePrefixes.add(prefix); + } + } // Set data iconSets[prefix] = { @@ -81,8 +104,10 @@ export function updateIconSets(): number { loadedIconSets = newLoadedIconSets; // Update prefixes - prefixes = Array.from(newPrefixes); - return prefixes.length; + allPrefixes = Array.from(newPrefixes); + prefixesWithInfo = Array.from(newPrefixesWithInfo); + visiblePrefixes = Array.from(newVisiblePrefixes); + return allPrefixes.length; } /** diff --git a/src/http/helpers/prefixes.ts b/src/http/helpers/prefixes.ts index 305b3cf..00eeab6 100644 --- a/src/http/helpers/prefixes.ts +++ b/src/http/helpers/prefixes.ts @@ -7,12 +7,16 @@ interface MatchPrefixesParams { } /** - * Filter prefixes + * Filter prefixes by name * * returnEmpty = true -> if no filter params set, returns empty array * returnEmpty = false -> if no filter params set, returns all filters */ -export function filterPrefixes(prefixes: string[], params: MatchPrefixesParams, returnEmpty: boolean): string[] { +export function filterPrefixesByPrefix( + prefixes: string[], + params: MatchPrefixesParams, + returnEmpty: boolean +): string[] { const exactMatch = params.prefix; if (exactMatch) { // Exact match diff --git a/src/http/index.ts b/src/http/index.ts index 93a1231..4381078 100644 --- a/src/http/index.ts +++ b/src/http/index.ts @@ -2,6 +2,7 @@ import fastify, { FastifyReply } from 'fastify'; import { appConfig } from '../config/app'; import { runWhenLoaded } from '../data/loading'; import { iconNameRoutePartialRegEx, iconNameRouteRegEx, splitIconName } from '../misc/name'; +import { generateCollectionsListResponse } from './responses/collections'; import { generateIconsDataResponse } from './responses/icons'; import { generateLastModifiedResponse } from './responses/modified'; import { generateSVGResponse } from './responses/svg'; @@ -106,6 +107,13 @@ export async function startHTTPServer() { }); }); + // Icon sets list + server.get('/collections', (req, res) => { + runWhenLoaded(() => { + generateCollectionsListResponse(req.query, res); + }); + }); + // Update icon sets server.get('/update', (req, res) => { generateUpdateResponse(req.query, res); diff --git a/src/http/responses/collections.ts b/src/http/responses/collections.ts new file mode 100644 index 0000000..49297e2 --- /dev/null +++ b/src/http/responses/collections.ts @@ -0,0 +1,32 @@ +import type { IconifyInfo } from '@iconify/types'; +import type { FastifyReply, FastifyRequest } from 'fastify'; +import { getPrefixes, iconSets } from '../../data/icon-sets'; +import { checkJSONPQuery, sendJSONResponse } from '../helpers/json'; +import { filterPrefixesByPrefix } from '../helpers/prefixes'; + +/** + * Send response + */ +export function generateCollectionsListResponse(query: FastifyRequest['query'], res: FastifyReply) { + const q = (query || {}) as Record; + const wrap = checkJSONPQuery(q); + if (!wrap) { + // Invalid JSONP callback + res.send(400); + return; + } + + // Filter prefixes + const prefixes = filterPrefixesByPrefix(getPrefixes('info'), q, false); + const response = Object.create(null) as Record; + + for (let i = 0; i < prefixes.length; i++) { + const prefix = prefixes[i]; + const info = iconSets[prefix]?.item.info; + if (info) { + response[prefix] = info; + } + } + + sendJSONResponse(response, q, wrap, res); +} diff --git a/src/http/responses/modified.ts b/src/http/responses/modified.ts index fef7fff..d03a721 100644 --- a/src/http/responses/modified.ts +++ b/src/http/responses/modified.ts @@ -2,7 +2,7 @@ import type { FastifyReply, FastifyRequest } from 'fastify'; import { getPrefixes, iconSets } from '../../data/icon-sets'; import type { LastModifiedAPIResponse } from '../../types/server/modified'; import { checkJSONPQuery, sendJSONResponse } from '../helpers/json'; -import { filterPrefixes } from '../helpers/prefixes'; +import { filterPrefixesByPrefix } from '../helpers/prefixes'; /** * Generate icons data @@ -17,7 +17,7 @@ export function generateLastModifiedResponse(query: FastifyRequest['query'], res } // Filter prefixes - const prefixes = filterPrefixes(getPrefixes(), q, false); + const prefixes = filterPrefixesByPrefix(getPrefixes(), q, false); // Generate result const lastModified = Object.create(null) as Record;