UNPKG

@publidata/utils-fontawesome

Version:
195 lines (169 loc) 5.79 kB
const FontAwesomeApi = require("../FontAwesomeApi/index.js"); const { isValidFa, isFaKit } = require("../validators"); /** * Provides methods to fetch svgs from FontAwesome */ class FontAwesomeUtils { api; static _kit; static _token; static _cache = new Map(); constructor(token, kit) { this._kit = kit; this._token = token; if (this._token) this.api = new FontAwesomeApi(this._token); } /** * Set the token to use for the api * @param {string} token * @returns {void} * @memberof FontAwesomeSvg * @example FontAwesome.setToken("TOKEN"); */ setToken(token) { this._token = token; this.api = new FontAwesomeApi(this._token); } /** * Set the kit to use for the api * @param {string} kit * @returns {void} * @memberof FontAwesomeSvg * @example * FontAwesomeSvg.setKit("2BC39F11-A80E-4DB4-AA7A-41FC26176101"); */ setKit(kit) { this._kit = kit; } /** * Clear the cache * @returns {void} * @memberof FontAwesomeSvg * @example FontAwesome.clearCache(); */ clearCache() { FontAwesomeUtils._cache.clear(); } /** * Fetch the svg from FontAwesome * @param {string} fa * @returns {Promise<string>} * @memberof FontAwesomeSvg * @example * const fa = "fas fa-nop"; * FontAwesomeSvg.toSgv(fa).then(res => { * console.log(res); * }); */ toSvg(fa) { return new Promise((resolve, reject) => { if (!isValidFa(fa)) return reject(Error("Invalid FontAwesome object")); // Check cache first if (FontAwesomeUtils._cache.has(fa)) { return resolve(FontAwesomeUtils._cache.get(fa)); } const iconName = fa.replace("fa-", "").split(" ")[1]; if (!this._token) reject(Error("FontAwesome token not set")); if (!isFaKit(fa)) { return this.api.getIcon(iconName).then((icon) => { const svg = icon?.html; if (svg) FontAwesomeUtils._cache.set(fa, svg); resolve(svg); }); } if (!this._kit) reject(Error("FontAwesome kit not set")); this.api.kitIcons(this._kit, [iconName]).then((icons) => { if (!icons.length) reject(Error("Invalid FontAwesome custom icon")); const asSvg = faKitAsSvg(icons[0]); if (!asSvg) console.log( `Error while converting to svg, this icon is invalid : ${iconName} for kit ${this._kit}` ); if (asSvg) FontAwesomeUtils._cache.set(fa, asSvg); resolve(asSvg); }); }); } toSvgs(fas) { return new Promise((resolve, reject) => { if (!Array.isArray(fas)) reject(Error("Invalid FontAwesome array")); const cleanFas = fas.filter(isValidFa); const kitFas = cleanFas.filter(isFaKit); const nativeFas = cleanFas.filter((fa) => !isFaKit(fa)); const hasSvgKey = (fa) => fa.svg; if (!this._token) reject(Error("FontAwesome token not set")); // Separate cached and uncached native icons const cachedNative = []; const uncachedNative = []; nativeFas.forEach((fa) => { if (FontAwesomeUtils._cache.has(fa)) { cachedNative.push({ fa, svg: FontAwesomeUtils._cache.get(fa) }); } else { uncachedNative.push(fa); } }); // Fetch only uncached native icons using API in a single request const nativeIconsToFetch = uncachedNative.map((fa) => { const [prefix, iconName] = fa.replace("fa-", "").split(" "); return { prefix, iconName }; }); const nativeIconsPromise = nativeIconsToFetch.length > 0 ? this.api.getIcons(nativeIconsToFetch).then((icons) => { const results = icons.map((icon, index) => { const fa = uncachedNative[index]; const svg = icon?.html; if (svg) FontAwesomeUtils._cache.set(fa, svg); return { fa, svg }; }); return [...cachedNative, ...results.filter(hasSvgKey)]; }) : Promise.resolve(cachedNative); if (!kitFas.length) { return nativeIconsPromise.then(resolve); } if (!this._kit) reject(Error("FontAwesome kit not set")); // Separate cached and uncached kit icons const cachedKit = []; const uncachedKit = []; const uncachedKitNames = []; kitFas.forEach((fa) => { if (FontAwesomeUtils._cache.has(fa)) { cachedKit.push({ fa, svg: FontAwesomeUtils._cache.get(fa) }); } else { uncachedKit.push(fa); uncachedKitNames.push(fa?.replace("fa-", "")?.split(" ")[1]); } }); if (!uncachedKitNames.length) { return nativeIconsPromise.then((nativeSgvs) => { resolve([...nativeSgvs, ...cachedKit]); }); } Promise.all([ nativeIconsPromise, this.api.kitIcons(this._kit, uncachedKitNames) ]).then(([nativeSgvs, icons]) => { let kitSgvs = icons .map((icon, index) => { const fa = `fak fa-${icon.name}`; const svg = faKitAsSvg(icon); if (!svg) console.log( `Error while converting to svg, this icon is invalid : ${uncachedKitNames[index]} for kit ${this._kit}` ); if (svg) FontAwesomeUtils._cache.set(fa, svg); return { fa, svg }; }) .filter(hasSvgKey); const sgvs = [...nativeSgvs, ...cachedKit, ...kitSgvs]; resolve(sgvs); }); }); } } const faKitAsSvg = icon => { if (!icon) return null; const { height, width, path } = icon; return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}"><path d="${path}"></path></svg>`; }; module.exports = new FontAwesomeUtils();