mirror of
				https://github.com/Mibew/simple-icons.git
				synced 2025-10-31 18:41:07 +03:00 
			
		
		
		
	* Update all dependencies * Apply format to file --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Álvaro Mondéjar Rubio <mondejar1994@gmail.com>
		
			
				
	
	
		
			223 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			223 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | ||
|  * @fileoverview
 | ||
|  * Simple Icons SDK.
 | ||
|  */
 | ||
| 
 | ||
| import path from 'node:path';
 | ||
| import fs from 'node:fs/promises';
 | ||
| import { fileURLToPath } from 'node:url';
 | ||
| 
 | ||
| /**
 | ||
|  * @typedef {import("./sdk").ThirdPartyExtension} ThirdPartyExtension
 | ||
|  * @typedef {import("./sdk").IconData} IconData
 | ||
|  */
 | ||
| 
 | ||
| const TITLE_TO_SLUG_REPLACEMENTS = {
 | ||
|   '+': 'plus',
 | ||
|   '.': 'dot',
 | ||
|   '&': 'and',
 | ||
|   đ: 'd',
 | ||
|   ħ: 'h',
 | ||
|   ı: 'i',
 | ||
|   ĸ: 'k',
 | ||
|   ŀ: 'l',
 | ||
|   ł: 'l',
 | ||
|   ß: 'ss',
 | ||
|   ŧ: 't',
 | ||
| };
 | ||
| 
 | ||
| const TITLE_TO_SLUG_CHARS_REGEX = RegExp(
 | ||
|   `[${Object.keys(TITLE_TO_SLUG_REPLACEMENTS).join('')}]`,
 | ||
|   'g',
 | ||
| );
 | ||
| 
 | ||
| const TITLE_TO_SLUG_RANGE_REGEX = /[^a-z0-9]/g;
 | ||
| 
 | ||
| /**
 | ||
|  * Regex to validate HTTPs URLs.
 | ||
|  */
 | ||
