sounds, better files
This commit is contained in:
102
src/model/FileSystem/NginxFS.ts
Normal file
102
src/model/FileSystem/NginxFS.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user