You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

504 lines
20 KiB

var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
__markAsModule(target);
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
// src/main.ts
__export(exports, {
default: () => ThePlugin
});
var import_obsidian6 = __toModule(require("obsidian"));
// src/SettingsTab.ts
var import_obsidian = __toModule(require("obsidian"));
var SettingsTab = class extends import_obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("h2", { text: this.plugin.appName });
new import_obsidian.Setting(containerEl).setName("Auto-update at startup").setDesc("If enabled all beta plugins will be checked for updates each time Obsidian starts.").addToggle((cb) => {
cb.setValue(this.plugin.settings.updateAtStartup);
cb.onChange(async (value) => {
this.plugin.settings.updateAtStartup = value;
await this.plugin.saveSettings();
});
});
containerEl.createEl("hr");
containerEl.createEl("h2", { text: "Beta Plugin List" });
containerEl.createEl("div", { text: `The following is a list of beta plugins added via the command palette "Add a beta plugin for testing". ` });
containerEl.createEl("p");
containerEl.createEl("div", { text: `Click the x button next to a plugin to remove it from the list.` });
containerEl.createEl("p");
containerEl.createEl("span").createEl("b", { text: "Note: " });
containerEl.createSpan({ text: "This does not delete the plugin, this should be done from the Community Plugins tab in Settings." });
new import_obsidian.Setting(containerEl).addButton((cb) => {
cb.setButtonText("Add Beta plugin");
cb.onClick(async () => {
this.plugin.app.setting.close();
await this.plugin.betaPlugins.displayAddNewPluginModal(true);
});
});
for (const bp of this.plugin.settings.pluginList) {
new import_obsidian.Setting(containerEl).setName(bp).addButton((btn) => {
btn.setIcon("cross");
btn.setTooltip("Delete this beta plugin");
btn.onClick(async () => {
if (btn.buttonEl.textContent === "")
btn.setButtonText("Click once more to confirm removal");
else {
btn.buttonEl.parentElement.parentElement.remove();
await this.plugin.betaPlugins.deletePlugin(bp);
}
});
});
}
}
};
// src/settings.ts
var DEFAULT_SETTINGS = {
pluginList: [],
updateAtStartup: false
};
async function addBetaPluginToList(plugin, repositoryPath) {
if (!plugin.settings.pluginList.contains(repositoryPath)) {
plugin.settings.pluginList.unshift(repositoryPath);
plugin.saveSettings();
}
}
async function existBetaPluginInList(plugin, repositoryPath) {
return plugin.settings.pluginList.contains(repositoryPath);
}
// src/AddNewPluginModal.ts
var import_obsidian2 = __toModule(require("obsidian"));
var AddNewPluginModal = class extends import_obsidian2.Modal {
constructor(plugin, betaPlugins, openSettingsTabAfterwards = false) {
super(plugin.app);
this.plugin = plugin;
this.betaPlugins = betaPlugins;
this.address = "";
this.openSettingsTabAfterwards = openSettingsTabAfterwards;
}
async submitForm() {
if (this.address === "")
return;
const scrubbedAddress = this.address.replace("https://github.com/", "");
if (await existBetaPluginInList(this.plugin, scrubbedAddress)) {
new import_obsidian2.Notice(`BRAT
This plugin is already in the list for beta testing`, 1e4);
return;
}
const result = await this.betaPlugins.addPlugin(scrubbedAddress);
if (result) {
this.close();
}
}
onOpen() {
this.contentEl.createEl("h4", { text: "Github repository for beta plugin:" });
this.contentEl.createEl("form", {}, (formEl) => {
new import_obsidian2.Setting(formEl).addText((textEl) => {
textEl.setPlaceholder("Repository (example: TfTHacker/obsidian-brat");
textEl.onChange((value) => {
this.address = value.trim();
});
textEl.inputEl.addEventListener("keydown", async (e) => {
if (e.key === "Enter" && this.address !== " ") {
e.preventDefault();
await this.submitForm();
}
});
textEl.inputEl.style.width = "100%";
window.setTimeout(() => {
const title = document.querySelector(".setting-item-info");
if (title)
title.remove();
textEl.inputEl.focus();
}, 10);
});
formEl.createDiv("modal-button-container", (buttonContainerEl) => {
buttonContainerEl.createEl("button", { attr: { type: "button" }, text: "Never mind" }).addEventListener("click", () => this.close());
buttonContainerEl.createEl("button", {
attr: { type: "submit" },
cls: "mod-cta",
text: "Add Plugin"
});
});
formEl.addEventListener("submit", async (e) => {
e.preventDefault();
if (this.address !== "")
await this.submitForm();
});
});
}
async onClose() {
if (this.openSettingsTabAfterwards) {
await this.plugin.app.setting.open();
await this.plugin.app.setting.openTabById("obsidian42-brat");
}
}
};
// src/githubUtils.ts
var import_obsidian3 = __toModule(require("obsidian"));
var GITHUB_RAW_USERCONTENT_PATH = "https://raw.githubusercontent.com/";
var grabReleaseFileFromRepository = async (repository, version, fileName) => {
const URL = `https://github.com/${repository}/releases/download/${version}/${fileName}`;
try {
const download = await (0, import_obsidian3.request)({ url: URL });
return download === "Not Found" || download === `{"error":"Not Found"}` ? null : download;
} catch (error) {
console.log("error in grabReleaseFileFromRepository", URL, error);
}
};
var grabManifestJsonFromRepository = async (repositoryPath, rootManifest = true) => {
const manifestJsonPath = GITHUB_RAW_USERCONTENT_PATH + repositoryPath + (rootManifest === true ? "/HEAD/manifest.json" : "/HEAD/manifest-beta.json");
try {
const response = await (0, import_obsidian3.request)({ url: manifestJsonPath });
return response === "404: Not Found" ? null : await JSON.parse(response);
} catch (error) {
console.log("error in grabManifestJsonFromRepository", error);
}
};
var grabCommmunityPluginList = async () => {
const pluginListURL = `https://raw.githubusercontent.com/obsidianmd/obsidian-releases/HEAD/community-plugins.json`;
try {
const response = await (0, import_obsidian3.request)({ url: pluginListURL });
return response === "404: Not Found" ? null : await JSON.parse(response);
} catch (error) {
console.log("error in grabCommmunityPluginList", error);
}
};
// src/BetaPlugins.ts
var import_obsidian4 = __toModule(require("obsidian"));
var BetaPlugins = class {
constructor(plugin) {
this.plugin = plugin;
}
async displayAddNewPluginModal(openSettingsTabAfterwards = false) {
const newPlugin = new AddNewPluginModal(this.plugin, this, openSettingsTabAfterwards);
newPlugin.open();
}
async validateRepository(repositoryPath, getBetaManifest = false, reportIsues = false) {
const noticeTimeout = 1e4;
const manifestJson = await grabManifestJsonFromRepository(repositoryPath, !getBetaManifest);
if (!manifestJson) {
if (reportIsues)
new import_obsidian4.Notice(`BRAT
${repositoryPath}
This does not seem to be an obsidian plugin, as there is no manifest.json file.`, noticeTimeout);
return null;
}
if (!("id" in manifestJson)) {
if (reportIsues)
new import_obsidian4.Notice(`BRAT
${repositoryPath}
The plugin id attribute for the release is missing from the manifest file`, noticeTimeout);
return null;
}
if (!("version" in manifestJson)) {
if (reportIsues)
new import_obsidian4.Notice(`BRAT
${repositoryPath}
The version attribute for the release is missing from the manifest file`, noticeTimeout);
return null;
}
return manifestJson;
}
async getAllReleaseFiles(repositoryPath, manifest, getManifest) {
return {
mainJs: await grabReleaseFileFromRepository(repositoryPath, manifest.version, "main.js"),
manifest: getManifest ? await grabReleaseFileFromRepository(repositoryPath, manifest.version, "manifest.json") : null,
styles: await grabReleaseFileFromRepository(repositoryPath, manifest.version, "styles.css")
};
}
async writeReleaseFilesToPluginFolder(betaPluginID, relFiles) {
const pluginTargetFolderPath = (0, import_obsidian4.normalizePath)(this.plugin.app.vault.configDir + "/plugins/" + betaPluginID) + "/";
const adapter = this.plugin.app.vault.adapter;
if (await adapter.exists(pluginTargetFolderPath) === false || !await adapter.exists(pluginTargetFolderPath + "manifest.json")) {
await adapter.mkdir(pluginTargetFolderPath);
}
await adapter.write(pluginTargetFolderPath + "main.js", relFiles.mainJs);
await adapter.write(pluginTargetFolderPath + "manifest.json", relFiles.manifest);
if (relFiles.styles)
await adapter.write(pluginTargetFolderPath + "styles.css", relFiles.styles);
}
async addPlugin(repositoryPath, updatePluginFiles = false, seeIfUpdatedOnly = false, reportIfNotUpdted = false) {
const noticeTimeout = 1e4;
let primaryManifest = await this.validateRepository(repositoryPath, true, false);
const usingBetaManifest = primaryManifest ? true : false;
if (usingBetaManifest === false)
primaryManifest = await this.validateRepository(repositoryPath, false, true);
if (primaryManifest === null) {
new import_obsidian4.Notice(`BRAT
${repositoryPath}
A manifest.json or manifest-beta.json file does not exist in the root directory of the repository. This plugin cannot be installed.`, noticeTimeout);
return false;
}
if (!primaryManifest.hasOwnProperty("version")) {
new import_obsidian4.Notice(`BRAT
${repositoryPath}
The manifest${usingBetaManifest ? "-beta" : ""}.json file in the root directory of the repository does not have a version number in the file. This plugin cannot be installed.`, noticeTimeout);
return false;
}
const getRelease = async () => {
const rFiles = await this.getAllReleaseFiles(repositoryPath, primaryManifest, usingBetaManifest);
if (usingBetaManifest || rFiles.manifest === null)
rFiles.manifest = JSON.stringify(primaryManifest);
if (rFiles.mainJs === null) {
new import_obsidian4.Notice(`BRAT
${repositoryPath}
The release is not complete and cannot be download. main.js is missing from the Release`, noticeTimeout);
return null;
}
return rFiles;
};
if (updatePluginFiles === false) {
const releaseFiles = await getRelease();
if (releaseFiles === null)
return;
await this.writeReleaseFilesToPluginFolder(primaryManifest.id, releaseFiles);
await addBetaPluginToList(this.plugin, repositoryPath);
await this.plugin.app.plugins.loadManifests();
new import_obsidian4.Notice(`BRAT
${repositoryPath}
The plugin has been registered with BRAT. You may still need to enable it the Community Plugin List.`, noticeTimeout);
} else {
const pluginTargetFolderPath = this.plugin.app.vault.configDir + "/plugins/" + primaryManifest.id + "/";
let localManifestContents = null;
try {
localManifestContents = await this.plugin.app.vault.adapter.read(pluginTargetFolderPath + "manifest.json");
} catch (e) {
if (e.errno === -4058) {
await this.addPlugin(repositoryPath, false, usingBetaManifest);
return true;
} else
console.log("BRAT - Local Manifest Load", primaryManifest.id, JSON.stringify(e, null, 2));
}
const localManifestJSON = await JSON.parse(localManifestContents);
if (localManifestJSON.version !== primaryManifest.version) {
const releaseFiles = await getRelease();
if (releaseFiles === null)
return;
if (seeIfUpdatedOnly) {
new import_obsidian4.Notice(`BRAT
There is an update available for ${primaryManifest.id}`);
} else {
await this.writeReleaseFilesToPluginFolder(primaryManifest.id, releaseFiles);
await this.plugin.app.plugins.loadManifests();
if (this.plugin.app.plugins.plugins[primaryManifest.id]?.manifest)
await this.reloadPlugin(primaryManifest.id);
new import_obsidian4.Notice(`BRAT
${primaryManifest.id}
Plugin has been updated.`, noticeTimeout);
}
} else if (reportIfNotUpdted)
new import_obsidian4.Notice(`BRAT
No update available for ${repositoryPath}`, 3e3);
}
return true;
}
async reloadPlugin(pluginName) {
const plugins = this.plugin.app.plugins;
try {
await plugins.disablePlugin(pluginName);
await plugins.enablePlugin(pluginName);
} catch (e) {
console.log("reload plugin", e);
}
}
async updatePlugin(repositoryPath, onlyCheckDontUpdate = false, reportIfNotUpdted = false) {
const result = await this.addPlugin(repositoryPath, true, onlyCheckDontUpdate, reportIfNotUpdted);
if (result === false && onlyCheckDontUpdate === false)
new import_obsidian4.Notice(`BRAT
${repositoryPath}
Update of plugin failed.`);
return result;
}
async checkForUpdatesAndInstallUpdates(showInfo = false, onlyCheckDontUpdate = false) {
if (showInfo)
new import_obsidian4.Notice(`BRAT
Checking for plugin updates STARTED`, 1e4);
for (const bp of this.plugin.settings.pluginList) {
await this.updatePlugin(bp, onlyCheckDontUpdate);
}
if (showInfo)
new import_obsidian4.Notice(`BRAT
Checking for plugin updates COMPLETED`, 1e4);
}
async deletePlugin(repositoryPath) {
this.plugin.settings.pluginList = this.plugin.settings.pluginList.filter((b) => b != repositoryPath);
this.plugin.saveSettings();
}
};
// src/GenericFuzzySuggester.ts
var import_obsidian5 = __toModule(require("obsidian"));
var GenericFuzzySuggester = class extends import_obsidian5.FuzzySuggestModal {
constructor(plugin) {
super(plugin.app);
this.scope.register(["Shift"], "Enter", (evt) => this.enterTrigger(evt));
this.scope.register(["Ctrl"], "Enter", (evt) => this.enterTrigger(evt));
}
setSuggesterData(suggesterData) {
this.data = suggesterData;
}
async display(callBack) {
this.callbackFunction = callBack;
this.open();
}
getItems() {
return this.data;
}
getItemText(item) {
return item.display;
}
onChooseItem() {
return;
}
renderSuggestion(item, el) {
el.createEl("div", { text: item.item.display });
}
enterTrigger(evt) {
const selectedText = document.querySelector(".suggestion-item.is-selected div").textContent;
const item = this.data.find((i) => i.display === selectedText);
if (item) {
this.invokeCallback(item, evt);
this.close();
}
}
onChooseSuggestion(item, evt) {
this.invokeCallback(item.item, evt);
}
invokeCallback(item, evt) {
this.callbackFunction(item, evt);
}
};
// src/main.ts
var ThePlugin = class extends import_obsidian6.Plugin {
constructor() {
super(...arguments);
this.appName = "Obsidian42 - Beta Reviewer's Auto-update Tool (BRAT)";
this.appID = "obsidian42-brat";
}
async onload() {
console.log("loading Obsidian42 - BRAT");
await this.loadSettings();
this.addSettingTab(new SettingsTab(this.app, this));
this.betaPlugins = new BetaPlugins(this);
this.addCommand({
id: "BRAT-AddBetaPlugin",
name: "Add a beta plugin for testing",
callback: async () => {
await this.betaPlugins.displayAddNewPluginModal();
}
});
this.addCommand({
id: "BRAT-checkForUpdatesAndUpdate",
name: "Check for updates to all beta plugins and UPDATE",
callback: async () => {
await this.betaPlugins.checkForUpdatesAndInstallUpdates(true, false);
}
});
this.addCommand({
id: "BRAT-checkForUpdatesAndDontUpdate",
name: "Only check for updates to beta plugins, but don't Update",
callback: async () => {
await this.betaPlugins.checkForUpdatesAndInstallUpdates(true, true);
}
});
this.addCommand({
id: "BRAT-updateOnePlugin",
name: "Choose a single plugin to update",
callback: async () => {
const pluginList = Object.values(this.settings.pluginList).map((m) => {
return { display: m, info: m };
});
const gfs = new GenericFuzzySuggester(this);
gfs.setSuggesterData(pluginList);
await gfs.display(async (results) => {
new import_obsidian6.Notice(`BRAT
Checking for updates for ${results.info}`, 3e3);
await this.betaPlugins.updatePlugin(results.info, false, true);
});
}
});
this.addCommand({
id: "BRAT-restartPlugin",
name: "Restart a plugin that is already installed",
callback: async () => {
const pluginList = Object.values(this.app.plugins.manifests).map((m) => {
return { display: m.id, info: m.id };
});
const gfs = new GenericFuzzySuggester(this);
gfs.setSuggesterData(pluginList);
await gfs.display(async (results) => {
new import_obsidian6.Notice(`${results.info}
Plugin reloading .....`, 5e3);
await this.betaPlugins.reloadPlugin(results.info);
});
}
});
this.addCommand({
id: "BRAT-openGitHubRepository",
name: "Open the GitHub repository for a plugin",
callback: async () => {
const communityPlugins = await grabCommmunityPluginList();
const communityPluginList = Object.values(communityPlugins).map((p) => {
return { display: `Community: ${p.name} (${p.repo})`, info: p.repo };
});
const bratList = Object.values(this.settings.pluginList).map((p) => {
return { display: "BRAT: " + p, info: p };
});
communityPluginList.forEach((si) => bratList.push(si));
const gfs = new GenericFuzzySuggester(this);
gfs.setSuggesterData(bratList);
await gfs.display(async (results) => {
if (results.info)
window.open(`https://github.com/${results.info}`);
});
}
});
this.app.workspace.onLayoutReady(() => {
if (this.settings.updateAtStartup)
setTimeout(async () => {
await this.betaPlugins.checkForUpdatesAndInstallUpdates(false);
}, 6e4);
});
}
onunload() {
console.log("unloading " + this.appName);
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
};