diff --git a/README.md b/README.md index d93092b..16dd7b1 100644 --- a/README.md +++ b/README.md @@ -164,3 +164,13 @@ Origin while the proxy forwards it over HTTP, including missing/combined scheme headers. This prevents an apparently loaded editor with empty dropdowns when its module script is rejected before initialization. The browser also reports asset load failures instead of leaving the editor permanently at Checking. + +### Linux component previews + +Studio is pinned to 0.1.1, which resolves component files through the UI registry +instead of assuming a filename from the public component name. This fixes Linux +lookups such as Input -> input.wrn. Install the committed lockfile before +rebuilding and restarting; restarting a deployment still using Studio 0.1.0 +cannot fix this error. Tests enforce exact casing for the installed package on +all platforms, and the production check renders the composed preview plus every +component gallery page. diff --git a/bun.lock b/bun.lock index 26bb82f..b3823ed 100644 --- a/bun.lock +++ b/bun.lock @@ -6,7 +6,7 @@ "name": "component-showcase", "dependencies": { "@wrnexus/core": "0.8.25", - "@wrnexus/design-studio": "0.1.0", + "@wrnexus/design-studio": "0.1.1", "@wrnexus/design-system": "0.1.0", "@wrnexus/dev-server": "0.8.83", "@wrnexus/helpers": "0.8.10", @@ -164,7 +164,7 @@ "@wrnexus/db": ["@wrnexus/db@0.8.24", "https://registry.workroot.in/repository/npm/@wrnexus/db/-/db-0.8.24.tgz", {}, "sha512-zLT7e+C1nWhYs3BnqEjEO0QSli0JNl5sSnSHObjSX0C+wty30ASWD1WyBnfu9xFjOFn1eucZGthzo1xdGGQ1TQ=="], - "@wrnexus/design-studio": ["@wrnexus/design-studio@0.1.0", "https://registry.workroot.in/repository/npm/@wrnexus/design-studio/-/design-studio-0.1.0.tgz", { "dependencies": { "@wrnexus/ai": "^0.8.10", "@wrnexus/compiler": "^0.8.44", "@wrnexus/core": "^0.8.25", "@wrnexus/csr": "^0.8.74", "@wrnexus/design-system": "^0.1.0", "@wrnexus/ssr": "^0.8.20", "@wrnexus/styles": "^0.8.27", "@wrnexus/ui": "^0.8.118" }, "bin": { "wrnexus-design-studio": "dist/cli.js" } }, "sha512-HeY3zG45oEvsLy1my9nCgKHb11ip9eTthhp/bzeOIXEn8vk71pRhqdgrltEwn2vFKIlKuPBQlA4xftmLDhSWTQ=="], + "@wrnexus/design-studio": ["@wrnexus/design-studio@0.1.1", "https://registry.workroot.in/repository/npm/@wrnexus/design-studio/-/design-studio-0.1.1.tgz", { "dependencies": { "@wrnexus/ai": "^0.8.10", "@wrnexus/compiler": "^0.8.44", "@wrnexus/core": "^0.8.25", "@wrnexus/csr": "^0.8.74", "@wrnexus/design-system": "^0.1.0", "@wrnexus/ssr": "^0.8.20", "@wrnexus/styles": "^0.8.27", "@wrnexus/ui": "^0.8.118" }, "bin": { "wrnexus-design-studio": "dist/cli.js" } }, "sha512-BV8O34W/ey+izIgGuFevq+c0c3vjxB75KqHPhVaALt97X8I1FUvALzzODIhUyIMOSMlHGq0qaTW+2LQvbeUYyg=="], "@wrnexus/design-system": ["@wrnexus/design-system@0.1.0", "https://registry.workroot.in/repository/npm/@wrnexus/design-system/-/design-system-0.1.0.tgz", {}, "sha512-gNH/B+kYYZy+Pvlvl3gXoQZlTS6iP/teXct2MoClmsGp6M1vKa8IEptVXKs7po3E83zj5kSh3FIXwcBJHtZqLg=="], diff --git a/deploy/studio-linux-preview-fixed.jpg b/deploy/studio-linux-preview-fixed.jpg new file mode 100644 index 0000000..63b53b3 Binary files /dev/null and b/deploy/studio-linux-preview-fixed.jpg differ diff --git a/package-lock.json b/package-lock.json index 65a7400..3dddaa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.8.8", "dependencies": { "@wrnexus/core": "0.8.25", - "@wrnexus/design-studio": "0.1.0", + "@wrnexus/design-studio": "0.1.1", "@wrnexus/design-system": "0.1.0", "@wrnexus/dev-server": "0.8.83", "@wrnexus/helpers": "0.8.10", @@ -1186,9 +1186,9 @@ } }, "node_modules/@wrnexus/design-studio": { - "version": "0.1.0", - "resolved": "https://registry.workroot.in/repository/npm/@wrnexus/design-studio/-/design-studio-0.1.0.tgz", - "integrity": "sha512-HeY3zG45oEvsLy1my9nCgKHb11ip9eTthhp/bzeOIXEn8vk71pRhqdgrltEwn2vFKIlKuPBQlA4xftmLDhSWTQ==", + "version": "0.1.1", + "resolved": "https://registry.workroot.in/repository/npm/@wrnexus/design-studio/-/design-studio-0.1.1.tgz", + "integrity": "sha512-BV8O34W/ey+izIgGuFevq+c0c3vjxB75KqHPhVaALt97X8I1FUvALzzODIhUyIMOSMlHGq0qaTW+2LQvbeUYyg==", "license": "MIT", "dependencies": { "@wrnexus/ai": "^0.8.10", diff --git a/package.json b/package.json index c740696..f45e0f7 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "@wrnexus/styles": "0.8.27", "@wrnexus/syntax": "0.8.20", "@wrnexus/ui": "0.8.118", - "@wrnexus/design-studio": "0.1.0", + "@wrnexus/design-studio": "0.1.1", "@wrnexus/design-system": "0.1.0" }, "devDependencies": { diff --git a/scripts/verify-deployment.ts b/scripts/verify-deployment.ts index b018caa..4787e40 100644 --- a/scripts/verify-deployment.ts +++ b/scripts/verify-deployment.ts @@ -105,6 +105,24 @@ try { !(await fetch(origin + url)).ok ) throw Error("Studio preview was not mounted under the app path."); + for (let page = 0; page < 7; page++) { + const gallery = await fetch(origin + "/design-studio/api/preview", { + method: "POST", + headers: { "content-type": "application/json", origin }, + body: JSON.stringify({ + system: CORE_DESIGN_SYSTEMS.soft, + content: "catalog", + page, + }), + }); + if (!gallery.ok) + throw Error( + `Component gallery page ${page + 1} failed: ${await gallery.text()}`, + ); + const artifact = await gallery.json(); + if (!(await fetch(origin + artifact.url)).ok) + throw Error(`Gallery page ${page + 1} did not render.`); + } console.log( "Compiled server serves component pages, Studio assets, export-only APIs and previews on one port.", ); diff --git a/test/studio-case.test.ts b/test/studio-case.test.ts new file mode 100644 index 0000000..5905b94 --- /dev/null +++ b/test/studio-case.test.ts @@ -0,0 +1,43 @@ +import { expect, test } from "bun:test"; +import { resolve } from "node:path"; + +test("installed Studio previews resolve exact Linux filenames for every component", () => { + const probe = ` + import { mock } from "bun:test"; + import { readFileSync, readdirSync } from "node:fs"; + import { dirname, basename } from "node:path"; + import { uiComponentsDir } from "@wrnexus/ui/registry"; + import { CORE_DESIGN_SYSTEMS } from "@wrnexus/design-system"; + const directory = uiComponentsDir(), names = new Set(readdirSync(directory)), originalRead = readFileSync; + let checked = 0; + mock.module("node:fs", () => ({ readFileSync(path, ...options) { + if (typeof path === "string" && dirname(path) === directory && path.endsWith(".wrn")) { + if (!names.has(basename(path))) throw Error("Case-sensitive component lookup failed: " + basename(path)); + checked++; + } + return originalRead(path, ...options); + }})); + const { createStudioHandler } = await import("@wrnexus/design-studio/server"); + const handler = await createStudioHandler(); + for (const options of [{}, ...Array.from({length:7}, (_, page) => ({content:"catalog", page}))]) { + const response = await handler(new Request("http://127.0.0.1/api/preview", { + method:"POST", headers:{"content-type":"application/json"}, body:JSON.stringify({system:CORE_DESIGN_SYSTEMS.soft,...options}) + })); + if (!response.ok) throw Error(await response.text()); + } + if (checked < 104) throw Error("Incomplete installed preview coverage: " + checked); + console.log("All 104 installed preview components pass case-sensitive file lookup."); + `; + const result = Bun.spawnSync([process.execPath, "--eval", probe], { + cwd: resolve(import.meta.dir, ".."), + stdout: "pipe", + stderr: "pipe", + }); + expect(new TextDecoder().decode(result.stderr)).not.toContain( + "Case-sensitive component lookup failed", + ); + expect(result.exitCode).toBe(0); + expect(new TextDecoder().decode(result.stdout)).toContain( + "All 104 installed preview components", + ); +});