mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-22 18:24:21 +01:00
fix: support scoped npm plugins (#3785)
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -11,3 +11,5 @@ playground
|
|||||||
tmp
|
tmp
|
||||||
dist
|
dist
|
||||||
.turbo
|
.turbo
|
||||||
|
**/.serena
|
||||||
|
.serena/
|
||||||
|
|||||||
@@ -34,8 +34,10 @@ export namespace Plugin {
|
|||||||
for (let plugin of plugins) {
|
for (let plugin of plugins) {
|
||||||
log.info("loading plugin", { path: plugin })
|
log.info("loading plugin", { path: plugin })
|
||||||
if (!plugin.startsWith("file://")) {
|
if (!plugin.startsWith("file://")) {
|
||||||
const [pkg, version] = plugin.split("@")
|
const lastAtIndex = plugin.lastIndexOf("@")
|
||||||
plugin = await BunProc.install(pkg, version ?? "latest")
|
const pkg = lastAtIndex > 0 ? plugin.substring(0, lastAtIndex) : plugin
|
||||||
|
const version = lastAtIndex > 0 ? plugin.substring(lastAtIndex + 1) : "latest"
|
||||||
|
plugin = await BunProc.install(pkg, version)
|
||||||
}
|
}
|
||||||
const mod = await import(plugin)
|
const mod = await import(plugin)
|
||||||
for (const [_name, fn] of Object.entries<PluginInstance>(mod)) {
|
for (const [_name, fn] of Object.entries<PluginInstance>(mod)) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Instance } from "../../src/project/instance"
|
|||||||
import { tmpdir } from "../fixture/fixture"
|
import { tmpdir } from "../fixture/fixture"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
|
import { pathToFileURL } from "url"
|
||||||
|
|
||||||
test("loads config with defaults when no files exist", async () => {
|
test("loads config with defaults when no files exist", async () => {
|
||||||
await using tmp = await tmpdir()
|
await using tmp = await tmpdir()
|
||||||
@@ -350,3 +351,59 @@ test("gets config directories", async () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("resolves scoped npm plugins in config", async () => {
|
||||||
|
await using tmp = await tmpdir({
|
||||||
|
init: async (dir) => {
|
||||||
|
const pluginDir = path.join(dir, "node_modules", "@scope", "plugin")
|
||||||
|
await fs.mkdir(pluginDir, { recursive: true })
|
||||||
|
|
||||||
|
await Bun.write(
|
||||||
|
path.join(dir, "package.json"),
|
||||||
|
JSON.stringify({ name: "config-fixture", version: "1.0.0", type: "module" }, null, 2),
|
||||||
|
)
|
||||||
|
|
||||||
|
await Bun.write(
|
||||||
|
path.join(pluginDir, "package.json"),
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
name: "@scope/plugin",
|
||||||
|
version: "1.0.0",
|
||||||
|
type: "module",
|
||||||
|
main: "./index.js",
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
await Bun.write(path.join(pluginDir, "index.js"), "export default {}\n")
|
||||||
|
|
||||||
|
await Bun.write(
|
||||||
|
path.join(dir, "opencode.json"),
|
||||||
|
JSON.stringify(
|
||||||
|
{ $schema: "https://opencode.ai/config.json", plugin: ["@scope/plugin"] },
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await Instance.provide({
|
||||||
|
directory: tmp.path,
|
||||||
|
fn: async () => {
|
||||||
|
const config = await Config.get()
|
||||||
|
const pluginEntries = config.plugin ?? []
|
||||||
|
|
||||||
|
const baseUrl = pathToFileURL(path.join(tmp.path, "opencode.json")).href
|
||||||
|
const expected = import.meta.resolve("@scope/plugin", baseUrl)
|
||||||
|
|
||||||
|
expect(pluginEntries.includes(expected)).toBe(true)
|
||||||
|
|
||||||
|
const scopedEntry = pluginEntries.find((entry) => entry === expected)
|
||||||
|
expect(scopedEntry).toBeDefined()
|
||||||
|
expect(scopedEntry?.includes("/node_modules/@scope/plugin/")).toBe(true)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user