//// // Manages the commands on disk, in NOSE_SYS_BIN and NOSE_BIN import { Glob } from "bun" import { watch } from "fs" import { join } from "path" import { isFile } from "./utils" import { sendAll } from "./websocket" import { expectDir } from "./utils" import { NOSE_SYS_BIN, NOSE_BIN } from "./config" export function initCommands() { startWatchers() } export async function commands(): Promise { return (await findCommands(NOSE_SYS_BIN)).concat(await findCommands(NOSE_BIN)) } export async function findCommands(path: string): Promise { const glob = new Glob("**/*.{ts,tsx}") let list: string[] = [] for await (const file of glob.scan(path)) { list.push(file.replace(".tsx", "").replace(".ts", "")) } return list } export function commandPath(cmd: string): string | undefined { return [ join(NOSE_SYS_BIN, cmd + ".ts"), join(NOSE_SYS_BIN, cmd + ".tsx"), join(NOSE_BIN, cmd + ".ts"), join(NOSE_BIN, cmd + ".tsx") ].find((path: string) => isFile(path)) } export function commandExists(cmd: string): boolean { return commandPath(cmd) !== undefined } export async function commandSource(name: string): Promise { const path = commandPath(name) if (!path) return "" return Bun.file(path).text() } export async function loadCommandModule(cmd: string) { const path = commandPath(cmd) if (!path) return return await import(path + "?t+" + Date.now()) } let sysCmdWatcher let usrCmdWatcher function startWatchers() { if (!expectDir(NOSE_BIN)) return sysCmdWatcher = watch(NOSE_SYS_BIN, async (event, filename) => sendAll({ type: "commands", data: await commands() }) ) usrCmdWatcher = watch(NOSE_BIN, async (event, filename) => { sendAll({ type: "commands", data: await commands() }) }) }