| export const URL_REGEX = /^https:\/\/[^\s"']+$/;
 | ||
| 
 | ||
| /**
 | ||
|  * Regex to validate SVG paths.
 | ||
|  */
 | ||
| export const SVG_PATH_REGEX = /^m[-mzlhvcsqtae0-9,. ]+$/i;
 | ||
| 
 | ||
| /**
 | ||
|  * Get the directory name where this file is located from `import.meta.url`,
 | ||
|  * equivalent to the `__dirname` global variable in CommonJS.
 | ||
|  * @param {String} importMetaUrl import.meta.url
 | ||
|  * @returns {String} Directory name in which this file is located
 | ||
|  */
 | ||
| export const getDirnameFromImportMeta = (importMetaUrl) =>
 | ||
|   path.dirname(fileURLToPath(importMetaUrl));
 | ||
| 
 | ||
| /**
 | ||
|  * Get the slug/filename for an icon.
 | ||
|  * @param {IconData} icon The icon data as it appears in *_data/simple-icons.json*
 | ||
|  * @returns {String} The slug/filename for the icon
 | ||
|  */
 | ||
| export const getIconSlug = (icon) => icon.slug || titleToSlug(icon.title);
 | ||
| 
 | ||
| /**
 | ||
|  * Extract the path from an icon SVG content.
 | ||
|  * @param {String} svg The icon SVG content
 | ||
|  * @returns {String} The path from the icon SVG content
 | ||
|  **/
 | ||
| export const svgToPath = (svg) => svg.split('"', 8)[7];
 | ||
| 
 | ||
| /**
 | ||
|  * Converts a brand title into a slug/filename.
 | ||
|  * @param {String} title The title to convert
 | ||
|  * @returns {String} The slug/filename for the title
 | ||
|  */
 | ||
| export const titleToSlug = (title) =>
 | ||
|   title
 | ||
|     .toLowerCase()
 | ||
|     .replace(
 | ||
|       TITLE_TO_SLUG_CHARS_REGEX,
 | ||
|       (char) => TITLE_TO_SLUG_REPLACEMENTS[char],
 | ||
|     )
 | ||
|     .normalize('NFD')
 | ||
|     .replace(TITLE_TO_SLUG_RANGE_REGEX, '');
 | ||
| 
 | ||
| /**
 | ||
|  * Converts a slug into a variable name that can be exported.
 | ||
|  * @param {String} slug The slug to convert
 | ||
|  * @returns {String} The variable name for the slug
 | ||
|  */
 | ||
| export const slugToVariableName = (slug) => {
 | ||
|   const slugFirstLetter = slug[0].toUpperCase();
 | ||
|   return `si${slugFirstLetter}${slug.slice(1)}`;
 | ||
| };
 | ||
| 
 | ||
| /**
 | ||
|  * Converts a brand title as defined in *_data/simple-icons.json* into a brand
 | ||
|  * title in HTML/SVG friendly format.
 | ||
|  * @param {String} brandTitle The title to convert
 | ||
|  * @returns {String} The brand title in HTML/SVG friendly format
 | ||
|  */
 | ||
| export const titleToHtmlFriendly = (brandTitle) =>
 | ||
|   brandTitle
 | ||
|     .replace(/&/g, '&')
 | ||
|     .replace(/"/g, '"')
 | ||
|     .replace(/</g, '<')
 | ||
|     .replace(/>/g, '>')
 | ||
|     .replace(/./g, (char) => {
 | ||
|       const charCode = char.charCodeAt(0);
 | ||
|       return charCode > 127 ? `&#${charCode};` : char;
 | ||
|     });
 | ||
| 
 | ||
| /**
 | ||
|  * Converts a brand title in HTML/SVG friendly format into a brand title (as
 | ||
|  * it is seen in *_data/simple-icons.json*)
 | ||
|  * @param {String} htmlFriendlyTitle The title to convert
 | ||
|  * @returns {String} The brand title in HTML/SVG friendly format
 | ||
|  */
 | ||
| export const htmlFriendlyToTitle = (htmlFriendlyTitle) =>
 | ||
|   htmlFriendlyTitle
 | ||
|     .replace(/&#([0-9]+);/g, (_, num) => String.fromCodePoint(parseInt(num)))
 | ||
|     .replace(
 | ||
|       /&(quot|amp|lt|gt);/g,
 | ||
|       (_, ref) => ({ quot: '"', amp: '&', lt: '<', gt: '>' })[ref],
 | ||
|     );
 | ||
| 
 | ||
| /**
 | ||
|  * Get path of *_data/simpe-icons.json*.
 | ||
|  * @param {String} rootDir Path to the root directory of the project
 | ||
|  * @returns {String} Path of *_data/simple-icons.json*
 | ||
|  */
 | ||
| export const getIconDataPath = (
 | ||
|   rootDir = getDirnameFromImportMeta(import.meta.url),
 | ||
| ) => {
 | ||
|   return path.resolve(rootDir, '_data', 'simple-icons.json');
 | ||
| };
 | ||
| 
 | ||
| /**
 | ||
|  * Get contents of *_data/simple-icons.json*.
 | ||
|  * @param {String} rootDir Path to the root directory of the project
 | ||
|  * @returns {String} Content of *_data/simple-icons.json*
 | ||
|  */
 | ||
| export const getIconsDataString = (
 | ||
|   rootDir = getDirnameFromImportMeta(import.meta.url),
 | ||
| ) => {
 | ||
|   return fs.readFile(getIconDataPath(rootDir), 'utf8');
 | ||
| };
 | ||
| 
 | ||
| /**
 | ||
|  * Get icons data as object from *_data/simple-icons.json*.
 | ||
|  * @param {String} rootDir Path to the root directory of the project
 | ||
|  * @returns {IconData[]} Icons data as array from *_data/simple-icons.json*
 | ||
|  */
 | ||
| export const getIconsData = async (
 | ||
|   rootDir = getDirnameFromImportMeta(import.meta.url),
 | ||
| ) => {
 | ||
|   const fileContents = await getIconsDataString(rootDir);
 | ||
|   return JSON.parse(fileContents).icons;
 | ||
| };
 | ||
| 
 | ||
| /**
 | ||
|  * Replace Windows newline characters by Unix ones.
 | ||
|  * @param {String} text The text to replace
 | ||
|  * @returns {String} The text with Windows newline characters replaced by Unix ones
 | ||
|  */
 | ||
| export const normalizeNewlines = (text) => {
 | ||
|   return text.replace(/\r\n/g, '\n');
 | ||
| };
 | ||
| 
 | ||
| /**
 | ||
|  * Convert non-6-digit hex color to 6-digit with the character `#` stripped.
 | ||
|  * @param {String} text The color text
 | ||
|  * @returns {String} The color text in 6-digit hex format
 | ||
|  */
 | ||
| export const normalizeColor = (text) => {
 | ||
|   let color = text.replace('#', '').toUpperCase();
 | ||
|   if (color.length < 6) {
 | ||
|     color = [...color.slice(0, 3)].map((x) => x.repeat(2)).join('');
 | ||
|   } else if (color.length > 6) {
 | ||
|     color = color.slice(0, 6);
 | ||
|   }
 | ||
|   return color;
 | ||
| };
 | ||
| 
 | ||
| /**
 | ||
|  * Get information about third party extensions from the README table.
 | ||
|  * @param {String} readmePath Path to the README file
 | ||
|  * @returns {Promise<ThirdPartyExtension[]>} Information about third party extensions
 | ||
|  */
 | ||
| export const getThirdPartyExtensions = async (
 | ||
|   readmePath = path.join(
 | ||
|     getDirnameFromImportMeta(import.meta.url),
 | ||
|     'README.md',
 | ||
|   ),
 | ||
| ) =>
 | ||
|   normalizeNewlines(await fs.readFile(readmePath, 'utf8'))
 | ||
|     .split('## Third-Party Extensions\n\n')[1]
 | ||
|     .split('\n\n', 1)[0]
 | ||
|     .split('\n')
 | ||
|     .slice(2)
 | ||
|     .map((line) => {
 | ||
|       let [module, author] = line.split(' | ');
 | ||
|       module = module.split('<img src="')[0];
 | ||
|       return {
 | ||
|         module: {
 | ||
|           name: /\[(.+)\]/.exec(module)[1],
 | ||
|           url: /\((.+)\)/.exec(module)[1],
 | ||
|         },
 | ||
|         author: {
 | ||
|           name: /\[(.+)\]/.exec(author)[1],
 | ||
|           url: /\((.+)\)/.exec(author)[1],
 | ||
|         },
 | ||
|       };
 | ||
|     });
 | ||
| 
 | ||
| /**
 | ||
|  * `Intl.Collator` object ready to be used for icon titles sorting.
 | ||
|  * @type {Intl.Collator}
 | ||
|  * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator Intl.Collator}
 | ||
|  **/
 | ||
| export const collator = new Intl.Collator('en', {
 | ||
|   usage: 'search',
 | ||
|   caseFirst: 'upper',
 | ||
| });
 |