mirror of
https://github.com/iconify/iconify.git
synced 2024-12-12 13:47:49 +00:00
chore: add export to utils index
This commit is contained in:
parent
ffd23fb8ec
commit
609537b7bf
@ -1,13 +1,13 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import type { IconifyJSON } from '@iconify/types'
|
||||
import type { FullIconifyIcon } from '@iconify/utils'
|
||||
import { promises as fs } from 'fs';
|
||||
import type { IconifyJSON } from '@iconify/types';
|
||||
import type { FullIconifyIcon } from '@iconify/utils';
|
||||
import { defaultCustomisations as DefaultIconCustomizations, iconToSVG, getIconData, tryInstallPkg } from '@iconify/utils';
|
||||
import createDebugger from 'debug'
|
||||
import { isPackageExists, resolveModule } from 'local-pkg'
|
||||
import createDebugger from 'debug';
|
||||
import { isPackageExists, resolveModule } from 'local-pkg';
|
||||
|
||||
const debug = createDebugger('@iconify-core:icon')
|
||||
const debugModern = createDebugger('@iconify-core:modern')
|
||||
const debugLegacy = createDebugger('@iconify-core:legacy')
|
||||
const debug = createDebugger('@iconify-core:icon');
|
||||
const debugModern = createDebugger('@iconify-core:modern');
|
||||
const debugLegacy = createDebugger('@iconify-core:legacy');
|
||||
|
||||
export interface ResolvedIconPath {
|
||||
collection: string
|
||||
@ -15,54 +15,57 @@ export interface ResolvedIconPath {
|
||||
query: Record<string, string | undefined>
|
||||
}
|
||||
|
||||
const _collections: Record<string, Promise<IconifyJSON | undefined>> = {}
|
||||
const isLegacyExists = isPackageExists('@iconify/json')
|
||||
const _collections: Record<string, Promise<IconifyJSON | undefined>> = {};
|
||||
const isLegacyExists = isPackageExists('@iconify/json');
|
||||
|
||||
export async function loadCollection(name: string, autoInstall = false): Promise<IconifyJSON | undefined> {
|
||||
if (!_collections[name])
|
||||
_collections[name] = task()
|
||||
if (!_collections[name]) {
|
||||
_collections[name] = task();
|
||||
}
|
||||
|
||||
return _collections[name]
|
||||
return _collections[name];
|
||||
|
||||
async function task(): Promise<IconifyJSON | undefined> {
|
||||
let jsonPath = resolveModule(`@iconify-json/${name}/icons.json`)
|
||||
if (jsonPath)
|
||||
debugModern(name)
|
||||
let jsonPath = resolveModule(`@iconify-json/${name}/icons.json`);
|
||||
if (jsonPath) {
|
||||
debugModern(name);
|
||||
}
|
||||
|
||||
if (!jsonPath && isLegacyExists) {
|
||||
jsonPath = resolveModule(`@iconify/json/json/${name}.json`)
|
||||
if (jsonPath)
|
||||
debugLegacy(name)
|
||||
jsonPath = resolveModule(`@iconify/json/json/${name}.json`);
|
||||
if (jsonPath) {
|
||||
debugLegacy(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!jsonPath && !isLegacyExists && autoInstall) {
|
||||
await tryInstallPkg(`@iconify-json/${name}`)
|
||||
jsonPath = resolveModule(`@iconify-json/${name}/icons.json`)
|
||||
await tryInstallPkg(`@iconify-json/${name}`);
|
||||
jsonPath = resolveModule(`@iconify-json/${name}/icons.json`);
|
||||
}
|
||||
|
||||
if (jsonPath) {
|
||||
return JSON.parse(await fs.readFile(jsonPath, 'utf8'))
|
||||
return JSON.parse(await fs.readFile(jsonPath, 'utf8'));
|
||||
}
|
||||
else {
|
||||
debugModern(`failed to load ${name}`)
|
||||
return undefined
|
||||
debugModern(`failed to load ${name}`);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function searchForIcon(iconSet: IconifyJSON, collection: string, ids: string[], scale = 1): FullIconifyIcon | null {
|
||||
let iconData: FullIconifyIcon | null
|
||||
let iconData: FullIconifyIcon | null;
|
||||
for (const id of ids) {
|
||||
iconData = getIconData(iconSet, id, true)
|
||||
iconData = getIconData(iconSet, id, true);
|
||||
if (iconData) {
|
||||
debug(`${collection}:${id}`)
|
||||
debug(`${collection}:${id}`);
|
||||
const { attributes, body } = iconToSVG(iconData, {
|
||||
...DefaultIconCustomizations,
|
||||
height: `${scale}em`,
|
||||
width: `${scale}em`,
|
||||
})
|
||||
return `<svg ${Object.entries(attributes).map(i => `${i[0]}="${i[1]}"`).join(' ')}>${body}</svg>`
|
||||
});
|
||||
return `<svg ${Object.entries(attributes).map(i => `${i[0]}="${i[1]}"`).join(' ')}>${body}</svg>`;
|
||||
}
|
||||
}
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
@ -45,3 +45,7 @@ export { colorKeywords } from './colors/keywords';
|
||||
export { stringToColor, compareColors, colorToString } from './colors/index';
|
||||
|
||||
// SVG Icon loader
|
||||
export type { CustomIconLoader, CustomCollections, InlineCollection } from './loader/types';
|
||||
export { camelize, camelToKebab, pascalize, tryInstallPkg } from './loader/utils';
|
||||
export { FileSystemIconLoader } from './loader/loaders';
|
||||
export { getCustomIcon } from './loader/custom';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import createDebugger from 'debug'
|
||||
import type { CustomIconLoader, InlineCollection } from '.'
|
||||
import createDebugger from 'debug';
|
||||
import type { CustomIconLoader, InlineCollection } from './types';
|
||||
|
||||
const debug = createDebugger('@iconify-loader:custom')
|
||||
const debug = createDebugger('@iconify-loader:custom');
|
||||
|
||||
export async function getCustomIcon(
|
||||
custom: CustomIconLoader | InlineCollection,
|
||||
@ -9,23 +9,24 @@ export async function getCustomIcon(
|
||||
icon: string,
|
||||
scale = 1
|
||||
): Promise<string | undefined> {
|
||||
let result: string | undefined | null
|
||||
let result: string | undefined | null;
|
||||
|
||||
debug(`${collection}:${icon}`)
|
||||
debug(`${collection}:${icon}`);
|
||||
|
||||
if (typeof custom === 'function') {
|
||||
result = await custom(icon)
|
||||
result = await custom(icon);
|
||||
}
|
||||
else {
|
||||
const inline = custom[icon]
|
||||
const inline = custom[icon];
|
||||
result = typeof inline === 'function'
|
||||
? await inline()
|
||||
: inline
|
||||
: inline;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
if (!result.startsWith('<svg '))
|
||||
console.warn(`Custom icon "${icon}" in "${collection}" is not a valid SVG`)
|
||||
return result.replace('<svg ', `<svg height="${scale}em" width="${scale}em" `)
|
||||
if (!result.startsWith('<svg ')) {
|
||||
console.warn(`Custom icon "${icon}" in "${collection}" is not a valid SVG`);
|
||||
}
|
||||
return result.replace('<svg ', `<svg height="${scale}em" width="${scale}em" `);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
export type { CustomIconLoader, CustomCollections, InlineCollection } from './types'
|
||||
|
||||
export { camelize, camelToKebab, pascalize } from './utils'
|
||||
export { FileSystemIconLoader } from './loaders'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { Awaitable } from '@antfu/utils'
|
||||
import type { Awaitable } from '@antfu/utils';
|
||||
import { existsSync, promises as fs } from 'fs';
|
||||
import type { CustomIconLoader } from './types';
|
||||
import { camelize, pascalize } from './utils';
|
||||
@ -9,12 +9,12 @@ export function FileSystemIconLoader(dir: string, transform?: (svg: string) => A
|
||||
`${dir}/${name}.svg`,
|
||||
`${dir}/${camelize(name)}.svg`,
|
||||
`${dir}/${pascalize(name)}.svg`,
|
||||
]
|
||||
];
|
||||
for (const path of paths) {
|
||||
if (existsSync(path)) {
|
||||
const svg = await fs.readFile(path, 'utf-8')
|
||||
return typeof transform === 'function' ? await transform(svg) : svg
|
||||
const svg = await fs.readFile(path, 'utf-8');
|
||||
return typeof transform === 'function' ? await transform(svg) : svg;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { Awaitable } from '@antfu/utils'
|
||||
import type { Awaitable } from '@antfu/utils';
|
||||
|
||||
export type CustomIconLoader = (name: string) => Awaitable<string | undefined>
|
||||
export type InlineCollection = Record<string, string | (() => Awaitable<string | undefined>)>
|
||||
|
@ -1,43 +1,44 @@
|
||||
import { installPackage } from '@antfu/install-pkg'
|
||||
import { sleep } from '@antfu/utils'
|
||||
import { installPackage } from '@antfu/install-pkg';
|
||||
import { sleep } from '@antfu/utils';
|
||||
|
||||
export function camelize(str: string): string {
|
||||
return str.replace(/-([a-z0-9])/g, g => g[1].toUpperCase())
|
||||
return str.replace(/-([a-z0-9])/g, g => g[1].toUpperCase());
|
||||
}
|
||||
|
||||
export function pascalize(str: string): string {
|
||||
const camel = camelize(str)
|
||||
return camel[0].toUpperCase() + camel.slice(1)
|
||||
const camel = camelize(str);
|
||||
return camel[0].toUpperCase() + camel.slice(1);
|
||||
}
|
||||
|
||||
export function camelToKebab(key: string): string {
|
||||
const result = key
|
||||
.replace(/:/g, '-')
|
||||
.replace(/([A-Z])/g, ' $1')
|
||||
.trim()
|
||||
return result.split(/\s+/g).join('-').toLowerCase()
|
||||
.trim();
|
||||
return result.split(/\s+/g).join('-').toLowerCase();
|
||||
}
|
||||
|
||||
const warnned = new Set<string>()
|
||||
const warnned = new Set<string>();
|
||||
|
||||
export function warnOnce(msg: string): void {
|
||||
if (!warnned.has(msg)) {
|
||||
warnned.add(msg)
|
||||
console.warn(`[@iconify-loader] ${msg}`)
|
||||
warnned.add(msg);
|
||||
console.warn(`[@iconify-loader] ${msg}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let pending: Promise<void> | undefined
|
||||
const tasks: Record<string, Promise<void> | undefined> = {}
|
||||
let pending: Promise<void> | undefined;
|
||||
const tasks: Record<string, Promise<void> | undefined> = {};
|
||||
|
||||
export async function tryInstallPkg(name: string): Promise<void | undefined> {
|
||||
if (pending)
|
||||
await pending
|
||||
if (pending) {
|
||||
await pending;
|
||||
}
|
||||
|
||||
if (!tasks[name]) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Installing ${name}...`)
|
||||
console.log(`Installing ${name}...`);
|
||||
tasks[name] = pending = installPackage(name, { dev: true, preferOffline: true })
|
||||
.then(() => sleep(300))
|
||||
// eslint-disable-next-line
|
||||
@ -47,9 +48,9 @@ export async function tryInstallPkg(name: string): Promise<void | undefined> {
|
||||
})
|
||||
.finally(() => {
|
||||
pending = undefined
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
return tasks[name]!
|
||||
return tasks[name]!;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user