1
0
mirror of https://github.com/simple-icons/simple-icons.git synced 2025-01-05 01:20:39 +02:00

Refactor JSONSchema and URL checks (#10276)

This commit is contained in:
Álvaro Mondéjar Rubio 2024-05-22 09:13:35 +02:00 committed by GitHub
parent 3e65e780f6
commit 788014313d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 33 additions and 24 deletions

View File

@ -599,9 +599,8 @@
"required": ["type", "url"], "required": ["type", "url"],
"properties": { "properties": {
"type": { "type": {
"description": "The license name or 'custom'", "description": "Custom license type",
"type": "string", "const": "custom"
"enum": ["custom"]
}, },
"url": { "url": {
"description": "The URL to the license text by the brand", "description": "The URL to the license text by the brand",
@ -617,7 +616,7 @@
}, },
"duplicate": { "duplicate": {
"$id": "#duplicate", "$id": "#duplicate",
"description": "A \"dup\" brand", "description": "A brand that uses the same icon",
"type": "object", "type": "object",
"required": ["title"], "required": ["title"],
"properties": { "properties": {

View File

@ -15,3 +15,4 @@
!sdk.mjs !sdk.mjs
!sdk.js !sdk.js
!sdk.d.ts !sdk.d.ts
!.jsonschema.json

View File

@ -458,7 +458,7 @@ A SDK is included in the `simple-icons/sdk` entrypoint of the npm package to mak
```typescript ```typescript
import { getIconsData, type IconData } from 'simple-icons/sdk'; import { getIconsData, type IconData } from 'simple-icons/sdk';
const iconsData: IconData[] = getIconsData(); const iconsData: Promise<IconData[]> = getIconsData();
``` ```
```javascript ```javascript
@ -466,6 +466,6 @@ import { getIconsData } from 'simple-icons/sdk';
/* @typedef {import("./simple-icons/sdk").IconData} IconData */ /* @typedef {import("./simple-icons/sdk").IconData} IconData */
/* @type {IconData[]} */ /* @type {Promise<IconData[]>} */
const iconsData = getIconsData(); const iconsData = getIconsData();
``` ```

View File

@ -7,11 +7,11 @@ import {search} from 'fast-fuzzy';
import getRelativeLuminance from 'get-relative-luminance'; import getRelativeLuminance from 'get-relative-luminance';
import autocomplete from 'inquirer-autocomplete-standalone'; import autocomplete from 'inquirer-autocomplete-standalone';
import { import {
URL_REGEX,
collator, collator,
getIconsDataString, getIconsDataString,
normalizeColor, normalizeColor,
titleToSlug, titleToSlug,
urlRegex,
} from '../sdk.mjs'; } from '../sdk.mjs';
import {getJsonSchemaData, writeIconsData} from './utils.js'; import {getJsonSchemaData, writeIconsData} from './utils.js';
@ -30,8 +30,10 @@ const licenseTypes =
(license) => ({name: license, value: license}), (license) => ({name: license, value: license}),
); );
const isValidURL = (input) => const isValidURL = async (input) => {
URL_REGEX.test(input) || 'Must be a valid and secure (https://) URL.'; const regex = await urlRegex();
return regex.test(input) || 'Must be a valid and secure (https://) URL.';
};
const isValidHexColor = (input) => const isValidHexColor = (input) =>
HEX_REGEX.test(input) || 'Must be a valid hex code.'; HEX_REGEX.test(input) || 'Must be a valid hex code.';

2
sdk.d.ts vendored
View File

@ -63,9 +63,9 @@ export type IconData = {
/* The next code is autogenerated from sdk.mjs */ /* The next code is autogenerated from sdk.mjs */
/* eslint-disable */ /* eslint-disable */
export const URL_REGEX: RegExp;
export const SVG_PATH_REGEX: RegExp; export const SVG_PATH_REGEX: RegExp;
export function getDirnameFromImportMeta(importMetaUrl: string): string; export function getDirnameFromImportMeta(importMetaUrl: string): string;
export function urlRegex(jsonschemaPath?: string): Promise<RegExp>;
export function getIconSlug(icon: IconData): string; export function getIconSlug(icon: IconData): string;
export function svgToPath(svg: string): string; export function svgToPath(svg: string): string;
export function titleToSlug(title: string): string; export function titleToSlug(title: string): string;

23
sdk.mjs
View File

@ -33,11 +33,6 @@ const TITLE_TO_SLUG_CHARS_REGEX = new RegExp(
const TITLE_TO_SLUG_RANGE_REGEX = /[^a-z\d]/g; const TITLE_TO_SLUG_RANGE_REGEX = /[^a-z\d]/g;
/**
* Regex to validate HTTPs URLs.
*/
export const URL_REGEX = /^https:\/\/[^\s"']+$/;
/** /**
* Regex to validate SVG paths. * Regex to validate SVG paths.
*/ */
@ -52,6 +47,24 @@ export const SVG_PATH_REGEX = /^m[-mzlhvcsqtae\d,. ]+$/i;
export const getDirnameFromImportMeta = (importMetaUrl) => export const getDirnameFromImportMeta = (importMetaUrl) =>
path.dirname(fileURLToPath(importMetaUrl)); path.dirname(fileURLToPath(importMetaUrl));
/**
* Build a regex to validate HTTPs URLs.
* @param {String} jsonschemaPath Path to the *.jsonschema.json* file
* @returns {Promise<RegExp>} Regex to validate HTTPs URLs
*/
export const urlRegex = async (
jsonschemaPath = path.join(
getDirnameFromImportMeta(import.meta.url),
'.jsonschema.json',
),
) => {
return new RegExp(
JSON.parse(
await fs.readFile(jsonschemaPath, 'utf8'),
).definitions.url.pattern,
);
};
/** /**
* Get the slug/filename for an icon. * Get the slug/filename for an icon.
* @param {IconData} icon The icon data as it appears in *_data/simple-icons.json* * @param {IconData} icon The icon data as it appears in *_data/simple-icons.json*

View File

@ -9,11 +9,11 @@ import {
SVG_PATH_REGEX, SVG_PATH_REGEX,
collator, collator,
getDirnameFromImportMeta, getDirnameFromImportMeta,
getIconsData,
htmlFriendlyToTitle, htmlFriendlyToTitle,
} from './sdk.mjs'; } from './sdk.mjs';
const __dirname = getDirnameFromImportMeta(import.meta.url); const __dirname = getDirnameFromImportMeta(import.meta.url);
const dataFile = path.join(__dirname, '_data', 'simple-icons.json');
const htmlNamedEntitiesFile = path.join( const htmlNamedEntitiesFile = path.join(
__dirname, __dirname,
'node_modules', 'node_modules',
@ -22,7 +22,7 @@ const htmlNamedEntitiesFile = path.join(
); );
const svglintIgnoredFile = path.join(__dirname, '.svglint-ignored.json'); const svglintIgnoredFile = path.join(__dirname, '.svglint-ignored.json');
const data = JSON.parse(await fs.readFile(dataFile, 'utf8')); const icons = await getIconsData();
const htmlNamedEntities = JSON.parse( const htmlNamedEntities = JSON.parse(
await fs.readFile(htmlNamedEntitiesFile, 'utf8'), await fs.readFile(htmlNamedEntitiesFile, 'utf8'),
); );
@ -369,9 +369,7 @@ const config = {
if (_validCodepointsRepr) { if (_validCodepointsRepr) {
const iconName = htmlFriendlyToTitle(iconTitleText); const iconName = htmlFriendlyToTitle(iconTitleText);
const iconExists = data.icons.some( const iconExists = icons.some((icon) => icon.title === iconName);
(icon) => icon.title === iconName,
);
if (!iconExists) { if (!iconExists) {
reporter.error( reporter.error(
`No icon with title "${iconName}" found in simple-icons.json`, `No icon with title "${iconName}" found in simple-icons.json`,

View File

@ -4,7 +4,6 @@ import path from 'node:path';
import {describe, it} from 'mocha'; import {describe, it} from 'mocha';
import { import {
SVG_PATH_REGEX, SVG_PATH_REGEX,
URL_REGEX,
getDirnameFromImportMeta, getDirnameFromImportMeta,
titleToSlug, titleToSlug,
} from '../sdk.mjs'; } from '../sdk.mjs';
@ -43,7 +42,6 @@ export const testIcon = (icon, subject, slug) => {
it('has the correct "source"', () => { it('has the correct "source"', () => {
assert.equal(subject.source, icon.source); assert.equal(subject.source, icon.source);
assert.match(subject.source, URL_REGEX);
}); });
it('has an "svg" value', () => { it('has an "svg" value', () => {
@ -67,8 +65,6 @@ export const testIcon = (icon, subject, slug) => {
assert.equal(subject.license.type, icon.license.type); assert.equal(subject.license.type, icon.license.type);
if (icon.license.type === 'custom') { if (icon.license.type === 'custom') {
assert.equal(subject.license.url, icon.license.url); assert.equal(subject.license.url, icon.license.url);
} else {
assert.match(subject.license.url, URL_REGEX);
} }
} else { } else {
assert.equal(subject.license, undefined); assert.equal(subject.license, undefined);