Files
battle-caster-v1/src/model/FileSystem/NginxFS.ts
2024-10-13 16:09:21 +00:00

103 lines
2.4 KiB
TypeScript

import { extensionMimeType } from "../FileMeta/ExtensionMimeType";
import { FileSystemSource, VirtualFile, VirtualDirectory } from "./types";
export type NginxFsConfig = {
name: string;
rootUrl: string;
auth?: {
username: string;
password: string;
};
}
type DateString = string & {};
interface NginxFile {
name: string;
type: 'file'
mtime: DateString;
size: number;
}
interface NginxDirectory {
name: string;
type: 'directory';
mtime: DateString;
}
export class NginxFS implements FileSystemSource<NginxFsConfig> {
constructor(private options: NginxFsConfig) {}
get name() {
return this.options.name;
}
get root():VirtualDirectory {
return {
type: 'directory',
source: this.options.name,
path: [],
name: this.options.name
}
}
private get sanitizedRootUrl() {
return this.options.rootUrl.endsWith("/") ? this.options.rootUrl : this.options.rootUrl + "/";
}
private get authHeaders(): {Authorization: string}|{} {
return this.options.auth ? {
Authorization: `Basic ${btoa(`${this.options.auth.username}:${this.options.auth.password}`)}`
} : {}
}
async listDir(dir: VirtualDirectory): Promise<(VirtualDirectory|VirtualFile)[]> {
const response = await fetch(`${this.sanitizedRootUrl}${dir.path.map((x) => `${x}/`).join("")}`, {
headers: {
...this.authHeaders,
}
});
if (!response.ok) {
console.error("Failed to list directory", response);
return [];
}
const data = await response.json() as Array<NginxFile | NginxDirectory>;
return data.map((item) => {
if (item.type === "directory") {
return {
type: "directory",
source: this.options.name,
path: [...dir.path, item.name],
name: item.name
}
} else {
return {
type: "file",
source: this.options.name,
path: [...dir.path, item.name],
name: item.name,
mimeType: extensionMimeType(item.name),
}
}
});
}
async download(file: VirtualFile): Promise<File> {
const response = await fetch(`${this.sanitizedRootUrl}${file.path.join("/")}`);
if (!response.ok) {
throw new Error("Failed to download file");
}
return new File([await response.blob()], file.name, { type: file.mimeType });
}
getConfig() {
return {
...this.options,
type: "nginx",
} as const;
}
}