Skip to content

Commit

Permalink
add fs.emptyDir
Browse files Browse the repository at this point in the history
  • Loading branch information
jarvisjiang committed May 17, 2024
1 parent 43a041e commit 7e84718
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 20 deletions.
89 changes: 70 additions & 19 deletions src/std/fs/mina_fs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { basename, dirname } from '@std/path/posix';
import { NOT_FOUND_ERROR, assertAbsolutePath, type ExistsOptions, type WriteOptions } from 'happy-opfs';
import { Err, Ok, type AsyncIOResult } from 'happy-rusty';
import { Err, Ok, type AsyncIOResult, type IOResult } from 'happy-rusty';
import { assertSafeUrl, assertString } from '../assert/assertions.ts';
import type { FileEncoding, ReadFileContent, ReadOptions, WriteFileContent } from './fs_define.ts';

Expand Down Expand Up @@ -39,6 +39,23 @@ function getAbsolutePath(path: string): string {
return rootPath + path;
}

/**
* interface FileError 转换为 Err<Error>
* @param err FileError
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function toErr(err: WechatMinigame.FileError | WechatMinigame.GeneralCallbackResult): IOResult<any> {
const error = new Error(err.errMsg);

// 1300002 no such file or directory ${path}
// 可能没有errCode
if ((err as WechatMinigame.FileError).errCode === 1300002 || err.errMsg.includes('no such file or directory')) {
error.name = NOT_FOUND_ERROR;
}

return Err(error);
}

/**
* 递归创建文件夹,相当于`mkdir -p`
* @param dirPath 要创建的文件夹路径
Expand All @@ -62,7 +79,7 @@ export function mkdir(dirPath: string): AsyncIOResult<boolean> {
return;
}

resolve(Err(new Error(err.errMsg)));
resolve(toErr(err));
},
});
});
Expand All @@ -83,7 +100,7 @@ export function readDir(dirPath: string): AsyncIOResult<string[]> {
resolve(Ok(res.files));
},
fail(err): void {
resolve(Err(new Error(err.errMsg)));
resolve(toErr(err));
},
});
});
Expand Down Expand Up @@ -120,7 +137,7 @@ export function readFile<T extends ReadFileContent>(filePath: string, options?:
resolve(Ok(res.data as T));
},
fail(err): void {
resolve(Err(new Error(err.errMsg)));
resolve(toErr(err));
},
});
});
Expand Down Expand Up @@ -149,7 +166,7 @@ export async function remove(path: string): AsyncIOResult<boolean> {
resolve(Ok(true));
},
fail(err): void {
resolve(Err(new Error(err.errMsg)));
resolve(toErr(err));
},
});
} else {
Expand All @@ -159,7 +176,7 @@ export async function remove(path: string): AsyncIOResult<boolean> {
resolve(Ok(true));
},
fail(err): void {
resolve(Err(new Error(err.errMsg)));
resolve(toErr(err));
},
});
}
Expand All @@ -184,7 +201,7 @@ export function rename(oldPath: string, newPath: string): AsyncIOResult<boolean>
resolve(Ok(true));
},
fail(err): void {
resolve(Err(new Error(err.errMsg)));
resolve(toErr(err));
},
});
});
Expand All @@ -205,15 +222,7 @@ export function stat(path: string): AsyncIOResult<WechatMinigame.Stats> {
resolve(Ok(res.stats as WechatMinigame.Stats));
},
fail(err): void {
const error = new Error(err.errMsg);

// 1300002 no such file or directory ${path}
// 可能没有errCode
if (err.errCode === 1300002 || err.errMsg.includes('no such file or directory')) {
error.name = NOT_FOUND_ERROR;
}

resolve(Err(error));
resolve(toErr(err));
},
});
});
Expand Down Expand Up @@ -253,7 +262,7 @@ export async function writeFile(filePath: string, contents: WriteFileContent, op
resolve(Ok(true));
},
fail(err): void {
resolve(Err(new Error(err.errMsg)));
resolve(toErr(err));
},
});
});
Expand Down Expand Up @@ -300,6 +309,48 @@ export async function exists(path: string, options?: ExistsOptions): AsyncIOResu
return Ok(!notExist);
}

/**
* 清空文件夹,不存在则创建
* @param dirPath 文件夹路径
* @returns
*/
export async function emptyDir(dirPath: string): AsyncIOResult<boolean> {
type T = boolean;

const res = await readDir(dirPath);
if (res.isErr()) {
if (res.err().name === NOT_FOUND_ERROR) {
// 不存在则创建
return mkdir(dirPath);
}

return res;
}

const items: AsyncIOResult<T>[] = [];

for await (const name of res.unwrap()) {
items.push(remove(`${ dirPath }/${ name }`));
}

const success: IOResult<T> = await Promise.all(items).then((x) => {
let err: IOResult<T> | null = null;

const success = x.every(y => {
if (y.isErr()) {
err = y;
return false;
}

return y.unwrap();
});

return err ?? Ok(success);
});

return success;
}

/**
* 以字符串格式读取文件
* @param filePath 要读取的文件路径
Expand Down Expand Up @@ -331,7 +382,7 @@ export function downloadFile(fileUrl: string, filePath: string, headers?: Header
resolve(Ok(true));
},
fail(err): void {
resolve(Err(new Error(err.errMsg)));
resolve(toErr(err));
},
});
});
Expand All @@ -358,7 +409,7 @@ export async function uploadFile(filePath: string, fileUrl: string, headers?: He
resolve(Ok(true));
},
fail(err): void {
resolve(Err(new Error(err.errMsg)));
resolve(toErr(err));
},
});
});
Expand Down
13 changes: 12 additions & 1 deletion src/std/fs/mod.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
appendFile as webAppendFile,
downloadFile as webDownloadFile,
emptyDir as webEmptyDir,
exists as webExists,
mkdir as webMkdir,
readDir as webReadDir,
Expand All @@ -18,6 +19,7 @@ import type { WriteFileContent } from './fs_define.ts';
import {
appendFile as minaAppendFile,
downloadFile as minaDownloadFile,
emptyDir as minaEmptyDir,
exists as minaExists,
mkdir as minaMkdir,
readDir as minaReadDir,
Expand Down Expand Up @@ -163,6 +165,15 @@ export function exists(path: string): AsyncIOResult<boolean> {
return isMinaEnv() ? minaExists(path) : webExists(path);
}

/**
* 清空文件夹,不存在则创建
* @param dirPath 文件夹路径
* @returns
*/
export function emptyDir(dirPath: string): AsyncIOResult<boolean> {
return isMinaEnv() ? minaEmptyDir(dirPath) : webEmptyDir(dirPath);
}

/**
* 读取文件内容,返回`string`
* @param filePath 要读取的文件路径
Expand All @@ -178,6 +189,6 @@ export function readTextFile(filePath: string): AsyncIOResult<string> {
* @param requestInit 传递给`fetch`的参数
* @returns
*/
export async function uploadFile(filePath: string, fileUrl: string, requestInit?: RequestInit): AsyncIOResult<boolean> {
export function uploadFile(filePath: string, fileUrl: string, requestInit?: RequestInit): AsyncIOResult<boolean> {
return isMinaEnv() ? minaUploadFile(filePath, fileUrl, requestInit?.headers) : webUploadFile(filePath, fileUrl, requestInit);
}

0 comments on commit 7e84718

Please sign in to comment.