silverbullet/plugos/syscalls/fs.deno.ts

101 lines
2.8 KiB
TypeScript
Raw Normal View History

2022-10-04 22:33:29 +08:00
import type { SysCallMapping } from "../system.ts";
2022-10-08 22:29:43 +08:00
import { path } from "../../dep_server.ts";
import { base64Decode, base64Encode } from "../../common/base64.ts";
export type FileMeta = {
name: string;
lastModified: number;
};
2022-10-04 22:33:29 +08:00
export default function fileSystemSyscalls(root = "/"): SysCallMapping {
function resolvedPath(p: string): string {
p = path.resolve(root, p);
if (!p.startsWith(root)) {
throw Error("Path outside root, not allowed");
}
return p;
}
return {
"fs.readFile": async (
ctx,
2022-09-05 22:15:01 +08:00
filePath: string,
2022-10-08 22:29:43 +08:00
encoding: "utf8" | "dataurl" = "utf8",
): Promise<{ text: string; meta: FileMeta }> => {
let p = resolvedPath(filePath);
2022-09-05 22:15:01 +08:00
let text = "";
if (encoding === "utf8") {
2022-10-08 22:29:43 +08:00
text = await Deno.readTextFile(p);
2022-09-05 22:15:01 +08:00
} else {
2022-10-08 22:29:43 +08:00
text = `data:application/octet-stream,${
base64Encode(await Deno.readFile(p))
}`;
2022-09-05 22:15:01 +08:00
}
2022-10-08 22:29:43 +08:00
let s = await Deno.stat(p);
return {
text,
meta: {
name: filePath,
2022-10-08 22:29:43 +08:00
lastModified: s.mtime!.getTime(),
},
};
},
"fs.getFileMeta": async (ctx, filePath: string): Promise<FileMeta> => {
let p = resolvedPath(filePath);
2022-10-08 22:29:43 +08:00
let s = await Deno.stat(p);
return {
name: filePath,
2022-10-08 22:29:43 +08:00
lastModified: s.mtime!.getTime(),
};
},
"fs.writeFile": async (
ctx,
filePath: string,
2022-09-05 22:15:01 +08:00
text: string,
2022-10-08 22:29:43 +08:00
encoding: "utf8" | "dataurl" = "utf8",
): Promise<FileMeta> => {
let p = resolvedPath(filePath);
2022-10-08 22:29:43 +08:00
await Deno.mkdir(path.dirname(p), { recursive: true });
2022-09-05 22:15:01 +08:00
if (encoding === "utf8") {
2022-10-08 22:29:43 +08:00
await Deno.writeTextFile(p, text);
2022-09-05 22:15:01 +08:00
} else {
2022-10-08 22:29:43 +08:00
await Deno.writeFile(p, base64Decode(text.split(",")[1]));
2022-09-05 22:15:01 +08:00
}
2022-10-08 22:29:43 +08:00
let s = await Deno.stat(p);
return {
name: filePath,
2022-10-08 22:29:43 +08:00
lastModified: s.mtime!.getTime(),
};
},
"fs.deleteFile": async (ctx, filePath: string): Promise<void> => {
let p = resolvedPath(filePath);
2022-10-08 22:29:43 +08:00
await Deno.remove(p);
},
"fs.listFiles": async (
ctx,
dirPath: string,
2022-10-08 22:29:43 +08:00
recursive: boolean,
): Promise<FileMeta[]> => {
dirPath = resolvedPath(dirPath);
let allFiles: FileMeta[] = [];
async function walkPath(dir: string) {
2022-10-08 22:29:43 +08:00
let files = await Deno.readDir(dir);
for await (const file of files) {
const fullPath = path.join(dir, file.name);
let s = await Deno.stat(fullPath);
if (s.isDirectory && recursive) {
await walkPath(fullPath);
} else {
allFiles.push({
name: fullPath.substring(dirPath.length + 1),
2022-10-08 22:29:43 +08:00
lastModified: s.mtime!.getTime(),
});
}
}
}
await walkPath(dirPath);
return allFiles;
},
};
}