fix(plugins): isole les contributions plugin en erreur et durcit menus.ts
Le chargement de l'archive hello-plugin (build/hello-plugin-0.1.0.zip) vidait la fenêtre principale : une contribution plugin fautive remontait jusqu'au rendu global au lieu de rester locale à la cellule. Ajoute un boundary local dans PluginLayoutCellView/PluginLayoutSelectorSection et durcit menus.ts/loader.ts/registry.ts contre les entrées de menu ou contributions malformées. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@ -59,6 +59,23 @@ describe("resolveTopLevelMenus", () => {
|
||||
const resolved = resolveTopLevelMenus(registry);
|
||||
expect(resolved.map((m) => m.label)).toEqual(["Z Menu", "A Menu", "B Menu"]);
|
||||
});
|
||||
|
||||
it("drops malformed top-level menus instead of throwing during resolution", () => {
|
||||
const registry = new PluginRuntimeRegistry();
|
||||
registry.add(
|
||||
stubPlugin("dev.bad", "Bad", {
|
||||
...empty(),
|
||||
menus: [
|
||||
{ id: "bad.menu", label: "Good", topLevel: true },
|
||||
{ id: "bad.empty", label: "", topLevel: true },
|
||||
{ id: undefined, label: "No id", topLevel: true },
|
||||
{ id: "bad.no-label", label: undefined, topLevel: true },
|
||||
] as unknown as PluginContributionDto["menus"],
|
||||
}),
|
||||
);
|
||||
|
||||
expect(resolveTopLevelMenus(registry).map((m) => m.label)).toEqual(["Good"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveMenuItems", () => {
|
||||
@ -137,6 +154,36 @@ describe("resolveMenuItems", () => {
|
||||
expect(items.map((i) => i.label)).toEqual(["A item", "Z item"]);
|
||||
});
|
||||
|
||||
it("resolves hello-plugin's bare plugin menu target and skips malformed items", () => {
|
||||
const registry = new PluginRuntimeRegistry();
|
||||
registry.add(
|
||||
stubPlugin("com.example.hello-plugin", "Hello Plugin", {
|
||||
...empty(),
|
||||
menus: [{ id: "hello-plugin.menu", label: "Hello", topLevel: true }],
|
||||
menuItems: [
|
||||
{
|
||||
id: "hello-plugin.sayHello.item",
|
||||
targetMenuId: "hello-plugin.menu",
|
||||
label: "Say Hello",
|
||||
command: "hello-plugin.sayHello",
|
||||
},
|
||||
{
|
||||
id: "hello-plugin.broken.item",
|
||||
targetMenuId: "hello-plugin.menu",
|
||||
label: undefined,
|
||||
command: "hello-plugin.broken",
|
||||
},
|
||||
] as unknown as PluginContributionDto["menuItems"],
|
||||
}),
|
||||
);
|
||||
|
||||
const menus = resolveTopLevelMenus(registry);
|
||||
expect(menus.map((m) => m.id)).toEqual(["plugin:hello-plugin.menu"]);
|
||||
const items = resolveMenuItems(registry, "plugin:hello-plugin.menu", NO_CONTEXT);
|
||||
expect(items.map((i) => i.label)).toEqual(["Say Hello"]);
|
||||
expect(items[0].targetMenuId).toBe("plugin:hello-plugin.menu");
|
||||
});
|
||||
|
||||
it("dispatches a command via the registry's runCommand", async () => {
|
||||
const registry = new PluginRuntimeRegistry();
|
||||
let ran = false;
|
||||
|
||||
Reference in New Issue
Block a user