mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-08-08 18:03:17 +02:00
#558 - Moved taxonomy to its own database file
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Generated
+21
-23
@@ -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",
|
||||
|
||||
+2
-2
@@ -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",
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -186,6 +186,9 @@ export class Dashboard {
|
||||
* @returns The webview
|
||||
*/
|
||||
public static getWebview() {
|
||||
if (Dashboard.isDisposed) {
|
||||
return undefined;
|
||||
}
|
||||
return Dashboard.webview?.webview;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.`);
|
||||
|
||||
@@ -3,5 +3,6 @@ export const LocalStore = {
|
||||
contentFolder: 'content',
|
||||
databaseFolder: 'database',
|
||||
templatesFolder: 'templates',
|
||||
mediaDatabaseFile: 'mediaDb.json'
|
||||
mediaDatabaseFile: 'mediaDb.json',
|
||||
taxonomyDatabaseFile: 'taxonomyDb.json'
|
||||
};
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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<string[]>(SETTING_TAXONOMY_TAGS) || [];
|
||||
const categories = Settings.get<string[]>(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<T>(
|
||||
|
||||
+15
-13
@@ -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<MediaRecord | undefined> {
|
||||
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 {
|
||||
|
||||
@@ -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<IPanelSettings> {
|
||||
const gitActions = Settings.get<boolean>(SETTING_GIT_ENABLED);
|
||||
|
||||
const aiEnabled = Settings.get<boolean>(SETTING_SPONSORS_AI_ENABLED);
|
||||
|
||||
return {
|
||||
aiEnabled: Settings.get<boolean>(SETTING_SPONSORS_AI_ENABLED) || false,
|
||||
git: {
|
||||
@@ -72,8 +69,8 @@ export class PanelSettings {
|
||||
date: {
|
||||
format: Settings.get<string>(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<CustomScript[]>(SETTING_CUSTOM_SCRIPTS) || []).filter(
|
||||
|
||||
@@ -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<ContentType[]>(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
|
||||
*
|
||||
|
||||
@@ -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<CustomTaxonomy[]>(SETTING_TAXONOMY_CUSTOM) || []
|
||||
};
|
||||
|
||||
return taxonomyData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the taxonomy settings
|
||||
*
|
||||
* @param type
|
||||
* @param options
|
||||
*/
|
||||
public static async get(type: TaxonomyType): Promise<string[] | undefined> {
|
||||
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<string[]>(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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<string[]>(SETTING_TAXONOMY_TAGS) || [],
|
||||
categories: Settings.get<string[]>(SETTING_TAXONOMY_CATEGORIES) || [],
|
||||
customTaxonomy: Settings.get<CustomTaxonomy[]>(SETTING_TAXONOMY_CUSTOM) || []
|
||||
};
|
||||
const taxonomyData = TaxonomyHelper.getAll();
|
||||
|
||||
this.sendMsg(DashboardCommand.setTaxonomyData, taxonomyData);
|
||||
}
|
||||
|
||||
@@ -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<string[]>(SETTING_TAXONOMY_TAGS, true)
|
||||
: Settings.get<string[]>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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<string[]>(SETTING_TAXONOMY_TAGS, true)
|
||||
: Settings.get<string[]>(SETTING_TAXONOMY_CATEGORIES, true);
|
||||
? await TaxonomyHelper.get(TaxonomyType.Tag)
|
||||
: await TaxonomyHelper.get(TaxonomyType.Category);
|
||||
|
||||
const optionsString = options?.join(',') || '';
|
||||
const body = JSON.stringify({
|
||||
|
||||
Reference in New Issue
Block a user