import type { ExtensionProcessDefinition, ProcessLauncherAPI, ProcessLauncherDefinition, } from "./extension-api.js"; import { cloneMap, registerUnique } from "./registry-utils.js"; /** @public */ export interface BuiltProcessLauncherDefinition { /** @public */ launchers: ReadonlyMap>; } function validateLauncherDefinition(def: ProcessLauncherDefinition): void { if (!def.id.trim()) { throw new Error("Launcher id is required"); } if (!def.label.trim()) { throw new Error(`Launcher '${def.id}' must define a non-empty label`); } if (!def.description.trim()) { throw new Error(`Launcher '${def.id}' must define a non-empty description`); } if (def.visibility !== "ui") { throw new Error(`Launcher '${def.id}' has unsupported visibility`); } if (!def.ui) { throw new Error(`UI launcher '${def.id}' must define a ui block`); } } /** @internal */ export function createProcessLauncherBuilder(): ProcessLauncherAPI & { /** @internal */ getDefinition(): BuiltProcessLauncherDefinition; } { const launchers = new Map>(); return { launcher(def: ProcessLauncherDefinition) { registerUnique(launchers, def.id, def, { duplicateMessage: `Launcher '${def.id}' is already registered`, validate: validateLauncherDefinition, }); }, getDefinition() { return { launchers: cloneMap(launchers), }; }, }; } /** @public */ export function buildProcessLaunchers( process: ExtensionProcessDefinition, ): BuiltProcessLauncherDefinition | undefined { if (!process.launchers) { return undefined; } const builder = createProcessLauncherBuilder(); process.launchers(builder); return builder.getDefinition(); }