(input: PlugInput, dep: PlugDeps = defaultPlugDeps)
| 68 | } |
| 69 | |
| 70 | export function createPlugTask(input: PlugInput, dep: PlugDeps = defaultPlugDeps) { |
| 71 | const mod = input.mod |
| 72 | const force = Boolean(input.force) |
| 73 | const global = Boolean(input.global) |
| 74 | |
| 75 | return async (ctx: PlugCtx) => { |
| 76 | const install = dep.spinner() |
| 77 | install.start("Installing plugin package...") |
| 78 | const target = await installPlugin(mod, dep) |
| 79 | if (!target.ok) { |
| 80 | install.stop("Install failed", 1) |
| 81 | dep.log.error(`Could not install "${mod}"`) |
| 82 | const hit = cause(target.error) ?? target.error |
| 83 | if (hit instanceof Process.RunFailedError) { |
| 84 | const lines = hit.stderr |
| 85 | .toString() |
| 86 | .split(/\r?\n/) |
| 87 | .map((line) => line.trim()) |
| 88 | .filter(Boolean) |
| 89 | const errs = lines.filter((line) => line.startsWith("error:")).map((line) => line.replace(/^error:\s*/, "")) |
| 90 | const detail = errs[0] ?? lines.at(-1) |
| 91 | if (detail) dep.log.error(detail) |
| 92 | if (lines.some((line) => line.includes("No version matching"))) { |
| 93 | dep.log.info("This package depends on a version that is not available in your npm registry.") |
| 94 | dep.log.info("Check npm registry/auth settings and try again.") |
| 95 | } |
| 96 | } |
| 97 | if (!(hit instanceof Process.RunFailedError)) { |
| 98 | dep.log.error(errorMessage(hit)) |
| 99 | } |
| 100 | return false |
| 101 | } |
| 102 | install.stop("Plugin package ready") |
| 103 | |
| 104 | const inspect = dep.spinner() |
| 105 | inspect.start("Reading plugin manifest...") |
| 106 | const manifest = await readPluginManifest(target.target) |
| 107 | if (!manifest.ok) { |
| 108 | if (manifest.code === "manifest_read_failed") { |
| 109 | inspect.stop("Manifest read failed", 1) |
| 110 | dep.log.error(`Installed "${mod}" but failed to read ${manifest.file}`) |
| 111 | dep.log.error(errorMessage(cause(manifest.error) ?? manifest.error)) |
| 112 | return false |
| 113 | } |
| 114 | |
| 115 | if (manifest.code === "manifest_no_targets") { |
| 116 | inspect.stop("No plugin targets found", 1) |
| 117 | dep.log.error(`"${mod}" does not expose plugin entrypoints in package.json`) |
| 118 | dep.log.info( |
| 119 | 'Expected one of: exports["./tui"], exports["./server"], package.json main for server, or package.json["oc-themes"] for tui themes.', |
| 120 | ) |
| 121 | return false |
| 122 | } |
| 123 | |
| 124 | inspect.stop("Manifest read failed", 1) |
| 125 | return false |
| 126 | } |
| 127 |
no test coverage detected