import { readdir, readFile } from 'node:fs/promises'; import { join, relative } from 'node:path'; // Mistakes this client has made, each with what to do instead. const rules = [ { pattern: /crypto\.randomUUID/, why: 'crypto.randomUUID only exists in secure contexts (https or localhost); use uuidv7 from api.ts', }, { pattern: /<[a-z][^>]*\sautofocus\b/, why: 'autofocus does not take inside a flow node or a mounted window; focus with an attachment', }, { pattern: /svelte-flow__node\s*>\s*\.window-slot/, why: 'where a window sits is board.placeOf, on its slot as data-place; do not read it off its ancestors', }, ]; const root = new URL('../src', import.meta.url).pathname; async function* sources(dir) { for (const entry of await readdir(dir, { withFileTypes: true })) { const path = join(dir, entry.name); if (entry.isDirectory()) yield* sources(path); else if (/\.(svelte|ts|css)$/.test(entry.name) && !entry.name.endsWith('.gen.d.ts')) yield path; } } for await (const path of sources(root)) { const lines = (await readFile(path, 'utf8')).split('\n'); lines.forEach((line, at) => { for (const { pattern, why } of rules) { if (!pattern.test(line)) continue; console.error(`src/${relative(root, path)}:${at + 1}: ${why}`); process.exitCode = 1; } }); }