1
0
silverbullet/mobile/spaces/capacitor_space_primitives.ts
2023-01-13 15:41:29 +01:00

162 lines
4.3 KiB
TypeScript

import {
FileData,
FileEncoding,
SpacePrimitives,
} from "../../common/spaces/space_primitives.ts";
import type { FileMeta } from "../../common/types.ts";
import {
base64Decode,
base64Encode,
} from "../../plugos/asset_bundle/base64.ts";
import type { Plug } from "../../plugos/plug.ts";
import { Directory, Encoding, Filesystem } from "../deps.ts";
import { mime } from "../../plugos/deps.ts";
export class CapacitorSpacePrimitives implements SpacePrimitives {
constructor(
readonly source: Directory,
readonly root: string,
) {
}
async fetchFileList(): Promise<FileMeta[]> {
const allFiles: FileMeta[] = [];
const directory = this.source;
const root = this.root;
async function readAllFiles(dir: string) {
const files = await Filesystem.readdir({
path: `${root}/${dir}`,
directory,
});
for (const file of files.files) {
if (file.type === "file") {
const name = `${dir}/${file.name}`.substring(1);
allFiles.push({
name: name,
lastModified: file.mtime,
perm: "rw",
contentType: mime.getType(file.name) || "application/octet-stream",
size: file.size,
});
} else { // Directory
await readAllFiles(`${dir}/${file.name}`);
}
}
}
await readAllFiles("");
return allFiles;
}
async readFile(
name: string,
encoding: FileEncoding,
): Promise<{ data: FileData; meta: FileMeta }> {
let data: FileData | undefined;
try {
switch (encoding) {
case "utf8":
data = (await Filesystem.readFile({
path: this.root + name,
directory: this.source,
encoding: Encoding.UTF8,
})).data;
break;
case "arraybuffer": {
const b64Data = (await Filesystem.readFile({
path: this.root + name,
directory: this.source,
})).data;
data = base64Decode(b64Data);
break;
}
case "dataurl": {
const b64Data = (await Filesystem.readFile({
path: this.root + name,
directory: this.source,
})).data;
data = `data:${
mime.getType(name) || "application/octet-stream"
};base64,${b64Data}`;
break;
}
}
return {
data: data!,
meta: await this.getFileMeta(name),
};
} catch {
throw new Error(`Page not found`);
}
}
async getFileMeta(name: string): Promise<FileMeta> {
try {
const statResult = await Filesystem.stat({
path: this.root + name,
directory: this.source,
});
return {
name,
contentType: mime.getType(name) || "application/octet-stream",
lastModified: statResult.mtime,
perm: "rw",
size: statResult.size,
};
} catch (e: any) {
console.error("Error getting file meta", e.message);
throw new Error(`Page not found`);
}
}
async writeFile(
name: string,
encoding: FileEncoding,
data: FileData,
): Promise<FileMeta> {
switch (encoding) {
case "utf8":
await Filesystem.writeFile({
path: this.root + name,
directory: this.source,
encoding: Encoding.UTF8,
data: data as string,
recursive: true,
});
break;
case "arraybuffer":
await Filesystem.writeFile({
path: this.root + name,
directory: this.source,
data: base64Encode(new Uint8Array(data as ArrayBuffer)),
recursive: true,
});
break;
case "dataurl":
await Filesystem.writeFile({
path: this.root + name,
directory: this.source,
data: (data as string).split(";base64,")[1],
recursive: true,
});
break;
}
return this.getFileMeta(name);
}
async deleteFile(name: string): Promise<void> {
await Filesystem.deleteFile({
path: this.root + name,
directory: this.source,
});
}
proxySyscall(plug: Plug<any>, name: string, args: any[]): Promise<any> {
return plug.syscall(name, args);
}
invokeFunction(
plug: Plug<any>,
_env: string,
name: string,
args: any[],
): Promise<any> {
return plug.invoke(name, args);
}
}