diff --git a/scripts/add-icon-data.js b/scripts/add-icon-data.js index 1f116b823..a1b066f79 100644 --- a/scripts/add-icon-data.js +++ b/scripts/add-icon-data.js @@ -5,6 +5,7 @@ import getRelativeLuminance from 'get-relative-luminance'; import { URL_REGEX, collator, + getJsonSchemaData, getIconsDataString, getIconDataPath, writeIconsData, @@ -15,6 +16,7 @@ import { const hexPattern = /^#?[a-f0-9]{3,8}$/i; const iconsData = JSON.parse(await getIconsDataString()); +const jsonSchema = await getJsonSchemaData(); const titleValidator = (text) => { if (!text) return 'This field is required'; @@ -42,6 +44,18 @@ const hexTransformer = (text) => { return chalk.bgHex(`#${color}`).hex(luminance < 0.4 ? '#fff' : '#000')(text); }; +const aliasesTransformer = (text) => + text + .split(',') + .map((x) => chalk.cyan(x)) + .join(','); + +const aliasesChoices = Object.entries( + jsonSchema.definitions.brand.properties.aliases.properties, +) + .filter(([k]) => ['aka', 'old'].includes(k)) + .map(([k, v]) => ({ name: `${k}: ${v.description}`, value: k })); + const getIconDataFromAnswers = (answers) => ({ title: answers.title, hex: answers.hex, @@ -55,6 +69,21 @@ const getIconDataFromAnswers = (answers) => ({ }, } : {}), + ...(answers.hasAliases + ? { + aliases: aliasesChoices.reduce((previous, current) => { + const promptKey = `${current.value}AliasesList`; + if (answers[promptKey]) + return { + ...previous, + [current.value]: answers[promptKey] + .split(',') + .map((x) => x.trim()), + }; + return previous; + }, {}), + } + : {}), }); const dataPrompt = [ @@ -112,7 +141,29 @@ const dataPrompt = [ }, { type: 'confirm', - name: 'confirm', + name: 'hasAliases', + message: 'The icon has brand aliases?', + default: false, + }, + { + type: 'checkbox', + name: 'aliasesTypes', + message: 'What types of aliases do you want to add?', + choices: aliasesChoices, + when: ({ hasAliases }) => hasAliases, + }, + ...aliasesChoices.map((x) => ({ + type: 'input', + name: `${x.value}AliasesList`, + message: x.value, + suffix: ' (separate with commas)', + validate: (text) => Boolean(text), + transformer: aliasesTransformer, + when: (answers) => answers?.aliasesTypes.includes(x.value), + })), + { + type: 'confirm', + name: 'confirmToAdd', message: (answers) => { const icon = getIconDataFromAnswers(answers); return [ @@ -127,7 +178,7 @@ const dataPrompt = [ const answers = await inquirer.prompt(dataPrompt); const icon = getIconDataFromAnswers(answers); -if (answers.confirm) { +if (answers.confirmToAdd) { iconsData.icons.push(icon); iconsData.icons.sort((a, b) => collator.compare(a.title, b.title)); await writeIconsData(iconsData); diff --git a/scripts/lint/jsonlint.js b/scripts/lint/jsonlint.js index 7e6151578..920d0bd42 100644 --- a/scripts/lint/jsonlint.js +++ b/scripts/lint/jsonlint.js @@ -7,27 +7,23 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { Validator } from 'jsonschema'; -import { getDirnameFromImportMeta, getIconsData } from '../utils.js'; +import { + getDirnameFromImportMeta, + getIconsData, + getJsonSchemaData, +} from '../utils.js'; +const icons = await getIconsData(); const __dirname = getDirnameFromImportMeta(import.meta.url); +const schema = await getJsonSchemaData(path.resolve(__dirname, '..', '..')); -const rootDir = path.resolve(__dirname, '..', '..'); -const schemaFile = path.resolve(rootDir, '.jsonschema.json'); +const validator = new Validator(); +const result = validator.validate({ icons }, schema); +if (result.errors.length > 0) { + result.errors.forEach((error) => { + console.error(error); + }); -(async () => { - const icons = await getIconsData(); - const schema = JSON.parse(await fs.readFile(schemaFile, 'utf8')); - - 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); +} diff --git a/scripts/utils.js b/scripts/utils.js index 8cf6cee36..0d5252dee 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -30,6 +30,16 @@ const TITLE_TO_SLUG_RANGE_REGEX = /[^a-z0-9]/g; export const URL_REGEX = /^https:\/\/[^\s]+$/; +/** + * 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 + */ +export const getDirnameFromImportMeta = (importMetaUrl) => + path.dirname(fileURLToPath(importMetaUrl)); + +const __dirname = getDirnameFromImportMeta(import.meta.url); + /** * Get the slug/filename for an icon. * @param {Object} icon The icon data as it appears in _data/simple-icons.json @@ -95,14 +105,26 @@ export const htmlFriendlyToTitle = (htmlFriendlyTitle) => (_, ref) => ({ quot: '"', amp: '&', lt: '<', gt: '>' }[ref]), ); +/** + * Get JSON schema data. + * @param {String|undefined} rootDir Path to the root directory of the project. + */ +export const getJsonSchemaData = async ( + rootDir = path.resolve(__dirname, '..'), +) => { + const __dirname = getDirnameFromImportMeta(import.meta.url); + const jsonSchemaPath = path.resolve(rootDir, '.jsonschema.json'); + const jsonSchemaString = await fs.readFile(jsonSchemaPath, 'utf8'); + return JSON.parse(jsonSchemaString); +}; + /** * Get path of _data/simpe-icons.json. * @param {String|undefined} rootDir Path to the root directory of the project. */ -export const getIconDataPath = (rootDir) => { - if (rootDir === undefined) { - rootDir = path.resolve(getDirnameFromImportMeta(import.meta.url), '..'); - } +export const getIconDataPath = ( + rootDir = path.resolve(getDirnameFromImportMeta(import.meta.url), '..'), +) => { return path.resolve(rootDir, '_data', 'simple-icons.json'); }; @@ -136,14 +158,6 @@ export const writeIconsData = async (iconsData, rootDir) => { ); }; -/** - * 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 - */ -export const getDirnameFromImportMeta = (importMetaUrl) => - path.dirname(fileURLToPath(importMetaUrl)); - /** * Replace Windows newline characters by Unix ones. * @param {String} text The text to replace