fix(plugins): support export default { activate }, cleanup partiel et erreurs visibles
Le loader accepte désormais aussi la forme export default { activate }
en plus de l'export nommé, les subscriptions partiellement établies
sont nettoyées en cas d'échec d'activation, et une erreur de
runtime-catalog est remontée visuellement dans PluginsPanel avec un
badge Invalide/Isolé sur les plugins concernés (#116/#120).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -81,6 +81,12 @@ function isIdeaPluginModule(mod: unknown): mod is IdeaPluginModule {
|
||||
);
|
||||
}
|
||||
|
||||
function resolveIdeaPluginModule(mod: unknown): IdeaPluginModule | null {
|
||||
if (isIdeaPluginModule(mod)) return mod;
|
||||
const defaultExport = objectOrEmpty(mod).default;
|
||||
return isIdeaPluginModule(defaultExport) ? defaultExport : null;
|
||||
}
|
||||
|
||||
function createPluginLogger(entry: PluginRuntimePlugin): PluginLogger {
|
||||
const prefix = `[plugin:${safePluginId(entry)}]`;
|
||||
return {
|
||||
@ -169,6 +175,8 @@ async function loadOne(
|
||||
const pluginId = safePluginId(entry);
|
||||
const displayName = nonEmptyString(entryObject.displayName) ?? pluginId;
|
||||
const version = nonEmptyString(entryObject.version) ?? "";
|
||||
let activation: void | PluginActivation = undefined;
|
||||
const subscriptions: Disposable[] = [];
|
||||
try {
|
||||
// The bundle URL is a plugin-scoped, content-hashed local protocol URL
|
||||
// served by the backend (carnet §1.3) — never a disk path or arbitrary
|
||||
@ -178,8 +186,8 @@ async function loadOne(
|
||||
throw new Error("missing plugin bundle URL");
|
||||
}
|
||||
|
||||
const mod: unknown = await import(/* @vite-ignore */ bundleUrl);
|
||||
if (!isIdeaPluginModule(mod)) {
|
||||
const mod = resolveIdeaPluginModule(await import(/* @vite-ignore */ bundleUrl));
|
||||
if (!mod) {
|
||||
return {
|
||||
failure: {
|
||||
pluginId,
|
||||
@ -194,7 +202,6 @@ async function loadOne(
|
||||
const commands = new PluginCommandRegistry(pluginId, declaredCommandIds);
|
||||
const layouts = new PluginLayoutRegistry(pluginId, declaredLayoutTypes);
|
||||
const menu = new PluginMenuRegistry(pluginId);
|
||||
const subscriptions: Disposable[] = [];
|
||||
|
||||
const ctx: IdeaPluginContext = {
|
||||
pluginId,
|
||||
@ -208,7 +215,7 @@ async function loadOne(
|
||||
...gateways,
|
||||
};
|
||||
|
||||
const activation = await mod.activate(ctx);
|
||||
activation = await mod.activate(ctx);
|
||||
|
||||
const plugin: LoadedPlugin = {
|
||||
pluginId,
|
||||
@ -225,6 +232,7 @@ async function loadOne(
|
||||
};
|
||||
return { plugin };
|
||||
} catch (e) {
|
||||
await disposeAll(subscriptions, activation);
|
||||
return {
|
||||
failure: {
|
||||
pluginId,
|
||||
|
||||
Reference in New Issue
Block a user