diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index 69ff8ef8..74238d0a 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -17,6 +17,7 @@ import { DEFAULT_FILE_TYPES } from '../constants/DefaultFileTypes'; import { Telemetry } from '../helpers/Telemetry'; import { glob } from 'glob'; import { mkdirAsync } from '../utils/mkdirAsync'; +import { existsAsync } from '../utils'; export const WORKSPACE_PLACEHOLDER = `[[workspace]]`; @@ -63,7 +64,7 @@ export class Folders { parentFolders.push(folder); - if (!existsSync(folderPath)) { + if (!(await existsAsync(folderPath))) { await mkdirAsync(folderPath); } } diff --git a/src/commands/Project.ts b/src/commands/Project.ts index c9daa83b..a6303a8d 100644 --- a/src/commands/Project.ts +++ b/src/commands/Project.ts @@ -8,8 +8,7 @@ import { Folders } from "./Folders"; import { FrameworkDetector, Logger, Settings } from "../helpers"; import { SETTING_CONTENT_DEFAULT_FILETYPE, SETTING_TAXONOMY_CONTENT_TYPES, TelemetryEvent } from "../constants"; import { SettingsListener } from '../listeners/dashboard'; -import { writeFileAsync } from '../utils'; -import { existsSync } from 'fs'; +import { existsAsync, writeFileAsync } from '../utils'; export class Project { @@ -80,7 +79,7 @@ categories: [] const article = Uri.file(join(templatePath.fsPath, `article.${fileType}`)); - if (!existsSync(templatePath.fsPath)) { + if (!(await existsAsync(templatePath.fsPath))) { await workspace.fs.createDirectory(templatePath); } diff --git a/src/helpers/ArticleHelper.ts b/src/helpers/ArticleHelper.ts index 670ed422..ed051543 100644 --- a/src/helpers/ArticleHelper.ts +++ b/src/helpers/ArticleHelper.ts @@ -14,7 +14,6 @@ import { Article } from '../commands'; import { join } from 'path'; import { EditorHelper } from '@estruyf/vscode'; import sanitize from '../helpers/Sanitize'; -import { existsSync } from 'fs'; import { ContentType } from '../models'; import { DateHelper } from './DateHelper'; import { DiagnosticSeverity, Position, window, Range } from 'vscode'; @@ -25,7 +24,7 @@ import { Content } from 'mdast'; import { processKnownPlaceholders } from './PlaceholderHelper'; import { CustomScript } from './CustomScript'; import { Folders } from '../commands/Folders'; -import { readFileAsync } from '../utils'; +import { existsAsync, readFileAsync } from '../utils'; import { mkdirAsync } from '../utils/mkdirAsync'; export class ArticleHelper { @@ -342,7 +341,7 @@ export class ArticleHelper { // Create a folder with the `index.md` file if (contentType?.pageBundle) { const newFolder = join(folderPath, sanitizedName); - if (existsSync(newFolder)) { + if (await existsAsync(newFolder)) { Notifications.error(`A page bundle with the name ${sanitizedName} already exists in ${folderPath}`); return; } else { @@ -358,7 +357,7 @@ export class ArticleHelper { newFilePath = join(folderPath, newFileName); - if (existsSync(newFilePath)) { + if (await existsAsync(newFilePath)) { Notifications.warning(`Content with the title already exists. Please specify a new title.`); return; } diff --git a/src/helpers/ContentType.ts b/src/helpers/ContentType.ts index 6cc7be6f..5308a92c 100644 --- a/src/helpers/ContentType.ts +++ b/src/helpers/ContentType.ts @@ -6,14 +6,13 @@ import { ContentType as IContentType, DraftField, Field, FieldGroup, FieldType, import { Uri, commands, window, ProgressLocation, workspace } from 'vscode'; import { Folders } from "../commands/Folders"; import { Questions } from "./Questions"; -import { existsSync } from "fs"; import { Notifications } from "./Notifications"; import { DEFAULT_CONTENT_TYPE_NAME } from "../constants/ContentType"; import { Telemetry } from './Telemetry'; import { processKnownPlaceholders } from './PlaceholderHelper'; import { basename } from 'path'; import { ParsedFrontMatter } from '../parsers'; -import { writeFileAsync } from '../utils'; +import { existsAsync, writeFileAsync } from '../utils'; export class ContentType { @@ -198,9 +197,9 @@ export class ContentType { Settings.update(SETTING_TAXONOMY_CONTENT_TYPES, contentTypes, true); const configPath = Settings.projectConfigPath; - const notificationAction = await Notifications.info(`Content type ${contentTypeName} has been ${overrideBool ? `updated` : `generated`}.`, configPath && existsSync(configPath) ? `Open settings` : undefined); + const notificationAction = await Notifications.info(`Content type ${contentTypeName} has been ${overrideBool ? `updated` : `generated`}.`, configPath && await existsAsync(configPath) ? `Open settings` : undefined); - if (notificationAction === "Open settings" && configPath && existsSync(configPath)) { + if (notificationAction === "Open settings" && configPath && await existsAsync(configPath)) { commands.executeCommand('vscode.open', Uri.file(configPath)); } } @@ -232,9 +231,9 @@ export class ContentType { Settings.update(SETTING_TAXONOMY_CONTENT_TYPES, contentTypes, true); const configPath = Settings.projectConfigPath; - const notificationAction = await Notifications.info(`Content type ${contentType.name} has been updated.`, configPath && existsSync(configPath) ? `Open settings` : undefined); + const notificationAction = await Notifications.info(`Content type ${contentType.name} has been updated.`, configPath && await existsAsync(configPath) ? `Open settings` : undefined); - if (notificationAction === "Open settings" && configPath && existsSync(configPath)) { + if (notificationAction === "Open settings" && configPath && await existsAsync(configPath)) { commands.executeCommand('vscode.open', Uri.file(configPath)); } } diff --git a/src/helpers/CustomScript.ts b/src/helpers/CustomScript.ts index 7789b8cb..95525db5 100644 --- a/src/helpers/CustomScript.ts +++ b/src/helpers/CustomScript.ts @@ -14,7 +14,7 @@ import { DashboardCommand } from '../dashboardWebView/DashboardCommand'; import { ParsedFrontMatter } from '../parsers'; import { TelemetryEvent } from '../constants/TelemetryEvent'; import { SETTING_CUSTOM_SCRIPTS } from '../constants'; -import { existsSync } from 'fs'; +import { existsAsync } from '../utils'; export class CustomScript { @@ -264,7 +264,7 @@ export class CustomScript { * @returns */ public static async executeScript(script: ICustomScript, wsPath: string, args: string): Promise { - return new Promise((resolve, reject) => { + return new Promise(async (resolve, reject) => { // Check the command to use let command = script.nodeBin || "node"; @@ -274,7 +274,7 @@ export class CustomScript { const scriptPath = join(wsPath, script.script); - if (!existsSync(scriptPath)) { + if (!await existsAsync(scriptPath)) { reject(new Error(`Script not found: ${scriptPath}`)); return; } diff --git a/src/helpers/DataFileHelper.ts b/src/helpers/DataFileHelper.ts index 25f1547c..aa04dc7b 100644 --- a/src/helpers/DataFileHelper.ts +++ b/src/helpers/DataFileHelper.ts @@ -1,4 +1,3 @@ -import { existsSync } from "fs"; import { Folders } from "../commands/Folders"; import { DataFile } from "../models"; import * as yaml from 'js-yaml'; @@ -7,7 +6,7 @@ import { Notifications } from "./Notifications"; import { commands } from "vscode"; import { COMMAND_NAME, SETTING_DATA_FILES } from "../constants"; import { Settings } from "./SettingsHelper"; -import { readFileAsync } from "../utils"; +import { existsAsync, readFileAsync } from "../utils"; export class DataFileHelper { @@ -19,7 +18,7 @@ export class DataFileHelper { */ public static async get(filePath: string) { const absPath = Folders.getAbsFilePath(filePath); - if (existsSync(absPath)) { + if (await existsAsync(absPath)) { return await readFileAsync(absPath, 'utf8'); } diff --git a/src/helpers/FrameworkDetector.ts b/src/helpers/FrameworkDetector.ts index 5c1c0b97..1c5a54e5 100644 --- a/src/helpers/FrameworkDetector.ts +++ b/src/helpers/FrameworkDetector.ts @@ -1,5 +1,4 @@ import * as jsoncParser from 'jsonc-parser'; -import { existsSync } from "fs"; import jsyaml = require("js-yaml"); import { join, resolve } from "path"; import { commands, Uri } from "vscode"; @@ -8,7 +7,7 @@ import { COMMAND_NAME } from "../constants"; import { FrameworkDetectors } from "../constants/FrameworkDetectors"; import { Framework } from "../models"; import { Logger } from "./Logger"; -import { readFileAsync } from '../utils'; +import { existsAsync, readFileAsync } from '../utils'; export class FrameworkDetector { @@ -28,7 +27,7 @@ export class FrameworkDetector { // Try fetching the package JSON file try { const pkgFile = join(folder, 'package.json'); - if (existsSync(pkgFile)) { + if (await existsAsync(pkgFile)) { let packageJson: any = await readFileAsync(pkgFile, "utf8"); if (packageJson) { packageJson = typeof packageJson === "string" ? jsoncParser.parse(packageJson) : packageJson; @@ -44,7 +43,7 @@ export class FrameworkDetector { // Try fetching the Gemfile try { const gemFile = join(folder, 'Gemfile'); - if (existsSync(gemFile)) { + if (await existsAsync(gemFile)) { gemContent = await readFileAsync(gemFile, "utf8"); } } catch (e) { @@ -71,7 +70,7 @@ export class FrameworkDetector { // Verify by files for (const filename of detector.requiredFiles ?? []) { - const fileExists = existsSync(resolve(folder, filename)); + const fileExists = await existsAsync(resolve(folder, filename)); if (fileExists) { return detector.framework; } @@ -95,7 +94,7 @@ export class FrameworkDetector { const jekyllConfig = join(wsFolder?.fsPath || "", '_config.yml'); let collectionDir = ""; - if (existsSync(jekyllConfig)) { + if (await existsAsync(jekyllConfig)) { const content = await readFileAsync(jekyllConfig, "utf8"); // Convert YAML to JSON const config = jsyaml.safeLoad(content); @@ -108,7 +107,7 @@ export class FrameworkDetector { const draftsPath = join(wsFolder?.fsPath || "", collectionDir, "_drafts"); const postsPath = join(wsFolder?.fsPath || "", collectionDir, "_posts"); - if (existsSync(draftsPath)) { + if (await existsAsync(draftsPath)) { const folderUri = Uri.file(draftsPath); commands.executeCommand(COMMAND_NAME.registerFolder, { title: "drafts", @@ -116,7 +115,7 @@ export class FrameworkDetector { }); } - if (existsSync(postsPath)) { + if (await existsAsync(postsPath)) { const folderUri = Uri.file(postsPath); commands.executeCommand(COMMAND_NAME.registerFolder, { title: "posts", diff --git a/src/helpers/MediaHelpers.ts b/src/helpers/MediaHelpers.ts index 6573913e..68d77bc6 100644 --- a/src/helpers/MediaHelpers.ts +++ b/src/helpers/MediaHelpers.ts @@ -5,7 +5,7 @@ import { DEFAULT_CONTENT_TYPE, ExtensionState, HOME_PAGE_NAVIGATION_ID, SETTING_ import { SortingOption } from "../dashboardWebView/models"; import { MediaInfo, MediaPaths, SortOrder, SortType } from "../models"; import { basename, join, parse, dirname, relative } from "path"; -import { existsSync, statSync } from "fs"; +import { statSync } from "fs"; import { Uri, workspace, window, Position } from "vscode"; import imageSize from "image-size"; import { EditorHelper } from "@estruyf/vscode"; @@ -13,7 +13,7 @@ import { SortOption } from "../dashboardWebView/constants/SortOption"; import { DataListener, MediaListener } from "../listeners/panel"; import { ArticleHelper } from "./ArticleHelper"; import { lookup } from "mime-types"; -import { readdirAsync, unlinkAsync, writeFileAsync } from "../utils"; +import { existsAsync, readdirAsync, unlinkAsync, writeFileAsync } from "../utils"; export class MediaHelpers { @@ -49,7 +49,7 @@ export class MediaHelpers { if (viewData?.data?.filePath && (viewData?.data?.filePath.endsWith('index.md') || viewData?.data?.filePath.endsWith('index.mdx'))) { const folderPath = parse(viewData.data.filePath).dir; selectedFolder = folderPath; - } else if (stateValue && existsSync(stateValue)) { + } else if (stateValue && await existsAsync(stateValue)) { selectedFolder = stateValue; } } @@ -151,14 +151,14 @@ export class MediaHelpers { let allFolders: string[] = []; if (selectedFolder) { - if (existsSync(selectedFolder)) { + if (await existsAsync(selectedFolder)) { allFolders = (await readdirAsync(selectedFolder, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(selectedFolder, dir.name))); } } else { if (pageBundleContentTypes.length > 0) { for (const contentFolder of contentFolders) { const contentPath = contentFolder.path; - if (contentPath && existsSync(contentPath)) { + if (contentPath && await existsAsync(contentPath)) { const subFolders = (await readdirAsync(contentPath, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(contentPath, dir.name))); allContentFolders = [...allContentFolders, ...subFolders]; } @@ -166,7 +166,7 @@ export class MediaHelpers { } const staticPath = join(parseWinPath(wsFolder?.fsPath || ""), staticFolder || ""); - if (staticPath && existsSync(staticPath)) { + if (staticPath && await existsAsync(staticPath)) { allFolders = (await readdirAsync(staticPath, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(staticPath, dir.name))); } } @@ -219,11 +219,11 @@ export class MediaHelpers { absFolderPath = folder; } - if (!existsSync(absFolderPath)) { + if (!(await existsAsync(absFolderPath))) { absFolderPath = join(wsPath, folder || ""); } - if (!existsSync(absFolderPath)) { + if (!(await existsAsync(absFolderPath))) { Notifications.error(`We couldn't find your selected folder.`); return; } @@ -351,14 +351,14 @@ export class MediaHelpers { * Update the metadata of a media file * @param data */ - public static updateMetadata(data: any) { + public static async updateMetadata(data: any) { const { file, filename, page, folder, ...metadata }: { file:string; filename:string; page: number; folder: string | null; metadata: any; } = data; const mediaLib = MediaLibrary.getInstance(); mediaLib.set(file, metadata); // Check if filename needs to be updated - mediaLib.updateFilename(file, filename); + await mediaLib.updateFilename(file, filename); } /** diff --git a/src/helpers/MediaLibrary.ts b/src/helpers/MediaLibrary.ts index 430966df..5edc0ff4 100644 --- a/src/helpers/MediaLibrary.ts +++ b/src/helpers/MediaLibrary.ts @@ -3,10 +3,10 @@ import { workspace } from 'vscode'; import { JsonDB } from 'node-json-db/dist/JsonDB'; import { basename, dirname, join, parse } from 'path'; import { Folders, WORKSPACE_PLACEHOLDER } from '../commands/Folders'; -import { existsSync, renameSync } from 'fs'; import { Notifications } from './Notifications'; import { parseWinPath } from './parseWinPath'; import { LocalStore } from '../constants'; +import { existsAsync, renameAsync } from '../utils'; interface MediaRecord { description: string; @@ -75,7 +75,7 @@ export class MediaLibrary { } } - public updateFilename(filePath: string, filename: string) { + public async updateFilename(filePath: string, filename: string) { const name = basename(filePath); if (name !== filename && filename) { @@ -84,10 +84,10 @@ export class MediaLibrary { const newFileInfo = parse(filename); const newPath = join(dirname(filePath), `${newFileInfo.name}${oldFileInfo.ext}`); - if (existsSync(newPath)) { + if (await existsAsync(newPath)) { Notifications.warning(`The name "${filename}" already exists at the file location.`); } else { - renameSync(filePath, newPath); + await renameAsync(filePath, newPath); this.rename(filePath, newPath); MediaHelpers.resetMedia(); } diff --git a/src/helpers/SettingsHelper.ts b/src/helpers/SettingsHelper.ts index a98314d6..5190a825 100644 --- a/src/helpers/SettingsHelper.ts +++ b/src/helpers/SettingsHelper.ts @@ -12,7 +12,7 @@ import { Extension } from './Extension'; import { debounceCallback } from './DebounceCallback'; import { Logger } from './Logger'; import * as jsoncParser from 'jsonc-parser'; -import { readFileAsync, writeFileAsync } from '../utils'; +import { existsAsync, readFileAsync, writeFileAsync } from '../utils'; export class Settings { public static globalFile = "frontmatter.json"; @@ -182,7 +182,7 @@ export class Settings { const fmConfig = Settings.projectConfigPath; if (updateGlobal) { - if (fmConfig && existsSync(fmConfig)) { + if (fmConfig && await existsAsync(fmConfig)) { const localConfig = await readFileAsync(fmConfig, 'utf8'); Settings.globalConfig = jsoncParser.parse(localConfig); Settings.globalConfig[`${CONFIG_KEY}.${name}`] = value; @@ -232,7 +232,7 @@ export class Settings { if (wsFolder) { const configPath = join(wsFolder.fsPath, Settings.globalFile); - if (!existsSync(configPath)) { + if (!(await existsAsync(configPath))) { await writeFileAsync(configPath, JSON.stringify(initialConfig, null, 2), 'utf8'); } } @@ -419,7 +419,7 @@ export class Settings { private static async readConfig() { try { const fmConfig = Settings.projectConfigPath; - if (fmConfig && existsSync(fmConfig)) { + if (fmConfig && await existsAsync(fmConfig)) { const localConfig = await readFileAsync(fmConfig, 'utf8'); Settings.globalConfig = jsoncParser.parse(localConfig); commands.executeCommand('setContext', CONTEXT.isEnabled, true); diff --git a/src/listeners/dashboard/DataListener.ts b/src/listeners/dashboard/DataListener.ts index 54395e76..fa9e3e32 100644 --- a/src/listeners/dashboard/DataListener.ts +++ b/src/listeners/dashboard/DataListener.ts @@ -4,11 +4,10 @@ import { DashboardMessage } from "../../dashboardWebView/DashboardMessage"; import { BaseListener } from "./BaseListener"; import { DashboardCommand } from '../../dashboardWebView/DashboardCommand'; import { Folders } from '../../commands/Folders'; -import { existsSync } from 'fs'; import { dirname } from 'path'; import * as yaml from 'js-yaml'; import { DataFileHelper } from '../../helpers'; -import { readFileAsync, writeFileAsync } from '../../utils'; +import { existsAsync, readFileAsync, writeFileAsync } from '../../utils'; import { mkdirAsync } from '../../utils/mkdirAsync'; @@ -41,9 +40,9 @@ export class DataListener extends BaseListener { const { file, fileType, entries } = msgData as { file: string, fileType: string, entries: unknown | unknown[] }; const absPath = Folders.getAbsFilePath(file); - if (!existsSync(absPath)) { + if (!await existsAsync(absPath)) { const dirPath = dirname(absPath); - if (!existsSync(dirPath)) { + if (!await existsAsync(dirPath)) { await mkdirAsync(dirPath, { recursive: true }); } } diff --git a/src/listeners/dashboard/MediaListener.ts b/src/listeners/dashboard/MediaListener.ts index cd940b7c..6be6ac55 100644 --- a/src/listeners/dashboard/MediaListener.ts +++ b/src/listeners/dashboard/MediaListener.ts @@ -113,11 +113,11 @@ export class MediaListener extends BaseListener { * Update media metadata * @param data */ - private static update(data: any) { + private static async update(data: any) { try { const { page, folder } = data; - MediaHelpers.updateMetadata(data); + await MediaHelpers.updateMetadata(data); this.sendMediaFiles(page || 0, folder || ""); } catch {} diff --git a/src/services/PagesParser.ts b/src/services/PagesParser.ts index 965ceef3..df4e9dfa 100644 --- a/src/services/PagesParser.ts +++ b/src/services/PagesParser.ts @@ -1,5 +1,4 @@ import { parseWinPath } from './../helpers/parseWinPath'; -import { existsSync } from "fs"; import { dirname, join } from "path"; import { StatusBarAlignment, Uri, window } from "vscode"; import { Dashboard } from "../commands/Dashboard"; @@ -7,6 +6,7 @@ import { Folders } from "../commands/Folders"; import { DefaultFields, DEFAULT_CONTENT_TYPE_NAME, ExtensionState, SETTING_SEO_DESCRIPTION_FIELD } from "../constants"; import { Page } from "../dashboardWebView/models"; import { ArticleHelper, ContentType, DateHelper, Extension, isValidFile, Logger, Notifications, Settings } from "../helpers"; +import { existsAsync } from '../utils'; export class PagesParser { @@ -240,9 +240,9 @@ export class PagesParser { const contentFolderPath = join(dirname(filePath), fieldValue); let previewUri = null; - if (existsSync(staticPath)) { + if (await existsAsync(staticPath)) { previewUri = Uri.file(staticPath); - } else if (existsSync(contentFolderPath)) { + } else if (await existsAsync(contentFolderPath)) { previewUri = Uri.file(contentFolderPath); } diff --git a/src/utils/index.ts b/src/utils/index.ts index cc092021..c23da193 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -3,5 +3,6 @@ export * from './existsAsync'; export * from './mkdirAsync'; export * from './readFileAsync'; export * from './readdirAsync'; +export * from './renameAsync'; export * from './unlinkAsync'; export * from './writeFileAsync'; diff --git a/src/utils/renameAsync.ts b/src/utils/renameAsync.ts new file mode 100644 index 00000000..ed28c3a1 --- /dev/null +++ b/src/utils/renameAsync.ts @@ -0,0 +1,4 @@ +import { promisify } from "util"; +import { rename as renameCb } from "fs"; + +export const renameAsync = promisify(renameCb); \ No newline at end of file