mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-22 10:14:22 +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
|
||||
dist
|
||||
.turbo
|
||||
**/.serena
|
||||
.serena/
|
||||
|
||||
@@ -34,8 +34,10 @@ export namespace Plugin {
|
||||
for (let plugin of plugins) {
|
||||
log.info("loading plugin", { path: plugin })
|
||||
if (!plugin.startsWith("file://")) {
|
||||
const [pkg, version] = plugin.split("@")
|
||||
plugin = await BunProc.install(pkg, version ?? "latest")
|
||||
const lastAtIndex = plugin.lastIndexOf("@")
|
||||
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)
|
||||
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 path from "path"
|
||||
import fs from "fs/promises"
|
||||
import { pathToFileURL } from "url"
|
||||
|
||||
test("loads config with defaults when no files exist", async () => {
|
||||
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