Enable writing on the settings page from plugs

This commit is contained in:
Guillermo Vaya
2022-07-23 19:18:03 +02:00
parent 88121da341
commit dd3cfd8e98
5 changed files with 102 additions and 8 deletions
+28 -3
View File
@@ -1,4 +1,5 @@
import { readYamlPage } from "./yaml_page";
import { flashNotification } from "@silverbulletmd/plugos-silverbullet-syscall/editor";
import { readYamlPage, writeYamlPage } from "./yaml_page";
/**
* Convenience function to read a specific set of settings from the `SETTINGS` page as well as default values
@@ -10,13 +11,16 @@ import { readYamlPage } from "./yaml_page";
* @returns an object with the same shape as `settings` but with non-default values override based on `SETTINGS`
*/
const SETTINGS_PAGE = "SETTINGS";
const SETTINGS_TEMPLATE = `This page contains settings for configuring SilverBullet and its Plugs:\n\`\`\`yaml\n\`\`\``; // might need \r\n for windows?
export async function readSettings<T extends object>(settings: T): Promise<T> {
try {
let allSettings = (await readYamlPage("SETTINGS", ["yaml"])) || {};
let allSettings = (await readYamlPage(SETTINGS_PAGE, ["yaml"])) || {};
// TODO: I'm sure there's a better way to type this than "any"
let collectedSettings: any = {};
for (let [key, defaultVal] of Object.entries(settings)) {
if (allSettings[key]) {
if (key in allSettings) {
collectedSettings[key] = allSettings[key];
} else {
collectedSettings[key] = defaultVal;
@@ -31,3 +35,24 @@ export async function readSettings<T extends object>(settings: T): Promise<T> {
throw e;
}
}
/**
* Convenience function to write a specific set of settings from the `SETTINGS` page.
* If the SETTiNGS page doesn't exist it will create it.
* @param settings
*/
export async function writeSettings<T extends object>(settings: T) {
let readSettings = {};
try {
readSettings = (await readYamlPage(SETTINGS_PAGE, ["yaml"])) || {};
} catch (e: any) {
console.log("Couldn't read settings, generating a new settings page");
flashNotification("Creating a new SETTINGS page...", "info");
}
const writeSettings = {...readSettings, ...settings};
if(await writeYamlPage(SETTINGS_PAGE, writeSettings, SETTINGS_TEMPLATE)) {
flashNotification("SETTINGS page written successfully", "info");
} else {
flashNotification("SETTINGS page failed to update", "error");
}
}
+41 -2
View File
@@ -1,6 +1,6 @@
import { findNodeOfType, traverseTree } from "@silverbulletmd/common/tree";
import { findNodeOfType, ParseTree, renderToText, replaceNodesMatching, traverseTree } from "@silverbulletmd/common/tree";
import { parseMarkdown } from "@silverbulletmd/plugos-silverbullet-syscall/markdown";
import { readPage } from "@silverbulletmd/plugos-silverbullet-syscall/space";
import { readPage, writePage } from "@silverbulletmd/plugos-silverbullet-syscall/space";
import YAML from "yaml";
export async function readYamlPage(
@@ -40,3 +40,42 @@ export async function readYamlPage(
return data;
}
export async function writeYamlPage(
pageName: string,
properties: any,
templateOnEmpty: string,
): Promise<Boolean> {
let text;
try {
const page = await readPage(pageName);
text = page.text;
} catch {
// page doesn't exist, so let's create one.
text = templateOnEmpty;
}
const tree = await parseMarkdown(text);
// if we use any other language than yaml... how to create it?
const doc = new YAML.Document();
doc.contents = properties;
// generate a new node for the properties
const newCode = `\`\`\`yaml\n${doc.toString()}\n\`\`\``;
const subtree = await parseMarkdown(newCode);
// find the original set of properties and replace
let replaced = false;
replaceNodesMatching(tree, (node: ParseTree) => {
if (node.type !== 'FencedCode') {
return;
}
const codeinfoNode = findNodeOfType(node, "CodeInfo");
if (!codeinfoNode || codeinfoNode.children![0].text! !== "yaml") {
return;
}
replaced = true;
return subtree;
});
if (replaced) {
await writePage(pageName, renderToText(tree));
}
return replaced;
}