2
0
mirror of https://github.com/iconify/iconify.git synced 2024-11-09 23:00:56 +00:00

chore: move some modules and update types

test: include some tests for `writeOnce`
This commit is contained in:
Joaquín Sánchez Jiménez 2022-02-27 15:03:40 +01:00
parent 062a852a79
commit 6134d1f62b
10 changed files with 123 additions and 54 deletions

View File

@ -152,6 +152,10 @@
"require": "./lib/loader/utils.js", "require": "./lib/loader/utils.js",
"import": "./lib/loader/utils.mjs" "import": "./lib/loader/utils.mjs"
}, },
"./lib/loader/warn": {
"require": "./lib/loader/warn.js",
"import": "./lib/loader/warn.mjs"
},
"./lib/misc/strings": { "./lib/misc/strings": {
"require": "./lib/misc/strings.js", "require": "./lib/misc/strings.js",
"import": "./lib/misc/strings.mjs" "import": "./lib/misc/strings.mjs"

View File

@ -55,8 +55,7 @@ export type {
InlineCollection, InlineCollection,
} from './loader/types'; } from './loader/types';
export { mergeIconProps } from './loader/utils'; export { mergeIconProps } from './loader/utils';
export { isNode, loadIcon } from './loader/loader'; export { warnOnce } from './loader/warn';
export { FileSystemIconLoader } from './loader/loaders';
export { getCustomIcon } from './loader/custom'; export { getCustomIcon } from './loader/custom';
export { searchForIcon } from './loader/modern'; export { searchForIcon } from './loader/modern';

View File

@ -1,15 +1,7 @@
import { installPackage } from '@antfu/install-pkg'; import { installPackage } from '@antfu/install-pkg';
import { sleep } from '@antfu/utils'; import { sleep } from '@antfu/utils';
import { cyan, yellow } from 'kolorist'; import { cyan } from 'kolorist';
import { warnOnce } from './warn';
const warned = new Set<string>();
export function warnOnce(msg: string): void {
if (!warned.has(msg)) {
warned.add(msg);
console.warn(yellow(`[@iconify-loader] ${msg}`));
}
}
let pending: Promise<void> | undefined; let pending: Promise<void> | undefined;
const tasks: Record<string, Promise<void> | undefined> = {}; const tasks: Record<string, Promise<void> | undefined> = {};

View File

@ -1,9 +1,9 @@
import { getCustomIcon } from './custom'; import { getCustomIcon } from './custom';
import { searchForIcon } from './modern'; import { searchForIcon } from './modern';
import { warnOnce } from './install-pkg'; import { warnOnce } from './warn';
import type { IconifyLoaderOptions } from './types'; import type { IconifyLoaderOptions } from './types';
export const isNode = typeof process < 'u' && typeof process.stdout < 'u' export const isNode = typeof process < 'u' && typeof process.stdout < 'u';
export async function loadIcon( export async function loadIcon(
collection: string, collection: string,
@ -44,24 +44,27 @@ async function loadNodeBuiltinIcon(
collection: string, collection: string,
icon: string, icon: string,
options?: IconifyLoaderOptions, options?: IconifyLoaderOptions,
warn = true,
): Promise<string | undefined> { ): Promise<string | undefined> {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment let result: string | undefined;
// @ts-ignore const loadCollectionFromFS = await importFsModule().then(i => i?.loadCollectionFromFS);
const { loadCollectionFromFS } = await importFsModule(); if (loadCollectionFromFS) {
const iconSet = await loadCollectionFromFS(collection, options?.autoInstall); const iconSet = await loadCollectionFromFS(collection, options?.autoInstall);
if (iconSet) { if (iconSet) {
// possible icon names // possible icon names
const ids = [ const ids = [
icon, icon,
icon.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(), icon.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(),
icon.replace(/([a-z])(\d+)/g, '$1-$2'), icon.replace(/([a-z])(\d+)/g, '$1-$2'),
]; ];
return await searchForIcon(iconSet, collection, ids, options); result = await searchForIcon(iconSet, collection, ids, options);
}
} }
if (warn) { if (!result && options?.warn) {
warnOnce(`failed to load \`@iconify-json/${collection}\`, have you installed it?`); warnOnce(`failed to load ${options.warn} icon`);
} }
return result;
} }

View File

@ -2,7 +2,6 @@ import type { Awaitable } from '@antfu/utils';
import { promises as fs, Stats } from 'fs'; import { promises as fs, Stats } from 'fs';
import type { CustomIconLoader } from './types'; import type { CustomIconLoader } from './types';
import { camelize, pascalize } from '../misc/strings'; import { camelize, pascalize } from '../misc/strings';
import { isNode } from './loader';
/** /**
* Returns CustomIconLoader for loading icons from a directory * Returns CustomIconLoader for loading icons from a directory
@ -11,26 +10,25 @@ export function FileSystemIconLoader(
dir: string, dir: string,
transform?: (svg: string) => Awaitable<string> transform?: (svg: string) => Awaitable<string>
): CustomIconLoader { ): CustomIconLoader {
return isNode return async (name) => {
? async (name) => { const paths = [
const paths = [ `${dir}/${name}.svg`,
`${dir}/${name}.svg`, `${dir}/${camelize(name)}.svg`,
`${dir}/${camelize(name)}.svg`, `${dir}/${pascalize(name)}.svg`,
`${dir}/${pascalize(name)}.svg`, ];
]; let stat: Stats;
let stat: Stats; for (const path of paths) {
for (const path of paths) { try {
try { stat = await fs.lstat(path);
stat = await fs.lstat(path); } catch {
} catch (err) { continue;
continue;
}
if (stat.isFile()) {
const svg = await fs.readFile(path, 'utf-8');
return typeof transform === 'function'
? await transform(svg)
: svg;
}
} }
} : () => undefined; if (stat.isFile()) {
const svg = await fs.readFile(path, 'utf-8');
return typeof transform === 'function'
? await transform(svg)
: svg;
}
}
};
} }

View File

@ -75,6 +75,11 @@ export type CustomCollections = Record<
* Options to use with the modern loader. * Options to use with the modern loader.
*/ */
export type IconifyLoaderOptions = { export type IconifyLoaderOptions = {
/**
* Emit warning when missing icons are matched
*/
warn?: string
/** /**
* Add svg and xlink xml namespace when necessary. * Add svg and xlink xml namespace when necessary.
* *

View File

@ -0,0 +1,10 @@
import { yellow } from 'kolorist';
const warned = new Set<string>();
export function warnOnce(msg: string): void {
if (!warned.has(msg)) {
warned.add(msg);
console.warn(yellow(`[@iconify-loader] ${msg}`));
}
}

View File

@ -1,4 +1,4 @@
import { FileSystemIconLoader } from '../lib'; import { FileSystemIconLoader } from '../lib/loader/loaders';
describe('Testing FileSystemIconLoader', () => { describe('Testing FileSystemIconLoader', () => {
test('FileSystemIconLoader', async () => { test('FileSystemIconLoader', async () => {

View File

@ -1,4 +1,4 @@
import { loadIcon } from '../lib'; import { loadIcon } from '../lib/loader/loader';
describe('Testing loadIcon with @iconify-json/flat-color-icons>', () => { describe('Testing loadIcon with @iconify-json/flat-color-icons>', () => {
@ -56,4 +56,61 @@ describe('Testing loadIcon with @iconify-json/flat-color-icons>', () => {
expect(result && result.includes('width="2em"')).toBeTruthy(); expect(result && result.includes('width="2em"')).toBeTruthy();
expect(result && result.includes('height="2em"')).toBeTruthy(); expect(result && result.includes('height="2em"')).toBeTruthy();
}); });
test('loadIcon warn missing icon', async () => {
// Intercept console.warn
let warned = false;
const warn = console.warn;
console.warn = (/*...args*/) => {
// warn.apply(this, args);
warned = true;
};
const result = await loadIcon('flat-color-icons', 'missing1', {
warn: 'flat-color-icons:missing'
});
// Restore console.warn
console.warn = warn;
expect(result).toBeFalsy();
expect(warned).toEqual(true);
});
test('test warnOnce on loadIcon on missing icon', async () => {
// Intercept console.warn
let warned = false;
const warn = console.warn;
console.warn = (/*...args*/) => {
// warn.apply(this, args);
warned = true;
};
// use another name since it is using warnOnce
const result = await loadIcon('flat-color-icons', 'missing1', {
warn: 'flat-color-icons:missing'
});
// Restore console.warn
console.warn = warn;
expect(result).toBeFalsy();
expect(warned).toEqual(false);
});
test('loadIcon doesn\'t warn missing icon', async () => {
// Intercept console.warn
let warned = false;
const warn = console.warn;
console.warn = (/*...args*/) => {
// warn.apply(this, args);
warned = true;
};
// use another name since it is using warnOnce
const result = await loadIcon('flat-color-icons', 'missing2');
// Restore console.warn
console.warn = warn;
expect(result).toBeFalsy();
expect(warned).toEqual(false);
});
}); });

View File

@ -1,5 +1,6 @@
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import { CustomIconLoader, loadIcon } from '../lib'; import type { CustomIconLoader } from '../lib';
import { loadIcon } from '../lib/loader/loader';
const fixturesDir = __dirname + '/fixtures'; const fixturesDir = __dirname + '/fixtures';