mirror of
https://github.com/iconify/iconify.git
synced 2024-12-12 21:57:50 +00:00
chore: move some modules and update types
test: include some tests for `writeOnce`
This commit is contained in:
parent
062a852a79
commit
6134d1f62b
@ -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"
|
||||||
|
@ -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';
|
||||||
|
|
||||||
|
@ -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> = {};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
10
packages/utils/src/loader/warn.ts
Normal file
10
packages/utils/src/loader/warn.ts
Normal 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}`));
|
||||||
|
}
|
||||||
|
}
|
@ -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 () => {
|
||||||
|
@ -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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -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';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user