|
| 1 | +#!/usr/bin/env node |
| 2 | + |
| 3 | +/** |
| 4 | + * Auto-generate assets index.js from all files in this directory and subdirectories |
| 5 | + * |
| 6 | + * ?Usage: |
| 7 | + * node generate_assets_index.js |
| 8 | + * (or: bun generate_assets_index.js) |
| 9 | + * |
| 10 | + * !Requirements: |
| 11 | + * - Run this script in the src/assets directory |
| 12 | + * - All asset files (images, sounds, videos, etc.) should be placed in this directory or its subfolders |
| 13 | + * - Asset files should not be named index.* or generate_assets_index.* |
| 14 | + * - The script will ignore .DS_Store and similar system files |
| 15 | + * - The generated index.js will export an Assets object with all assets imported and mapped by PascalCase name |
| 16 | + * |
| 17 | + * @example |
| 18 | + * import Assets from './assets/index.js'; |
| 19 | + * Usage: Assets.VueSvg, Assets.NavMenuClickMp3, etc. |
| 20 | + * |
| 21 | + * @author ThinhPhoenix |
| 22 | + * @version 1.0.0 |
| 23 | + */ |
| 24 | +const fs = require('fs'); |
| 25 | +const path = require('path'); |
| 26 | + |
| 27 | +const assetsDir = path.join(__dirname, '../src/assets'); |
| 28 | +const indexPath = path.join(assetsDir, 'index.ts'); |
| 29 | + |
| 30 | +function toExportName(filePath: any) { |
| 31 | + let name = path.basename(filePath, path.extname(filePath)); |
| 32 | + const rel = path.relative(assetsDir, filePath).split(path.sep); |
| 33 | + if (rel.length > 1) { |
| 34 | + name = rel.slice(0, -1).concat(name).join('_'); |
| 35 | + } |
| 36 | + return name.replace(/(^|[-_])(\w)/g, (_: string, __: string, c: string) => |
| 37 | + c.toUpperCase(), |
| 38 | + ); |
| 39 | +} |
| 40 | + |
| 41 | +function walk(dir: any) { |
| 42 | + let results: any = []; |
| 43 | + const list = fs.readdirSync(dir); |
| 44 | + list.forEach((file: any) => { |
| 45 | + const filePath = path.join(dir, file); |
| 46 | + const stat = fs.statSync(filePath); |
| 47 | + if (stat && stat.isDirectory()) { |
| 48 | + results = results.concat(walk(filePath)); |
| 49 | + } else if ( |
| 50 | + !file.startsWith('index.') && |
| 51 | + !file.startsWith('generate-assets-index') |
| 52 | + ) { |
| 53 | + results.push(filePath); |
| 54 | + } |
| 55 | + }); |
| 56 | + return results; |
| 57 | +} |
| 58 | + |
| 59 | +const files = walk(assetsDir).filter((f: any) => !f.endsWith('.DS_Store')); |
| 60 | + |
| 61 | +const importLines = files.map((f: any) => { |
| 62 | + const relPath = './' + path.relative(assetsDir, f).replace(/\\/g, '/'); |
| 63 | + const exportName = toExportName(f); |
| 64 | + return `import ${exportName} from '${relPath}';`; |
| 65 | +}); |
| 66 | + |
| 67 | +const assetObjectLines = files.map((f: any) => { |
| 68 | + const exportName = toExportName(f); |
| 69 | + return ` ${exportName},`; |
| 70 | +}); |
| 71 | + |
| 72 | +const output = [ |
| 73 | + '//! ⚠️ THIS FILE IS AUTO-GENERATED. DO NOT EDIT DIRECTLY. RUN generate_index.js TO UPDATE. ⚠️', |
| 74 | + ...importLines, |
| 75 | + '', |
| 76 | + 'const Assets = {', |
| 77 | + ...assetObjectLines, |
| 78 | + '};', |
| 79 | + '', |
| 80 | + 'export default Assets;', |
| 81 | + '', |
| 82 | +].join('\n'); |
| 83 | + |
| 84 | +fs.writeFileSync(indexPath, output); |
0 commit comments