mirror of https://github.com/iconify/api.git
feat: support deprecated API v1 list-icons queries
This commit is contained in:
parent
b137290974
commit
d9134cac49
|
|
@ -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 { generateAPIv1IconsListResponse } from './responses/collection-v1';
|
||||
import { generateAPIv2CollectionResponse } from './responses/collection-v2';
|
||||
import { generateCollectionsListResponse } from './responses/collections';
|
||||
import { generateIconsDataResponse } from './responses/icons';
|
||||
|
|
@ -122,6 +123,18 @@ export async function startHTTPServer() {
|
|||
});
|
||||
});
|
||||
|
||||
// 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);
|
||||
});
|
||||
});
|
||||
|
||||
// Update icon sets
|
||||
server.get('/update', (req, res) => {
|
||||
generateUpdateResponse(req.query, res);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,132 @@
|
|||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||
import { getPrefixes, iconSets } from '../../data/icon-sets';
|
||||
import type { StoredIconSet } from '../../types/icon-set/storage';
|
||||
import type {
|
||||
APIv1ListIconsBaseResponse,
|
||||
APIv1ListIconsCategorisedResponse,
|
||||
APIv1ListIconsResponse,
|
||||
} from '../../types/server/v1';
|
||||
import { checkJSONPQuery, sendJSONResponse } from '../helpers/json';
|
||||
import { filterPrefixesByPrefix } from '../helpers/prefixes';
|
||||
|
||||
/**
|
||||
* Send API v2 response
|
||||
*
|
||||
* This response ignores the following parameters:
|
||||
* - `aliases` -> always enabled
|
||||
* - `hidden` -> always enabled
|
||||
*
|
||||
* Those parameters are always requested anyway, so does not make sense to re-create data in case they are disabled
|
||||
*/
|
||||
export function generateAPIv1IconsListResponse(
|
||||
query: FastifyRequest['query'],
|
||||
res: FastifyReply,
|
||||
categorised: boolean
|
||||
) {
|
||||
const q = (query || {}) as Record<string, string>;
|
||||
|
||||
const wrap = checkJSONPQuery(q);
|
||||
if (!wrap) {
|
||||
// Invalid JSONP callback
|
||||
res.send(400);
|
||||
return;
|
||||
}
|
||||
|
||||
function parse(prefix: string, iconSet: StoredIconSet): APIv1ListIconsResponse | APIv1ListIconsCategorisedResponse {
|
||||
const v2Cache = iconSet.apiV2IconsCache;
|
||||
const rendered = v2Cache.rendered;
|
||||
|
||||
// Generate common data
|
||||
const base: APIv1ListIconsBaseResponse = {
|
||||
prefix,
|
||||
total: rendered.total,
|
||||
};
|
||||
if (rendered.title) {
|
||||
base.title = rendered.title;
|
||||
}
|
||||
if (q.info && rendered.info) {
|
||||
base.info = rendered.info;
|
||||
}
|
||||
if (q.aliases && rendered.aliases) {
|
||||
base.aliases = rendered.aliases;
|
||||
}
|
||||
if (q.chars && v2Cache.chars) {
|
||||
base.chars = v2Cache.chars;
|
||||
}
|
||||
|
||||
// Add icons
|
||||
if (categorised) {
|
||||
const result = base as APIv1ListIconsCategorisedResponse;
|
||||
if (rendered.categories) {
|
||||
result.categories = rendered.categories;
|
||||
}
|
||||
if (rendered.uncategorized) {
|
||||
result.uncategorized = rendered.uncategorized;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const result = base as APIv1ListIconsResponse;
|
||||
result.icons = Array.from(iconSet.icons.visible);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (q.prefix) {
|
||||
const prefix = q.prefix;
|
||||
const iconSet = iconSets[prefix]?.item;
|
||||
if (!iconSet) {
|
||||
res.send(404);
|
||||
return;
|
||||
}
|
||||
sendJSONResponse(parse(prefix, iconSet), q, wrap, res);
|
||||
return;
|
||||
}
|
||||
|
||||
if (q.prefixes) {
|
||||
const prefixes = filterPrefixesByPrefix(
|
||||
getPrefixes(),
|
||||
{
|
||||
prefixes: q.prefixes,
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// Retrieve all items
|
||||
interface Item {
|
||||
prefix: string;
|
||||
iconSet: StoredIconSet;
|
||||
}
|
||||
const items: Item[] = [];
|
||||
for (let i = 0; i < prefixes.length; i++) {
|
||||
const prefix = prefixes[i];
|
||||
const iconSet = iconSets[prefix]?.item;
|
||||
if (iconSet) {
|
||||
items.push({
|
||||
prefix,
|
||||
iconSet,
|
||||
});
|
||||
if (items.length > 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!items.length) {
|
||||
// Empty list
|
||||
res.send(404);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all items
|
||||
const result = Object.create(null) as Record<string, ReturnType<typeof parse>>;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
result[item.prefix] = parse(item.prefix, item.iconSet);
|
||||
}
|
||||
sendJSONResponse(result, q, wrap, res);
|
||||
return;
|
||||
}
|
||||
|
||||
// Invalid
|
||||
res.send(400);
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||
import { generateIconSetIconsTree } from '../../data/icon-set/lists/icons';
|
||||
import { iconSets } from '../../data/icon-sets';
|
||||
import type { APIv2CollectionResponse } from '../../types/server/v2';
|
||||
import { checkJSONPQuery, sendJSONResponse } from '../helpers/json';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
import type { IconifyInfo, IconifyJSON } from '@iconify/types';
|
||||
|
||||
/**
|
||||
* /list-icons
|
||||
* /list-icons-categorized
|
||||
*
|
||||
* Do not use, supported only for legacy software that should no longer be used
|
||||
*/
|
||||
export interface APIv1ListIconsParams {
|
||||
// Icon set prefix
|
||||
prefix: string;
|
||||
|
||||
// Include info in response
|
||||
info?: boolean;
|
||||
|
||||
// Include aliases in response
|
||||
aliases?: boolean;
|
||||
|
||||
// Include characters in response
|
||||
chars?: boolean;
|
||||
}
|
||||
|
||||
export interface APIv1ListIconsBaseResponse {
|
||||
// Icon set prefix
|
||||
prefix: string;
|
||||
|
||||
// Number of icons (duplicate of info?.total)
|
||||
total: number;
|
||||
|
||||
// Icon set title, if available (duplicate of info?.name)
|
||||
title?: string;
|
||||
|
||||
// Icon set info
|
||||
info?: IconifyInfo;
|
||||
|
||||
// List of aliases, key = alias, value = parent icon
|
||||
aliases?: Record<string, string>;
|
||||
|
||||
// Characters, key = character, value = icon name
|
||||
chars?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface APIv1ListIconsResponse extends APIv1ListIconsBaseResponse {
|
||||
// Icons
|
||||
icons: string[];
|
||||
}
|
||||
|
||||
export interface APIv1ListIconsCategorisedResponse extends APIv1ListIconsBaseResponse {
|
||||
// Icons, sorted by category
|
||||
categories?: Record<string, string[]>;
|
||||
|
||||
// Icons, sorted by category
|
||||
uncategorized?: string[];
|
||||
|
||||
// Themes
|
||||
themes?: IconifyJSON['themes'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as above, but with `prefixes` parameter set
|
||||
*
|
||||
* Result is object, where prefix is key, value is icons list
|
||||
*/
|
||||
export interface APIv1ListIconsPrefixedParams extends Omit<APIv1ListIconsParams, 'prefix'> {
|
||||
// Comma separated list of prefix matches: 'mdi,mdi-'
|
||||
// If value ends with '-', it is treated as partial prefix
|
||||
prefixes: string;
|
||||
}
|
||||
|
||||
export type APIv1ListIconsPrefixedResponse = Record<string, APIv1ListIconsResponse>;
|
||||
|
||||
export type APIv1ListIconsCategorisedPrefixedResponse = Record<string, APIv1ListIconsCategorisedResponse>;
|
||||
Loading…
Reference in New Issue