bring back type sniffing
This commit is contained in:
parent
ebfddbb278
commit
34379e40d4
21
bin/help.ts
21
bin/help.ts
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import { commandPath } from "@/commands"
|
import { commandPath } from "@/commands"
|
||||||
import type { CommandOutput } from "@/shared/types"
|
import type { CommandOutput } from "@/shared/types"
|
||||||
|
import { moduleExports, type ExportInfo } from "@/sniffer"
|
||||||
import commands from "./commands"
|
import commands from "./commands"
|
||||||
|
|
||||||
export default async function (cmd: string): Promise<CommandOutput> {
|
export default async function (cmd: string): Promise<CommandOutput> {
|
||||||
|
|
@ -12,9 +13,14 @@ export default async function (cmd: string): Promise<CommandOutput> {
|
||||||
const path = commandPath(cmd)
|
const path = commandPath(cmd)
|
||||||
if (!path) return await commands(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")
|
const code = (await Bun.file(path).text()).split("\n")
|
||||||
let docs = []
|
let docs = []
|
||||||
|
|
||||||
|
docs.push(usage(cmd, signature), "")
|
||||||
|
|
||||||
for (const line of code) {
|
for (const line of code) {
|
||||||
if (line.startsWith("///")) {
|
if (line.startsWith("///")) {
|
||||||
docs.push("Runs in the browser.\n")
|
docs.push("Runs in the browser.\n")
|
||||||
|
|
@ -28,3 +34,18 @@ export default async function (cmd: string): Promise<CommandOutput> {
|
||||||
|
|
||||||
return docs.join("\n")
|
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(" ")
|
||||||
|
}
|
||||||
|
|
@ -82,7 +82,7 @@ export async function commandSource(name: string): Promise<string> {
|
||||||
export async function loadCommandModule(cmd: string) {
|
export async function loadCommandModule(cmd: string) {
|
||||||
const path = commandPath(cmd)
|
const path = commandPath(cmd)
|
||||||
if (!path) return
|
if (!path) return
|
||||||
return await importUrl(path + "?t+" + Date.now())
|
return await importUrl(path + "?t=" + Date.now())
|
||||||
}
|
}
|
||||||
|
|
||||||
let noseDirWatcher
|
let noseDirWatcher
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { send } from "./websocket"
|
||||||
import { setState } from "./state"
|
import { setState } from "./state"
|
||||||
|
|
||||||
export async function dispatchMessage(ws: any, msg: Message) {
|
export async function dispatchMessage(ws: any, msg: Message) {
|
||||||
console.log("<- receive", msg)
|
// console.log("<- receive", msg)
|
||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
case "input":
|
case "input":
|
||||||
await inputMessage(ws, msg); break
|
await inputMessage(ws, msg); break
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,7 @@ export type ExportInfo =
|
||||||
|
|
||||||
let prevProgram: ts.Program | undefined
|
let prevProgram: ts.Program | undefined
|
||||||
|
|
||||||
|
export async function moduleExports(file: string): Promise<Record<string, ExportInfo>> {
|
||||||
export async function allExports(file: string): Promise<ExportInfo[]> {
|
|
||||||
const program = ts.createProgram([file], {
|
const program = ts.createProgram([file], {
|
||||||
target: ts.ScriptTarget.ESNext,
|
target: ts.ScriptTarget.ESNext,
|
||||||
module: ts.ModuleKind.ESNext,
|
module: ts.ModuleKind.ESNext,
|
||||||
|
|
@ -48,7 +47,7 @@ export async function allExports(file: string): Promise<ExportInfo[]> {
|
||||||
if (!sf) throw new SniffError(`File not found: ${file}`)
|
if (!sf) throw new SniffError(`File not found: ${file}`)
|
||||||
|
|
||||||
const moduleSym = (sf as any).symbol as ts.Symbol | undefined
|
const moduleSym = (sf as any).symbol as ts.Symbol | undefined
|
||||||
if (!moduleSym) return []
|
if (!moduleSym) return {}
|
||||||
|
|
||||||
const exportSymbols = checker.getExportsOfModule(moduleSym)
|
const exportSymbols = checker.getExportsOfModule(moduleSym)
|
||||||
const result: ExportInfo[] = []
|
const result: ExportInfo[] = []
|
||||||
|
|
@ -92,7 +91,9 @@ export async function allExports(file: string): Promise<ExportInfo[]> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return Object.fromEntries(
|
||||||
|
result.map(item => [item.name, item])
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (import.meta.main) {
|
if (import.meta.main) {
|
||||||
|
|
@ -101,5 +102,5 @@ if (import.meta.main) {
|
||||||
console.error("usage: sniff <path>")
|
console.error("usage: sniff <path>")
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
console.log(await allExports(path))
|
console.log(await moduleExports(path))
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,7 @@ import type { Message } from "./shared/types"
|
||||||
const wsConnections: any[] = []
|
const wsConnections: any[] = []
|
||||||
|
|
||||||
export function send(ws: any, msg: Message) {
|
export function send(ws: any, msg: Message) {
|
||||||
console.log("-> send", msg)
|
// console.log("-> send", msg)
|
||||||
ws.send(JSON.stringify(msg))
|
ws.send(JSON.stringify(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user