58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
import { escapeHTML } from "bun"
|
|
import { readdirSync } from "fs"
|
|
import { join, extname } from "path"
|
|
|
|
import type { CommandOutput } from "@/shared/types"
|
|
import { NOSE_WWW } from "@/config"
|
|
import { getState } from "@/state"
|
|
import { appPath } from "@/webapp"
|
|
import { isBinaryFile } from "@/utils"
|
|
import { countChar } from "@/shared/utils"
|
|
|
|
export default async function (path: string) {
|
|
const state = getState()
|
|
if (!state) return { error: "no state" }
|
|
|
|
const project = state.project
|
|
if (!project) return { error: "no project loaded" }
|
|
|
|
const root = appPath(project)
|
|
if (!root) return { error: "error loading project" }
|
|
|
|
let files: string[] = []
|
|
|
|
for (const file of readdirSync(root, { withFileTypes: true })) {
|
|
files.push(file.name)
|
|
}
|
|
|
|
if (root === NOSE_WWW) {
|
|
files = files.filter(file => file.endsWith(`${project}.ts`) || file.endsWith(`${project}.tsx`))
|
|
}
|
|
|
|
if (files.includes(path))
|
|
return await readFile(join(root, path))
|
|
else
|
|
return await newFile(join(root, path))
|
|
}
|
|
|
|
async function readFile(path: string): Promise<CommandOutput> {
|
|
const ext = extname(path).slice(1)
|
|
const file = Bun.file(path)
|
|
|
|
if (await isBinaryFile(path))
|
|
throw "Cannot display binary file"
|
|
|
|
const text = await file.text()
|
|
const rows = countChar(text, "\n") + 1
|
|
|
|
return {
|
|
html: `<textarea class="editor" spellcheck="false" rows=${rows} data-path="${path}">${text}</textarea>`
|
|
}
|
|
}
|
|
|
|
function newFile(path: string): CommandOutput {
|
|
return {
|
|
html: `<textarea class="editor" spellcheck="false" rows=1 data-path="${path}"></textarea>`
|
|
}
|
|
}
|