-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbuild-plugins.mjs
More file actions
115 lines (102 loc) · 3.32 KB
/
Copy pathbuild-plugins.mjs
File metadata and controls
115 lines (102 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { mkdir, readFile, rm } from "node:fs/promises"
import { builtinModules } from "node:module"
import { dirname, resolve } from "node:path"
import { fileURLToPath, pathToFileURL } from "node:url"
import { build } from "esbuild"
import { transformAsync } from "@babel/core"
import { pluginManifest, validatePluginManifest } from "./plugin-manifest.mjs"
const projectRoot = dirname(fileURLToPath(import.meta.url))
const distRoot = resolve(projectRoot, "dist")
const hostDependencies = [
"solid-js",
"solid-js/*",
"@opentui/*",
"@opencode-ai/plugin",
"@opencode-ai/plugin/*",
"@opencode-ai/sdk",
"@opencode-ai/sdk/*",
"bun:*",
"better-sqlite3",
...builtinModules,
...builtinModules.filter((name) => !name.startsWith("node:")).map((name) => `node:${name}`),
]
const common = {
absWorkingDir: projectRoot,
bundle: true,
external: hostDependencies,
format: "esm",
metafile: true,
minify: true,
platform: "node",
target: "es2022",
}
async function transformSolid(code, filename) {
const solidPreset = (await import("babel-preset-solid")).default
const tsPreset = (await import("@babel/preset-typescript")).default
const presets = [[solidPreset, { moduleName: "@opentui/solid", generate: "universal" }]]
if (/\.[cm]?tsx?$/.test(filename)) {
presets.push([tsPreset])
}
const result = await transformAsync(code, { filename, configFile: false, babelrc: false, presets })
return result?.code ?? code
}
function solidTransformPlugin() {
return {
name: "solid-jsx-transform",
setup(buildApi) {
buildApi.onLoad({ filter: /\.[cm]?tsx?$/ }, async (args) => {
const code = await readFile(args.path, "utf8")
const transformed = await transformSolid(code, args.path)
return { contents: transformed, loader: "js" }
})
},
}
}
function sharedImport(path) {
return {
name: "external-shared-artifact",
setup(buildApi) {
buildApi.onResolve({ filter: /(?:^|\/)shared\/opencode-tools-shared(?:\.js)?$/ }, () => ({
external: true,
path,
}))
},
}
}
function hostRuntimeImports() {
return {
name: "opencode-host-runtime",
setup(buildApi) {
buildApi.onResolve({ filter: /^(?:solid-js|@opentui\/solid|@opentui\/solid\/jsx-runtime)$/ }, (args) => ({
external: true,
path: `opentui:runtime-module:${encodeURIComponent(args.path)}`,
}))
},
}
}
export async function buildPlugins({ logLevel = "info", manifest = pluginManifest } = {}) {
validatePluginManifest(manifest)
await mkdir(distRoot, { recursive: true })
await rm(resolve(distRoot, "plugins/opencode-tools-tokens.js"), { force: true })
const shared = await build({
...common,
entryPoints: ["shared/opencode-tools-shared.ts"],
logLevel,
outfile: resolve(distRoot, "opencode-tools-shared.js"),
plugins: [solidTransformPlugin(), hostRuntimeImports()],
})
const features = {}
for (const entry of manifest) {
features[entry.key] = await build({
...common,
entryPoints: [entry.source],
logLevel,
outfile: resolve(distRoot, entry.outfile),
plugins: [solidTransformPlugin(), hostRuntimeImports(), sharedImport("./opencode-tools-shared.js")],
})
}
return { shared, features }
}
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
await buildPlugins()
}