From 628782432a92620cd1786a6b0c56bb71a03f08bd Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 14 Apr 2023 15:53:16 +0200 Subject: [PATCH] #558 - Moved taxonomy to its own database file --- CHANGELOG.md | 1 + package-lock.json | 44 +++---- package.json | 4 +- src/commands/Article.ts | 4 +- src/commands/Dashboard.ts | 3 + src/commands/Settings.ts | 26 ++-- src/constants/LocalStore.ts | 3 +- src/helpers/DashboardSettings.ts | 5 +- src/helpers/Extension.ts | 26 +++- src/helpers/MediaLibrary.ts | 28 ++-- src/helpers/PanelSettings.ts | 13 +- src/helpers/SettingsHelper.ts | 55 ++++---- src/helpers/TaxonomyHelper.ts | 135 +++++++++++++++++++- src/listeners/dashboard/PagesListener.ts | 36 +++--- src/listeners/dashboard/TaxonomyListener.ts | 19 +-- src/listeners/panel/TaxonomyListener.ts | 12 +- src/services/PagesParser.ts | 15 ++- src/services/SponsorAI.ts | 13 +- 18 files changed, 282 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01d23f64..6c3a3bdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - [#566](https://github.com/estruyf/vscode-front-matter/issues/566): Keep the panel context on the live preview - [#568](https://github.com/estruyf/vscode-front-matter/issues/568): Update the preview URL if the slug changes +- [#558](https://github.com/estruyf/vscode-front-matter/issues/558): Moved the tags and categories to a `.frontmatter/database/taxonomyDb.json` file ### ⚡️ Optimizations diff --git a/package-lock.json b/package-lock.json index c96cbe99..f7ef8993 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,7 +69,7 @@ "mocha": "^10.0.0", "mustache": "^4.2.0", "node-fetch": "^2.6.9", - "node-json-db": "^1.3.0", + "node-json-db": "^2.2.0", "npm-run-all": "^4.1.5", "path-browserify": "^1.0.1", "postcss": "^8.4.21", @@ -7839,22 +7839,12 @@ } }, "node_modules/node-json-db": { - "version": "1.3.0", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-json-db/-/node-json-db-2.2.0.tgz", + "integrity": "sha512-GBuXPjItZ+XivMxR7bhSjVeXKiHZKRN/HbvqrwVemV6V5atcnIIZbg2J2vJHE6RYHydtPCJoUy05YaK4wQO0TA==", "dev": true, - "license": "MIT", "dependencies": { - "mkdirp": "~1.0.4" - } - }, - "node_modules/node-json-db/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" + "rwlock": "^5.0.0" } }, "node_modules/node-releases": { @@ -10315,6 +10305,12 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rwlock": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rwlock/-/rwlock-5.0.0.tgz", + "integrity": "sha512-XgzRqLMfCcm9QfZuPav9cV3Xin5TRcIlp4X/SH3CvB+x5D2AakdlEepfJKDd8ByncvfpcxNWdRZVUl38PS6ZJg==", + "dev": true + }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -18173,16 +18169,12 @@ "dev": true }, "node-json-db": { - "version": "1.3.0", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-json-db/-/node-json-db-2.2.0.tgz", + "integrity": "sha512-GBuXPjItZ+XivMxR7bhSjVeXKiHZKRN/HbvqrwVemV6V5atcnIIZbg2J2vJHE6RYHydtPCJoUy05YaK4wQO0TA==", "dev": true, "requires": { - "mkdirp": "~1.0.4" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "dev": true - } + "rwlock": "^5.0.0" } }, "node-releases": { @@ -19806,6 +19798,12 @@ "queue-microtask": "^1.2.2" } }, + "rwlock": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rwlock/-/rwlock-5.0.0.tgz", + "integrity": "sha512-XgzRqLMfCcm9QfZuPav9cV3Xin5TRcIlp4X/SH3CvB+x5D2AakdlEepfJKDd8ByncvfpcxNWdRZVUl38PS6ZJg==", + "dev": true + }, "sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", diff --git a/package.json b/package.json index 55c97a41..1904fc9c 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Front Matter CMS", "description": "Front Matter is a CMS that runs within Visual Studio Code. It gives you the power and control of a full-blown CMS while also providing you the flexibility and speed of the static site generator of your choice like: Hugo, Jekyll, Docusaurus, NextJs, Gatsby, and many more...", "icon": "assets/frontmatter-teal-128x128.png", - "version": "8.4.0", + "version": "8.5.0", "preview": false, "publisher": "eliostruyf", "galleryBanner": { @@ -2387,7 +2387,7 @@ "mocha": "^10.0.0", "mustache": "^4.2.0", "node-fetch": "^2.6.9", - "node-json-db": "^1.3.0", + "node-json-db": "^2.2.0", "npm-run-all": "^4.1.5", "path-browserify": "^1.0.1", "postcss": "^8.4.21", diff --git a/src/commands/Article.ts b/src/commands/Article.ts index 1e36403f..8d03c1d7 100644 --- a/src/commands/Article.ts +++ b/src/commands/Article.ts @@ -15,7 +15,7 @@ import { import * as vscode from 'vscode'; import { CustomPlaceholder, Field, TaxonomyType } from '../models'; import { format } from 'date-fns'; -import { ArticleHelper, Settings, SlugHelper } from '../helpers'; +import { ArticleHelper, Settings, SlugHelper, TaxonomyHelper } from '../helpers'; import { Notifications } from '../helpers/Notifications'; import { extname, basename, parse, dirname } from 'path'; import { COMMAND_NAME, DefaultFields } from '../constants'; @@ -66,7 +66,7 @@ export class Article { } // Add all the known options to the selection list - const crntOptions = Settings.getTaxonomy(type); + const crntOptions = (await TaxonomyHelper.get(type)) || []; if (crntOptions && crntOptions.length > 0) { for (const crntOpt of crntOptions) { if (!options.find((o) => o.label === crntOpt)) { diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts index 218eff00..04212bfc 100644 --- a/src/commands/Dashboard.ts +++ b/src/commands/Dashboard.ts @@ -186,6 +186,9 @@ export class Dashboard { * @returns The webview */ public static getWebview() { + if (Dashboard.isDisposed) { + return undefined; + } return Dashboard.webview?.webview; } diff --git a/src/commands/Settings.ts b/src/commands/Settings.ts index 24be7cf0..5190bd5c 100644 --- a/src/commands/Settings.ts +++ b/src/commands/Settings.ts @@ -1,8 +1,8 @@ import { TaxonomyHelper } from './../helpers/TaxonomyHelper'; import * as vscode from 'vscode'; import { TaxonomyType } from '../models'; -import { SETTING_TAXONOMY_TAGS, SETTING_TAXONOMY_CATEGORIES, EXTENSION_NAME } from '../constants'; -import { ArticleHelper, Settings as SettingsHelper, FilesHelper } from '../helpers'; +import { EXTENSION_NAME } from '../constants'; +import { ArticleHelper, FilesHelper } from '../helpers'; import { FrontMatterParser } from '../parsers'; import { Notifications } from '../helpers/Notifications'; @@ -22,12 +22,7 @@ export class Settings { }); if (newOption) { - const configSetting = - type === TaxonomyType.Tag ? SETTING_TAXONOMY_TAGS : SETTING_TAXONOMY_CATEGORIES; - let options = SettingsHelper.get(configSetting, true) as string[]; - if (!options) { - options = []; - } + let options = (await TaxonomyHelper.get(type)) || []; if (options.find((o) => o === newOption)) { Notifications.info( @@ -37,7 +32,7 @@ export class Settings { } options.push(newOption); - await SettingsHelper.updateTaxonomy(type, options); + TaxonomyHelper.update(type, options); // Ask if the new term needs to be added to the page const addToPage = await vscode.window.showQuickPick(['yes', 'no'], { @@ -128,7 +123,7 @@ export class Settings { } // Retrieve the currently known tags, and add the new ones - let crntTags: string[] = SettingsHelper.get(SETTING_TAXONOMY_TAGS, true) as string[]; + let crntTags: string[] = (await TaxonomyHelper.get(TaxonomyType.Tag)) || []; if (!crntTags) { crntTags = []; } @@ -136,13 +131,10 @@ export class Settings { // Update the tags and filter out the duplicates crntTags = [...new Set(crntTags)]; crntTags = crntTags.sort().filter((t) => !!t); - await SettingsHelper.update(SETTING_TAXONOMY_TAGS, crntTags, true); + TaxonomyHelper.update(TaxonomyType.Tag, crntTags); // Retrieve the currently known tags, and add the new ones - let crntCategories: string[] = SettingsHelper.get( - SETTING_TAXONOMY_CATEGORIES, - true - ) as string[]; + let crntCategories: string[] = (await TaxonomyHelper.get(TaxonomyType.Category)) || []; if (!crntCategories) { crntCategories = []; } @@ -150,7 +142,7 @@ export class Settings { // Update the categories and filter out the duplicates crntCategories = [...new Set(crntCategories)]; crntCategories = crntCategories.sort().filter((c) => !!c); - await SettingsHelper.update(SETTING_TAXONOMY_CATEGORIES, crntCategories, true); + TaxonomyHelper.update(TaxonomyType.Category, crntCategories); // Done Notifications.info( @@ -176,7 +168,7 @@ export class Settings { } const type = taxType === 'Tag' ? TaxonomyType.Tag : TaxonomyType.Category; - const options = SettingsHelper.getTaxonomy(type); + const options = (await TaxonomyHelper.get(type)) || []; if (!options || options.length === 0) { Notifications.info(`No ${type === TaxonomyType.Tag ? 'tags' : 'categories'} configured.`); diff --git a/src/constants/LocalStore.ts b/src/constants/LocalStore.ts index 01f81aec..e3ecc86c 100644 --- a/src/constants/LocalStore.ts +++ b/src/constants/LocalStore.ts @@ -3,5 +3,6 @@ export const LocalStore = { contentFolder: 'content', databaseFolder: 'database', templatesFolder: 'templates', - mediaDatabaseFile: 'mediaDb.json' + mediaDatabaseFile: 'mediaDb.json', + taxonomyDatabaseFile: 'taxonomyDb.json' }; diff --git a/src/helpers/DashboardSettings.ts b/src/helpers/DashboardSettings.ts index 83299da5..7e1ca42c 100644 --- a/src/helpers/DashboardSettings.ts +++ b/src/helpers/DashboardSettings.ts @@ -39,6 +39,7 @@ import { Extension } from './Extension'; import { FrameworkDetector } from './FrameworkDetector'; import { Settings } from './SettingsHelper'; import { parseWinPath } from './parseWinPath'; +import { TaxonomyHelper } from './TaxonomyHelper'; export class DashboardSettings { private static cachedSettings: ISettings | undefined = undefined; @@ -69,8 +70,8 @@ export class DashboardSettings { wsFolder: wsFolder ? wsFolder.fsPath : '', staticFolder: Folders.getStaticFolderRelativePath(), initialized: isInitialized, - tags: Settings.getTaxonomy(TaxonomyType.Tag), - categories: Settings.getTaxonomy(TaxonomyType.Category), + tags: (await TaxonomyHelper.get(TaxonomyType.Tag)) || [], + categories: (await TaxonomyHelper.get(TaxonomyType.Category)) || [], customTaxonomy: Settings.get(SETTING_TAXONOMY_CUSTOM, true) || [], openOnStart: Settings.get(SETTING_DASHBOARD_OPENONSTART), versionInfo: ext.getVersion(), diff --git a/src/helpers/Extension.ts b/src/helpers/Extension.ts index 0f8ba7fd..5e061486 100644 --- a/src/helpers/Extension.ts +++ b/src/helpers/Extension.ts @@ -24,11 +24,14 @@ import { SETTING_CONTENT_PAGE_FOLDERS, SETTING_DASHBOARD_MEDIA_SNIPPET, SETTING_CONTENT_SNIPPETS, - SETTING_TEMPLATES_ENABLED + SETTING_TEMPLATES_ENABLED, + SETTING_TAXONOMY_TAGS, + SETTING_TAXONOMY_CATEGORIES } from '../constants'; -import { ContentFolder, Snippet } from '../models'; +import { ContentFolder, Snippet, TaxonomyType } from '../models'; import { Notifications } from './Notifications'; import { Settings } from './SettingsHelper'; +import { TaxonomyHelper } from './TaxonomyHelper'; export class Extension { private static instance: Extension; @@ -297,6 +300,25 @@ export class Extension { ); } } + + // The tags and categories settings need to be moved to the database + const tags = Settings.get(SETTING_TAXONOMY_TAGS) || []; + const categories = Settings.get(SETTING_TAXONOMY_CATEGORIES) || []; + + if (tags.length > 0 || categories.length > 0) { + const tagsFromDb = (await TaxonomyHelper.get(TaxonomyType.Tag)) || []; + const categoriesFromDb = (await TaxonomyHelper.get(TaxonomyType.Category)) || []; + + if (tagsFromDb.length === 0) { + await TaxonomyHelper.update(TaxonomyType.Tag, tags); + await Settings.remove(SETTING_TAXONOMY_TAGS); + } + + if (categoriesFromDb.length === 0) { + await TaxonomyHelper.update(TaxonomyType.Category, categories); + await Settings.remove(SETTING_TAXONOMY_CATEGORIES); + } + } } public async setState( diff --git a/src/helpers/MediaLibrary.ts b/src/helpers/MediaLibrary.ts index c9535389..663984c2 100644 --- a/src/helpers/MediaLibrary.ts +++ b/src/helpers/MediaLibrary.ts @@ -1,6 +1,6 @@ import { MediaHelpers } from './MediaHelpers'; import { workspace } from 'vscode'; -import { JsonDB } from 'node-json-db/dist/JsonDB'; +import { Config, JsonDB } from 'node-json-db'; import { basename, dirname, join, parse } from 'path'; import { Folders, WORKSPACE_PLACEHOLDER } from '../commands/Folders'; import { Notifications } from './Notifications'; @@ -52,15 +52,17 @@ export class MediaLibrary { } this.db = new JsonDB( - join( - parseWinPath(wsFolder?.fsPath || ''), - LocalStore.rootFolder, - LocalStore.databaseFolder, - LocalStore.mediaDatabaseFile - ), - true, - false, - '/' + new Config( + join( + parseWinPath(wsFolder?.fsPath || ''), + LocalStore.rootFolder, + LocalStore.databaseFolder, + LocalStore.mediaDatabaseFile + ), + true, + false, + '/' + ) ); workspace.onDidRenameFiles((e) => { @@ -88,11 +90,11 @@ export class MediaLibrary { return MediaLibrary.instance; } - public get(id: string): MediaRecord | undefined { + public async get(id: string): Promise { try { const fileId = this.parsePath(id); - if (this.db?.exists(fileId)) { - return this.db.getData(fileId); + if (await this.db?.exists(fileId)) { + return await this.db?.getData(fileId); } return undefined; } catch { diff --git a/src/helpers/PanelSettings.ts b/src/helpers/PanelSettings.ts index 180a162b..27467266 100644 --- a/src/helpers/PanelSettings.ts +++ b/src/helpers/PanelSettings.ts @@ -1,6 +1,6 @@ import { SETTING_SPONSORS_AI_ENABLED } from './../constants/settings'; import { workspace } from 'vscode'; -import { Extension, Settings } from '.'; +import { Extension, Settings, TaxonomyHelper } from '.'; import { Dashboard } from '../commands/Dashboard'; import { Preview } from '../commands/Preview'; import { Project } from '../commands/Project'; @@ -25,11 +25,9 @@ import { SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_SLUG_UPDATE_FILE_NAME, - SETTING_TAXONOMY_CATEGORIES, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_TAXONOMY_CUSTOM, SETTING_TAXONOMY_FIELD_GROUPS, - SETTING_TAXONOMY_TAGS, SETTING_GIT_ENABLED, SETTING_SEO_TITLE_FIELD } from '../constants'; @@ -40,15 +38,14 @@ import { DraftField, FieldGroup, PanelSettings as IPanelSettings, - ScriptType + ScriptType, + TaxonomyType } from '../models'; export class PanelSettings { public static async get(): Promise { const gitActions = Settings.get(SETTING_GIT_ENABLED); - const aiEnabled = Settings.get(SETTING_SPONSORS_AI_ENABLED); - return { aiEnabled: Settings.get(SETTING_SPONSORS_AI_ENABLED) || false, git: { @@ -72,8 +69,8 @@ export class PanelSettings { date: { format: Settings.get(SETTING_DATE_FORMAT) || '' }, - tags: Settings.get(SETTING_TAXONOMY_TAGS, true) || [], - categories: Settings.get(SETTING_TAXONOMY_CATEGORIES, true) || [], + tags: (await TaxonomyHelper.get(TaxonomyType.Tag)) || [], + categories: (await TaxonomyHelper.get(TaxonomyType.Category)) || [], customTaxonomy: Settings.get(SETTING_TAXONOMY_CUSTOM, true) || [], freeform: Settings.get(SETTING_PANEL_FREEFORM), scripts: (Settings.get(SETTING_CUSTOM_SCRIPTS) || []).filter( diff --git a/src/helpers/SettingsHelper.ts b/src/helpers/SettingsHelper.ts index 42c23e49..34689607 100644 --- a/src/helpers/SettingsHelper.ts +++ b/src/helpers/SettingsHelper.ts @@ -321,6 +321,31 @@ export class Settings { await Settings.config.update(name, value); } + public static async remove(name: string) { + const fmConfig = Settings.projectConfigPath; + + if (fmConfig && (await existsAsync(fmConfig))) { + const localConfig = await readFileAsync(fmConfig, 'utf8'); + Settings.globalConfig = jsoncParser.parse(localConfig); + delete Settings.globalConfig[`${CONFIG_KEY}.${name}`]; + + const content = JSON.stringify(Settings.globalConfig, null, 2); + await writeFileAsync(fmConfig, content, 'utf8'); + + const workspaceSettingValue = Settings.hasWorkspaceSettings(name); + if (workspaceSettingValue) { + await Settings.update(name, undefined); + } + + // Make sure to reload the whole config + all the data files + await Settings.readConfig(); + + return; + } + + await Settings.config.update(name, undefined); + } + /** * Checks if the project contains the frontmatter.json file */ @@ -357,22 +382,6 @@ export class Settings { } } - /** - * Return the taxonomy settings - * - * @param type - */ - public static getTaxonomy(type: TaxonomyType): string[] { - // Add all the known options to the selection list - const configSetting = - type === TaxonomyType.Tag ? SETTING_TAXONOMY_TAGS : SETTING_TAXONOMY_CATEGORIES; - const crntOptions = Settings.get(configSetting, true) as string[]; - if (crntOptions && crntOptions.length > 0) { - return crntOptions; - } - return []; - } - /** * Return the taxonomy settings * @@ -386,20 +395,6 @@ export class Settings { return []; } - /** - * Update the taxonomy settings - * - * @param type - * @param options - */ - public static async updateTaxonomy(type: TaxonomyType, options: string[]) { - const configSetting = - type === TaxonomyType.Tag ? SETTING_TAXONOMY_TAGS : SETTING_TAXONOMY_CATEGORIES; - options = [...new Set(options)]; - options = options.sort().filter((o) => !!o); - await Settings.update(configSetting, options, true); - } - /** * Update the custom taxonomy settings * diff --git a/src/helpers/TaxonomyHelper.ts b/src/helpers/TaxonomyHelper.ts index 7c0a64bb..2422ba33 100644 --- a/src/helpers/TaxonomyHelper.ts +++ b/src/helpers/TaxonomyHelper.ts @@ -1,5 +1,11 @@ import { getTaxonomyField } from './getTaxonomyField'; -import { EXTENSION_NAME, SETTING_TAXONOMY_CUSTOM } from '../constants'; +import { + EXTENSION_NAME, + LocalStore, + SETTING_TAXONOMY_CATEGORIES, + SETTING_TAXONOMY_CUSTOM, + SETTING_TAXONOMY_TAGS +} from '../constants'; import { CustomTaxonomy, TaxonomyType, ContentType as IContentType } from '../models'; import { FilesHelper } from './FilesHelper'; import { ProgressLocation, window } from 'vscode'; @@ -11,8 +17,101 @@ import { Notifications } from './Notifications'; import { ArticleHelper } from './ArticleHelper'; import { ContentType } from './ContentType'; import { readFileAsync, writeFileAsync } from '../utils'; +import { Config, JsonDB } from 'node-json-db'; +import { Folders } from '../commands'; +import { join } from 'path'; +import { SettingsListener as PanelSettingsListener } from '../listeners/panel'; +import { SettingsListener as DashboardSettingsListener } from '../listeners/dashboard'; export class TaxonomyHelper { + private static db: JsonDB; + + /** + * Get all the taxonomy values + */ + public static async getAll() { + if (!this.db) { + const db = this.initDb(); + if (!db) { + return; + } + + this.db = db; + } + + const taxonomyData = { + tags: (await TaxonomyHelper.get(TaxonomyType.Tag)) || [], + categories: (await TaxonomyHelper.get(TaxonomyType.Category)) || [], + customTaxonomy: Settings.get(SETTING_TAXONOMY_CUSTOM) || [] + }; + + return taxonomyData; + } + + /** + * Get the taxonomy settings + * + * @param type + * @param options + */ + public static async get(type: TaxonomyType): Promise { + if (!this.db) { + const db = this.initDb(); + if (!db) { + return; + } + + this.db = db; + } + + const tagType = TaxonomyHelper.getTaxonomyDbPath(type); + + let taxonomy: string[] = []; + if (await this.db.exists(tagType)) { + taxonomy = await this.db.getObject(tagType); + } + return taxonomy; + } + + /** + * Update the taxonomy settings + * + * @param type + * @param options + */ + public static async update(type: TaxonomyType, options: string[]) { + if (!this.db) { + const db = this.initDb(); + if (!db) { + return; + } + + this.db = db; + } + + const tagType = TaxonomyHelper.getTaxonomyDbPath(type); + + options = [...new Set(options)]; + options = options.sort().filter((o) => !!o); + + await this.db.push(tagType, options, true); + + // Trigger the update of the taxonomy + PanelSettingsListener.getSettings(); + DashboardSettingsListener.getSettings(true); + } + + /** + * Get the Taxonomy path of the db entry + * @param type + * @returns + */ + public static getTaxonomyDbPath(type: TaxonomyType) { + let tagType = type === TaxonomyType.Tag ? SETTING_TAXONOMY_TAGS : SETTING_TAXONOMY_CATEGORIES; + tagType = tagType.replace('.', '/'); + return `/${tagType}`; + } + /** * Rename an taxonomy value * @param data @@ -56,7 +155,7 @@ export class TaxonomyHelper { let options = []; if (taxonomyType === TaxonomyType.Tag || taxonomyType === TaxonomyType.Category) { - options = Settings.getTaxonomy(taxonomyType); + options = (await TaxonomyHelper.get(taxonomyType)) || []; } else { options = Settings.getCustomTaxonomy(taxonomyType); } @@ -114,7 +213,7 @@ export class TaxonomyHelper { const { type } = data; const taxonomyType = this.getTypeFromString(type); - const options = this.getTaxonomyOptions(taxonomyType); + const options = await this.getTaxonomyOptions(taxonomyType); const newOption = await window.showInputBox({ title: `Create a new ${type} value`, @@ -366,6 +465,28 @@ export class TaxonomyHelper { ); } + /** + * Initialize the database + * @returns + */ + private static initDb() { + const wsFolder = Folders.getWorkspaceFolder(); + if (!wsFolder) { + return; + } + + const dbFolder = join( + parseWinPath(wsFolder?.fsPath || ''), + LocalStore.rootFolder, + LocalStore.databaseFolder + ); + const dbPath = join(dbFolder, LocalStore.taxonomyDatabaseFile); + + const db = new JsonDB(new Config(dbPath, true, false, '/')); + + return db; + } + /** * Retrieve the fields for the taxonomy field * @returns @@ -413,7 +534,7 @@ export class TaxonomyHelper { newValue?: string ) { // Update the settings - let options = this.getTaxonomyOptions(taxonomyType); + let options = await this.getTaxonomyOptions(taxonomyType); const idx = options.findIndex((o) => o === oldValue); if (newValue) { @@ -429,7 +550,7 @@ export class TaxonomyHelper { } if (taxonomyType === TaxonomyType.Tag || taxonomyType === TaxonomyType.Category) { - await Settings.updateTaxonomy(taxonomyType, options); + TaxonomyHelper.update(taxonomyType, options); } else { await Settings.updateCustomTaxonomyOptions(taxonomyType, options); } @@ -440,11 +561,11 @@ export class TaxonomyHelper { * @param taxonomyType * @returns */ - private static getTaxonomyOptions(taxonomyType: TaxonomyType | string) { + private static async getTaxonomyOptions(taxonomyType: TaxonomyType | string) { let options = []; if (taxonomyType === TaxonomyType.Tag || taxonomyType === TaxonomyType.Category) { - options = Settings.getTaxonomy(taxonomyType); + options = (await TaxonomyHelper.get(taxonomyType)) || []; } else { options = Settings.getCustomTaxonomy(taxonomyType); } diff --git a/src/listeners/dashboard/PagesListener.ts b/src/listeners/dashboard/PagesListener.ts index 408dd905..3f123085 100644 --- a/src/listeners/dashboard/PagesListener.ts +++ b/src/listeners/dashboard/PagesListener.ts @@ -125,28 +125,28 @@ export class PagesListener extends BaseListener { * @param file */ private static async watcherExec(file: Uri) { - if (Dashboard.isOpen) { - const ext = Extension.getInstance(); - Logger.info(`File watcher execution for: ${file.fsPath}`); + const ext = Extension.getInstance(); + Logger.info(`File watcher execution for: ${file.fsPath}`); - const pageIdx = this.lastPages.findIndex((p) => p.fmFilePath === file.fsPath); - if (pageIdx !== -1) { - const stats = await workspace.fs.stat(file); - const crntPage = this.lastPages[pageIdx]; - const updatedPage = await PagesParser.processPageContent( - file.fsPath, - stats.mtime, - basename(file.fsPath), - crntPage.fmFolder - ); - if (updatedPage) { - this.lastPages[pageIdx] = updatedPage; + const pageIdx = this.lastPages.findIndex((p) => p.fmFilePath === file.fsPath); + if (pageIdx !== -1) { + const stats = await workspace.fs.stat(file); + const crntPage = this.lastPages[pageIdx]; + const updatedPage = await PagesParser.processPageContent( + file.fsPath, + stats.mtime, + basename(file.fsPath), + crntPage.fmFolder + ); + if (updatedPage) { + this.lastPages[pageIdx] = updatedPage; + if (Dashboard.isOpen) { this.sendPageData(this.lastPages); - await ext.setState(ExtensionState.Dashboard.Pages.Cache, this.lastPages, 'workspace'); } - } else { - this.getPagesData(true); + await ext.setState(ExtensionState.Dashboard.Pages.Cache, this.lastPages, 'workspace'); } + } else { + this.getPagesData(true); } } diff --git a/src/listeners/dashboard/TaxonomyListener.ts b/src/listeners/dashboard/TaxonomyListener.ts index 2a9e4e22..5df365a7 100644 --- a/src/listeners/dashboard/TaxonomyListener.ts +++ b/src/listeners/dashboard/TaxonomyListener.ts @@ -1,14 +1,9 @@ import { commands } from 'vscode'; -import { - COMMAND_NAME, - SETTING_TAXONOMY_CATEGORIES, - SETTING_TAXONOMY_CUSTOM, - SETTING_TAXONOMY_TAGS -} from '../../constants'; +import { COMMAND_NAME } from '../../constants'; import { DashboardCommand } from '../../dashboardWebView/DashboardCommand'; import { DashboardMessage } from '../../dashboardWebView/DashboardMessage'; -import { Settings, TaxonomyHelper } from '../../helpers'; -import { CustomTaxonomy, PostMessageData } from '../../models'; +import { TaxonomyHelper } from '../../helpers'; +import { PostMessageData } from '../../models'; import { BaseListener } from './BaseListener'; export class TaxonomyListener extends BaseListener { @@ -47,13 +42,9 @@ export class TaxonomyListener extends BaseListener { } } - private static async getData() { + private static getData() { // Retrieve the tags, categories and custom taxonomy - const taxonomyData = { - tags: Settings.get(SETTING_TAXONOMY_TAGS) || [], - categories: Settings.get(SETTING_TAXONOMY_CATEGORIES) || [], - customTaxonomy: Settings.get(SETTING_TAXONOMY_CUSTOM) || [] - }; + const taxonomyData = TaxonomyHelper.getAll(); this.sendMsg(DashboardCommand.setTaxonomyData, taxonomyData); } diff --git a/src/listeners/panel/TaxonomyListener.ts b/src/listeners/panel/TaxonomyListener.ts index 549a207b..208a6268 100644 --- a/src/listeners/panel/TaxonomyListener.ts +++ b/src/listeners/panel/TaxonomyListener.ts @@ -2,15 +2,13 @@ import { CommandToCode } from '../../panelWebView/CommandToCode'; import { TagType } from '../../panelWebView/TagType'; import { BaseListener } from './BaseListener'; import { authentication, window } from 'vscode'; -import { ArticleHelper, Extension, Settings } from '../../helpers'; +import { ArticleHelper, Extension, Settings, TaxonomyHelper } from '../../helpers'; import { BlockFieldData, CustomTaxonomyData, PostMessageData, TaxonomyType } from '../../models'; import { DataListener } from '.'; import { DefaultFields, SETTING_SEO_DESCRIPTION_FIELD, - SETTING_SEO_TITLE_FIELD, - SETTING_TAXONOMY_CATEGORIES, - SETTING_TAXONOMY_TAGS + SETTING_SEO_TITLE_FIELD } from '../../constants'; import { SponsorAi } from '../../services/SponsorAI'; import { ExplorerView } from '../../explorerView/ExplorerView'; @@ -202,8 +200,8 @@ export class TaxonomyListener extends BaseListener { if (value) { let options = tagType === TagType.tags - ? Settings.get(SETTING_TAXONOMY_TAGS, true) - : Settings.get(SETTING_TAXONOMY_CATEGORIES, true); + ? await TaxonomyHelper.get(TaxonomyType.Tag) + : await TaxonomyHelper.get(TaxonomyType.Category); if (!options) { options = []; @@ -211,7 +209,7 @@ export class TaxonomyListener extends BaseListener { options.push(value); const taxType = tagType === TagType.tags ? TaxonomyType.Tag : TaxonomyType.Category; - await Settings.updateTaxonomy(taxType, options); + TaxonomyHelper.update(taxType, options); } } } diff --git a/src/services/PagesParser.ts b/src/services/PagesParser.ts index 1355d8c6..383e5709 100644 --- a/src/services/PagesParser.ts +++ b/src/services/PagesParser.ts @@ -1,7 +1,7 @@ import { STATIC_FOLDER_PLACEHOLDER } from './../constants/StaticFolderPlaceholder'; import { parseWinPath } from './../helpers/parseWinPath'; import { dirname, extname, join } from 'path'; -import { StatusBarAlignment, Uri, window } from 'vscode'; +import { StatusBarAlignment, Uri, window, Webview } from 'vscode'; import { Dashboard } from '../commands/Dashboard'; import { Folders } from '../commands/Folders'; import { @@ -307,13 +307,16 @@ export class PagesParser { } if (previewUri) { - let previewPath = Dashboard.getWebview()?.asWebviewUri(previewUri); + let previewPath: string = ''; - if (!previewPath) { - previewPath = PagesParser.getWebviewUri(previewUri); + const Webview = Dashboard.getWebview(); + if (Webview) { + previewPath = Webview.asWebviewUri(previewUri).toString(); + } else { + previewPath = PagesParser.getWebviewUri(previewUri).toString(); } - page['fmPreviewImage'] = previewPath?.toString() || ''; + page['fmPreviewImage'] = previewPath || ''; } } } @@ -342,7 +345,7 @@ export class PagesParser { return Uri.from({ scheme: 'https', authority, - path: resource.path, + path: parseWinPath(resource.path), query: resource.query, fragment: resource.fragment }); diff --git a/src/services/SponsorAI.ts b/src/services/SponsorAI.ts index 7c2f8ba8..0c915d37 100644 --- a/src/services/SponsorAI.ts +++ b/src/services/SponsorAI.ts @@ -1,11 +1,8 @@ -import { - SETTING_SEO_TITLE_LENGTH, - SETTING_TAXONOMY_CATEGORIES, - SETTING_TAXONOMY_TAGS -} from '../constants'; -import { Logger, Notifications, Settings } from '../helpers'; +import { SETTING_SEO_TITLE_LENGTH } from '../constants'; +import { Logger, Notifications, Settings, TaxonomyHelper } from '../helpers'; import fetch from 'node-fetch'; import { TagType } from '../panelWebView/TagType'; +import { TaxonomyType } from '../models'; const AI_URL = 'https://frontmatter.codes/api/ai'; // const AI_URL = 'http://localhost:3000/api/ai'; @@ -74,8 +71,8 @@ export class SponsorAi { let options = type === TagType.tags - ? Settings.get(SETTING_TAXONOMY_TAGS, true) - : Settings.get(SETTING_TAXONOMY_CATEGORIES, true); + ? await TaxonomyHelper.get(TaxonomyType.Tag) + : await TaxonomyHelper.get(TaxonomyType.Category); const optionsString = options?.join(',') || ''; const body = JSON.stringify({