From 32f350177349cf540c81f60b96f66f20d13f7c92 Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Thu, 21 Apr 2022 11:46:33 +0200 Subject: [PATCH] Exposing `fetch` to functions and initial work on Electron --- desktop/main.js | 70 +++ desktop/preload.js | 5 + package.json | 5 +- plugos/environments/node_worker.ts | 17 +- plugos/environments/sandbox_worker.ts | 2 +- plugos/package.json | 1 + plugos/yarn.lock | 5 + plugs/core/core.plug.yaml | 11 - plugs/core/page.ts | 39 +- plugs/core/template.ts | 24 +- plugs/markdown/util.ts | 11 +- plugs/mattermost/client.ts | 120 ------ plugs/mattermost/mattermost.ts | 50 ++- plugs/package.json | 3 +- plugs/query/command.ts | 7 + plugs/query/data.ts | 11 +- plugs/query/engine.test.ts | 9 + plugs/query/engine.ts | 21 + plugs/query/parse-query.js | 24 +- plugs/query/parse-query.terms.js | 3 +- plugs/query/query.grammar | 7 +- plugs/query/query.plug.yaml | 4 + plugs/query/util.ts | 25 ++ plugs/tasks/task.ts | 168 +++++--- plugs/tasks/tasks.plug.yaml | 15 +- plugs/yarn.lock | 599 ++++++++++++++------------ webapp/boot.ts | 63 +-- webapp/components/filter.tsx | 2 +- webapp/editor.tsx | 22 +- webapp/hooks/command.ts | 2 + webapp/reducer.ts | 11 + webapp/types.ts | 5 +- yarn.lock | 20 +- 33 files changed, 810 insertions(+), 571 deletions(-) create mode 100644 desktop/main.js create mode 100644 desktop/preload.js delete mode 100644 plugs/mattermost/client.ts create mode 100644 plugs/query/command.ts diff --git a/desktop/main.js b/desktop/main.js new file mode 100644 index 00000000..8e7b9e52 --- /dev/null +++ b/desktop/main.js @@ -0,0 +1,70 @@ +const { app, BrowserWindow, protocol } = require("electron"); +const path = require("path"); + +console.log("Got here", process.version); + +const createWindow = () => { + const WEB_FOLDER = "../dist/webapp"; + const PROTOCOL = "file"; + + protocol.interceptFileProtocol(PROTOCOL, (request, callback) => { + // Strip protocol + let url = request.url.substring(PROTOCOL.length + 2); + if (url.endsWith("/")) { + url = url.substring(0, url.length - 1); + } + + console.log("Requested url", url); + + if (!/\.(js|css|png|webmanifest|map)/.exec(url)) { + url = "/index.html"; + } + + if (url.includes("/service_worker.js?")) { + url = "/service_worker.js"; + } + + // if (!url.includes(".")) { + // url = "/index.html"; + // } + + // Build complete path for node require function + url = path.join(__dirname, WEB_FOLDER, url); + + // Replace backslashes by forward slashes (windows) + // url = url.replace(/\\/g, '/'); + url = path.normalize(url); + + // console.log("Requested path", url); + callback({ path: url }); + }); + + // Create the browser window. + let mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + // nodeIntegration: false, + preload: path.join(__dirname, "preload.js"), + }, + }); + + // and load the index.html of the app. + mainWindow.loadURL("file://start"); + // url.format({ + // pathname: "index.html", + // protocol: PROTOCOL + ":", + // slashes: true, + // }) + // ); +}; +app.on("window-all-closed", () => { + if (process.platform !== "darwin") app.quit(); +}); +app.whenReady().then(() => { + createWindow(); + + app.on("activate", () => { + if (BrowserWindow.getAllWindows().length === 0) createWindow(); + }); +}); diff --git a/desktop/preload.js b/desktop/preload.js new file mode 100644 index 00000000..be8a7cf1 --- /dev/null +++ b/desktop/preload.js @@ -0,0 +1,5 @@ +const { contextBridge } = require("electron"); + +contextBridge.exposeInMainWorld("desktop", { + url: "http://localhost:3000", +}); diff --git a/package.json b/package.json index 314083f1..001499fa 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,9 @@ "plugs/query/engine.test.ts", "common/spaces/sync.test.ts" ], - "includeNodeModules": ["@codemirror/legacy-modes"], + "includeNodeModules": [ + "@codemirror/legacy-modes" + ], "outputFormat": "commonjs", "isLibrary": true, "context": "node" @@ -85,6 +87,7 @@ "react-dom": "^17.0.2", "supertest": "^6.2.2", "vm2": "^3.9.9", + "ws": "^8.5.0", "yaml": "^1.10.2", "yargs": "^17.3.1" }, diff --git a/plugos/environments/node_worker.ts b/plugos/environments/node_worker.ts index a4e5822e..c82a48b4 100644 --- a/plugos/environments/node_worker.ts +++ b/plugos/environments/node_worker.ts @@ -1,9 +1,9 @@ import { preloadModules } from "../../common/preload_modules"; const { parentPort, workerData } = require("worker_threads"); -// @ts-ignore -let vm2 = `${workerData}/vm2`; -const { VM, VMScript } = require(vm2); +const { VM, VMScript } = require(`${workerData}/vm2`); +const fetch = require(`${workerData}/node-fetch`); +const WebSocket = require(`${workerData}/ws`); // console.log("Process env", process.env); @@ -20,11 +20,16 @@ let syscallReqId = 0; let vm = new VM({ sandbox: { + // Exposing some "safe" APIs console, setTimeout, clearTimeout, setInterval, clearInterval, + fetch, + WebSocket, + // This is only going to be called for pre-bundled modules, we won't allow + // arbitrary requiring of modules require: (moduleName: string): any => { // console.log("Loading", moduleName); if (preloadModules.includes(moduleName)) { @@ -97,12 +102,6 @@ parentPort.on("message", (data: any) => { let syscallId = data.id; const lookup = pendingRequests.get(syscallId); if (!lookup) { - console.log( - "Current outstanding requests", - pendingRequests, - "looking up", - syscallId - ); throw Error("Invalid request id"); } pendingRequests.delete(syscallId); diff --git a/plugos/environments/sandbox_worker.ts b/plugos/environments/sandbox_worker.ts index 068d3835..3f3fd56c 100644 --- a/plugos/environments/sandbox_worker.ts +++ b/plugos/environments/sandbox_worker.ts @@ -48,7 +48,7 @@ const preloadedModules: { [key: string]: any } = { // @ts-ignore self.require = (moduleName: string): any => { - console.log("Loading", moduleName, preloadedModules[moduleName]); + // console.log("Loading", moduleName, preloadedModules[moduleName]); return preloadedModules[moduleName]; }; diff --git a/plugos/package.json b/plugos/package.json index dcdab16e..9cc24033 100644 --- a/plugos/package.json +++ b/plugos/package.json @@ -57,6 +57,7 @@ "node-watch": "^0.7.3", "supertest": "^6.2.2", "vm2": "^3.9.9", + "ws": "^8.5.0", "yaml": "^1.10.2", "yargs": "^17.3.1" }, diff --git a/plugos/yarn.lock b/plugos/yarn.lock index 81353e5b..63fc51d2 100644 --- a/plugos/yarn.lock +++ b/plugos/yarn.lock @@ -5566,6 +5566,11 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== +ws@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" diff --git a/plugs/core/core.plug.yaml b/plugs/core/core.plug.yaml index 4dccdc2a..be3ea0ca 100644 --- a/plugs/core/core.plug.yaml +++ b/plugs/core/core.plug.yaml @@ -103,14 +103,3 @@ functions: path: ./template.ts:instantiateTemplateCommand command: name: "Template: Instantiate for Page" - - instantiateTemplate: - path: ./template.ts:instantiateTemplate - env: server - - - - replaceTemplateVarsCommand: - path: ./template.ts:replaceTemplateVarsCommand - command: - name: "Template: Replace Variables" diff --git a/plugs/core/page.ts b/plugs/core/page.ts index e00b475c..b915e69a 100644 --- a/plugs/core/page.ts +++ b/plugs/core/page.ts @@ -3,7 +3,8 @@ import { batchSet, clearPageIndex as clearPageIndexSyscall, clearPageIndexForPage, - scanPrefixGlobal + scanPrefixGlobal, + set } from "plugos-silverbullet-syscall/index"; import { flashNotification, @@ -27,11 +28,22 @@ import { } from "../../common/tree"; import { applyQuery, QueryProviderEvent } from "../query/engine"; import { PageMeta } from "../../common/types"; +import { extractMeta } from "../query/data"; +import { jsonToMDTable } from "../query/util"; + +// Key space: +// pl:toPage:pos => pageName +// meta => metaJson export async function indexLinks({ name, tree }: IndexTreeEvent) { let backLinks: { key: string; value: string }[] = []; // [[Style Links]] console.log("Now indexing", name); + let pageMeta = extractMeta(tree); + if (Object.keys(pageMeta).length > 0) { + await set(name, "meta:", pageMeta); + } + collectNodesMatching(tree, (n) => n.type === "WikiLinkPage").forEach((n) => { let toPage = n.children![0].text!; if (toPage.includes("@")) { @@ -50,10 +62,27 @@ export async function pageQueryProvider({ query, }: QueryProviderEvent): Promise { let allPages = await listPages(); - let markdownPages = applyQuery(query, allPages).map( - (pageMeta: PageMeta) => `* [[${pageMeta.name}]]` - ); - return markdownPages.join("\n"); + if (query.select) { + let allPageMap: Map = new Map( + allPages.map((pm) => [pm.name, pm]) + ); + for (let { page, value } of await scanPrefixGlobal("meta:")) { + let p = allPageMap.get(page); + if (p) { + for (let [k, v] of Object.entries(value)) { + p[k] = v; + } + } + } + allPages = [...allPageMap.values()]; + return jsonToMDTable(applyQuery(query, allPages), (k, v) => + k === "name" ? `[[${v}]]` : v + ); + } else { + return applyQuery(query, allPages) + .map((pageMeta: PageMeta) => `* [[${pageMeta.name}]]`) + .join("\n"); + } } export async function linkQueryProvider({ diff --git a/plugs/core/template.ts b/plugs/core/template.ts index 53bef7d1..61038bbb 100644 --- a/plugs/core/template.ts +++ b/plugs/core/template.ts @@ -1,10 +1,9 @@ import { listPages, readPage, writePage } from "plugos-silverbullet-syscall/space"; -import { filterBox, getCurrentPage, getText, navigate, prompt } from "plugos-silverbullet-syscall/editor"; +import { filterBox, navigate, prompt } from "plugos-silverbullet-syscall/editor"; import { parseMarkdown } from "plugos-silverbullet-syscall/markdown"; import { extractMeta } from "../query/data"; import { renderToText } from "../../common/tree"; import { niceDate } from "./dates"; -import { invokeFunction } from "plugos-silverbullet-syscall/system"; const pageTemplatePrefix = `template/page/`; @@ -35,26 +34,9 @@ export async function instantiateTemplateCommand() { if (!pageName) { return; } - await invokeFunction( - "server", - "instantiateTemplate", - pageName, - renderToText(parseTree) - ); - // let pageText = replaceTemplateVars(, pageName); - // await writePage(pageName, pageText); - await navigate(pageName); -} - -export async function instantiateTemplate(pageName: string, text: string) { - let pageText = replaceTemplateVars(text, pageName); + let pageText = replaceTemplateVars(renderToText(parseTree), pageName); await writePage(pageName, pageText); -} - -export async function replaceTemplateVarsCommand() { - let currentPage = await getCurrentPage(); - let text = await getText(); - await invokeFunction("server", "instantiateTemplate", currentPage, text); + await navigate(pageName); } export function replaceTemplateVars(s: string, pageName: string): string { diff --git a/plugs/markdown/util.ts b/plugs/markdown/util.ts index 81423466..89422577 100644 --- a/plugs/markdown/util.ts +++ b/plugs/markdown/util.ts @@ -1,4 +1,4 @@ -import { renderToText, replaceNodesMatching } from "../../common/tree"; +import { findNodeOfType, renderToText, replaceNodesMatching } from "../../common/tree"; import { parseMarkdown } from "plugos-silverbullet-syscall/markdown"; export function encodePageUrl(name: string): string { @@ -19,6 +19,15 @@ export async function cleanMarkdown(text: string): Promise { if (n.type === "CommentBlock" || n.type === "Comment") { return null; } + if (n.type === "FencedCode") { + let codeInfoNode = findNodeOfType(n, "CodeInfo"); + if (!codeInfoNode) { + return; + } + if (codeInfoNode.children![0].text === "meta") { + return null; + } + } }); return renderToText(mdTree); } diff --git a/plugs/mattermost/client.ts b/plugs/mattermost/client.ts deleted file mode 100644 index 378f815b..00000000 --- a/plugs/mattermost/client.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { readPage } from "plugos-silverbullet-syscall/space"; -import { parseMarkdown } from "plugos-silverbullet-syscall/markdown"; -import { extractMeta } from "../query/data"; -import { json } from "plugos-syscall/fetch"; -import type { UserProfile } from "@mattermost/types/lib/users"; -import type { Post } from "@mattermost/types/lib/posts"; -import type { Channel } from "@mattermost/types/lib/channels"; -import type { Team } from "@mattermost/types/lib/teams"; -import { niceDate } from "../core/dates"; - -type MattermostConfig = { - url: string; - token: string; -}; - -async function getConfig(): Promise { - let { text } = await readPage("mattermost-config"); - let parsedContent = await parseMarkdown(text); - let pageMeta = await extractMeta(parsedContent); - return pageMeta as MattermostConfig; -} - -type AugmentedPost = Post & { - // Dates we can use to filter - createdAt: string; - updatedAt: string; - editedAt: string; -}; - -export class MattermostClient { - userCache = new Map(); - channelCache = new Map(); - teamCache = new Map(); - - constructor(readonly url: string, readonly token: string) {} - - static async fromConfig(): Promise { - let config = await getConfig(); - return new MattermostClient(config.url, config.token); - } - - getMe(): Promise { - return this.getUser("me"); - } - - async getUser(userId: string): Promise { - let user = this.userCache.get(userId); - if (user) { - return user; - } - user = await json(`${this.url}/api/v4/users/${userId}`, { - headers: { - Authorization: `Bearer ${this.token}`, - }, - }); - this.userCache.set(userId, user!); - return user!; - } - - async getChannel(channelId: string): Promise { - let channel = this.channelCache.get(channelId); - if (channel) { - return channel; - } - channel = await json(`${this.url}/api/v4/channels/${channelId}`, { - headers: { - Authorization: `Bearer ${this.token}`, - }, - }); - this.channelCache.set(channelId, channel!); - return channel!; - } - - async getTeam(teamId: string): Promise { - let team = this.teamCache.get(teamId); - if (team) { - return team; - } - team = await json(`${this.url}/api/v4/teams/${teamId}`, { - headers: { - Authorization: `Bearer ${this.token}`, - }, - }); - this.teamCache.set(teamId, team!); - return team!; - } - - async getFlaggedPosts( - userId: string, - perPage: number = 10 - ): Promise { - let postCollection = await json( - `${this.url}/api/v4/users/${userId}/posts/flagged?per_page=${perPage}`, - { - headers: { - Authorization: `Bearer ${this.token}`, - }, - } - ); - let posts: AugmentedPost[] = []; - for (let order of postCollection.order) { - let post = postCollection.posts[order]; - augmentPost(post); - posts.push(post); - } - return posts; - } -} - -function augmentPost(post: AugmentedPost) { - if (post.create_at) { - post.createdAt = niceDate(new Date(post.create_at)); - } - if (post.update_at) { - post.updatedAt = niceDate(new Date(post.update_at)); - } - if (post.edit_at) { - post.editedAt = niceDate(new Date(post.edit_at)); - } -} diff --git a/plugs/mattermost/mattermost.ts b/plugs/mattermost/mattermost.ts index c6034208..0fe8e346 100644 --- a/plugs/mattermost/mattermost.ts +++ b/plugs/mattermost/mattermost.ts @@ -1,5 +1,17 @@ -import { MattermostClient } from "./client"; +import { Client4 } from "@mattermost/client"; import { applyQuery, QueryProviderEvent } from "../query/engine"; +import { readPage } from "plugos-silverbullet-syscall/space"; +import { parseMarkdown } from "plugos-silverbullet-syscall/markdown"; +import { extractMeta } from "../query/data"; +import { niceDate } from "../core/dates"; +import { Post } from "@mattermost/types/lib/posts"; + +type AugmentedPost = Post & { + // Dates we can use to filter + createdAt: string; + updatedAt: string; + editedAt: string; +}; // https://community.mattermost.com/private-core/pl/rbp7a7jtr3f89nzsefo6ftqt3o @@ -10,13 +22,45 @@ function mattermostDesktopUrlForPost( ) { return `${url.replace("https://", "mattermost://")}/${teamName}/pl/${postId}`; } +type MattermostConfig = { + url: string; + token: string; +}; + +async function getConfig(): Promise { + let { text } = await readPage("mattermost-config"); + let parsedContent = await parseMarkdown(text); + let pageMeta = await extractMeta(parsedContent); + return pageMeta as MattermostConfig; +} + +function augmentPost(post: AugmentedPost) { + if (post.create_at) { + post.createdAt = niceDate(new Date(post.create_at)); + } + if (post.update_at) { + post.updatedAt = niceDate(new Date(post.update_at)); + } + if (post.edit_at) { + post.editedAt = niceDate(new Date(post.edit_at)); + } +} export async function savedPostsQueryProvider({ query, }: QueryProviderEvent): Promise { - let client = await MattermostClient.fromConfig(); + let config = await getConfig(); + let client = new Client4(); + client.setUrl(config.url); + client.setToken(config.token); let me = await client.getMe(); - let savedPosts = await client.getFlaggedPosts(me.id); + let postCollection = await client.getFlaggedPosts(me.id); + let savedPosts: AugmentedPost[] = []; + for (let order of postCollection.order) { + let post = postCollection.posts[order]; + augmentPost(post); + savedPosts.push(post); + } let savedPostsMd = []; savedPosts = applyQuery(query, savedPosts); for (let savedPost of savedPosts) { diff --git a/plugs/package.json b/plugs/package.json index 4f737180..ebed1cfb 100644 --- a/plugs/package.json +++ b/plugs/package.json @@ -5,10 +5,11 @@ "generate": "lezer-generator query/query.grammar -o query/parse-query.js" }, "dependencies": { - "@mattermost/types": "^6.7.0-0", "@jest/globals": "^27.5.1", "@lezer/generator": "^0.15.4", "@lezer/lr": "^0.15.8", + "@mattermost/client": "^6.7.0-0", + "@mattermost/types": "^6.7.0-0", "@types/yaml": "^1.9.7", "plugos-silverbullet-syscall": "file:../plugos-silverbullet-syscall", "plugos-syscall": "file:../plugos-syscall", diff --git a/plugs/query/command.ts b/plugs/query/command.ts new file mode 100644 index 00000000..e7678142 --- /dev/null +++ b/plugs/query/command.ts @@ -0,0 +1,7 @@ +import { getCursor, insertAtCursor, moveCursor } from "plugos-silverbullet-syscall/editor"; + +export async function insertQuery() { + let cursorPos = await getCursor(); + await insertAtCursor(`\n\n`); + await moveCursor(cursorPos + 12); +} diff --git a/plugs/query/data.ts b/plugs/query/data.ts index c07c0338..b165a3d5 100644 --- a/plugs/query/data.ts +++ b/plugs/query/data.ts @@ -4,13 +4,16 @@ import { IndexTreeEvent } from "../../webapp/app_event"; import { batchSet, scanPrefixGlobal } from "plugos-silverbullet-syscall"; import { collectNodesOfType, findNodeOfType, ParseTree, replaceNodesMatching } from "../../common/tree"; -import YAML, { parse as parseYaml, parseAllDocuments } from "yaml"; +import { parse as parseYaml, parseAllDocuments } from "yaml"; import type { QueryProviderEvent } from "./engine"; import { applyQuery } from "./engine"; +import { jsonToMDTable, removeQueries } from "./util"; export async function indexData({ name, tree }: IndexTreeEvent) { let dataObjects: { key: string; value: Object }[] = []; + removeQueries(tree); + collectNodesOfType(tree, "FencedCode").forEach((t) => { let codeInfoNode = findNodeOfType(t, "CodeInfo"); if (!codeInfoNode) { @@ -85,8 +88,6 @@ export async function queryProvider({ pos: +pos, }); } - let markdownData = applyQuery(query, allData).map((item) => - YAML.stringify(item) - ); - return `\`\`\`data\n${markdownData.join("---\n")}\`\`\``; + let resultData = applyQuery(query, allData); + return jsonToMDTable(resultData); } diff --git a/plugs/query/engine.test.ts b/plugs/query/engine.test.ts index cef74c39..8c5c2e49 100644 --- a/plugs/query/engine.test.ts +++ b/plugs/query/engine.test.ts @@ -41,6 +41,12 @@ test("Test parser", () => { prop: "something", value: null, }); + + expect(parseQuery(`page select name`).select).toStrictEqual(["name"]); + expect(parseQuery(`page select name, age`).select).toStrictEqual([ + "name", + "age", + ]); }); test("Test performing the queries", () => { @@ -83,4 +89,7 @@ test("Test performing the queries", () => { expect( applyQuery(parseQuery(`page where age > 28 and age < 38`), data) ).toStrictEqual([]); + expect( + applyQuery(parseQuery(`page where age > 30 select name`), data) + ).toStrictEqual([{ name: "Pete" }]); }); diff --git a/plugs/query/engine.ts b/plugs/query/engine.ts index df524fd0..28eb9289 100644 --- a/plugs/query/engine.ts +++ b/plugs/query/engine.ts @@ -21,6 +21,7 @@ export type ParsedQuery = { orderDesc?: boolean; limit?: number; filter: Filter[]; + select?: string[]; }; export function parseQuery(query: string): ParsedQuery { @@ -90,6 +91,17 @@ export function parseQuery(query: string): ParsedQuery { }; parsedQuery.filter.push(f); } + let selectNode = findNodeOfType(queryNode, "SelectClause"); + if (selectNode) { + console.log("Select node", JSON.stringify(selectNode)); + parsedQuery.select = []; + collectNodesOfType(selectNode, "Name").forEach((t) => { + parsedQuery.select!.push(t.children![0].text!); + }); + // let nameNode = findNodeOfType(selectNode, "Number"); + // parsedQuery.limit = +nameNode!.children![0].text!; + } + // console.log(JSON.stringify(queryNode, null, 2)); return parsedQuery; } @@ -168,5 +180,14 @@ export function applyQuery(parsedQuery: ParsedQuery, records: T[]): T[] { if (parsedQuery.limit) { resultRecords = resultRecords.slice(0, parsedQuery.limit); } + if (parsedQuery.select) { + resultRecords = resultRecords.map((rec) => { + let newRec: any = {}; + for (let k of parsedQuery.select!) { + newRec[k] = rec[k]; + } + return newRec; + }); + } return resultRecords; } diff --git a/plugs/query/parse-query.js b/plugs/query/parse-query.js index 6fe25cb3..2bd54e9d 100644 --- a/plugs/query/parse-query.js +++ b/plugs/query/parse-query.js @@ -3,19 +3,15 @@ import { LRParser } from "@lezer/lr"; export const parser = LRParser.deserialize({ version: 13, - states: - "$[OVQPOOO[QQO'#C^QOQPOOOjQPO'#C`OoQQO'#CjOtQPO'#ClOOQO'#Cm'#CmOyQQO,58xO!XQPO'#CcO!sQQO'#CaOOQO'#Ca'#CaOOQO,58z,58zO#UQPO,59UOOQO,59W,59WOOQO-E6k-E6kO#ZQQO,58}OjQPO,58|O#oQQO1G.pOOQO'#Cg'#CgOOQO'#Ci'#CiOOQO'#Cd'#CdOOQO1G.i1G.iOOQO1G.h1G.hOOQO'#Ck'#CkOOQO7+$[7+$[", - stateData: - "$T~OdOS~ORPO~OeROrSOvTObQX~ORWO~Os[O~OX]O~OeROrSOvTObQa~Of_Oj_Ok_Ol_Om_On_Oo_Op_O~Oq`ObTXeTXrTXvTX~ORaO~OXdOYdO[dOgbOhbOicO~OtgOugOb^ie^ir^iv^i~O", - goto: "!VbPPcPfjmpvPPyPyf|f!PRQOTUPVRZRRYRQXRRf`Re_Rd_RhaQVPR^V", - nodeNames: - "⚠ Program Query Name WhereClause LogicalExpr AndExpr FilterExpr Value Number String Bool Regex Null OrderClause Order LimitClause", - maxTerm: 38, + states: "%WOVQPOOO[QQO'#C^QOQPOOOmQPO'#C`OrQQO'#CjOwQPO'#ClO|QPO'#CmOOQO'#Cn'#CnO!RQQO,58xO!dQPO'#CcO#OQQO'#CaOOQO'#Ca'#CaOOQO,58z,58zO#dQPO,59UOOQO,59W,59WO#iQQO'#DWOOQO,59X,59XOOQO-E6l-E6lO#}QQO,58}OmQPO,58|O$cQQO1G.pO$zQPO'#CoO%PQQO,59rOOQO'#Cg'#CgOOQO'#Ci'#CiOOQO'#Cd'#CdOOQO1G.i1G.iOOQO1G.h1G.hOOQO'#Ck'#CkOOQO7+$[7+$[OOQO,59Z,59ZOOQO-E6m-E6m", + stateData: "%e~OfOS~ORPO~OgROtSOxTOyUOdQX~ORXO~Ou]O~OX^O~OR_O~OgROtSOxTOyUOdQa~OhbOlbOmbOnbOobOpbOqbOrbO~OscOdTXgTXtTXxTXyTX~ORdO~O{eOdzXgzXtzXxzXyzX~OXiOYiO[iOigOjgOkhO~OvlOwlOd^ig^it^ix^iy^i~ORnO~O{eOdzagzatzaxzayza~O", + goto: "!y{PP|P!P!T!W!Z!aPP!dP!d!P!g!P!P!j!pPPPPPPPPPPPPPPPPPPPPPP!vRQOTVPWR[RRZRQYRRkcRjbRibRmdQWPRaWQf_RofR`U", + nodeNames: "⚠ Program Query Name WhereClause LogicalExpr AndExpr FilterExpr Value Number String Bool Regex Null OrderClause Order LimitClause SelectClause", + maxTerm: 43, skippedNodes: [0], - repeatNodeCount: 1, - tokenData: - ":W~RvX^#ipq#iqr$^rs$q}!O%]!P!Q%n!Q![&e!^!_&m!_!`&z!`!a'X!c!}%]#R#S%]#T#U'f#U#V){#V#W%]#W#X*w#X#Y%]#Y#Z,s#Z#`%]#`#a/T#a#b%]#b#c1h#c#d3d#d#h%]#h#i5w#i#k%]#k#l7s#l#o%]#y#z#i$f$g#i#BY#BZ#i$IS$I_#i$Ip$Iq$q$Iq$Ir$q$I|$JO#i$JT$JU#i$KV$KW#i&FU&FV#i~#nYd~X^#ipq#i#y#z#i$f$g#i#BY#BZ#i$IS$I_#i$I|$JO#i$JT$JU#i$KV$KW#i&FU&FV#i~$aP!_!`$d~$iPl~#r#s$l~$qOp~~$tUOr$qrs%Ws$Ip$q$Ip$Iq%W$Iq$Ir%W$Ir~$q~%]OY~P%bSRP}!O%]!c!}%]#R#S%]#T#o%]~%sV[~OY%nZ]%n^!P%n!P!Q&Y!Q#O%n#O#P&_#P~%n~&_O[~~&bPO~%n~&jPX~!Q![&e~&rPf~!_!`&u~&zOj~~'PPk~#r#s'S~'XOo~~'^Pn~!_!`'a~'fOm~R'kWRP}!O%]!c!}%]#R#S%]#T#b%]#b#c(T#c#g%]#g#h)P#h#o%]R(YURP}!O%]!c!}%]#R#S%]#T#W%]#W#X(l#X#o%]R(sSqQRP}!O%]!c!}%]#R#S%]#T#o%]R)UURP}!O%]!c!}%]#R#S%]#T#V%]#V#W)h#W#o%]R)oSuQRP}!O%]!c!}%]#R#S%]#T#o%]R*QURP}!O%]!c!}%]#R#S%]#T#m%]#m#n*d#n#o%]R*kSsQRP}!O%]!c!}%]#R#S%]#T#o%]R*|URP}!O%]!c!}%]#R#S%]#T#X%]#X#Y+`#Y#o%]R+eURP}!O%]!c!}%]#R#S%]#T#g%]#g#h+w#h#o%]R+|URP}!O%]!c!}%]#R#S%]#T#V%]#V#W,`#W#o%]R,gStQRP}!O%]!c!}%]#R#S%]#T#o%]R,xTRP}!O%]!c!}%]#R#S%]#T#U-X#U#o%]R-^URP}!O%]!c!}%]#R#S%]#T#`%]#`#a-p#a#o%]R-uURP}!O%]!c!}%]#R#S%]#T#g%]#g#h.X#h#o%]R.^URP}!O%]!c!}%]#R#S%]#T#X%]#X#Y.p#Y#o%]R.wShQRP}!O%]!c!}%]#R#S%]#T#o%]R/YURP}!O%]!c!}%]#R#S%]#T#]%]#]#^/l#^#o%]R/qURP}!O%]!c!}%]#R#S%]#T#a%]#a#b0T#b#o%]R0YURP}!O%]!c!}%]#R#S%]#T#]%]#]#^0l#^#o%]R0qURP}!O%]!c!}%]#R#S%]#T#h%]#h#i1T#i#o%]R1[SvQRP}!O%]!c!}%]#R#S%]#T#o%]R1mURP}!O%]!c!}%]#R#S%]#T#i%]#i#j2P#j#o%]R2UURP}!O%]!c!}%]#R#S%]#T#`%]#`#a2h#a#o%]R2mURP}!O%]!c!}%]#R#S%]#T#`%]#`#a3P#a#o%]R3WSiQRP}!O%]!c!}%]#R#S%]#T#o%]R3iURP}!O%]!c!}%]#R#S%]#T#f%]#f#g3{#g#o%]R4QURP}!O%]!c!}%]#R#S%]#T#W%]#W#X4d#X#o%]R4iURP}!O%]!c!}%]#R#S%]#T#X%]#X#Y4{#Y#o%]R5QURP}!O%]!c!}%]#R#S%]#T#f%]#f#g5d#g#o%]R5kSrQRP}!O%]!c!}%]#R#S%]#T#o%]R5|URP}!O%]!c!}%]#R#S%]#T#f%]#f#g6`#g#o%]R6eURP}!O%]!c!}%]#R#S%]#T#i%]#i#j6w#j#o%]R6|URP}!O%]!c!}%]#R#S%]#T#X%]#X#Y7`#Y#o%]R7gSgQRP}!O%]!c!}%]#R#S%]#T#o%]R7xURP}!O%]!c!}%]#R#S%]#T#[%]#[#]8[#]#o%]R8aURP}!O%]!c!}%]#R#S%]#T#X%]#X#Y8s#Y#o%]R8xURP}!O%]!c!}%]#R#S%]#T#f%]#f#g9[#g#o%]R9aURP}!O%]!c!}%]#R#S%]#T#X%]#X#Y9s#Y#o%]R9zSeQRP}!O%]!c!}%]#R#S%]#T#o%]", + repeatNodeCount: 2, + tokenData: "=_~RxX^#opq#oqr$drs$w|}%c}!O%h!P!Q%y!Q![&p!^!_&x!_!`'V!`!a'd!c!}%h#R#S%h#T#U'q#U#V*W#V#W%h#W#X+S#X#Y%h#Y#Z-O#Z#`%h#`#a/`#a#b%h#b#c1s#c#d3o#d#g%h#g#h6S#h#i9O#i#k%h#k#l:z#l#o%h#y#z#o$f$g#o#BY#BZ#o$IS$I_#o$Ip$Iq$w$Iq$Ir$w$I|$JO#o$JT$JU#o$KV$KW#o&FU&FV#o~#tYf~X^#opq#o#y#z#o$f$g#o#BY#BZ#o$IS$I_#o$I|$JO#o$JT$JU#o$KV$KW#o&FU&FV#o~$gP!_!`$j~$oPn~#r#s$r~$wOr~~$zUOr$wrs%^s$Ip$w$Ip$Iq%^$Iq$Ir%^$Ir~$w~%cOY~~%hO{~P%mSRP}!O%h!c!}%h#R#S%h#T#o%h~&OV[~OY%yZ]%y^!P%y!P!Q&e!Q#O%y#O#P&j#P~%y~&jO[~~&mPO~%y~&uPX~!Q![&p~&}Ph~!_!`'Q~'VOl~~'[Pm~#r#s'_~'dOq~~'iPp~!_!`'l~'qOo~R'vWRP}!O%h!c!}%h#R#S%h#T#b%h#b#c(`#c#g%h#g#h)[#h#o%hR(eURP}!O%h!c!}%h#R#S%h#T#W%h#W#X(w#X#o%hR)OSsQRP}!O%h!c!}%h#R#S%h#T#o%hR)aURP}!O%h!c!}%h#R#S%h#T#V%h#V#W)s#W#o%hR)zSwQRP}!O%h!c!}%h#R#S%h#T#o%hR*]URP}!O%h!c!}%h#R#S%h#T#m%h#m#n*o#n#o%hR*vSuQRP}!O%h!c!}%h#R#S%h#T#o%hR+XURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y+k#Y#o%hR+pURP}!O%h!c!}%h#R#S%h#T#g%h#g#h,S#h#o%hR,XURP}!O%h!c!}%h#R#S%h#T#V%h#V#W,k#W#o%hR,rSvQRP}!O%h!c!}%h#R#S%h#T#o%hR-TTRP}!O%h!c!}%h#R#S%h#T#U-d#U#o%hR-iURP}!O%h!c!}%h#R#S%h#T#`%h#`#a-{#a#o%hR.QURP}!O%h!c!}%h#R#S%h#T#g%h#g#h.d#h#o%hR.iURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y.{#Y#o%hR/SSjQRP}!O%h!c!}%h#R#S%h#T#o%hR/eURP}!O%h!c!}%h#R#S%h#T#]%h#]#^/w#^#o%hR/|URP}!O%h!c!}%h#R#S%h#T#a%h#a#b0`#b#o%hR0eURP}!O%h!c!}%h#R#S%h#T#]%h#]#^0w#^#o%hR0|URP}!O%h!c!}%h#R#S%h#T#h%h#h#i1`#i#o%hR1gSxQRP}!O%h!c!}%h#R#S%h#T#o%hR1xURP}!O%h!c!}%h#R#S%h#T#i%h#i#j2[#j#o%hR2aURP}!O%h!c!}%h#R#S%h#T#`%h#`#a2s#a#o%hR2xURP}!O%h!c!}%h#R#S%h#T#`%h#`#a3[#a#o%hR3cSkQRP}!O%h!c!}%h#R#S%h#T#o%hR3tURP}!O%h!c!}%h#R#S%h#T#f%h#f#g4W#g#o%hR4]URP}!O%h!c!}%h#R#S%h#T#W%h#W#X4o#X#o%hR4tURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y5W#Y#o%hR5]URP}!O%h!c!}%h#R#S%h#T#f%h#f#g5o#g#o%hR5vStQRP}!O%h!c!}%h#R#S%h#T#o%hR6XURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y6k#Y#o%hR6pURP}!O%h!c!}%h#R#S%h#T#`%h#`#a7S#a#o%hR7XURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y7k#Y#o%hR7pURP}!O%h!c!}%h#R#S%h#T#V%h#V#W8S#W#o%hR8XURP}!O%h!c!}%h#R#S%h#T#h%h#h#i8k#i#o%hR8rSyQRP}!O%h!c!}%h#R#S%h#T#o%hR9TURP}!O%h!c!}%h#R#S%h#T#f%h#f#g9g#g#o%hR9lURP}!O%h!c!}%h#R#S%h#T#i%h#i#j:O#j#o%hR:TURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y:g#Y#o%hR:nSiQRP}!O%h!c!}%h#R#S%h#T#o%hR;PURP}!O%h!c!}%h#R#S%h#T#[%h#[#];c#]#o%hR;hURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y;z#Y#o%hR { content ("," content)* } + WhereClause { "where" LogicalExpr } OrderClause { "order" "by" Name Order? } LimitClause { "limit" Number } +SelectClause { "select" commaSep } Order { "desc" | "asc" @@ -33,6 +36,8 @@ FilterExpr { @skip { space } + + Bool { "true" | "false" } diff --git a/plugs/query/query.plug.yaml b/plugs/query/query.plug.yaml index 0271ceb1..4829744b 100644 --- a/plugs/query/query.plug.yaml +++ b/plugs/query/query.plug.yaml @@ -18,3 +18,7 @@ functions: path: ./data.ts:queryProvider events: - query:data + insertQueryCommand: + path: ./command.ts:insertQuery + slashCommand: + name: query diff --git a/plugs/query/util.ts b/plugs/query/util.ts index 8142a521..e17e2a77 100644 --- a/plugs/query/util.ts +++ b/plugs/query/util.ts @@ -43,3 +43,28 @@ export function removeQueries(pt: ParseTree) { return true; }); } + +// Nicely format an array of JSON objects as a Markdown table +export function jsonToMDTable( + jsonArray: any[], + valueTransformer?: (k: string, v: any) => string | undefined +): string { + let headers = new Set(); + for (let entry of jsonArray) { + for (let k of Object.keys(entry)) { + headers.add(k); + } + } + let headerList = [...headers]; + let lines = []; + lines.push("|" + headerList.join("|") + "|"); + lines.push("|" + headerList.map((title) => "----").join("|") + "|"); + for (const val of jsonArray) { + let el = []; + for (let prop of headerList) { + el.push(valueTransformer ? valueTransformer(prop, val[prop]) : val[prop]); + } + lines.push("|" + el.join("|") + "|"); + } + return lines.join("\n"); +} diff --git a/plugs/tasks/task.ts b/plugs/tasks/task.ts index 9aa8aef8..59d9458f 100644 --- a/plugs/tasks/task.ts +++ b/plugs/tasks/task.ts @@ -3,16 +3,19 @@ import type { ClickEvent, IndexTreeEvent } from "../../webapp/app_event"; import { batchSet, scanPrefixGlobal } from "plugos-silverbullet-syscall/index"; import { readPage, writePage } from "plugos-silverbullet-syscall/space"; import { parseMarkdown } from "plugos-silverbullet-syscall/markdown"; -import { dispatch, getCurrentPage, getText } from "plugos-silverbullet-syscall/editor"; +import { dispatch, filterBox, getCursor, getText } from "plugos-silverbullet-syscall/editor"; import { addParentPointers, collectNodesMatching, collectNodesOfType, + findNodeOfType, nodeAtPos, + ParseTree, renderToText } from "../../common/tree"; import { removeQueries } from "../query/util"; import { applyQuery, QueryProviderEvent } from "../query/engine"; +import { niceDate } from "../core/dates"; export type Task = { name: string; @@ -24,6 +27,10 @@ export type Task = { page?: string; }; +function getDeadline(deadlineNode: ParseTree): string { + return deadlineNode.children![0].text!.replace(/📅\s*/, ""); +} + export async function indexTasks({ name, tree }: IndexTreeEvent) { // console.log("Indexing tasks"); let tasks: { key: string; value: Task }[] = []; @@ -36,9 +43,9 @@ export async function indexTasks({ name, tree }: IndexTreeEvent) { done: complete, }; - let deadlineNodes = collectNodesOfType(n, "DeadlineDate"); - if (deadlineNodes.length > 0) { - value.deadline = deadlineNodes[0].children![0].text!.replace(/📅\s*/, ""); + let deadlineNode = findNodeOfType(n, "DeadlineDate"); + if (deadlineNode) { + value.deadline = getDeadline(deadlineNode); } let taskIndex = n.parent!.children!.indexOf(n); @@ -61,65 +68,120 @@ export async function taskToggle(event: ClickEvent) { return taskToggleAtPos(event.pos); } +async function toggleTaskMarker(node: ParseTree, moveToPos: number) { + let changeTo = "[x]"; + if (node.children![0].text === "[x]" || node.children![0].text === "[X]") { + changeTo = "[ ]"; + } + await dispatch({ + changes: { + from: node.from, + to: node.to, + insert: changeTo, + }, + selection: { + anchor: moveToPos, + }, + }); + + let parentWikiLinks = collectNodesMatching( + node.parent!, + (n) => n.type === "WikiLinkPage" + ); + for (let wikiLink of parentWikiLinks) { + let ref = wikiLink.children![0].text!; + if (ref.includes("@")) { + let [page, pos] = ref.split("@"); + let text = (await readPage(page)).text; + + let referenceMdTree = await parseMarkdown(text); + // Adding +1 to immediately hit the task marker + let taskMarkerNode = nodeAtPos(referenceMdTree, +pos + 1); + + if (!taskMarkerNode || taskMarkerNode.type !== "TaskMarker") { + console.error( + "Reference not a task marker, out of date?", + taskMarkerNode + ); + return; + } + taskMarkerNode.children![0].text = changeTo; + text = renderToText(referenceMdTree); + console.log("Updated reference paged text", text); + await writePage(page, text); + } + } +} + export async function taskToggleAtPos(pos: number) { - let currentpage = await getCurrentPage(); let text = await getText(); let mdTree = await parseMarkdown(text); addParentPointers(mdTree); let node = nodeAtPos(mdTree, pos); if (node && node.type === "TaskMarker") { - let changeTo = "[x]"; - if (node.children![0].text === "[x]" || node.children![0].text === "[X]") { - changeTo = "[ ]"; - } - await dispatch({ - changes: { - from: node.from, - to: node.to, - insert: changeTo, - }, - selection: { - anchor: pos, - }, - }); - - let parentWikiLinks = collectNodesMatching( - node.parent!, - (n) => n.type === "WikiLinkPage" - ); - for (let wikiLink of parentWikiLinks) { - let ref = wikiLink.children![0].text!; - if (ref.includes("@")) { - let [page, pos] = ref.split("@"); - if (page !== currentpage) { - text = (await readPage(page)).text; - } - - let referenceMdTree = await parseMarkdown(text); - // Adding +1 to immediately hit the task marker - let taskMarkerNode = nodeAtPos(referenceMdTree, +pos + 1); - - if (!taskMarkerNode || taskMarkerNode.type !== "TaskMarker") { - console.error( - "Reference not a task marker, out of date?", - taskMarkerNode - ); - return; - } - taskMarkerNode.children![0].text = changeTo; - console.log( - "This will be the new marker", - renderToText(taskMarkerNode) - ); - text = renderToText(referenceMdTree); - console.log("Updated reference paged text", text); - await writePage(page, text); - } - } + await toggleTaskMarker(node, pos); } } +export async function taskToggleCommand() { + let text = await getText(); + let pos = await getCursor(); + let tree = await parseMarkdown(text); + addParentPointers(tree); + + let node = nodeAtPos(tree, pos); + // We kwow node.type === Task (due to the task context) + let taskMarker = findNodeOfType(node!, "TaskMarker"); + await toggleTaskMarker(taskMarker!, pos); +} + +export async function postponeCommand() { + let text = await getText(); + let pos = await getCursor(); + let tree = await parseMarkdown(text); + addParentPointers(tree); + + let node = nodeAtPos(tree, pos)!; + // We kwow node.type === DeadlineDate (due to the task context) + let date = getDeadline(node); + let option = await filterBox( + "Postpone for...", + [ + { name: "a day", orderId: 1 }, + { name: "a week", orderId: 2 }, + { name: "following Monday", orderId: 3 }, + ], + "Select the desired time span to delay this task" + ); + if (!option) { + return; + } + let d = new Date(date); + switch (option.name) { + case "a day": + d.setDate(d.getDate() + 1); + break; + case "a week": + d.setDate(d.getDate() + 7); + break; + case "following Monday": + d.setDate(d.getDate() + ((7 - d.getDay() + 1) % 7 || 7)); + break; + } + await dispatch({ + changes: { + from: node.from, + to: node.to, + insert: `📅 ${niceDate(d)}`, + }, + selection: { + anchor: pos, + }, + }); + // await toggleTaskMarker(taskMarker!, pos); +} + export async function queryProvider({ query, }: QueryProviderEvent): Promise { diff --git a/plugs/tasks/tasks.plug.yaml b/plugs/tasks/tasks.plug.yaml index 943787d0..59a6c663 100644 --- a/plugs/tasks/tasks.plug.yaml +++ b/plugs/tasks/tasks.plug.yaml @@ -30,4 +30,17 @@ functions: path: ./task.ts:queryProvider events: - query:task - + taskToggleCommand: + path: ./task.ts:taskToggleCommand + command: + name: "Task: Toggle" + key: Alt-t + contexts: + - Task + taskPostponeCommand: + path: ./task.ts:postponeCommand + command: + name: "Task: Postpone by 1 day" + key: Alt-+ + contexts: + - DeadlineDate diff --git a/plugs/yarn.lock b/plugs/yarn.lock index 5ffe0286..592b7d86 100644 --- a/plugs/yarn.lock +++ b/plugs/yarn.lock @@ -3,423 +3,466 @@ "@babel/code-frame@^7.12.13": - "integrity" "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==" - "resolved" "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz" - "version" "7.16.7" + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== dependencies: "@babel/highlight" "^7.16.7" "@babel/helper-validator-identifier@^7.16.7": - "integrity" "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" - "resolved" "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz" - "version" "7.16.7" + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== "@babel/highlight@^7.16.7": - "integrity" "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==" - "resolved" "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz" - "version" "7.16.10" + version "7.16.10" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== dependencies: "@babel/helper-validator-identifier" "^7.16.7" - "chalk" "^2.0.0" - "js-tokens" "^4.0.0" + chalk "^2.0.0" + js-tokens "^4.0.0" "@jest/environment@^27.5.1": - "integrity" "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==" - "resolved" "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz" - "version" "27.5.1" + version "27.5.1" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== dependencies: "@jest/fake-timers" "^27.5.1" "@jest/types" "^27.5.1" "@types/node" "*" - "jest-mock" "^27.5.1" + jest-mock "^27.5.1" "@jest/fake-timers@^27.5.1": - "integrity" "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==" - "resolved" "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz" - "version" "27.5.1" + version "27.5.1" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== dependencies: "@jest/types" "^27.5.1" "@sinonjs/fake-timers" "^8.0.1" "@types/node" "*" - "jest-message-util" "^27.5.1" - "jest-mock" "^27.5.1" - "jest-util" "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" "@jest/globals@^27.5.1": - "integrity" "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==" - "resolved" "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz" - "version" "27.5.1" + version "27.5.1" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== dependencies: "@jest/environment" "^27.5.1" "@jest/types" "^27.5.1" - "expect" "^27.5.1" + expect "^27.5.1" "@jest/types@^27.5.1": - "integrity" "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==" - "resolved" "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz" - "version" "27.5.1" + version "27.5.1" + resolved "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" "@types/yargs" "^16.0.0" - "chalk" "^4.0.0" + chalk "^4.0.0" "@lezer/common@^0.15.0": - "integrity" "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==" - "resolved" "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz" - "version" "0.15.12" + version "0.15.12" + resolved "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz" + integrity sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig== "@lezer/generator@^0.15.4": - "integrity" "sha512-9bBwU2TzKMBQ6OCEDevuMNWGOBKlkq5YIGEhjrz9pb3MLb+oYYR4dVFZ7ehwLcDoSecsSA7PdlAy0thJO5pt2w==" - "resolved" "https://registry.npmjs.org/@lezer/generator/-/generator-0.15.4.tgz" - "version" "0.15.4" + version "0.15.4" + resolved "https://registry.npmjs.org/@lezer/generator/-/generator-0.15.4.tgz" + integrity sha512-9bBwU2TzKMBQ6OCEDevuMNWGOBKlkq5YIGEhjrz9pb3MLb+oYYR4dVFZ7ehwLcDoSecsSA7PdlAy0thJO5pt2w== dependencies: "@lezer/common" "^0.15.0" "@lezer/lr" "^0.15.0" "@lezer/lr@^0.15.0", "@lezer/lr@^0.15.8": - "integrity" "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==" - "resolved" "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz" - "version" "0.15.8" + version "0.15.8" + resolved "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz" + integrity sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg== dependencies: "@lezer/common" "^0.15.0" +"@mattermost/client@^6.7.0-0": + version "6.7.0-0" + resolved "https://registry.yarnpkg.com/@mattermost/client/-/client-6.7.0-0.tgz#85d79d364f1f37f3eab1b77ae2e823a51254f89e" + integrity sha512-XIKEWYmadlCh3Bb3JwMi65raKe7jhBLPJ5DPPu6FPMZc4FoM1YoHdPfrkuT1c2KgcTX5HNbkGd1cXV6cLXxHUw== + dependencies: + form-data "^4.0.0" + "@mattermost/types@^6.7.0-0": - "integrity" "sha512-mT8wJwWEp20KPo9D12y7bW7EdUHO7VhUHxr3gH8nPGapWooGcl0Ra0H3u1iCjPpqPWvp7LiodcneU0IysunYKQ==" - "resolved" "https://registry.npmjs.org/@mattermost/types/-/types-6.7.0-0.tgz" - "version" "6.7.0-0" + version "6.7.0-0" + resolved "https://registry.npmjs.org/@mattermost/types/-/types-6.7.0-0.tgz" + integrity sha512-mT8wJwWEp20KPo9D12y7bW7EdUHO7VhUHxr3gH8nPGapWooGcl0Ra0H3u1iCjPpqPWvp7LiodcneU0IysunYKQ== "@sinonjs/commons@^1.7.0": - "integrity" "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==" - "resolved" "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz" - "version" "1.8.3" + version "1.8.3" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== dependencies: - "type-detect" "4.0.8" + type-detect "4.0.8" "@sinonjs/fake-timers@^8.0.1": - "integrity" "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==" - "resolved" "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz" - "version" "8.1.0" + version "8.1.0" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== dependencies: "@sinonjs/commons" "^1.7.0" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - "integrity" "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" - "resolved" "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz" - "version" "2.0.4" + version "2.0.4" + resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== "@types/istanbul-lib-report@*": - "integrity" "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==" - "resolved" "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" - "version" "3.0.0" + version "3.0.0" + resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": - "integrity" "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==" - "resolved" "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz" - "version" "3.0.1" + version "3.0.1" + resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== dependencies: "@types/istanbul-lib-report" "*" "@types/node@*": - "integrity" "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" - "resolved" "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz" - "version" "17.0.23" + version "17.0.23" + resolved "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz" + integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw== "@types/stack-utils@^2.0.0": - "integrity" "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" - "resolved" "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz" - "version" "2.0.1" + version "2.0.1" + resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/yaml@^1.9.7": - "integrity" "sha512-8WMXRDD1D+wCohjfslHDgICd2JtMATZU8CkhH8LVJqcJs6dyYj5TGptzP8wApbmEullGBSsCEzzap73DQ1HJaA==" - "resolved" "https://registry.npmjs.org/@types/yaml/-/yaml-1.9.7.tgz" - "version" "1.9.7" + version "1.9.7" + resolved "https://registry.npmjs.org/@types/yaml/-/yaml-1.9.7.tgz" + integrity sha512-8WMXRDD1D+wCohjfslHDgICd2JtMATZU8CkhH8LVJqcJs6dyYj5TGptzP8wApbmEullGBSsCEzzap73DQ1HJaA== dependencies: - "yaml" "*" + yaml "*" "@types/yargs-parser@*": - "integrity" "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" - "resolved" "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" - "version" "21.0.0" + version "21.0.0" + resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^16.0.0": - "integrity" "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==" - "resolved" "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz" - "version" "16.0.4" + version "16.0.4" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== dependencies: "@types/yargs-parser" "*" -"ansi-regex@^5.0.1": - "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - "version" "5.0.1" +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -"ansi-styles@^3.2.1": - "integrity" "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==" - "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" - "version" "3.2.1" +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: - "color-convert" "^1.9.0" + color-convert "^1.9.0" -"ansi-styles@^4.1.0": - "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" - "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - "version" "4.3.0" +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: - "color-convert" "^2.0.1" + color-convert "^2.0.1" -"ansi-styles@^5.0.0": - "integrity" "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" - "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" - "version" "5.2.0" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -"braces@^3.0.2": - "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" - "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - "version" "3.0.2" +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: - "fill-range" "^7.0.1" + fill-range "^7.0.1" -"chalk@^2.0.0": - "integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==" - "resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - "version" "2.4.2" +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: - "ansi-styles" "^3.2.1" - "escape-string-regexp" "^1.0.5" - "supports-color" "^5.3.0" + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" -"chalk@^4.0.0": - "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" - "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - "version" "4.1.2" +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: - "ansi-styles" "^4.1.0" - "supports-color" "^7.1.0" + ansi-styles "^4.1.0" + supports-color "^7.1.0" -"ci-info@^3.2.0": - "integrity" "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==" - "resolved" "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz" - "version" "3.3.0" +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== -"color-convert@^1.9.0": - "integrity" "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==" - "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" - "version" "1.9.3" +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: - "color-name" "1.1.3" + color-name "1.1.3" -"color-convert@^2.0.1": - "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" - "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - "version" "2.0.1" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: - "color-name" "~1.1.4" + color-name "~1.1.4" -"color-name@~1.1.4": - "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - "version" "1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -"color-name@1.1.3": - "integrity" "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - "version" "1.1.3" +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -"diff-sequences@^27.5.1": - "integrity" "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==" - "resolved" "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz" - "version" "27.5.1" +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" -"escape-string-regexp@^1.0.5": - "integrity" "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - "version" "1.0.5" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -"escape-string-regexp@^2.0.0": - "integrity" "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" - "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" - "version" "2.0.0" +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== -"expect@^27.5.1": - "integrity" "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==" - "resolved" "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz" - "version" "27.5.1" +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== dependencies: "@jest/types" "^27.5.1" - "jest-get-type" "^27.5.1" - "jest-matcher-utils" "^27.5.1" - "jest-message-util" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" -"fill-range@^7.0.1": - "integrity" "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==" - "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - "version" "7.0.1" +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: - "to-regex-range" "^5.0.1" + to-regex-range "^5.0.1" -"graceful-fs@^4.2.9": - "integrity" "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" - "resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz" - "version" "4.2.9" - -"has-flag@^3.0.0": - "integrity" "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - "version" "3.0.0" - -"has-flag@^4.0.0": - "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - "version" "4.0.0" - -"is-number@^7.0.0": - "integrity" "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - "resolved" "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - "version" "7.0.0" - -"jest-diff@^27.5.1": - "integrity" "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==" - "resolved" "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz" - "version" "27.5.1" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: - "chalk" "^4.0.0" - "diff-sequences" "^27.5.1" - "jest-get-type" "^27.5.1" - "pretty-format" "^27.5.1" + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" -"jest-get-type@^27.5.1": - "integrity" "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==" - "resolved" "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz" - "version" "27.5.1" +graceful-fs@^4.2.9: + version "4.2.9" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== -"jest-matcher-utils@^27.5.1": - "integrity" "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==" - "resolved" "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz" - "version" "27.5.1" +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== dependencies: - "chalk" "^4.0.0" - "jest-diff" "^27.5.1" - "jest-get-type" "^27.5.1" - "pretty-format" "^27.5.1" + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" -"jest-message-util@^27.5.1": - "integrity" "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==" - "resolved" "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz" - "version" "27.5.1" +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + +jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== dependencies: "@babel/code-frame" "^7.12.13" "@jest/types" "^27.5.1" "@types/stack-utils" "^2.0.0" - "chalk" "^4.0.0" - "graceful-fs" "^4.2.9" - "micromatch" "^4.0.4" - "pretty-format" "^27.5.1" - "slash" "^3.0.0" - "stack-utils" "^2.0.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" -"jest-mock@^27.5.1": - "integrity" "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==" - "resolved" "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz" - "version" "27.5.1" +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== dependencies: "@jest/types" "^27.5.1" "@types/node" "*" -"jest-util@^27.5.1": - "integrity" "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==" - "resolved" "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz" - "version" "27.5.1" +jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== dependencies: "@jest/types" "^27.5.1" "@types/node" "*" - "chalk" "^4.0.0" - "ci-info" "^3.2.0" - "graceful-fs" "^4.2.9" - "picomatch" "^2.2.3" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" -"js-tokens@^4.0.0": - "integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - "resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" - "version" "4.0.0" +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -"micromatch@^4.0.4": - "integrity" "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==" - "resolved" "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - "version" "4.0.5" +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: - "braces" "^3.0.2" - "picomatch" "^2.3.1" + braces "^3.0.2" + picomatch "^2.3.1" -"picomatch@^2.2.3", "picomatch@^2.3.1": - "integrity" "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - "version" "2.3.1" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== "plugos-silverbullet-syscall@file:../plugos-silverbullet-syscall": - "resolved" "file:../plugos-silverbullet-syscall" - "version" "1.0.0" + version "1.0.0" "plugos-syscall@file:../plugos-syscall": - "resolved" "file:../plugos-syscall" - "version" "1.0.0" + version "1.0.0" -"pretty-format@^27.5.1": - "integrity" "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==" - "resolved" "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz" - "version" "27.5.1" +pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== dependencies: - "ansi-regex" "^5.0.1" - "ansi-styles" "^5.0.0" - "react-is" "^17.0.1" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" -"react-is@^17.0.1": - "integrity" "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - "resolved" "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" - "version" "17.0.2" +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -"slash@^3.0.0": - "integrity" "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - "resolved" "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - "version" "3.0.0" +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -"stack-utils@^2.0.3": - "integrity" "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==" - "resolved" "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz" - "version" "2.0.5" +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== dependencies: - "escape-string-regexp" "^2.0.0" + escape-string-regexp "^2.0.0" -"supports-color@^5.3.0": - "integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" - "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" - "version" "5.5.0" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: - "has-flag" "^3.0.0" + has-flag "^3.0.0" -"supports-color@^7.1.0": - "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" - "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - "version" "7.2.0" +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: - "has-flag" "^4.0.0" + has-flag "^4.0.0" -"to-regex-range@^5.0.1": - "integrity" "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==" - "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" - "version" "5.0.1" +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: - "is-number" "^7.0.0" + is-number "^7.0.0" -"type-detect@4.0.8": - "integrity" "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - "resolved" "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" - "version" "4.0.8" +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -"yaml@*", "yaml@^2.0.0": - "integrity" "sha512-JbfdlHKGP2Ik9IHylzWlGd4pPK++EU46/IxMykphS2ZKw7a7h+dHNmcXObLgpRDriBY+rpWslldikckX8oruWQ==" - "resolved" "https://registry.npmjs.org/yaml/-/yaml-2.0.0.tgz" - "version" "2.0.0" +yaml@*, yaml@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/yaml/-/yaml-2.0.0.tgz" + integrity sha512-JbfdlHKGP2Ik9IHylzWlGd4pPK++EU46/IxMykphS2ZKw7a7h+dHNmcXObLgpRDriBY+rpWslldikckX8oruWQ== diff --git a/webapp/boot.ts b/webapp/boot.ts index 05d27e9b..24d28b82 100644 --- a/webapp/boot.ts +++ b/webapp/boot.ts @@ -2,32 +2,37 @@ import { Editor } from "./editor"; import { safeRun } from "./util"; import { Space } from "../common/spaces/space"; import { HttpSpacePrimitives } from "../common/spaces/http_space_primitives"; -import { IndexedDBSpacePrimitives } from "../common/spaces/indexeddb_space_primitives"; -import { SpaceSync } from "../common/spaces/sync"; -let localSpace = new Space(new IndexedDBSpacePrimitives("pages"), true); -localSpace.watch(); -let serverSpace = new Space(new HttpSpacePrimitives(""), true); -serverSpace.watch(); +// let localSpace = new Space(new IndexedDBSpacePrimitives("pages"), true); +// localSpace.watch(); // @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 isDesktop = typeof window.desktop !== "undefined"; + +// @ts-ignore +let url = isDesktop ? window.desktop.url : ""; + +let serverSpace = new Space(new HttpSpacePrimitives(url), true); +serverSpace.watch(); + +// // @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 () => { @@ -37,8 +42,10 @@ safeRun(async () => { // @ts-ignore window.editor = editor; -navigator.serviceWorker - .register(new URL("service_worker.ts", import.meta.url), { type: "module" }) - .then((r) => { - // console.log("Service worker registered", r); - }); +if (!isDesktop) { + navigator.serviceWorker + .register(new URL("service_worker.ts", import.meta.url), { type: "module" }) + .then((r) => { + // console.log("Service worker registered", r); + }); +} diff --git a/webapp/components/filter.tsx b/webapp/components/filter.tsx index b66ba347..f6a30bd3 100644 --- a/webapp/components/filter.tsx +++ b/webapp/components/filter.tsx @@ -168,7 +168,7 @@ export function FilterList({ break; case " ": if (completePrefix && !text) { - setText(completePrefix); + updateFilter(completePrefix); e.preventDefault(); } break; diff --git a/webapp/editor.tsx b/webapp/editor.tsx index be7dac07..c260476d 100644 --- a/webapp/editor.tsx +++ b/webapp/editor.tsx @@ -51,6 +51,7 @@ import { StatusBar } from "./components/status_bar"; import { loadMarkdownExtensions, MDExt } from "./markdown_ext"; import { FilterList } from "./components/filter"; import { FilterOption } from "../common/types"; +import { syntaxTree } from "@codemirror/language"; class PageState { scrollTop: number; @@ -252,6 +253,7 @@ export class Editor { return new Promise((resolve) => { this.viewDispatch({ type: "show-filterbox", + label, options, placeHolder, helpText, @@ -276,6 +278,12 @@ export class Editor { key: def.command.key, mac: def.command.mac, run: (): boolean => { + if (def.command.contexts) { + let context = this.getContext(); + if (!context || !def.command.contexts.includes(context)) { + return false; + } + } Promise.resolve() .then(def.run) .catch((e: any) => { @@ -361,8 +369,10 @@ export class Editor { key: "Ctrl-/", mac: "Cmd-/", run: (): boolean => { + let context = this.getContext(); this.viewDispatch({ type: "show-palette", + context, }); return true; }, @@ -436,6 +446,7 @@ export class Editor { if (editorView.contentDOM) { editorView.contentDOM.spellcheck = true; } + editorView.focus(); } } @@ -580,7 +591,7 @@ export class Editor { )} {viewState.showFilterBox && ( , container); } + + private getContext(): string | undefined { + let state = this.editorView!.state; + let selection = state.selection.main; + if (selection.empty) { + return syntaxTree(state).resolveInner(selection.from).name; + } + return; + } } diff --git a/webapp/hooks/command.ts b/webapp/hooks/command.ts index 1f82c165..4be996da 100644 --- a/webapp/hooks/command.ts +++ b/webapp/hooks/command.ts @@ -5,6 +5,8 @@ import { EventEmitter } from "../../common/event"; export type CommandDef = { name: string; + contexts?: string[]; + // Bind to keyboard shortcut key?: string; mac?: string; diff --git a/webapp/reducer.ts b/webapp/reducer.ts index ed1abba0..bcc9e2bb 100644 --- a/webapp/reducer.ts +++ b/webapp/reducer.ts @@ -44,8 +44,18 @@ export default function reducer( allPages: action.pages, }; case "show-palette": + let commands = new Map(state.commands); + for (let [k, v] of state.commands.entries()) { + if ( + v.command.contexts && + (!action.context || !v.command.contexts.includes(action.context)) + ) { + commands.delete(k); + } + } return { ...state, + commands, showCommandPalette: true, }; case "hide-palette": @@ -99,6 +109,7 @@ export default function reducer( filterBoxOnSelect: action.onSelect, filterBoxPlaceHolder: action.placeHolder, filterBoxOptions: action.options, + filterBoxLabel: action.label, filterBoxHelpText: action.helpText, }; case "hide-filterbox": diff --git a/webapp/types.ts b/webapp/types.ts index ec26231f..77c71736 100644 --- a/webapp/types.ts +++ b/webapp/types.ts @@ -23,6 +23,7 @@ export type AppViewState = { notifications: Notification[]; showFilterBox: boolean; + filterBoxLabel: string; filterBoxPlaceHolder: string; filterBoxOptions: FilterOption[]; filterBoxHelpText: string; @@ -42,6 +43,7 @@ export const initialViewState: AppViewState = { notifications: [], showFilterBox: false, filterBoxHelpText: "", + filterBoxLabel: "", filterBoxOnSelect: () => {}, filterBoxOptions: [], filterBoxPlaceHolder: "", @@ -55,7 +57,7 @@ export type Action = | { type: "start-navigate" } | { type: "stop-navigate" } | { type: "update-commands"; commands: Map } - | { type: "show-palette" } + | { type: "show-palette"; context?: string } | { type: "hide-palette" } | { type: "show-notification"; notification: Notification } | { type: "dismiss-notification"; id: number } @@ -68,6 +70,7 @@ export type Action = options: FilterOption[]; placeHolder: string; helpText: string; + label: string; onSelect: (option: FilterOption | undefined) => void; } | { type: "hide-filterbox" }; diff --git a/yarn.lock b/yarn.lock index 6fae41cb..155332ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -389,20 +389,7 @@ "@lezer/common" "^0.15.0" "@lezer/html" "^0.15.0" -"@codemirror/lang-javascript@^0.19.0": - version "0.19.7" - resolved "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-0.19.7.tgz" - integrity sha512-DL9f3JLqOEHH9cIwEqqjnP5bkjdVXeECksLtV+/MbPm+l4H+AG+PkwZaJQ2oR1GfPZKh8MVSIE94aGWNkJP8WQ== - dependencies: - "@codemirror/autocomplete" "^0.19.0" - "@codemirror/highlight" "^0.19.7" - "@codemirror/language" "^0.19.0" - "@codemirror/lint" "^0.19.0" - "@codemirror/state" "^0.19.0" - "@codemirror/view" "^0.19.0" - "@lezer/javascript" "^0.15.1" - -"@codemirror/lang-javascript@^0.19.7": +"@codemirror/lang-javascript@^0.19.0", "@codemirror/lang-javascript@^0.19.7": version "0.19.7" resolved "https://registry.yarnpkg.com/@codemirror/lang-javascript/-/lang-javascript-0.19.7.tgz#84581ef6abf2a16d78f017ffc96c2d6227de5eb5" integrity sha512-DL9f3JLqOEHH9cIwEqqjnP5bkjdVXeECksLtV+/MbPm+l4H+AG+PkwZaJQ2oR1GfPZKh8MVSIE94aGWNkJP8WQ== @@ -6224,6 +6211,11 @@ ws@^7.4.6: resolved "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz" integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== +ws@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== + xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz"