All files / packages/icons/scripts generate-icons-data.ts

0% Statements 0/43
0% Branches 0/12
0% Functions 0/8
0% Lines 0/43

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                                                                                                                                                                                                                                                               
/*
 * Generates `public/icons-all.json` for the previewer.
 *
 * Scans the source `svg/<type>/common` and `svg/<type>/ltr` folders and emits a
 * JSON map of icon names per type, split into `common` and `directional`
 * (ltr) lists. The previewer loads this to enumerate available icons without
 * reading the filesystem at runtime.
 */
import fs from 'node:fs';
import path from 'node:path';
 
const rootDir = path.resolve(import.meta.dirname, '..');
 
const iconTypes = ['action', 'custom', 'doctype', 'standard', 'utility'] as const;
 
interface IconsData {
  [key: string]: {
    common: string[];
    directional: string[];
  };
}
 
/*
 * Returns an icon type's symbol names, split into `common` (svg/<type>/common)
 * and `directional` (svg/<type>/ltr). Each list is sorted; missing folders
 * yield empty lists.
 */
function getIconNames(iconType: string): { common: string[]; directional: string[] } {
  const svgDir = path.join(rootDir, 'svg', iconType);
  const commonDir = path.join(svgDir, 'common');
  const ltrDir = path.join(svgDir, 'ltr');
 
  const common: string[] = [];
  const directional: string[] = [];
 
  // Get common icons
  if (fs.existsSync(commonDir)) {
    const files = fs.readdirSync(commonDir);
    files.forEach((file) => {
      if (file.endsWith('.svg')) {
        common.push(path.basename(file, '.svg'));
      }
    });
  }
 
  // Get directional icons (ltr)
  if (fs.existsSync(ltrDir)) {
    const files = fs.readdirSync(ltrDir);
    files.forEach((file) => {
      if (file.endsWith('.svg')) {
        directional.push(path.basename(file, '.svg'));
      }
    });
  }
 
  return {
    common: common.sort(),
    directional: directional.sort(),
  };
}
 
/* Builds the full icons map by collecting names for every icon type. */
function generateIconsData(): IconsData {
  const data: IconsData = {};
 
  iconTypes.forEach((iconType) => {
    data[iconType] = getIconNames(iconType);
  });
 
  return data;
}
 
/*
 * Stages the icon assets the previewer serves at runtime into `public/icons/`,
 * where Next.js exposes them as static files. The previewer's <img>/<use> tags
 * fetch source SVGs from `/icons/svg/...` and built assets (dist SVGs, sprites,
 * PNGs) from `/icons/dist/...`, so both trees must be copied under `public`.
 *
 * The `svg/` source is always present; `dist/` only exists after `yarn build`.
 * When dist is missing we skip it with a warning rather than failing — the
 * source-SVG column still renders, and the built columns light up once the
 * user runs a build.
 */
function stagePreviewerAssets() {
  const publicIconsDir = path.join(rootDir, 'public', 'icons');
 
  const stage = (srcDir: string, destName: string) => {
    const dest = path.join(publicIconsDir, destName);
    fs.rmSync(dest, { recursive: true, force: true });
    fs.cpSync(srcDir, dest, { recursive: true });
    console.log(`Staged ${srcDir} -> ${dest}`);
  };
 
  fs.mkdirSync(publicIconsDir, { recursive: true });
  stage(path.join(rootDir, 'svg'), 'svg');
 
  const distDir = path.join(rootDir, 'dist');
  if (fs.existsSync(distDir)) {
    stage(distDir, 'dist');
  } else {
    console.warn(
      'No dist/ found — built SVG, sprite, and PNG columns will 404. Run `yarn build` to populate them.',
    );
  }
}
 
/*
 * Entry point: builds the icons map and writes it to `public/icons-all.json`,
 * creating the output directory if needed, then stages the previewer assets.
 */
function main() {
  const iconsData = generateIconsData();
  const outputPath = path.join(rootDir, 'public', 'icons-all.json');
 
  // Ensure output directory exists
  const outputDir = path.dirname(outputPath);
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }
 
  fs.writeFileSync(outputPath, JSON.stringify(iconsData, null, 2));
  console.log(`Generated ${outputPath}`);
 
  stagePreviewerAssets();
}
 
main();