type Component = { name: string, type: string, animated: boolean, sizeBefore: number, sizeAfter: number } /** * Generates the main index file */ export function generateIndexFile(components: Component[]) { // Import all the actual assets const assetImports = components .map(({ name }) => `import { type ${name}Asset } from './${name}'`) .join('\n') const typeExports = components .map(({ name }) => `export type { ${name}Asset } from './${name}'`) .join('\n') const nameUnion = components .map(({ name }) => `'${name}'`) .join(' | ') const assetTypeUnion = components .map(({ name }) => `${name}Asset`) .join(' | ') const illustrationNamesArray = components .map(({ name }) => `'${name}'`) .join(', ') // Create the components map for lazy loading const componentsMap = `{ ${components.map(({ name }) => `'${name}': () => import('./${name}')`).join(',\n ')} }` // Generate statistics comment const stats = generateStatsComment(components) return `// AUTO-GENERATED FILE. DO NOT EDIT. ${stats} // Re-export shared types export type { IllustrationAsset, IllustrationAssetBrand, BaseSvgAsset, BaseImageAsset, BaseAnimatedImageAsset } from './types' // Import all assets for union type ${assetImports} /** * Map of all illustrations with lazy loading * Use this for dynamic imports of illustrations */ export const lazyIllustrationsMap = ${componentsMap} // Type exports ${typeExports} /** * Union of all available illustration names */ export type UnityIllustrationName = ${nameUnion} /** * Union of all branded illustration asset types * This prevents creation of fake illustration objects */ export type UnityIllustrationAsset = ${assetTypeUnion} /** * Array of all available illustration names * Useful for iteration or validation */ export const illustrationNames: readonly UnityIllustrationName[] = [${illustrationNamesArray}] as const ` } /** * Generates statistics comment for the index file */ function generateStatsComment(components: Component[]) { const totalCount = components.length const svgCount = components.filter(c => c.type === 'svg').length const imageCount = components.filter(c => c.type === 'image').length const animatedCount = components.filter(c => c.animated).length const totalSizeBefore = components.reduce((sum, c) => sum + (c.sizeBefore || 0), 0) const totalSizeAfter = components.reduce((sum, c) => sum + (c.sizeAfter || 0), 0) const totalReduction = totalSizeBefore > 0 ? ((totalSizeBefore - totalSizeAfter) / totalSizeBefore * 100).toFixed(1) : '0' return `// // 📊 Generation Statistics: // - Total illustrations: ${totalCount} // - SVGs: ${svgCount} // - Images: ${imageCount} // - Animated: ${animatedCount} // - Size optimization: ${(totalSizeBefore / 1024).toFixed(1)}KB → ${(totalSizeAfter / 1024).toFixed(1)}KB (-${totalReduction}%) // - Generated: ${new Date().toISOString()} //` }