import browserslist from 'browserslist'; import { transform, browserslistToTargets, Features } from 'lightningcss'; import { readdir, rmdir, copyFile, mkdir, exists } from 'node:fs/promises'; import { type Dirent } from 'node:fs'; const assignmentDir = './assignments'; const outDir = './.out'; const ENABLE_TRANSPILE = false; const targets = browserslistToTargets(browserslist('last 2 versions, > 0.1%')); const handleAssignment = async (project: Dirent) => { console.log(`transpiling project ${project.name}`); if (!ENABLE_TRANSPILE) console.warn('WARNING: transpilation is disabled!!'); await mkdir(`${outDir}/assignments/${project.name}`, { recursive: true }); const files = await readdir(`${assignmentDir}/${project.name}`, { withFileTypes: true, recursive: true }).then(n => n.filter(f => f.isFile()).map(f => (f.name.endsWith('.css') ? transpileCss(f) : copy(f))), ); await Promise.all(files); console.log(`transpiled project ${project.name}`); }; const copy = async ({ name, parentPath }: { name: string; parentPath: string }) => { console.log(`copying file ${name}`); if (!(await exists(`${outDir}/${parentPath}}`))) await mkdir(`${outDir}/${parentPath}`, { recursive: true }); await copyFile(`./${parentPath}/${name}`, `${outDir}/${parentPath}/${name}`); }; const transpileCss = async ({ name, parentPath }: { name: string; parentPath: string }) => { if (!ENABLE_TRANSPILE) return copy({ name, parentPath }); console.log(`transpiling css file ${name}`); const content = await Bun.file(`./${parentPath}/${name}`).arrayBuffer(); const { code, map } = transform({ filename: name, code: Buffer.from(content), minify: false, sourceMap: false, exclude: Features.Nesting, targets, }); await Bun.write(`${outDir}/${parentPath}/${name}`, code); if (map) await Bun.write(`${outDir}/${parentPath}/${name}.map`, map); }; await rmdir(outDir, { recursive: true }); const ignores = await Bun.file('.gitignore') .text() .then(n => n .split('\n') .filter(Boolean) .filter(n => !n.startsWith('#')), ); const assignments = await readdir(assignmentDir, { withFileTypes: true }).then(n => n.filter(f => f.isDirectory() && !f.name.startsWith('.') && !ignores.includes(f.name)).map(handleAssignment), ); await Promise.all(assignments);