import { promises as fs } from 'node:fs' import * as path from 'node:path' async function ensureDir(dir: string): Promise { await fs.mkdir(dir, { recursive: true }) } async function copyDir(src: string, dest: string): Promise { await ensureDir(dest) const entries = await fs.readdir(src, { withFileTypes: true }) for (const entry of entries) { const srcPath = path.join(src, entry.name) const destPath = path.join(dest, entry.name) if (entry.isDirectory()) { await copyDir(srcPath, destPath) } else if (entry.isFile()) { await fs.copyFile(srcPath, destPath) } // Symlinks and others are ignored } } export async function copyFilesCLI(): Promise { const args = process.argv.slice(2) const showHelp = args.includes('-h') || args.includes('--help') const sourceArg = args[0] const destArg = args[1] console.log('sourceArg:', sourceArg, 'destArg:', destArg) if (showHelp || !sourceArg || !destArg) { console.error( [ 'Usage: tsx scripts/copyFiles.ts ', '', 'Copies all files from into .', 'Examples:', ' tsx scripts/copyFiles.ts static/fonts dist/fonts', ].join('\n') ) process.exit(showHelp ? 0 : 1) } const src = path.resolve(process.cwd(), sourceArg) const dest = path.resolve(process.cwd(), destArg) // Prevent copying into source or a parent of source const rel = path.relative(src, dest) if (!rel || !rel.startsWith('..')) { console.error('Destination must not be inside the source fonts directory.') process.exit(1) } await ensureDir(dest) await copyDir(src, dest) console.log(`Copied files from "${src}" to "${dest}".`) } // Run if invoked via CLI if (require.main === module) { try { await copyFilesCLI() } catch (err) { console.error(err instanceof Error ? err.message : String(err)) process.exit(1) } }