(state: RuntimeState | undefined, raw: string)
| 846 | } |
| 847 | |
| 848 | async function addPluginBySpec(state: RuntimeState | undefined, raw: string) { |
| 849 | if (!state) return false |
| 850 | const spec = raw.trim() |
| 851 | if (!spec) return false |
| 852 | |
| 853 | const cfg = state.pending.get(spec) ?? defaultPluginOrigin(state, spec) |
| 854 | const next = ConfigPlugin.pluginSpecifier(cfg.spec) |
| 855 | if (state.plugins.some((plugin) => plugin.load.spec === next)) { |
| 856 | state.pending.delete(spec) |
| 857 | return true |
| 858 | } |
| 859 | const ready = await resolveExternalPlugins([cfg], () => TuiConfig.waitForDependencies()).catch((error) => { |
| 860 | fail("failed to add tui plugin", { path: next, error }) |
| 861 | return [] as PluginLoad[] |
| 862 | }) |
| 863 | if (!ready.length) { |
| 864 | return false |
| 865 | } |
| 866 | |
| 867 | const first = ready[0] |
| 868 | if (!first) { |
| 869 | fail("failed to add tui plugin", { path: next }) |
| 870 | return false |
| 871 | } |
| 872 | if (state.plugins_by_id.has(first.id)) { |
| 873 | state.pending.delete(spec) |
| 874 | return true |
| 875 | } |
| 876 | |
| 877 | const out = await addExternalPluginEntries(state, [first]) |
| 878 | let ok = out.ok && out.plugins.length > 0 |
| 879 | for (const plugin of out.plugins) { |
| 880 | const active = await activatePluginEntry(state, plugin, false) |
| 881 | if (!active) ok = false |
| 882 | } |
| 883 | |
| 884 | if (ok) state.pending.delete(spec) |
| 885 | if (!ok) { |
| 886 | fail("failed to add tui plugin", { path: next }) |
| 887 | } |
| 888 | return ok |
| 889 | } |
| 890 | |
| 891 | async function installPluginBySpec( |
| 892 | state: RuntimeState | undefined, |
no test coverage detected