From fad5ad7243ce6a394292de1ba261b5ecd82b5792 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Thu, 6 Oct 2022 21:36:51 +0200 Subject: [PATCH] Moving away from fs sync methods --- src/commands/Folders.ts | 9 +++++---- src/commands/Project.ts | 13 +++++++------ src/commands/Template.ts | 14 +++++++------- src/helpers/ArticleHelper.ts | 13 +++++++------ src/helpers/ContentType.ts | 9 +++++---- src/helpers/CustomScript.ts | 6 +++--- src/helpers/DashboardSettings.ts | 2 +- src/helpers/DataFileHelper.ts | 9 +++++---- src/helpers/Extension.ts | 2 +- src/helpers/FrameworkDetector.ts | 17 +++++++++-------- src/helpers/MediaHelpers.ts | 17 +++++++++-------- src/helpers/SettingsHelper.ts | 17 +++++++++-------- src/helpers/TaxonomyHelper.ts | 10 +++++----- src/listeners/dashboard/DataListener.ts | 14 ++++++++------ src/listeners/dashboard/PagesListener.ts | 6 +++--- src/listeners/dashboard/SettingsListener.ts | 4 ++-- src/services/PagesParser.ts | 6 +++--- src/utils/copyFileAsync.ts | 4 ++++ src/utils/existsAsync.ts | 6 ++++++ src/utils/index.ts | 7 +++++++ src/utils/mkdirAsync.ts | 4 ++++ src/utils/readFileAsync.ts | 4 ++++ src/utils/readdirAsync.ts | 4 ++++ src/utils/unlinkAsync.ts | 4 ++++ src/utils/writeFileAsync.ts | 4 ++++ 25 files changed, 126 insertions(+), 79 deletions(-) create mode 100644 src/utils/copyFileAsync.ts create mode 100644 src/utils/existsAsync.ts create mode 100644 src/utils/index.ts create mode 100644 src/utils/mkdirAsync.ts create mode 100644 src/utils/readFileAsync.ts create mode 100644 src/utils/readdirAsync.ts create mode 100644 src/utils/unlinkAsync.ts create mode 100644 src/utils/writeFileAsync.ts diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index ea39ae10..69ff8ef8 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -7,7 +7,7 @@ import uniqBy = require("lodash.uniqby"); import { Template } from "./Template"; import { Notifications } from "../helpers/Notifications"; import { Logger, Settings } from "../helpers"; -import { existsSync, mkdirSync } from 'fs'; +import { existsSync } from 'fs'; import { format } from 'date-fns'; import { Dashboard } from './Dashboard'; import { parseWinPath } from '../helpers/parseWinPath'; @@ -16,6 +16,7 @@ import { MediaListener, PagesListener, SettingsListener } from '../listeners/das import { DEFAULT_FILE_TYPES } from '../constants/DefaultFileTypes'; import { Telemetry } from '../helpers/Telemetry'; import { glob } from 'glob'; +import { mkdirAsync } from '../utils/mkdirAsync'; export const WORKSPACE_PLACEHOLDER = `[[workspace]]`; @@ -63,7 +64,7 @@ export class Folders { parentFolders.push(folder); if (!existsSync(folderPath)) { - mkdirSync(folderPath); + await mkdirAsync(folderPath); } } @@ -210,9 +211,9 @@ export class Folders { if (!projectFolder) { window.showWorkspaceFolderPick({ placeHolder: `Please select the main workspace folder for Front Matter to use.` - }).then(selectedFolder => { + }).then(async (selectedFolder) => { if (selectedFolder) { - Settings.createGlobalFile(selectedFolder.uri); + await Settings.createGlobalFile(selectedFolder.uri); // Full reload to make sure the whole extension is reloaded correctly commands.executeCommand(`workbench.action.reloadWindow`); } diff --git a/src/commands/Project.ts b/src/commands/Project.ts index d7cb3488..c9daa83b 100644 --- a/src/commands/Project.ts +++ b/src/commands/Project.ts @@ -2,13 +2,14 @@ import { DEFAULT_CONTENT_TYPE } from './../constants/ContentType'; import { Telemetry } from './../helpers/Telemetry'; import { workspace, Uri } from "vscode"; import { join } from "path"; -import * as fs from "fs"; import { Notifications } from "../helpers/Notifications"; import { Template } from "./Template"; 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'; export class Project { @@ -34,7 +35,7 @@ categories: [] */ public static async init(sampleTemplate?: boolean) { try { - Settings.createTeamSettings(); + await Settings.createTeamSettings(); // Add the default content type Settings.update(SETTING_TAXONOMY_CONTENT_TYPES, [DEFAULT_CONTENT_TYPE], true); @@ -49,10 +50,10 @@ categories: [] // Check if you can find the framework const wsFolder = Folders.getWorkspaceFolder(); - const framework = FrameworkDetector.get(wsFolder?.fsPath || ""); + const framework = await FrameworkDetector.get(wsFolder?.fsPath || ""); if (framework) { - SettingsListener.setFramework(framework.name); + await SettingsListener.setFramework(framework.name); } SettingsListener.getSettings(true); @@ -79,12 +80,12 @@ categories: [] const article = Uri.file(join(templatePath.fsPath, `article.${fileType}`)); - if (!fs.existsSync(templatePath.fsPath)) { + if (!existsSync(templatePath.fsPath)) { await workspace.fs.createDirectory(templatePath); } if (sampleTemplate) { - fs.writeFileSync(article.fsPath, Project.content, { encoding: "utf-8" }); + await writeFileAsync(article.fsPath, Project.content, { encoding: "utf-8" }); Notifications.info("Sample template created."); } } diff --git a/src/commands/Template.ts b/src/commands/Template.ts index 03b6119c..6201c2c3 100644 --- a/src/commands/Template.ts +++ b/src/commands/Template.ts @@ -1,7 +1,6 @@ import { Questions } from './../helpers/Questions'; import * as vscode from 'vscode'; import * as path from 'path'; -import * as fs from 'fs'; import { SETTING_CONTENT_DEFAULT_FILETYPE, SETTING_TEMPLATES_FOLDER, TelemetryEvent } from '../constants'; import { ArticleHelper, Settings } from '../helpers'; import { Article } from '.'; @@ -12,6 +11,7 @@ import { ContentType as IContentType } from '../models'; import { PagesListener } from '../listeners/dashboard'; import { extname } from 'path'; import { Telemetry } from '../helpers/Telemetry'; +import { writeFileAsync, copyFileAsync } from '../utils'; export class Template { @@ -60,7 +60,7 @@ export class Template { let fileContents = ArticleHelper.stringifyFrontMatter(keepContents === "no" ? "" : clonedArticle.content, clonedArticle.data); const templateFile = path.join(templatePath.fsPath, `${titleValue}.${fileType}`); - fs.writeFileSync(templateFile, fileContents, { encoding: "utf-8" }); + await writeFileAsync(templateFile, fileContents, { encoding: "utf-8" }); Notifications.info(`Template created and is now available in your ${folder} folder.`); } @@ -120,23 +120,23 @@ export class Template { return; } - const templateData = ArticleHelper.getFrontMatterByPath(template.fsPath); + const templateData = await ArticleHelper.getFrontMatterByPath(template.fsPath); let contentType: IContentType | undefined; if (templateData && templateData.data && templateData.data.type) { contentType = contentTypes?.find(t => t.name === templateData.data.type); } const fileExtension = extname(template.fsPath).replace(".", ""); - let newFilePath: string | undefined = ArticleHelper.createContent(contentType, folderPath, titleValue, fileExtension); + let newFilePath: string | undefined = await ArticleHelper.createContent(contentType, folderPath, titleValue, fileExtension); if (!newFilePath) { return; } // Start the new file creation - fs.copyFileSync(template.fsPath, newFilePath); + await copyFileAsync(template.fsPath, newFilePath); // Update the properties inside the template - let frontMatter = ArticleHelper.getFrontMatterByPath(newFilePath); + let frontMatter = await ArticleHelper.getFrontMatterByPath(newFilePath); if (!frontMatter) { Notifications.warning(`Something failed when retrieving the newly created file.`); return; @@ -147,7 +147,7 @@ export class Template { frontMatter = Article.updateDate(frontMatter); - fs.writeFileSync(newFilePath, ArticleHelper.stringifyFrontMatter(frontMatter.content, frontMatter.data), { encoding: "utf8" }); + await writeFileAsync(newFilePath, ArticleHelper.stringifyFrontMatter(frontMatter.content, frontMatter.data), { encoding: "utf8" }); await vscode.commands.executeCommand('vscode.open', vscode.Uri.file(newFilePath)); } diff --git a/src/helpers/ArticleHelper.ts b/src/helpers/ArticleHelper.ts index 2fa1ba5c..670ed422 100644 --- a/src/helpers/ArticleHelper.ts +++ b/src/helpers/ArticleHelper.ts @@ -4,7 +4,6 @@ import { Uri, workspace } from 'vscode'; import { MarkdownFoldingProvider } from './../providers/MarkdownFoldingProvider'; import { DEFAULT_CONTENT_TYPE, DEFAULT_CONTENT_TYPE_NAME } from './../constants/ContentType'; import * as vscode from 'vscode'; -import * as fs from "fs"; import { DefaultFields, SETTING_CONTENT_DEFAULT_FILETYPE, SETTING_CONTENT_PLACEHOLDERS, SETTING_CONTENT_SUPPORTED_FILETYPES, SETTING_FILE_PRESERVE_CASING, SETTING_COMMA_SEPARATED_FIELDS, SETTING_DATE_FIELD, SETTING_DATE_FORMAT, SETTING_INDENT_ARRAY, SETTING_REMOVE_QUOTES, SETTING_SITE_BASEURL, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_TEMPLATES_PREFIX, SETTING_MODIFIED_FIELD, DefaultFieldValues } from '../constants'; import { DumpOptions } from 'js-yaml'; import { FrontMatterParser, ParsedFrontMatter } from '../parsers'; @@ -15,7 +14,7 @@ import { Article } from '../commands'; import { join } from 'path'; import { EditorHelper } from '@estruyf/vscode'; import sanitize from '../helpers/Sanitize'; -import { existsSync, mkdirSync } from 'fs'; +import { existsSync } from 'fs'; import { ContentType } from '../models'; import { DateHelper } from './DateHelper'; import { DiagnosticSeverity, Position, window, Range } from 'vscode'; @@ -26,6 +25,8 @@ import { Content } from 'mdast'; import { processKnownPlaceholders } from './PlaceholderHelper'; import { CustomScript } from './CustomScript'; import { Folders } from '../commands/Folders'; +import { readFileAsync } from '../utils'; +import { mkdirAsync } from '../utils/mkdirAsync'; export class ArticleHelper { private static notifiedFiles: string[] = []; @@ -70,8 +71,8 @@ export class ArticleHelper { * Retrieve the file's front matter by its path * @param filePath */ - public static getFrontMatterByPath(filePath: string) { - const file = fs.readFileSync(filePath, { encoding: "utf-8" }); + public static async getFrontMatterByPath(filePath: string) { + const file = await readFileAsync(filePath, { encoding: "utf-8" }); return ArticleHelper.parseFile(file, filePath); } @@ -328,7 +329,7 @@ export class ArticleHelper { * @param titleValue * @returns The new file path */ - public static createContent(contentType: ContentType | undefined, folderPath: string, titleValue: string, fileExtension?: string): string | undefined { + public static async createContent(contentType: ContentType | undefined, folderPath: string, titleValue: string, fileExtension?: string): Promise { FrontMatterParser.currentContent = null; const prefix = Settings.get(SETTING_TEMPLATES_PREFIX); @@ -345,7 +346,7 @@ export class ArticleHelper { Notifications.error(`A page bundle with the name ${sanitizedName} already exists in ${folderPath}`); return; } else { - mkdirSync(newFolder); + await mkdirAsync(newFolder); newFilePath = join(newFolder, `index.${fileExtension || contentType.fileType || fileType}`); } } else { diff --git a/src/helpers/ContentType.ts b/src/helpers/ContentType.ts index 7b64a2d9..6cc7be6f 100644 --- a/src/helpers/ContentType.ts +++ b/src/helpers/ContentType.ts @@ -6,13 +6,14 @@ 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, writeFileSync } from "fs"; +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'; export class ContentType { @@ -558,10 +559,10 @@ export class ContentType { let templateData: ParsedFrontMatter | null = null; if (templatePath) { templatePath = Folders.getAbsFilePath(templatePath); - templateData = ArticleHelper.getFrontMatterByPath(templatePath); + templateData = await ArticleHelper.getFrontMatterByPath(templatePath); } - let newFilePath: string | undefined = ArticleHelper.createContent(contentType, folderPath, titleValue); + let newFilePath: string | undefined = await ArticleHelper.createContent(contentType, folderPath, titleValue); if (!newFilePath) { return; } @@ -586,7 +587,7 @@ export class ContentType { const content = ArticleHelper.stringifyFrontMatter(templateData?.content || ``, data); - writeFileSync(newFilePath, content, { encoding: "utf8" }); + await writeFileAsync(newFilePath, content, { encoding: "utf8" }); // Check if the content type has a post script to execute if (contentType.postScript) { diff --git a/src/helpers/CustomScript.ts b/src/helpers/CustomScript.ts index 5f2db7db..7789b8cb 100644 --- a/src/helpers/CustomScript.ts +++ b/src/helpers/CustomScript.ts @@ -77,7 +77,7 @@ export class CustomScript { articlePath = editor.document.uri.fsPath; article = ArticleHelper.getFrontMatter(editor); } else { - article = ArticleHelper.getFrontMatterByPath(path); + article = await ArticleHelper.getFrontMatterByPath(path); } if (articlePath && article) { @@ -119,7 +119,7 @@ export class CustomScript { if (folder.lastModified.length > 0) { for await (const file of folder.lastModified) { try { - const article = ArticleHelper.getFrontMatterByPath(file.filePath); + const article = await ArticleHelper.getFrontMatterByPath(file.filePath); if (article) { const crntOutput = await CustomScript.runScript(wsPath, article, file.filePath, script); if (crntOutput) { @@ -220,7 +220,7 @@ export class CustomScript { articlePath = editor.document.uri.fsPath; article = ArticleHelper.getFrontMatter(editor); } else { - article = ArticleHelper.getFrontMatterByPath(articlePath); + article = await ArticleHelper.getFrontMatterByPath(articlePath); } if (article && article.data) { diff --git a/src/helpers/DashboardSettings.ts b/src/helpers/DashboardSettings.ts index 6119a1fb..b31c6286 100644 --- a/src/helpers/DashboardSettings.ts +++ b/src/helpers/DashboardSettings.ts @@ -53,7 +53,7 @@ export class DashboardSettings { customSorting: Settings.get(SETTING_CONTENT_SORTING), contentFolders: Folders.get(), crntFramework: Settings.get(SETTING_FRAMEWORK_ID), - framework: (!isInitialized && wsFolder) ? FrameworkDetector.get(wsFolder.fsPath) : null, + framework: (!isInitialized && wsFolder) ? await FrameworkDetector.get(wsFolder.fsPath) : null, scripts: (Settings.get(SETTING_CUSTOM_SCRIPTS) || []), date: { format: Settings.get(SETTING_DATE_FORMAT) || "" diff --git a/src/helpers/DataFileHelper.ts b/src/helpers/DataFileHelper.ts index e7c59d12..25f1547c 100644 --- a/src/helpers/DataFileHelper.ts +++ b/src/helpers/DataFileHelper.ts @@ -1,4 +1,4 @@ -import { existsSync, readFileSync } from "fs"; +import { existsSync } from "fs"; import { Folders } from "../commands/Folders"; import { DataFile } from "../models"; import * as yaml from 'js-yaml'; @@ -7,6 +7,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"; export class DataFileHelper { @@ -16,10 +17,10 @@ export class DataFileHelper { * @param filePath * @returns */ - public static get(filePath: string) { + public static async get(filePath: string) { const absPath = Folders.getAbsFilePath(filePath); if (existsSync(absPath)) { - return readFileSync(absPath, 'utf8'); + return await readFileAsync(absPath, 'utf8'); } return null; @@ -53,7 +54,7 @@ export class DataFileHelper { public static async process(data: DataFile) { try { const { file, fileType } = data; - const dataFile = DataFileHelper.get(file); + const dataFile = await DataFileHelper.get(file); if (fileType === "yaml") { return yaml.safeLoad(dataFile || ""); diff --git a/src/helpers/Extension.ts b/src/helpers/Extension.ts index 4ab882ec..6a01ad69 100644 --- a/src/helpers/Extension.ts +++ b/src/helpers/Extension.ts @@ -154,7 +154,7 @@ export class Extension { // Create team settings if (Settings.hasSettings()) { - Settings.createTeamSettings(); + await Settings.createTeamSettings(); } const hideDateDeprecation = await Extension.getInstance().getState(ExtensionState.Updates.v7_0_0.dateFields, "workspace"); diff --git a/src/helpers/FrameworkDetector.ts b/src/helpers/FrameworkDetector.ts index d1607e0c..5c1c0b97 100644 --- a/src/helpers/FrameworkDetector.ts +++ b/src/helpers/FrameworkDetector.ts @@ -1,5 +1,5 @@ import * as jsoncParser from 'jsonc-parser'; -import { existsSync, readFileSync } from "fs"; +import { existsSync } from "fs"; import jsyaml = require("js-yaml"); import { join, resolve } from "path"; import { commands, Uri } from "vscode"; @@ -8,6 +8,7 @@ import { COMMAND_NAME } from "../constants"; import { FrameworkDetectors } from "../constants/FrameworkDetectors"; import { Framework } from "../models"; import { Logger } from "./Logger"; +import { readFileAsync } from '../utils'; export class FrameworkDetector { @@ -19,7 +20,7 @@ export class FrameworkDetector { return FrameworkDetectors.map((detector: any) => detector.framework); } - private static check(folder: string) { + private static async check(folder: string) { let dependencies = null; let devDependencies = null; let gemContent = null; @@ -28,7 +29,7 @@ export class FrameworkDetector { try { const pkgFile = join(folder, 'package.json'); if (existsSync(pkgFile)) { - let packageJson: any = readFileSync(pkgFile, "utf8"); + let packageJson: any = await readFileAsync(pkgFile, "utf8"); if (packageJson) { packageJson = typeof packageJson === "string" ? jsoncParser.parse(packageJson) : packageJson; @@ -44,7 +45,7 @@ export class FrameworkDetector { try { const gemFile = join(folder, 'Gemfile'); if (existsSync(gemFile)) { - gemContent = readFileSync(gemFile, "utf8"); + gemContent = await readFileAsync(gemFile, "utf8"); } } catch (e) { // do nothing @@ -81,21 +82,21 @@ export class FrameworkDetector { return undefined; } - public static checkDefaultSettings(framework: Framework) { + public static async checkDefaultSettings(framework: Framework) { if (framework.name.toLowerCase() === "jekyll") { - FrameworkDetector.jekyll(); + await FrameworkDetector.jekyll(); } } - private static jekyll() { + private static async jekyll() { try { const wsFolder = Folders.getWorkspaceFolder(); const jekyllConfig = join(wsFolder?.fsPath || "", '_config.yml'); let collectionDir = ""; if (existsSync(jekyllConfig)) { - const content = readFileSync(jekyllConfig, "utf8"); + const content = await readFileAsync(jekyllConfig, "utf8"); // Convert YAML to JSON const config = jsyaml.safeLoad(content); diff --git a/src/helpers/MediaHelpers.ts b/src/helpers/MediaHelpers.ts index d6295df5..6573913e 100644 --- a/src/helpers/MediaHelpers.ts +++ b/src/helpers/MediaHelpers.ts @@ -4,15 +4,16 @@ import { Folders } from "../commands/Folders"; import { DEFAULT_CONTENT_TYPE, ExtensionState, HOME_PAGE_NAVIGATION_ID, SETTING_MEDIA_SUPPORTED_MIMETYPES } from "../constants"; import { SortingOption } from "../dashboardWebView/models"; import { MediaInfo, MediaPaths, SortOrder, SortType } from "../models"; -import { basename, extname, join, parse, dirname, relative } from "path"; -import { existsSync, readdirSync, statSync, unlinkSync, writeFileSync } from "fs"; -import { commands, Uri, workspace, window, Position } from "vscode"; +import { basename, join, parse, dirname, relative } from "path"; +import { existsSync, statSync } from "fs"; +import { Uri, workspace, window, Position } from "vscode"; import imageSize from "image-size"; import { EditorHelper } from "@estruyf/vscode"; 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"; export class MediaHelpers { @@ -151,14 +152,14 @@ export class MediaHelpers { if (selectedFolder) { if (existsSync(selectedFolder)) { - allFolders = readdirSync(selectedFolder, { withFileTypes: true }).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(selectedFolder, dir.name))); + 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)) { - const subFolders = readdirSync(contentPath, { withFileTypes: true }).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(contentPath, dir.name))); + const subFolders = (await readdirAsync(contentPath, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(contentPath, dir.name))); allContentFolders = [...allContentFolders, ...subFolders]; } } @@ -166,7 +167,7 @@ export class MediaHelpers { const staticPath = join(parseWinPath(wsFolder?.fsPath || ""), staticFolder || ""); if (staticPath && existsSync(staticPath)) { - allFolders = readdirSync(staticPath, { withFileTypes: true }).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(staticPath, dir.name))); + allFolders = (await readdirAsync(staticPath, { withFileTypes: true })).filter(dir => dir.isDirectory()).map(dir => parseWinPath(join(staticPath, dir.name))); } } @@ -231,7 +232,7 @@ export class MediaHelpers { const imgData = decodeBase64(contents); if (imgData) { - writeFileSync(staticPath, imgData.data); + await writeFileAsync(staticPath, imgData.data); Notifications.info(`File ${fileName} uploaded to: ${folder}`); return true; @@ -255,7 +256,7 @@ export class MediaHelpers { } try { - unlinkSync(file); + await unlinkAsync(file); MediaHelpers.media = []; return true; diff --git a/src/helpers/SettingsHelper.ts b/src/helpers/SettingsHelper.ts index e3eafc3c..a98314d6 100644 --- a/src/helpers/SettingsHelper.ts +++ b/src/helpers/SettingsHelper.ts @@ -7,11 +7,12 @@ import { ContentType, CustomTaxonomy, TaxonomyType } from '../models'; import { SETTING_TAXONOMY_TAGS, SETTING_TAXONOMY_CATEGORIES, CONFIG_KEY, CONTEXT, ExtensionState, SETTING_TAXONOMY_CUSTOM, TelemetryEvent, COMMAND_NAME, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_CONTENT_PAGE_FOLDERS, SETTING_CONTENT_SNIPPETS, SETTING_CONTENT_PLACEHOLDERS, SETTING_CUSTOM_SCRIPTS, SETTING_DATA_FILES, SETTING_DATA_TYPES, SETTING_DATA_FOLDERS } from '../constants'; import { Folders } from '../commands/Folders'; import { join, basename, dirname, parse } from 'path'; -import { existsSync, readFileSync, writeFileSync } from 'fs'; +import { existsSync } from 'fs'; import { Extension } from './Extension'; import { debounceCallback } from './DebounceCallback'; import { Logger } from './Logger'; import * as jsoncParser from 'jsonc-parser'; +import { readFileAsync, writeFileAsync } from '../utils'; export class Settings { public static globalFile = "frontmatter.json"; @@ -182,10 +183,10 @@ export class Settings { if (updateGlobal) { if (fmConfig && existsSync(fmConfig)) { - const localConfig = readFileSync(fmConfig, 'utf8'); + const localConfig = await readFileAsync(fmConfig, 'utf8'); Settings.globalConfig = jsoncParser.parse(localConfig); Settings.globalConfig[`${CONFIG_KEY}.${name}`] = value; - writeFileSync(fmConfig, JSON.stringify(Settings.globalConfig, null, 2), 'utf8'); + await writeFileAsync(fmConfig, JSON.stringify(Settings.globalConfig, null, 2), 'utf8'); const workspaceSettingValue = Settings.hasWorkspaceSettings(name); if (workspaceSettingValue) { @@ -215,16 +216,16 @@ export class Settings { /** * Create team settings */ - public static createTeamSettings() { + public static async createTeamSettings() { const wsFolder = Folders.getWorkspaceFolder(); - this.createGlobalFile(wsFolder); + await this.createGlobalFile(wsFolder); } /** * Create the frontmatter.json file * @param wsFolder */ - public static createGlobalFile(wsFolder: Uri | undefined | null) { + public static async createGlobalFile(wsFolder: Uri | undefined | null) { const initialConfig = { "$schema": `https://${Extension.getInstance().isBetaVersion() ? `beta.` : ``}frontmatter.codes/frontmatter.schema.json` }; @@ -232,7 +233,7 @@ export class Settings { if (wsFolder) { const configPath = join(wsFolder.fsPath, Settings.globalFile); if (!existsSync(configPath)) { - writeFileSync(configPath, JSON.stringify(initialConfig, null, 2), 'utf8'); + await writeFileAsync(configPath, JSON.stringify(initialConfig, null, 2), 'utf8'); } } } @@ -419,7 +420,7 @@ export class Settings { try { const fmConfig = Settings.projectConfigPath; if (fmConfig && existsSync(fmConfig)) { - const localConfig = readFileSync(fmConfig, 'utf8'); + const localConfig = await readFileAsync(fmConfig, 'utf8'); Settings.globalConfig = jsoncParser.parse(localConfig); commands.executeCommand('setContext', CONTEXT.isEnabled, true); } else { diff --git a/src/helpers/TaxonomyHelper.ts b/src/helpers/TaxonomyHelper.ts index 1327f321..1ffeac24 100644 --- a/src/helpers/TaxonomyHelper.ts +++ b/src/helpers/TaxonomyHelper.ts @@ -4,13 +4,13 @@ import { CustomTaxonomy, TaxonomyType, ContentType as IContentType } from "../mo import { FilesHelper } from "./FilesHelper"; import { ProgressLocation, window } from "vscode"; import { parseWinPath } from "./parseWinPath"; -import { readFileSync, writeFileSync } from "fs"; import { FrontMatterParser } from "../parsers"; import { DumpOptions } from "js-yaml"; import { Settings } from "./SettingsHelper"; import { Notifications } from "./Notifications"; import { ArticleHelper } from './ArticleHelper'; import { ContentType } from './ContentType'; +import { readFileAsync, writeFileAsync } from '../utils'; export class TaxonomyHelper { @@ -186,7 +186,7 @@ export class TaxonomyHelper { for (const file of allFiles) { progress.report({ increment: (++i/progressNr) }); - const mdFile = readFileSync(parseWinPath(file.fsPath), { encoding: "utf8" }); + const mdFile = await readFileAsync(parseWinPath(file.fsPath), { encoding: "utf8" }); if (mdFile) { try { @@ -217,7 +217,7 @@ export class TaxonomyHelper { const spaces = window.activeTextEditor?.options?.tabSize; // Update the file - writeFileSync(parseWinPath(file.fsPath), FrontMatterParser.toFile(article.content, article.data, mdFile, { + await writeFileAsync(parseWinPath(file.fsPath), FrontMatterParser.toFile(article.content, article.data, mdFile, { indent: spaces || 2 } as DumpOptions as any), { encoding: "utf8" }); } @@ -291,7 +291,7 @@ export class TaxonomyHelper { for (const file of allFiles) { progress.report({ increment: (++i/progressNr) }); - const mdFile = readFileSync(parseWinPath(file.fsPath), { encoding: "utf8" }); + const mdFile = await readFileAsync(parseWinPath(file.fsPath), { encoding: "utf8" }); if (mdFile) { try { @@ -324,7 +324,7 @@ export class TaxonomyHelper { const spaces = window.activeTextEditor?.options?.tabSize; // Update the file - writeFileSync(parseWinPath(file.fsPath), FrontMatterParser.toFile(article.content, article.data, mdFile, { + await writeFileAsync(parseWinPath(file.fsPath), FrontMatterParser.toFile(article.content, article.data, mdFile, { indent: spaces || 2 } as DumpOptions as any), { encoding: "utf8" }); } diff --git a/src/listeners/dashboard/DataListener.ts b/src/listeners/dashboard/DataListener.ts index 10530503..54395e76 100644 --- a/src/listeners/dashboard/DataListener.ts +++ b/src/listeners/dashboard/DataListener.ts @@ -4,10 +4,12 @@ import { DashboardMessage } from "../../dashboardWebView/DashboardMessage"; import { BaseListener } from "./BaseListener"; import { DashboardCommand } from '../../dashboardWebView/DashboardCommand'; import { Folders } from '../../commands/Folders'; -import { existsSync, writeFileSync, mkdirSync, readFileSync } from 'fs'; +import { existsSync } from 'fs'; import { dirname } from 'path'; import * as yaml from 'js-yaml'; import { DataFileHelper } from '../../helpers'; +import { readFileAsync, writeFileAsync } from '../../utils'; +import { mkdirAsync } from '../../utils/mkdirAsync'; export class DataListener extends BaseListener { @@ -35,28 +37,28 @@ export class DataListener extends BaseListener { * Process the data update * @param msgData */ - private static processDataUpdate(msgData: any) { + private static async processDataUpdate(msgData: any) { const { file, fileType, entries } = msgData as { file: string, fileType: string, entries: unknown | unknown[] }; const absPath = Folders.getAbsFilePath(file); if (!existsSync(absPath)) { const dirPath = dirname(absPath); if (!existsSync(dirPath)) { - mkdirSync(dirPath, { recursive: true }); + await mkdirAsync(dirPath, { recursive: true }); } } - const fileContent = readFileSync(absPath, 'utf8'); + const fileContent = await readFileAsync(absPath, 'utf8'); // check if file content ends with newline const newFileContent = fileContent.endsWith('\n'); const insertFinalNewLine = newFileContent || workspace.getConfiguration().get('files.insertFinalNewline'); if (fileType === 'yaml') { const yamlData = yaml.safeDump(entries); - writeFileSync(absPath, insertFinalNewLine ? `${yamlData}\n` : yamlData, 'utf8'); + await writeFileAsync(absPath, insertFinalNewLine ? `${yamlData}\n` : yamlData, 'utf8'); } else { const jsonData = JSON.stringify(entries, null, 2); - writeFileSync(absPath, insertFinalNewLine ? `${jsonData}\n` : jsonData, 'utf8'); + await writeFileAsync(absPath, insertFinalNewLine ? `${jsonData}\n` : jsonData, 'utf8'); } this.processDataFile(msgData); diff --git a/src/listeners/dashboard/PagesListener.ts b/src/listeners/dashboard/PagesListener.ts index 37531d6b..2d167318 100644 --- a/src/listeners/dashboard/PagesListener.ts +++ b/src/listeners/dashboard/PagesListener.ts @@ -1,4 +1,3 @@ -import { unlinkSync } from "fs"; import { basename } from "path"; import { commands, FileSystemWatcher, RelativePattern, TextDocument, Uri, workspace } from "vscode"; import { Dashboard } from "../../commands/Dashboard"; @@ -12,6 +11,7 @@ import { BaseListener } from "./BaseListener"; import { DataListener } from '../panel'; import Fuse from 'fuse.js'; import { PagesParser } from '../../services/PagesParser'; +import { unlinkAsync } from "../../utils"; export class PagesListener extends BaseListener { @@ -106,7 +106,7 @@ export class PagesListener extends BaseListener { Logger.info(`Deleting file: ${path}`) - unlinkSync(path); + await unlinkAsync(path); this.lastPages = this.lastPages.filter(p => p.fmFilePath !== path); this.sendPageData(this.lastPages); @@ -128,7 +128,7 @@ export class PagesListener extends BaseListener { if (pageIdx !== -1) { const stats = await workspace.fs.stat(file); const crntPage = this.lastPages[pageIdx]; - const updatedPage = PagesParser.processPageContent(file.fsPath, stats.mtime, basename(file.fsPath), crntPage.fmFolder); + const updatedPage = await PagesParser.processPageContent(file.fsPath, stats.mtime, basename(file.fsPath), crntPage.fmFolder); if (updatedPage) { this.lastPages[pageIdx] = updatedPage; this.sendPageData(this.lastPages); diff --git a/src/listeners/dashboard/SettingsListener.ts b/src/listeners/dashboard/SettingsListener.ts index e9c7ee9b..ffce8394 100644 --- a/src/listeners/dashboard/SettingsListener.ts +++ b/src/listeners/dashboard/SettingsListener.ts @@ -59,7 +59,7 @@ export class SettingsListener extends BaseListener { * Set the current site-generator or framework + related settings * @param frameworkId */ - public static setFramework(frameworkId: string | null) { + public static async setFramework(frameworkId: string | null) { Settings.update(SETTING_FRAMEWORK_ID, frameworkId, true); if (frameworkId) { @@ -68,7 +68,7 @@ export class SettingsListener extends BaseListener { if (framework) { Settings.update(SETTING_CONTENT_STATIC_FOLDER, framework.static, true); - FrameworkDetector.checkDefaultSettings(framework); + await FrameworkDetector.checkDefaultSettings(framework); } else { Settings.update(SETTING_CONTENT_STATIC_FOLDER, "", true); } diff --git a/src/services/PagesParser.ts b/src/services/PagesParser.ts index 24bb3b8a..965ceef3 100644 --- a/src/services/PagesParser.ts +++ b/src/services/PagesParser.ts @@ -72,7 +72,7 @@ export class PagesParser { let page = await PagesParser.getCachedPage(file.filePath, file.mtime); if (!page) { - page = this.processPageContent(file.filePath, file.mtime, file.fileName, folder.title); + page = await this.processPageContent(file.filePath, file.mtime, file.fileName, folder.title); } if (page && !pages.find(p => p.fmFilePath === page?.fmFilePath)) { @@ -123,8 +123,8 @@ export class PagesParser { * @param folderTitle * @returns */ - public static processPageContent(filePath: string, fileMtime: number, fileName: string, folderTitle: string): Page | undefined { - const article = ArticleHelper.getFrontMatterByPath(filePath); + public static async processPageContent(filePath: string, fileMtime: number, fileName: string, folderTitle: string): Promise { + const article = await ArticleHelper.getFrontMatterByPath(filePath); if (article?.data.title) { const wsFolder = Folders.getWorkspaceFolder(); diff --git a/src/utils/copyFileAsync.ts b/src/utils/copyFileAsync.ts new file mode 100644 index 00000000..e5d1924e --- /dev/null +++ b/src/utils/copyFileAsync.ts @@ -0,0 +1,4 @@ +import { promisify } from "util"; +import { copyFile as copyFileCb } from "fs"; + +export const copyFileAsync = promisify(copyFileCb); \ No newline at end of file diff --git a/src/utils/existsAsync.ts b/src/utils/existsAsync.ts new file mode 100644 index 00000000..c4f793d8 --- /dev/null +++ b/src/utils/existsAsync.ts @@ -0,0 +1,6 @@ +import { stat } from "fs"; +import { promisify } from "util"; + +export const existsAsync = async (path: string) => { + return promisify(stat)(path).then(() => true).catch(() => false); +}; \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 00000000..cc092021 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,7 @@ +export * from './copyFileAsync'; +export * from './existsAsync'; +export * from './mkdirAsync'; +export * from './readFileAsync'; +export * from './readdirAsync'; +export * from './unlinkAsync'; +export * from './writeFileAsync'; diff --git a/src/utils/mkdirAsync.ts b/src/utils/mkdirAsync.ts new file mode 100644 index 00000000..6c52bbcf --- /dev/null +++ b/src/utils/mkdirAsync.ts @@ -0,0 +1,4 @@ +import { promisify } from "util"; +import { mkdir as mkdirCb } from "fs"; + +export const mkdirAsync = promisify(mkdirCb); \ No newline at end of file diff --git a/src/utils/readFileAsync.ts b/src/utils/readFileAsync.ts new file mode 100644 index 00000000..3f4ba8cb --- /dev/null +++ b/src/utils/readFileAsync.ts @@ -0,0 +1,4 @@ +import { promisify } from "util"; +import { readFile as readFileCb } from "fs"; + +export const readFileAsync = promisify(readFileCb); \ No newline at end of file diff --git a/src/utils/readdirAsync.ts b/src/utils/readdirAsync.ts new file mode 100644 index 00000000..82fd807c --- /dev/null +++ b/src/utils/readdirAsync.ts @@ -0,0 +1,4 @@ +import { promisify } from "util"; +import { readdir as readdirCb } from "fs"; + +export const readdirAsync = promisify(readdirCb); \ No newline at end of file diff --git a/src/utils/unlinkAsync.ts b/src/utils/unlinkAsync.ts new file mode 100644 index 00000000..46d8d917 --- /dev/null +++ b/src/utils/unlinkAsync.ts @@ -0,0 +1,4 @@ +import { promisify } from "util"; +import { unlink as unlinkCb } from "fs"; + +export const unlinkAsync = promisify(unlinkCb); \ No newline at end of file diff --git a/src/utils/writeFileAsync.ts b/src/utils/writeFileAsync.ts new file mode 100644 index 00000000..6250fdd3 --- /dev/null +++ b/src/utils/writeFileAsync.ts @@ -0,0 +1,4 @@ +import { promisify } from "util"; +import { writeFile as writeFileCb } from "fs"; + +export const writeFileAsync = promisify(writeFileCb); \ No newline at end of file