feat: rebuild raw apps on a ui/-only change, fail sync push on ui/ errors (#12051)

* feat: rebuild raw apps on a ui/-only change and fail sync push on ui/ errors

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: catch unquoted css ui/ imports and surface app lookup errors

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: match the raw app metadata file on windows sync paths

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
hugocasa
2026-10-28 06:07:55 +01:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 375bf03cdc
commit d3872cb183
4 changed files with 185 additions and 8 deletions
+51 -1
View File
@@ -14,6 +14,7 @@ import * as path from "node:path";
let remoteFiles: Record<string, string> = {};
let remoteUnreadable = false;
let pushedFiles: Record<string, string> | undefined;
let deployedApps: Record<string, { value: Record<string, unknown> }> = {};
mockServices({
getSharedUi: async (_args: { workspace: string }) => {
@@ -26,9 +27,15 @@ mockServices({
}) => {
pushedFiles = args.requestBody.files;
},
getAppByPath: async (args: { workspace: string; path: string }) => {
const app = deployedApps[args.path];
if (!app) throw Object.assign(new Error("not found"), { status: 404 });
return app;
},
});
const { diffSharedUi, pushSharedUi } = await import(
const { diffSharedUi, pushSharedUi, rawAppsStaleOnSharedUi, sharedUiHash } =
await import(
"../src/commands/shared_ui.ts"
);
@@ -148,3 +155,46 @@ describe("pushSharedUi with keepDeleted", () => {
.toEqual("keep me");
});
});
describe("rawAppsStaleOnSharedUi", () => {
let tmpDir: string;
let prevCwd: string;
beforeEach(() => {
prevCwd = process.cwd();
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "wm-shared-ui-apps-"));
process.chdir(tmpDir);
fs.mkdirSync(path.join(tmpDir, "ui"), { recursive: true });
fs.writeFileSync(path.join(tmpDir, "ui", "button.ts"), "v2", "utf-8");
});
afterEach(() => {
process.chdir(prevCwd);
fs.rmSync(tmpDir, { recursive: true, force: true });
});
const app = (name: string, index: string) => ({
[path.join("f", `${name}.raw_app`, "raw_app.yaml")]: "summary: x",
[path.join("f", `${name}.raw_app`, "index.tsx")]: index,
});
test("queues an app importing ui/ only when its bundle was built from other ui/ content", async () => {
const hash = await sharedUiHash();
deployedApps = {
"f/stale": { value: { shared_ui_hash: "old" } },
"f/fresh": { value: { shared_ui_hash: hash } },
"f/plain": { value: {} },
"f/css": { value: {} },
};
const localMap = {
...app("stale", `import { B } from "/ui/button"`),
...app("fresh", `import { B } from "/ui/button"`),
...app("plain", `import x from "./x"`),
...app("css", `@import url(/ui/theme.css);`),
};
expect(await rawAppsStaleOnSharedUi("ws", localMap, new Set())).toEqual([
path.join("f", "stale.raw_app", "raw_app.yaml"),
path.join("f", "css.raw_app", "raw_app.yaml"),
]);
});
});