Work
parent
a4e127a6dd
commit
098a419ff3
|
@ -9848,7 +9848,15 @@
|
||||||
"packages/common": {
|
"packages/common": {
|
||||||
"name": "@silverbulletmd/common",
|
"name": "@silverbulletmd/common",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/highlight": "^0.19.0",
|
||||||
|
"@codemirror/lang-javascript": "^0.19.7",
|
||||||
|
"@codemirror/language": "^0.19.0",
|
||||||
|
"@codemirror/legacy-modes": "^0.19.1",
|
||||||
|
"@codemirror/stream-parser": "^0.19.9",
|
||||||
|
"@lezer/markdown": "^0.15.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"packages/plugos": {
|
"packages/plugos": {
|
||||||
"name": "@plugos/plugos",
|
"name": "@plugos/plugos",
|
||||||
|
@ -11509,7 +11517,15 @@
|
||||||
"version": "file:packages/plugos-syscall"
|
"version": "file:packages/plugos-syscall"
|
||||||
},
|
},
|
||||||
"@silverbulletmd/common": {
|
"@silverbulletmd/common": {
|
||||||
"version": "file:packages/common"
|
"version": "file:packages/common",
|
||||||
|
"requires": {
|
||||||
|
"@codemirror/highlight": "^0.19.0",
|
||||||
|
"@codemirror/lang-javascript": "^0.19.7",
|
||||||
|
"@codemirror/language": "^0.19.0",
|
||||||
|
"@codemirror/legacy-modes": "^0.19.1",
|
||||||
|
"@codemirror/stream-parser": "^0.19.9",
|
||||||
|
"@lezer/markdown": "^0.15.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"@silverbulletmd/plugos-silverbullet-syscall": {
|
"@silverbulletmd/plugos-silverbullet-syscall": {
|
||||||
"version": "file:packages/plugos-silverbullet-syscall"
|
"version": "file:packages/plugos-silverbullet-syscall"
|
||||||
|
|
|
@ -5,5 +5,13 @@
|
||||||
"email": "zef@zef.me"
|
"email": "zef@zef.me"
|
||||||
},
|
},
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/highlight": "^0.19.0",
|
||||||
|
"@codemirror/language": "^0.19.0",
|
||||||
|
"@codemirror/stream-parser": "^0.19.9",
|
||||||
|
"@codemirror/lang-javascript": "^0.19.7",
|
||||||
|
"@codemirror/legacy-modes": "^0.19.1",
|
||||||
|
"@lezer/markdown": "^0.15.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,10 +29,6 @@ import {
|
||||||
|
|
||||||
export const pageLinkRegex = /^\[\[([^\]]+)\]\]/;
|
export const pageLinkRegex = /^\[\[([^\]]+)\]\]/;
|
||||||
|
|
||||||
// const pageLinkRegexPrefix = new RegExp(
|
|
||||||
// "^" + pageLinkRegex.toString().slice(1, -1)
|
|
||||||
// );
|
|
||||||
|
|
||||||
const WikiLink: MarkdownConfig = {
|
const WikiLink: MarkdownConfig = {
|
||||||
defineNodes: ["WikiLink", "WikiLinkPage"],
|
defineNodes: ["WikiLink", "WikiLinkPage"],
|
||||||
parseInline: [
|
parseInline: [
|
|
@ -11,21 +11,30 @@ import * as path from "path";
|
||||||
import { PageMeta } from "../types";
|
import { PageMeta } from "../types";
|
||||||
import { SpacePrimitives } from "./space_primitives";
|
import { SpacePrimitives } from "./space_primitives";
|
||||||
import { Plug } from "@plugos/plugos/plug";
|
import { Plug } from "@plugos/plugos/plug";
|
||||||
|
import { realpathSync } from "fs";
|
||||||
|
|
||||||
export class DiskSpacePrimitives implements SpacePrimitives {
|
export class DiskSpacePrimitives implements SpacePrimitives {
|
||||||
rootPath: string;
|
rootPath: string;
|
||||||
plugPrefix: string;
|
plugPrefix: string;
|
||||||
|
|
||||||
constructor(rootPath: string, plugPrefix: string = "_plug/") {
|
constructor(rootPath: string, plugPrefix: string = "_plug/") {
|
||||||
this.rootPath = rootPath;
|
this.rootPath = realpathSync(rootPath);
|
||||||
this.plugPrefix = plugPrefix;
|
this.plugPrefix = plugPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
safePath(p: string): string {
|
||||||
|
let realPath = realpathSync(p);
|
||||||
|
if (!realPath.startsWith(this.rootPath)) {
|
||||||
|
throw Error(`Path ${p} is not in the space`);
|
||||||
|
}
|
||||||
|
return realPath;
|
||||||
|
}
|
||||||
|
|
||||||
pageNameToPath(pageName: string) {
|
pageNameToPath(pageName: string) {
|
||||||
if (pageName.startsWith(this.plugPrefix)) {
|
if (pageName.startsWith(this.plugPrefix)) {
|
||||||
return path.join(this.rootPath, pageName + ".plug.json");
|
return this.safePath(path.join(this.rootPath, pageName + ".plug.json"));
|
||||||
}
|
}
|
||||||
return path.join(this.rootPath, pageName + ".md");
|
return this.safePath(path.join(this.rootPath, pageName + ".md"));
|
||||||
}
|
}
|
||||||
|
|
||||||
pathToPageName(fullPath: string): string {
|
pathToPageName(fullPath: string): string {
|
||||||
|
|
|
@ -5,17 +5,34 @@ import { SpacePrimitives } from "./space_primitives";
|
||||||
export class HttpSpacePrimitives implements SpacePrimitives {
|
export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
pageUrl: string;
|
pageUrl: string;
|
||||||
private plugUrl: string;
|
private plugUrl: string;
|
||||||
|
token?: string;
|
||||||
|
|
||||||
constructor(url: string) {
|
constructor(url: string, token?: string) {
|
||||||
this.pageUrl = url + "/fs";
|
this.pageUrl = url + "/fs";
|
||||||
this.plugUrl = url + "/plug";
|
this.plugUrl = url + "/plug";
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async authenticatedFetch(
|
||||||
|
url: string,
|
||||||
|
options: any
|
||||||
|
): Promise<Response> {
|
||||||
|
if (this.token) {
|
||||||
|
options.headers = options.headers || {};
|
||||||
|
options.headers["Authorization"] = `Bearer ${this.token}`;
|
||||||
|
}
|
||||||
|
let result = await fetch(url, options);
|
||||||
|
if (result.status === 401) {
|
||||||
|
throw Error("Unauthorized");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchPageList(): Promise<{
|
public async fetchPageList(): Promise<{
|
||||||
pages: Set<PageMeta>;
|
pages: Set<PageMeta>;
|
||||||
nowTimestamp: number;
|
nowTimestamp: number;
|
||||||
}> {
|
}> {
|
||||||
let req = await fetch(this.pageUrl, {
|
let req = await this.authenticatedFetch(this.pageUrl, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -35,7 +52,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
}
|
}
|
||||||
|
|
||||||
async readPage(name: string): Promise<{ text: string; meta: PageMeta }> {
|
async readPage(name: string): Promise<{ text: string; meta: PageMeta }> {
|
||||||
let res = await fetch(`${this.pageUrl}/${name}`, {
|
let res = await this.authenticatedFetch(`${this.pageUrl}/${name}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
if (res.headers.get("X-Status") === "404") {
|
if (res.headers.get("X-Status") === "404") {
|
||||||
|
@ -54,7 +71,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
lastModified?: number
|
lastModified?: number
|
||||||
): Promise<PageMeta> {
|
): Promise<PageMeta> {
|
||||||
// TODO: lastModified ignored for now
|
// TODO: lastModified ignored for now
|
||||||
let res = await fetch(`${this.pageUrl}/${name}`, {
|
let res = await this.authenticatedFetch(`${this.pageUrl}/${name}`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: text,
|
body: text,
|
||||||
headers: lastModified
|
headers: lastModified
|
||||||
|
@ -68,7 +85,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
}
|
}
|
||||||
|
|
||||||
async deletePage(name: string): Promise<void> {
|
async deletePage(name: string): Promise<void> {
|
||||||
let req = await fetch(`${this.pageUrl}/${name}`, {
|
let req = await this.authenticatedFetch(`${this.pageUrl}/${name}`, {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
});
|
});
|
||||||
if (req.status !== 200) {
|
if (req.status !== 200) {
|
||||||
|
@ -77,13 +94,16 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
}
|
}
|
||||||
|
|
||||||
async proxySyscall(plug: Plug<any>, name: string, args: any[]): Promise<any> {
|
async proxySyscall(plug: Plug<any>, name: string, args: any[]): Promise<any> {
|
||||||
let req = await fetch(`${this.plugUrl}/${plug.name}/syscall/${name}`, {
|
let req = await this.authenticatedFetch(
|
||||||
method: "POST",
|
`${this.plugUrl}/${plug.name}/syscall/${name}`,
|
||||||
headers: {
|
{
|
||||||
"Content-type": "application/json",
|
method: "POST",
|
||||||
},
|
headers: {
|
||||||
body: JSON.stringify(args),
|
"Content-type": "application/json",
|
||||||
});
|
},
|
||||||
|
body: JSON.stringify(args),
|
||||||
|
}
|
||||||
|
);
|
||||||
if (req.status !== 200) {
|
if (req.status !== 200) {
|
||||||
let error = await req.text();
|
let error = await req.text();
|
||||||
throw Error(error);
|
throw Error(error);
|
||||||
|
@ -105,13 +125,16 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
return plug.invoke(name, args);
|
return plug.invoke(name, args);
|
||||||
}
|
}
|
||||||
// Or dispatch to server
|
// Or dispatch to server
|
||||||
let req = await fetch(`${this.plugUrl}/${plug.name}/function/${name}`, {
|
let req = await this.authenticatedFetch(
|
||||||
method: "POST",
|
`${this.plugUrl}/${plug.name}/function/${name}`,
|
||||||
headers: {
|
{
|
||||||
"Content-type": "application/json",
|
method: "POST",
|
||||||
},
|
headers: {
|
||||||
body: JSON.stringify(args),
|
"Content-type": "application/json",
|
||||||
});
|
},
|
||||||
|
body: JSON.stringify(args),
|
||||||
|
}
|
||||||
|
);
|
||||||
if (req.status !== 200) {
|
if (req.status !== 200) {
|
||||||
let error = await req.text();
|
let error = await req.text();
|
||||||
throw Error(error);
|
throw Error(error);
|
||||||
|
@ -127,7 +150,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPageMeta(name: string): Promise<PageMeta> {
|
async getPageMeta(name: string): Promise<PageMeta> {
|
||||||
let res = await fetch(`${this.pageUrl}/${name}`, {
|
let res = await this.authenticatedFetch(`${this.pageUrl}/${name}`, {
|
||||||
method: "OPTIONS",
|
method: "OPTIONS",
|
||||||
});
|
});
|
||||||
if (res.headers.get("X-Status") === "404") {
|
if (res.headers.get("X-Status") === "404") {
|
||||||
|
|
|
@ -7,9 +7,9 @@ import {
|
||||||
nodeAtPos,
|
nodeAtPos,
|
||||||
removeParentPointers,
|
removeParentPointers,
|
||||||
renderToText,
|
renderToText,
|
||||||
replaceNodesMatching
|
replaceNodesMatching,
|
||||||
} from "./tree";
|
} from "./tree";
|
||||||
import wikiMarkdownLang from "@silverbulletmd/web/parser";
|
import wikiMarkdownLang from "@silverbulletmd/common/parser";
|
||||||
|
|
||||||
const mdTest1 = `
|
const mdTest1 = `
|
||||||
# Heading
|
# Heading
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
var $hVExJ$jestglobals = require("@jest/globals");
|
var $hVExJ$jestglobals = require("@jest/globals");
|
||||||
|
var $hVExJ$handlebars = require("handlebars");
|
||||||
|
var $hVExJ$yaml = require("yaml");
|
||||||
var $hVExJ$lezerlr = require("@lezer/lr");
|
var $hVExJ$lezerlr = require("@lezer/lr");
|
||||||
|
|
||||||
|
function $parcel$interopDefault(a) {
|
||||||
|
return a && a.__esModule ? a.default : a;
|
||||||
|
}
|
||||||
|
|
||||||
function $255163dfff8c42fb$export$6dd7a1b2f91e0e12(tree) {
|
function $255163dfff8c42fb$export$6dd7a1b2f91e0e12(tree) {
|
||||||
if (!tree.children) return;
|
if (!tree.children) return;
|
||||||
|
@ -151,6 +156,8 @@ function $88d466d5aaf7a497$export$98e6a39c04603d36(language, text) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const $d85524f23de2149a$export$8f49e4af10703ce3 = $hVExJ$lezerlr.LRParser.deserialize({
|
const $d85524f23de2149a$export$8f49e4af10703ce3 = $hVExJ$lezerlr.LRParser.deserialize({
|
||||||
version: 13,
|
version: 13,
|
||||||
states: "&fOVQPOOOmQQO'#C^QOQPOOOtQPO'#C`OyQQO'#CkO!OQPO'#CmO!TQPO'#CnO!YQPO'#CoOOQO'#Cp'#CpO!_QQO,58xO!fQQO'#CcO#TQQO'#CaOOQO'#Ca'#CaOOQO,58z,58zO#lQPO,59VOOQO,59X,59XO#qQQO'#D`OOQO,59Y,59YOOQO,59Z,59ZOOQO-E6n-E6nO$YQQO,58}OtQPO,58|O$qQQO1G.qO%]QPO'#CrO%bQQO,59zOOQO'#Cg'#CgOOQO'#Ci'#CiO$YQQO'#CjOOQO'#Cd'#CdOOQO1G.i1G.iOOQO1G.h1G.hOOQO'#Cl'#ClOOQO7+$]7+$]OOQO,59^,59^OOQO-E6p-E6pO%yQPO'#C|O&RQPO,59UO$YQQO'#CqO&WQPO,59hOOQO1G.p1G.pOOQO,59],59]OOQO-E6o-E6o",
|
states: "&fOVQPOOOmQQO'#C^QOQPOOOtQPO'#C`OyQQO'#CkO!OQPO'#CmO!TQPO'#CnO!YQPO'#CoOOQO'#Cp'#CpO!_QQO,58xO!fQQO'#CcO#TQQO'#CaOOQO'#Ca'#CaOOQO,58z,58zO#lQPO,59VOOQO,59X,59XO#qQQO'#D`OOQO,59Y,59YOOQO,59Z,59ZOOQO-E6n-E6nO$YQQO,58}OtQPO,58|O$qQQO1G.qO%]QPO'#CrO%bQQO,59zOOQO'#Cg'#CgOOQO'#Ci'#CiO$YQQO'#CjOOQO'#Cd'#CdOOQO1G.i1G.iOOQO1G.h1G.hOOQO'#Cl'#ClOOQO7+$]7+$]OOQO,59^,59^OOQO-E6p-E6pO%yQPO'#C|O&RQPO,59UO$YQQO'#CqO&WQPO,59hOOQO1G.p1G.pOOQO,59],59]OOQO-E6o-E6o",
|
||||||
|
@ -194,6 +201,92 @@ async function $2780e5830b4782c9$export$2e9858c25869c949(name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function $11a7e2bff790f35a$export$7945ba8eb1c827e6() {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.getCurrentPage");
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$5e830c5f3cd8a610(newName) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.setPage", newName);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$c72d34660a162238() {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.getText");
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$da3f040fb23d21f() {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.getCursor");
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$a1544dad697b423d() {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.save");
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$ff7962acd6052c28(name, pos) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.navigate", name, pos);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$da22d4a5076a7905() {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.reloadPage");
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$a238cfe4a10e6279(url) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.openUrl", url);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$4f02334034b5dd8c(message) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.flashNotification", message);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$83b9d7a71bc0a208(label, options, helpText = "", placeHolder = "") {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.filterBox", label, options, helpText, placeHolder);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$53ed0b99a5f8822e(html, flex = 1) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.showRhs", html, flex);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$f19f28e8a128fabe() {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.hideRhs");
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$dcf0ace441f4b3a4(html, flex = 1) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.showLhs", html, flex);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$1be2ad20c6324dcf() {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.hideLhs");
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$6ebe231c70cc6efb(html, flex = 1) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.showBhs", html, flex);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$a7a5aa8ba1cd9dc3() {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.hideBhs");
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$f1124a4ce9f9bf29(text, pos) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.insertAtPos", text, pos);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$54cb80d99fa58e48(from, to, text) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.replaceRange", from, to, text);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$185d1f0722e636b2(pos) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.moveCursor", pos);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$df659347c0c138a9(text) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.insertAtCursor", text);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$c4c1b7dbe675fa50(re) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.matchBefore", re);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$635e15bbd66f01ea(change) {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.dispatch", change);
|
||||||
|
}
|
||||||
|
function $11a7e2bff790f35a$export$195ba6d62321b933(message, defaultValue = "") {
|
||||||
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.prompt", message, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const $c3893eec0c49ec96$var$dateMatchRegex = /(\d{4}\-\d{2}\-\d{2})/g;
|
||||||
|
function $c3893eec0c49ec96$export$5dc1410f87262ed6(d) {
|
||||||
|
return d.toISOString().split("T")[0];
|
||||||
|
}
|
||||||
|
async function $c3893eec0c49ec96$export$151bb3c215c78d5a() {
|
||||||
|
await $11a7e2bff790f35a$export$df659347c0c138a9($c3893eec0c49ec96$export$5dc1410f87262ed6(new Date()));
|
||||||
|
}
|
||||||
|
async function $c3893eec0c49ec96$export$2177dd573df27382() {
|
||||||
|
let d = new Date();
|
||||||
|
d.setDate(d.getDate() + 1);
|
||||||
|
await $11a7e2bff790f35a$export$df659347c0c138a9($c3893eec0c49ec96$export$5dc1410f87262ed6(d));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function $9072202279b76d33$export$1e8473eaf75b0d10(query) {
|
function $9072202279b76d33$export$1e8473eaf75b0d10(query) {
|
||||||
let n1 = $88d466d5aaf7a497$export$87cc1c28aef74af1(query, $d85524f23de2149a$export$8f49e4af10703ce3.parse(query).topNode);
|
let n1 = $88d466d5aaf7a497$export$87cc1c28aef74af1(query, $d85524f23de2149a$export$8f49e4af10703ce3.parse(query).topNode);
|
||||||
// Clean the tree a bit
|
// Clean the tree a bit
|
||||||
|
@ -327,11 +420,26 @@ function $9072202279b76d33$export$5884dae03c64f759(parsedQuery, records) {
|
||||||
});
|
});
|
||||||
return resultRecords;
|
return resultRecords;
|
||||||
}
|
}
|
||||||
async function $9072202279b76d33$var$renderQuery(parsedQuery, data) {
|
async function $9072202279b76d33$export$b3c659c1456e61b0(parsedQuery, data) {
|
||||||
if (parsedQuery.render) {
|
if (parsedQuery.render) {
|
||||||
|
($parcel$interopDefault($hVExJ$handlebars)).registerHelper("json", (v)=>JSON.stringify(v)
|
||||||
|
);
|
||||||
|
($parcel$interopDefault($hVExJ$handlebars)).registerHelper("niceDate", (ts)=>$c3893eec0c49ec96$export$5dc1410f87262ed6(new Date(ts))
|
||||||
|
);
|
||||||
|
($parcel$interopDefault($hVExJ$handlebars)).registerHelper("yaml", (v, prefix)=>{
|
||||||
|
if (typeof prefix === "string") {
|
||||||
|
let yaml = ($parcel$interopDefault($hVExJ$yaml)).stringify(v).split("\n").join("\n" + prefix).trim();
|
||||||
|
if (Array.isArray(v)) return "\n" + prefix + yaml;
|
||||||
|
else return yaml;
|
||||||
|
} else return ($parcel$interopDefault($hVExJ$yaml)).stringify(v).trim();
|
||||||
|
});
|
||||||
let { text: templateText } = await $2780e5830b4782c9$export$126f79da5c357ad(parsedQuery.render);
|
let { text: templateText } = await $2780e5830b4782c9$export$126f79da5c357ad(parsedQuery.render);
|
||||||
// let template = Handlebars.compile(templateText);
|
let template = ($parcel$interopDefault($hVExJ$handlebars)).compile(templateText, {
|
||||||
|
noEscape: true
|
||||||
|
});
|
||||||
|
return template(data);
|
||||||
}
|
}
|
||||||
|
return "ERROR";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,29 @@
|
||||||
|
import { beforeEach, afterEach, expect, test } from "@jest/globals";
|
||||||
|
import { unlink } from "fs/promises";
|
||||||
|
import knex, { Knex } from "knex";
|
||||||
|
import { Authenticator } from "./auth";
|
||||||
|
|
||||||
|
let db: Knex<any, unknown[]> | undefined;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
db = knex({
|
||||||
|
client: "better-sqlite3",
|
||||||
|
connection: {
|
||||||
|
filename: "test.db",
|
||||||
|
},
|
||||||
|
useNullAsDefault: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
db!.destroy();
|
||||||
|
await unlink("test.db");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Test auth", async () => {
|
||||||
|
let auth = new Authenticator(db!);
|
||||||
|
await auth.ensureTables();
|
||||||
|
await auth.createAccount("admin", "admin");
|
||||||
|
expect(await auth.verify("admin", "admin")).toBe(true);
|
||||||
|
expect(await auth.verify("admin", "sup")).toBe(false);
|
||||||
|
});
|
|
@ -0,0 +1,71 @@
|
||||||
|
import * as crypto from "crypto";
|
||||||
|
import { Knex } from "knex";
|
||||||
|
import { promisify } from "util";
|
||||||
|
const pbkdf2 = promisify(crypto.pbkdf2);
|
||||||
|
|
||||||
|
type Account = {
|
||||||
|
username: string;
|
||||||
|
hashed_password: any;
|
||||||
|
salt: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class Authenticator {
|
||||||
|
tableName = "tokens";
|
||||||
|
|
||||||
|
constructor(private db: Knex<any, unknown[]>) {}
|
||||||
|
|
||||||
|
middleware(req: any, res: any, next: any) {
|
||||||
|
console.log("GOing through here", req.headers.authorization);
|
||||||
|
// if (req.headers)
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
async ensureTables() {
|
||||||
|
if (!(await this.db.schema.hasTable(this.tableName))) {
|
||||||
|
await this.db.schema.createTable(this.tableName, (table) => {
|
||||||
|
table.string("username");
|
||||||
|
table.binary("hashed_password");
|
||||||
|
table.binary("salt");
|
||||||
|
table.primary(["username"]);
|
||||||
|
});
|
||||||
|
// await this.createAccount("admin", "admin");
|
||||||
|
console.log(`Created table ${this.tableName}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createAccount(username: string, password: string) {
|
||||||
|
var salt = crypto.randomBytes(16);
|
||||||
|
let encryptedPassword = await pbkdf2(password, salt, 310000, 32, "sha256");
|
||||||
|
await this.db<Account>(this.tableName).insert({
|
||||||
|
username,
|
||||||
|
hashed_password: encryptedPassword,
|
||||||
|
salt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async updatePassword(username: string, password: string) {
|
||||||
|
var salt = crypto.randomBytes(16);
|
||||||
|
let encryptedPassword = await pbkdf2(password, salt, 310000, 32, "sha256");
|
||||||
|
await this.db<Account>(this.tableName).update({
|
||||||
|
username,
|
||||||
|
hashed_password: encryptedPassword,
|
||||||
|
salt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async verify(username: string, password: string): Promise<boolean> {
|
||||||
|
let users = await this.db<Account>(this.tableName).where({ username });
|
||||||
|
if (users.length === 0) {
|
||||||
|
throw new Error(`No such user: ${username}`);
|
||||||
|
}
|
||||||
|
let user = users[0];
|
||||||
|
let encryptedPassword = await pbkdf2(
|
||||||
|
password,
|
||||||
|
user.salt,
|
||||||
|
310000,
|
||||||
|
32,
|
||||||
|
"sha256"
|
||||||
|
);
|
||||||
|
return crypto.timingSafeEqual(user.hashed_password, encryptedPassword);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,13 +19,26 @@ import { EventedSpacePrimitives } from "@silverbulletmd/common/spaces/evented_sp
|
||||||
import { Space } from "@silverbulletmd/common/spaces/space";
|
import { Space } from "@silverbulletmd/common/spaces/space";
|
||||||
import { createSandbox } from "@plugos/plugos/environments/node_sandbox";
|
import { createSandbox } from "@plugos/plugos/environments/node_sandbox";
|
||||||
import { jwtSyscalls } from "@plugos/plugos/syscalls/jwt";
|
import { jwtSyscalls } from "@plugos/plugos/syscalls/jwt";
|
||||||
import buildMarkdown from "@silverbulletmd/web/parser";
|
import buildMarkdown from "@silverbulletmd/common/parser";
|
||||||
import { loadMarkdownExtensions } from "@silverbulletmd/web/markdown_ext";
|
import { loadMarkdownExtensions } from "@silverbulletmd/common/markdown_ext";
|
||||||
import http, { Server } from "http";
|
import http, { Server } from "http";
|
||||||
import { esbuildSyscalls } from "@plugos/plugos/syscalls/esbuild";
|
import { esbuildSyscalls } from "@plugos/plugos/syscalls/esbuild";
|
||||||
import { systemSyscalls } from "./syscalls/system";
|
import { systemSyscalls } from "./syscalls/system";
|
||||||
import { plugPrefix } from "@silverbulletmd/common/spaces/constants";
|
import { plugPrefix } from "@silverbulletmd/common/spaces/constants";
|
||||||
|
|
||||||
|
import { Authenticator } from "./auth";
|
||||||
|
import { nextTick } from "process";
|
||||||
|
|
||||||
|
const safeFilename = /^[a-zA-Z0-9_\-\.]+$/;
|
||||||
|
|
||||||
|
export type ServerOptions = {
|
||||||
|
port: number;
|
||||||
|
pagesPath: string;
|
||||||
|
distDir: string;
|
||||||
|
builtinPlugDir: string;
|
||||||
|
preloadedModules: string[];
|
||||||
|
token?: string;
|
||||||
|
};
|
||||||
export class ExpressServer {
|
export class ExpressServer {
|
||||||
app: Express;
|
app: Express;
|
||||||
system: System<SilverBulletHooks>;
|
system: System<SilverBulletHooks>;
|
||||||
|
@ -37,27 +50,23 @@ export class ExpressServer {
|
||||||
private server?: Server;
|
private server?: Server;
|
||||||
builtinPlugDir: string;
|
builtinPlugDir: string;
|
||||||
preloadedModules: string[];
|
preloadedModules: string[];
|
||||||
|
token?: string;
|
||||||
|
|
||||||
constructor(
|
constructor(options: ServerOptions) {
|
||||||
port: number,
|
this.port = options.port;
|
||||||
pagesPath: string,
|
|
||||||
distDir: string,
|
|
||||||
builtinPlugDir: string,
|
|
||||||
preloadedModules: string[]
|
|
||||||
) {
|
|
||||||
this.port = port;
|
|
||||||
this.app = express();
|
this.app = express();
|
||||||
this.builtinPlugDir = builtinPlugDir;
|
this.builtinPlugDir = options.builtinPlugDir;
|
||||||
this.distDir = distDir;
|
this.distDir = options.distDir;
|
||||||
this.system = new System<SilverBulletHooks>("server");
|
this.system = new System<SilverBulletHooks>("server");
|
||||||
this.preloadedModules = preloadedModules;
|
this.preloadedModules = options.preloadedModules;
|
||||||
|
this.token = options.token;
|
||||||
|
|
||||||
// Setup system
|
// Setup system
|
||||||
this.eventHook = new EventHook();
|
this.eventHook = new EventHook();
|
||||||
this.system.addHook(this.eventHook);
|
this.system.addHook(this.eventHook);
|
||||||
this.space = new Space(
|
this.space = new Space(
|
||||||
new EventedSpacePrimitives(
|
new EventedSpacePrimitives(
|
||||||
new DiskSpacePrimitives(pagesPath),
|
new DiskSpacePrimitives(options.pagesPath),
|
||||||
this.eventHook
|
this.eventHook
|
||||||
),
|
),
|
||||||
true
|
true
|
||||||
|
@ -65,27 +74,33 @@ export class ExpressServer {
|
||||||
this.db = knex({
|
this.db = knex({
|
||||||
client: "better-sqlite3",
|
client: "better-sqlite3",
|
||||||
connection: {
|
connection: {
|
||||||
filename: path.join(pagesPath, "data.db"),
|
filename: path.join(options.pagesPath, "data.db"),
|
||||||
},
|
},
|
||||||
useNullAsDefault: true,
|
useNullAsDefault: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.system.registerSyscalls(["shell"], shellSyscalls(pagesPath));
|
this.system.registerSyscalls(["shell"], shellSyscalls(options.pagesPath));
|
||||||
this.system.addHook(new NodeCronHook());
|
this.system.addHook(new NodeCronHook());
|
||||||
|
|
||||||
this.system.registerSyscalls([], pageIndexSyscalls(this.db));
|
this.system.registerSyscalls(
|
||||||
this.system.registerSyscalls([], spaceSyscalls(this.space));
|
[],
|
||||||
this.system.registerSyscalls([], eventSyscalls(this.eventHook));
|
pageIndexSyscalls(this.db),
|
||||||
this.system.registerSyscalls([], markdownSyscalls(buildMarkdown([])));
|
spaceSyscalls(this.space),
|
||||||
this.system.registerSyscalls([], esbuildSyscalls());
|
eventSyscalls(this.eventHook),
|
||||||
this.system.registerSyscalls([], systemSyscalls(this));
|
markdownSyscalls(buildMarkdown([])),
|
||||||
this.system.registerSyscalls([], jwtSyscalls());
|
esbuildSyscalls(),
|
||||||
|
systemSyscalls(this),
|
||||||
|
jwtSyscalls()
|
||||||
|
);
|
||||||
this.system.addHook(new EndpointHook(this.app, "/_/"));
|
this.system.addHook(new EndpointHook(this.app, "/_/"));
|
||||||
|
|
||||||
this.eventHook.addLocalListener(
|
this.eventHook.addLocalListener(
|
||||||
"get-plug:builtin",
|
"get-plug:builtin",
|
||||||
async (plugName: string): Promise<Manifest> => {
|
async (plugName: string): Promise<Manifest> => {
|
||||||
// console.log("Ok, resovling a plugin", plugName);
|
// console.log("Ok, resovling a plugin", plugName);
|
||||||
|
if (!safeFilename.test(plugName)) {
|
||||||
|
throw new Error(`Invalid plug name: ${plugName}`);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
let manifestJson = await readFile(
|
let manifestJson = await readFile(
|
||||||
path.join(this.builtinPlugDir, `${plugName}.plug.json`),
|
path.join(this.builtinPlugDir, `${plugName}.plug.json`),
|
||||||
|
@ -156,9 +171,24 @@ export class ExpressServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
|
const tokenMiddleware: (req: any, res: any, next: any) => void = this.token
|
||||||
|
? (req, res, next) => {
|
||||||
|
if (req.headers.authorization === `Bearer ${this.token}`) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
res.status(401).send("Unauthorized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: (req, res, next) => {
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
await ensurePageIndexTable(this.db);
|
await ensurePageIndexTable(this.db);
|
||||||
console.log("Setting up router");
|
console.log("Setting up router");
|
||||||
|
|
||||||
|
let auth = new Authenticator(this.db);
|
||||||
|
|
||||||
|
// Serve static files (javascript, css, html)
|
||||||
this.app.use("/", express.static(this.distDir));
|
this.app.use("/", express.static(this.distDir));
|
||||||
|
|
||||||
let fsRouter = express.Router();
|
let fsRouter = express.Router();
|
||||||
|
@ -170,8 +200,6 @@ export class ExpressServer {
|
||||||
res.json([...pages]);
|
res.json([...pages]);
|
||||||
});
|
});
|
||||||
|
|
||||||
fsRouter.route("/").post(bodyParser.json(), async (req, res) => {});
|
|
||||||
|
|
||||||
fsRouter
|
fsRouter
|
||||||
.route(/\/(.+)/)
|
.route(/\/(.+)/)
|
||||||
.get(async (req, res) => {
|
.get(async (req, res) => {
|
||||||
|
@ -242,6 +270,7 @@ export class ExpressServer {
|
||||||
|
|
||||||
this.app.use(
|
this.app.use(
|
||||||
"/fs",
|
"/fs",
|
||||||
|
tokenMiddleware,
|
||||||
cors({
|
cors({
|
||||||
methods: "GET,HEAD,PUT,OPTIONS,POST,DELETE",
|
methods: "GET,HEAD,PUT,OPTIONS,POST,DELETE",
|
||||||
preflightContinue: true,
|
preflightContinue: true,
|
||||||
|
@ -251,6 +280,8 @@ export class ExpressServer {
|
||||||
|
|
||||||
let plugRouter = express.Router();
|
let plugRouter = express.Router();
|
||||||
|
|
||||||
|
// TODO: This is currently only used for the indexer calls, it's potentially dangerous
|
||||||
|
// do we need a better solution?
|
||||||
plugRouter.post(
|
plugRouter.post(
|
||||||
"/:plug/syscall/:name",
|
"/:plug/syscall/:name",
|
||||||
bodyParser.json(),
|
bodyParser.json(),
|
||||||
|
@ -277,6 +308,7 @@ export class ExpressServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
plugRouter.post(
|
plugRouter.post(
|
||||||
"/:plug/function/:name",
|
"/:plug/function/:name",
|
||||||
bodyParser.json(),
|
bodyParser.json(),
|
||||||
|
@ -290,7 +322,6 @@ export class ExpressServer {
|
||||||
return res.send(`Plug ${plugName} not found`);
|
return res.send(`Plug ${plugName} not found`);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
console.log("Invoking", name);
|
|
||||||
const result = await plug.invoke(name, args);
|
const result = await plug.invoke(name, args);
|
||||||
res.status(200);
|
res.status(200);
|
||||||
res.send(result);
|
res.send(result);
|
||||||
|
@ -304,6 +335,7 @@ export class ExpressServer {
|
||||||
|
|
||||||
this.app.use(
|
this.app.use(
|
||||||
"/plug",
|
"/plug",
|
||||||
|
tokenMiddleware,
|
||||||
cors({
|
cors({
|
||||||
methods: "GET,HEAD,PUT,OPTIONS,POST,DELETE",
|
methods: "GET,HEAD,PUT,OPTIONS,POST,DELETE",
|
||||||
preflightContinue: true,
|
preflightContinue: true,
|
||||||
|
@ -312,13 +344,8 @@ export class ExpressServer {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Fallback, serve index.html
|
// Fallback, serve index.html
|
||||||
// let cachedIndex: string | undefined = undefined;
|
|
||||||
this.app.get("/*", async (req, res) => {
|
this.app.get("/*", async (req, res) => {
|
||||||
// if (!cachedIndex) {
|
|
||||||
// let cachedIndex = await readFile(`${this.distDir}/index.html`, "utf8");
|
|
||||||
// }
|
|
||||||
res.sendFile(`${this.distDir}/index.html`, {});
|
res.sendFile(`${this.distDir}/index.html`, {});
|
||||||
// res.status(200).header("Content-Type", "text/html").send(cachedIndex);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.server = http.createServer(this.app);
|
this.server = http.createServer(this.app);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,8 @@
|
||||||
"silverbullet": "./dist/server.js"
|
"silverbullet": "./dist/server.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "nodemon -w dist --exec 'node --enable-source-maps dist/server.js ../../pages'"
|
"start": "nodemon -w dist --exec 'node --enable-source-maps dist/server/server.js --token abc ../../pages'",
|
||||||
|
"test": "jest dist/test"
|
||||||
},
|
},
|
||||||
"targets": {
|
"targets": {
|
||||||
"server": {
|
"server": {
|
||||||
|
@ -25,6 +26,14 @@
|
||||||
"@silverbulletmd/common",
|
"@silverbulletmd/common",
|
||||||
"@silverbulletmd/web"
|
"@silverbulletmd/web"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"source": [
|
||||||
|
"auth.test.ts"
|
||||||
|
],
|
||||||
|
"outputFormat": "commonjs",
|
||||||
|
"isLibrary": true,
|
||||||
|
"context": "node"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -12,6 +12,9 @@ let args = yargs(hideBin(process.argv))
|
||||||
type: "number",
|
type: "number",
|
||||||
default: 3000,
|
default: 3000,
|
||||||
})
|
})
|
||||||
|
.option("token", {
|
||||||
|
type: "string",
|
||||||
|
})
|
||||||
.parse();
|
.parse();
|
||||||
|
|
||||||
if (!args._.length) {
|
if (!args._.length) {
|
||||||
|
@ -31,13 +34,14 @@ const plugDistDir = realpathSync(
|
||||||
);
|
);
|
||||||
console.log("Builtin plug dist dir", plugDistDir);
|
console.log("Builtin plug dist dir", plugDistDir);
|
||||||
|
|
||||||
const expressServer = new ExpressServer(
|
const expressServer = new ExpressServer({
|
||||||
port,
|
port: port,
|
||||||
pagesPath,
|
pagesPath: pagesPath,
|
||||||
webappDistDir,
|
preloadedModules: preloadModules,
|
||||||
plugDistDir,
|
distDir: webappDistDir,
|
||||||
preloadModules
|
builtinPlugDir: plugDistDir,
|
||||||
);
|
token: args.token,
|
||||||
|
});
|
||||||
expressServer.start().catch((e) => {
|
expressServer.start().catch((e) => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,40 +3,56 @@ import { safeRun } from "@silverbulletmd/common/util";
|
||||||
import { Space } from "@silverbulletmd/common/spaces/space";
|
import { Space } from "@silverbulletmd/common/spaces/space";
|
||||||
import { HttpSpacePrimitives } from "@silverbulletmd/common/spaces/http_space_primitives";
|
import { HttpSpacePrimitives } from "@silverbulletmd/common/spaces/http_space_primitives";
|
||||||
|
|
||||||
// let localSpace = new Space(new IndexedDBSpacePrimitives("pages"), true);
|
|
||||||
// localSpace.watch();
|
|
||||||
|
|
||||||
let serverSpace = new Space(new HttpSpacePrimitives(""), true);
|
|
||||||
serverSpace.watch();
|
|
||||||
|
|
||||||
console.log("Booting...");
|
|
||||||
|
|
||||||
// // @ts-ignore
|
|
||||||
// window.syncer = async () => {
|
|
||||||
// let lastLocalSync = +(localStorage.getItem("lastLocalSync") || "0"),
|
|
||||||
// lastRemoteSync = +(localStorage.getItem("lastRemoteSync") || "0");
|
|
||||||
// let syncer = new SpaceSync(
|
|
||||||
// serverSpace,
|
|
||||||
// localSpace,
|
|
||||||
// lastRemoteSync,
|
|
||||||
// lastLocalSync,
|
|
||||||
// "_trash/"
|
|
||||||
// );
|
|
||||||
// await syncer.syncPages(
|
|
||||||
// SpaceSync.primaryConflictResolver(serverSpace, localSpace)
|
|
||||||
// );
|
|
||||||
// localStorage.setItem("lastLocalSync", "" + syncer.secondaryLastSync);
|
|
||||||
// localStorage.setItem("lastRemoteSync", "" + syncer.primaryLastSync);
|
|
||||||
// console.log("Done!");
|
|
||||||
// };
|
|
||||||
let editor = new Editor(serverSpace, document.getElementById("root")!);
|
|
||||||
|
|
||||||
safeRun(async () => {
|
safeRun(async () => {
|
||||||
await editor.init();
|
// let localSpace = new Space(new IndexedDBSpacePrimitives("pages"), true);
|
||||||
});
|
// localSpace.watch();
|
||||||
|
let token: string | undefined = sessionStorage.getItem("token") || undefined;
|
||||||
|
|
||||||
// @ts-ignore
|
let httpPrimitives = new HttpSpacePrimitives("", token);
|
||||||
window.editor = editor;
|
while (true) {
|
||||||
|
try {
|
||||||
|
await httpPrimitives.getPageMeta("start");
|
||||||
|
break;
|
||||||
|
} catch (e: any) {
|
||||||
|
if (e.message === "Unauthorized") {
|
||||||
|
token = prompt("Token: ") || undefined;
|
||||||
|
if (!token) {
|
||||||
|
alert("Sorry, that's it then");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sessionStorage.setItem("token", token!);
|
||||||
|
httpPrimitives = new HttpSpacePrimitives("", token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let serverSpace = new Space(httpPrimitives, true);
|
||||||
|
serverSpace.watch();
|
||||||
|
|
||||||
|
console.log("Booting...");
|
||||||
|
|
||||||
|
// // @ts-ignore
|
||||||
|
// window.syncer = async () => {
|
||||||
|
// let lastLocalSync = +(localStorage.getItem("lastLocalSync") || "0"),
|
||||||
|
// lastRemoteSync = +(localStorage.getItem("lastRemoteSync") || "0");
|
||||||
|
// let syncer = new SpaceSync(
|
||||||
|
// serverSpace,
|
||||||
|
// localSpace,
|
||||||
|
// lastRemoteSync,
|
||||||
|
// lastLocalSync,
|
||||||
|
// "_trash/"
|
||||||
|
// );
|
||||||
|
// await syncer.syncPages(
|
||||||
|
// SpaceSync.primaryConflictResolver(serverSpace, localSpace)
|
||||||
|
// );
|
||||||
|
// localStorage.setItem("lastLocalSync", "" + syncer.secondaryLastSync);
|
||||||
|
// localStorage.setItem("lastRemoteSync", "" + syncer.primaryLastSync);
|
||||||
|
// console.log("Done!");
|
||||||
|
// };
|
||||||
|
let editor = new Editor(serverSpace, document.getElementById("root")!);
|
||||||
|
await editor.init();
|
||||||
|
// @ts-ignore
|
||||||
|
window.editor = editor;
|
||||||
|
});
|
||||||
|
|
||||||
// if (!isDesktop) {
|
// if (!isDesktop) {
|
||||||
// if (localStorage.getItem("disable_sw") !== "true") {
|
// if (localStorage.getItem("disable_sw") !== "true") {
|
||||||
|
|
|
@ -28,10 +28,9 @@ import { CommandPalette } from "./components/command_palette";
|
||||||
import { PageNavigator } from "./components/page_navigator";
|
import { PageNavigator } from "./components/page_navigator";
|
||||||
import { TopBar } from "./components/top_bar";
|
import { TopBar } from "./components/top_bar";
|
||||||
import { lineWrapper } from "./line_wrapper";
|
import { lineWrapper } from "./line_wrapper";
|
||||||
import { markdown } from "./markdown";
|
import { markdown } from "@silverbulletmd/common/markdown";
|
||||||
import { PathPageNavigator } from "./navigator";
|
import { PathPageNavigator } from "./navigator";
|
||||||
import customMarkDown from "./parser";
|
import buildMarkdown from "@silverbulletmd/common/parser";
|
||||||
import buildMarkdown from "./parser";
|
|
||||||
import reducer from "./reducer";
|
import reducer from "./reducer";
|
||||||
import { smartQuoteKeymap } from "./smart_quotes";
|
import { smartQuoteKeymap } from "./smart_quotes";
|
||||||
import { Space } from "@silverbulletmd/common/spaces/space";
|
import { Space } from "@silverbulletmd/common/spaces/space";
|
||||||
|
@ -52,7 +51,10 @@ import { pasteLinkExtension } from "./editor_paste";
|
||||||
import { markdownSyscalls } from "@silverbulletmd/common/syscalls/markdown";
|
import { markdownSyscalls } from "@silverbulletmd/common/syscalls/markdown";
|
||||||
import { clientStoreSyscalls } from "./syscalls/clientStore";
|
import { clientStoreSyscalls } from "./syscalls/clientStore";
|
||||||
import { StatusBar } from "./components/status_bar";
|
import { StatusBar } from "./components/status_bar";
|
||||||
import { loadMarkdownExtensions, MDExt } from "./markdown_ext";
|
import {
|
||||||
|
loadMarkdownExtensions,
|
||||||
|
MDExt,
|
||||||
|
} from "@silverbulletmd/common/markdown_ext";
|
||||||
import { FilterList } from "./components/filter";
|
import { FilterList } from "./components/filter";
|
||||||
import { FilterOption } from "@silverbulletmd/common/types";
|
import { FilterOption } from "@silverbulletmd/common/types";
|
||||||
import { syntaxTree } from "@codemirror/language";
|
import { syntaxTree } from "@codemirror/language";
|
||||||
|
@ -402,7 +404,7 @@ export class Editor {
|
||||||
),
|
),
|
||||||
pasteLinkExtension,
|
pasteLinkExtension,
|
||||||
markdown({
|
markdown({
|
||||||
base: customMarkDown(this.mdExtensions),
|
base: buildMarkdown(this.mdExtensions),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { HighlightStyle, tags as t } from "@codemirror/highlight";
|
import { HighlightStyle, tags as t } from "@codemirror/highlight";
|
||||||
import * as ct from "./customtags";
|
import * as ct from "@silverbulletmd/common/customtags";
|
||||||
import { MDExt } from "./markdown_ext";
|
import { MDExt } from "@silverbulletmd/common/markdown_ext";
|
||||||
|
|
||||||
export default function highlightStyles(mdExtension: MDExt[]) {
|
export default function highlightStyles(mdExtension: MDExt[]) {
|
||||||
return HighlightStyle.define([
|
return HighlightStyle.define([
|
||||||
|
|
Loading…
Reference in New Issue