//// // runs commands and such. import type { CommandResult } from "./shared/types" import { join } from "path" import { NOSE_BIN } from "./config" import { isFile } from "./utils" export async function runCommand(input: string): Promise { const [cmd = "", ...args] = input.split(" ") if (!commandExists(cmd)) { return { status: "error", output: `${cmd} not found` } } let status: "ok" | "error" = "ok" let output = "" try { [status, output] = await exec(cmd, args) } catch (err) { status = "error" output = errorMessage(err) } return { status, output } } async function exec(cmd: string, args: string[]): Promise<["ok" | "error", string]> { const module = await import(commandPath(cmd) + "?t+" + Date.now()) if (!module || !module.default) { return ["error", `${cmd} has no default export`] } return ["ok", await module.default(...args)] } function commandPath(cmd: string): string { return join(NOSE_BIN, cmd + ".ts") } function commandExists(cmd: string): boolean { return isFile(commandPath(cmd)) } function errorMessage(error: Error | any): string { if (!(error instanceof Error)) return String(error) let msg = `${error.name}: ${error.message}` if (error.stack) msg += `\n${error.stack}` return msg }