mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-30 22:03:58 +00:00
135 lines
3.0 KiB
TypeScript
135 lines
3.0 KiB
TypeScript
import { App } from "../app/app"
|
|
import { BunProc } from "../bun"
|
|
import { Config } from "../config/config"
|
|
import { Log } from "../util/log"
|
|
import path from "path"
|
|
|
|
export namespace Format {
|
|
const log = Log.create({ service: "format" })
|
|
|
|
const state = App.state("format", async () => {
|
|
const hooks: Record<string, Hook[]> = {}
|
|
for (const item of FORMATTERS) {
|
|
if (await item.enabled()) {
|
|
for (const ext of item.extensions) {
|
|
const list = hooks[ext] ?? []
|
|
list.push({
|
|
command: item.command,
|
|
environment: item.environment,
|
|
})
|
|
hooks[ext] = list
|
|
}
|
|
}
|
|
}
|
|
|
|
const cfg = await Config.get()
|
|
for (const [file, items] of Object.entries(
|
|
cfg.experimental?.hook?.file_edited ?? {},
|
|
)) {
|
|
for (const item of items) {
|
|
const list = hooks[file] ?? []
|
|
list.push({
|
|
command: item.command,
|
|
environment: item.environment,
|
|
})
|
|
hooks[file] = list
|
|
}
|
|
}
|
|
|
|
return {
|
|
hooks,
|
|
}
|
|
})
|
|
|
|
export async function run(file: string) {
|
|
log.info("formatting", { file })
|
|
const { hooks } = await state()
|
|
const ext = path.extname(file)
|
|
const match = hooks[ext]
|
|
if (!match) return
|
|
|
|
for (const item of match) {
|
|
log.info("running", { command: item.command })
|
|
const proc = Bun.spawn({
|
|
cmd: item.command.map((x) => x.replace("$FILE", file)),
|
|
cwd: App.info().path.cwd,
|
|
env: item.environment,
|
|
})
|
|
const exit = await proc.exited
|
|
if (exit !== 0)
|
|
log.error("failed", {
|
|
command: item.command,
|
|
...item.environment,
|
|
})
|
|
}
|
|
}
|
|
|
|
interface Hook {
|
|
command: string[]
|
|
environment?: Record<string, string>
|
|
}
|
|
|
|
interface Native {
|
|
name: string
|
|
command: string[]
|
|
environment?: Record<string, string>
|
|
extensions: string[]
|
|
enabled(): Promise<boolean>
|
|
}
|
|
|
|
const FORMATTERS: Native[] = [
|
|
{
|
|
name: "prettier",
|
|
command: [BunProc.which(), "run", "prettier", "--write", "$FILE"],
|
|
environment: {
|
|
BUN_BE_BUN: "1",
|
|
},
|
|
extensions: [
|
|
".js",
|
|
".jsx",
|
|
".mjs",
|
|
".cjs",
|
|
".ts",
|
|
".tsx",
|
|
".mts",
|
|
".cts",
|
|
".html",
|
|
".htm",
|
|
".css",
|
|
".scss",
|
|
".sass",
|
|
".less",
|
|
".vue",
|
|
".svelte",
|
|
".json",
|
|
".jsonc",
|
|
".yaml",
|
|
".yml",
|
|
".toml",
|
|
".xml",
|
|
".md",
|
|
".mdx",
|
|
".graphql",
|
|
".gql",
|
|
],
|
|
async enabled() {
|
|
try {
|
|
const proc = Bun.spawn({
|
|
cmd: [BunProc.which(), "run", "prettier", "--version"],
|
|
cwd: App.info().path.cwd,
|
|
env: {
|
|
BUN_BE_BUN: "1",
|
|
},
|
|
stdout: "ignore",
|
|
stderr: "ignore",
|
|
})
|
|
const exit = await proc.exited
|
|
return exit === 0
|
|
} catch {
|
|
return false
|
|
}
|
|
},
|
|
},
|
|
]
|
|
}
|