diff --git a/bin/help.ts b/bin/help.ts index b0e2f2c..1c2c1a7 100644 --- a/bin/help.ts +++ b/bin/help.ts @@ -4,6 +4,7 @@ import { commandPath } from "@/commands" import type { CommandOutput } from "@/shared/types" +import { moduleExports, type ExportInfo } from "@/sniffer" import commands from "./commands" export default async function (cmd: string): Promise { @@ -12,9 +13,14 @@ export default async function (cmd: string): Promise { const path = commandPath(cmd) if (!path) return await commands(cmd) + const signatures = await moduleExports(path) + const signature = signatures.default + const code = (await Bun.file(path).text()).split("\n") let docs = [] + docs.push(usage(cmd, signature), "") + for (const line of code) { if (line.startsWith("///")) { docs.push("Runs in the browser.\n") @@ -28,3 +34,18 @@ export default async function (cmd: string): Promise { return docs.join("\n") } + +function usage(cmd: string, signature?: ExportInfo) { + let out: string[] = [`usage: ${cmd}`] + + if (signature?.kind === "function" && signature.signatures.length) { + const params = signature.signatures[0]!.params + for (const param of params) { + let desc = `${param.name}=` + desc += param.default ? `${param.default}` : `<${param.type}>` + out.push(desc) + } + } + + return out.join(" ") +} \ No newline at end of file diff --git a/src/commands.ts b/src/commands.ts index 644f76d..a4488b7 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -82,7 +82,7 @@ export async function commandSource(name: string): Promise { export async function loadCommandModule(cmd: string) { const path = commandPath(cmd) if (!path) return - return await importUrl(path + "?t+" + Date.now()) + return await importUrl(path + "?t=" + Date.now()) } let noseDirWatcher diff --git a/src/dispatch.ts b/src/dispatch.ts index 2eea407..14903e9 100644 --- a/src/dispatch.ts +++ b/src/dispatch.ts @@ -8,7 +8,7 @@ import { send } from "./websocket" import { setState } from "./state" export async function dispatchMessage(ws: any, msg: Message) { - console.log("<- receive", msg) + // console.log("<- receive", msg) switch (msg.type) { case "input": await inputMessage(ws, msg); break diff --git a/src/sniff.ts b/src/sniffer.ts similarity index 92% rename from src/sniff.ts rename to src/sniffer.ts index 2131bc6..5a3bb1c 100644 --- a/src/sniff.ts +++ b/src/sniffer.ts @@ -30,8 +30,7 @@ export type ExportInfo = let prevProgram: ts.Program | undefined - -export async function allExports(file: string): Promise { +export async function moduleExports(file: string): Promise> { const program = ts.createProgram([file], { target: ts.ScriptTarget.ESNext, module: ts.ModuleKind.ESNext, @@ -48,7 +47,7 @@ export async function allExports(file: string): Promise { if (!sf) throw new SniffError(`File not found: ${file}`) const moduleSym = (sf as any).symbol as ts.Symbol | undefined - if (!moduleSym) return [] + if (!moduleSym) return {} const exportSymbols = checker.getExportsOfModule(moduleSym) const result: ExportInfo[] = [] @@ -92,7 +91,9 @@ export async function allExports(file: string): Promise { } } - return result + return Object.fromEntries( + result.map(item => [item.name, item]) + ) } if (import.meta.main) { @@ -101,5 +102,5 @@ if (import.meta.main) { console.error("usage: sniff ") process.exit(1) } - console.log(await allExports(path)) + console.log(await moduleExports(path)) } \ No newline at end of file diff --git a/src/websocket.ts b/src/websocket.ts index 813c3de..7d4b210 100644 --- a/src/websocket.ts +++ b/src/websocket.ts @@ -6,7 +6,7 @@ import type { Message } from "./shared/types" const wsConnections: any[] = [] export function send(ws: any, msg: Message) { - console.log("-> send", msg) + // console.log("-> send", msg) ws.send(JSON.stringify(msg)) }