Single target plugin entrypoints (#19467)

This commit is contained in:
Sebastian
2026-03-28 00:44:46 +01:00
committed by GitHub
parent 02b19bc3d7
commit f3997d8082
18 changed files with 292 additions and 62 deletions

View File

@@ -130,3 +130,60 @@ test("rejects npm tui export that resolves outside plugin directory", async () =
delete process.env.OPENCODE_PLUGIN_META_FILE
}
})
test("rejects npm tui plugin that exports server and tui together", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
const mod = path.join(dir, "mods", "acme-plugin")
const marker = path.join(dir, "mixed-called.txt")
await fs.mkdir(mod, { recursive: true })
await Bun.write(
path.join(mod, "package.json"),
JSON.stringify({
name: "acme-plugin",
type: "module",
exports: { ".": "./index.js", "./tui": "./tui.js" },
}),
)
await Bun.write(path.join(mod, "index.js"), "export default {}\n")
await Bun.write(
path.join(mod, "tui.js"),
`export default {
id: "demo.mixed",
server: async () => ({}),
tui: async () => {
await Bun.write(${JSON.stringify(marker)}, "called")
},
}
`,
)
return { mod, marker, spec: "acme-plugin@1.0.0" }
},
})
process.env.OPENCODE_PLUGIN_META_FILE = path.join(tmp.path, "plugin-meta.json")
const get = spyOn(TuiConfig, "get").mockResolvedValue({
plugin: [tmp.extra.spec],
plugin_meta: {
[tmp.extra.spec]: { scope: "local", source: path.join(tmp.path, "tui.json") },
},
})
const wait = spyOn(TuiConfig, "waitForDependencies").mockResolvedValue()
const cwd = spyOn(process, "cwd").mockImplementation(() => tmp.path)
const install = spyOn(BunProc, "install").mockResolvedValue(tmp.extra.mod)
try {
await TuiPluginRuntime.init(createTuiPluginApi())
await expect(fs.readFile(tmp.extra.marker, "utf8")).rejects.toThrow()
expect(TuiPluginRuntime.list().some((item) => item.spec === tmp.extra.spec)).toBe(false)
} finally {
await TuiPluginRuntime.dispose()
install.mockRestore()
cwd.mockRestore()
get.mockRestore()
wait.mockRestore()
delete process.env.OPENCODE_PLUGIN_META_FILE
}
})