'use strict'; // Generate manifest.json from the shader sources — the .glsl files are the SINGLE source of truth. // Each shader's header carries its display name (first `//` line) and a `// blurb: ...` line; params // come from parseParams (the same convention the renderer + dashboard read). Nothing is hand-kept in // the manifest, so it can't drift. `npm run build:manifest` writes it; the compile test byte-compares. const fs = require('fs'); const path = require('path'); const { parseParams } = require('./params.js'); const DIR = __dirname; function entryFor(file, src) { const lines = src.split('\n'); const titleLine = lines.find((l) => /^\/\/\s*\S/.test(l) && !/^\/\/\s*(blurb|author|license|gl transitions)\b/i.test(l)); const name = titleLine ? titleLine.replace(/^\/\/\s*/, '').trim() : file.replace(/\.glsl$/, ''); const blurbLine = lines.find((l) => /^\/\/\s*blurb\s*:/i.test(l)); const blurb = blurbLine ? blurbLine.replace(/^\/\/\s*blurb\s*:\s*/i, '').trim() : ''; const params = parseParams(src).map((p) => ({ name: p.name, default: p.default, min: p.min, max: p.max })); return { id: file.replace(/\.glsl$/, ''), name, blurb, file, params }; } function build() { return fs.readdirSync(DIR) .filter((f) => f.endsWith('.glsl')) .sort() // deterministic order so the generated bytes are stable .map((file) => entryFor(file, fs.readFileSync(path.join(DIR, file), 'utf8'))); } function serialize(manifest) { return JSON.stringify(manifest, null, 2) + '\n'; } if (require.main === module) { const bytes = serialize(build()); fs.writeFileSync(path.join(DIR, 'manifest.json'), bytes); console.log(`Wrote manifest.json (${build().length} shaders).`); } module.exports = { build, serialize };