import { resolve } from 'node:path'; import { readdirSync } from 'node:fs'; import { defineConfig, IndexHtmlTransformContext, Plugin } from 'vite'; const canvasWebsiteDir = resolve(__dirname, './website/canvas'); function getCanvasFiles() { return readdirSync(canvasWebsiteDir).filter((file) => file.endsWith('.html')); } const linkGenerator = (): Plugin => { return { name: 'link-generator', transformIndexHtml(html: string, ctx: IndexHtmlTransformContext) { if (!ctx.filename.endsWith('canvas/index.html')) return; const files = getCanvasFiles(); // First, handle ungrouped files const ungroupedFiles = files.filter( (file) => !file.includes('index') && !file.startsWith('_') && !file.match(/^\[([^\]]+)\]/) ); // Then handle grouped files const groups = files .filter((file) => !file.includes('index') && file.match(/^\[([^\]]+)\]/)) .reduce((acc, file) => { const match = file.match(/^\[([^\]]+)\](.+)\.html$/); const group = match![1]; if (!acc[group]) acc[group] = []; acc[group].push(file); return acc; }, {} as Record); // Generate ungrouped HTML first const ungroupedHtml = ungroupedFiles .sort() .map((file) => { const title = file.replace('.html', '').replaceAll('-', ' '); return `
  • ${title}
  • `; }) .join('\n'); // Then generate grouped HTML const groupedHtml = Object.entries(groups) .sort(([a], [b]) => a.localeCompare(b)) .map(([group, groupFiles]) => { const groupHtml = groupFiles .sort() .map((file) => { const title = file .replace(/^\[[^\]]+\]/, '') .replace('.html', '') .replaceAll('-', ' '); return `
  • ${title}
  • `; }) .join('\n'); return `

    ${group.replaceAll('-', ' ')}

    \n`; }) .join('\n'); return html.replace('{{ LINKS }}', `${ungroupedHtml}\n${groupedHtml}`); }, }; }; export default defineConfig({ root: 'website', resolve: { alias: { '@lib': resolve(__dirname, './lib'), '@labs': resolve(__dirname, './labs'), '@propagators': resolve(__dirname, './propagators'), }, }, plugins: [linkGenerator()], build: { target: 'esnext', rollupOptions: { input: { index: resolve(__dirname, './website/index.html'), ...getCanvasFiles().reduce((acc, file) => { acc[`canvas/${file.replace('.html', '')}`] = resolve(canvasWebsiteDir, file); return acc; }, {} as Record), }, }, modulePreload: { polyfill: false, }, outDir: './dist', emptyOutDir: true, }, });