diff --git a/README.md b/README.md index b1590475..af132cc4 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,19 @@ -# WRNexusJS 0.4.0 lint fix +# WRNexusJS 0.4.0 UI reference determinism fix -Extract this archive into the WRNexusJS repository root and replace the included files. +This fixes the release loop where `generate-ui-component-reference.mjs` writes one layout and Prettier rewrites it differently. The generator now formats both generated files with the repository Prettier configuration before writing them. -Fixes: +Replace: -- Removes the `no-useless-assignment` failure in the CAPTCHA page-grant endpoint. -- Restores the Button showcase's specialized examples so `buttonUses` is used. -- Declares browser globals for the package-owned CAPTCHA runtime. -- Replaces empty catch blocks with documented best-effort cleanup. -- Fixes `prefer-const` in package discovery. -- Removes unused plugin, style-audit, and UI-test bindings. -- Uses the UI-reference verifier in the release workflow. -- Declares Node globals correctly in installer and validation scripts. +- `scripts/generate-ui-component-reference.mjs` -Run: +Then run: ```bash -bun run lint -bun run validate:0.4 +bun run scripts/generate-ui-component-reference.mjs +bun run format +bun run format:check +git add scripts/generate-ui-component-reference.mjs packages/ui/component-reference.json packages/ui/COMPONENTS.md +git commit -m "fix(release): make UI reference generation deterministic" +git push origin main +bun run release:private ``` diff --git a/scripts/generate-ui-component-reference.mjs b/scripts/generate-ui-component-reference.mjs index 4e16e345..16a1c166 100644 --- a/scripts/generate-ui-component-reference.mjs +++ b/scripts/generate-ui-component-reference.mjs @@ -1,11 +1,22 @@ import { readdirSync, readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; +import { format, resolveConfig } from "prettier"; const uiRoot = join(import.meta.dirname, "..", "packages", "ui"); const componentsDir = join(uiRoot, "components"); const catalog = JSON.parse(readFileSync(join(uiRoot, "component-catalog.json"), "utf8")); const metadata = new Map(catalog.components.map((entry) => [entry.name, entry])); +async function writeFormatted(path, source, parser) { + const config = (await resolveConfig(path)) ?? {}; + const formatted = await format(source, { + ...config, + filepath: path, + parser, + }); + writeFileSync(path, formatted); +} + function block(source, keyword) { const start = source.indexOf(`${keyword} {`); if (start < 0) return ""; @@ -84,13 +95,15 @@ const components = readdirSync(componentsDir) }) .sort((left, right) => left.name.localeCompare(right.name)); -writeFileSync( - join(uiRoot, "component-reference.json"), +const referencePath = join(uiRoot, "component-reference.json"); +await writeFormatted( + referencePath, JSON.stringify( { generatedFrom: "packages/ui/components/*.wrn", count: components.length, components }, null, 2, ) + "\n", + "json", ); const lines = [ @@ -123,4 +136,5 @@ for (const category of [...new Set(components.map((component) => component.categ ); } } -writeFileSync(join(uiRoot, "COMPONENTS.md"), `${lines.join("\n").trimEnd()}\n`); +const componentsPath = join(uiRoot, "COMPONENTS.md"); +await writeFormatted(componentsPath, `${lines.join("\n").trimEnd()}\n`, "markdown");