offline.icon.ts 1.7 KB
import { IconifyJSON } from '@iconify/iconify';
import { camelCase } from 'lodash-es';

interface IconType {
  prefix: string;
  icon: string;
  alias?: string;
}

export function getCacheIcons() {
  const storageKeys = Object.keys(localStorage);

  const iconifyKeys = storageKeys.filter((key) => key.startsWith('iconify'));

  const allIcons: IconType[] = [];
  for (const key of iconifyKeys) {
    try {
      const res: Record<'data', IconifyJSON> = JSON.parse(localStorage.getItem(key)!);

      const {
        data: { prefix, icons, aliases },
      } = res;

      allIcons.push(...Object.keys(icons).map((icon) => ({ icon, prefix })));

      allIcons.push(
        ...Object.entries(aliases || {}).map(([key, value]) => ({
          icon: key,
          alias: value.parent,
          prefix,
        }))
      );
    } catch {
      continue;
    }
  }

  const collect = allIcons.reduce((prev, next) => {
    if (Reflect.has(prev, next.prefix)) {
      prev[next.prefix].push(next);
    } else {
      prev[next.prefix] = [next];
    }
    return prev;
  }, {} as Record<string, IconType[]>);

  const icons = Object.entries(collect).reduce(
    (prev, [key, value]) => {
      for (const { icon, alias } of value) {
        const importName = camelCase(`${key}-${alias || icon}`);

        prev.imports.push(
          `import ${importName} from 'virtual:@iconify/json/${key}/${alias || icon}';`
        );

        prev.registerIcons.push(`addIcon('${key}:${icon}', ${importName});`);
      }

      return prev;
    },
    { imports: [], registerIcons: [] } as Record<'imports' | 'registerIcons', string[]>
  );

  return `${[...new Set(icons.imports)].join('\n')}\n${[...new Set(icons.registerIcons)].join(
    '\n'
  )}`;
}