添加filesystem
This commit is contained in:
57
packages/filesystem/webdav/rw.ts
Normal file
57
packages/filesystem/webdav/rw.ts
Normal file
@ -0,0 +1,57 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import { WebDAVClient } from "webdav/web";
|
||||
import { FileReader, FileWriter } from "../filesystem";
|
||||
|
||||
export class WebDAVFileReader implements FileReader {
|
||||
client: WebDAVClient;
|
||||
|
||||
path: string;
|
||||
|
||||
constructor(client: WebDAVClient, path: string) {
|
||||
this.client = client;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
async read(type?: "string" | "blob"): Promise<string | Blob> {
|
||||
switch (type) {
|
||||
case "string":
|
||||
return this.client.getFileContents(this.path, {
|
||||
format: "text",
|
||||
}) as Promise<string>;
|
||||
default: {
|
||||
const resp = (await this.client.getFileContents(this.path, {
|
||||
format: "binary",
|
||||
})) as ArrayBuffer;
|
||||
return Promise.resolve(new Blob([resp]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class WebDAVFileWriter implements FileWriter {
|
||||
client: WebDAVClient;
|
||||
|
||||
path: string;
|
||||
|
||||
constructor(client: WebDAVClient, path: string) {
|
||||
this.client = client;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
async write(content: string | Blob): Promise<void> {
|
||||
let resp;
|
||||
if (content instanceof Blob) {
|
||||
resp = await this.client.putFileContents(
|
||||
this.path,
|
||||
await content.arrayBuffer()
|
||||
);
|
||||
} else {
|
||||
resp = await this.client.putFileContents(this.path, content);
|
||||
}
|
||||
if (resp) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error("write error"));
|
||||
}
|
||||
}
|
106
packages/filesystem/webdav/webdav.ts
Normal file
106
packages/filesystem/webdav/webdav.ts
Normal file
@ -0,0 +1,106 @@
|
||||
import { AuthType, createClient, FileStat, WebDAVClient } from "webdav/web";
|
||||
import FileSystem, { File, FileReader, FileWriter } from "../filesystem";
|
||||
import { joinPath } from "../utils";
|
||||
import { WebDAVFileReader, WebDAVFileWriter } from "./rw";
|
||||
import { WarpTokenError } from "../error";
|
||||
|
||||
export default class WebDAVFileSystem implements FileSystem {
|
||||
client: WebDAVClient;
|
||||
|
||||
url: string;
|
||||
|
||||
basePath: string = "/";
|
||||
|
||||
constructor(
|
||||
authType: AuthType | WebDAVClient,
|
||||
url?: string,
|
||||
username?: string,
|
||||
password?: string
|
||||
) {
|
||||
if (typeof authType === "object") {
|
||||
this.client = authType;
|
||||
this.basePath = joinPath(url || "");
|
||||
this.url = username!;
|
||||
} else {
|
||||
this.url = url!;
|
||||
this.client = createClient(url!, {
|
||||
authType,
|
||||
username,
|
||||
password,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async verify(): Promise<void> {
|
||||
try {
|
||||
await this.client.getQuota();
|
||||
} catch (e: any) {
|
||||
if (e.response && e.response.status === 401) {
|
||||
throw new WarpTokenError(e);
|
||||
}
|
||||
throw new Error("verify failed");
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
open(file: File): Promise<FileReader> {
|
||||
return Promise.resolve(
|
||||
new WebDAVFileReader(this.client, joinPath(file.path, file.name))
|
||||
);
|
||||
}
|
||||
|
||||
openDir(path: string): Promise<FileSystem> {
|
||||
return Promise.resolve(
|
||||
new WebDAVFileSystem(this.client, joinPath(this.basePath, path), this.url)
|
||||
);
|
||||
}
|
||||
|
||||
create(path: string): Promise<FileWriter> {
|
||||
return Promise.resolve(
|
||||
new WebDAVFileWriter(this.client, joinPath(this.basePath, path))
|
||||
);
|
||||
}
|
||||
|
||||
async createDir(path: string): Promise<void> {
|
||||
try {
|
||||
return Promise.resolve(
|
||||
await this.client.createDirectory(joinPath(this.basePath, path))
|
||||
);
|
||||
} catch (e: any) {
|
||||
// 如果是405错误,则忽略
|
||||
if (e.message.includes("405")) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
async delete(path: string): Promise<void> {
|
||||
return this.client.deleteFile(joinPath(this.basePath, path));
|
||||
}
|
||||
|
||||
async list(): Promise<File[]> {
|
||||
const dir = (await this.client.getDirectoryContents(
|
||||
this.basePath
|
||||
)) as FileStat[];
|
||||
const ret: File[] = [];
|
||||
dir.forEach((item: FileStat) => {
|
||||
if (item.type !== "file") {
|
||||
return;
|
||||
}
|
||||
ret.push({
|
||||
name: item.basename,
|
||||
path: this.basePath,
|
||||
digest: item.etag || "",
|
||||
size: item.size,
|
||||
createtime: new Date(item.lastmod).getTime(),
|
||||
updatetime: new Date(item.lastmod).getTime(),
|
||||
});
|
||||
});
|
||||
return Promise.resolve(ret);
|
||||
}
|
||||
|
||||
getDirUrl(): Promise<string> {
|
||||
return Promise.resolve(this.url + this.basePath);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user