mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-05-18 07:15:43 +02:00
281 lines
9.3 KiB
TypeScript
281 lines
9.3 KiB
TypeScript
import { basename } from "path";
|
|
import { extensions, Uri, ExtensionContext, window, workspace, commands, ExtensionMode, DiagnosticCollection, languages } from "vscode";
|
|
import { Folders } from "../commands/Folders";
|
|
import { Template } from "../commands/Template";
|
|
import { EXTENSION_NAME, GITHUB_LINK, SETTING_DATE_FIELD, SETTING_MODIFIED_FIELD, EXTENSION_BETA_ID, EXTENSION_ID, ExtensionState, CONFIG_KEY, SETTING_CONTENT_PAGE_FOLDERS, SETTING_DASHBOARD_MEDIA_SNIPPET, SETTING_CONTENT_SNIPPETS, SETTING_TEMPLATES_ENABLED } from "../constants";
|
|
import { ContentFolder, Snippet } from "../models";
|
|
import { Notifications } from "./Notifications";
|
|
import { Settings } from "./SettingsHelper";
|
|
|
|
|
|
export class Extension {
|
|
private static instance: Extension;
|
|
private _collection: DiagnosticCollection;
|
|
|
|
private constructor(private ctx: ExtensionContext) {
|
|
this._collection = languages.createDiagnosticCollection(this.title);
|
|
}
|
|
|
|
/**
|
|
* Creates the singleton instance for the panel
|
|
* @param extPath
|
|
*/
|
|
public static getInstance(ctx?: ExtensionContext): Extension {
|
|
if (!Extension.instance && ctx) {
|
|
Extension.instance = new Extension(ctx);
|
|
}
|
|
|
|
return Extension.instance;
|
|
}
|
|
|
|
/**
|
|
* Get the current version information for the extension
|
|
*/
|
|
public getVersion(): { usedVersion: string | undefined, installedVersion: string } {
|
|
const frontMatter = extensions.getExtension(this.isBetaVersion() ? EXTENSION_BETA_ID : EXTENSION_ID)!;
|
|
let installedVersion = frontMatter.packageJSON.version;
|
|
const usedVersion = this.ctx.globalState.get<string>(ExtensionState.Version);
|
|
|
|
if (this.isBetaVersion()) {
|
|
installedVersion = `${installedVersion}-beta`;
|
|
}
|
|
|
|
if (usedVersion !== installedVersion) {
|
|
const whatIsNewTitle = `Check the changelog`;
|
|
const githubTitle = `Give it a ⭐️`;
|
|
|
|
const whatIsNew = {
|
|
title: whatIsNewTitle,
|
|
run: () => {
|
|
const uri = Uri.file(`${Extension.getInstance().extensionPath.fsPath}/CHANGELOG.md`);
|
|
workspace.openTextDocument(uri).then((() => {
|
|
commands.executeCommand("markdown.showPreview", uri)
|
|
}));
|
|
}
|
|
};
|
|
|
|
const starGitHub = {
|
|
title: githubTitle,
|
|
run: () => {
|
|
commands.executeCommand('vscode.open', Uri.parse(GITHUB_LINK));
|
|
}
|
|
};
|
|
|
|
window.showInformationMessage(`${EXTENSION_NAME} has been updated to v${installedVersion} — check out what's new!`, starGitHub, whatIsNew).then((selection => {
|
|
if (selection?.title === whatIsNewTitle || selection?.title === githubTitle) {
|
|
selection.run();
|
|
}
|
|
}));
|
|
|
|
this.setVersion(installedVersion);
|
|
}
|
|
|
|
return {
|
|
usedVersion,
|
|
installedVersion
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get the title of the extension
|
|
*/
|
|
public get title(): string {
|
|
return this.ctx.extension.packageJSON.name;
|
|
}
|
|
|
|
/**
|
|
* Get the displayName of the extension
|
|
*/
|
|
public get displayName(): string {
|
|
return this.ctx.extension.packageJSON.displayName;
|
|
}
|
|
|
|
/**
|
|
* Returns the extension's version
|
|
*/
|
|
public get version(): string {
|
|
return this.ctx.extension.packageJSON.version;
|
|
}
|
|
|
|
/**
|
|
* Check if the extension is in production/development mode
|
|
*/
|
|
public get isProductionMode(): boolean {
|
|
return this.ctx.extensionMode === ExtensionMode.Production;
|
|
}
|
|
|
|
/**
|
|
* Get the diagnostic collection for the extension
|
|
*/
|
|
public get diagnosticCollection(): DiagnosticCollection {
|
|
return this._collection;
|
|
}
|
|
|
|
/**
|
|
* Get extension subscriptions
|
|
*/
|
|
public get subscriptions() {
|
|
return this.ctx.subscriptions;
|
|
}
|
|
|
|
/**
|
|
* Set the current version information for the extension
|
|
*/
|
|
public setVersion(installedVersion: string): void {
|
|
this.ctx.globalState.update(ExtensionState.Version, installedVersion);
|
|
}
|
|
|
|
/**
|
|
* Get the path to the extension
|
|
*/
|
|
public get extensionPath(): Uri {
|
|
return this.ctx.extensionUri;
|
|
}
|
|
|
|
/**
|
|
* Migrate old settings to new settings
|
|
*/
|
|
public async migrateSettings(): Promise<void> {
|
|
const versionInfo = this.getVersion();
|
|
if (versionInfo.usedVersion === undefined) {
|
|
return;
|
|
}
|
|
|
|
if (!versionInfo.usedVersion) {
|
|
return;
|
|
}
|
|
|
|
// Split semantic version
|
|
const version = versionInfo.usedVersion.split('.');
|
|
const major = parseInt(version[0]);
|
|
const minor = parseInt(version[1]);
|
|
const patch = parseInt(version[2]);
|
|
|
|
|
|
// Create team settings
|
|
if (Settings.hasSettings()) {
|
|
Settings.createTeamSettings();
|
|
}
|
|
|
|
const hideDateDeprecation = await Extension.getInstance().getState<boolean>(ExtensionState.Updates.v7_0_0.dateFields, "workspace");
|
|
if (!hideDateDeprecation) {
|
|
// Migration scripts can be written here
|
|
const publishField = Settings.inspect(SETTING_DATE_FIELD);
|
|
const modifiedField = Settings.inspect(SETTING_MODIFIED_FIELD);
|
|
|
|
// Check for extension deprecations
|
|
if (publishField?.workspaceValue ||
|
|
publishField?.globalValue ||
|
|
publishField?.teamValue ||
|
|
modifiedField?.workspaceValue ||
|
|
modifiedField?.globalValue ||
|
|
modifiedField?.teamValue) {
|
|
Notifications.warning(`The "${CONFIG_KEY}.${SETTING_DATE_FIELD}" and "${CONFIG_KEY}.${SETTING_MODIFIED_FIELD}" settings have been deprecated. Please use the "isPublishDate" and "isModifiedDate" datetime field properties instead.`, "Hide", "See migration guide").then(async (value) => {
|
|
if (value === "See migration guide") {
|
|
const isProd = this.isProductionMode;
|
|
commands.executeCommand("vscode.open", Uri.parse(`https://${isProd ? '' : 'beta.'}frontmatter.codes/docs/troubleshooting#publish-and-modified-date-migration`));
|
|
await Extension.getInstance().setState<boolean>(ExtensionState.Updates.v7_0_0.dateFields, true, "workspace");
|
|
} else if (value === "Hide") {
|
|
await Extension.getInstance().setState<boolean>(ExtensionState.Updates.v7_0_0.dateFields, true, "workspace");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
if (major < 7) {
|
|
const contentFolders: ContentFolder[] = Settings.get(SETTING_CONTENT_PAGE_FOLDERS) as ContentFolder[];
|
|
const wsFolder = Folders.getWorkspaceFolder();
|
|
if (wsFolder) {
|
|
let update = false;
|
|
|
|
for (const cFolder of contentFolders) {
|
|
if (cFolder.path.indexOf(wsFolder.fsPath) !== -1) {
|
|
update = true;
|
|
cFolder.path = Folders.relWsFolder(cFolder, wsFolder);
|
|
}
|
|
}
|
|
|
|
if (update) {
|
|
Folders.update(contentFolders);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (major <= 7 && minor < 3) {
|
|
const mediaSnippet = Settings.get<string[]>(SETTING_DASHBOARD_MEDIA_SNIPPET);
|
|
if (mediaSnippet && mediaSnippet.length > 0) {
|
|
let snippet = mediaSnippet.join(`\n`);
|
|
|
|
snippet = snippet.replace(`{mediaUrl}`, `[[&mediaUrl]]`);
|
|
snippet = snippet.replace(`{mediaHeight}`, `[[mediaHeight]]`);
|
|
snippet = snippet.replace(`{mediaWidth}`, `[[mediaWidth]]`);
|
|
snippet = snippet.replace(`{caption}`, `[[&caption]]`);
|
|
snippet = snippet.replace(`{alt}`, `[[alt]]`);
|
|
snippet = snippet.replace(`{filename}`, `[[filename]]`);
|
|
snippet = snippet.replace(`{title}`, `[[title]]`);
|
|
|
|
const snippets = Settings.get<Snippet[]>(SETTING_CONTENT_SNIPPETS) || {} as any;
|
|
snippets[`Media snippet (migrated)`] = {
|
|
body: snippet.split(`\n`),
|
|
isMediaSnippet: true,
|
|
description: `Migrated media snippet from frontMatter.dashboard.mediaSnippet setting`
|
|
}
|
|
|
|
await Settings.update(SETTING_CONTENT_SNIPPETS, snippets, true);
|
|
}
|
|
|
|
const templates = await Template.getTemplates();
|
|
if (templates && templates.length > 0) {
|
|
const answer = await window.showQuickPick(["Yes", "No"], {
|
|
title: "Front Matter - Templates",
|
|
placeHolder: "Do you want to keep on using the template functionality?",
|
|
ignoreFocusOut: true
|
|
});
|
|
|
|
Settings.update(SETTING_TEMPLATES_ENABLED, answer?.toLocaleLowerCase() === "yes", true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public async setState<T>(propKey: string, propValue: T, type: "workspace" | "global" = "global"): Promise<void> {
|
|
if (type === "global") {
|
|
await this.ctx.globalState.update(propKey, propValue);
|
|
} else {
|
|
await this.ctx.workspaceState.update(propKey, propValue);
|
|
}
|
|
}
|
|
|
|
public async getState<T>(propKey: string, type: "workspace" | "global" = "global"): Promise<T | undefined> {
|
|
if (type === "global") {
|
|
return await this.ctx.globalState.get(propKey);
|
|
} else {
|
|
return await this.ctx.workspaceState.get(propKey);
|
|
}
|
|
}
|
|
|
|
public isBetaVersion() {
|
|
return basename(this.ctx.globalStorageUri.fsPath) === EXTENSION_BETA_ID;
|
|
}
|
|
|
|
public checkIfExtensionCanRun() {
|
|
if (this.isBetaVersion()) {
|
|
const mainVersionInstalled = extensions.getExtension(EXTENSION_ID);
|
|
|
|
if (mainVersionInstalled) {
|
|
Notifications.error(`Front Matter BETA cannot be used while the main version is installed. Please ensure that you have only over version installed.`);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public asAbsolutePath(path: string) {
|
|
return this.ctx.asAbsolutePath(path);
|
|
}
|
|
|
|
public get packageJson() {
|
|
const frontMatter = extensions.getExtension(this.isBetaVersion() ? EXTENSION_BETA_ID : EXTENSION_ID)!;
|
|
return frontMatter.packageJSON;
|
|
}
|
|
} |