-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
60 lines (48 loc) · 2.32 KB
/
index.ts
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
import { readFile } from "fs/promises"
import { spawnSync } from "child_process"
import { cwd, chdir } from "process"
import { parse } from "toml"
import { basename } from "path"
import { Plugin, PluginBuild, Message } from "esbuild"
const PLUGIN_NAME = "esgleam"
const convertMessage = (message: string): Message => ({ id: message, pluginName: PLUGIN_NAME, location: null, notes: [], detail: null, text: `\n${PLUGIN_NAME}:\n${message}` })
const compile = (gleam_dir: string, extra_args: string[]) => {
const pwd = cwd()
chdir(gleam_dir)
const gleam = spawnSync("gleam", ["build", "--target", "javascript", ...extra_args])
if (cwd() !== pwd) {
chdir(pwd)
}
return { out: gleam.stdout, stderr: gleam.stderr, err: gleam.error }
}
const load_gleam_name = async (gleam_dir: string): Promise<string> => {
const contents = await readFile(`${gleam_dir}/gleam.toml`, "utf8")
return parse(contents).name
}
export interface EsGleamOptions { project_root?: string, main_function?: string, compile_args?: string[] }
export function esgleam(opts: EsGleamOptions | undefined = undefined): Plugin {
return {
name: PLUGIN_NAME,
setup(build: PluginBuild) {
build.onLoad({ filter: /\.gleam$/ }, async (args) => {
const project_root = opts?.project_root ?? "."
const compile_args = opts?.compile_args ?? []
const filename = basename(args.path).replace(".gleam", ".mjs")
const project_name = await load_gleam_name(project_root)
const build_path = `${project_root}/build/dev/javascript/${project_name}/dist`
const { out: _, stderr, err } = compile(project_root, compile_args)
if (stderr && stderr.length > 0) {
return { errors: [convertMessage(stderr.toString())] }
}
if (err && err?.message.length > 0) {
return { errors: [convertMessage(`Error running gleam: ${err.message}`)] }
}
let contents = await readFile(`${build_path}/${filename}`, "utf8")
if (opts?.main_function !== undefined) {
contents += `\n\n${opts.main_function}();`
}
return { contents, loader: "js", resolveDir: build_path }
})
}
}
}