// The obsidian surface written out as a number instead of read from its token. // // fabled-tokens.js is the palette's single copy ("do not hand-edit hexes; // re-mirror here"). Thirteen hand-typed `rgba(20, 23, 26, …)` across six // components meant a changed obsidian would miss most of the UI (#3108). // Components read `--v-theme-background` (Vuetify maps background → obsidian) // or, for nav-style chrome, `--fc-chrome-rgb`. Comments may still name it. import { readdirSync, readFileSync, statSync } from 'node:fs' import { join, relative } from 'node:path' import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' const SRC = fileURLToPath(new URL('../src', import.meta.url)) const LITERAL = /rgba?\(\s*20\s*,\s*23\s*,\s*26\b/ function vueFiles (dir) { return readdirSync(dir).flatMap((name) => { const path = join(dir, name) if (statSync(path).isDirectory()) return vueFiles(path) return name.endsWith('.vue') ? [path] : [] }) } function stripComments (text) { return text.replace(/\/\*[\s\S]*?\*\//g, '').replace(//g, '') } describe('palette literals', () => { it('no component hand-types the obsidian surface', () => { const offenders = vueFiles(SRC).flatMap((path) => stripComments(readFileSync(path, 'utf8')) .split('\n') .filter((line) => LITERAL.test(line)) .map((line) => `${relative(SRC, path)}: ${line.trim()}`) ) expect(offenders).toEqual([]) }) })