types
parent
3cc33e39e7
commit
a7400a77ea
|
|
@ -18,7 +18,7 @@ import { resolvePluginTarget, uniqueModuleEntries } from "@/plugin/shared"
|
|||
import { registerThemes } from "./context/theme"
|
||||
|
||||
type Slot = <K extends keyof TuiSlotMap>(props: { name: K } & TuiSlotMap[K]) => JSX.Element | null
|
||||
type InitInput<Renderer> = Omit<TuiPluginInput<Renderer>, "slots">
|
||||
type InitInput = Omit<TuiPluginInput<CliRenderer>, "slots">
|
||||
|
||||
function empty<K extends keyof TuiSlotMap>(_props: { name: K } & TuiSlotMap[K]) {
|
||||
return null
|
||||
|
|
@ -44,22 +44,16 @@ function getThemes(value: unknown) {
|
|||
return value.themes
|
||||
}
|
||||
|
||||
function isTuiPlugin<Renderer>(value: unknown): value is TuiPluginFn<Renderer> {
|
||||
function isTuiPlugin(value: unknown): value is TuiPluginFn<CliRenderer> {
|
||||
return typeof value === "function"
|
||||
}
|
||||
|
||||
function getTuiPlugin<Renderer>(value: unknown) {
|
||||
function getTuiPlugin(value: unknown) {
|
||||
if (!isRecord(value) || !("tui" in value)) return
|
||||
if (!isTuiPlugin<Renderer>(value.tui)) return
|
||||
if (!isTuiPlugin(value.tui)) return
|
||||
return value.tui
|
||||
}
|
||||
|
||||
function isCliRenderer(value: unknown): value is CliRenderer {
|
||||
if (!isRecord(value)) return false
|
||||
if (!("once" in value)) return false
|
||||
return typeof value.once === "function"
|
||||
}
|
||||
|
||||
export namespace TuiPlugin {
|
||||
const log = Log.create({ service: "tui.plugin" })
|
||||
let loaded: Promise<void> | undefined
|
||||
|
|
@ -67,11 +61,7 @@ export namespace TuiPlugin {
|
|||
|
||||
export const Slot: Slot = (props) => view(props)
|
||||
|
||||
function setupSlots(renderer: unknown): TuiSlots {
|
||||
if (!isCliRenderer(renderer)) {
|
||||
throw new TypeError("Invalid TUI renderer")
|
||||
}
|
||||
|
||||
function setupSlots(renderer: CliRenderer): TuiSlots {
|
||||
const reg = createSolidSlotRegistry<TuiSlotMap, TuiSlotContext>(
|
||||
renderer,
|
||||
{},
|
||||
|
|
@ -98,7 +88,7 @@ export namespace TuiPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
export async function init<Renderer>(input: InitInput<Renderer>) {
|
||||
export async function init(input: InitInput) {
|
||||
if (loaded) return loaded
|
||||
loaded = load({
|
||||
...input,
|
||||
|
|
@ -107,7 +97,7 @@ export namespace TuiPlugin {
|
|||
return loaded
|
||||
}
|
||||
|
||||
async function load<Renderer>(input: TuiPluginInput<Renderer>) {
|
||||
async function load(input: TuiPluginInput<CliRenderer>) {
|
||||
const dir = process.cwd()
|
||||
|
||||
await Instance.provide({
|
||||
|
|
@ -148,7 +138,7 @@ export namespace TuiPlugin {
|
|||
const slotPlugin = getTuiSlotPlugin(entry)
|
||||
if (slotPlugin) input.slots.register(slotPlugin)
|
||||
|
||||
const tuiPlugin = getTuiPlugin<Renderer>(entry)
|
||||
const tuiPlugin = getTuiPlugin(entry)
|
||||
if (!tuiPlugin) continue
|
||||
await tuiPlugin(input, Config.pluginOptions(item))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import fs from "fs/promises"
|
|||
import path from "path"
|
||||
import { pathToFileURL } from "url"
|
||||
import { createOpencodeClient } from "@opencode-ai/sdk/v2"
|
||||
import type { CliRenderer } from "@opentui/core"
|
||||
import { tmpdir } from "../../fixture/fixture"
|
||||
import { Log } from "../../../src/util/log"
|
||||
|
||||
|
|
@ -80,6 +81,13 @@ test("ignores function-only tui exports and loads object exports", async () => {
|
|||
process.env.OPENCODE_TUI_CONFIG = tmp.extra.configPath
|
||||
const cwd = spyOn(process, "cwd").mockImplementation(() => tmp.path)
|
||||
|
||||
const renderer = {
|
||||
...Object.create(null),
|
||||
once(this: CliRenderer) {
|
||||
return this
|
||||
},
|
||||
} satisfies CliRenderer
|
||||
|
||||
try {
|
||||
await TuiPlugin.init({
|
||||
client: createOpencodeClient({
|
||||
|
|
@ -88,9 +96,7 @@ test("ignores function-only tui exports and loads object exports", async () => {
|
|||
event: {
|
||||
on: () => () => {},
|
||||
},
|
||||
renderer: {
|
||||
once: () => undefined,
|
||||
},
|
||||
renderer,
|
||||
})
|
||||
|
||||
expect(await fs.readFile(tmp.extra.objMarker, "utf8")).toBe("called")
|
||||
|
|
|
|||
Loading…
Reference in New Issue