mirror of
https://github.com/Mibew/simple-icons.git
synced 2024-11-15 09:54:11 +03:00
convert scripts to esm (#6946)
* convert scripts to esm * fix tests * fix tests * fix lints * syncFs to fsSync * named export for fs Co-authored-by: LitoMore <LitoMore@users.noreply.github.com> * fsSync to { promises as fs } * convert update-svgs-count to esm * rename data to icons * fix build script * switch svglintrc file to mjs * use node: protocol * pluralize getIcons Co-authored-by: LitoMore <LitoMore@users.noreply.github.com>
This commit is contained in:
parent
0150cbd986
commit
a930dc57ec
@ -1,11 +1,28 @@
|
||||
const fs = require('fs');
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import {
|
||||
getDirnameFromImportMeta,
|
||||
htmlFriendlyToTitle,
|
||||
} from './scripts/utils.js';
|
||||
import svgpath from 'svgpath';
|
||||
import svgPathBbox from 'svg-path-bbox';
|
||||
import parsePath from 'svg-path-segments';
|
||||
|
||||
const data = require('./_data/simple-icons.json');
|
||||
const { htmlFriendlyToTitle } = require('./scripts/utils.js');
|
||||
const htmlNamedEntities = require('named-html-entities-json');
|
||||
const svgpath = require('svgpath');
|
||||
const svgPathBbox = require('svg-path-bbox');
|
||||
const parsePath = require('svg-path-segments');
|
||||
const __dirname = getDirnameFromImportMeta(import.meta.url);
|
||||
const dataFile = path.join(__dirname, '_data', 'simple-icons.json');
|
||||
const htmlNamedEntitiesFile = path.join(
|
||||
__dirname,
|
||||
'node_modules',
|
||||
'named-html-entities-json',
|
||||
'index.json',
|
||||
);
|
||||
const svglintIgnoredFile = path.join(__dirname, '.svglint-ignored.json');
|
||||
|
||||
const data = JSON.parse(fs.readFileSync(dataFile, 'utf8'));
|
||||
const htmlNamedEntities = JSON.parse(
|
||||
fs.readFileSync(htmlNamedEntitiesFile, 'utf8'),
|
||||
);
|
||||
const svglintIgnores = JSON.parse(fs.readFileSync(svglintIgnoredFile, 'utf8'));
|
||||
|
||||
const svgRegexp =
|
||||
/^<svg( [^\s]*=".*"){3}><title>.*<\/title><path d=".*"\/><\/svg>\n?$/;
|
||||
@ -19,7 +36,7 @@ const iconTolerance = 0.001;
|
||||
// set env SI_UPDATE_IGNORE to recreate the ignore file
|
||||
const updateIgnoreFile = process.env.SI_UPDATE_IGNORE === 'true';
|
||||
const ignoreFile = './.svglint-ignored.json';
|
||||
const iconIgnored = !updateIgnoreFile ? require(ignoreFile) : {};
|
||||
const iconIgnored = !updateIgnoreFile ? svglintIgnores : {};
|
||||
|
||||
const sortObjectByKey = (obj) => {
|
||||
return Object.keys(obj)
|
||||
@ -126,7 +143,7 @@ const ignoreIcon = (linterName, path, $) => {
|
||||
iconIgnored[linterName][path] = iconName;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
rules: {
|
||||
elm: {
|
||||
svg: 1,
|
@ -56,12 +56,12 @@
|
||||
"our-lint": "node scripts/lint/ourlint.js",
|
||||
"jslint": "prettier --check .",
|
||||
"jsonlint": "node scripts/lint/jsonlint.js",
|
||||
"svglint": "svglint icons/*.svg --ci",
|
||||
"svglint": "svglint icons/*.svg --ci --config .svglintrc.mjs",
|
||||
"wslint": "editorconfig-checker",
|
||||
"prepare": "is-ci || husky install",
|
||||
"prepublishOnly": "npm run build",
|
||||
"postpublish": "npm run clean",
|
||||
"test": "node --experimental-specifier-resolution=node node_modules/uvu/bin.js",
|
||||
"test": "uvu",
|
||||
"pretest": "npm run prepublishOnly",
|
||||
"posttest": "npm run postpublish",
|
||||
"svgo": "svgo --config svgo.config.js",
|
||||
|
@ -7,15 +7,24 @@
|
||||
* tree-shakeable
|
||||
*/
|
||||
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
const util = require('util');
|
||||
const { transform: esbuildTransform } = require('esbuild');
|
||||
import { promises as fs } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import util from 'node:util';
|
||||
import { transform as esbuildTransform } from 'esbuild';
|
||||
import {
|
||||
getIconSlug,
|
||||
svgToPath,
|
||||
titleToHtmlFriendly,
|
||||
slugToVariableName,
|
||||
getIconsData,
|
||||
getDirnameFromImportMeta,
|
||||
} from '../utils.js';
|
||||
|
||||
const __dirname = getDirnameFromImportMeta(import.meta.url);
|
||||
|
||||
const UTF8 = 'utf8';
|
||||
|
||||
const rootDir = path.resolve(__dirname, '..', '..');
|
||||
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
|
||||
const indexFile = path.resolve(rootDir, 'index.js');
|
||||
const iconsDir = path.resolve(rootDir, 'icons');
|
||||
const iconsJsFile = path.resolve(rootDir, 'icons.js');
|
||||
@ -26,15 +35,8 @@ const templatesDir = path.resolve(__dirname, 'templates');
|
||||
const indexTemplateFile = path.resolve(templatesDir, 'index.js');
|
||||
const iconObjectTemplateFile = path.resolve(templatesDir, 'icon-object.js');
|
||||
|
||||
const data = require(dataFile);
|
||||
const {
|
||||
getIconSlug,
|
||||
svgToPath,
|
||||
titleToHtmlFriendly,
|
||||
slugToVariableName,
|
||||
} = require('../utils.js');
|
||||
|
||||
const build = async () => {
|
||||
const icons = await getIconsData();
|
||||
const indexTemplate = await fs.readFile(indexTemplateFile, UTF8);
|
||||
const iconObjectTemplate = await fs.readFile(iconObjectTemplateFile, UTF8);
|
||||
|
||||
@ -82,16 +84,16 @@ const build = async () => {
|
||||
const iconsBarrelMjs = [];
|
||||
const iconsBarrelJs = [];
|
||||
const iconsBarrelDts = [];
|
||||
const icons = [];
|
||||
const buildIcons = [];
|
||||
|
||||
await Promise.all(
|
||||
data.icons.map(async (icon) => {
|
||||
icons.map(async (icon) => {
|
||||
const filename = getIconSlug(icon);
|
||||
const svgFilepath = path.resolve(iconsDir, `${filename}.svg`);
|
||||
icon.svg = (await fs.readFile(svgFilepath, UTF8)).replace(/\r?\n/, '');
|
||||
icon.path = svgToPath(icon.svg);
|
||||
icon.slug = filename;
|
||||
icons.push(icon);
|
||||
buildIcons.push(icon);
|
||||
|
||||
const iconObject = iconToObject(icon);
|
||||
|
||||
@ -126,7 +128,7 @@ const build = async () => {
|
||||
// write our generic index.js
|
||||
const rawIndexJs = util.format(
|
||||
indexTemplate,
|
||||
icons.map(iconToKeyValue).join(','),
|
||||
buildIcons.map(iconToKeyValue).join(','),
|
||||
);
|
||||
await writeJs(indexFile, rawIndexJs);
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* icon SVG filename to standard output.
|
||||
*/
|
||||
|
||||
const { titleToSlug } = require('./utils.js');
|
||||
import { titleToSlug } from './utils.js';
|
||||
|
||||
if (process.argv.length < 3) {
|
||||
console.error('Provide a brand name as argument');
|
||||
|
@ -4,23 +4,30 @@
|
||||
* CLI tool to run jsonschema on the simple-icons.json data file.
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const { Validator } = require('jsonschema');
|
||||
import { promises as fs } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { Validator } from 'jsonschema';
|
||||
import { getDirnameFromImportMeta, getIconsData } from '../utils.js';
|
||||
|
||||
const __dirname = getDirnameFromImportMeta(import.meta.url);
|
||||
|
||||
const rootDir = path.resolve(__dirname, '..', '..');
|
||||
const schemaFile = path.resolve(rootDir, '.jsonschema.json');
|
||||
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
|
||||
|
||||
const schema = require(schemaFile);
|
||||
const data = require(dataFile);
|
||||
(async () => {
|
||||
const icons = await getIconsData();
|
||||
const schema = JSON.parse(await fs.readFile(schemaFile, 'utf8'));
|
||||
|
||||
const validator = new Validator();
|
||||
const result = validator.validate(data, schema);
|
||||
if (result.errors.length > 0) {
|
||||
result.errors.forEach((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
const validator = new Validator();
|
||||
const result = validator.validate({ icons }, schema);
|
||||
if (result.errors.length > 0) {
|
||||
result.errors.forEach((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
console.error(`Found ${result.errors.length} error(s) in simple-icons.json`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.error(
|
||||
`Found ${result.errors.length} error(s) in simple-icons.json`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
|
@ -5,16 +5,8 @@
|
||||
* linters (e.g. jsonlint/svglint).
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const fakeDiff = require('fake-diff');
|
||||
|
||||
const UTF8 = 'utf8';
|
||||
|
||||
const rootDir = path.resolve(__dirname, '..', '..');
|
||||
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
|
||||
const data = require(dataFile);
|
||||
import fakeDiff from 'fake-diff';
|
||||
import { getIconsDataString } from '../utils.js';
|
||||
|
||||
/**
|
||||
* Contains our tests so they can be isolated from each other.
|
||||
@ -22,7 +14,7 @@ const data = require(dataFile);
|
||||
*/
|
||||
const TESTS = {
|
||||
/* Tests whether our icons are in alphabetical order */
|
||||
alphabetical: () => {
|
||||
alphabetical: (data) => {
|
||||
const collector = (invalidEntries, icon, index, array) => {
|
||||
if (index > 0) {
|
||||
const prev = array[index - 1];
|
||||
@ -54,22 +46,30 @@ const TESTS = {
|
||||
},
|
||||
|
||||
/* Check the formatting of the data file */
|
||||
prettified: () => {
|
||||
const dataString = fs.readFileSync(dataFile, UTF8).replace(/\r\n/g, '\n');
|
||||
prettified: async (data, dataString) => {
|
||||
const normalizedDataString = dataString.replace(/\r\n/g, '\n');
|
||||
const dataPretty = `${JSON.stringify(data, null, ' ')}\n`;
|
||||
if (dataString !== dataPretty) {
|
||||
const dataDiff = fakeDiff(dataString, dataPretty);
|
||||
|
||||
if (normalizedDataString !== dataPretty) {
|
||||
const dataDiff = fakeDiff(normalizedDataString, dataPretty);
|
||||
return `Data file is formatted incorrectly:\n\n${dataDiff}`;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// execute all tests and log all errors
|
||||
const errors = Object.keys(TESTS)
|
||||
.map((k) => TESTS[k]())
|
||||
.filter(Boolean);
|
||||
(async () => {
|
||||
const dataString = await getIconsDataString();
|
||||
const data = JSON.parse(dataString);
|
||||
|
||||
if (errors.length > 0) {
|
||||
errors.forEach((error) => console.error(`\u001b[31m${error}\u001b[0m`));
|
||||
process.exit(1);
|
||||
}
|
||||
const errors = (
|
||||
await Promise.all(
|
||||
Object.keys(TESTS).map((test) => TESTS[test](data, dataString)),
|
||||
)
|
||||
).filter(Boolean);
|
||||
|
||||
if (errors.length > 0) {
|
||||
errors.forEach((error) => console.error(`\u001b[31m${error}\u001b[0m`));
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
|
3
scripts/package.json
Normal file
3
scripts/package.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
@ -4,8 +4,11 @@
|
||||
* Updates the version of this package to the CLI specified version.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { getDirnameFromImportMeta } from '../utils.js';
|
||||
|
||||
const __dirname = getDirnameFromImportMeta(import.meta.url);
|
||||
|
||||
const rootDir = path.resolve(__dirname, '..', '..');
|
||||
const packageJsonFile = path.resolve(rootDir, 'package.json');
|
||||
|
@ -5,8 +5,11 @@
|
||||
* NPM package manifest. Does nothing if the README.md is already up-to-date.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { getDirnameFromImportMeta } from '../utils.js';
|
||||
|
||||
const __dirname = getDirnameFromImportMeta(import.meta.url);
|
||||
|
||||
const rootDir = path.resolve(__dirname, '..', '..');
|
||||
const packageJsonFile = path.resolve(rootDir, 'package.json');
|
||||
|
@ -4,16 +4,17 @@
|
||||
* Generates a MarkDown file that lists every brand name and their slug.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import { promises as fs } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { getIconsData, getIconSlug } from '../utils.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const rootDir = path.resolve(__dirname, '..', '..');
|
||||
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
|
||||
const slugsFile = path.resolve(rootDir, 'slugs.md');
|
||||
|
||||
const data = require(dataFile);
|
||||
const { getIconSlug } = require('../utils.js');
|
||||
|
||||
let content = `<!--
|
||||
This file is automatically generated. If you want to change something, please
|
||||
update the script at '${path.relative(rootDir, __filename)}'.
|
||||
@ -25,10 +26,14 @@ update the script at '${path.relative(rootDir, __filename)}'.
|
||||
| :--- | :--- |
|
||||
`;
|
||||
|
||||
data.icons.forEach((icon) => {
|
||||
const brandName = icon.title;
|
||||
const brandSlug = getIconSlug(icon);
|
||||
content += `| \`${brandName}\` | \`${brandSlug}\` |\n`;
|
||||
});
|
||||
(async () => {
|
||||
const icons = await getIconsData();
|
||||
|
||||
fs.writeFileSync(slugsFile, content);
|
||||
icons.forEach((icon) => {
|
||||
const brandName = icon.title;
|
||||
const brandSlug = getIconSlug(icon);
|
||||
content += `| \`${brandName}\` | \`${brandSlug}\` |\n`;
|
||||
});
|
||||
|
||||
await fs.writeFile(slugsFile, content);
|
||||
})();
|
||||
|
@ -5,34 +5,39 @@
|
||||
* at README every time the number of current icons is more than `updateRange`
|
||||
* more than the previous milestone.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import { promises as fs } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { getDirnameFromImportMeta, getIconsData } from '../utils.js';
|
||||
|
||||
const regexMatcher = /Over\s(\d+)\s/;
|
||||
const updateRange = 100;
|
||||
|
||||
const __dirname = getDirnameFromImportMeta(import.meta.url);
|
||||
|
||||
const rootDir = path.resolve(__dirname, '..', '..');
|
||||
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
|
||||
const readmeFile = path.resolve(rootDir, 'README.md');
|
||||
const readmeContent = fs.readFileSync(readmeFile, 'utf-8');
|
||||
|
||||
let overNIconsInReadme;
|
||||
try {
|
||||
overNIconsInReadme = parseInt(regexMatcher.exec(readmeContent)[1]);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
'Failed to obtain number of SVG icons of current milestone in README:',
|
||||
err,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
(async () => {
|
||||
const readmeContent = await fs.readFile(readmeFile, 'utf-8');
|
||||
|
||||
const nIcons = require(dataFile).icons.length,
|
||||
newNIcons = overNIconsInReadme + updateRange;
|
||||
if (nIcons <= newNIcons) {
|
||||
process.exit(0);
|
||||
}
|
||||
let overNIconsInReadme;
|
||||
try {
|
||||
overNIconsInReadme = parseInt(regexMatcher.exec(readmeContent)[1]);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
'Failed to obtain number of SVG icons of current milestone in README:',
|
||||
err,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const newContent = readmeContent.replace(regexMatcher, `Over ${newNIcons} `);
|
||||
fs.writeFileSync(readmeFile, newContent);
|
||||
const nIcons = (await getIconsData()).length;
|
||||
const newNIcons = overNIconsInReadme + updateRange;
|
||||
|
||||
if (nIcons <= newNIcons) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const newContent = readmeContent.replace(regexMatcher, `Over ${newNIcons} `);
|
||||
await fs.writeFile(readmeFile, newContent);
|
||||
})();
|
||||
|
163
scripts/utils.js
163
scripts/utils.js
@ -3,76 +3,103 @@
|
||||
* Some common utilities for scripts.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Get the slug/filename for an icon.
|
||||
* @param {Object} icon The icon data as it appears in _data/simple-icons.json
|
||||
*/
|
||||
getIconSlug: (icon) => icon.slug || module.exports.titleToSlug(icon.title),
|
||||
import path from 'node:path';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
/**
|
||||
* Extract the path from an icon SVG content.
|
||||
* @param {Object} svg The icon SVG content
|
||||
**/
|
||||
svgToPath: (svg) => svg.match(/<path\s+d="([^"]*)/)[1],
|
||||
/**
|
||||
* Get the slug/filename for an icon.
|
||||
* @param {Object} icon The icon data as it appears in _data/simple-icons.json
|
||||
*/
|
||||
export const getIconSlug = (icon) => icon.slug || titleToSlug(icon.title);
|
||||
|
||||
/**
|
||||
* Converts a brand title into a slug/filename.
|
||||
* @param {String} title The title to convert
|
||||
*/
|
||||
titleToSlug: (title) =>
|
||||
title
|
||||
.toLowerCase()
|
||||
.replace(/\+/g, 'plus')
|
||||
.replace(/\./g, 'dot')
|
||||
.replace(/&/g, 'and')
|
||||
.replace(/đ/g, 'd')
|
||||
.replace(/ħ/g, 'h')
|
||||
.replace(/ı/g, 'i')
|
||||
.replace(/ĸ/g, 'k')
|
||||
.replace(/ŀ/g, 'l')
|
||||
.replace(/ł/g, 'l')
|
||||
.replace(/ß/g, 'ss')
|
||||
.replace(/ŧ/g, 't')
|
||||
.normalize('NFD')
|
||||
.replace(/[^a-z0-9]/g, ''),
|
||||
/**
|
||||
* Extract the path from an icon SVG content.
|
||||
* @param {Object} svg The icon SVG content
|
||||
**/
|
||||
export const svgToPath = (svg) => svg.match(/<path\s+d="([^"]*)/)[1];
|
||||
|
||||
/**
|
||||
* Converts a brand title in HTML/SVG friendly format into a brand title (as
|
||||
* it is seen in simple-icons.json)
|
||||
* @param {String} htmlFriendlyTitle The title to convert
|
||||
*/
|
||||
htmlFriendlyToTitle: (htmlFriendlyTitle) =>
|
||||
htmlFriendlyTitle
|
||||
.replace(/&#([0-9]+);/g, (_, num) => String.fromCharCode(parseInt(num)))
|
||||
.replace(
|
||||
/&(quot|amp|lt|gt);/g,
|
||||
(_, ref) => ({ quot: '"', amp: '&', lt: '<', gt: '>' }[ref]),
|
||||
),
|
||||
/**
|
||||
* Converts a brand title into a slug/filename.
|
||||
* @param {String} title The title to convert
|
||||
*/
|
||||
export const titleToSlug = (title) =>
|
||||
title
|
||||
.toLowerCase()
|
||||
.replace(/\+/g, 'plus')
|
||||
.replace(/\./g, 'dot')
|
||||
.replace(/&/g, 'and')
|
||||
.replace(/đ/g, 'd')
|
||||
.replace(/ħ/g, 'h')
|
||||
.replace(/ı/g, 'i')
|
||||
.replace(/ĸ/g, 'k')
|
||||
.replace(/ŀ/g, 'l')
|
||||
.replace(/ł/g, 'l')
|
||||
.replace(/ß/g, 'ss')
|
||||
.replace(/ŧ/g, 't')
|
||||
.normalize('NFD')
|
||||
.replace(/[^a-z0-9]/g, '');
|
||||
|
||||
/**
|
||||
* Converts a slug into a variable name that can be exported.
|
||||
* @param {String} slug The slug to convert
|
||||
*/
|
||||
slugToVariableName: (slug) => {
|
||||
const slugFirstLetter = slug[0].toUpperCase();
|
||||
const slugRest = slug.slice(1);
|
||||
return `si${slugFirstLetter}${slugRest}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a brand title (as it is seen in simple-icons.json) into a brand
|
||||
* title in HTML/SVG friendly format.
|
||||
* @param {String} brandTitle The title to convert
|
||||
*/
|
||||
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 slug into a variable name that can be exported.
|
||||
* @param {String} slug The slug to convert
|
||||
*/
|
||||
export const slugToVariableName = (slug) => {
|
||||
const slugFirstLetter = slug[0].toUpperCase();
|
||||
const slugRest = slug.slice(1);
|
||||
return `si${slugFirstLetter}${slugRest}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a brand title (as it is seen in simple-icons.json) into a brand
|
||||
* title in HTML/SVG friendly format.
|
||||
* @param {String} brandTitle The title to convert
|
||||
*/
|
||||
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 simple-icons.json)
|
||||
* @param {String} htmlFriendlyTitle The title to convert
|
||||
*/
|
||||
export const htmlFriendlyToTitle = (htmlFriendlyTitle) =>
|
||||
htmlFriendlyTitle
|
||||
.replace(/&#([0-9]+);/g, (_, num) => String.fromCharCode(parseInt(num)))
|
||||
.replace(
|
||||
/&(quot|amp|lt|gt);/g,
|
||||
(_, ref) => ({ quot: '"', amp: '&', lt: '<', gt: '>' }[ref]),
|
||||
);
|
||||
|
||||
/**
|
||||
* Get contents of _data/simple-icons.json.
|
||||
*/
|
||||
export const getIconsDataString = () => {
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const rootDir = path.resolve(__dirname, '..');
|
||||
const iconDataPath = path.resolve(rootDir, '_data', 'simple-icons.json');
|
||||
return fs.readFile(iconDataPath, 'utf8');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get icon data as object from _data/simple-icons.json.
|
||||
*/
|
||||
export const getIconsData = async () => {
|
||||
const fileContents = await getIconsDataString();
|
||||
return JSON.parse(fileContents).icons;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the directory name from import.meta.url.
|
||||
* @param {String} importMetaUrl import.meta.url
|
||||
*/
|
||||
export const getDirnameFromImportMeta = (importMetaUrl) =>
|
||||
path.dirname(fileURLToPath(importMetaUrl));
|
||||
|
19
tests/icons-cjs.test.js
Normal file
19
tests/icons-cjs.test.js
Normal file
@ -0,0 +1,19 @@
|
||||
import { exec } from 'uvu';
|
||||
import { testIcon } from './test-icon.js';
|
||||
import { getIconSlug, getIconsData } from '../scripts/utils.js';
|
||||
(async () => {
|
||||
console.warn = () => {};
|
||||
|
||||
const icons = await getIconsData();
|
||||
|
||||
const tests = icons.map(async (icon) => {
|
||||
const slug = getIconSlug(icon);
|
||||
const { default: subject } = await import(`../icons/${slug}.js`);
|
||||
|
||||
testIcon(icon, subject, slug);
|
||||
});
|
||||
|
||||
await Promise.all(tests);
|
||||
|
||||
exec();
|
||||
})();
|
22
tests/icons-esm.test.js
Normal file
22
tests/icons-esm.test.js
Normal file
@ -0,0 +1,22 @@
|
||||
import {
|
||||
getIconsData,
|
||||
getIconSlug,
|
||||
slugToVariableName,
|
||||
} from '../scripts/utils.js';
|
||||
import * as simpleIcons from '../icons.mjs';
|
||||
import { testIcon } from './test-icon.js';
|
||||
import { exec } from 'uvu';
|
||||
|
||||
(async () => {
|
||||
const icons = await getIconsData();
|
||||
|
||||
icons.map((icon) => {
|
||||
const slug = getIconSlug(icon);
|
||||
const variableName = slugToVariableName(slug);
|
||||
const subject = simpleIcons[variableName];
|
||||
|
||||
testIcon(icon, subject, slug);
|
||||
});
|
||||
|
||||
exec();
|
||||
})();
|
@ -1,12 +0,0 @@
|
||||
const { icons } = require('../_data/simple-icons.json');
|
||||
const { getIconSlug } = require('../scripts/utils.js');
|
||||
const testIcon = require('./test-icon.js');
|
||||
|
||||
console.warn = () => {};
|
||||
|
||||
icons.forEach((icon) => {
|
||||
const slug = getIconSlug(icon);
|
||||
const subject = require(`../icons/${slug}.js`);
|
||||
|
||||
testIcon(icon, subject, slug);
|
||||
});
|
@ -1,14 +0,0 @@
|
||||
import simpleIconsData from '../_data/simple-icons.json';
|
||||
import utils from '../scripts/utils.js';
|
||||
import * as simpleIcons from '../icons.mjs';
|
||||
import testIcon from './test-icon.js';
|
||||
|
||||
const { getIconSlug, slugToVariableName } = utils;
|
||||
|
||||
simpleIconsData.icons.forEach((icon) => {
|
||||
const slug = getIconSlug(icon);
|
||||
const variableName = slugToVariableName(slug);
|
||||
const subject = simpleIcons[variableName];
|
||||
|
||||
testIcon(icon, subject, slug);
|
||||
});
|
@ -1,27 +1,32 @@
|
||||
const { icons } = require('../_data/simple-icons.json');
|
||||
const simpleIcons = require('../index.js');
|
||||
const { getIconSlug } = require('../scripts/utils');
|
||||
const { test } = require('uvu');
|
||||
const assert = require('uvu/assert');
|
||||
import simpleIcons from '../index.js';
|
||||
import { getIconSlug, getIconsData } from '../scripts/utils.js';
|
||||
import { test, exec } from 'uvu';
|
||||
import * as assert from 'uvu/assert';
|
||||
|
||||
icons.forEach((icon) => {
|
||||
const slug = getIconSlug(icon);
|
||||
(async () => {
|
||||
const icons = await getIconsData();
|
||||
|
||||
test(`'Get' ${icon.title} by its slug`, () => {
|
||||
const found = simpleIcons.Get(slug);
|
||||
assert.ok(found);
|
||||
assert.is(found.title, icon.title);
|
||||
assert.is(found.hex, icon.hex);
|
||||
assert.is(found.source, icon.source);
|
||||
icons.forEach((icon) => {
|
||||
const slug = getIconSlug(icon);
|
||||
|
||||
test(`'Get' ${icon.title} by its slug`, () => {
|
||||
const found = simpleIcons.Get(slug);
|
||||
assert.ok(found);
|
||||
assert.is(found.title, icon.title);
|
||||
assert.is(found.hex, icon.hex);
|
||||
assert.is(found.source, icon.source);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test(`Iterating over simpleIcons only exposes icons`, () => {
|
||||
const iconArray = Object.values(simpleIcons);
|
||||
for (let icon of iconArray) {
|
||||
assert.ok(icon);
|
||||
assert.type(icon, 'object');
|
||||
}
|
||||
});
|
||||
test(`Iterating over simpleIcons only exposes icons`, () => {
|
||||
const iconArray = Object.values(simpleIcons);
|
||||
for (let icon of iconArray) {
|
||||
assert.ok(icon);
|
||||
assert.type(icon, 'object');
|
||||
}
|
||||
});
|
||||
|
||||
test.run();
|
||||
test.run();
|
||||
|
||||
exec();
|
||||
})();
|
||||
|
3
tests/package.json
Normal file
3
tests/package.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { suite } from 'uvu';
|
||||
import * as assert from 'uvu/assert';
|
||||
|
||||
const iconsDir = path.resolve(process.cwd(), 'icons');
|
||||
const { suite } = require('uvu');
|
||||
const assert = require('uvu/assert');
|
||||
|
||||
/**
|
||||
* Checks if icon data matches a subject icon.
|
||||
@ -11,7 +11,7 @@ const assert = require('uvu/assert');
|
||||
* @param {import('..').SimpleIcon} subject Icon to check against icon data
|
||||
* @param {String} slug Icon data slug
|
||||
*/
|
||||
const testIcon = (icon, subject, slug) => {
|
||||
export const testIcon = (icon, subject, slug) => {
|
||||
const test = suite(icon.title);
|
||||
const svgPath = path.resolve(iconsDir, `${slug}.svg`);
|
||||
|
||||
@ -69,5 +69,3 @@ const testIcon = (icon, subject, slug) => {
|
||||
|
||||
test.run();
|
||||
};
|
||||
|
||||
module.exports = testIcon;
|
||||
|
Loading…
Reference in New Issue
Block a user