diff --git a/src/http/helpers/prefixes.ts b/src/http/helpers/prefixes.ts new file mode 100644 index 0000000..305b3cf --- /dev/null +++ b/src/http/helpers/prefixes.ts @@ -0,0 +1,55 @@ +interface MatchPrefixesParams { + // One prefix + prefix?: string; + + // Comma separated prefixes + prefixes?: string; +} + +/** + * Filter prefixes + * + * 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[] { + const exactMatch = params.prefix; + if (exactMatch) { + // Exact match + return prefixes.indexOf(exactMatch) === -1 ? [] : [exactMatch]; + } + + const partialMatch = params.prefixes; + if (partialMatch) { + // Split matches by partial and full + const exact: Set = new Set(); + const partial: string[] = []; + + partialMatch.split(',').forEach((prefix) => { + if (prefix.slice(-1) === '-') { + // Partial prefix: 'mdi-' + partial.push(prefix); + } else { + // Exact match + exact.add(prefix); + } + }); + + // Filter prefixes + return prefixes.filter((prefix) => { + if (exact.has(prefix)) { + return true; + } + for (let i = 0; i < partial.length; i++) { + const match = partial[i]; + if (prefix.slice(0, match.length) === match) { + return true; + } + } + return false; + }); + } + + // No filters + return returnEmpty ? [] : prefixes; +} diff --git a/src/http/index.ts b/src/http/index.ts index 67c2c6d..981bec0 100644 --- a/src/http/index.ts +++ b/src/http/index.ts @@ -3,6 +3,7 @@ import { appConfig } from '../config/app'; import { runWhenLoaded } from '../data/loading'; import { iconNameRoutePartialRegEx, iconNameRouteRegEx, splitIconName } from '../misc/name'; import { generateIconsDataResponse } from './responses/icons'; +import { generateLastModifiedResponse } from './responses/modified'; import { generateSVGResponse } from './responses/svg'; import { initVersionResponse, versionResponse } from './responses/version'; @@ -97,6 +98,13 @@ export async function startHTTPServer() { }); }); + // Last modification time + server.get('/last-modified', (req, res) => { + runWhenLoaded(() => { + generateLastModifiedResponse(req.query, res); + }); + }); + // Options server.options('/*', (req, res) => { res.send(200); diff --git a/src/http/responses/modified.ts b/src/http/responses/modified.ts new file mode 100644 index 0000000..fef7fff --- /dev/null +++ b/src/http/responses/modified.ts @@ -0,0 +1,47 @@ +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'; + +/** + * Generate icons data + */ +export function generateLastModifiedResponse(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 = filterPrefixes(getPrefixes(), q, false); + + // Generate result + const lastModified = Object.create(null) as Record; + const response: LastModifiedAPIResponse = { + lastModified, + }; + let found = false; + + for (let i = 0; i < prefixes.length; i++) { + const prefix = prefixes[i]; + const item = iconSets[prefix]; + if (item) { + const value = item.item.common.lastModified; + if (value) { + found = true; + lastModified[prefix] = value; + } + } + } + + if (!found) { + // No matches + res.send(404); + return; + } + sendJSONResponse(response, q, wrap, res); +} diff --git a/src/types/server/modified.ts b/src/types/server/modified.ts new file mode 100644 index 0000000..1a7333e --- /dev/null +++ b/src/types/server/modified.ts @@ -0,0 +1,8 @@ +/** + * Response for `/last-modified` query + * + * Key is prefix, value is last modification time number + */ +export interface LastModifiedAPIResponse { + lastModified: Record; +}