diff --git a/src/cmd/blog-export/download.ts b/src/cmd/blog-export/download.ts index c5275949..fbc83a34 100644 --- a/src/cmd/blog-export/download.ts +++ b/src/cmd/blog-export/download.ts @@ -11,6 +11,7 @@ import { promisify } from 'util' import { WorkspaceCfg } from '@/ctx/cfg/workspace' import AdmZip from 'adm-zip' import { setCtx } from '@/ctx/global-ctx' +import { fsUtil } from '@/infra/fs/fsUtil' export async function downloadBlogExport(treeItem?: BlogExportRecordTreeItem) { if (!(treeItem instanceof BlogExportRecordTreeItem)) return @@ -24,7 +25,7 @@ export async function downloadBlogExport(treeItem?: BlogExportRecordTreeItem) { const nonZipFilePath = path.join(targetDir, treeItem.record.fileName) const zipFilePath = nonZipFilePath + '.zip' const downloadStream = BlogExportApi.download(blogId, exportId) - const isFileExist = fs.existsSync(zipFilePath) + const isFileExist = await fsUtil.exists(zipFilePath) await extTreeViews.blogExport.reveal(treeItem, { expand: true }) diff --git a/src/cmd/blog-export/open-local.ts b/src/cmd/blog-export/open-local.ts index 8a52fe54..029df51a 100644 --- a/src/cmd/blog-export/open-local.ts +++ b/src/cmd/blog-export/open-local.ts @@ -6,6 +6,7 @@ import { Alert } from '@/infra/alert' import { DownloadedExportStore } from '@/service/downloaded-export.store' import { BlogExportProvider } from '@/tree-view/provider/blog-export-provider' import { BlogExportRecordsStore } from '@/service/blog-export/blog-export-records.store' +import { fsUtil } from '@/infra/fs/fsUtil' const defaultOptions = { confirmUnzip: true } @@ -51,7 +52,7 @@ export async function openLocalExport(opts: Partial = def } const dbFileName = path.basename(dbFilePath) - if (!fs.existsSync(dbFilePath)) return void Alert.warn('文件不存在') + if (!(await fsUtil.exists(dbFilePath))) return void Alert.warn('文件不存在') const treeProvider = BlogExportProvider.optionalInstance const dbFileSize = (await promisify(fs.stat)(dbFilePath)).size diff --git a/src/cmd/post-cat/update-post-cat-treeview.ts b/src/cmd/post-cat/update-post-cat-treeview.ts index 97532155..f2a78a01 100644 --- a/src/cmd/post-cat/update-post-cat-treeview.ts +++ b/src/cmd/post-cat/update-post-cat-treeview.ts @@ -1,4 +1,3 @@ -import fs from 'fs' import { ProgressLocation, window, Uri, workspace } from 'vscode' import { PostCat } from '@/model/post-cat' import { PostCatService } from '@/service/post/post-cat' @@ -9,6 +8,7 @@ import { Alert } from '@/infra/alert' import { PostCatTreeItem } from '@/tree-view/model/post-category-tree-item' import { extTreeViews } from '@/tree-view/tree-view-register' import { postCategoryDataProvider } from '@/tree-view/provider/post-category-tree-data-provider' +import { fsUtil } from '@/infra/fs/fsUtil' export async function updatePostCatTreeView(arg?: PostCat | PostCatTreeItem) { let category: PostCat @@ -39,8 +39,8 @@ export async function updatePostCatTreeView(arg?: PostCat | PostCatTreeItem) { // 如果选择了createLocalPostFileWithCategory模式且本地有该目录,则重命名该目录 const workspaceUri = WorkspaceCfg.getWorkspaceUri() const shouldCreateLocalPostFileWithCategory = PostCatCfg.isCreateLocalPostFileWithCategory() - const uri = Uri.joinPath(workspaceUri, category.title).fsPath - const isFileExist = fs.existsSync(uri) + const path = Uri.joinPath(workspaceUri, category.title).fsPath + const isFileExist = await fsUtil.exists(path) if (shouldCreateLocalPostFileWithCategory && isFileExist) { const oldUri = Uri.joinPath(workspaceUri, category.title) const newUri = Uri.joinPath(workspaceUri, addDto.title) diff --git a/src/cmd/post-list/modify-post-setting.ts b/src/cmd/post-list/modify-post-setting.ts index b30867a9..d5f72b77 100644 --- a/src/cmd/post-list/modify-post-setting.ts +++ b/src/cmd/post-list/modify-post-setting.ts @@ -5,12 +5,12 @@ import { PostService } from '@/service/post/post' import { PostFileMapManager } from '@/service/post/post-file-map' import { revealPostListItem } from '@/service/post/post-list-view' import { PostCfgPanel } from '@/service/post/post-cfg-panel' -import fs from 'fs' import { LocalPost } from '@/service/local-post' import { saveFilePendingChanges } from '@/infra/save-file-pending-changes' import { postDataProvider } from '@/tree-view/provider/post-data-provider' import { PostTreeItem } from '@/tree-view/model/post-tree-item' import { postCategoryDataProvider } from '@/tree-view/provider/post-category-tree-data-provider' +import { fsUtil } from '@/infra/fs/fsUtil' export async function modifyPostSetting(input: Post | PostTreeItem | Uri) { let post: Post | undefined @@ -43,7 +43,7 @@ export async function modifyPostSetting(input: Post | PostTreeItem | Uri) { postCategoryDataProvider.onPostUpdated({ refreshPost: false, postIds: [id] }) }, beforeUpdate: async post => { - if (localFilePath !== undefined && fs.existsSync(localFilePath)) { + if (localFilePath !== undefined && (await fsUtil.exists(localFilePath))) { await saveFilePendingChanges(localFilePath) post.postBody = await new LocalPost(localFilePath).readAllText() } diff --git a/src/cmd/post-list/open-post-in-vscode.ts b/src/cmd/post-list/open-post-in-vscode.ts index 21561596..84a15a03 100644 --- a/src/cmd/post-list/open-post-in-vscode.ts +++ b/src/cmd/post-list/open-post-in-vscode.ts @@ -1,4 +1,3 @@ -import fs from 'fs' import path from 'path' import { FileSystemError, Uri, workspace } from 'vscode' import { Post } from '@/model/post' @@ -10,6 +9,7 @@ import { PostCatService } from '@/service/post/post-cat' import sanitizeFileName from 'sanitize-filename' import { WorkspaceCfg } from '@/ctx/cfg/workspace' import { PostCatCfg } from '@/ctx/cfg/post-cat' +import { fsUtil } from '@/infra/fs/fsUtil' export async function buildLocalPostFileUri(post: Post, includePostId = false): Promise { const workspaceUri = WorkspaceCfg.getWorkspaceUri() @@ -39,7 +39,7 @@ export async function buildLocalPostFileUri(post: Post, includePostId = false): export async function openPostInVscode(postId: number, forceUpdateLocalPostFile = false): Promise { let mappedPostFilePath = PostFileMapManager.getFilePath(postId) - const isFileExist = mappedPostFilePath !== undefined && fs.existsSync(mappedPostFilePath) + const isFileExist = mappedPostFilePath !== undefined && (await fsUtil.exists(mappedPostFilePath)) if (mappedPostFilePath !== undefined && isFileExist && !forceUpdateLocalPostFile) { await openPostFile(mappedPostFilePath) return Uri.file(mappedPostFilePath) @@ -58,7 +58,7 @@ export async function openPostInVscode(postId: number, forceUpdateLocalPostFile // 博文尚未关联到本地文件的情况 // 本地存在和博文同名的文件, 询问用户是要覆盖还是同时保留两者 - if (mappedPostFilePath === undefined && fs.existsSync(fileUri.fsPath)) { + if (mappedPostFilePath === undefined && (await fsUtil.exists(fileUri.fsPath))) { const opt = ['保留本地文件并以博文 ID 为文件名新建另一个文件', '覆盖本地文件'] const selected = await Alert.info( `无法建立博文与本地文件的关联, 文件名冲突`, diff --git a/src/cmd/post-list/post-pull-all.ts b/src/cmd/post-list/post-pull-all.ts index 667e1a13..025f1737 100644 --- a/src/cmd/post-list/post-pull-all.ts +++ b/src/cmd/post-list/post-pull-all.ts @@ -1,11 +1,11 @@ import { PostService } from '@/service/post/post' import { Alert } from '@/infra/alert' import { PostFileMapManager } from '@/service/post/post-file-map' -import fs from 'fs' import { basename } from 'path' import { ProgressLocation, Uri, window, workspace } from 'vscode' import { buildLocalPostFileUri } from '@/cmd/post-list/open-post-in-vscode' import { UserService } from '@/service/user-info' +import { fsUtil } from '@/infra/fs/fsUtil' enum ConflictStrategy { ask, @@ -67,7 +67,7 @@ export async function postPullAll() { const path = PostFileMapManager.getFilePath(post.id) // 本地没有博文或关联到的文件不存在 - if (path === undefined || !fs.existsSync(path)) { + if (path === undefined || !(await fsUtil.exists(path))) { const uri = await buildLocalPostFileUri(post, false) const buf = Buffer.from(post.postBody) await workspace.fs.writeFile(uri, buf) diff --git a/src/cmd/post-list/post-pull.ts b/src/cmd/post-list/post-pull.ts index 2a000214..afeb9e4d 100644 --- a/src/cmd/post-list/post-pull.ts +++ b/src/cmd/post-list/post-pull.ts @@ -8,7 +8,7 @@ import path from 'path' import { revealPostListItem } from '@/service/post/post-list-view' import { PostTreeItem } from '@/tree-view/model/post-tree-item' import { MarkdownCfg } from '@/ctx/cfg/markdown' -import fs from 'fs' +import { fsUtil } from '@/infra/fs/fsUtil' export async function postPull(input: Post | PostTreeItem | Uri | undefined | null) { const ctxList: CmdCtx[] = [] @@ -52,7 +52,7 @@ const parsePostInput = (input: InputType): input is Post => input instanceof Pos async function handlePostInput(post: Post, contexts: CmdCtx[]) { const path = PostFileMapManager.getFilePath(post.id) // 本地没有博文或关联到的文件不存在 - if (path === undefined || !fs.existsSync(path)) { + if (path === undefined || !(await fsUtil.exists(path))) { const uri = await buildLocalPostFileUri(post, false) await workspace.fs.writeFile(uri, Buffer.from(post.postBody)) await PostFileMapManager.updateOrCreate(post.id, uri.path) diff --git a/src/cmd/post-list/upload-post.ts b/src/cmd/post-list/upload-post.ts index 30bab00c..35bbcf8c 100644 --- a/src/cmd/post-list/upload-post.ts +++ b/src/cmd/post-list/upload-post.ts @@ -15,10 +15,10 @@ import { PostTreeItem } from '@/tree-view/model/post-tree-item' import { MarkdownCfg } from '@/ctx/cfg/markdown' import { PostListView } from '@/cmd/post-list/post-list-view' import { LocalPost } from '@/service/local-post' -import fs from 'fs' import { extractImg } from '@/service/extract-img/extract-img' import { dirname } from 'path' import { Workspace } from '@/cmd/workspace' +import { fsUtil } from '@/infra/fs/fsUtil' async function parseFileUri(fileUri?: Uri) { if (fileUri !== undefined && fileUri.scheme !== 'file') return undefined @@ -64,7 +64,7 @@ export async function saveLocalPost(localPost: LocalPost) { beforeUpdate: async postToSave => { await saveFilePendingChanges(localPost.filePath) - if (!fs.existsSync(localPost.filePath)) { + if (!(await fsUtil.exists(localPost.filePath))) { void Alert.warn('本地文件已删除, 无法新建博文') return false } diff --git a/src/infra/fs/fsUtil.ts b/src/infra/fs/fsUtil.ts new file mode 100644 index 00000000..ae2df1fd --- /dev/null +++ b/src/infra/fs/fsUtil.ts @@ -0,0 +1,12 @@ +import { Uri, workspace } from 'vscode' + +export namespace fsUtil { + export async function exists(path: string) { + try { + await workspace.fs.stat(Uri.file(path)) + return true + } catch (e) { + return false + } + } +} diff --git a/src/service/downloaded-export.store.ts b/src/service/downloaded-export.store.ts index 2c3f93d5..e76794f1 100644 --- a/src/service/downloaded-export.store.ts +++ b/src/service/downloaded-export.store.ts @@ -1,7 +1,7 @@ import { DownloadedBlogExport } from '@/model/blog-export' -import fs from 'fs' import { take } from 'lodash-es' import { LocalState } from '@/ctx/local-state' +import { fsUtil } from '@/infra/fs/fsUtil' const listKey = 'downloadExports' const metadataKey = 'downloadedExport-' @@ -30,8 +30,8 @@ export namespace DownloadedExportStore { if (prune) { const prunedItems: DownloadedBlogExport[] = [] - items = items.filter(x => { - const isExist = fs.existsSync(x.filePath) + items = items.filter(async x => { + const isExist = await fsUtil.exists(x.filePath) if (!isExist) { prunedItems.push(x) return false @@ -69,7 +69,7 @@ export namespace DownloadedExportStore { let item = LocalState.getState(key) as DownloadedBlogExport | undefined if (prune && item !== undefined) { - const isExist = fs.existsSync(item.filePath) + const isExist = await fsUtil.exists(item.filePath) if (!isExist) { item = undefined await updateExport(id, undefined) diff --git a/src/service/extract-img/get-replace-list.ts b/src/service/extract-img/get-replace-list.ts index 5a719b89..2d636f04 100644 --- a/src/service/extract-img/get-replace-list.ts +++ b/src/service/extract-img/get-replace-list.ts @@ -4,6 +4,7 @@ import { join } from 'path' import { ImgBytes, ImgReq, RsHttp, Token } from '@/wasm' import { AuthManager } from '@/auth/auth-manager' import { readableToBytes } from '@/infra/convert/readableToBuffer' +import { fsUtil } from '@/infra/fs/fsUtil' export async function getAuthedImgReq() { const token = await AuthManager.acquireToken() @@ -56,11 +57,11 @@ async function caseFsImg(baseDirPath: string, path: string) { path = decodeURIComponent(path) let readable - if (fs.existsSync(path)) { + if (await fsUtil.exists(path)) { readable = fs.createReadStream(path) } else { const absPath = join(baseDirPath, path) - if (fs.existsSync(absPath)) readable = fs.createReadStream(absPath) + if (await fsUtil.exists(absPath)) readable = fs.createReadStream(absPath) else throw Error('文件不存在') } diff --git a/src/service/post/create.ts b/src/service/post/create.ts index 42b35990..20b203ac 100644 --- a/src/service/post/create.ts +++ b/src/service/post/create.ts @@ -6,7 +6,7 @@ import { WorkspaceCfg } from '@/ctx/cfg/workspace' import { saveLocalPost } from '@/cmd/post-list/upload-post' import { openPostFile } from '@/cmd/post-list/open-post-file' import { LocalPost } from '@/service/local-post' -import fs from 'fs' +import { fsUtil } from '@/infra/fs/fsUtil' export async function createPost() { const workspacePath = WorkspaceCfg.getWorkspaceUri().fsPath @@ -24,7 +24,8 @@ export async function createPost() { const filePath = path.join(workspacePath, `${title}.md`) - if (!fs.existsSync(filePath)) await workspace.fs.writeFile(Uri.file(filePath), Buffer.from('# Hello World\n')) + if (!(await fsUtil.exists(filePath))) + await workspace.fs.writeFile(Uri.file(filePath), Buffer.from('# Hello World\n')) await openPostFile(filePath) await osOpenActiveFile()