|
| 1 | +// @ts-check |
| 2 | +// Copyright (c) Microsoft Corporation. |
| 3 | +// Licensed under the MIT license. |
| 4 | + |
| 5 | +// Populates ./src/utils/fonts from the canonical font binaries committed in the |
| 6 | +// repo-root `fonts/` folder (the single source of truth, regenerated at release |
| 7 | +// time by `importer`'s `deploy:fonts`). Instead of re-running fantasticon four |
| 8 | +// times during every react-icons build, we simply copy the already-generated |
| 9 | +// font families and their glyph-named codepoint maps. |
| 10 | +// |
| 11 | +// Copied per family (Regular / Filled / Light / Resizable): |
| 12 | +// - {ttf,woff,woff2} -> imported by createFluentFontIcon.styles.ts (@font-face) |
| 13 | +// - .json (glyph-named) -> read by convert-font.js, which then overwrites it |
| 14 | +// in place with the React-named codepoint map. |
| 15 | +// |
| 16 | +// The generated `.css` / `.html` fantasticon byproducts are intentionally NOT |
| 17 | +// copied: nothing in the react-icons build consumes them. |
| 18 | + |
| 19 | +const fs = require('node:fs'); |
| 20 | +const path = require('node:path'); |
| 21 | +const { parseArgs } = require('node:util'); |
| 22 | + |
| 23 | +const FONT_TYPES = ['Regular', 'Filled', 'Light', 'Resizable']; |
| 24 | +const BINARY_EXTENSIONS = ['ttf', 'woff', 'woff2']; |
| 25 | + |
| 26 | +if (require.main === module) { |
| 27 | + try { |
| 28 | + main(); |
| 29 | + } catch (err) { |
| 30 | + console.error('[copy-base-fonts] failed:', err); |
| 31 | + process.exit(1); |
| 32 | + } |
| 33 | +} |
| 34 | + |
| 35 | +function main() { |
| 36 | + const { |
| 37 | + values: { source, dest, help }, |
| 38 | + } = parseArgs({ |
| 39 | + options: { |
| 40 | + source: { type: 'string' }, |
| 41 | + dest: { type: 'string' }, |
| 42 | + help: { type: 'boolean', short: 'h' }, |
| 43 | + }, |
| 44 | + }); |
| 45 | + |
| 46 | + if (help) { |
| 47 | + printUsage(); |
| 48 | + return; |
| 49 | + } |
| 50 | + |
| 51 | + if (!source) throw new Error('Font source folder not specified by --source'); |
| 52 | + if (!dest) throw new Error('Output destination folder not specified by --dest'); |
| 53 | + |
| 54 | + const sourceDir = path.resolve(source); |
| 55 | + const destDir = path.resolve(dest); |
| 56 | + |
| 57 | + if (!fs.existsSync(sourceDir)) { |
| 58 | + throw new Error(`Font source folder not found: ${sourceDir}. The repo-root fonts/ folder is the source of truth.`); |
| 59 | + } |
| 60 | + |
| 61 | + fs.mkdirSync(destDir, { recursive: true }); |
| 62 | + |
| 63 | + let copied = 0; |
| 64 | + for (const type of FONT_TYPES) { |
| 65 | + const baseName = `FluentSystemIcons-${type}`; |
| 66 | + for (const ext of [...BINARY_EXTENSIONS, 'json']) { |
| 67 | + const fileName = `${baseName}.${ext}`; |
| 68 | + const srcPath = path.join(sourceDir, fileName); |
| 69 | + if (!fs.existsSync(srcPath)) { |
| 70 | + throw new Error(`Expected font file missing in source: ${srcPath}`); |
| 71 | + } |
| 72 | + fs.copyFileSync(srcPath, path.join(destDir, fileName)); |
| 73 | + copied++; |
| 74 | + } |
| 75 | + } |
| 76 | + |
| 77 | + console.log(`[copy-base-fonts] Copied ${copied} font file(s) from ${sourceDir} -> ${destDir}`); |
| 78 | +} |
| 79 | + |
| 80 | +function printUsage() { |
| 81 | + console.log( |
| 82 | + `Usage: node copy-base-fonts.js --source <dir> --dest <dir>\n\n` + |
| 83 | + `Copies the canonical font binaries and glyph-named codepoint maps from the\n` + |
| 84 | + `repo-root fonts/ folder into the react-icons build, avoiding a redundant\n` + |
| 85 | + `fantasticon run.\n\n` + |
| 86 | + `Options:\n` + |
| 87 | + ` --source <dir> Source folder containing FluentSystemIcons-*.{ttf,woff,woff2,json} (required)\n` + |
| 88 | + ` --dest <dir> Destination folder to copy the font files into (required)\n` + |
| 89 | + ` -h, --help Show this help message`, |
| 90 | + ); |
| 91 | +} |
0 commit comments