From 5aca42e09a5e250e55ab288f60f0c800a896ad59 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Fri, 23 Sep 2022 10:14:08 +0800 Subject: [PATCH 01/20] Add `add-icon` script --- package.json | 6 +++++- scripts/add-icon.js | 42 ++++++++++++++++++++++++++++++++++++++++++ scripts/utils.js | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 scripts/add-icon.js diff --git a/package.json b/package.json index 307217657fee..5534b69d6de9 100644 --- a/package.json +++ b/package.json @@ -37,12 +37,15 @@ "url": "https://opencollective.com/simple-icons" }, "devDependencies": { + "chalk-pipe": "^5.1.1", "editorconfig-checker": "4.0.2", "esbuild": "0.15.6", "fake-diff": "1.0.0", "husky": "8.0.1", + "inquirer": "^9.1.2", "is-ci": "3.0.1", "jsonschema": "1.4.1", + "log-symbols": "^5.1.0", "mocha": "10.0.0", "named-html-entities-json": "1.0.0", "npm-run-all": "4.1.5", @@ -71,7 +74,8 @@ "pretest": "npm run prepublishOnly", "posttest": "npm run postpublish", "svgo": "svgo --config svgo.config.js", - "get-filename": "node scripts/get-filename.js" + "get-filename": "node scripts/get-filename.js", + "add-icon": "node scripts/add-icon.js" }, "engines": { "node": ">=0.12.18" diff --git a/scripts/add-icon.js b/scripts/add-icon.js new file mode 100644 index 000000000000..98d5f0b0d41c --- /dev/null +++ b/scripts/add-icon.js @@ -0,0 +1,42 @@ +import fs from 'node:fs/promises'; +import inquirer from 'inquirer'; +import chalkPipe from 'chalk-pipe'; +import logSymbols from 'log-symbols'; +import { getIconsDataString, titleToSlug } from './utils.js'; + +const prompts = [ + { + type: 'input', + name: 'title', + message: 'Title', + }, + { + type: 'input', + name: 'hex', + message: 'HEX color', + validate: (text) => /^[a-fA-F0-9]{6}$/.test(text.replace(/^#/, '')), + transformer: (text) => { + return chalkPipe(text.startsWith('#') ? text : `#${text}`)(text); + }, + }, + { + type: 'input', + name: 'source', + message: 'source', + }, +]; + +const icon = await inquirer.prompt(prompts); +const iconsData = JSON.parse(await getIconsDataString()); + +if (iconsData.icons.find((x) => x.title === icon.title)) { + console.error(logSymbols.error, 'Duplicated icon'); + process.exit(1); +} + +console.log( + logSymbols.success, + `Icon added, your icon filename should be: ${chalkPipe('blue')( + titleToSlug(icon.title) + '.svg', + )}`, +); diff --git a/scripts/utils.js b/scripts/utils.js index db0fed588c19..f1de92ba39dc 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -4,7 +4,7 @@ */ import path from 'node:path'; -import { promises as fs } from 'node:fs'; +import fs from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; const TITLE_TO_SLUG_REPLACEMENTS = { From 9e10d1faec820b520ab69a113aab1e4dd4cc33e1 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Fri, 23 Sep 2022 11:00:09 +0800 Subject: [PATCH 02/20] Add write file logic --- scripts/add-icon.js | 11 ++++++++++- scripts/utils.js | 15 +++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/scripts/add-icon.js b/scripts/add-icon.js index 98d5f0b0d41c..220983fe3c34 100644 --- a/scripts/add-icon.js +++ b/scripts/add-icon.js @@ -2,7 +2,7 @@ import fs from 'node:fs/promises'; import inquirer from 'inquirer'; import chalkPipe from 'chalk-pipe'; import logSymbols from 'log-symbols'; -import { getIconsDataString, titleToSlug } from './utils.js'; +import { getIconsDataString, getIconDataPath, titleToSlug } from './utils.js'; const prompts = [ { @@ -34,6 +34,15 @@ if (iconsData.icons.find((x) => x.title === icon.title)) { process.exit(1); } +iconsData.icons.push(icon); +iconsData.icons.sort((a, b) => a.title.localeCompare(b.title)); + +await fs.writeFile( + getIconDataPath(), + JSON.stringify(iconsData, null, 4) + '\n', + 'utf8', +); + console.log( logSymbols.success, `Icon added, your icon filename should be: ${chalkPipe('blue')( diff --git a/scripts/utils.js b/scripts/utils.js index f1de92ba39dc..05299c8f3b3c 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -94,15 +94,22 @@ export const htmlFriendlyToTitle = (htmlFriendlyTitle) => ); /** - * Get contents of _data/simple-icons.json. + * Get path of _data/simpe-icons.json. * @param {String|undefined} rootDir Path to the root directory of the project. */ -export const getIconsDataString = (rootDir) => { +export const getIconDataPath = (rootDir) => { if (rootDir === undefined) { rootDir = path.resolve(getDirnameFromImportMeta(import.meta.url), '..'); } - const iconDataPath = path.resolve(rootDir, '_data', 'simple-icons.json'); - return fs.readFile(iconDataPath, 'utf8'); + return path.resolve(rootDir, '_data', 'simple-icons.json'); +}; + +/** + * Get contents of _data/simple-icons.json. + * @param {String|undefined} rootDir Path to the root directory of the project. + */ +export const getIconsDataString = (rootDir) => { + return fs.readFile(getIconDataPath(rootDir), 'utf8'); }; /** From 40489ece187e00f930d97b9ee62e3d191f4c47fb Mon Sep 17 00:00:00 2001 From: LitoMore Date: Fri, 23 Sep 2022 11:07:31 +0800 Subject: [PATCH 03/20] Format hex color --- scripts/add-icon.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/add-icon.js b/scripts/add-icon.js index 220983fe3c34..112bed02589c 100644 --- a/scripts/add-icon.js +++ b/scripts/add-icon.js @@ -34,7 +34,11 @@ if (iconsData.icons.find((x) => x.title === icon.title)) { process.exit(1); } -iconsData.icons.push(icon); +iconsData.icons.push({ + title: icon.title, + hex: icon.hex.replace(/^#/, '').toUpperCase(), + source: icon.source, +}); iconsData.icons.sort((a, b) => a.title.localeCompare(b.title)); await fs.writeFile( From 2e2c69fd2d5a920d15c7cd8ba25fae2490c7fe07 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Fri, 23 Sep 2022 11:22:37 +0800 Subject: [PATCH 04/20] Add hint --- scripts/add-icon.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/scripts/add-icon.js b/scripts/add-icon.js index 112bed02589c..57a35ea72750 100644 --- a/scripts/add-icon.js +++ b/scripts/add-icon.js @@ -4,17 +4,28 @@ import chalkPipe from 'chalk-pipe'; import logSymbols from 'log-symbols'; import { getIconsDataString, getIconDataPath, titleToSlug } from './utils.js'; +const iconsData = JSON.parse(await getIconsDataString()); + const prompts = [ { type: 'input', name: 'title', + validate: (text) => { + if (!text) return 'This field is required'; + if (iconsData.icons.find((x) => x.title === text)) + return 'This icon title already exist'; + return true; + }, message: 'Title', }, { type: 'input', name: 'hex', - message: 'HEX color', - validate: (text) => /^[a-fA-F0-9]{6}$/.test(text.replace(/^#/, '')), + message: 'Hex', + validate: (text) => + /^[a-fA-F0-9]{6}$/.test(text.replace(/^#/, '')) + ? true + : 'It should be a 6-digit hex code', transformer: (text) => { return chalkPipe(text.startsWith('#') ? text : `#${text}`)(text); }, @@ -23,16 +34,14 @@ const prompts = [ type: 'input', name: 'source', message: 'source', + validate: (text) => + Boolean(text.startsWith('https://') || text.startsWith('http://')) + ? true + : 'It should be a URL', }, ]; const icon = await inquirer.prompt(prompts); -const iconsData = JSON.parse(await getIconsDataString()); - -if (iconsData.icons.find((x) => x.title === icon.title)) { - console.error(logSymbols.error, 'Duplicated icon'); - process.exit(1); -} iconsData.icons.push({ title: icon.title, From 46e0ccf0e9f9daa7ecb827d053c8d4e8b4b235b3 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Fri, 23 Sep 2022 11:23:57 +0800 Subject: [PATCH 05/20] Tweaks --- scripts/add-icon.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/add-icon.js b/scripts/add-icon.js index 57a35ea72750..ecca94a6da01 100644 --- a/scripts/add-icon.js +++ b/scripts/add-icon.js @@ -25,7 +25,7 @@ const prompts = [ validate: (text) => /^[a-fA-F0-9]{6}$/.test(text.replace(/^#/, '')) ? true - : 'It should be a 6-digit hex code', + : 'This should be a 6-digit hex code', transformer: (text) => { return chalkPipe(text.startsWith('#') ? text : `#${text}`)(text); }, @@ -37,7 +37,7 @@ const prompts = [ validate: (text) => Boolean(text.startsWith('https://') || text.startsWith('http://')) ? true - : 'It should be a URL', + : 'This should be a URL', }, ]; From 9f55a8b33ee44259f99c6a829babe002f68cf052 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Fri, 23 Sep 2022 12:23:52 +0800 Subject: [PATCH 06/20] Tweaks --- package.json | 1 + scripts/add-icon.js | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5534b69d6de9..cce911669d03 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "editorconfig-checker": "4.0.2", "esbuild": "0.15.6", "fake-diff": "1.0.0", + "get-relative-luminance": "^1.0.0", "husky": "8.0.1", "inquirer": "^9.1.2", "is-ci": "3.0.1", diff --git a/scripts/add-icon.js b/scripts/add-icon.js index ecca94a6da01..a2e6a9b3d209 100644 --- a/scripts/add-icon.js +++ b/scripts/add-icon.js @@ -2,8 +2,10 @@ import fs from 'node:fs/promises'; import inquirer from 'inquirer'; import chalkPipe from 'chalk-pipe'; import logSymbols from 'log-symbols'; +import getRelativeLuminance from 'get-relative-luminance'; import { getIconsDataString, getIconDataPath, titleToSlug } from './utils.js'; +const hexPattern = /^#?[a-fA-F0-9]{6}$/; const iconsData = JSON.parse(await getIconsDataString()); const prompts = [ @@ -23,17 +25,22 @@ const prompts = [ name: 'hex', message: 'Hex', validate: (text) => - /^[a-fA-F0-9]{6}$/.test(text.replace(/^#/, '')) - ? true - : 'This should be a 6-digit hex code', + hexPattern.test(text) ? true : 'This should be a 6-digit hex code', transformer: (text) => { - return chalkPipe(text.startsWith('#') ? text : `#${text}`)(text); + const color = text.startsWith('#') ? text : `#${text}`; + const luminance = hexPattern.test(text) + ? getRelativeLuminance.default(color) + : -1; + if (luminance === -1) return text; + return chalkPipe(`bg${color}.${luminance < 0.4 ? 'white' : 'black'}`)( + text, + ); }, }, { type: 'input', name: 'source', - message: 'source', + message: 'Source', validate: (text) => Boolean(text.startsWith('https://') || text.startsWith('http://')) ? true From 6495bce6c78fe044cd799d1da3c03d5543613339 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Fri, 23 Sep 2022 12:28:12 +0800 Subject: [PATCH 07/20] Add command hint to contributing doc --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c89ec0c48cfc..678f440a40e7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -265,6 +265,8 @@ Here is the object of a fictional brand as an example: } ``` +You can use `npm run add-icon` to add metadata via a CLI prompt. + Make sure the icon is added in alphabetical order. If you're in doubt, you can always run `npm run our-lint` - this will tell you if any of the JSON data is in the wrong order. #### Optional Data From 9ae29462bcf261830afa7d1be9730e1162d7e034 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sat, 24 Sep 2022 22:57:21 +0800 Subject: [PATCH 08/20] Updates --- _data/simple-icons.json | 10 +++++ package.json | 4 +- scripts/add-icon-data.js | 87 ++++++++++++++++++++++++++++++++++++++++ scripts/add-icon.js | 71 -------------------------------- scripts/lint/ourlint.js | 2 +- scripts/utils.js | 28 +++++++++++++ 6 files changed, 128 insertions(+), 74 deletions(-) create mode 100644 scripts/add-icon-data.js delete mode 100644 scripts/add-icon.js diff --git a/_data/simple-icons.json b/_data/simple-icons.json index 32ee2c761236..e16e82538bca 100644 --- a/_data/simple-icons.json +++ b/_data/simple-icons.json @@ -6370,6 +6370,11 @@ "hex": "00A5BC", "source": "https://litiengine.com/" }, + { + "title": "litomore", + "hex": "FF99CC", + "source": "https://github.com" + }, { "title": "LiveChat", "hex": "FFD000", @@ -10098,6 +10103,11 @@ "type": "CC0-1.0" } }, + { + "title": "simpleiocns", + "hex": "FF99CC", + "source": "https://github.com" + }, { "title": "Simplenote", "hex": "3361CC", diff --git a/package.json b/package.json index cce911669d03..5394d48ea020 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "url": "https://opencollective.com/simple-icons" }, "devDependencies": { - "chalk-pipe": "^5.1.1", + "chalk": "^5.0.1", "editorconfig-checker": "4.0.2", "esbuild": "0.15.6", "fake-diff": "1.0.0", @@ -76,7 +76,7 @@ "posttest": "npm run postpublish", "svgo": "svgo --config svgo.config.js", "get-filename": "node scripts/get-filename.js", - "add-icon": "node scripts/add-icon.js" + "add-icon-data": "node scripts/add-icon-data.js" }, "engines": { "node": ">=0.12.18" diff --git a/scripts/add-icon-data.js b/scripts/add-icon-data.js new file mode 100644 index 000000000000..0bfc0af15632 --- /dev/null +++ b/scripts/add-icon-data.js @@ -0,0 +1,87 @@ +import fs from 'node:fs/promises'; +import inquirer from 'inquirer'; +import chalk from 'chalk'; +import logSymbols from 'log-symbols'; +import getRelativeLuminance from 'get-relative-luminance'; +import { + getIconsDataString, + getIconDataPath, + writeIconsData, + titleToSlug, + normalizeColor, +} from './utils.js'; + +const hexPattern = /^#?[a-f0-9]{3,8}$/i; +const linkPattern = /^https:\/\/[^\s]+$/; + +const iconsData = JSON.parse(await getIconsDataString()); + +const titleValidator = (text) => { + if (!text) return 'This field is required'; + if ( + iconsData.icons.find( + (x) => x.title === text || titleToSlug(x.title) === titleToSlug(text), + ) + ) + return 'This icon title or slug already exist'; + return true; +}; + +const hexValidator = (text) => + hexPattern.test(text) ? true : 'This should be a valid hex code'; + +const sourceValidator = (text) => + linkPattern.test(text) ? true : 'This should be a secure URL'; + +const hexTransformer = (text) => { + const color = normalizeColor(text); + const luminance = hexPattern.test(text) + ? getRelativeLuminance.default(`#${color}`) + : -1; + if (luminance === -1) return text; + return chalk.bgHex(`#${color}`).hex(luminance < 0.4 ? '#fff' : '#000')(text); +}; + +const dataPrompt = [ + { + type: 'input', + name: 'title', + message: 'Title', + validate: titleValidator, + }, + { + type: 'input', + name: 'hex', + message: 'Hex', + validate: hexValidator, + filter: (text) => normalizeColor(text), + transformer: hexTransformer, + }, + { + type: 'input', + name: 'source', + message: 'Source', + validate: sourceValidator, + }, + { + type: 'confirm', + name: 'confirm', + message: (answers) => + [ + 'About to write to simple-icons.json', + chalk.reset(JSON.stringify(answers, null, 4)), + chalk.reset('Is this OK?'), + ].join('\n\n'), + }, +]; + +const { confirm, ...icon } = await inquirer.prompt(dataPrompt); + +if (confirm) { + iconsData.icons.push(icon); + iconsData.icons.sort((a, b) => a.title.localeCompare(b.title)); + await writeIconsData(iconsData); +} else { + console.log('Aborted.'); + process.exit(1); +} diff --git a/scripts/add-icon.js b/scripts/add-icon.js deleted file mode 100644 index a2e6a9b3d209..000000000000 --- a/scripts/add-icon.js +++ /dev/null @@ -1,71 +0,0 @@ -import fs from 'node:fs/promises'; -import inquirer from 'inquirer'; -import chalkPipe from 'chalk-pipe'; -import logSymbols from 'log-symbols'; -import getRelativeLuminance from 'get-relative-luminance'; -import { getIconsDataString, getIconDataPath, titleToSlug } from './utils.js'; - -const hexPattern = /^#?[a-fA-F0-9]{6}$/; -const iconsData = JSON.parse(await getIconsDataString()); - -const prompts = [ - { - type: 'input', - name: 'title', - validate: (text) => { - if (!text) return 'This field is required'; - if (iconsData.icons.find((x) => x.title === text)) - return 'This icon title already exist'; - return true; - }, - message: 'Title', - }, - { - type: 'input', - name: 'hex', - message: 'Hex', - validate: (text) => - hexPattern.test(text) ? true : 'This should be a 6-digit hex code', - transformer: (text) => { - const color = text.startsWith('#') ? text : `#${text}`; - const luminance = hexPattern.test(text) - ? getRelativeLuminance.default(color) - : -1; - if (luminance === -1) return text; - return chalkPipe(`bg${color}.${luminance < 0.4 ? 'white' : 'black'}`)( - text, - ); - }, - }, - { - type: 'input', - name: 'source', - message: 'Source', - validate: (text) => - Boolean(text.startsWith('https://') || text.startsWith('http://')) - ? true - : 'This should be a URL', - }, -]; - -const icon = await inquirer.prompt(prompts); - -iconsData.icons.push({ - title: icon.title, - hex: icon.hex.replace(/^#/, '').toUpperCase(), - source: icon.source, -}); -iconsData.icons.sort((a, b) => a.title.localeCompare(b.title)); - -await fs.writeFile( - getIconDataPath(), - JSON.stringify(iconsData, null, 4) + '\n', - 'utf8', -); - -console.log( - logSymbols.success, - `Icon added, your icon filename should be: ${chalkPipe('blue')( - titleToSlug(icon.title) + '.svg', - )}`, -); diff --git a/scripts/lint/ourlint.js b/scripts/lint/ourlint.js index 677775a4a7c3..01cd915ad8e7 100644 --- a/scripts/lint/ourlint.js +++ b/scripts/lint/ourlint.js @@ -48,7 +48,7 @@ const TESTS = { /* Check the formatting of the data file */ prettified: async (data, dataString) => { const normalizedDataString = normalizeNewlines(dataString); - const dataPretty = `${JSON.stringify(data, null, ' ')}\n`; + const dataPretty = `${JSON.stringify(data, null, 4)}\n`; if (normalizedDataString !== dataPretty) { const dataDiff = fakeDiff(normalizedDataString, dataPretty); diff --git a/scripts/utils.js b/scripts/utils.js index 05299c8f3b3c..eb236692c4ec 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -121,6 +121,20 @@ export const getIconsData = async (rootDir) => { return JSON.parse(fileContents).icons; }; +/** + * Write icons data to _data/simple-icons.json. + * @param {Object} iconsData Icons data object. + * @param {String|undefined} rootDir Path to the root directory of the project. + * + */ +export const writeIconsData = async (iconsData, rootDir) => { + return fs.writeFile( + getIconDataPath(rootDir), + `${JSON.stringify(iconsData, null, 4)}\n`, + 'utf8', + ); +}; + /** * Get the directory name where this file is located from `import.meta.url`, * equivalent to the `__dirname` global variable in CommonJS. @@ -137,6 +151,20 @@ export const normalizeNewlines = (text) => { return text.replace(/\r\n/g, '\n'); }; +/** + * Convert non-6-digit hex color to 6-digit. + * @param {String} text The color text + */ +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. * @param {String} readmePath Path to the README file From 3182d0eb58ee718ac30e51cc6879c191b3cc6f75 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sat, 24 Sep 2022 22:59:35 +0800 Subject: [PATCH 09/20] Remove mock data --- _data/simple-icons.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/_data/simple-icons.json b/_data/simple-icons.json index e16e82538bca..9f492bcddce7 100644 --- a/_data/simple-icons.json +++ b/_data/simple-icons.json @@ -6370,11 +6370,6 @@ "hex": "00A5BC", "source": "https://litiengine.com/" }, - { - "title": "litomore", - "hex": "FF99CC", - "source": "https://github.com" - }, { "title": "LiveChat", "hex": "FFD000", From 2166bc9eaf0de108a6803c5428e970934ae64e0d Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sat, 24 Sep 2022 23:00:43 +0800 Subject: [PATCH 10/20] Fixes --- _data/simple-icons.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/_data/simple-icons.json b/_data/simple-icons.json index 9f492bcddce7..32ee2c761236 100644 --- a/_data/simple-icons.json +++ b/_data/simple-icons.json @@ -10098,11 +10098,6 @@ "type": "CC0-1.0" } }, - { - "title": "simpleiocns", - "hex": "FF99CC", - "source": "https://github.com" - }, { "title": "Simplenote", "hex": "3361CC", From cad9007b8ccb881dd012322ed068bd5812e7de9a Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sat, 24 Sep 2022 23:51:35 +0800 Subject: [PATCH 11/20] Apply locale comparison and URL regex changes --- scripts/add-icon-data.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/add-icon-data.js b/scripts/add-icon-data.js index 0bfc0af15632..b38fd26bee75 100644 --- a/scripts/add-icon-data.js +++ b/scripts/add-icon-data.js @@ -4,6 +4,8 @@ import chalk from 'chalk'; import logSymbols from 'log-symbols'; import getRelativeLuminance from 'get-relative-luminance'; import { + URL_REGEX, + collator, getIconsDataString, getIconDataPath, writeIconsData, @@ -12,7 +14,6 @@ import { } from './utils.js'; const hexPattern = /^#?[a-f0-9]{3,8}$/i; -const linkPattern = /^https:\/\/[^\s]+$/; const iconsData = JSON.parse(await getIconsDataString()); @@ -31,7 +32,7 @@ const hexValidator = (text) => hexPattern.test(text) ? true : 'This should be a valid hex code'; const sourceValidator = (text) => - linkPattern.test(text) ? true : 'This should be a secure URL'; + URL_REGEX.test(text) ? true : 'This should be a secure URL'; const hexTransformer = (text) => { const color = normalizeColor(text); @@ -79,7 +80,7 @@ const { confirm, ...icon } = await inquirer.prompt(dataPrompt); if (confirm) { iconsData.icons.push(icon); - iconsData.icons.sort((a, b) => a.title.localeCompare(b.title)); + iconsData.icons.sort((a, b) => collator.compare(a.title, b.title)); await writeIconsData(iconsData); } else { console.log('Aborted.'); From 64f8ebedd0aa8d8df9a4b3f37337994f4f967807 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sat, 24 Sep 2022 23:54:16 +0800 Subject: [PATCH 12/20] Fix doc --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 60b387c6cf21..e5b6682ae939 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -265,7 +265,7 @@ Here is the object of a fictional brand as an example: } ``` -You can use `npm run add-icon` to add metadata via a CLI prompt. +You can use `npm run add-icon-data` to add metadata via a CLI prompt. Make sure the icon is added in alphabetical order. If you're in doubt, you can always run `npm run our-lint` - this will tell you if any of the JSON data is in the wrong order. From 2bd128343215e3514e5d743c65e045125d513909 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sun, 25 Sep 2022 00:18:18 +0800 Subject: [PATCH 13/20] Remove unused package --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 5394d48ea020..8c047adc0297 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "inquirer": "^9.1.2", "is-ci": "3.0.1", "jsonschema": "1.4.1", - "log-symbols": "^5.1.0", "mocha": "10.0.0", "named-html-entities-json": "1.0.0", "npm-run-all": "4.1.5", From 5e5e178d7373ec9e287c398051cb0fe62dbecdc5 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sun, 25 Sep 2022 00:18:39 +0800 Subject: [PATCH 14/20] Minor fix --- scripts/add-icon-data.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/add-icon-data.js b/scripts/add-icon-data.js index b38fd26bee75..30212015b4c5 100644 --- a/scripts/add-icon-data.js +++ b/scripts/add-icon-data.js @@ -1,7 +1,6 @@ import fs from 'node:fs/promises'; import inquirer from 'inquirer'; import chalk from 'chalk'; -import logSymbols from 'log-symbols'; import getRelativeLuminance from 'get-relative-luminance'; import { URL_REGEX, From a6a33910a6a1917da4950931dfa6f694743d8949 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sun, 25 Sep 2022 00:46:20 +0800 Subject: [PATCH 15/20] Update scripts/add-icon-data.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Álvaro Mondéjar --- scripts/add-icon-data.js | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/scripts/add-icon-data.js b/scripts/add-icon-data.js index 30212015b4c5..0096e1b8a94b 100644 --- a/scripts/add-icon-data.js +++ b/scripts/add-icon-data.js @@ -63,16 +63,35 @@ const dataPrompt = [ message: 'Source', validate: sourceValidator, }, + { + type: 'confirm', + name: 'add-guidelines', + message: 'The icon has brand guidelines?', + }, + { + type: 'input', + name: 'guidelines', + message: 'Guidelines', + validate: sourceValidator, + when: (answers) => answers['add-guidelines'], + }, { type: 'confirm', name: 'confirm', - message: (answers) => - [ + message: (answers) => { + answers = Object.assign( + ...Object.keys(answers) + .filter((key) => !key.includes('-')) + .map((key) => { + return { [key]: answers[key] }; + }), + ); + return [ 'About to write to simple-icons.json', chalk.reset(JSON.stringify(answers, null, 4)), chalk.reset('Is this OK?'), - ].join('\n\n'), - }, + ].join('\n\n'); + }, ]; const { confirm, ...icon } = await inquirer.prompt(dataPrompt); From 0f0673390ee43248609fa3397fb267d68661464a Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sun, 25 Sep 2022 00:55:43 +0800 Subject: [PATCH 16/20] Optimize code --- scripts/add-icon-data.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/scripts/add-icon-data.js b/scripts/add-icon-data.js index 0096e1b8a94b..b9e664d7e5ea 100644 --- a/scripts/add-icon-data.js +++ b/scripts/add-icon-data.js @@ -65,7 +65,7 @@ const dataPrompt = [ }, { type: 'confirm', - name: 'add-guidelines', + name: 'addGuidelines', message: 'The icon has brand guidelines?', }, { @@ -73,25 +73,19 @@ const dataPrompt = [ name: 'guidelines', message: 'Guidelines', validate: sourceValidator, - when: (answers) => answers['add-guidelines'], + when: (answers) => answers.addGuidelines, }, { type: 'confirm', name: 'confirm', - message: (answers) => { - answers = Object.assign( - ...Object.keys(answers) - .filter((key) => !key.includes('-')) - .map((key) => { - return { [key]: answers[key] }; - }), - ); + message: ({ addGuidelines: _, ...icon }) => { return [ 'About to write to simple-icons.json', - chalk.reset(JSON.stringify(answers, null, 4)), + chalk.reset(JSON.stringify(icon, null, 4)), chalk.reset('Is this OK?'), ].join('\n\n'); }, + }, ]; const { confirm, ...icon } = await inquirer.prompt(dataPrompt); From b15bec3bcf0df5d376d4ead1f180cc9b2a02468b Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sun, 25 Sep 2022 00:56:57 +0800 Subject: [PATCH 17/20] Update variable name --- scripts/add-icon-data.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/add-icon-data.js b/scripts/add-icon-data.js index b9e664d7e5ea..f2645c3e84a8 100644 --- a/scripts/add-icon-data.js +++ b/scripts/add-icon-data.js @@ -65,7 +65,7 @@ const dataPrompt = [ }, { type: 'confirm', - name: 'addGuidelines', + name: 'hasGuidelines', message: 'The icon has brand guidelines?', }, { @@ -73,12 +73,12 @@ const dataPrompt = [ name: 'guidelines', message: 'Guidelines', validate: sourceValidator, - when: (answers) => answers.addGuidelines, + when: (answers) => answers.hasGuidelines, }, { type: 'confirm', name: 'confirm', - message: ({ addGuidelines: _, ...icon }) => { + message: ({ hasGuidelines: _, ...icon }) => { return [ 'About to write to simple-icons.json', chalk.reset(JSON.stringify(icon, null, 4)), From c046b535cfed58528644e0513cf28997e8f18d94 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sun, 25 Sep 2022 01:31:53 +0800 Subject: [PATCH 18/20] Add license fields --- scripts/add-icon-data.js | 43 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/scripts/add-icon-data.js b/scripts/add-icon-data.js index f2645c3e84a8..1f53856abcf9 100644 --- a/scripts/add-icon-data.js +++ b/scripts/add-icon-data.js @@ -42,6 +42,21 @@ const hexTransformer = (text) => { return chalk.bgHex(`#${color}`).hex(luminance < 0.4 ? '#fff' : '#000')(text); }; +const getIconDataFromAnswers = (answers) => ({ + title: answers.title, + hex: answers.hex, + source: answers.source, + ...(answers.hasGuidelines ? { guidelines: answers.guidelines } : {}), + ...(answers.hasLicense + ? { + license: { + type: answers.licenseType, + ...(answers.licenseUrl ? { url: answers.licenseUrl } : {}), + }, + } + : {}), +}); + const dataPrompt = [ { type: 'input', @@ -73,12 +88,33 @@ const dataPrompt = [ name: 'guidelines', message: 'Guidelines', validate: sourceValidator, - when: (answers) => answers.hasGuidelines, + when: ({ hasGuidelines }) => hasGuidelines, + }, + { + type: 'confirm', + name: 'hasLicense', + message: 'The icon has brand license?', + }, + { + type: 'input', + name: 'licenseType', + message: 'License type', + validate: (text) => Boolean(text), + when: ({ hasLicense }) => hasLicense, + }, + { + type: 'input', + name: 'licenseUrl', + message: 'License URL', + suffix: ' (optional)', + validate: (text) => !Boolean(text) || sourceValidator(text), + when: ({ hasLicense }) => hasLicense, }, { type: 'confirm', name: 'confirm', - message: ({ hasGuidelines: _, ...icon }) => { + message: (answers) => { + const icon = getIconDataFromAnswers(answers); return [ 'About to write to simple-icons.json', chalk.reset(JSON.stringify(icon, null, 4)), @@ -88,7 +124,8 @@ const dataPrompt = [ }, ]; -const { confirm, ...icon } = await inquirer.prompt(dataPrompt); +const answers = await inquirer.prompt(dataPrompt); +const icon = getIconDataFromAnswers(answers); if (confirm) { iconsData.icons.push(icon); From 3b0f38010d5ef34b090c134537eafc4abde820c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Mond=C3=A9jar?= Date: Sat, 24 Sep 2022 21:46:07 +0200 Subject: [PATCH 19/20] Stylistic minor change --- scripts/utils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/utils.js b/scripts/utils.js index c7453982a739..8cf6cee36653 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -127,7 +127,6 @@ export const getIconsData = async (rootDir) => { * Write icons data to _data/simple-icons.json. * @param {Object} iconsData Icons data object. * @param {String|undefined} rootDir Path to the root directory of the project. - * */ export const writeIconsData = async (iconsData, rootDir) => { return fs.writeFile( From 482eaacdf7dc4158d7114473e704e013113d0662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Mond=C3=A9jar?= Date: Sat, 24 Sep 2022 21:48:15 +0200 Subject: [PATCH 20/20] Fix error --- scripts/add-icon-data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/add-icon-data.js b/scripts/add-icon-data.js index 1f53856abcf9..1f116b823dda 100644 --- a/scripts/add-icon-data.js +++ b/scripts/add-icon-data.js @@ -127,7 +127,7 @@ const dataPrompt = [ const answers = await inquirer.prompt(dataPrompt); const icon = getIconDataFromAnswers(answers); -if (confirm) { +if (answers.confirm) { iconsData.icons.push(icon); iconsData.icons.sort((a, b) => collator.compare(a.title, b.title)); await writeIconsData(iconsData);