} = {
content: {
type: "tiptap",
data: `Hello This is colorful
`
@@ -64,13 +75,18 @@ const IMG_CONTENT_WITHOUT_HASH = `This is a note for me.j
\n
+const noteTest = (
+ note: Partial<
+ Note & { content: NoteContent; sessionId: string }
+ > = TEST_NOTE
+) =>
databaseTest().then(async (db) => {
- let id = await db.notes.add(note);
+ const id = await db.notes.add(note);
+ if (!id) throw new Error("Failed to add note.");
return { db, id };
});
-const groupedTest = (type) =>
+const groupedTest = (type: GroupOptions["groupBy"]) =>
noteTest().then(async ({ db }) => {
await db.notes.add({ ...TEST_NOTE, title: "HELLO WHAT!" });
await db.notes.add({
@@ -83,7 +99,7 @@ const groupedTest = (type) =>
title: "Some title and title title",
dateCreated: dayjs().subtract(2, "weeks").unix()
});
- let grouped = groupArray(db.notes.all, {
+ const grouped = groupArray(db.notes.all, {
groupBy: type,
sortDirection: "desc",
sortBy: "dateCreated"
@@ -92,25 +108,24 @@ const groupedTest = (type) =>
expect(grouped.some((i) => i.type === "header")).toBe(true);
});
-function delay(ms) {
+function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function loginFakeUser(db) {
const email = "johndoe@example.com";
const userSalt = randomBytes(16).toString("base64");
- await db.storage.deriveCryptoKey(`_uk_@${email}`, {
+ await db.storage().deriveCryptoKey(`_uk_@${email}`, {
password: "password",
salt: userSalt
});
- const userEncryptionKey = await db.storage.getCryptoKey(`_uk_@${email}`);
+ const userEncryptionKey = await db.storage().getCryptoKey(`_uk_@${email}`);
- const key = await db.storage.generateRandomKey();
- const attachmentsKey = await db.storage.encrypt(
- { password: userEncryptionKey },
- JSON.stringify(key)
- );
+ const key = await db.crypto().generateRandomKey();
+ const attachmentsKey = await db
+ .storage()
+ .encrypt({ password: userEncryptionKey }, JSON.stringify(key));
await db.user.setUser({
email,
diff --git a/packages/core/__tests__/vault.test.js b/packages/core/__tests__/vault.test.js
index bdb1b2b4a..b7c01af86 100644
--- a/packages/core/__tests__/vault.test.js
+++ b/packages/core/__tests__/vault.test.js
@@ -23,7 +23,7 @@ import { test, expect } from "vitest";
test("create vault", () =>
databaseTest().then(async (db) => {
await expect(db.vault.create("password")).resolves.toBe(true);
- const vaultKey = await db.storage.read("vaultKey");
+ const vaultKey = await db.storage().read("vaultKey");
expect(vaultKey).toBeDefined();
expect(vaultKey.iv).toBeDefined();
expect(vaultKey.cipher).toBeDefined();
diff --git a/packages/core/globals.setup.js b/packages/core/globals.setup.js
index 39650b37c..0f25a8bf4 100644
--- a/packages/core/globals.setup.js
+++ b/packages/core/globals.setup.js
@@ -20,7 +20,9 @@ along with this program. If not, see .
import "isomorphic-fetch";
import dotenv from "dotenv";
import { DOMParser } from "linkedom";
+import WebSocket from "ws";
globalThis.DOMParser = DOMParser;
+globalThis.WebSocket = WebSocket;
require("abortcontroller-polyfill/dist/polyfill-patch-fetch");
dotenv.config();
diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json
index 0b43b7f8d..7777f5b8f 100644
--- a/packages/core/package-lock.json
+++ b/packages/core/package-lock.json
@@ -1,7 +1,7 @@
{
"name": "@notesnook/core",
"version": "7.4.1",
- "lockfileVersion": 2,
+ "lockfileVersion": 3,
"requires": true,
"packages": {
"": {
@@ -25,14 +25,18 @@
"mime-db": "1.52.0",
"prismjs": "^1.29.0",
"qclone": "^1.2.0",
+ "rfdc": "^1.3.0",
"spark-md5": "^3.0.2"
},
"devDependencies": {
"@notesnook/crypto": "file:../crypto",
+ "@types/event-source-polyfill": "^1.0.1",
"@types/html-to-text": "^9.0.0",
- "@types/katex": "^0.16.1",
+ "@types/katex": "^0.16.2",
"@types/prismjs": "^1.26.0",
+ "@types/spark-md5": "^3.0.2",
"@types/streetwriters__showdown": "npm:@types/showdown@^2.0.6",
+ "@types/ws": "^8.5.5",
"@vitest/coverage-v8": "^0.34.1",
"abortcontroller-polyfill": "^1.7.3",
"cross-env": "^7.0.3",
@@ -46,7 +50,8 @@
"otplib": "^12.0.1",
"refractor": "^4.8.1",
"vitest": "^0.34.1",
- "vitest-fetch-mock": "^0.2.2"
+ "vitest-fetch-mock": "^0.2.2",
+ "ws": "^8.13.0"
}
},
"../crypto": {
@@ -59,17 +64,1378 @@
},
"devDependencies": {}
},
+ "../crypto/node_modules/@notesnook/sodium": {
+ "resolved": "../sodium",
+ "link": true
+ },
"../logger": {
"name": "@notesnook/logger",
"version": "1.0.3",
"license": "GPL-3.0-or-later",
"devDependencies": {}
},
+ "../sodium": {
+ "name": "@notesnook/sodium",
+ "version": "1.1.0",
+ "dev": true,
+ "license": "GPL-3.0-or-later",
+ "dependencies": {
+ "libsodium-wrappers-sumo": "^0.7.11",
+ "sodium-native": "^4.0.1"
+ },
+ "devDependencies": {
+ "@types/libsodium-wrappers-sumo": "0.7.5",
+ "benny": "^3.7.1",
+ "ts-node": "^10.9.1",
+ "vitest": "^0.32.2"
+ }
+ },
+ "../sodium/node_modules/@arrows/array": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@arrows/composition": "^1.2.2"
+ }
+ },
+ "../sodium/node_modules/@arrows/composition": {
+ "version": "1.2.2",
+ "dev": true,
+ "license": "ISC"
+ },
+ "../sodium/node_modules/@arrows/dispatch": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@arrows/composition": "^1.2.2"
+ }
+ },
+ "../sodium/node_modules/@arrows/error": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "ISC"
+ },
+ "../sodium/node_modules/@arrows/multimethod": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@arrows/array": "^1.4.1",
+ "@arrows/composition": "^1.2.2",
+ "@arrows/error": "^1.0.2",
+ "fast-deep-equal": "^3.1.3"
+ }
+ },
+ "../sodium/node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "../sodium/node_modules/@esbuild/win32-x64": {
+ "version": "0.17.19",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "../sodium/node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "../sodium/node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "../sodium/node_modules/@tsconfig/node10": {
+ "version": "1.0.9",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/@tsconfig/node16": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/@types/chai": {
+ "version": "4.3.5",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/@types/chai-subset": {
+ "version": "1.3.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "*"
+ }
+ },
+ "../sodium/node_modules/@types/libsodium-wrappers": {
+ "version": "0.7.10",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/@types/libsodium-wrappers-sumo": {
+ "version": "0.7.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/libsodium-wrappers": "*"
+ }
+ },
+ "../sodium/node_modules/@types/node": {
+ "version": "18.15.9",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/@vitest/expect": {
+ "version": "0.32.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "0.32.2",
+ "@vitest/utils": "0.32.2",
+ "chai": "^4.3.7"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "../sodium/node_modules/@vitest/runner": {
+ "version": "0.32.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "0.32.2",
+ "concordance": "^5.0.4",
+ "p-limit": "^4.0.0",
+ "pathe": "^1.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "../sodium/node_modules/@vitest/snapshot": {
+ "version": "0.32.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "magic-string": "^0.30.0",
+ "pathe": "^1.1.0",
+ "pretty-format": "^27.5.1"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "../sodium/node_modules/@vitest/spy": {
+ "version": "0.32.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^2.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "../sodium/node_modules/@vitest/utils": {
+ "version": "0.32.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "diff-sequences": "^29.4.3",
+ "loupe": "^2.3.6",
+ "pretty-format": "^27.5.1"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "../sodium/node_modules/acorn": {
+ "version": "8.9.0",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "../sodium/node_modules/acorn-walk": {
+ "version": "8.2.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "../sodium/node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "../sodium/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "../sodium/node_modules/arg": {
+ "version": "4.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/assertion-error": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "../sodium/node_modules/astral-regex": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/benchmark": {
+ "version": "2.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.17.4",
+ "platform": "^1.3.3"
+ }
+ },
+ "../sodium/node_modules/benny": {
+ "version": "3.7.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@arrows/composition": "^1.0.0",
+ "@arrows/dispatch": "^1.0.2",
+ "@arrows/multimethod": "^1.1.6",
+ "benchmark": "^2.1.4",
+ "common-tags": "^1.8.0",
+ "fs-extra": "^10.0.0",
+ "json2csv": "^5.0.6",
+ "kleur": "^4.1.4",
+ "log-update": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "../sodium/node_modules/blueimp-md5": {
+ "version": "2.19.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/cac": {
+ "version": "6.7.14",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/chai": {
+ "version": "4.3.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^1.1.0",
+ "check-error": "^1.0.2",
+ "deep-eql": "^4.1.2",
+ "get-func-name": "^2.0.0",
+ "loupe": "^2.3.1",
+ "pathval": "^1.1.1",
+ "type-detect": "^4.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "../sodium/node_modules/check-error": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "../sodium/node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/color-convert": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "../sodium/node_modules/color-name": {
+ "version": "1.1.4",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/commander": {
+ "version": "6.2.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "../sodium/node_modules/common-tags": {
+ "version": "1.8.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "../sodium/node_modules/concordance": {
+ "version": "5.0.4",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "date-time": "^3.1.0",
+ "esutils": "^2.0.3",
+ "fast-diff": "^1.2.0",
+ "js-string-escape": "^1.0.1",
+ "lodash": "^4.17.15",
+ "md5-hex": "^3.0.1",
+ "semver": "^7.3.2",
+ "well-known-symbols": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14"
+ }
+ },
+ "../sodium/node_modules/create-require": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/date-time": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "time-zone": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "../sodium/node_modules/debug": {
+ "version": "4.3.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "../sodium/node_modules/deep-eql": {
+ "version": "4.1.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-detect": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "../sodium/node_modules/diff-sequences": {
+ "version": "29.4.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "../sodium/node_modules/esbuild": {
+ "version": "0.17.19",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.17.19",
+ "@esbuild/android-arm64": "0.17.19",
+ "@esbuild/android-x64": "0.17.19",
+ "@esbuild/darwin-arm64": "0.17.19",
+ "@esbuild/darwin-x64": "0.17.19",
+ "@esbuild/freebsd-arm64": "0.17.19",
+ "@esbuild/freebsd-x64": "0.17.19",
+ "@esbuild/linux-arm": "0.17.19",
+ "@esbuild/linux-arm64": "0.17.19",
+ "@esbuild/linux-ia32": "0.17.19",
+ "@esbuild/linux-loong64": "0.17.19",
+ "@esbuild/linux-mips64el": "0.17.19",
+ "@esbuild/linux-ppc64": "0.17.19",
+ "@esbuild/linux-riscv64": "0.17.19",
+ "@esbuild/linux-s390x": "0.17.19",
+ "@esbuild/linux-x64": "0.17.19",
+ "@esbuild/netbsd-x64": "0.17.19",
+ "@esbuild/openbsd-x64": "0.17.19",
+ "@esbuild/sunos-x64": "0.17.19",
+ "@esbuild/win32-arm64": "0.17.19",
+ "@esbuild/win32-ia32": "0.17.19",
+ "@esbuild/win32-x64": "0.17.19"
+ }
+ },
+ "../sodium/node_modules/esutils": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "../sodium/node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/fast-diff": {
+ "version": "1.3.0",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "../sodium/node_modules/fs-extra": {
+ "version": "10.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "../sodium/node_modules/get-func-name": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "../sodium/node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "dev": true,
+ "license": "ISC"
+ },
+ "../sodium/node_modules/js-string-escape": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "../sodium/node_modules/json2csv": {
+ "version": "5.0.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^6.1.0",
+ "jsonparse": "^1.3.1",
+ "lodash.get": "^4.4.2"
+ },
+ "bin": {
+ "json2csv": "bin/json2csv.js"
+ },
+ "engines": {
+ "node": ">= 10",
+ "npm": ">= 6.13.0"
+ }
+ },
+ "../sodium/node_modules/jsonc-parser": {
+ "version": "3.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "../sodium/node_modules/jsonparse": {
+ "version": "1.3.1",
+ "dev": true,
+ "engines": [
+ "node >= 0.2.0"
+ ],
+ "license": "MIT"
+ },
+ "../sodium/node_modules/kleur": {
+ "version": "4.1.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "../sodium/node_modules/libsodium-sumo": {
+ "version": "0.7.11",
+ "dev": true,
+ "license": "ISC"
+ },
+ "../sodium/node_modules/libsodium-wrappers-sumo": {
+ "version": "0.7.11",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "libsodium-sumo": "^0.7.11"
+ }
+ },
+ "../sodium/node_modules/local-pkg": {
+ "version": "0.4.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "../sodium/node_modules/lodash": {
+ "version": "4.17.21",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/lodash.get": {
+ "version": "4.4.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/log-update": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^4.3.0",
+ "cli-cursor": "^3.1.0",
+ "slice-ansi": "^4.0.0",
+ "wrap-ansi": "^6.2.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "../sodium/node_modules/log-update/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "../sodium/node_modules/log-update/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/log-update/node_modules/slice-ansi": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "../sodium/node_modules/loupe": {
+ "version": "2.3.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-func-name": "^2.0.0"
+ }
+ },
+ "../sodium/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "../sodium/node_modules/magic-string": {
+ "version": "0.30.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.13"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "../sodium/node_modules/make-error": {
+ "version": "1.3.6",
+ "dev": true,
+ "license": "ISC"
+ },
+ "../sodium/node_modules/md5-hex": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "blueimp-md5": "^2.10.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "../sodium/node_modules/mlly": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "pathe": "^1.1.1",
+ "pkg-types": "^1.0.3",
+ "ufo": "^1.1.2"
+ }
+ },
+ "../sodium/node_modules/ms": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/nanoid": {
+ "version": "3.3.6",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "../sodium/node_modules/node-gyp-build": {
+ "version": "4.6.0",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
+ "../sodium/node_modules/onetime": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "../sodium/node_modules/p-limit": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^1.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "../sodium/node_modules/pathe": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/pathval": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "../sodium/node_modules/picocolors": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "../sodium/node_modules/pkg-types": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsonc-parser": "^3.2.0",
+ "mlly": "^1.2.0",
+ "pathe": "^1.1.0"
+ }
+ },
+ "../sodium/node_modules/platform": {
+ "version": "1.3.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/postcss": {
+ "version": "8.4.24",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "../sodium/node_modules/pretty-format": {
+ "version": "27.5.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "../sodium/node_modules/react-is": {
+ "version": "17.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/rollup": {
+ "version": "3.25.2",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "../sodium/node_modules/semver": {
+ "version": "7.5.3",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "../sodium/node_modules/siginfo": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "../sodium/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "dev": true,
+ "license": "ISC"
+ },
+ "../sodium/node_modules/sodium-native": {
+ "version": "4.0.1",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-gyp-build": "^4.3.0"
+ }
+ },
+ "../sodium/node_modules/source-map-js": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "../sodium/node_modules/stackback": {
+ "version": "0.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/std-env": {
+ "version": "3.3.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/strip-literal": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.8.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "../sodium/node_modules/time-zone": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "../sodium/node_modules/tinybench": {
+ "version": "2.5.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/tinypool": {
+ "version": "0.5.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "../sodium/node_modules/tinyspy": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "../sodium/node_modules/ts-node": {
+ "version": "10.9.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "../sodium/node_modules/ts-node/node_modules/diff": {
+ "version": "4.0.2",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "../sodium/node_modules/type-detect": {
+ "version": "4.0.8",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "../sodium/node_modules/type-fest": {
+ "version": "0.21.3",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "../sodium/node_modules/ufo": {
+ "version": "1.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/universalify": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "../sodium/node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/vite": {
+ "version": "4.3.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.17.5",
+ "postcss": "^8.4.23",
+ "rollup": "^3.21.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 14",
+ "less": "*",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "../sodium/node_modules/vite-node": {
+ "version": "0.32.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.3.4",
+ "mlly": "^1.2.0",
+ "pathe": "^1.1.0",
+ "picocolors": "^1.0.0",
+ "vite": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": ">=v14.18.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "../sodium/node_modules/vitest": {
+ "version": "0.32.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "^4.3.5",
+ "@types/chai-subset": "^1.3.3",
+ "@types/node": "*",
+ "@vitest/expect": "0.32.2",
+ "@vitest/runner": "0.32.2",
+ "@vitest/snapshot": "0.32.2",
+ "@vitest/spy": "0.32.2",
+ "@vitest/utils": "0.32.2",
+ "acorn": "^8.8.2",
+ "acorn-walk": "^8.2.0",
+ "cac": "^6.7.14",
+ "chai": "^4.3.7",
+ "concordance": "^5.0.4",
+ "debug": "^4.3.4",
+ "local-pkg": "^0.4.3",
+ "magic-string": "^0.30.0",
+ "pathe": "^1.1.0",
+ "picocolors": "^1.0.0",
+ "std-env": "^3.3.2",
+ "strip-literal": "^1.0.1",
+ "tinybench": "^2.5.0",
+ "tinypool": "^0.5.0",
+ "vite": "^3.0.0 || ^4.0.0",
+ "vite-node": "0.32.2",
+ "why-is-node-running": "^2.2.2"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": ">=v14.18.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@vitest/browser": "*",
+ "@vitest/ui": "*",
+ "happy-dom": "*",
+ "jsdom": "*",
+ "playwright": "*",
+ "safaridriver": "*",
+ "webdriverio": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@vitest/browser": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ },
+ "playwright": {
+ "optional": true
+ },
+ "safaridriver": {
+ "optional": true
+ },
+ "webdriverio": {
+ "optional": true
+ }
+ }
+ },
+ "../sodium/node_modules/well-known-symbols": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "../sodium/node_modules/why-is-node-running": {
+ "version": "2.2.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "../sodium/node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "../sodium/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "4.2.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "../sodium/node_modules/yallist": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "../sodium/node_modules/yn": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "../sodium/node_modules/yocto-queue": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@ampproject/remapping": {
"version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
- "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
@@ -80,14 +1446,29 @@
},
"node_modules/@bcoe/v8-coverage": {
"version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
- "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
+ "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
},
"node_modules/@esbuild/android-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
- "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
+ "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
"cpu": [
"arm"
],
@@ -101,9 +1482,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
- "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
+ "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
"cpu": [
"arm64"
],
@@ -117,9 +1498,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
- "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
+ "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
"cpu": [
"x64"
],
@@ -133,9 +1514,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
- "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
+ "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
"cpu": [
"arm64"
],
@@ -149,9 +1530,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
- "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
+ "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
"cpu": [
"x64"
],
@@ -165,9 +1546,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
- "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
+ "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
"cpu": [
"arm64"
],
@@ -181,9 +1562,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
- "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
+ "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
"cpu": [
"x64"
],
@@ -197,9 +1578,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
- "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
+ "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
"cpu": [
"arm"
],
@@ -213,9 +1594,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
- "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
+ "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
"cpu": [
"arm64"
],
@@ -229,9 +1610,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
- "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
+ "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
"cpu": [
"ia32"
],
@@ -245,9 +1626,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
- "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
+ "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
"cpu": [
"loong64"
],
@@ -261,9 +1642,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
- "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
+ "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
"cpu": [
"mips64el"
],
@@ -277,9 +1658,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
- "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
+ "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
"cpu": [
"ppc64"
],
@@ -293,9 +1674,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
- "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
+ "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
"cpu": [
"riscv64"
],
@@ -309,9 +1690,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
- "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
+ "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
"cpu": [
"s390x"
],
@@ -325,9 +1706,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
- "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
+ "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
"cpu": [
"x64"
],
@@ -341,9 +1722,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
- "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
"cpu": [
"x64"
],
@@ -357,9 +1738,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
- "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
"cpu": [
"x64"
],
@@ -373,9 +1754,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
- "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
+ "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
"cpu": [
"x64"
],
@@ -389,9 +1770,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
- "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
+ "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
"cpu": [
"arm64"
],
@@ -405,9 +1786,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
- "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
+ "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
"cpu": [
"ia32"
],
@@ -421,9 +1802,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
- "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
+ "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
"cpu": [
"x64"
],
@@ -438,18 +1819,28 @@
},
"node_modules/@istanbuljs/schema": {
"version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "dev": true,
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.0.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
@@ -461,33 +1852,29 @@
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
- "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.19",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
- "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@@ -495,8 +1882,7 @@
},
"node_modules/@microsoft/signalr": {
"version": "8.0.0",
- "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-8.0.0.tgz",
- "integrity": "sha512-K/wS/VmzRWePCGqGh8MU8OWbS1Zvu7DG7LSJS62fBB8rJUXwwj4axQtqrAAwKGUZHQF6CuteuQR9xMsVpM2JNA==",
+ "license": "MIT",
"dependencies": {
"abort-controller": "^3.0.0",
"eventsource": "^2.0.2",
@@ -505,6 +1891,25 @@
"ws": "^7.4.5"
}
},
+ "node_modules/@microsoft/signalr/node_modules/ws": {
+ "version": "7.5.9",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@notesnook/crypto": {
"resolved": "../crypto",
"link": true
@@ -515,24 +1920,21 @@
},
"node_modules/@otplib/core": {
"version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/core/-/core-12.0.1.tgz",
- "integrity": "sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@otplib/plugin-crypto": {
"version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/plugin-crypto/-/plugin-crypto-12.0.1.tgz",
- "integrity": "sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@otplib/core": "^12.0.1"
}
},
"node_modules/@otplib/plugin-thirty-two": {
"version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/plugin-thirty-two/-/plugin-thirty-two-12.0.1.tgz",
- "integrity": "sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@otplib/core": "^12.0.1",
"thirty-two": "^1.0.2"
@@ -540,9 +1942,8 @@
},
"node_modules/@otplib/preset-default": {
"version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/preset-default/-/preset-default-12.0.1.tgz",
- "integrity": "sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@otplib/core": "^12.0.1",
"@otplib/plugin-crypto": "^12.0.1",
@@ -551,9 +1952,8 @@
},
"node_modules/@otplib/preset-v11": {
"version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/preset-v11/-/preset-v11-12.0.1.tgz",
- "integrity": "sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@otplib/core": "^12.0.1",
"@otplib/plugin-crypto": "^12.0.1",
@@ -562,16 +1962,183 @@
},
"node_modules/@readme/data-urls": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@readme/data-urls/-/data-urls-3.0.0.tgz",
- "integrity": "sha512-b0L7VWqbLZqOSSAFUrxS5ZwUfec35WDsAwwCH481vYnhk0dWO3nvmNVNCbP8CY4cXqwL1W4uCAnhDz+CUmXM3g==",
+ "license": "ISC",
"engines": {
"node": ">=18"
}
},
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz",
+ "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz",
+ "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz",
+ "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz",
+ "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz",
+ "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz",
+ "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz",
+ "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz",
+ "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz",
+ "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz",
+ "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz",
+ "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz",
+ "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz",
+ "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/@selderee/plugin-htmlparser2": {
"version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz",
- "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==",
+ "license": "MIT",
"dependencies": {
"domhandler": "^5.0.3",
"selderee": "^0.11.0"
@@ -580,10 +2147,15 @@
"url": "https://ko-fi.com/killymxi"
}
},
+ "node_modules/@sinclair/typebox": {
+ "version": "0.27.8",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
+ "dev": true
+ },
"node_modules/@streetwriters/showdown": {
"version": "3.0.5-alpha",
- "resolved": "https://registry.npmjs.org/@streetwriters/showdown/-/showdown-3.0.5-alpha.tgz",
- "integrity": "sha512-jD9JFhxLDx6XeyZOLVB0zWtwGduwNiFpxn5rxu6ThyKyWGnu1O+L1w04WLC1L56pyEhypr3Tsk24dzo2Se/50g==",
+ "license": "MIT",
"bin": {
"showdown": "bin/showdown.js"
},
@@ -594,84 +2166,99 @@
},
"node_modules/@tootallnate/once": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
- "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 10"
}
},
"node_modules/@types/chai": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz",
- "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==",
+ "version": "4.3.14",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz",
+ "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==",
"dev": true
},
"node_modules/@types/chai-subset": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz",
- "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==",
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz",
+ "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==",
"dev": true,
"dependencies": {
"@types/chai": "*"
}
},
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "dev": true
+ },
+ "node_modules/@types/event-source-polyfill": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/hast": {
"version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz",
- "integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/unist": "^2"
}
},
"node_modules/@types/html-to-text": {
"version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@types/html-to-text/-/html-to-text-9.0.0.tgz",
- "integrity": "sha512-FnF3p2FJZ1kJT/0C/lmBzw7HSlH3RhtACVYyrwUsJoCmFNuiLpusWT2FWWB7P9A48CaYpvD6Q2fprn7sZeffpw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/istanbul-lib-coverage": {
- "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==",
- "dev": true
+ "version": "2.0.6",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/katex": {
- "version": "0.16.1",
- "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.1.tgz",
- "integrity": "sha512-cwglq2A63Yk082CQk0t8LIoDhZAVgJqkumLyk3grpg3K8sevaDW//Qsspmxj9Sf+97biqt79CfAlPrvizHlP0w==",
- "dev": true
+ "version": "0.16.7",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/node": {
"version": "18.11.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
- "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/prismjs": {
"version": "1.26.0",
- "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.0.tgz",
- "integrity": "sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/spark-md5": {
+ "version": "3.0.4",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/streetwriters__showdown": {
"name": "@types/showdown",
"version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@types/showdown/-/showdown-2.0.6.tgz",
- "integrity": "sha512-pTvD/0CIeqe4x23+YJWlX2gArHa8G0J0Oh6GKaVXV7TAeickpkkZiNOgFcFcmLQ5lB/K0qBJL1FtRYltBfbGCQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/unist": {
"version": "2.0.7",
- "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.7.tgz",
- "integrity": "sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/ws": {
+ "version": "8.5.10",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
},
"node_modules/@vitest/coverage-v8": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-0.34.1.tgz",
- "integrity": "sha512-lRgUwjTMr8idXEbUPSNH4jjRZJXJCVY3BqUa+LDXyJVe3pldxYMn/r0HMqatKUGTp0Kyf1j5LfFoY6kRqRp7jw==",
+ "version": "0.34.6",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-0.34.6.tgz",
+ "integrity": "sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.2.1",
@@ -694,26 +2281,26 @@
}
},
"node_modules/@vitest/expect": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.1.tgz",
- "integrity": "sha512-q2CD8+XIsQ+tHwypnoCk8Mnv5e6afLFvinVGCq3/BOT4kQdVQmY6rRfyKkwcg635lbliLPqbunXZr+L1ssUWiQ==",
+ "version": "0.34.6",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz",
+ "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==",
"dev": true,
"dependencies": {
- "@vitest/spy": "0.34.1",
- "@vitest/utils": "0.34.1",
- "chai": "^4.3.7"
+ "@vitest/spy": "0.34.6",
+ "@vitest/utils": "0.34.6",
+ "chai": "^4.3.10"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/runner": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.1.tgz",
- "integrity": "sha512-YfQMpYzDsYB7yqgmlxZ06NI4LurHWfrH7Wy3Pvf/z/vwUSgq1zLAb1lWcItCzQG+NVox+VvzlKQrYEXb47645g==",
+ "version": "0.34.6",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz",
+ "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==",
"dev": true,
"dependencies": {
- "@vitest/utils": "0.34.1",
+ "@vitest/utils": "0.34.6",
"p-limit": "^4.0.0",
"pathe": "^1.1.1"
},
@@ -721,37 +2308,10 @@
"url": "https://opencollective.com/vitest"
}
},
- "node_modules/@vitest/runner/node_modules/p-limit": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
- "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^1.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@vitest/runner/node_modules/yocto-queue": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
- "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
- "dev": true,
- "engines": {
- "node": ">=12.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@vitest/snapshot": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.1.tgz",
- "integrity": "sha512-0O9LfLU0114OqdF8lENlrLsnn024Tb1CsS9UwG0YMWY2oGTQfPtkW+B/7ieyv0X9R2Oijhi3caB1xgGgEgclSQ==",
+ "version": "0.34.6",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz",
+ "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==",
"dev": true,
"dependencies": {
"magic-string": "^0.30.1",
@@ -762,54 +2322,10 @@
"url": "https://opencollective.com/vitest"
}
},
- "node_modules/@vitest/snapshot/node_modules/@jest/schemas": {
- "version": "29.6.0",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz",
- "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==",
- "dev": true,
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/snapshot/node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true
- },
- "node_modules/@vitest/snapshot/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@vitest/snapshot/node_modules/pretty-format": {
- "version": "29.6.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz",
- "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==",
- "dev": true,
- "dependencies": {
- "@jest/schemas": "^29.6.0",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/@vitest/spy": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.1.tgz",
- "integrity": "sha512-UT4WcI3EAPUNO8n6y9QoEqynGGEPmmRxC+cLzneFFXpmacivjHZsNbiKD88KUScv5DCHVDgdBsLD7O7s1enFcQ==",
+ "version": "0.34.6",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz",
+ "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==",
"dev": true,
"dependencies": {
"tinyspy": "^2.1.1"
@@ -819,9 +2335,9 @@
}
},
"node_modules/@vitest/utils": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.1.tgz",
- "integrity": "sha512-/ql9dsFi4iuEbiNcjNHQWXBum7aL8pyhxvfnD9gNtbjR9fUKAjxhj4AA3yfLXg6gJpMGGecvtF8Au2G9y3q47Q==",
+ "version": "0.34.6",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz",
+ "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==",
"dev": true,
"dependencies": {
"diff-sequences": "^29.4.3",
@@ -832,69 +2348,14 @@
"url": "https://opencollective.com/vitest"
}
},
- "node_modules/@vitest/utils/node_modules/@jest/schemas": {
- "version": "29.6.0",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz",
- "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==",
- "dev": true,
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/utils/node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true
- },
- "node_modules/@vitest/utils/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@vitest/utils/node_modules/diff-sequences": {
- "version": "29.4.3",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz",
- "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==",
- "dev": true,
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/utils/node_modules/pretty-format": {
- "version": "29.6.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz",
- "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==",
- "dev": true,
- "dependencies": {
- "@jest/schemas": "^29.6.0",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/abab": {
"version": "2.0.6",
- "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
- "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
- "dev": true
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/abort-controller": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
- "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "license": "MIT",
"dependencies": {
"event-target-shim": "^5.0.0"
},
@@ -904,14 +2365,13 @@
},
"node_modules/abortcontroller-polyfill": {
"version": "1.7.5",
- "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz",
- "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/acorn": {
- "version": "8.10.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
- "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "version": "8.11.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
+ "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -921,19 +2381,17 @@
}
},
"node_modules/acorn-walk": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
- "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "version": "8.3.2",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/agent-base": {
"version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"debug": "4"
},
@@ -941,6 +2399,18 @@
"node": ">= 6.0.0"
}
},
+ "node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
"node_modules/assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
@@ -952,34 +2422,29 @@
},
"node_modules/async-mutex": {
"version": "0.3.2",
- "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz",
- "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==",
+ "license": "MIT",
"dependencies": {
"tslib": "^2.3.1"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/balanced-match": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/boolbase": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
+ "license": "ISC"
},
"node_modules/brace-expansion": {
"version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -995,18 +2460,18 @@
}
},
"node_modules/chai": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz",
- "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz",
+ "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==",
"dev": true,
"dependencies": {
"assertion-error": "^1.1.0",
- "check-error": "^1.0.2",
- "deep-eql": "^4.1.2",
- "get-func-name": "^2.0.0",
- "loupe": "^2.3.1",
+ "check-error": "^1.0.3",
+ "deep-eql": "^4.1.3",
+ "get-func-name": "^2.0.2",
+ "loupe": "^2.3.6",
"pathval": "^1.1.1",
- "type-detect": "^4.0.5"
+ "type-detect": "^4.0.8"
},
"engines": {
"node": ">=4"
@@ -1014,9 +2479,8 @@
},
"node_modules/character-entities": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
- "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
"dev": true,
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -1024,9 +2488,8 @@
},
"node_modules/character-entities-legacy": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
- "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
"dev": true,
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -1034,28 +2497,29 @@
},
"node_modules/character-reference-invalid": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
- "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
"dev": true,
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/check-error": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
- "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
+ "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
"dev": true,
+ "dependencies": {
+ "get-func-name": "^2.0.2"
+ },
"engines": {
"node": "*"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
@@ -1065,9 +2529,8 @@
},
"node_modules/comma-separated-tokens": {
"version": "2.0.3",
- "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
- "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
"dev": true,
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -1075,21 +2538,18 @@
},
"node_modules/concat-map": {
"version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/convert-source-map": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
- "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
- "dev": true
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/cross-env": {
"version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
- "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"cross-spawn": "^7.0.1"
},
@@ -1105,18 +2565,16 @@
},
"node_modules/cross-fetch": {
"version": "3.1.5",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
- "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"node-fetch": "2.6.7"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -1128,8 +2586,7 @@
},
"node_modules/css-select": {
"version": "5.1.0",
- "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
- "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "license": "BSD-2-Clause",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
@@ -1143,8 +2600,7 @@
},
"node_modules/css-what": {
"version": "6.1.0",
- "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
- "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "license": "BSD-2-Clause",
"engines": {
"node": ">= 6"
},
@@ -1154,14 +2610,12 @@
},
"node_modules/cssom": {
"version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
- "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="
+ "license": "MIT"
},
"node_modules/cssstyle": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz",
- "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"rrweb-cssom": "^0.6.0"
},
@@ -1171,14 +2625,12 @@
},
"node_modules/dayjs": {
"version": "1.11.9",
- "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz",
- "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA=="
+ "license": "MIT"
},
"node_modules/debug": {
"version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
@@ -1193,15 +2645,13 @@
},
"node_modules/decimal.js": {
"version": "10.4.3",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
- "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/decode-named-character-reference": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
- "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"character-entities": "^2.0.0"
},
@@ -1224,30 +2674,35 @@
},
"node_modules/deepmerge": {
"version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
+ "node_modules/diff-sequences": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
+ "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
"node_modules/discontinuous-range": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
- "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ=="
+ "license": "MIT"
},
"node_modules/dom-serializer": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
- "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
@@ -1259,20 +2714,18 @@
},
"node_modules/domelementtype": {
"version": "2.3.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
- "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
- ]
+ ],
+ "license": "BSD-2-Clause"
},
"node_modules/domexception": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
- "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"webidl-conversions": "^7.0.0"
},
@@ -1282,8 +2735,7 @@
},
"node_modules/domhandler": {
"version": "5.0.3",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
- "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
"dependencies": {
"domelementtype": "^2.3.0"
},
@@ -1295,13 +2747,12 @@
}
},
"node_modules/domutils": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
- "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "version": "3.1.0",
+ "license": "BSD-2-Clause",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
- "domhandler": "^5.0.1"
+ "domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
@@ -1309,17 +2760,15 @@
},
"node_modules/dotenv": {
"version": "16.0.3",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
- "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=12"
}
},
"node_modules/entities": {
"version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
@@ -1328,9 +2777,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
- "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
+ "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
"dev": true,
"hasInstallScript": true,
"bin": {
@@ -1340,56 +2789,53 @@
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
+ "@esbuild/aix-ppc64": "0.20.2",
+ "@esbuild/android-arm": "0.20.2",
+ "@esbuild/android-arm64": "0.20.2",
+ "@esbuild/android-x64": "0.20.2",
+ "@esbuild/darwin-arm64": "0.20.2",
+ "@esbuild/darwin-x64": "0.20.2",
+ "@esbuild/freebsd-arm64": "0.20.2",
+ "@esbuild/freebsd-x64": "0.20.2",
+ "@esbuild/linux-arm": "0.20.2",
+ "@esbuild/linux-arm64": "0.20.2",
+ "@esbuild/linux-ia32": "0.20.2",
+ "@esbuild/linux-loong64": "0.20.2",
+ "@esbuild/linux-mips64el": "0.20.2",
+ "@esbuild/linux-ppc64": "0.20.2",
+ "@esbuild/linux-riscv64": "0.20.2",
+ "@esbuild/linux-s390x": "0.20.2",
+ "@esbuild/linux-x64": "0.20.2",
+ "@esbuild/netbsd-x64": "0.20.2",
+ "@esbuild/openbsd-x64": "0.20.2",
+ "@esbuild/sunos-x64": "0.20.2",
+ "@esbuild/win32-arm64": "0.20.2",
+ "@esbuild/win32-ia32": "0.20.2",
+ "@esbuild/win32-x64": "0.20.2"
}
},
"node_modules/event-source-polyfill": {
"version": "1.0.31",
- "resolved": "https://registry.npmjs.org/event-source-polyfill/-/event-source-polyfill-1.0.31.tgz",
- "integrity": "sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/event-target-shim": {
"version": "5.0.1",
- "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
- "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/eventsource": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
- "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==",
+ "license": "MIT",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/fetch-cookie": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-2.1.0.tgz",
- "integrity": "sha512-39+cZRbWfbibmj22R2Jy6dmTbAWC+oqun1f1FzQaNurkPDUP4C38jpeZbiXCR88RKRVDp8UcDrbFXkNhN+NjYg==",
+ "license": "Unlicense",
"dependencies": {
"set-cookie-parser": "^2.4.8",
"tough-cookie": "^4.0.0"
@@ -1397,9 +2843,8 @@
},
"node_modules/form-data": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
@@ -1411,14 +2856,13 @@
},
"node_modules/fs.realpath": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"optional": true,
@@ -1430,9 +2874,9 @@
}
},
"node_modules/get-func-name": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
- "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
+ "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
"dev": true,
"engines": {
"node": "*"
@@ -1440,9 +2884,8 @@
},
"node_modules/glob": {
"version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -1460,24 +2903,21 @@
},
"node_modules/has-flag": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/hash-wasm": {
"version": "4.9.0",
- "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.9.0.tgz",
- "integrity": "sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/hast-util-parse-selector": {
"version": "3.1.1",
- "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz",
- "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/hast": "^2.0.0"
},
@@ -1488,9 +2928,8 @@
},
"node_modules/hastscript": {
"version": "7.2.0",
- "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz",
- "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/hast": "^2.0.0",
"comma-separated-tokens": "^2.0.0",
@@ -1505,9 +2944,8 @@
},
"node_modules/html-encoding-sniffer": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
- "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"whatwg-encoding": "^2.0.0"
},
@@ -1517,14 +2955,12 @@
},
"node_modules/html-escaper": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/html-to-text": {
"version": "9.0.5",
- "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz",
- "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==",
+ "license": "MIT",
"dependencies": {
"@selderee/plugin-htmlparser2": "^0.11.0",
"deepmerge": "^4.3.1",
@@ -1538,8 +2974,6 @@
},
"node_modules/htmlparser2": {
"version": "8.0.1",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
- "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
@@ -1547,6 +2981,7 @@
"url": "https://github.com/sponsors/fb55"
}
],
+ "license": "MIT",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
@@ -1556,9 +2991,8 @@
},
"node_modules/http-proxy-agent": {
"version": "5.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
- "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@tootallnate/once": "2",
"agent-base": "6",
@@ -1570,9 +3004,8 @@
},
"node_modules/https-proxy-agent": {
"version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"agent-base": "6",
"debug": "4"
@@ -1583,9 +3016,8 @@
},
"node_modules/iconv-lite": {
"version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
@@ -1595,9 +3027,8 @@
},
"node_modules/inflight": {
"version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -1605,15 +3036,13 @@
},
"node_modules/inherits": {
"version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/is-alphabetical": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
- "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
"dev": true,
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -1621,9 +3050,8 @@
},
"node_modules/is-alphanumerical": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
- "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-alphabetical": "^2.0.0",
"is-decimal": "^2.0.0"
@@ -1635,9 +3063,8 @@
},
"node_modules/is-decimal": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
- "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
"dev": true,
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -1645,9 +3072,8 @@
},
"node_modules/is-hexadecimal": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
- "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
"dev": true,
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -1655,40 +3081,35 @@
},
"node_modules/is-potential-custom-element-name": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
- "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/isexe": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/isomorphic-fetch": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
- "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"node-fetch": "^2.6.1",
"whatwg-fetch": "^3.4.1"
}
},
"node_modules/istanbul-lib-coverage": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
- "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "version": "3.2.2",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=8"
}
},
"node_modules/istanbul-lib-report": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"istanbul-lib-coverage": "^3.0.0",
"make-dir": "^4.0.0",
@@ -1700,9 +3121,8 @@
},
"node_modules/istanbul-lib-source-maps": {
"version": "4.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
- "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"debug": "^4.1.1",
"istanbul-lib-coverage": "^3.0.0",
@@ -1714,9 +3134,8 @@
},
"node_modules/istanbul-reports": {
"version": "3.1.6",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
- "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"html-escaper": "^2.0.0",
"istanbul-lib-report": "^3.0.0"
@@ -1727,9 +3146,8 @@
},
"node_modules/jsdom": {
"version": "22.1.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz",
- "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"abab": "^2.0.6",
"cssstyle": "^3.0.0",
@@ -1769,9 +3187,8 @@
},
"node_modules/jsdom/node_modules/data-urls": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz",
- "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"abab": "^2.0.6",
"whatwg-mimetype": "^3.0.0",
@@ -1783,9 +3200,8 @@
},
"node_modules/jsdom/node_modules/ws": {
"version": "8.13.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
- "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10.0.0"
},
@@ -1803,19 +3219,18 @@
}
},
"node_modules/jsonc-parser": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
- "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz",
+ "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==",
"dev": true
},
"node_modules/katex": {
"version": "0.16.2",
- "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.2.tgz",
- "integrity": "sha512-70DJdQAyh9EMsthw3AaQlDyFf54X7nWEUIa5W+rq8XOpEk//w5Th7/8SqFqpvi/KZ2t6MHUj4f9wLmztBmAYQA==",
"funding": [
"https://opencollective.com/katex",
"https://github.com/sponsors/katex"
],
+ "license": "MIT",
"dependencies": {
"commander": "^8.0.0"
},
@@ -1825,24 +3240,21 @@
},
"node_modules/katex/node_modules/commander": {
"version": "8.3.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
- "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/leac": {
"version": "0.6.0",
- "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
- "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==",
+ "license": "MIT",
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/linkedom": {
"version": "0.14.20",
- "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.14.20.tgz",
- "integrity": "sha512-H7BX22kn4Ul4Mfr5/Jz039TgfsYce/YCvQ6272LEIlIJ1sYmU3R6yFNSYZU6iDX2aoF76wX+qjcSZEaLwumcAw==",
+ "license": "ISC",
"dependencies": {
"css-select": "^5.1.0",
"cssom": "^0.5.0",
@@ -1853,13 +3265,11 @@
},
"node_modules/linkedom/node_modules/html-escaper": {
"version": "3.0.3",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz",
- "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="
+ "license": "MIT"
},
"node_modules/liqe": {
"version": "1.13.0",
- "resolved": "https://registry.npmjs.org/liqe/-/liqe-1.13.0.tgz",
- "integrity": "sha512-3ZnkfWXtnG7Bnzy5zfQ3VWYSf0Mdv8YXMgYOC3ooXyW6wNS6XElxJ9zVHT7xeTh8BL76U0T0vo8y4L41DuWSaw==",
+ "license": "BSD-3-Clause",
"dependencies": {
"nearley": "^2.20.1",
"ts-error": "^1.0.6"
@@ -1881,19 +3291,18 @@
}
},
"node_modules/loupe": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
- "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==",
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
+ "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
"dev": true,
"dependencies": {
- "get-func-name": "^2.0.0"
+ "get-func-name": "^2.0.1"
}
},
"node_modules/lru-cache": {
"version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
},
@@ -1902,10 +3311,9 @@
}
},
"node_modules/magic-string": {
- "version": "0.30.2",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz",
- "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==",
+ "version": "0.30.6",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
@@ -1915,9 +3323,8 @@
},
"node_modules/make-dir": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
- "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"semver": "^7.5.3"
},
@@ -1930,17 +3337,15 @@
},
"node_modules/mime-db": {
"version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
@@ -1950,9 +3355,8 @@
},
"node_modules/minimatch": {
"version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -1961,56 +3365,34 @@
}
},
"node_modules/mlly": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.0.tgz",
- "integrity": "sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==",
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz",
+ "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==",
"dev": true,
"dependencies": {
- "acorn": "^8.9.0",
- "pathe": "^1.1.1",
+ "acorn": "^8.11.3",
+ "pathe": "^1.1.2",
"pkg-types": "^1.0.3",
- "ufo": "^1.1.2"
+ "ufo": "^1.3.2"
}
},
"node_modules/mockdate": {
"version": "3.0.5",
- "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz",
- "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/moo": {
"version": "0.5.2",
- "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
- "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
+ "license": "BSD-3-Clause"
},
"node_modules/ms": {
"version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- },
- "node_modules/nanoid": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
- "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
+ "license": "MIT"
},
"node_modules/nearley": {
"version": "2.20.1",
- "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
- "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
+ "license": "MIT",
"dependencies": {
"commander": "^2.19.0",
"moo": "^0.5.0",
@@ -2030,13 +3412,11 @@
},
"node_modules/nearley/node_modules/commander": {
"version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ "license": "MIT"
},
"node_modules/node-fetch": {
"version": "2.6.7",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
- "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
@@ -2054,18 +3434,15 @@
},
"node_modules/node-fetch/node_modules/tr46": {
"version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ "license": "MIT"
},
"node_modules/node-fetch/node_modules/webidl-conversions": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ "license": "BSD-2-Clause"
},
"node_modules/node-fetch/node_modules/whatwg-url": {
"version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
@@ -2073,8 +3450,7 @@
},
"node_modules/nth-check": {
"version": "2.1.1",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
- "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "license": "BSD-2-Clause",
"dependencies": {
"boolbase": "^1.0.0"
},
@@ -2084,35 +3460,46 @@
},
"node_modules/nwsapi": {
"version": "2.2.7",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz",
- "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/once": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/otplib": {
"version": "12.0.1",
- "resolved": "https://registry.npmjs.org/otplib/-/otplib-12.0.1.tgz",
- "integrity": "sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@otplib/core": "^12.0.1",
"@otplib/preset-default": "^12.0.1",
"@otplib/preset-v11": "^12.0.1"
}
},
+ "node_modules/p-limit": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
+ "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^1.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/parse-entities": {
"version": "4.0.1",
- "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz",
- "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/unist": "^2.0.0",
"character-entities": "^2.0.0",
@@ -2130,9 +3517,8 @@
},
"node_modules/parse5": {
"version": "7.1.2",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
- "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"entities": "^4.4.0"
},
@@ -2142,8 +3528,7 @@
},
"node_modules/parseley": {
"version": "0.12.0",
- "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.0.tgz",
- "integrity": "sha512-uLqDm6IQVb6m50a3dIxF66hI8VWr7wFDYUULtHa1ITRh9mwYIXzFpPTkPM66Cm5V0t+bMyeSHgUCGzoXTV96LQ==",
+ "license": "MIT",
"dependencies": {
"leac": "^0.6.0",
"peberminta": "^0.9.0"
@@ -2154,26 +3539,24 @@
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/path-key": {
"version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/pathe": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz",
- "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
+ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
"dev": true
},
"node_modules/pathval": {
@@ -2187,17 +3570,15 @@
},
"node_modules/peberminta": {
"version": "0.9.0",
- "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz",
- "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==",
+ "license": "MIT",
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/picocolors": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/pkg-types": {
"version": "1.0.3",
@@ -2211,9 +3592,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz",
- "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==",
+ "version": "8.4.38",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+ "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
"dev": true,
"funding": [
{
@@ -2230,27 +3611,57 @@
}
],
"dependencies": {
- "nanoid": "^3.3.6",
+ "nanoid": "^3.3.7",
"picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "source-map-js": "^1.2.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/postcss/node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
"node_modules/prismjs": {
"version": "1.29.0",
- "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
- "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/property-information": {
"version": "6.2.0",
- "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz",
- "integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==",
"dev": true,
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -2258,36 +3669,30 @@
},
"node_modules/psl": {
"version": "1.9.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
- "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
+ "license": "MIT"
},
"node_modules/punycode": {
"version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/qclone": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/qclone/-/qclone-1.2.0.tgz",
- "integrity": "sha512-ah9Mpb9/UBdY5vvOcpqFq8g489YIqLTJlSk+FddPyPbE1nISrYx3TBAKQB590cGoXTd5yWQbVstDVatHMOoxnA=="
+ "license": "MIT"
},
"node_modules/querystringify": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
- "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
+ "license": "MIT"
},
"node_modules/railroad-diagrams": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
- "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A=="
+ "license": "CC0-1.0"
},
"node_modules/randexp": {
"version": "0.4.6",
- "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
- "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
+ "license": "MIT",
"dependencies": {
"discontinuous-range": "1.0.0",
"ret": "~0.1.10"
@@ -2304,9 +3709,8 @@
},
"node_modules/refractor": {
"version": "4.8.1",
- "resolved": "https://registry.npmjs.org/refractor/-/refractor-4.8.1.tgz",
- "integrity": "sha512-/fk5sI0iTgFYlmVGYVew90AoYnNMP6pooClx/XKqyeeCQXrL0Kvgn8V0VEht5ccdljbzzF1i3Q213gcntkRExg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/hast": "^2.0.0",
"@types/prismjs": "^1.0.0",
@@ -2320,50 +3724,65 @@
},
"node_modules/requires-port": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
+ "license": "MIT"
},
"node_modules/ret": {
"version": "0.1.15",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "license": "MIT",
"engines": {
"node": ">=0.12"
}
},
+ "node_modules/rfdc": {
+ "version": "1.3.1",
+ "license": "MIT"
+ },
"node_modules/rollup": {
- "version": "3.28.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.0.tgz",
- "integrity": "sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz",
+ "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==",
"dev": true,
+ "dependencies": {
+ "@types/estree": "1.0.5"
+ },
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
- "node": ">=14.18.0",
+ "node": ">=18.0.0",
"npm": ">=8.0.0"
},
"optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.13.0",
+ "@rollup/rollup-android-arm64": "4.13.0",
+ "@rollup/rollup-darwin-arm64": "4.13.0",
+ "@rollup/rollup-darwin-x64": "4.13.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.13.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.13.0",
+ "@rollup/rollup-linux-arm64-musl": "4.13.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.13.0",
+ "@rollup/rollup-linux-x64-gnu": "4.13.0",
+ "@rollup/rollup-linux-x64-musl": "4.13.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.13.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.13.0",
+ "@rollup/rollup-win32-x64-msvc": "4.13.0",
"fsevents": "~2.3.2"
}
},
"node_modules/rrweb-cssom": {
"version": "0.6.0",
- "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
- "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/safer-buffer": {
"version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/saxes": {
"version": "6.0.0",
- "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
- "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"xmlchars": "^2.2.0"
},
@@ -2373,8 +3792,7 @@
},
"node_modules/selderee": {
"version": "0.11.0",
- "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz",
- "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==",
+ "license": "MIT",
"dependencies": {
"parseley": "^0.12.0"
},
@@ -2384,9 +3802,8 @@
},
"node_modules/semver": {
"version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -2399,14 +3816,12 @@
},
"node_modules/set-cookie-parser": {
"version": "2.6.0",
- "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz",
- "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ=="
+ "license": "MIT"
},
"node_modules/shebang-command": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
@@ -2416,32 +3831,29 @@
},
"node_modules/shebang-command/node_modules/shebang-regex": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/siginfo": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
- "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/source-map": {
"version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -2449,9 +3861,8 @@
},
"node_modules/space-separated-tokens": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
- "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
"dev": true,
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -2459,20 +3870,17 @@
},
"node_modules/spark-md5": {
"version": "3.0.2",
- "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
- "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
+ "license": "(WTFPL OR MIT)"
},
"node_modules/stackback": {
"version": "0.0.2",
- "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
- "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/std-env": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz",
- "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==",
- "dev": true
+ "version": "3.7.0",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/strip-literal": {
"version": "1.3.0",
@@ -2488,9 +3896,8 @@
},
"node_modules/supports-color": {
"version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -2500,15 +3907,13 @@
},
"node_modules/symbol-tree": {
"version": "3.2.4",
- "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
- "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/test-exclude": {
"version": "6.0.0",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
- "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"@istanbuljs/schema": "^0.1.2",
"glob": "^7.1.4",
@@ -2520,18 +3925,15 @@
},
"node_modules/thirty-two": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz",
- "integrity": "sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==",
"dev": true,
"engines": {
"node": ">=0.2.6"
}
},
"node_modules/tinybench": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz",
- "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==",
- "dev": true
+ "version": "2.6.0",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/tinypool": {
"version": "0.7.0",
@@ -2543,9 +3945,9 @@
}
},
"node_modules/tinyspy": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz",
- "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
+ "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
"dev": true,
"engines": {
"node": ">=14.0.0"
@@ -2553,8 +3955,7 @@
},
"node_modules/tough-cookie": {
"version": "4.1.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
- "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
+ "license": "BSD-3-Clause",
"dependencies": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
@@ -2567,9 +3968,8 @@
},
"node_modules/tr46": {
"version": "4.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
- "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"punycode": "^2.3.0"
},
@@ -2579,13 +3979,11 @@
},
"node_modules/ts-error": {
"version": "1.0.6",
- "resolved": "https://registry.npmjs.org/ts-error/-/ts-error-1.0.6.tgz",
- "integrity": "sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA=="
+ "license": "MIT"
},
"node_modules/tslib": {
"version": "2.4.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
- "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
+ "license": "0BSD"
},
"node_modules/type-detect": {
"version": "4.0.8",
@@ -2597,71 +3995,67 @@
}
},
"node_modules/ufo": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.2.0.tgz",
- "integrity": "sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz",
+ "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==",
"dev": true
},
"node_modules/uhyphen": {
"version": "0.1.0",
- "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.1.0.tgz",
- "integrity": "sha512-o0QVGuFg24FK765Qdd5kk0zU/U4dEsCtN/GSiwNI9i8xsSVtjIAOdTaVhLwZ1nrbWxFVMxNDDl+9fednsOMsBw=="
+ "license": "ISC"
},
"node_modules/universalify": {
"version": "0.2.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
- "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "license": "MIT",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/url-parse": {
"version": "1.5.10",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
- "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "license": "MIT",
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"node_modules/v8-to-istanbul": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz",
- "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==",
+ "version": "9.2.0",
"dev": true,
+ "license": "ISC",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.12",
"@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^1.6.0"
+ "convert-source-map": "^2.0.0"
},
"engines": {
"node": ">=10.12.0"
}
},
"node_modules/vite": {
- "version": "4.4.9",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz",
- "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.2.tgz",
+ "integrity": "sha512-FWZbz0oSdLq5snUI0b6sULbz58iXFXdvkZfZWR/F0ZJuKTSPO7v72QPXt6KqYeMFb0yytNp6kZosxJ96Nr/wDQ==",
"dev": true,
"dependencies": {
- "esbuild": "^0.18.10",
- "postcss": "^8.4.27",
- "rollup": "^3.27.1"
+ "esbuild": "^0.20.1",
+ "postcss": "^8.4.36",
+ "rollup": "^4.13.0"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
- "node": "^14.18.0 || >=16.0.0"
+ "node": "^18.0.0 || >=20.0.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
- "fsevents": "~2.3.2"
+ "fsevents": "~2.3.3"
},
"peerDependencies": {
- "@types/node": ">= 14",
+ "@types/node": "^18.0.0 || >=20.0.0",
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
@@ -2694,9 +4088,9 @@
}
},
"node_modules/vite-node": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.1.tgz",
- "integrity": "sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==",
+ "version": "0.34.6",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz",
+ "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==",
"dev": true,
"dependencies": {
"cac": "^6.7.14",
@@ -2704,7 +4098,7 @@
"mlly": "^1.4.0",
"pathe": "^1.1.1",
"picocolors": "^1.0.0",
- "vite": "^3.0.0 || ^4.0.0"
+ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0"
},
"bin": {
"vite-node": "vite-node.mjs"
@@ -2717,23 +4111,23 @@
}
},
"node_modules/vitest": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.1.tgz",
- "integrity": "sha512-G1PzuBEq9A75XSU88yO5G4vPT20UovbC/2osB2KEuV/FisSIIsw7m5y2xMdB7RsAGHAfg2lPmp2qKr3KWliVlQ==",
+ "version": "0.34.6",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz",
+ "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==",
"dev": true,
"dependencies": {
"@types/chai": "^4.3.5",
"@types/chai-subset": "^1.3.3",
"@types/node": "*",
- "@vitest/expect": "0.34.1",
- "@vitest/runner": "0.34.1",
- "@vitest/snapshot": "0.34.1",
- "@vitest/spy": "0.34.1",
- "@vitest/utils": "0.34.1",
+ "@vitest/expect": "0.34.6",
+ "@vitest/runner": "0.34.6",
+ "@vitest/snapshot": "0.34.6",
+ "@vitest/spy": "0.34.6",
+ "@vitest/utils": "0.34.6",
"acorn": "^8.9.0",
"acorn-walk": "^8.2.0",
"cac": "^6.7.14",
- "chai": "^4.3.7",
+ "chai": "^4.3.10",
"debug": "^4.3.4",
"local-pkg": "^0.4.3",
"magic-string": "^0.30.1",
@@ -2743,8 +4137,8 @@
"strip-literal": "^1.0.1",
"tinybench": "^2.5.0",
"tinypool": "^0.7.0",
- "vite": "^3.0.0 || ^4.0.0",
- "vite-node": "0.34.1",
+ "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0",
+ "vite-node": "0.34.6",
"why-is-node-running": "^2.2.2"
},
"bin": {
@@ -2795,9 +4189,8 @@
},
"node_modules/vitest-fetch-mock": {
"version": "0.2.2",
- "resolved": "https://registry.npmjs.org/vitest-fetch-mock/-/vitest-fetch-mock-0.2.2.tgz",
- "integrity": "sha512-XmH6QgTSjCWrqXoPREIdbj40T7i1xnGmAsTAgfckoO75W1IEHKR8hcPCQ7SO16RsdW1t85oUm6pcQRLeBgjVYQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"cross-fetch": "^3.0.6"
},
@@ -2810,9 +4203,8 @@
},
"node_modules/w3c-xmlserializer": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
- "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"xml-name-validator": "^4.0.0"
},
@@ -2822,18 +4214,16 @@
},
"node_modules/webidl-conversions": {
"version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=12"
}
},
"node_modules/whatwg-encoding": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
- "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"iconv-lite": "0.6.3"
},
@@ -2843,24 +4233,21 @@
},
"node_modules/whatwg-fetch": {
"version": "3.6.17",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.17.tgz",
- "integrity": "sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/whatwg-mimetype": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
- "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=12"
}
},
"node_modules/whatwg-url": {
"version": "12.0.1",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz",
- "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"tr46": "^4.1.1",
"webidl-conversions": "^7.0.0"
@@ -2871,9 +4258,8 @@
},
"node_modules/which": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
@@ -2886,9 +4272,8 @@
},
"node_modules/why-is-node-running": {
"version": "2.2.2",
- "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz",
- "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"siginfo": "^2.0.0",
"stackback": "0.0.2"
@@ -2902,20 +4287,19 @@
},
"node_modules/wrappy": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/ws": {
- "version": "7.5.9",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
- "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+ "version": "8.16.0",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=8.3.0"
+ "node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
- "utf-8-validate": "^5.0.2"
+ "utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
@@ -2928,2040 +4312,33 @@
},
"node_modules/xml-name-validator": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
- "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=12"
}
},
"node_modules/xmlchars": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
- "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/yallist": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- }
- },
- "dependencies": {
- "@ampproject/remapping": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
- "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
"dev": true,
- "requires": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
- }
+ "license": "ISC"
},
- "@bcoe/v8-coverage": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
- "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
- "dev": true
- },
- "@esbuild/android-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
- "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
- "dev": true,
- "optional": true
- },
- "@esbuild/android-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
- "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
- "dev": true,
- "optional": true
- },
- "@esbuild/android-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
- "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
- "dev": true,
- "optional": true
- },
- "@esbuild/darwin-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
- "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
- "dev": true,
- "optional": true
- },
- "@esbuild/darwin-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
- "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
- "dev": true,
- "optional": true
- },
- "@esbuild/freebsd-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
- "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
- "dev": true,
- "optional": true
- },
- "@esbuild/freebsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
- "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
- "dev": true,
- "optional": true
- },
- "@esbuild/linux-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
- "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
- "dev": true,
- "optional": true
- },
- "@esbuild/linux-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
- "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
- "dev": true,
- "optional": true
- },
- "@esbuild/linux-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
- "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
- "dev": true,
- "optional": true
- },
- "@esbuild/linux-loong64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
- "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
- "dev": true,
- "optional": true
- },
- "@esbuild/linux-mips64el": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
- "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
- "dev": true,
- "optional": true
- },
- "@esbuild/linux-ppc64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
- "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
- "dev": true,
- "optional": true
- },
- "@esbuild/linux-riscv64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
- "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
- "dev": true,
- "optional": true
- },
- "@esbuild/linux-s390x": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
- "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
- "dev": true,
- "optional": true
- },
- "@esbuild/linux-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
- "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
- "dev": true,
- "optional": true
- },
- "@esbuild/netbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
- "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
- "dev": true,
- "optional": true
- },
- "@esbuild/openbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
- "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
- "dev": true,
- "optional": true
- },
- "@esbuild/sunos-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
- "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
- "dev": true,
- "optional": true
- },
- "@esbuild/win32-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
- "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
- "dev": true,
- "optional": true
- },
- "@esbuild/win32-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
- "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
- "dev": true,
- "optional": true
- },
- "@esbuild/win32-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
- "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
- "dev": true,
- "optional": true
- },
- "@istanbuljs/schema": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
- "dev": true
- },
- "@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
- "dev": true,
- "requires": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- }
- },
- "@jridgewell/resolve-uri": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
- "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
- "dev": true
- },
- "@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
- "dev": true
- },
- "@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
- "dev": true
- },
- "@jridgewell/trace-mapping": {
- "version": "0.3.19",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
- "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
- "dev": true,
- "requires": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "@microsoft/signalr": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-8.0.0.tgz",
- "integrity": "sha512-K/wS/VmzRWePCGqGh8MU8OWbS1Zvu7DG7LSJS62fBB8rJUXwwj4axQtqrAAwKGUZHQF6CuteuQR9xMsVpM2JNA==",
- "requires": {
- "abort-controller": "^3.0.0",
- "eventsource": "^2.0.2",
- "fetch-cookie": "^2.0.3",
- "node-fetch": "^2.6.7",
- "ws": "^7.4.5"
- }
- },
- "@notesnook/crypto": {
- "version": "file:../crypto",
- "requires": {
- "@notesnook/sodium": "file:../sodium"
- }
- },
- "@notesnook/logger": {
- "version": "file:../logger"
- },
- "@otplib/core": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/core/-/core-12.0.1.tgz",
- "integrity": "sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA==",
- "dev": true
- },
- "@otplib/plugin-crypto": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/plugin-crypto/-/plugin-crypto-12.0.1.tgz",
- "integrity": "sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g==",
- "dev": true,
- "requires": {
- "@otplib/core": "^12.0.1"
- }
- },
- "@otplib/plugin-thirty-two": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/plugin-thirty-two/-/plugin-thirty-two-12.0.1.tgz",
- "integrity": "sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA==",
- "dev": true,
- "requires": {
- "@otplib/core": "^12.0.1",
- "thirty-two": "^1.0.2"
- }
- },
- "@otplib/preset-default": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/preset-default/-/preset-default-12.0.1.tgz",
- "integrity": "sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ==",
- "dev": true,
- "requires": {
- "@otplib/core": "^12.0.1",
- "@otplib/plugin-crypto": "^12.0.1",
- "@otplib/plugin-thirty-two": "^12.0.1"
- }
- },
- "@otplib/preset-v11": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@otplib/preset-v11/-/preset-v11-12.0.1.tgz",
- "integrity": "sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==",
- "dev": true,
- "requires": {
- "@otplib/core": "^12.0.1",
- "@otplib/plugin-crypto": "^12.0.1",
- "@otplib/plugin-thirty-two": "^12.0.1"
- }
- },
- "@readme/data-urls": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@readme/data-urls/-/data-urls-3.0.0.tgz",
- "integrity": "sha512-b0L7VWqbLZqOSSAFUrxS5ZwUfec35WDsAwwCH481vYnhk0dWO3nvmNVNCbP8CY4cXqwL1W4uCAnhDz+CUmXM3g=="
- },
- "@selderee/plugin-htmlparser2": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz",
- "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==",
- "requires": {
- "domhandler": "^5.0.3",
- "selderee": "^0.11.0"
- }
- },
- "@streetwriters/showdown": {
- "version": "3.0.5-alpha",
- "resolved": "https://registry.npmjs.org/@streetwriters/showdown/-/showdown-3.0.5-alpha.tgz",
- "integrity": "sha512-jD9JFhxLDx6XeyZOLVB0zWtwGduwNiFpxn5rxu6ThyKyWGnu1O+L1w04WLC1L56pyEhypr3Tsk24dzo2Se/50g=="
- },
- "@tootallnate/once": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
- "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
- "dev": true
- },
- "@types/chai": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz",
- "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==",
- "dev": true
- },
- "@types/chai-subset": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz",
- "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==",
- "dev": true,
- "requires": {
- "@types/chai": "*"
- }
- },
- "@types/hast": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz",
- "integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==",
- "dev": true,
- "requires": {
- "@types/unist": "^2"
- }
- },
- "@types/html-to-text": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@types/html-to-text/-/html-to-text-9.0.0.tgz",
- "integrity": "sha512-FnF3p2FJZ1kJT/0C/lmBzw7HSlH3RhtACVYyrwUsJoCmFNuiLpusWT2FWWB7P9A48CaYpvD6Q2fprn7sZeffpw==",
- "dev": true
- },
- "@types/istanbul-lib-coverage": {
- "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==",
- "dev": true
- },
- "@types/katex": {
- "version": "0.16.1",
- "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.1.tgz",
- "integrity": "sha512-cwglq2A63Yk082CQk0t8LIoDhZAVgJqkumLyk3grpg3K8sevaDW//Qsspmxj9Sf+97biqt79CfAlPrvizHlP0w==",
- "dev": true
- },
- "@types/node": {
- "version": "18.11.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
- "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
- "dev": true
- },
- "@types/prismjs": {
- "version": "1.26.0",
- "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.0.tgz",
- "integrity": "sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==",
- "dev": true
- },
- "@types/streetwriters__showdown": {
- "version": "npm:@types/showdown@2.0.6",
- "resolved": "https://registry.npmjs.org/@types/showdown/-/showdown-2.0.6.tgz",
- "integrity": "sha512-pTvD/0CIeqe4x23+YJWlX2gArHa8G0J0Oh6GKaVXV7TAeickpkkZiNOgFcFcmLQ5lB/K0qBJL1FtRYltBfbGCQ==",
- "dev": true
- },
- "@types/unist": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.7.tgz",
- "integrity": "sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==",
- "dev": true
- },
- "@vitest/coverage-v8": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-0.34.1.tgz",
- "integrity": "sha512-lRgUwjTMr8idXEbUPSNH4jjRZJXJCVY3BqUa+LDXyJVe3pldxYMn/r0HMqatKUGTp0Kyf1j5LfFoY6kRqRp7jw==",
- "dev": true,
- "requires": {
- "@ampproject/remapping": "^2.2.1",
- "@bcoe/v8-coverage": "^0.2.3",
- "istanbul-lib-coverage": "^3.2.0",
- "istanbul-lib-report": "^3.0.1",
- "istanbul-lib-source-maps": "^4.0.1",
- "istanbul-reports": "^3.1.5",
- "magic-string": "^0.30.1",
- "picocolors": "^1.0.0",
- "std-env": "^3.3.3",
- "test-exclude": "^6.0.0",
- "v8-to-istanbul": "^9.1.0"
- }
- },
- "@vitest/expect": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.1.tgz",
- "integrity": "sha512-q2CD8+XIsQ+tHwypnoCk8Mnv5e6afLFvinVGCq3/BOT4kQdVQmY6rRfyKkwcg635lbliLPqbunXZr+L1ssUWiQ==",
- "dev": true,
- "requires": {
- "@vitest/spy": "0.34.1",
- "@vitest/utils": "0.34.1",
- "chai": "^4.3.7"
- }
- },
- "@vitest/runner": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.1.tgz",
- "integrity": "sha512-YfQMpYzDsYB7yqgmlxZ06NI4LurHWfrH7Wy3Pvf/z/vwUSgq1zLAb1lWcItCzQG+NVox+VvzlKQrYEXb47645g==",
- "dev": true,
- "requires": {
- "@vitest/utils": "0.34.1",
- "p-limit": "^4.0.0",
- "pathe": "^1.1.1"
- },
- "dependencies": {
- "p-limit": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
- "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
- "dev": true,
- "requires": {
- "yocto-queue": "^1.0.0"
- }
- },
- "yocto-queue": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
- "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
- "dev": true
- }
- }
- },
- "@vitest/snapshot": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.1.tgz",
- "integrity": "sha512-0O9LfLU0114OqdF8lENlrLsnn024Tb1CsS9UwG0YMWY2oGTQfPtkW+B/7ieyv0X9R2Oijhi3caB1xgGgEgclSQ==",
- "dev": true,
- "requires": {
- "magic-string": "^0.30.1",
- "pathe": "^1.1.1",
- "pretty-format": "^29.5.0"
- },
- "dependencies": {
- "@jest/schemas": {
- "version": "29.6.0",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz",
- "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==",
- "dev": true,
- "requires": {
- "@sinclair/typebox": "^0.27.8"
- }
- },
- "@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true
- },
- "ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true
- },
- "pretty-format": {
- "version": "29.6.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz",
- "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==",
- "dev": true,
- "requires": {
- "@jest/schemas": "^29.6.0",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- }
- }
- }
- },
- "@vitest/spy": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.1.tgz",
- "integrity": "sha512-UT4WcI3EAPUNO8n6y9QoEqynGGEPmmRxC+cLzneFFXpmacivjHZsNbiKD88KUScv5DCHVDgdBsLD7O7s1enFcQ==",
- "dev": true,
- "requires": {
- "tinyspy": "^2.1.1"
- }
- },
- "@vitest/utils": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.1.tgz",
- "integrity": "sha512-/ql9dsFi4iuEbiNcjNHQWXBum7aL8pyhxvfnD9gNtbjR9fUKAjxhj4AA3yfLXg6gJpMGGecvtF8Au2G9y3q47Q==",
- "dev": true,
- "requires": {
- "diff-sequences": "^29.4.3",
- "loupe": "^2.3.6",
- "pretty-format": "^29.5.0"
- },
- "dependencies": {
- "@jest/schemas": {
- "version": "29.6.0",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz",
- "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==",
- "dev": true,
- "requires": {
- "@sinclair/typebox": "^0.27.8"
- }
- },
- "@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true
- },
- "ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true
- },
- "diff-sequences": {
- "version": "29.4.3",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz",
- "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==",
- "dev": true
- },
- "pretty-format": {
- "version": "29.6.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz",
- "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==",
- "dev": true,
- "requires": {
- "@jest/schemas": "^29.6.0",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- }
- }
- }
- },
- "abab": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
- "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
- "dev": true
- },
- "abort-controller": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
- "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
- "requires": {
- "event-target-shim": "^5.0.0"
- }
- },
- "abortcontroller-polyfill": {
- "version": "1.7.5",
- "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz",
- "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==",
- "dev": true
- },
- "acorn": {
- "version": "8.10.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
- "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
- "dev": true
- },
- "acorn-walk": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
- "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
- "dev": true
- },
- "agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "dev": true,
- "requires": {
- "debug": "4"
- }
- },
- "assertion-error": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
- "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
- "dev": true
- },
- "async-mutex": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz",
- "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==",
- "requires": {
- "tslib": "^2.3.1"
- }
- },
- "asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "dev": true
- },
- "balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
- },
- "boolbase": {
+ "node_modules/yocto-queue": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
+ "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
"dev": true,
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "cac": {
- "version": "6.7.14",
- "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
- "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
- "dev": true
- },
- "chai": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz",
- "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==",
- "dev": true,
- "requires": {
- "assertion-error": "^1.1.0",
- "check-error": "^1.0.2",
- "deep-eql": "^4.1.2",
- "get-func-name": "^2.0.0",
- "loupe": "^2.3.1",
- "pathval": "^1.1.1",
- "type-detect": "^4.0.5"
- }
- },
- "character-entities": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
- "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
- "dev": true
- },
- "character-entities-legacy": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
- "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
- "dev": true
- },
- "character-reference-invalid": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
- "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
- "dev": true
- },
- "check-error": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
- "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==",
- "dev": true
- },
- "combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
- "requires": {
- "delayed-stream": "~1.0.0"
- }
- },
- "comma-separated-tokens": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
- "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
- "dev": true
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "convert-source-map": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
- "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
- "dev": true
- },
- "cross-env": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
- "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
- "dev": true,
- "requires": {
- "cross-spawn": "^7.0.1"
- }
- },
- "cross-fetch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
- "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
- "dev": true,
- "requires": {
- "node-fetch": "2.6.7"
- }
- },
- "cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
- "dev": true,
- "requires": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- }
- },
- "css-select": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
- "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
- "requires": {
- "boolbase": "^1.0.0",
- "css-what": "^6.1.0",
- "domhandler": "^5.0.2",
- "domutils": "^3.0.1",
- "nth-check": "^2.0.1"
- }
- },
- "css-what": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
- "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
- },
- "cssom": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
- "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="
- },
- "cssstyle": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz",
- "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==",
- "dev": true,
- "requires": {
- "rrweb-cssom": "^0.6.0"
- }
- },
- "dayjs": {
- "version": "1.11.9",
- "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz",
- "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA=="
- },
- "debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "dev": true,
- "requires": {
- "ms": "2.1.2"
- }
- },
- "decimal.js": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
- "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
- "dev": true
- },
- "decode-named-character-reference": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
- "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
- "dev": true,
- "requires": {
- "character-entities": "^2.0.0"
- }
- },
- "deep-eql": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
- "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
- "dev": true,
- "requires": {
- "type-detect": "^4.0.0"
- }
- },
- "deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="
- },
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "dev": true
- },
- "discontinuous-range": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
- "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ=="
- },
- "dom-serializer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
- "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
- "requires": {
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.2",
- "entities": "^4.2.0"
- }
- },
- "domelementtype": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
- "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
- },
- "domexception": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
- "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
- "dev": true,
- "requires": {
- "webidl-conversions": "^7.0.0"
- }
- },
- "domhandler": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
- "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
- "requires": {
- "domelementtype": "^2.3.0"
- }
- },
- "domutils": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
- "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
- "requires": {
- "dom-serializer": "^2.0.0",
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.1"
- }
- },
- "dotenv": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
- "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
- "dev": true
- },
- "entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
- },
- "esbuild": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
- "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
- "dev": true,
- "requires": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
- }
- },
- "event-source-polyfill": {
- "version": "1.0.31",
- "resolved": "https://registry.npmjs.org/event-source-polyfill/-/event-source-polyfill-1.0.31.tgz",
- "integrity": "sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==",
- "dev": true
- },
- "event-target-shim": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
- "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
- },
- "eventsource": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
- "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA=="
- },
- "fetch-cookie": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-2.1.0.tgz",
- "integrity": "sha512-39+cZRbWfbibmj22R2Jy6dmTbAWC+oqun1f1FzQaNurkPDUP4C38jpeZbiXCR88RKRVDp8UcDrbFXkNhN+NjYg==",
- "requires": {
- "set-cookie-parser": "^2.4.8",
- "tough-cookie": "^4.0.0"
- }
- },
- "form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
- "dev": true,
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
- },
- "fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "optional": true
- },
- "get-func-name": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
- "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==",
- "dev": true
- },
- "glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "hash-wasm": {
- "version": "4.9.0",
- "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.9.0.tgz",
- "integrity": "sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==",
- "dev": true
- },
- "hast-util-parse-selector": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz",
- "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==",
- "dev": true,
- "requires": {
- "@types/hast": "^2.0.0"
- }
- },
- "hastscript": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz",
- "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==",
- "dev": true,
- "requires": {
- "@types/hast": "^2.0.0",
- "comma-separated-tokens": "^2.0.0",
- "hast-util-parse-selector": "^3.0.0",
- "property-information": "^6.0.0",
- "space-separated-tokens": "^2.0.0"
- }
- },
- "html-encoding-sniffer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
- "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
- "dev": true,
- "requires": {
- "whatwg-encoding": "^2.0.0"
- }
- },
- "html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true
- },
- "html-to-text": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz",
- "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==",
- "requires": {
- "@selderee/plugin-htmlparser2": "^0.11.0",
- "deepmerge": "^4.3.1",
- "dom-serializer": "^2.0.0",
- "htmlparser2": "^8.0.1",
- "selderee": "^0.11.0"
- }
- },
- "htmlparser2": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
- "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
- "requires": {
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.2",
- "domutils": "^3.0.1",
- "entities": "^4.3.0"
- }
- },
- "http-proxy-agent": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
- "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
- "dev": true,
- "requires": {
- "@tootallnate/once": "2",
- "agent-base": "6",
- "debug": "4"
- }
- },
- "https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "dev": true,
- "requires": {
- "agent-base": "6",
- "debug": "4"
- }
- },
- "iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "dev": true,
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- }
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "dev": true,
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
- },
- "is-alphabetical": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
- "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
- "dev": true
- },
- "is-alphanumerical": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
- "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
- "dev": true,
- "requires": {
- "is-alphabetical": "^2.0.0",
- "is-decimal": "^2.0.0"
- }
- },
- "is-decimal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
- "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
- "dev": true
- },
- "is-hexadecimal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
- "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
- "dev": true
- },
- "is-potential-custom-element-name": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
- "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
- "dev": true
- },
- "isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
- },
- "isomorphic-fetch": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
- "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
- "dev": true,
- "requires": {
- "node-fetch": "^2.6.1",
- "whatwg-fetch": "^3.4.1"
- }
- },
- "istanbul-lib-coverage": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
- "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
- "dev": true
- },
- "istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
- "dev": true,
- "requires": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^4.0.0",
- "supports-color": "^7.1.0"
- }
- },
- "istanbul-lib-source-maps": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
- "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
- "dev": true,
- "requires": {
- "debug": "^4.1.1",
- "istanbul-lib-coverage": "^3.0.0",
- "source-map": "^0.6.1"
- }
- },
- "istanbul-reports": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
- "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
- "dev": true,
- "requires": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
- }
- },
- "jsdom": {
- "version": "22.1.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz",
- "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==",
- "dev": true,
- "requires": {
- "abab": "^2.0.6",
- "cssstyle": "^3.0.0",
- "data-urls": "^4.0.0",
- "decimal.js": "^10.4.3",
- "domexception": "^4.0.0",
- "form-data": "^4.0.0",
- "html-encoding-sniffer": "^3.0.0",
- "http-proxy-agent": "^5.0.0",
- "https-proxy-agent": "^5.0.1",
- "is-potential-custom-element-name": "^1.0.1",
- "nwsapi": "^2.2.4",
- "parse5": "^7.1.2",
- "rrweb-cssom": "^0.6.0",
- "saxes": "^6.0.0",
- "symbol-tree": "^3.2.4",
- "tough-cookie": "^4.1.2",
- "w3c-xmlserializer": "^4.0.0",
- "webidl-conversions": "^7.0.0",
- "whatwg-encoding": "^2.0.0",
- "whatwg-mimetype": "^3.0.0",
- "whatwg-url": "^12.0.1",
- "ws": "^8.13.0",
- "xml-name-validator": "^4.0.0"
+ "engines": {
+ "node": ">=12.20"
},
- "dependencies": {
- "data-urls": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz",
- "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==",
- "dev": true,
- "requires": {
- "abab": "^2.0.6",
- "whatwg-mimetype": "^3.0.0",
- "whatwg-url": "^12.0.0"
- }
- },
- "ws": {
- "version": "8.13.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
- "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
- "dev": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
- },
- "jsonc-parser": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
- "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
- "dev": true
- },
- "katex": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.2.tgz",
- "integrity": "sha512-70DJdQAyh9EMsthw3AaQlDyFf54X7nWEUIa5W+rq8XOpEk//w5Th7/8SqFqpvi/KZ2t6MHUj4f9wLmztBmAYQA==",
- "requires": {
- "commander": "^8.0.0"
- },
- "dependencies": {
- "commander": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
- "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="
- }
- }
- },
- "leac": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
- "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg=="
- },
- "linkedom": {
- "version": "0.14.20",
- "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.14.20.tgz",
- "integrity": "sha512-H7BX22kn4Ul4Mfr5/Jz039TgfsYce/YCvQ6272LEIlIJ1sYmU3R6yFNSYZU6iDX2aoF76wX+qjcSZEaLwumcAw==",
- "requires": {
- "css-select": "^5.1.0",
- "cssom": "^0.5.0",
- "html-escaper": "^3.0.3",
- "htmlparser2": "^8.0.1",
- "uhyphen": "^0.1.0"
- },
- "dependencies": {
- "html-escaper": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz",
- "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="
- }
- }
- },
- "liqe": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/liqe/-/liqe-1.13.0.tgz",
- "integrity": "sha512-3ZnkfWXtnG7Bnzy5zfQ3VWYSf0Mdv8YXMgYOC3ooXyW6wNS6XElxJ9zVHT7xeTh8BL76U0T0vo8y4L41DuWSaw==",
- "requires": {
- "nearley": "^2.20.1",
- "ts-error": "^1.0.6"
- }
- },
- "local-pkg": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz",
- "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==",
- "dev": true
- },
- "loupe": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
- "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==",
- "dev": true,
- "requires": {
- "get-func-name": "^2.0.0"
- }
- },
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "magic-string": {
- "version": "0.30.2",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz",
- "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==",
- "dev": true,
- "requires": {
- "@jridgewell/sourcemap-codec": "^1.4.15"
- }
- },
- "make-dir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
- "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
- "dev": true,
- "requires": {
- "semver": "^7.5.3"
- }
- },
- "mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
- },
- "mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "dev": true,
- "requires": {
- "mime-db": "1.52.0"
- }
- },
- "minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "mlly": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.0.tgz",
- "integrity": "sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==",
- "dev": true,
- "requires": {
- "acorn": "^8.9.0",
- "pathe": "^1.1.1",
- "pkg-types": "^1.0.3",
- "ufo": "^1.1.2"
- }
- },
- "mockdate": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz",
- "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==",
- "dev": true
- },
- "moo": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
- "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- },
- "nanoid": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
- "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
- "dev": true
- },
- "nearley": {
- "version": "2.20.1",
- "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
- "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
- "requires": {
- "commander": "^2.19.0",
- "moo": "^0.5.0",
- "railroad-diagrams": "^1.0.0",
- "randexp": "0.4.6"
- },
- "dependencies": {
- "commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
- }
- }
- },
- "node-fetch": {
- "version": "2.6.7",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
- "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
- "requires": {
- "whatwg-url": "^5.0.0"
- },
- "dependencies": {
- "tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
- },
- "webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- },
- "whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "requires": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- }
- }
- },
- "nth-check": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
- "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
- "requires": {
- "boolbase": "^1.0.0"
- }
- },
- "nwsapi": {
- "version": "2.2.7",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz",
- "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==",
- "dev": true
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
- "requires": {
- "wrappy": "1"
- }
- },
- "otplib": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/otplib/-/otplib-12.0.1.tgz",
- "integrity": "sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg==",
- "dev": true,
- "requires": {
- "@otplib/core": "^12.0.1",
- "@otplib/preset-default": "^12.0.1",
- "@otplib/preset-v11": "^12.0.1"
- }
- },
- "parse-entities": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz",
- "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==",
- "dev": true,
- "requires": {
- "@types/unist": "^2.0.0",
- "character-entities": "^2.0.0",
- "character-entities-legacy": "^3.0.0",
- "character-reference-invalid": "^2.0.0",
- "decode-named-character-reference": "^1.0.0",
- "is-alphanumerical": "^2.0.0",
- "is-decimal": "^2.0.0",
- "is-hexadecimal": "^2.0.0"
- }
- },
- "parse5": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
- "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
- "dev": true,
- "requires": {
- "entities": "^4.4.0"
- }
- },
- "parseley": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.0.tgz",
- "integrity": "sha512-uLqDm6IQVb6m50a3dIxF66hI8VWr7wFDYUULtHa1ITRh9mwYIXzFpPTkPM66Cm5V0t+bMyeSHgUCGzoXTV96LQ==",
- "requires": {
- "leac": "^0.6.0",
- "peberminta": "^0.9.0"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true
- },
- "path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true
- },
- "pathe": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz",
- "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==",
- "dev": true
- },
- "pathval": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
- "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
- "dev": true
- },
- "peberminta": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz",
- "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ=="
- },
- "picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "dev": true
- },
- "pkg-types": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz",
- "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==",
- "dev": true,
- "requires": {
- "jsonc-parser": "^3.2.0",
- "mlly": "^1.2.0",
- "pathe": "^1.1.0"
- }
- },
- "postcss": {
- "version": "8.4.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz",
- "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==",
- "dev": true,
- "requires": {
- "nanoid": "^3.3.6",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- }
- },
- "prismjs": {
- "version": "1.29.0",
- "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
- "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="
- },
- "property-information": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz",
- "integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==",
- "dev": true
- },
- "psl": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
- "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
- },
- "punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
- },
- "qclone": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/qclone/-/qclone-1.2.0.tgz",
- "integrity": "sha512-ah9Mpb9/UBdY5vvOcpqFq8g489YIqLTJlSk+FddPyPbE1nISrYx3TBAKQB590cGoXTd5yWQbVstDVatHMOoxnA=="
- },
- "querystringify": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
- "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
- },
- "railroad-diagrams": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
- "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A=="
- },
- "randexp": {
- "version": "0.4.6",
- "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
- "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
- "requires": {
- "discontinuous-range": "1.0.0",
- "ret": "~0.1.10"
- }
- },
- "react-is": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
- "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
- "dev": true
- },
- "refractor": {
- "version": "4.8.1",
- "resolved": "https://registry.npmjs.org/refractor/-/refractor-4.8.1.tgz",
- "integrity": "sha512-/fk5sI0iTgFYlmVGYVew90AoYnNMP6pooClx/XKqyeeCQXrL0Kvgn8V0VEht5ccdljbzzF1i3Q213gcntkRExg==",
- "dev": true,
- "requires": {
- "@types/hast": "^2.0.0",
- "@types/prismjs": "^1.0.0",
- "hastscript": "^7.0.0",
- "parse-entities": "^4.0.0"
- }
- },
- "requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
- },
- "ret": {
- "version": "0.1.15",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
- },
- "rollup": {
- "version": "3.28.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.0.tgz",
- "integrity": "sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==",
- "dev": true,
- "requires": {
- "fsevents": "~2.3.2"
- }
- },
- "rrweb-cssom": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
- "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==",
- "dev": true
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true
- },
- "saxes": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
- "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
- "dev": true,
- "requires": {
- "xmlchars": "^2.2.0"
- }
- },
- "selderee": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz",
- "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==",
- "requires": {
- "parseley": "^0.12.0"
- }
- },
- "semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dev": true,
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "set-cookie-parser": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz",
- "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ=="
- },
- "shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "requires": {
- "shebang-regex": "^3.0.0"
- },
- "dependencies": {
- "shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true
- }
- }
- },
- "siginfo": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
- "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
- "dev": true
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- },
- "source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
- "dev": true
- },
- "space-separated-tokens": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
- "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
- "dev": true
- },
- "spark-md5": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
- "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
- },
- "stackback": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
- "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
- "dev": true
- },
- "std-env": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz",
- "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==",
- "dev": true
- },
- "strip-literal": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz",
- "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==",
- "dev": true,
- "requires": {
- "acorn": "^8.10.0"
- }
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "symbol-tree": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
- "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
- "dev": true
- },
- "test-exclude": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
- "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
- "dev": true,
- "requires": {
- "@istanbuljs/schema": "^0.1.2",
- "glob": "^7.1.4",
- "minimatch": "^3.0.4"
- }
- },
- "thirty-two": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz",
- "integrity": "sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==",
- "dev": true
- },
- "tinybench": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz",
- "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==",
- "dev": true
- },
- "tinypool": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz",
- "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==",
- "dev": true
- },
- "tinyspy": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz",
- "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==",
- "dev": true
- },
- "tough-cookie": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
- "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
- "requires": {
- "psl": "^1.1.33",
- "punycode": "^2.1.1",
- "universalify": "^0.2.0",
- "url-parse": "^1.5.3"
- }
- },
- "tr46": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
- "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
- "dev": true,
- "requires": {
- "punycode": "^2.3.0"
- }
- },
- "ts-error": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/ts-error/-/ts-error-1.0.6.tgz",
- "integrity": "sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA=="
- },
- "tslib": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
- "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
- },
- "type-detect": {
- "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==",
- "dev": true
- },
- "ufo": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.2.0.tgz",
- "integrity": "sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==",
- "dev": true
- },
- "uhyphen": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.1.0.tgz",
- "integrity": "sha512-o0QVGuFg24FK765Qdd5kk0zU/U4dEsCtN/GSiwNI9i8xsSVtjIAOdTaVhLwZ1nrbWxFVMxNDDl+9fednsOMsBw=="
- },
- "universalify": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
- "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="
- },
- "url-parse": {
- "version": "1.5.10",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
- "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
- "requires": {
- "querystringify": "^2.1.1",
- "requires-port": "^1.0.0"
- }
- },
- "v8-to-istanbul": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz",
- "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==",
- "dev": true,
- "requires": {
- "@jridgewell/trace-mapping": "^0.3.12",
- "@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^1.6.0"
- }
- },
- "vite": {
- "version": "4.4.9",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz",
- "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==",
- "dev": true,
- "requires": {
- "esbuild": "^0.18.10",
- "fsevents": "~2.3.2",
- "postcss": "^8.4.27",
- "rollup": "^3.27.1"
- }
- },
- "vite-node": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.1.tgz",
- "integrity": "sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==",
- "dev": true,
- "requires": {
- "cac": "^6.7.14",
- "debug": "^4.3.4",
- "mlly": "^1.4.0",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "vite": "^3.0.0 || ^4.0.0"
- }
- },
- "vitest": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.1.tgz",
- "integrity": "sha512-G1PzuBEq9A75XSU88yO5G4vPT20UovbC/2osB2KEuV/FisSIIsw7m5y2xMdB7RsAGHAfg2lPmp2qKr3KWliVlQ==",
- "dev": true,
- "requires": {
- "@types/chai": "^4.3.5",
- "@types/chai-subset": "^1.3.3",
- "@types/node": "*",
- "@vitest/expect": "0.34.1",
- "@vitest/runner": "0.34.1",
- "@vitest/snapshot": "0.34.1",
- "@vitest/spy": "0.34.1",
- "@vitest/utils": "0.34.1",
- "acorn": "^8.9.0",
- "acorn-walk": "^8.2.0",
- "cac": "^6.7.14",
- "chai": "^4.3.7",
- "debug": "^4.3.4",
- "local-pkg": "^0.4.3",
- "magic-string": "^0.30.1",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "std-env": "^3.3.3",
- "strip-literal": "^1.0.1",
- "tinybench": "^2.5.0",
- "tinypool": "^0.7.0",
- "vite": "^3.0.0 || ^4.0.0",
- "vite-node": "0.34.1",
- "why-is-node-running": "^2.2.2"
- }
- },
- "vitest-fetch-mock": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/vitest-fetch-mock/-/vitest-fetch-mock-0.2.2.tgz",
- "integrity": "sha512-XmH6QgTSjCWrqXoPREIdbj40T7i1xnGmAsTAgfckoO75W1IEHKR8hcPCQ7SO16RsdW1t85oUm6pcQRLeBgjVYQ==",
- "dev": true,
- "requires": {
- "cross-fetch": "^3.0.6"
- }
- },
- "w3c-xmlserializer": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
- "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
- "dev": true,
- "requires": {
- "xml-name-validator": "^4.0.0"
- }
- },
- "webidl-conversions": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
- "dev": true
- },
- "whatwg-encoding": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
- "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
- "dev": true,
- "requires": {
- "iconv-lite": "0.6.3"
- }
- },
- "whatwg-fetch": {
- "version": "3.6.17",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.17.tgz",
- "integrity": "sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ==",
- "dev": true
- },
- "whatwg-mimetype": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
- "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
- "dev": true
- },
- "whatwg-url": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz",
- "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==",
- "dev": true,
- "requires": {
- "tr46": "^4.1.1",
- "webidl-conversions": "^7.0.0"
- }
- },
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
- },
- "why-is-node-running": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz",
- "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==",
- "dev": true,
- "requires": {
- "siginfo": "^2.0.0",
- "stackback": "0.0.2"
- }
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
- },
- "ws": {
- "version": "7.5.9",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
- "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q=="
- },
- "xml-name-validator": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
- "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
- "dev": true
- },
- "xmlchars": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
- "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
- "dev": true
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
}
}
}
diff --git a/packages/core/package.json b/packages/core/package.json
index 7cc0dcae9..43a91e1ec 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -9,10 +9,13 @@
},
"devDependencies": {
"@notesnook/crypto": "file:../crypto",
+ "@types/event-source-polyfill": "^1.0.1",
"@types/html-to-text": "^9.0.0",
- "@types/katex": "^0.16.1",
+ "@types/katex": "^0.16.2",
"@types/prismjs": "^1.26.0",
+ "@types/spark-md5": "^3.0.2",
"@types/streetwriters__showdown": "npm:@types/showdown@^2.0.6",
+ "@types/ws": "^8.5.5",
"@vitest/coverage-v8": "^0.34.1",
"abortcontroller-polyfill": "^1.7.3",
"cross-env": "^7.0.3",
@@ -26,7 +29,8 @@
"otplib": "^12.0.1",
"refractor": "^4.8.1",
"vitest": "^0.34.1",
- "vitest-fetch-mock": "^0.2.2"
+ "vitest-fetch-mock": "^0.2.2",
+ "ws": "^8.13.0"
},
"scripts": {
"prebuild": "node scripts/prebuild.mjs",
@@ -54,6 +58,7 @@
"mime-db": "1.52.0",
"prismjs": "^1.29.0",
"qclone": "^1.2.0",
+ "rfdc": "^1.3.0",
"spark-md5": "^3.0.2"
},
"overrides": {
diff --git a/packages/core/src/api/__tests__/__snapshots__/debug.test.js.snap b/packages/core/src/api/__tests__/__snapshots__/debug.test.js.snap
deleted file mode 100644
index af4fd7e8c..000000000
--- a/packages/core/src/api/__tests__/__snapshots__/debug.test.js.snap
+++ /dev/null
@@ -1,13 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`strip note > stripped-note 1`] = `"{\\"title\\":true,\\"description\\":false,\\"headline\\":true,\\"colored\\":false,\\"type\\":\\"note\\",\\"tags\\":[],\\"id\\":\\"hello\\",\\"contentId\\":\\"hello2\\",\\"dateModified\\":123,\\"dateEdited\\":123,\\"dateCreated\\":123}"`;
-
-exports[`strip note with content > stripped-note-with-content 1`] = `"{\\"title\\":true,\\"description\\":false,\\"headline\\":true,\\"colored\\":false,\\"type\\":\\"note\\",\\"tags\\":[],\\"id\\":\\"hello\\",\\"contentId\\":\\"hello2\\",\\"dateModified\\":123,\\"dateEdited\\":123,\\"dateCreated\\":123,\\"additionalData\\":{\\"content\\":\\"{\\\\\\"title\\\\\\":false,\\\\\\"description\\\\\\":false,\\\\\\"headline\\\\\\":false,\\\\\\"colored\\\\\\":false,\\\\\\"type\\\\\\":\\\\\\"tiptap\\\\\\",\\\\\\"id\\\\\\":\\\\\\"hello\\\\\\",\\\\\\"dateModified\\\\\\":123,\\\\\\"dateEdited\\\\\\":123,\\\\\\"dateCreated\\\\\\":123}\\"}}"`;
-
-exports[`strip notebook > stripped-notebook 1`] = `"{\\"title\\":true,\\"description\\":true,\\"headline\\":false,\\"colored\\":false,\\"type\\":\\"notebook\\",\\"id\\":\\"hello\\",\\"dateModified\\":123,\\"dateEdited\\":123,\\"dateCreated\\":123,\\"additionalData\\":[{\\"type\\":\\"topic\\",\\"id\\":\\"hello\\",\\"notebookId\\":\\"hello23\\",\\"title\\":\\"hello\\",\\"dateCreated\\":123,\\"dateEdited\\":123,\\"dateModified\\":123}]}"`;
-
-exports[`strip tag > stripped-tag 1`] = `"{\\"title\\":true,\\"description\\":false,\\"headline\\":false,\\"colored\\":false,\\"type\\":\\"tag\\",\\"noteIds\\":[],\\"id\\":\\"hello\\",\\"dateModified\\":123,\\"dateEdited\\":123,\\"dateCreated\\":123}"`;
-
-exports[`strip topic > stripped-topic 1`] = `"{\\"title\\":true,\\"description\\":false,\\"headline\\":false,\\"colored\\":false,\\"type\\":\\"topic\\",\\"id\\":\\"hello\\",\\"dateModified\\":123,\\"dateEdited\\":123,\\"dateCreated\\":123}"`;
-
-exports[`strip trashed note > stripped-trashed-note 1`] = `"{\\"title\\":true,\\"description\\":false,\\"headline\\":true,\\"colored\\":false,\\"type\\":\\"trash\\",\\"tags\\":[],\\"id\\":\\"hello\\",\\"contentId\\":\\"hello2\\",\\"dateModified\\":123,\\"dateEdited\\":123,\\"dateDeleted\\":123,\\"dateCreated\\":123}"`;
diff --git a/packages/core/src/api/__tests__/debug.test.js b/packages/core/src/api/__tests__/debug.test.js
index b6ae49f90..1122ddfef 100644
--- a/packages/core/src/api/__tests__/debug.test.js
+++ b/packages/core/src/api/__tests__/debug.test.js
@@ -17,82 +17,11 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import Debug from "../debug";
-import { noteTest, notebookTest, databaseTest } from "../../../__tests__/utils";
+import { Debug } from "../debug";
import createFetchMock from "vitest-fetch-mock";
import { vi, test, expect } from "vitest";
const fetchMocker = createFetchMock(vi);
-test("strip empty item shouldn't throw", () => {
- const debug = new Debug();
- expect(debug.strip()).toBe("{}");
-});
-
-test("strip note", () =>
- noteTest().then(({ db, id }) => {
- const note = db.notes.note(id)._note;
- const debug = new Debug();
- expect(debug.strip(normalizeItem(note))).toMatchSnapshot("stripped-note");
- }));
-
-test("strip trashed note", () =>
- noteTest().then(async ({ db, id }) => {
- await db.notes.delete(id);
- const note = db.trash.all[0];
- const debug = new Debug();
- expect(debug.strip(normalizeItem(note))).toMatchSnapshot(
- "stripped-trashed-note"
- );
- }));
-
-test("strip note with content", () =>
- noteTest().then(async ({ db, id }) => {
- const note = db.notes.note(id)._note;
- const debug = new Debug();
-
- const content = await db.content.raw(note.contentId);
- note.additionalData = {
- content: db.debug.strip(normalizeItem(content))
- };
-
- expect(debug.strip(normalizeItem(note))).toMatchSnapshot(
- "stripped-note-with-content"
- );
- }));
-
-test("strip notebook", () =>
- notebookTest().then(async ({ db, id }) => {
- const notebook = db.notebooks.notebook(id)._notebook;
- const debug = new Debug();
- notebook.additionalData = notebook.topics.map((topic) =>
- normalizeItem(topic)
- );
- expect(debug.strip(normalizeItem(notebook))).toMatchSnapshot(
- "stripped-notebook"
- );
- }));
-
-test("strip topic", () =>
- notebookTest().then(async ({ db, id }) => {
- const notebook = db.notebooks.notebook(id)._notebook;
- const debug = new Debug();
- expect(debug.strip(normalizeItem(notebook.topics[0]))).toMatchSnapshot(
- "stripped-topic"
- );
- }));
-
-test("strip tag", () =>
- databaseTest().then(async (db) => {
- const tag = await db.tags.add("Hello tag");
- const debug = new Debug();
- expect(debug.strip(normalizeItem(tag))).toMatchSnapshot("stripped-tag");
- }));
-
-test("reporting empty issue should return undefined", async () => {
- const debug = new Debug();
- expect(await debug.report()).toBeUndefined();
-});
-
const SUCCESS_REPORT_RESPONSE = {
url: "https://reported/"
};
@@ -100,14 +29,12 @@ const SUCCESS_REPORT_RESPONSE = {
test("reporting issue should return issue url", async () => {
fetchMocker.enableMocks();
- const debug = new Debug();
-
fetch.mockResponseOnce(JSON.stringify(SUCCESS_REPORT_RESPONSE), {
headers: { "Content-Type": "application/json" }
});
expect(
- await debug.report({
+ await Debug.report({
title: "I am title",
body: "I am body",
userId: "anything"
@@ -120,8 +47,6 @@ test("reporting issue should return issue url", async () => {
test("reporting invalid issue should return undefined", async () => {
fetchMocker.enableMocks();
- const debug = new Debug();
-
fetch.mockResponseOnce(
JSON.stringify({
error_description: "Invalid issue."
@@ -129,18 +54,7 @@ test("reporting invalid issue should return undefined", async () => {
{ status: 400, headers: { "Content-Type": "application/json" } }
);
- expect(await debug.report({})).toBeUndefined();
+ expect(await Debug.report({})).toBeUndefined();
fetchMocker.disableMocks();
});
-
-function normalizeItem(item) {
- item.id = "hello";
- item.notebookId = "hello23";
- item.dateModified = 123;
- item.dateEdited = 123;
- item.dateCreated = 123;
- if (item.dateDeleted) item.dateDeleted = 123;
- if (item.contentId) item.contentId = "hello2";
- return item;
-}
diff --git a/packages/core/src/api/debug.js b/packages/core/src/api/debug.js
deleted file mode 100644
index a94e10bad..000000000
--- a/packages/core/src/api/debug.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-This file is part of the Notesnook project (https://notesnook.com/)
-
-Copyright (C) 2023 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-import hosts from "../utils/constants";
-
-export default class Debug {
- strip(item) {
- if (!item) return "{}";
- return JSON.stringify({
- title: !!item.title,
- description: !!item.description,
- headline: !!item.headline,
- colored: !!item.color,
- type: item.type,
- notebooks: item.notebooks,
- notes: item.notes,
- noteIds: item.noteIds,
- tags: item.tags,
- id: item.id,
- contentId: item.contentId,
- dateModified: item.dateModified,
- dateEdited: item.dateEdited,
- dateDeleted: item.dateDeleted,
- dateCreated: item.dateCreated,
- additionalData: item.additionalData
- });
- }
-
- /**
- *
- * @param {{
- * title: string,
- * body: string,
- * userId: string | undefined
- * }} reportData
- * @returns {Promise} link to the github issue
- */
- async report(reportData) {
- if (!reportData) return;
-
- const { title, body, userId } = reportData;
- const response = await fetch(`${hosts.ISSUES_HOST}/create/notesnook`, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ title, body, userId })
- });
- if (!response.ok) return;
- const json = await response.json();
- return json.url;
- }
-}
diff --git a/packages/core/src/api/debug.ts b/packages/core/src/api/debug.ts
new file mode 100644
index 000000000..4c41e43b4
--- /dev/null
+++ b/packages/core/src/api/debug.ts
@@ -0,0 +1,38 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+import hosts from "../utils/constants";
+
+export class Debug {
+ static async report(reportData: {
+ title: string;
+ body: string;
+ userId?: string;
+ }): Promise {
+ const { title, body, userId } = reportData;
+ const response = await fetch(`${hosts.ISSUES_HOST}/create/notesnook`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ title, body, userId })
+ });
+ if (!response.ok) return;
+ const json = await response.json();
+ return json.url;
+ }
+}
diff --git a/packages/core/src/api/healthcheck.js b/packages/core/src/api/healthcheck.ts
similarity index 77%
rename from packages/core/src/api/healthcheck.js
rename to packages/core/src/api/healthcheck.ts
index 5152e0eaa..e0298a1e9 100644
--- a/packages/core/src/api/healthcheck.js
+++ b/packages/core/src/api/healthcheck.ts
@@ -16,16 +16,21 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+
import hosts from "../utils/constants";
import http from "../utils/http";
export class HealthCheck {
- static async isAuthServerHealthy() {
- try {
- const response = await http.get(`${hosts.AUTH_HOST}/health`);
- return response.trim() === "Healthy";
- } catch {
- return false;
- }
+ static async auth() {
+ return check(hosts.AUTH_HOST);
+ }
+}
+
+async function check(host: string) {
+ try {
+ const response = await http.get(`${host}/health`);
+ return response.trim() === "Healthy";
+ } catch {
+ return false;
}
}
diff --git a/packages/core/src/api/index.js b/packages/core/src/api/index.js
deleted file mode 100644
index b3111b14c..000000000
--- a/packages/core/src/api/index.js
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
-This file is part of the Notesnook project (https://notesnook.com/)
-
-Copyright (C) 2023 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-import Notes from "../collections/notes";
-import Storage from "../database/storage";
-import FileStorage from "../database/fs";
-import Notebooks from "../collections/notebooks";
-import Trash from "../collections/trash";
-import Tags from "../collections/tags";
-import Sync from "./sync";
-import Vault from "./vault";
-import Lookup from "./lookup";
-import Content from "../collections/content";
-import Backup from "../database/backup";
-import Session from "./session";
-import Constants from "../utils/constants";
-import { EV, EVENTS } from "../common";
-import Settings from "./settings";
-import Migrations from "./migrations";
-import UserManager from "./user-manager";
-import http from "../utils/http";
-import Monographs from "./monographs";
-import Offers from "./offers";
-import Attachments from "../collections/attachments";
-import Debug from "./debug";
-import { Mutex } from "async-mutex";
-import NoteHistory from "../collections/note-history";
-import MFAManager from "./mfa-manager";
-import EventManager from "../utils/event-manager";
-import Pricing from "./pricing";
-import { logger } from "../logger";
-import Shortcuts from "../collections/shortcuts";
-import Reminders from "../collections/reminders";
-import Relations from "../collections/relations";
-import Subscriptions from "./subscriptions";
-
-/**
- * @type {EventSource}
- */
-var NNEventSource;
-// const DIFFERENCE_THRESHOLD = 20 * 1000;
-// const MAX_TIME_ERROR_FAILURES = 5;
-class Database {
- isInitialized = false;
- /**
- *
- * @param {any} storage
- * @param {EventSource} eventsource
- */
- constructor() {
- /**
- * @type {EventSource}
- */
- this.evtSource = null;
- this.sseMutex = new Mutex();
- this.lastHeartbeat = undefined; // { local: 0, server: 0 };
- this.timeErrorFailures = 0;
- this.eventManager = new EventManager();
- }
-
- setup(storage, eventsource, fs, compressor) {
- this.compressor = compressor;
- this.storage = storage ? new Storage(storage) : null;
- this.fs = fs && storage ? new FileStorage(fs, storage) : null;
- NNEventSource = eventsource;
-
- this.session = new Session(this.storage);
- this.user = new UserManager(this.storage, this);
- this.mfa = new MFAManager(this.storage, this);
- this.syncer = new Sync(this);
- this.vault = new Vault(this);
- this.lookup = new Lookup(this);
- this.backup = new Backup(this);
- this.settings = new Settings(this);
- this.migrations = new Migrations(this);
- this.monographs = new Monographs(this);
- this.offers = new Offers();
- this.debug = new Debug();
- this.pricing = new Pricing();
- this.subscriptions = new Subscriptions(this.user.tokenManager);
- this.trash = new Trash(this);
- }
-
- async _validate() {
- if (!(await this.session.valid())) {
- throw new Error(
- "Your system clock is not setup correctly. Please adjust your date and time and then retry."
- );
- }
- await this.session.set();
- }
-
- async init() {
- EV.subscribeMulti(
- [EVENTS.userLoggedIn, EVENTS.userFetched, EVENTS.tokenRefreshed],
- this.connectSSE,
- this
- );
- EV.subscribe(EVENTS.attachmentDeleted, async (attachment) => {
- await this.fs.cancel(attachment.metadata?.hash);
- });
- EV.subscribe(EVENTS.userLoggedOut, async () => {
- await this.monographs.deinit();
- await this.fs.clear();
- this.disconnectSSE();
- });
-
- await this._validate();
-
- await this.initCollections();
-
- await this.migrations.init();
- this.isInitialized = true;
- if (this.migrations.required()) {
- logger.warn("Database migration is required.");
- }
- }
-
- async initCollections() {
- await this.settings.init();
- // collections
- /** @type {Notebooks} */
- this.notebooks = await Notebooks.new(this, "notebooks");
- /** @type {Tags} */
- this.tags = await Tags.new(this, "tags");
- /** @type {Tags} */
- this.colors = await Tags.new(this, "colors");
- /** @type {Content} */
- this.content = await Content.new(this, "content", false);
- /** @type {Attachments} */
- this.attachments = await Attachments.new(this, "attachments");
- /**@type {NoteHistory} */
- this.noteHistory = await NoteHistory.new(this, "notehistory", false);
- /**@type {Shortcuts} */
- this.shortcuts = await Shortcuts.new(this, "shortcuts");
- /**@type {Reminders} */
- this.reminders = await Reminders.new(this, "reminders");
- /**@type {Relations} */
- this.relations = await Relations.new(this, "relations");
- /** @type {Notes} */
- this.notes = await Notes.new(this, "notes");
-
- await this.trash.init();
-
- this.monographs.init().catch(console.error);
- }
-
- disconnectSSE() {
- if (!this.evtSource) return;
- this.evtSource.onopen = null;
- this.evtSource.onmessage = null;
- this.evtSource.onerror = null;
- this.evtSource.close();
- this.evtSource = null;
- }
-
- /**
- *
- * @param {{force: boolean, error: any}} args
- */
- async connectSSE(args) {
- if (args && !!args.error) return;
- await this.sseMutex.runExclusive(async () => {
- this.eventManager.publish(EVENTS.databaseSyncRequested, true, false);
-
- const forceReconnect = args && args.force;
- if (
- !NNEventSource ||
- (!forceReconnect &&
- this.evtSource &&
- this.evtSource.readyState === this.evtSource.OPEN)
- )
- return;
- this.disconnectSSE();
-
- const token = await this.user.tokenManager.getAccessToken();
- if (!token) return;
-
- this.evtSource = new NNEventSource(`${Constants.SSE_HOST}/sse`, {
- headers: { Authorization: `Bearer ${token}` }
- });
-
- this.evtSource.onopen = async () => {
- console.log("SSE: opened channel successfully!");
- };
-
- this.evtSource.onerror = function (error) {
- console.log("SSE: error:", error);
- };
-
- this.evtSource.onmessage = async (event) => {
- try {
- var { type, data } = JSON.parse(event.data);
- data = JSON.parse(data);
- } catch (e) {
- console.log("SSE: Unsupported message. Message = ", event.data);
- return;
- }
-
- switch (type) {
- // TODO: increase reliablity for this.
- // case "heartbeat": {
- // const { t: serverTime } = data;
- // const localTime = Date.now();
-
- // if (!this.lastHeartbeat) {
- // this.lastHeartbeat = { local: localTime, server: serverTime };
- // break;
- // }
-
- // const timeElapsed = {
- // local: localTime - this.lastHeartbeat.local,
- // server: serverTime - this.lastHeartbeat.server,
- // };
- // const travelTime = timeElapsed.local - timeElapsed.server;
- // const actualTime = localTime - travelTime;
-
- // const diff = actualTime - serverTime;
-
- // // Fail several times consecutively before raising an error. This is done to root out
- // // false positives.
- // if (Math.abs(diff) > DIFFERENCE_THRESHOLD) {
- // if (this.timeErrorFailures >= MAX_TIME_ERROR_FAILURES) {
- // EV.publish(EVENTS.systemTimeInvalid, { serverTime, localTime });
- // } else this.timeErrorFailures++;
- // } else this.timeErrorFailures = 0;
-
- // this.lastHeartbeat.local = localTime;
- // this.lastHeartbeat.server = serverTime;
- // break;
- // }
- case "upgrade": {
- const user = await this.user.getUser();
- user.subscription = data;
- await this.user.setUser(user);
- EV.publish(EVENTS.userSubscriptionUpdated, data);
- break;
- }
- case "logout": {
- await this.user.logout(true, data.reason || "Unknown.");
- break;
- }
- case "emailConfirmed": {
- const token = await this.storage.read("token");
- await this.user.tokenManager._refreshToken(token);
- await this.user.fetchUser(true);
- EV.publish(EVENTS.userEmailConfirmed);
- break;
- }
- }
- };
- });
- }
-
- async lastSynced() {
- return (await this.storage.read("lastSynced")) || 0;
- }
-
- /**
- *
- * @param {{
- * type: "full" | "fetch" | "send";
- * force?: boolean;
- * serverLastSynced?: number;
- * }} options
- * @returns
- */
- sync(options) {
- return this.syncer.start(options);
- }
-
- /**
- *
- * @param {{AUTH_HOST: string, API_HOST: string, SSE_HOST: string, SUBSCRIPTIONS_HOST: string, ISSUES_HOST: string}} hosts
- */
- host(hosts) {
- if (process.env.NODE_ENV !== "production") {
- Constants.AUTH_HOST = hosts.AUTH_HOST || Constants.AUTH_HOST;
- Constants.API_HOST = hosts.API_HOST || Constants.API_HOST;
- Constants.SSE_HOST = hosts.SSE_HOST || Constants.SSE_HOST;
- Constants.SUBSCRIPTIONS_HOST =
- hosts.SUBSCRIPTIONS_HOST || Constants.SUBSCRIPTIONS_HOST;
- Constants.ISSUES_HOST = hosts.ISSUES_HOST || Constants.ISSUES_HOST;
- }
- }
-
- version() {
- return http.get(`${Constants.API_HOST}/version`);
- }
-
- async announcements() {
- let url = `${Constants.API_HOST}/announcements/active`;
- const user = await this.user.getUser();
- if (user) url += `?userId=${user.id}`;
- return http.get(url);
- }
-}
-
-export default Database;
diff --git a/packages/core/src/api/index.ts b/packages/core/src/api/index.ts
new file mode 100644
index 000000000..6fae0147c
--- /dev/null
+++ b/packages/core/src/api/index.ts
@@ -0,0 +1,316 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+import { Notes } from "../collections/notes";
+import { Crypto, CryptoAccessor } from "../database/crypto";
+import { FileStorage, FileStorageAccessor } from "../database/fs";
+import { Notebooks } from "../collections/notebooks";
+import Trash from "../collections/trash";
+import { Tags } from "../collections/tags";
+import { Colors } from "../collections/colors";
+import Sync, { SyncOptions } from "./sync";
+import Vault from "./vault";
+import Lookup from "./lookup";
+import { Content } from "../collections/content";
+import Backup from "../database/backup";
+import Session from "./session";
+import Hosts from "../utils/constants";
+import { EV, EVENTS } from "../common";
+import Settings from "../collections/settings";
+import Migrations from "./migrations";
+import UserManager from "./user-manager";
+import http from "../utils/http";
+import Monographs from "./monographs";
+import { Offers } from "./offers";
+import { Attachments } from "../collections/attachments";
+import { Debug } from "./debug";
+import { Mutex } from "async-mutex";
+import { NoteHistory } from "../collections/note-history";
+import MFAManager from "./mfa-manager";
+import EventManager from "../utils/event-manager";
+import { Pricing } from "./pricing";
+import { logger } from "../logger";
+import { Shortcuts } from "../collections/shortcuts";
+import { Reminders } from "../collections/reminders";
+import { Relations } from "../collections/relations";
+import Subscriptions from "./subscriptions";
+import {
+ CompressorAccessor,
+ ICompressor,
+ IFileStorage,
+ IStorage,
+ StorageAccessor
+} from "../interfaces";
+import TokenManager from "./token-manager";
+import { Attachment } from "../types";
+
+type EventSourceConstructor = new (
+ uri: string,
+ init: EventSourceInit & { headers?: Record }
+) => EventSource;
+type Options = {
+ storage: IStorage;
+ eventsource?: EventSourceConstructor;
+ fs: IFileStorage;
+ compressor: ICompressor;
+};
+
+// const DIFFERENCE_THRESHOLD = 20 * 1000;
+// const MAX_TIME_ERROR_FAILURES = 5;
+class Database {
+ isInitialized = false;
+ eventManager = new EventManager();
+ sseMutex = new Mutex();
+
+ storage: StorageAccessor = () => {
+ if (!this.options?.storage)
+ throw new Error(
+ "Database not initialized. Did you forget to call db.setup()?"
+ );
+ return this.options.storage;
+ };
+
+ fs: FileStorageAccessor = () => {
+ if (!this.options?.fs)
+ throw new Error(
+ "Database not initialized. Did you forget to call db.setup()?"
+ );
+ return new FileStorage(this.options.fs, this.storage);
+ };
+
+ crypto: CryptoAccessor = () => {
+ if (!this.options)
+ throw new Error(
+ "Database not initialized. Did you forget to call db.setup()?"
+ );
+ return new Crypto(this.storage);
+ };
+
+ compressor: CompressorAccessor = () => {
+ if (!this.options?.compressor)
+ throw new Error(
+ "Database not initialized. Did you forget to call db.setup()?"
+ );
+ return this.options.compressor;
+ };
+
+ private options?: Options;
+ EventSource?: EventSourceConstructor;
+ eventSource?: EventSource | null;
+
+ session = new Session(this.storage);
+ mfa = new MFAManager(this.storage);
+ tokenManager = new TokenManager(this.storage);
+ subscriptions = new Subscriptions(this.tokenManager);
+ offers = new Offers();
+ debug = new Debug();
+ pricing = new Pricing();
+
+ user = new UserManager(this);
+ syncer = new Sync(this);
+ vault = new Vault(this);
+ lookup = new Lookup(this);
+ backup = new Backup(this);
+ settings = new Settings(this);
+ migrations = new Migrations(this);
+ monographs = new Monographs(this);
+ trash = new Trash(this);
+
+ notebooks = new Notebooks(this);
+ tags = new Tags(this);
+ colors = new Colors(this);
+ content = new Content(this);
+ attachments = new Attachments(this);
+ noteHistory = new NoteHistory(this);
+ shortcuts = new Shortcuts(this);
+ reminders = new Reminders(this);
+ relations = new Relations(this);
+ notes = new Notes(this);
+ // constructor() {
+ // this.sseMutex = new Mutex();
+ // // this.lastHeartbeat = undefined; // { local: 0, server: 0 };
+ // // this.timeErrorFailures = 0;
+ // }
+
+ setup(options: Options) {
+ this.options = options;
+ }
+
+ async _validate() {
+ if (!(await this.session.valid())) {
+ throw new Error(
+ "Your system clock is not setup correctly. Please adjust your date and time and then retry."
+ );
+ }
+ await this.session.set();
+ }
+
+ async init() {
+ EV.subscribeMulti(
+ [EVENTS.userLoggedIn, EVENTS.userFetched, EVENTS.tokenRefreshed],
+ this.connectSSE,
+ this
+ );
+ EV.subscribe(EVENTS.attachmentDeleted, async (attachment: Attachment) => {
+ await this.fs().cancel(attachment.metadata.hash, "upload");
+ await this.fs().cancel(attachment.metadata.hash, "download");
+ });
+ EV.subscribe(EVENTS.userLoggedOut, async () => {
+ await this.monographs.deinit();
+ await this.fs().clear();
+ this.disconnectSSE();
+ });
+
+ await this._validate();
+
+ await this.initCollections();
+
+ await this.migrations.init();
+ this.isInitialized = true;
+ if (this.migrations.required()) {
+ logger.warn("Database migration is required.");
+ }
+ }
+
+ async initCollections() {
+ await this.settings.init();
+ // collections
+
+ await this.notebooks.init();
+ await this.tags.init();
+ await this.colors.init();
+ await this.content.init();
+ await this.attachments.init();
+ await this.noteHistory.init();
+ await this.shortcuts.init();
+ await this.reminders.init();
+ await this.relations.init();
+ await this.notes.init();
+
+ await this.trash.init();
+
+ this.monographs.init().catch(console.error);
+ }
+
+ disconnectSSE() {
+ if (!this.eventSource) return;
+ this.eventSource.onopen = null;
+ this.eventSource.onmessage = null;
+ this.eventSource.onerror = null;
+ this.eventSource.close();
+ this.eventSource = null;
+ }
+
+ /**
+ *
+ * @param {{force: boolean, error: any}} args
+ */
+ async connectSSE(args?: { force: boolean }) {
+ await this.sseMutex.runExclusive(async () => {
+ this.eventManager.publish(EVENTS.databaseSyncRequested, true, false);
+
+ const forceReconnect = args && args.force;
+ if (
+ !this.EventSource ||
+ (!forceReconnect &&
+ this.eventSource &&
+ this.eventSource.readyState === this.eventSource.OPEN)
+ )
+ return;
+ this.disconnectSSE();
+
+ const token = await this.tokenManager.getAccessToken();
+ if (!token) return;
+
+ this.eventSource = new this.EventSource(`${Hosts.SSE_HOST}/sse`, {
+ headers: { Authorization: `Bearer ${token}` }
+ });
+
+ this.eventSource.onopen = async () => {
+ console.log("SSE: opened channel successfully!");
+ };
+
+ this.eventSource.onerror = function (error) {
+ console.log("SSE: error:", error);
+ };
+
+ this.eventSource.onmessage = async (event) => {
+ try {
+ const message = JSON.parse(event.data);
+ const data = JSON.parse(message.data);
+ switch (message.type) {
+ case "upgrade": {
+ const user = await this.user.getUser();
+ if (!user) break;
+ user.subscription = data;
+ await this.user.setUser(user);
+ EV.publish(EVENTS.userSubscriptionUpdated, data);
+ break;
+ }
+ case "logout": {
+ await this.user.logout(true, data.reason || "Unknown.");
+ break;
+ }
+ case "emailConfirmed": {
+ await this.tokenManager._refreshToken(true);
+ await this.user.fetchUser();
+ EV.publish(EVENTS.userEmailConfirmed);
+ break;
+ }
+ }
+ } catch (e) {
+ console.log("SSE: Unsupported message. Message = ", event.data);
+ return;
+ }
+ };
+ });
+ }
+
+ async lastSynced() {
+ return (await this.storage().read("lastSynced")) || 0;
+ }
+
+ sync(options: SyncOptions) {
+ return this.syncer.start(options);
+ }
+
+ host(hosts: typeof Hosts) {
+ if (process.env.NODE_ENV !== "production") {
+ Hosts.AUTH_HOST = hosts.AUTH_HOST || Hosts.AUTH_HOST;
+ Hosts.API_HOST = hosts.API_HOST || Hosts.API_HOST;
+ Hosts.SSE_HOST = hosts.SSE_HOST || Hosts.SSE_HOST;
+ Hosts.SUBSCRIPTIONS_HOST =
+ hosts.SUBSCRIPTIONS_HOST || Hosts.SUBSCRIPTIONS_HOST;
+ Hosts.ISSUES_HOST = hosts.ISSUES_HOST || Hosts.ISSUES_HOST;
+ }
+ }
+
+ version() {
+ return http.get(`${Hosts.API_HOST}/version`);
+ }
+
+ async announcements() {
+ let url = `${Hosts.API_HOST}/announcements/active`;
+ const user = await this.user.getUser();
+ if (user) url += `?userId=${user.id}`;
+ return http.get(url);
+ }
+}
+
+export default Database;
diff --git a/packages/core/src/api/lookup.js b/packages/core/src/api/lookup.ts
similarity index 52%
rename from packages/core/src/api/lookup.js
rename to packages/core/src/api/lookup.ts
index 16ff4b0b4..28945d76b 100644
--- a/packages/core/src/api/lookup.js
+++ b/packages/core/src/api/lookup.ts
@@ -18,30 +18,42 @@ along with this program. If not, see .
*/
import { filter, parse } from "liqe";
+import Database from ".";
+import {
+ Attachment,
+ Note,
+ Notebook,
+ Reminder,
+ Tag,
+ Topic,
+ TrashItem,
+ isDeleted
+} from "../types";
+import { isUnencryptedContent } from "../collections/content";
export default class Lookup {
- /**
- *
- * @param {import('./index').default} db
- */
- constructor(db) {
- this._db = db;
- }
+ constructor(private readonly db: Database) {}
- async notes(notes, query) {
- const contents = await this._db.content.multi(
+ async notes(notes: Note[], query: string) {
+ const contents = await this.db.content.multi(
notes.map((note) => note.contentId || "")
);
return search(notes, query, (note) => {
let text = note.title;
- if (!note.locked && !!note.contentId && !!contents[note.contentId])
- text += contents[note.contentId]["data"];
+ const noteContent = note.contentId ? contents[note.contentId] : "";
+ if (
+ !note.locked &&
+ noteContent &&
+ !isDeleted(noteContent) &&
+ isUnencryptedContent(noteContent)
+ )
+ text += noteContent.data;
return text;
});
}
- notebooks(array, query) {
+ notebooks(array: Notebook[], query: string) {
return search(
array,
query,
@@ -50,36 +62,36 @@ export default class Lookup {
);
}
- topics(array, query) {
- return this._byTitle(array, query);
+ topics(array: Topic[], query: string) {
+ return this.byTitle(array, query);
}
- tags(array, query) {
- return this._byTitle(array, query);
+ tags(array: Tag[], query: string) {
+ return this.byTitle(array, query);
}
- reminders(array, query) {
+ reminders(array: Reminder[], query: string) {
return search(array, query, (n) => `${n.title} ${n.description || ""}`);
}
- trash(array, query) {
- return this._byTitle(array, query);
+ trash(array: TrashItem[], query: string) {
+ return this.byTitle(array, query);
}
- attachments(array, query) {
- return search(array, query, (n) =>
- n.metadata
- ? `${n.metadata.filename} ${n.metadata.type} ${n.metadata.hash}`
- : ""
+ attachments(array: Attachment[], query: string) {
+ return search(
+ array,
+ query,
+ (n) => `${n.metadata.filename} ${n.metadata.type} ${n.metadata.hash}`
);
}
- _byTitle(array, query) {
- return search(array, query, (n) => n.alias || n.title);
+ private byTitle(array: T[], query: string) {
+ return search(array, query, (n) => n.title);
}
}
-function search(items, query, selector) {
+function search(items: T[], query: string, selector: (item: T) => string) {
try {
return filter(
parse(`text:"${query.toLowerCase()}"`),
diff --git a/packages/core/src/api/mfa-manager.js b/packages/core/src/api/mfa-manager.ts
similarity index 72%
rename from packages/core/src/api/mfa-manager.js
rename to packages/core/src/api/mfa-manager.ts
index b82ac9220..f9c2890d9 100644
--- a/packages/core/src/api/mfa-manager.js
+++ b/packages/core/src/api/mfa-manager.ts
@@ -20,6 +20,7 @@ along with this program. If not, see .
import http from "../utils/http";
import constants from "../utils/constants";
import TokenManager from "./token-manager";
+import { StorageAccessor } from "../interfaces";
const ENDPOINTS = {
setup: "/mfa",
@@ -30,24 +31,12 @@ const ENDPOINTS = {
};
class MFAManager {
- /**
- *
- * @param {import("../database/storage").default} storage
- * @param {import("../api/index").default} db
- */
- constructor(storage, db) {
- this._storage = storage;
- this._db = db;
+ tokenManager: TokenManager;
+ constructor(private readonly storage: StorageAccessor) {
this.tokenManager = new TokenManager(storage);
}
- /**
- *
- * @param {"app" | "sms" | "email"} type
- * @param {string} phoneNumber
- * @returns
- */
- async setup(type, phoneNumber = undefined) {
+ async setup(type: "app" | "sms" | "email", phoneNumber?: string) {
const token = await this.tokenManager.getAccessToken();
if (!token) return;
return await http.post(
@@ -60,13 +49,7 @@ class MFAManager {
);
}
- /**
- *
- * @param {"app" | "sms" | "email"} type
- * @param {string} code
- * @returns
- */
- async enable(type, code) {
+ async enable(type: "app" | "sms" | "email", code: string) {
return this._enable(type, code, false);
}
@@ -76,19 +59,15 @@ class MFAManager {
* @param {string} code
* @returns
*/
- async enableFallback(type, code) {
+ async enableFallback(type: "app" | "sms" | "email", code: string) {
return this._enable(type, code, true);
}
- /**
- *
- * @param {"app" | "sms" | "email"} type
- * @param {string} code
- * @param {boolean} isFallback
- * @private
- * @returns
- */
- async _enable(type, code, isFallback) {
+ async _enable(
+ type: "app" | "sms" | "email",
+ code: string,
+ isFallback: boolean
+ ) {
const token = await this.tokenManager.getAccessToken();
if (!token) return;
return await http.patch(
@@ -107,11 +86,6 @@ class MFAManager {
);
}
- /**
- * Generate new 2FA recovery codes or get count of valid recovery codes.
- * @param {boolean} generate
- * @returns
- */
async codes() {
const token = await this.tokenManager.getAccessToken();
if (!token) return;
@@ -121,11 +95,7 @@ class MFAManager {
);
}
- /**
- * @param {"sms" | "email"} method
- * @returns
- */
- async sendCode(method) {
+ async sendCode(method: "sms" | "email") {
const token = await this.tokenManager.getAccessToken();
if (!token) throw new Error("Unauthorized.");
diff --git a/packages/core/src/api/migrations.js b/packages/core/src/api/migrations.js
deleted file mode 100644
index f8e274894..000000000
--- a/packages/core/src/api/migrations.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-This file is part of the Notesnook project (https://notesnook.com/)
-
-Copyright (C) 2023 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-import { CURRENT_DATABASE_VERSION } from "../common";
-import Migrator from "../database/migrator";
-
-class Migrations {
- /**
- *
- * @param {import("./index").default} db
- */
- constructor(db) {
- this._db = db;
- this._migrator = new Migrator();
- this._isMigrating = false;
- }
-
- async init() {
- this.dbVersion =
- (await this._db.storage.read("v")) || CURRENT_DATABASE_VERSION;
- this._db.storage.write("v", this.dbVersion);
- }
-
- required() {
- return this.dbVersion < CURRENT_DATABASE_VERSION;
- }
-
- async migrate() {
- try {
- if (!this.required() || this._isMigrating) return;
- this._isMigrating = true;
-
- await this._db.notes.init();
-
- const collections = [
- {
- index: () => this._db.attachments.all,
- dbCollection: this._db.attachments
- },
- {
- index: () => this._db.notebooks.raw,
- dbCollection: this._db.notebooks
- },
- {
- index: () => this._db.tags.raw,
- dbCollection: this._db.tags
- },
- {
- index: () => this._db.colors.raw,
- dbCollection: this._db.colors
- },
- {
- iterate: true,
- dbCollection: this._db.content
- },
- {
- index: () => [this._db.settings.raw],
- dbCollection: this._db.settings,
- type: "settings"
- },
- {
- index: () => this._db.shortcuts.raw,
- dbCollection: this._db.shortcuts
- },
- {
- index: () => this._db.reminders.raw,
- dbCollection: this._db.reminders
- },
- {
- index: () => this._db.relations.raw,
- dbCollection: this._db.relations
- },
- {
- iterate: true,
- dbCollection: this._db.noteHistory
- },
- {
- iterate: true,
- dbCollection: this._db.noteHistory.sessionContent
- },
- {
- index: () => this._db.notes.raw,
- dbCollection: this._db.notes
- }
- ];
-
- await this._migrator.migrate(
- this._db,
- collections,
- (item) => item,
- this.dbVersion
- );
- await this._db.storage.write("v", CURRENT_DATABASE_VERSION);
- this.dbVersion = CURRENT_DATABASE_VERSION;
- } finally {
- this._isMigrating = false;
- }
- }
-}
-export default Migrations;
diff --git a/packages/core/src/api/migrations.ts b/packages/core/src/api/migrations.ts
new file mode 100644
index 000000000..bebbf104f
--- /dev/null
+++ b/packages/core/src/api/migrations.ts
@@ -0,0 +1,106 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+import Database from ".";
+import { CURRENT_DATABASE_VERSION } from "../common";
+import Migrator, { MigratableCollections } from "../database/migrator";
+
+class Migrations {
+ private readonly migrator = new Migrator();
+ private migrating = false;
+ version = CURRENT_DATABASE_VERSION;
+ constructor(private readonly db: Database) {}
+
+ async init() {
+ this.version =
+ (await this.db.storage().read("v")) || CURRENT_DATABASE_VERSION;
+ this.db.storage().write("v", this.version);
+ }
+
+ required() {
+ return this.version < CURRENT_DATABASE_VERSION;
+ }
+
+ async migrate() {
+ try {
+ if (!this.required() || this.migrating) return;
+ this.migrating = true;
+
+ await this.db.notes.init();
+
+ const collections: MigratableCollections = [
+ {
+ items: () => this.db.attachments.all,
+ type: "attachments"
+ },
+ {
+ items: () => this.db.notebooks.raw,
+ type: "notebooks"
+ },
+ {
+ items: () => this.db.tags.raw,
+ type: "tags"
+ },
+ {
+ items: () => this.db.colors.raw,
+ type: "colors"
+ },
+ {
+ iterate: true,
+ type: "content"
+ },
+ {
+ items: () => [this.db.settings.raw],
+ type: "settings"
+ },
+ {
+ items: () => this.db.shortcuts.raw,
+ type: "shortcuts"
+ },
+ {
+ items: () => this.db.reminders.raw,
+ type: "reminders"
+ },
+ {
+ items: () => this.db.relations.raw,
+ type: "relations"
+ },
+ {
+ iterate: true,
+ type: "notehistory"
+ },
+ {
+ iterate: true,
+ type: "sessioncontent"
+ },
+ {
+ items: () => this.db.notes.raw,
+ type: "notes"
+ }
+ ];
+
+ await this.migrator.migrate(this.db, collections, this.version);
+ await this.db.storage().write("v", CURRENT_DATABASE_VERSION);
+ this.version = CURRENT_DATABASE_VERSION;
+ } finally {
+ this.migrating = false;
+ }
+ }
+}
+export default Migrations;
diff --git a/packages/core/src/api/monographs.js b/packages/core/src/api/monographs.js
index f82d2c08d..ac011a9ed 100644
--- a/packages/core/src/api/monographs.js
+++ b/packages/core/src/api/monographs.js
@@ -32,7 +32,7 @@ class Monographs {
async deinit() {
this.monographs = undefined;
- await this._db.storage.write("monographs", this.monographs);
+ await this._db.storage().write("monographs", this.monographs);
}
async init() {
@@ -40,9 +40,9 @@ class Monographs {
const user = await this._db.user.getUser();
const token = await this._db.user.tokenManager.getAccessToken();
if (!user || !token || !user.isEmailConfirmed) return;
- let monographs = await this._db.storage.read("monographs", true);
+ let monographs = await this._db.storage().read("monographs", true);
monographs = await http.get(`${Constants.API_HOST}/monographs`, token);
- await this._db.storage.write("monographs", monographs);
+ await this._db.storage().write("monographs", monographs);
if (monographs) this.monographs = monographs;
} catch (e) {
@@ -103,10 +103,12 @@ class Monographs {
};
if (opts.password) {
- monograph.encryptedContent = await this._db.storage.encrypt(
- { password: opts.password },
- JSON.stringify({ type: content.type, data: content.data })
- );
+ monograph.encryptedContent = await this._db
+ .storage()
+ .encrypt(
+ { password: opts.password },
+ JSON.stringify({ type: content.type, data: content.data })
+ );
} else {
monograph.content = JSON.stringify({
type: content.type,
diff --git a/packages/core/src/api/offers.js b/packages/core/src/api/offers.ts
similarity index 91%
rename from packages/core/src/api/offers.js
rename to packages/core/src/api/offers.ts
index e93b57547..d5df571ee 100644
--- a/packages/core/src/api/offers.js
+++ b/packages/core/src/api/offers.ts
@@ -21,8 +21,8 @@ import { CLIENT_ID } from "../common";
import hosts from "../utils/constants";
import http from "../utils/http";
-export default class Offers {
- async getCode(promo, platform) {
+export class Offers {
+ static async getCode(promo: string, platform: "ios" | "android" | "web") {
const result = await http.get(
`${hosts.SUBSCRIPTIONS_HOST}/offers?promoCode=${promo}&clientId=${CLIENT_ID}&platformId=${platform}`
);
diff --git a/packages/core/src/api/pricing.js b/packages/core/src/api/pricing.ts
similarity index 64%
rename from packages/core/src/api/pricing.js
rename to packages/core/src/api/pricing.ts
index b812c25da..587b6f82e 100644
--- a/packages/core/src/api/pricing.js
+++ b/packages/core/src/api/pricing.ts
@@ -19,35 +19,24 @@ along with this program. If not, see .
import http from "../utils/http";
+type Product = {
+ country: string;
+ countryCode: string;
+ sku?: string;
+ price?: string;
+ discount: number;
+};
+
const BASE_URL = `https://notesnook.com/api/v1/prices`;
-class Pricing {
- /**
- *
- * @param {"android"|"ios"|"web"} platform
- * @param {"monthly"|"yearly"} period
- * @returns {Promise<{
- * country: string,
- * countryCode: string,
- * sku: string,
- * discount: number
- * }>}
- */
- sku(platform, period) {
+export class Pricing {
+ static sku(
+ platform: "android" | "ios" | "web",
+ period: "monthly" | "yearly"
+ ): Promise {
return http.get(`${BASE_URL}/skus/${platform}/${period}`);
}
- /**
- *
- * @param {"monthly"|"yearly"} period
- * @returns {Promise<{
- * country: string,
- * countryCode: string,
- * price: string,
- * discount: number
- * }>}
- */
- price(period = "monthly") {
+ static price(period: "monthly" | "yearly" = "monthly"): Promise {
return http.get(`${BASE_URL}/${period}`);
}
}
-export default Pricing;
diff --git a/packages/core/src/api/session.js b/packages/core/src/api/session.ts
similarity index 80%
rename from packages/core/src/api/session.js
rename to packages/core/src/api/session.ts
index 8cf678eec..6cb989a7a 100644
--- a/packages/core/src/api/session.js
+++ b/packages/core/src/api/session.ts
@@ -17,21 +17,17 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+import { StorageAccessor } from "../interfaces";
+
class Session {
- /**
- *
- * @param {import("../database/storage").default} context
- */
- constructor(context) {
- this._storage = context;
- }
+ constructor(private readonly storage: StorageAccessor) {}
get() {
- return this._storage.read("t");
+ return this.storage().read("t");
}
set() {
- return this._storage.write("t", Date.now());
+ return this.storage().write("t", Date.now());
}
async valid() {
diff --git a/packages/core/src/api/settings.js b/packages/core/src/api/settings.js
deleted file mode 100644
index 0565ed02d..000000000
--- a/packages/core/src/api/settings.js
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
-This file is part of the Notesnook project (https://notesnook.com/)
-
-Copyright (C) 2023 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-import { EV, EVENTS } from "../common";
-import { getId } from "../utils/id";
-import "../types";
-
-class Settings {
- /**
- *
- * @param {import("./index").default} db
- */
- constructor(db) {
- this._db = db;
- }
-
- async init() {
- var settings = await this._db.storage.read("settings");
- this._initSettings(settings);
- await this._saveSettings(false);
-
- EV.subscribe(EVENTS.userLoggedOut, async () => {
- this._initSettings();
- await this._saveSettings(false);
- });
- }
-
- get raw() {
- return this._settings;
- }
-
- async merge(remoteItem, lastSynced) {
- if (this._settings.dateModified > lastSynced) {
- this._settings = {
- ...this._settings,
- ...(remoteItem.deleted
- ? {}
- : {
- ...remoteItem,
- groupOptions: {
- ...this._settings.groupOptions,
- ...remoteItem.groupOptions
- },
- toolbarConfig: {
- ...this._settings.toolbarConfig,
- ...remoteItem.toolbarConfig
- },
- aliases: {
- ...this._settings.aliases,
- ...remoteItem.aliases
- }
- })
- };
- this._settings.dateModified = Date.now();
- } else {
- this._initSettings(remoteItem);
- }
- await this._saveSettings(false);
- }
-
- /**
- *
- * @param {GroupingKey} key
- * @param {GroupOptions} groupOptions
- */
- async setGroupOptions(key, groupOptions) {
- if (!this._settings.groupOptions) this._settings.groupOptions = {};
- this._settings.groupOptions[key] = groupOptions;
- await this._saveSettings();
- }
-
- /**
- *
- * @param {GroupingKey} key
- * @returns {GroupOptions}
- */
- getGroupOptions(key) {
- return (
- (this._settings.groupOptions && this._settings.groupOptions[key]) || {
- groupBy: "default",
- sortBy:
- key === "trash"
- ? "dateDeleted"
- : key === "tags"
- ? "dateCreated"
- : key === "reminders"
- ? "dueDate"
- : "dateEdited",
- sortDirection: key === "reminders" ? "asc" : "desc"
- }
- );
- }
-
- /**
- *
- * @param {string} key
- * @param {{preset: string, config?: any[]}} config
- */
- async setToolbarConfig(key, config) {
- if (!this._settings.toolbarConfig) this._settings.toolbarConfig = {};
- this._settings.toolbarConfig[key] = config;
- await this._saveSettings();
- }
-
- /**
- *
- * @param {string} key
- * @returns {{preset: string, config: any[]}}
- */
- getToolbarConfig(key) {
- return this._settings.toolbarConfig && this._settings.toolbarConfig[key];
- }
-
- async setAlias(id, name) {
- if (!this._settings.aliases) this._settings.aliases = {};
- this._settings.aliases[id] = name;
- await this._saveSettings();
- }
-
- getAlias(id) {
- return this._settings.aliases && this._settings.aliases[id];
- }
- /**
- * Setting to -1 means never clear trash.
- * @param {1 | 7 | 30 | 365 | -1} time
- */
- async setTrashCleanupInterval(time) {
- this._settings.trashCleanupInterval = time;
- await this._saveSettings();
- }
-
- /**
- * @returns {7 | 30 | 365 | -1}
- */
- getTrashCleanupInterval() {
- return this._settings.trashCleanupInterval || 7;
- }
-
- /**
- *
- * @param {{id: string, topic?: string} | undefined} item
- */
- async setDefaultNotebook(item) {
- this._settings.defaultNotebook = !item
- ? undefined
- : {
- id: item.id,
- topic: item.topic
- };
- await this._saveSettings();
- }
- /**
- *
- * @returns {{id: string, topic?: string} | undefined}
- */
- getDefaultNotebook() {
- return this._settings.defaultNotebook;
- }
-
- async setTitleFormat(format) {
- this._settings.titleFormat = format;
- await this._saveSettings();
- }
-
- getTitleFormat() {
- return this._settings.titleFormat || "Note $date$ $time$";
- }
-
- getDateFormat() {
- return this._settings.dateFormat || "DD-MM-YYYY";
- }
-
- async setDateFormat(format) {
- this._settings.dateFormat = format;
- await this._saveSettings();
- }
- /**
- *
- * @returns {"12-hour" | "24-hour"}
- */
- getTimeFormat() {
- return this._settings.timeFormat || "12-hour";
- }
-
- async setTimeFormat(format) {
- this._settings.timeFormat = format;
- await this._saveSettings();
- }
-
- _initSettings(settings) {
- this._settings = {
- type: "settings",
- id: getId(),
- dateModified: 0,
- dateCreated: 0,
- ...(settings || {})
- };
- }
-
- async _saveSettings(updateDateModified = true) {
- this._db.eventManager.publish(
- EVENTS.databaseUpdated,
- "settings",
- this._settings
- );
-
- if (updateDateModified) {
- this._settings.dateModified = Date.now();
- this._settings.synced = false;
- }
- delete this._settings.remote;
-
- await this._db.storage.write("settings", this._settings);
- }
-}
-export default Settings;
diff --git a/packages/core/src/api/subscriptions.js b/packages/core/src/api/subscriptions.ts
similarity index 57%
rename from packages/core/src/api/subscriptions.js
rename to packages/core/src/api/subscriptions.ts
index 4c7995fc6..edb106657 100644
--- a/packages/core/src/api/subscriptions.js
+++ b/packages/core/src/api/subscriptions.ts
@@ -19,23 +19,52 @@ along with this program. If not, see .
import hosts from "../utils/constants";
import http from "../utils/http";
+import TokenManager from "./token-manager";
+
+export type TransactionStatus =
+ | "completed"
+ | "refunded"
+ | "partially_refunded"
+ | "disputed";
+
+export type Transaction = {
+ order_id: string;
+ checkout_id: string;
+ amount: string;
+ currency: string;
+ status: TransactionStatus;
+ created_at: string;
+ passthrough: null;
+ product_id: number;
+ is_subscription: boolean;
+ is_one_off: boolean;
+ subscription: Subscription;
+ user: User;
+ receipt_url: string;
+};
+
+type Subscription = {
+ subscription_id: number;
+ status: string;
+};
+
+type User = {
+ user_id: number;
+ email: string;
+ marketing_consent: boolean;
+};
export default class Subscriptions {
- /**
- * @param {import("../api/token-manager").default} tokenManager
- */
- constructor(tokenManager) {
- this._tokenManager = tokenManager;
- }
+ constructor(private readonly tokenManager: TokenManager) {}
async cancel() {
- const token = await this._tokenManager.getAccessToken();
+ const token = await this.tokenManager.getAccessToken();
if (!token) return;
await http.delete(`${hosts.SUBSCRIPTIONS_HOST}/subscriptions`, token);
}
async refund() {
- const token = await this._tokenManager.getAccessToken();
+ const token = await this.tokenManager.getAccessToken();
if (!token) return;
await http.post(
`${hosts.SUBSCRIPTIONS_HOST}/subscriptions/refund`,
@@ -44,8 +73,8 @@ export default class Subscriptions {
);
}
- async transactions() {
- const token = await this._tokenManager.getAccessToken();
+ async transactions(): Promise {
+ const token = await this.tokenManager.getAccessToken();
if (!token) return;
return await http.get(
`${hosts.SUBSCRIPTIONS_HOST}/subscriptions/transactions`,
@@ -53,8 +82,8 @@ export default class Subscriptions {
);
}
- async updateUrl() {
- const token = await this._tokenManager.getAccessToken();
+ async updateUrl(): Promise {
+ const token = await this.tokenManager.getAccessToken();
if (!token) return;
return await http.get(
`${hosts.SUBSCRIPTIONS_HOST}/subscriptions/update`,
diff --git a/packages/core/src/api/sync/__tests__/collector.test.js b/packages/core/src/api/sync/__tests__/collector.test.js
index 7cfba8c85..bb225985a 100644
--- a/packages/core/src/api/sync/__tests__/collector.test.js
+++ b/packages/core/src/api/sync/__tests__/collector.test.js
@@ -26,7 +26,7 @@ import {
import Collector from "../collector";
import { test, expect } from "vitest";
-test("newly created note should get included in collector", () =>
+test.only("newly created note should get included in collector", () =>
databaseTest().then(async (db) => {
await loginFakeUser(db);
const collector = new Collector(db);
diff --git a/packages/core/src/api/sync/__tests__/sync.test.js b/packages/core/src/api/sync/__tests__/sync.test.js
new file mode 100644
index 000000000..79f4507df
--- /dev/null
+++ b/packages/core/src/api/sync/__tests__/sync.test.js
@@ -0,0 +1,449 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+import Database from "../../index";
+import { NodeStorageInterface } from "../../../../__mocks__/node-storage.mock";
+import { FS } from "../../../../__mocks__/fs.mock";
+import Compressor from "../../../../__mocks__/compressor.mock";
+import { CHECK_IDS, EV, EVENTS } from "../../../common";
+import { EventSource } from "event-source-polyfill";
+import { delay } from "../../../../__tests__/utils";
+import { test, expect, vitest } from "vitest";
+import { login } from "../../../../__e2e__/utils";
+
+const TEST_TIMEOUT = 30 * 1000;
+
+test(
+ "case 1: device A & B should only download the changes from device C (no uploading)",
+ async () => {
+ const types = [];
+ function onSyncProgress({ type }) {
+ types.push(type);
+ }
+
+ const [deviceA, deviceB, deviceC] = await Promise.all([
+ initializeDevice("deviceA"),
+ initializeDevice("deviceB"),
+ initializeDevice("deviceC")
+ ]);
+
+ deviceA.eventManager.subscribe(EVENTS.syncProgress, onSyncProgress);
+ deviceB.eventManager.subscribe(EVENTS.syncProgress, onSyncProgress);
+
+ await deviceC.notes.add({ title: "new note 1" });
+ await syncAndWait(deviceC, deviceC);
+
+ expect(types.every((t) => t === "download")).toBe(true);
+
+ await cleanup(deviceA, deviceB, deviceC);
+ },
+ TEST_TIMEOUT
+);
+
+test(
+ "case 3: Device A & B have unsynced changes but server has nothing",
+ async () => {
+ const [deviceA, deviceB] = await Promise.all([
+ initializeDevice("deviceA"),
+ initializeDevice("deviceB")
+ ]);
+
+ const note1Id = await deviceA.notes.add({
+ title: "Test note from device A"
+ });
+ const note2Id = await deviceB.notes.add({
+ title: "Test note from device B"
+ });
+
+ await syncAndWait(deviceA, deviceB);
+
+ expect(deviceA.notes.note(note2Id)).toBeTruthy();
+ expect(deviceB.notes.note(note1Id)).toBeTruthy();
+ expect(deviceA.notes.note(note1Id)).toBeTruthy();
+ expect(deviceB.notes.note(note2Id)).toBeTruthy();
+
+ await cleanup(deviceA, deviceA);
+ },
+ TEST_TIMEOUT
+);
+
+// test(
+// "case 4: Device A's sync is interrupted halfway and Device B makes some changes afterwards and syncs.",
+// async () => {
+// const deviceA = await initializeDevice("deviceA");
+// const deviceB = await initializeDevice("deviceB");
+
+// const unsyncedNoteIds = [];
+// for (let i = 0; i < 10; ++i) {
+// const id = await deviceA.notes.add({
+// title: `Test note ${i} from device A`,
+// });
+// unsyncedNoteIds.push(id);
+// }
+
+// const half = unsyncedNoteIds.length / 2 + 1;
+// deviceA.eventManager.subscribe(
+// EVENTS.syncProgress,
+// async ({ type, current }) => {
+// if (type === "upload" && current === half) {
+// await deviceA.syncer.stop();
+// }
+// }
+// );
+
+// await expect(deviceA.sync(true)).rejects.toThrow();
+
+// let syncedNoteIds = [];
+// for (let i = 0; i < unsyncedNoteIds.length; ++i) {
+// const expectedNoteId = unsyncedNoteIds[i];
+// if (deviceB.notes.note(expectedNoteId))
+// syncedNoteIds.push(expectedNoteId);
+// }
+// expect(
+// syncedNoteIds.length === half - 1 || syncedNoteIds.length === half
+// ).toBe(true);
+
+// const deviceBNoteId = await deviceB.notes.add({
+// title: "Test note of case 4 from device B",
+// });
+
+// await deviceB.sync(true);
+
+// await syncAndWait(deviceA, deviceB);
+
+// expect(deviceA.notes.note(deviceBNoteId)).toBeTruthy();
+// expect(
+// unsyncedNoteIds
+// .map((id) => !!deviceB.notes.note(id))
+// .every((res) => res === true)
+// ).toBe(true);
+
+// await cleanup(deviceA, deviceB);
+// },
+//
+// );
+
+// test.only(
+// "case 5: Device A's sync is interrupted halfway and Device B makes changes on the same note's content that didn't get synced on Device A due to interruption.",
+// async () => {
+// const deviceA = await initializeDevice("deviceA");
+// const deviceB = await initializeDevice("deviceB");
+
+// const noteIds = [];
+// for (let i = 0; i < 10; ++i) {
+// const id = await deviceA.notes.add({
+// content: {
+// type: "tiptap",
+// data: `deviceA=true
`,
+// },
+// });
+// noteIds.push(id);
+// }
+
+// await deviceA.sync(true);
+// await deviceB.sync(true);
+
+// const unsyncedNoteIds = [];
+// for (let id of noteIds) {
+// const noteId = await deviceA.notes.add({
+// id,
+// content: {
+// type: "tiptap",
+// data: `deviceA=true+changed=true
`,
+// },
+// });
+// unsyncedNoteIds.push(noteId);
+// }
+
+// deviceA.eventManager.subscribe(
+// EVENTS.syncProgress,
+// async ({ type, total, current }) => {
+// const half = total / 2 + 1;
+// if (type === "upload" && current === half) {
+// await deviceA.syncer.stop();
+// }
+// }
+// );
+
+// await expect(deviceA.sync(true)).rejects.toThrow();
+
+// await delay(10 * 1000);
+
+// for (let id of unsyncedNoteIds) {
+// await deviceB.notes.add({
+// id,
+// content: {
+// type: "tiptap",
+// data: "changes from device B
",
+// },
+// });
+// }
+
+// const error = await withError(async () => {
+// await deviceB.sync(true);
+// await deviceA.sync(true);
+// });
+
+// expect(error).not.toBeInstanceOf(NoErrorThrownError);
+// expect(error.message.includes("Merge")).toBeTruthy();
+
+// await cleanup(deviceA, deviceB);
+// },
+//
+// );
+
+test(
+ "issue: running force sync from device A makes device B always download everything",
+ async () => {
+ const [deviceA, deviceB] = await Promise.all([
+ initializeDevice("deviceA"),
+ initializeDevice("deviceB")
+ ]);
+
+ await syncAndWait(deviceA, deviceB, true);
+
+ const handler = vitest.fn();
+ deviceB.eventManager.subscribe(EVENTS.syncProgress, handler);
+
+ await deviceB.sync(true);
+
+ expect(handler).not.toHaveBeenCalled();
+
+ await cleanup(deviceB);
+ },
+ TEST_TIMEOUT
+);
+
+test(
+ "issue: colors are not properly created if multiple notes are synced together",
+ async () => {
+ const [deviceA, deviceB] = await Promise.all([
+ initializeDevice("deviceA", [CHECK_IDS.noteColor]),
+ initializeDevice("deviceB", [CHECK_IDS.noteColor])
+ ]);
+
+ const noteIds = [];
+ for (let i = 0; i < 3; ++i) {
+ const id = await deviceA.notes.add({
+ content: {
+ type: "tiptap",
+ data: `deviceA=true
`
+ }
+ });
+ noteIds.push(id);
+ }
+
+ await syncAndWait(deviceA, deviceB);
+
+ const colorId = await deviceA.colors.add({
+ title: "yellow",
+ colorCode: "#ffff22"
+ });
+ for (let noteId of noteIds) {
+ expect(deviceB.notes.note(noteId)).toBeTruthy();
+ expect(
+ deviceB.relations
+ .from({ id: colorId, type: "color" }, "note")
+ .findIndex((a) => a.to.id === noteId)
+ ).toBe(-1);
+
+ await deviceA.relations.add(
+ { id: colorId, type: "color" },
+ { id: noteId, type: "note" }
+ );
+ }
+
+ await syncAndWait(deviceA, deviceB);
+
+ expect(deviceB.colors.exists(colorId)).toBeTruthy();
+ const purpleNotes = deviceB.relations
+ .from({ id: colorId, type: "color" }, "note")
+ .resolved();
+ expect(
+ noteIds.every((id) => purpleNotes.findIndex((p) => p.id === id) > -1)
+ ).toBe(true);
+
+ await cleanup(deviceA, deviceB);
+ },
+ TEST_TIMEOUT
+);
+
+test(
+ "issue: new topic on device A gets replaced by the new topic on device B",
+ async () => {
+ const [deviceA, deviceB] = await Promise.all([
+ initializeDevice("deviceA"),
+ initializeDevice("deviceB")
+ ]);
+ // const deviceA = await initializeDevice("deviceA");
+ // const deviceB = await initializeDevice("deviceB");
+
+ const id = await deviceA.notebooks.add({ title: "Notebook 1" });
+
+ await syncAndWait(deviceA, deviceB, false);
+
+ expect(deviceB.notebooks.notebook(id)).toBeDefined();
+
+ await deviceA.notebooks.topics(id).add({ title: "Topic 1" });
+ // to create a conflict
+ await delay(1500);
+ await deviceB.notebooks.topics(id).add({ title: "Topic 2" });
+
+ expect(deviceA.notebooks.topics(id).has("Topic 1")).toBeTruthy();
+ expect(deviceB.notebooks.topics(id).has("Topic 2")).toBeTruthy();
+
+ await syncAndWait(deviceA, deviceB, false);
+
+ // await delay(1000);
+
+ // await syncAndWait(deviceB, deviceB, false);
+
+ expect(deviceA.notebooks.topics(id).has("Topic 1")).toBeTruthy();
+ expect(deviceB.notebooks.topics(id).has("Topic 1")).toBeTruthy();
+
+ expect(deviceA.notebooks.topics(id).has("Topic 2")).toBeTruthy();
+ expect(deviceB.notebooks.topics(id).has("Topic 2")).toBeTruthy();
+
+ await cleanup(deviceA, deviceB);
+ },
+ TEST_TIMEOUT
+);
+
+test(
+ "issue: remove notebook reference from notes that are removed from topic during merge",
+ async () => {
+ const [deviceA, deviceB] = await Promise.all([
+ initializeDevice("deviceA"),
+ initializeDevice("deviceB")
+ ]);
+
+ const id = await deviceA.notebooks.add({
+ title: "Notebook 1",
+ topics: [{ title: "Topic 1" }]
+ });
+ const topic = deviceA.notebooks.topics(id).topic("Topic 1");
+
+ await syncAndWait(deviceA, deviceB, false);
+
+ expect(deviceB.notebooks.notebook(id)).toBeDefined();
+
+ const noteA = await deviceA.notes.add({ title: "Note 1" });
+ await deviceA.notes.addToNotebook({ id, topic: topic.id }, noteA);
+
+ expect(topic.totalNotes).toBe(1);
+
+ await delay(2000);
+
+ const noteB = await deviceB.notes.add({ title: "Note 2" });
+ await deviceB.notes.addToNotebook({ id, topic: topic.id }, noteB);
+
+ expect(deviceB.notebooks.topics(id).topic(topic.id).totalNotes).toBe(1);
+
+ await syncAndWait(deviceB, deviceA, false);
+ await syncAndWait(deviceA, deviceB, false);
+
+ expect(deviceA.notebooks.topics(id).topic(topic.id).totalNotes).toBe(2);
+ expect(deviceB.notebooks.topics(id).topic(topic.id).totalNotes).toBe(2);
+
+ expect(deviceA.notes.note(noteA).data.notebooks).toHaveLength(1);
+ expect(deviceA.notes.note(noteB).data.notebooks).toHaveLength(1);
+
+ await cleanup(deviceA, deviceB);
+ },
+ TEST_TIMEOUT
+);
+
+/**
+ *
+ * @param {string} id
+ * @returns {Promise}
+ */
+async function initializeDevice(id, capabilities = []) {
+ console.time(`Init ${id}`);
+ EV.subscribe(EVENTS.userCheckStatus, async (type) => {
+ return {
+ type,
+ result: capabilities.indexOf(type) > -1
+ };
+ });
+ EV.subscribe(EVENTS.syncCheckStatus, async (type) => {
+ return {
+ type,
+ result: true
+ };
+ });
+
+ const device = new Database();
+ device.setup({
+ storage: new NodeStorageInterface(),
+ eventsource: EventSource,
+ fs: FS,
+ compressor: Compressor
+ });
+
+ await device.init();
+
+ await login(device);
+
+ await device.user.resetUser(false);
+
+ await device.sync(true, false);
+
+ console.timeEnd(`Init ${id}`);
+ return device;
+}
+
+/**
+ *
+ * @param {...Database} devices
+ */
+async function cleanup(...devices) {
+ await Promise.all([
+ devices.map(async (device) => {
+ await device.syncer.stop();
+ await device.user.logout();
+ device.eventManager.unsubscribeAll();
+ })
+ ]);
+ EV.unsubscribeAll();
+}
+
+/**
+ *
+ * @param {Database} deviceA
+ * @param {Database} deviceB
+ * @returns
+ */
+function syncAndWait(deviceA, deviceB, force = false) {
+ return new Promise((resolve) => {
+ const ref = deviceB.eventManager.subscribe(EVENTS.syncCompleted, () => {
+ ref.unsubscribe();
+ console.log("sync completed.");
+ resolve();
+ });
+ console.log(
+ "waiting for sync...",
+ "Device A:",
+ deviceA.syncer.sync.syncing,
+ "Device B:",
+ deviceB.syncer.sync.syncing
+ );
+ deviceA.sync(true, force);
+ });
+}
diff --git a/packages/core/src/api/sync/auto-sync.js b/packages/core/src/api/sync/auto-sync.ts
similarity index 79%
rename from packages/core/src/api/sync/auto-sync.js
rename to packages/core/src/api/sync/auto-sync.ts
index ccb0fedf1..c75d77fa6 100644
--- a/packages/core/src/api/sync/auto-sync.js
+++ b/packages/core/src/api/sync/auto-sync.ts
@@ -17,22 +17,21 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+import Database from "..";
import { EVENTS } from "../../common";
import { logger } from "../../logger";
+import { Item } from "../../types";
export class AutoSync {
- /**
- *
- * @param {import("../index").default} db
- * @param {number} interval
- */
- constructor(db, interval) {
- this.db = db;
- this.interval = interval;
- this.timeout = null;
- this.isAutoSyncing = false;
- this.logger = logger.scope("AutoSync");
- }
+ timeout = 0;
+ isAutoSyncing = false;
+ logger = logger.scope("AutoSync");
+ databaseUpdatedEvent?: { unsubscribe: () => boolean };
+
+ constructor(
+ private readonly db: Database,
+ private readonly interval: number
+ ) {}
async start() {
this.logger.info(`Auto sync requested`);
@@ -55,13 +54,12 @@ export class AutoSync {
this.logger.info(`Auto sync stopped`);
}
- /**
- * @private
- */
- schedule(id, item) {
+ private schedule(id: string, item?: Item) {
if (
item &&
- (item.remote || item.localOnly || item.failed || !!item.dateUploaded)
+ (item.remote ||
+ ("localOnly" in item && item.localOnly) ||
+ ("failed" in item && item.failed) || ("dateUploaded" in item && item.dateUploaded))
)
return;
@@ -76,6 +74,6 @@ export class AutoSync {
this.timeout = setTimeout(() => {
this.logger.info(`Sync requested by: ${id}`);
this.db.eventManager.publish(EVENTS.databaseSyncRequested, false, false);
- }, interval);
+ }, interval) as unknown as number;
}
}
diff --git a/packages/core/src/api/sync/collector.js b/packages/core/src/api/sync/collector.js
deleted file mode 100644
index e1ad3fa5e..000000000
--- a/packages/core/src/api/sync/collector.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
-This file is part of the Notesnook project (https://notesnook.com/)
-
-Copyright (C) 2023 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-import { CURRENT_DATABASE_VERSION } from "../../common";
-import { logger } from "../../logger";
-
-const SYNC_COLLECTIONS_MAP = {
- note: "notes",
- notebook: "notebooks",
- shortcut: "shortcuts",
- reminder: "reminders",
- relation: "relations"
-};
-
-const ASYNC_COLLECTIONS_MAP = {
- content: "content"
-};
-class Collector {
- /**
- *
- * @param {import("../index").default} db
- */
- constructor(db) {
- this._db = db;
- this.logger = logger.scope("SyncCollector");
- }
-
- async *collect(chunkSize, lastSyncedTimestamp, isForceSync) {
- const key = await this._db.user.getEncryptionKey();
-
- const settings = await this.prepareChunk(
- [this._db.settings.raw],
- lastSyncedTimestamp,
- isForceSync,
- key,
- "settings"
- );
- if (settings) yield settings;
-
- const attachments = await this.prepareChunk(
- this._db.attachments.syncable,
- lastSyncedTimestamp,
- isForceSync,
- key,
- "attachment"
- );
- if (attachments) yield attachments;
-
- for (const itemType in ASYNC_COLLECTIONS_MAP) {
- const collectionKey = ASYNC_COLLECTIONS_MAP[itemType];
- const collection = this._db[collectionKey]._collection;
- for await (const chunk of collection.iterate(chunkSize)) {
- const items = await this.prepareChunk(
- chunk.map((item) => item[1]),
- lastSyncedTimestamp,
- isForceSync,
- key,
- itemType
- );
- if (!items) continue;
- yield items;
- }
- }
-
- for (const itemType in SYNC_COLLECTIONS_MAP) {
- const collectionKey = SYNC_COLLECTIONS_MAP[itemType];
- const collection = this._db[collectionKey]._collection;
- for (const chunk of collection.iterateSync(chunkSize)) {
- const items = await this.prepareChunk(
- chunk,
- lastSyncedTimestamp,
- isForceSync,
- key,
- itemType
- );
- if (!items) continue;
- yield items;
- }
- }
- }
-
- async prepareChunk(chunk, lastSyncedTimestamp, isForceSync, key, itemType) {
- const { ids, items } = filterSyncableItems(
- chunk,
- lastSyncedTimestamp,
- isForceSync
- );
- if (!ids.length) return;
- const ciphers = await this._db.storage.encryptMulti(key, items);
- return toPushItem(itemType, ids, ciphers);
- }
-}
-export default Collector;
-
-function toPushItem(type, ids, ciphers) {
- const items = ciphers.map((cipher, index) => {
- cipher.v = CURRENT_DATABASE_VERSION;
- cipher.id = ids[index];
- return cipher;
- });
- return {
- items,
- type
- };
-}
-
-function filterSyncableItems(items, lastSyncedTimestamp, isForceSync) {
- if (!items || !items.length) return { items: [], ids: [] };
-
- const ids = [];
- const syncableItems = [];
- for (const item of items) {
- if (!item) continue;
-
- const isSyncable = !item.synced || isForceSync;
- const isUnsynced = item.dateModified > lastSyncedTimestamp || isForceSync;
-
- // in case of resolved content
- delete item.resolved;
- // synced is a local only property
- delete item.synced;
-
- if (isUnsynced && isSyncable) {
- ids.push(item.id);
- syncableItems.push(
- JSON.stringify(
- item.localOnly
- ? {
- id: item.id,
- deleted: true,
- dateModified: item.dateModified,
- deleteReason: "localOnly"
- }
- : item
- )
- );
- }
- }
- return { items: syncableItems, ids };
-}
diff --git a/packages/core/src/api/sync/collector.ts b/packages/core/src/api/sync/collector.ts
new file mode 100644
index 000000000..8123500aa
--- /dev/null
+++ b/packages/core/src/api/sync/collector.ts
@@ -0,0 +1,144 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+import { Cipher, SerializedKey } from "@notesnook/crypto";
+import Database from "..";
+import { CURRENT_DATABASE_VERSION } from "../../common";
+import { Item, MaybeDeletedItem } from "../../types";
+
+export type SyncableItemType =
+ | "note"
+ | "shortcut"
+ | "notebook"
+ | "content"
+ | "attachment"
+ | "reminder"
+ | "relation"
+ | "color"
+ | "tag"
+ | "settings";
+export type CollectedResult = {
+ items: (MaybeDeletedItem- | Cipher)[];
+ types: (SyncableItemType | "vaultKey")[];
+};
+
+export type SyncItem = {
+ id: string;
+ v: number;
+} & Cipher;
+
+class Collector {
+ private lastSyncedTimestamp = 0;
+ private key?: SerializedKey;
+ constructor(private readonly db: Database) {}
+
+ async collect(lastSyncedTimestamp: number, isForceSync?: boolean) {
+ await this.db.notes.init();
+
+ this.lastSyncedTimestamp = lastSyncedTimestamp;
+ this.key = await this.db.user.getEncryptionKey();
+ const vaultKey = await this.db.vault.getKey();
+
+ const collections = {
+ note: this.db.notes.raw,
+ shortcut: this.db.shortcuts.raw,
+ notebook: this.db.notebooks.raw,
+ content: await this.db.content.all(),
+ attachment: this.db.attachments.syncable,
+ reminder: this.db.reminders.raw,
+ relation: this.db.relations.raw,
+ color: this.db.colors.raw,
+ tag: this.db.tags.raw,
+ settings: [this.db.settings.raw]
+ };
+
+ const result: CollectedResult = {
+ items: [],
+ types: []
+ };
+ for (const type in collections) {
+ this.collectInternal(
+ type as SyncableItemType,
+ collections[type as SyncableItemType],
+ result,
+ isForceSync
+ );
+ }
+
+ if (vaultKey) {
+ result.items.push(vaultKey);
+ result.types.push("vaultKey");
+ }
+
+ return result;
+ }
+
+ private serialize(item: MaybeDeletedItem
- ) {
+ if (!this.key) throw new Error("No encryption key found.");
+ return this.db.storage().encrypt(this.key, JSON.stringify(item));
+ }
+
+ encrypt(array: MaybeDeletedItem
- []) {
+ if (!array.length) return [];
+ return Promise.all(array.map(this.map, this));
+ }
+
+ private collectInternal(
+ itemType: SyncableItemType,
+ items: MaybeDeletedItem
- [],
+ result: CollectedResult,
+ isForceSync?: boolean
+ ) {
+ if (!items || !items.length) return;
+
+ for (const item of items) {
+ if (!item) continue;
+
+ const isSyncable = !item.synced || isForceSync;
+ const isUnsynced =
+ item.dateModified > this.lastSyncedTimestamp || isForceSync;
+
+ if (isUnsynced && isSyncable) {
+ result.items.push(
+ "localOnly" in item && item.localOnly
+ ? {
+ id: item.id,
+ deleted: true,
+ dateModified: item.dateModified,
+ deleteReason: "localOnly"
+ }
+ : item
+ );
+ result.types.push(itemType);
+ }
+ }
+ }
+
+ private async map(item: MaybeDeletedItem
- ) {
+ // synced is a local only property
+ delete item.synced;
+
+ return {
+ id: item.id,
+ v: CURRENT_DATABASE_VERSION,
+ ...(await this.serialize(item))
+ };
+ }
+}
+export default Collector;
diff --git a/packages/core/src/api/sync/conflicts.js b/packages/core/src/api/sync/conflicts.ts
similarity index 74%
rename from packages/core/src/api/sync/conflicts.js
rename to packages/core/src/api/sync/conflicts.ts
index 15d66710d..3a5ea6d9c 100644
--- a/packages/core/src/api/sync/conflicts.js
+++ b/packages/core/src/api/sync/conflicts.ts
@@ -17,29 +17,25 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+import Database from "..";
+
class Conflicts {
- /**
- *
- * @param {import('../index').default} db
- */
- constructor(db) {
- this._db = db;
- }
+ constructor(private readonly db: Database) {}
async recalculate() {
- if (this._db.notes.conflicted.length <= 0) {
- await this._db.storage.write("hasConflicts", false);
+ if (this.db.notes.conflicted.length <= 0) {
+ await this.db.storage().write("hasConflicts", false);
}
}
check() {
- return this._db.storage.read("hasConflicts");
+ return this.db.storage().read("hasConflicts");
}
throw() {
throw new Error(
- "Merge conflicts detected. Please resolve all conflicts to continue syncing.",
- { cause: "MERGE_CONFLICT" }
+ "Merge conflicts detected. Please resolve all conflicts to continue syncing."
+ // { cause: "MERGE_CONFLICT" }
);
}
}
diff --git a/packages/core/src/api/sync/index.js b/packages/core/src/api/sync/index.ts
similarity index 80%
rename from packages/core/src/api/sync/index.js
rename to packages/core/src/api/sync/index.ts
index 0752a86de..73c1d9fc6 100644
--- a/packages/core/src/api/sync/index.js
+++ b/packages/core/src/api/sync/index.ts
@@ -26,43 +26,59 @@ import {
} from "../../common";
import Constants from "../../utils/constants";
import TokenManager from "../token-manager";
-import Collector from "./collector";
+import Collector, {
+ CollectedResult,
+ SyncableItemType,
+ SyncItem
+} from "./collector";
import * as signalr from "@microsoft/signalr";
import Merger from "./merger";
import Conflicts from "./conflicts";
import { AutoSync } from "./auto-sync";
import { logger } from "../../logger";
import { Mutex } from "async-mutex";
+import Database from "..";
import { migrateItem } from "../../migrations";
+import { SerializedKey } from "@notesnook/crypto";
-/**
- * @typedef {{
- * items: any[],
- * type: string,
- * }} SyncTransferItem
- */
+const ITEM_TYPE_TO_COLLECTION_TYPE = {
+ note: "notes",
+ notebook: "notebooks",
+ content: "content",
+ attachment: "attachments",
+ relation: "relations",
+ reminder: "reminders",
+ shortcut: "shortcuts"
+};
+
+export type SyncOptions = {
+ type: "full" | "fetch" | "send";
+ force?: boolean;
+ serverLastSynced?: number;
+};
+
+type SyncTransferItem = {
+ items: SyncItem[];
+ type: SyncableItemType;
+};
export default class SyncManager {
- /**
- *
- * @param {import("../index").default} db
- */
- constructor(db) {
- this.sync = new Sync(db);
- this._db = db;
- }
+ sync = new Sync(this.db);
+ constructor(private readonly db: Database) {}
- async start(options) {
+ async start(options: SyncOptions) {
try {
await this.sync.autoSync.start();
await this.sync.start(options);
return true;
} catch (e) {
- var isHubException = e.message.includes("HubException:");
+ const isHubException = (e as Error).message.includes("HubException:");
if (isHubException) {
- var actualError = /HubException: (.*)/gm.exec(e.message);
+ var actualError = /HubException: (.*)/gm.exec((e as Error).message);
const errorText =
- actualError && actualError.length > 1 ? actualError[1] : e.message;
+ actualError && actualError.length > 1
+ ? actualError[1]
+ : (e as Error).message;
// NOTE: sometimes there's the case where the user has already
// confirmed their email but the server still thinks that it
@@ -71,9 +87,9 @@ export default class SyncManager {
if (
(errorText.includes("Please confirm your email ") ||
errorText.includes("Invalid token.")) &&
- (await this._db.user.getUser()).isEmailConfirmed
+ (await this.db.user.getUser())?.isEmailConfirmed
) {
- await this._db.user.tokenManager._refreshToken(true);
+ await this.db.tokenManager._refreshToken(true);
return false;
}
@@ -83,7 +99,7 @@ export default class SyncManager {
}
}
- async acquireLock(callback) {
+ async acquireLock(callback: () => Promise) {
try {
this.sync.autoSync.stop();
await callback();
@@ -98,33 +114,25 @@ export default class SyncManager {
}
class Sync {
- /**
- *
- * @param {import("../index").default} db
- */
- constructor(db) {
- this.db = db;
- this.conflicts = new Conflicts(db);
- this.collector = new Collector(db);
- this.merger = new Merger(db);
- this.autoSync = new AutoSync(db, 1000);
- this.logger = logger.scope("Sync");
- this.syncConnectionMutex = new Mutex();
- this.itemTypeToCollection = {
- note: "notes",
- notebook: "notebooks",
- content: "content",
- attachment: "attachments",
- relation: "relations",
- reminder: "reminders",
- shortcut: "shortcuts"
- };
+ conflicts = new Conflicts(this.db);
+ collector = new Collector(this.db);
+ merger = new Merger(this.db);
+ autoSync = new AutoSync(this.db, 1000);
+ logger = logger.scope("Sync");
+ syncConnectionMutex = new Mutex();
+ connection: signalr.HubConnection;
+
+ constructor(private readonly db: Database) {
let remoteSyncTimeout = 0;
const tokenManager = new TokenManager(db.storage);
this.connection = new signalr.HubConnectionBuilder()
.withUrl(`${Constants.API_HOST}/hubs/sync`, {
- accessTokenFactory: () => tokenManager.getAccessToken(),
+ accessTokenFactory: async () => {
+ const token = await tokenManager.getAccessToken();
+ if (!token) throw new Error("Failed to get access token.");
+ return token;
+ },
skipNegotiation: true,
transport: signalr.HttpTransportType.WebSockets,
logger: {
@@ -151,7 +159,6 @@ class Sync {
this.autoSync.stop();
});
- let count = 0;
this.connection.on("PushItems", async (chunk) => {
if (this.connection.state !== signalr.HubConnectionState.Connected)
return;
@@ -159,7 +166,7 @@ class Sync {
clearTimeout(remoteSyncTimeout);
remoteSyncTimeout = setTimeout(() => {
this.db.eventManager.publish(EVENTS.syncAborted);
- }, 15000);
+ }, 15000) as unknown as number;
const key = await this.db.user.getEncryptionKey();
const dbLastSynced = await this.db.lastSynced();
@@ -167,21 +174,12 @@ class Sync {
});
this.connection.on("PushCompleted", (lastSynced) => {
- count = 0;
clearTimeout(remoteSyncTimeout);
this.onPushCompleted(lastSynced);
});
}
- /**
- *
- * @param {{
- * type: "full" | "fetch" | "send";
- * force?: boolean;
- * serverLastSynced?: number;
- * }} options
- */
- async start(options) {
+ async start(options: SyncOptions) {
if (!(await checkSyncStatus(SYNC_CHECK_IDS.sync))) {
await this.connection.stop();
return;
@@ -206,7 +204,7 @@ class Sync {
options.type === "fetch" || options.type === "full"
? await this.fetch(lastSynced)
: null;
- this.logger.info("Data fetched", serverResponse);
+ this.logger.info("Data fetched", serverResponse || {});
if (
(options.type === "send" || options.type === "full") &&
@@ -227,7 +225,7 @@ class Sync {
}
}
- async init(isForceSync) {
+ async init(isForceSync?: boolean) {
await this.checkConnection();
await this.conflicts.recalculate();
@@ -242,7 +240,7 @@ class Sync {
return { lastSynced, oldLastSynced };
}
- async fetch(lastSynced) {
+ async fetch(lastSynced: number) {
await this.checkConnection();
const key = await this.db.user.getEncryptionKey();
@@ -339,7 +337,7 @@ class Sync {
this.logger.info("Stopping sync", { lastSynced });
const storedLastSynced = await this.db.lastSynced();
if (lastSynced > storedLastSynced)
- await this.db.storage.write("lastSynced", lastSynced);
+ await this.db.storage().write("lastSynced", lastSynced);
this.db.eventManager.publish(EVENTS.syncCompleted);
}
@@ -355,8 +353,12 @@ class Sync {
const attachments = this.db.attachments.pending;
this.logger.info("Uploading attachments...", { total: attachments.length });
- await this.db.fs.queueUploads(
- attachments.map((a) => ({ filename: a.metadata.hash })),
+ await this.db.fs().queueUploads(
+ attachments.map((a) => ({
+ filename: a.metadata.hash,
+ chunkSize: a.chunkSize,
+ metadata: a.metadata
+ })),
"sync-uploads"
);
}
@@ -379,8 +381,13 @@ class Sync {
await this.db.monographs.init();
}
- async processChunk(chunk, key, dbLastSynced, notify = false) {
- const decrypted = await this.db.storage.decryptMulti(key, chunk.items);
+ async processChunk(
+ chunk: SyncTransferItem,
+ key: SerializedKey,
+ dbLastSynced: number,
+ notify = false
+ ) {
+ const decrypted = await this.db.storage().decryptMulti(key, chunk.items);
const deserialized = await Promise.all(
decrypted.map((item, index) =>
@@ -426,20 +433,14 @@ class Sync {
}
}
- /**
- *
- * @param {SyncTransferItem} item
- * @returns {Promise}
- * @private
- */
- async pushItem(item, newLastSynced) {
+ private async pushItem(item: SyncTransferItem, newLastSynced: number) {
await this.checkConnection();
return (
(await this.connection.invoke("PushItems", item, newLastSynced)) === 1
);
}
- async checkConnection() {
+ private async checkConnection() {
await this.syncConnectionMutex.runExclusive(async () => {
try {
if (this.connection.state !== signalr.HubConnectionState.Connected) {
@@ -452,19 +453,22 @@ class Sync {
await promiseTimeout(30000, this.connection.start());
}
} catch (e) {
- this.logger.warn(e.message);
- throw new Error(
- "Could not connect to the Sync server. Please try again."
- );
+ console.error(e);
+ if (e instanceof Error) {
+ this.logger.warn(e.message);
+ throw new Error(
+ "Could not connect to the Sync server. Please try again."
+ );
+ }
}
});
}
}
-function promiseTimeout(ms, promise) {
+function promiseTimeout(ms: number, promise: Promise) {
// Create a promise that rejects in milliseconds
- let timeout = new Promise((resolve, reject) => {
- let id = setTimeout(() => {
+ const timeout = new Promise((resolve, reject) => {
+ const id = setTimeout(() => {
clearTimeout(id);
reject(new Error("Sync timed out in " + ms + "ms."));
}, ms);
diff --git a/packages/core/src/api/sync/merger.js b/packages/core/src/api/sync/merger.js
deleted file mode 100644
index ea7cafde4..000000000
--- a/packages/core/src/api/sync/merger.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
-This file is part of the Notesnook project (https://notesnook.com/)
-
-Copyright (C) 2023 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-import setManipulator from "../../utils/set";
-import { logger } from "../../logger";
-import { isHTMLEqual } from "../../utils/html-diff";
-
-class Merger {
- /**
- *
- * @param {import("../index").default} db
- */
- constructor(db) {
- this._db = db;
- this.logger = logger.scope("Merger");
-
- this.syncCollectionMap = {
- shortcut: "shortcuts",
- reminder: "reminders",
- relation: "relations",
- notebook: "notebooks"
- };
- }
-
- isSyncCollection(type) {
- return !!this.syncCollectionMap[type];
- }
-
- isConflicted(localItem, remoteItem, lastSynced, conflictThreshold) {
- const isResolved = localItem.dateResolved === remoteItem.dateModified;
- const isModified =
- // the local item is modified if it was changed/modified after the last
- // sync i.e. it wasn't synced yet.
- // However, in case a sync is interrupted the local item's date modified
- // will be ahead of last sync. In that case, we also have to check if the
- // synced flag is false (it is only false if a user makes edits on the
- // local device).
- localItem.dateModified > lastSynced && !localItem.synced;
- if (isModified && !isResolved) {
- // If time difference between local item's edits & remote item's edits
- // is less than threshold, we shouldn't trigger a merge conflict; instead
- // we will keep the most recently changed item.
- const timeDiff =
- Math.max(remoteItem.dateModified, localItem.dateModified) -
- Math.min(remoteItem.dateModified, localItem.dateModified);
-
- if (timeDiff < conflictThreshold) {
- if (remoteItem.dateModified > localItem.dateModified) {
- return "merge";
- }
- return;
- }
-
- return "conflict";
- } else if (!isResolved) {
- return "merge";
- }
- }
-
- mergeItemSync(remoteItem, type, lastSynced) {
- switch (type) {
- case "shortcut":
- case "reminder":
- case "relation": {
- const localItem = this._db[
- this.syncCollectionMap[type]
- ]._collection.getItem(remoteItem.id);
- if (!localItem || remoteItem.dateModified > localItem.dateModified) {
- return remoteItem;
- }
- break;
- }
- case "notebook": {
- const THRESHOLD = 1000;
- const localItem = this._db.notebooks._collection.getItem(remoteItem.id);
- if (
- !localItem ||
- this.isConflicted(localItem, remoteItem, lastSynced, THRESHOLD)
- ) {
- return this._db.notebooks.merge(localItem, remoteItem, lastSynced);
- }
- break;
- }
- }
- }
-
- async mergeContent(remoteItem, localItem, lastSynced) {
- if (localItem && localItem.localOnly) return;
-
- const THRESHOLD = process.env.NODE_ENV === "test" ? 6 * 1000 : 60 * 1000;
- const conflicted =
- localItem &&
- this.isConflicted(localItem, remoteItem, lastSynced, THRESHOLD);
- if (!localItem || conflicted === "merge") {
- return remoteItem;
- } else if (conflicted === "conflict") {
- const note = this._db.notes._collection.getItem(localItem.noteId);
- if (!note || note.deleted) return;
-
- // if hashes are equal do nothing
- if (
- !note.locked &&
- (!remoteItem ||
- !remoteItem ||
- !localItem.data ||
- !remoteItem.data ||
- isHTMLEqual(localItem.data, remoteItem.data))
- )
- return;
-
- if (remoteItem.deleted || localItem.deleted || note.locked) {
- // if note is locked or content is deleted we keep the most recent version.
- if (remoteItem.dateModified > localItem.dateModified) return remoteItem;
- } else {
- // otherwise we trigger the conflicts
- await this._db.notes.add({
- id: localItem.noteId,
- conflicted: true
- });
- await this._db.storage.write("hasConflicts", true);
- return {
- ...localItem,
- conflicted: remoteItem
- };
- }
- }
- }
-
- async mergeItem(remoteItem, type, lastSynced) {
- switch (type) {
- case "note": {
- const localItem = this._db.notes._collection.getItem(remoteItem.id);
- if (!localItem || remoteItem.dateModified > localItem.dateModified) {
- return await this._db.notes.merge(localItem, remoteItem);
- }
- break;
- }
- case "settings": {
- const localItem = this._db.settings.raw;
- if (
- !localItem ||
- this.isConflicted(localItem, remoteItem, lastSynced, 1000)
- ) {
- await this._db.settings.merge(remoteItem, lastSynced);
- }
- break;
- }
- case "attachment": {
- if (remoteItem.deleted)
- return this._db.attachments.merge(null, remoteItem);
-
- // rare case but if remote attachment doesn't have metadata it's probably broken so we should just skip it in this case.
- if (!remoteItem.metadata) break;
-
- const localItem = this._db.attachments.attachment(
- remoteItem.metadata?.hash
- );
- if (
- localItem &&
- localItem.metadata &&
- localItem.dateUploaded !== remoteItem.dateUploaded
- ) {
- const noteIds = localItem.noteIds.slice();
- const isRemoved = await this._db.attachments.remove(
- localItem.metadata.hash,
- true
- );
- if (!isRemoved)
- throw new Error(
- "Conflict could not be resolved in one of the attachments."
- );
- remoteItem.noteIds = setManipulator.union(
- remoteItem.noteIds,
- noteIds
- );
- remoteItem.remote = false;
- }
- return this._db.attachments.merge(localItem, remoteItem);
- }
- }
- }
-}
-export default Merger;
diff --git a/packages/core/src/api/sync/merger.ts b/packages/core/src/api/sync/merger.ts
new file mode 100644
index 000000000..8e44b8bb2
--- /dev/null
+++ b/packages/core/src/api/sync/merger.ts
@@ -0,0 +1,309 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+import { migrateItem } from "../../migrations";
+import { set } from "../../utils/set";
+import { logger } from "../../logger";
+import { isHTMLEqual } from "../../utils/html-diff";
+import { EV, EVENTS } from "../../common";
+import Database from "..";
+import { SyncItem, SyncableItemType } from "./collector";
+import { Item, ItemMap, MaybeDeletedItem, isDeleted } from "../../types";
+import { SerializedKey } from "@notesnook/crypto";
+import { isCipher } from "../../database/crypto";
+
+type Conflict
= (
+ local: MaybeDeletedItem,
+ remote: MaybeDeletedItem
+) => Promise;
+
+type Set = (
+ item: MaybeDeletedItem
+) => Promise;
+
+type Get = (
+ id: string
+) =>
+ | MaybeDeletedItem
+ | undefined
+ | Promise | undefined>;
+
+type MergeDefinition = {
+ [P in SyncableItemType]: {
+ threshold?: number;
+ get?: Get;
+ set: Set
;
+ conflict?: Conflict
;
+ };
+};
+
+class Merger {
+ private mergeDefinition: MergeDefinition;
+ private logger = logger.scope("Merger");
+ private lastSynced = 0;
+ private key?: SerializedKey;
+ constructor(private readonly db: Database) {
+ this.mergeDefinition = {
+ settings: {
+ threshold: 1000,
+ get: () => this.db.settings.raw,
+ set: (item) => this.db.settings.merge(item),
+ conflict: (_local, remote) => this.db.settings.merge(remote)
+ },
+ note: {
+ get: (id) => this.db.notes.note(id)?.data,
+ set: (item) => this.db.notes.merge(item)
+ },
+ shortcut: {
+ get: (id) => this.db.shortcuts.shortcut(id),
+ set: (item) => this.db.shortcuts.merge(item)
+ },
+ reminder: {
+ get: (id) => this.db.reminders.reminder(id),
+ set: (item) => this.db.reminders.merge(item)
+ },
+ relation: {
+ get: (id) => this.db.relations.relation(id),
+ set: (item) => this.db.relations.merge(item)
+ },
+ tag: {
+ get: (id) => this.db.tags.tag(id),
+ set: (item) => this.db.tags.merge(item)
+ },
+ color: {
+ get: (id) => this.db.colors.color(id),
+ set: (item) => this.db.colors.merge(item)
+ },
+ notebook: {
+ threshold: 1000,
+ get: (id) => this.db.notebooks.notebook(id)?.data,
+ set: (item) => this.db.notebooks.merge(item),
+ conflict: (_local, remote) => this.db.notebooks.merge(remote)
+ },
+ content: {
+ threshold: process.env.NODE_ENV === "test" ? 6 * 1000 : 60 * 1000,
+ get: (id) => this.db.content.raw(id),
+ set: async (item) => {
+ await this.db.content.merge(item);
+ },
+ conflict: async (local, remote) => {
+ if (isDeleted(local) || isDeleted(remote)) {
+ if (remote.dateModified > local.dateModified)
+ await db.content.merge(remote);
+ return;
+ }
+
+ const note = this.db.notes.note(local.noteId);
+ if (!note || !note.data) return;
+
+ // if hashes are equal do nothing
+ if (
+ !note.locked &&
+ (!remote ||
+ !local ||
+ !local.data ||
+ !remote.data ||
+ isHTMLEqual(local.data, remote.data))
+ )
+ return;
+
+ if (note.locked) {
+ // if note is locked or content is deleted we keep the most recent version.
+ if (remote.dateModified > local.dateModified)
+ await this.db.content.merge({ ...remote, id: local.id });
+ } else {
+ // otherwise we trigger the conflicts
+ await this.db.content.merge({ ...local, conflicted: remote });
+ await this.db.notes.add({ id: local.noteId, conflicted: true });
+ await this.db.storage().write("hasConflicts", true);
+ }
+ }
+ },
+ attachment: {
+ set: async (remoteAttachment) => {
+ if (isDeleted(remoteAttachment)) {
+ await this.db.attachments.merge(remoteAttachment);
+ return;
+ }
+
+ const localAttachment = this.db.attachments.attachment(
+ remoteAttachment.metadata.hash
+ );
+ if (
+ localAttachment &&
+ localAttachment.dateUploaded !== remoteAttachment.dateUploaded
+ ) {
+ const noteIds = localAttachment.noteIds.slice();
+ const isRemoved = await this.db.attachments.remove(
+ localAttachment.metadata.hash,
+ true
+ );
+ if (!isRemoved)
+ throw new Error(
+ "Conflict could not be resolved in one of the attachments."
+ );
+ remoteAttachment.noteIds = set.union(
+ remoteAttachment.noteIds,
+ noteIds
+ );
+ }
+ await this.db.attachments.merge(remoteAttachment);
+ }
+ }
+ };
+ }
+
+ async _migrate(deserialized: Item, version: number) {
+ // it is a locked note, bail out.
+ if (isCipher(deserialized) && deserialized.alg && deserialized.cipher)
+ return deserialized;
+
+ return migrateItem(deserialized, version, deserialized.type, this.db);
+ }
+
+ async _deserialize(item: SyncItem, migrate = true) {
+ if (!this.key) throw new Error("User encryption key not found.");
+
+ const decrypted = await this.db.storage().decrypt(this.key, item);
+ if (!decrypted) {
+ throw new Error("Decrypted item cannot be undefined or empty.");
+ }
+
+ const deserialized = JSON.parse(decrypted);
+ deserialized.remote = true;
+ deserialized.synced = true;
+ if (!migrate) return deserialized;
+ await this._migrate(deserialized, item.v);
+ return deserialized;
+ }
+
+ async _mergeItem(
+ syncItem: SyncItem,
+ get: Get,
+ add: Set
+ ) {
+ const remoteItem = (await this._deserialize(syncItem)) as MaybeDeletedItem<
+ ItemMap[TItemType]
+ >;
+ const localItem = await get(remoteItem.id);
+ if (!localItem || remoteItem.dateModified > localItem.dateModified) {
+ await add(remoteItem);
+ return remoteItem;
+ }
+ }
+
+ async _mergeItemWithConflicts(
+ syncItem: SyncItem,
+ get: Get,
+ add: Set,
+ markAsConflicted: Conflict,
+ threshold: number
+ ) {
+ const remoteItem = (await this._deserialize(syncItem)) as MaybeDeletedItem<
+ ItemMap[TItemType]
+ >;
+ const localItem = await get(remoteItem.id);
+
+ if (!localItem || isDeleted(localItem)) {
+ await add(remoteItem);
+ return remoteItem;
+ } else {
+ const isResolved =
+ "dateResolved" in localItem &&
+ localItem.dateResolved === remoteItem.dateModified;
+ const isModified =
+ // the local item is modified if it was changed/modified after the last sync
+ // i.e. it wasn't synced yet.
+ // However, in case a sync is interrupted the local item's date modified will
+ // be ahead of last sync. In that case, we also have to check if the synced flag
+ // is false (it is only false if a user makes edits on the local device).
+ localItem.dateModified > this.lastSynced && !localItem.synced;
+ if (isModified && !isResolved) {
+ // If time difference between local item's edits & remote item's edits
+ // is less than threshold, we shouldn't trigger a merge conflict; instead
+ // we will keep the most recently changed item.
+ const timeDiff =
+ Math.max(remoteItem.dateModified, localItem.dateModified) -
+ Math.min(remoteItem.dateModified, localItem.dateModified);
+
+ if (timeDiff < threshold) {
+ if (remoteItem.dateModified > localItem.dateModified) {
+ await add(remoteItem);
+ return remoteItem;
+ }
+ return;
+ }
+
+ this.logger.info("Conflict detected", {
+ itemId: remoteItem.id,
+ isResolved,
+ isModified,
+ timeDiff,
+ remote: remoteItem.dateModified,
+ local: localItem.dateModified,
+ lastSynced: this.lastSynced
+ });
+
+ await markAsConflicted(localItem, remoteItem);
+ } else if (!isResolved) {
+ await add(remoteItem);
+ return remoteItem;
+ }
+ }
+ }
+
+ async mergeItem(
+ type: TItemType | "vaultKey",
+ item: SyncItem
+ ) {
+ this.lastSynced = await this.db.lastSynced();
+
+ if (!this.key) this.key = await this.db.user.getEncryptionKey();
+ if (!this.key || !this.key.key || !this.key.salt) {
+ EV.publish(EVENTS.userSessionExpired);
+ throw new Error("User encryption key not generated. Please relogin.");
+ }
+
+ if (type === "vaultKey") {
+ await this.db.vault.setKey(await this._deserialize(item, false));
+ return;
+ }
+
+ const definition = this.mergeDefinition[type];
+ if (definition.conflict && definition.get && definition.threshold) {
+ return await this._mergeItemWithConflicts(
+ item,
+ definition.get,
+ definition.set,
+ definition.conflict,
+ definition.threshold
+ );
+ } else if (definition.get && definition.set) {
+ return await this._mergeItem(
+ item,
+ definition.get,
+ definition.set
+ );
+ } else if (!definition.get && !!definition.set) {
+ const remote = await this._deserialize(item);
+ await definition.set(remote);
+ }
+ }
+}
+export default Merger;
diff --git a/packages/core/src/api/sync/sync-queue.js b/packages/core/src/api/sync/sync-queue.js
deleted file mode 100644
index f52fbd2a5..000000000
--- a/packages/core/src/api/sync/sync-queue.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-This file is part of the Notesnook project (https://notesnook.com/)
-
-Copyright (C) 2023 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-import set from "../../utils/set";
-import qclone from "qclone";
-import { logger } from "../../logger";
-
-export class SyncQueue {
- /**
- *
- * @param {import("../../database/storage").default} storage
- */
- constructor(storage) {
- this.storage = storage;
- this.logger = logger.scope("SyncQueue");
- }
-
- async new(data, syncedAt) {
- const itemIds = mapToIds(data);
- const syncData = { itemIds, syncedAt };
- await this.save(syncData);
- return syncData;
- }
-
- async merge(data, syncedAt) {
- const syncQueue = await this.get();
- if (!syncQueue.itemIds) return;
-
- const itemIds = set.union(syncQueue.itemIds, mapToIds(data));
- const syncData = { itemIds, syncedAt };
- await this.save(syncData);
-
- this.logger.info("Ids after merge", { itemIds });
- return syncData;
- }
-
- async dequeue(...ids) {
- const syncQueue = await this.get();
- if (!syncQueue || !syncQueue.itemIds) return;
- const { itemIds } = syncQueue;
- for (let id of ids) {
- const index = itemIds.findIndex((i) => i === id);
- if (index <= -1) continue;
- itemIds.splice(index, 1);
- }
- this.logger.info("Ids after dequeue", { itemIds });
-
- if (itemIds.length <= 0) await this.save(null);
- else await this.save(syncQueue);
- }
-
- /**
- *
- * @returns {Promise<{ itemIds: string[]; syncedAt: number; }>}
- */
- async get() {
- const syncQueue = await this.storage.read("syncQueue");
- if (!syncQueue || syncQueue.itemIds.length <= 0) return {};
- return qclone(syncQueue);
- }
-
- async save(syncQueue) {
- await this.storage.write("syncQueue", syncQueue);
- }
-}
-
-function mapToIds(data) {
- const ids = [];
- const keys = ["attachments", "content", "notes", "notebooks", "settings"];
- for (let key of keys) {
- const array = data[key];
- if (!array || !Array.isArray(array)) continue;
-
- for (let item of array) {
- ids.push(`${key}:${item.id}`);
- }
- }
- return ids;
-}
diff --git a/packages/core/src/api/sync/utils.js b/packages/core/src/api/sync/utils.ts
similarity index 90%
rename from packages/core/src/api/sync/utils.js
rename to packages/core/src/api/sync/utils.ts
index 7ceedf6fb..dd8cace8a 100644
--- a/packages/core/src/api/sync/utils.js
+++ b/packages/core/src/api/sync/utils.ts
@@ -17,12 +17,10 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-function areAllEmpty(obj) {
- for (let key in obj) {
+export function areAllEmpty(obj: Record) {
+ for (const key in obj) {
const value = obj[key];
if (Array.isArray(value) && value.length > 0) return false;
}
return true;
}
-
-export { areAllEmpty };
diff --git a/packages/core/src/api/token-manager.js b/packages/core/src/api/token-manager.ts
similarity index 78%
rename from packages/core/src/api/token-manager.js
rename to packages/core/src/api/token-manager.ts
index d28ddda1c..1d9acc9f4 100644
--- a/packages/core/src/api/token-manager.js
+++ b/packages/core/src/api/token-manager.ts
@@ -22,6 +22,15 @@ import constants from "../utils/constants";
import { EV, EVENTS } from "../common";
import { withTimeout, Mutex } from "async-mutex";
import { logger } from "../logger";
+import { StorageAccessor } from "../interfaces";
+
+type Token = {
+ access_token: string;
+ t: number;
+ expires_in: number;
+ scope: string;
+ refresh_token: string;
+};
const ENDPOINTS = {
token: "/connect/token",
@@ -31,18 +40,12 @@ const ENDPOINTS = {
};
class TokenManager {
- /**
- *
- * @param {import("../database/storage").default} storage
- */
- constructor(storage) {
- this._storage = storage;
- this._refreshTokenMutex = withTimeout(new Mutex(), 10 * 1000);
- this.logger = logger.scope("TokenManager");
- }
+ mutex = withTimeout(new Mutex(), 10 * 1000);
+ logger = logger.scope("TokenManager");
+ constructor(private readonly storage: StorageAccessor) {}
- async getToken(renew = true, forceRenew = false) {
- let token = await this._storage.read("token");
+ async getToken(renew = true, forceRenew = false): Promise {
+ const token = await this.storage().read("token");
if (!token || !token.access_token) return;
this.logger.info("Access token requested", {
@@ -58,13 +61,13 @@ class TokenManager {
return token;
}
- _isTokenExpired(token) {
+ _isTokenExpired(token: Token) {
const { t, expires_in } = token;
const expiryMs = t + expires_in * 1000;
return Date.now() >= expiryMs;
}
- _isTokenRefreshable(token) {
+ _isTokenRefreshable(token: Token) {
const { scope, refresh_token } = token;
if (!refresh_token || !scope) return false;
@@ -81,7 +84,7 @@ class TokenManager {
}
async _refreshToken(forceRenew = false) {
- await this._refreshTokenMutex.runExclusive(async () => {
+ await this.mutex.runExclusive(async () => {
this.logger.info("Refreshing access token");
const token = await this.getToken(false, false);
@@ -116,7 +119,7 @@ class TokenManager {
if (!token) return;
const { access_token } = token;
- await this._storage.remove("token");
+ await this.storage().remove("token");
await http.post(
`${constants.AUTH_HOST}${ENDPOINTS.logout}`,
null,
@@ -124,14 +127,14 @@ class TokenManager {
);
}
- saveToken(tokenResponse) {
+ saveToken(tokenResponse: Omit) {
this.logger.info("Saving new token", tokenResponse);
if (!tokenResponse || !tokenResponse.access_token) return;
- let token = { ...tokenResponse, t: Date.now() };
- return this._storage.write("token", token);
+ const token: Token = { ...tokenResponse, t: Date.now() };
+ return this.storage().write("token", token);
}
- async getAccessTokenFromAuthorizationCode(userId, authCode) {
+ async getAccessTokenFromAuthorizationCode(userId: string, authCode: string) {
return await this.saveToken(
await http.post(`${constants.AUTH_HOST}${ENDPOINTS.temporaryToken}`, {
authorization_code: authCode,
@@ -143,12 +146,15 @@ class TokenManager {
}
export default TokenManager;
-async function getSafeToken(action, errorMessage) {
+async function getSafeToken(action: () => Promise, errorMessage: string) {
try {
return await action();
} catch (e) {
console.error(errorMessage, e);
- if (e.message === "invalid_grant" || e.message === "invalid_client") {
+ if (
+ e instanceof Error &&
+ (e.message === "invalid_grant" || e.message === "invalid_client")
+ ) {
EV.publish(EVENTS.userSessionExpired);
}
throw e;
diff --git a/packages/core/src/api/user-manager.js b/packages/core/src/api/user-manager.ts
similarity index 66%
rename from packages/core/src/api/user-manager.js
rename to packages/core/src/api/user-manager.ts
index db4172128..14841f5f0 100644
--- a/packages/core/src/api/user-manager.js
+++ b/packages/core/src/api/user-manager.ts
@@ -23,6 +23,32 @@ import constants from "../utils/constants";
import TokenManager from "./token-manager";
import { EV, EVENTS } from "../common";
import { HealthCheck } from "./healthcheck";
+import Database from ".";
+import { Cipher, SerializedKey } from "@notesnook/crypto";
+
+export type User = {
+ id: string;
+ email: string;
+ isEmailConfirmed: boolean;
+ salt: string;
+ attachmentsKey?: Cipher<"base64">;
+ mfa: {
+ isEnabled: boolean;
+ primaryMethod: string;
+ secondaryMethod: string;
+ remainingValidCodes: number;
+ };
+ subscription: {
+ appId: 0;
+ cancelURL: string | null;
+ expiry: number;
+ productId: string;
+ provider: 0 | 1 | 2 | 3;
+ start: number;
+ type: 0 | 1 | 2 | 5 | 6 | 7;
+ updateURL: string | null;
+ };
+};
const ENDPOINTS = {
signup: "/users",
@@ -38,26 +64,19 @@ const ENDPOINTS = {
};
class UserManager {
- /**
- *
- * @param {import("../database/storage").default} storage
- * @param {import("../api/index").default} db
- */
- constructor(storage, db) {
- this._storage = storage;
- this._db = db;
- this.tokenManager = new TokenManager(storage);
+ private tokenManager: TokenManager;
+ constructor(private readonly db: Database) {
+ this.tokenManager = new TokenManager(this.db.storage);
- EV.subscribe(EVENTS.userUnauthorized, async (url) => {
- if (
- url.includes("/connect/token") ||
- !(await HealthCheck.isAuthServerHealthy())
- )
- return;
+ EV.subscribe(EVENTS.userUnauthorized, async (url: string) => {
+ if (url.includes("/connect/token") || !(await HealthCheck.auth())) return;
try {
await this.tokenManager._refreshToken(true);
} catch (e) {
- if (e.message === "invalid_grant" || e.message === "invalid_client") {
+ if (
+ e instanceof Error &&
+ (e.message === "invalid_grant" || e.message === "invalid_client")
+ ) {
await this.logout(
false,
`Your token has been revoked. Error: ${e.message}.`
@@ -72,10 +91,10 @@ class UserManager {
if (!user) return;
}
- async signup(email, password) {
+ async signup(email: string, password: string) {
email = email.toLowerCase();
- const hashedPassword = await this._storage.hash(password, email);
+ const hashedPassword = await this.db.storage().hash(password, email);
await http.post(`${constants.API_HOST}${ENDPOINTS.signup}`, {
email,
password: hashedPassword,
@@ -85,7 +104,7 @@ class UserManager {
return await this._login({ email, password, hashedPassword });
}
- async authenticateEmail(email) {
+ async authenticateEmail(email: string) {
if (!email) throw new Error("Email is required.");
email = email.toLowerCase();
@@ -100,7 +119,7 @@ class UserManager {
return result.additional_data;
}
- async authenticateMultiFactorCode(code, method) {
+ async authenticateMultiFactorCode(code: string, method: string) {
if (!code || !method) throw new Error("code & method are required.");
const token = await this.tokenManager.getAccessToken();
@@ -122,10 +141,10 @@ class UserManager {
}
async authenticatePassword(
- email,
- password,
- hashedPassword = null,
- sessionExpired = false
+ email: string,
+ password: string,
+ hashedPassword?: string,
+ sessionExpired?: boolean
) {
if (!email || !password) throw new Error("email & password are required.");
@@ -134,7 +153,7 @@ class UserManager {
email = email.toLowerCase();
if (!hashedPassword) {
- hashedPassword = await this._storage.hash(password, email);
+ hashedPassword = await this.db.storage().hash(password, email);
}
try {
await this.tokenManager.saveToken(
@@ -154,10 +173,10 @@ class UserManager {
if (!user) throw new Error("Unauthorized.");
if (!sessionExpired) {
- await this._storage.write("lastSynced", 0);
+ await this.db.storage().write("lastSynced", 0);
}
- await this._storage.deriveCryptoKey(`_uk_@${user.email}`, {
+ await this.db.storage().deriveCryptoKey(`_uk_@${user.email}`, {
password,
salt: user.salt
});
@@ -168,14 +187,23 @@ class UserManager {
}
}
- /**
- * @private
- */
- async _login({ email, password, hashedPassword, code, method }) {
+ async _login({
+ email,
+ password,
+ hashedPassword,
+ code,
+ method
+ }: {
+ email: string;
+ password: string;
+ hashedPassword?: string;
+ code?: string;
+ method?: string;
+ }) {
email = email && email.toLowerCase();
if (!hashedPassword && password) {
- hashedPassword = await this._storage.hash(password, email);
+ hashedPassword = await this.db.storage().hash(password, email);
}
await this.tokenManager.saveToken(
@@ -191,11 +219,13 @@ class UserManager {
);
const user = await this.fetchUser();
- await this._storage.deriveCryptoKey(`_uk_@${user.email}`, {
+ if (!user) return;
+
+ await this.db.storage().deriveCryptoKey(`_uk_@${user.email}`, {
password,
salt: user.salt
});
- await this._storage.write("lastSynced", 0);
+ await this.db.storage().write("lastSynced", 0);
EV.publish(EVENTS.userLoggedIn, user);
}
@@ -228,33 +258,28 @@ class UserManager {
return true;
}
- async logout(revoke = true, reason) {
+ async logout(revoke = true, reason?: string) {
try {
if (revoke) await this.tokenManager.revokeToken();
} catch (e) {
console.error(e);
} finally {
- await this._storage.clear();
+ await this.db.storage().clear();
EV.publish(EVENTS.userLoggedOut, reason);
EV.publish(EVENTS.appRefreshRequested);
}
}
- setUser(user) {
- if (!user) return;
- return this._storage.write("user", user);
+ setUser(user: User) {
+ return this.db.storage().write("user", user);
}
- /**
- *
- * @returns {Promise}
- */
getUser() {
- return this._storage.read("user");
+ return this.db.storage().read("user");
}
async resetUser(removeAttachments = true) {
- let token = await this.tokenManager.getAccessToken();
+ const token = await this.tokenManager.getAccessToken();
if (!token) return;
await http.post(
`${constants.API_HOST}${ENDPOINTS.resetUser}`,
@@ -264,10 +289,8 @@ class UserManager {
return true;
}
- async updateUser(user) {
- if (!user) return;
-
- let token = await this.tokenManager.getAccessToken();
+ async updateUser(user: User) {
+ const token = await this.tokenManager.getAccessToken();
await http.patch.json(
`${constants.API_HOST}${ENDPOINTS.user}`,
user,
@@ -277,26 +300,23 @@ class UserManager {
await this.setUser(user);
}
- async deleteUser(password) {
- let token = await this.tokenManager.getAccessToken();
- if (!token) return;
+ async deleteUser(password: string) {
+ const token = await this.tokenManager.getAccessToken();
const user = await this.getUser();
+ if (!token || !user) return;
+
await http.post(
`${constants.API_HOST}${ENDPOINTS.deleteUser}`,
- { password: await this._storage.hash(password, user.email) },
+ { password: await this.db.storage().hash(password, user.email) },
token
);
await this.logout(false, "Account deleted.");
return true;
}
- /**
- *
- * @returns {Promise}
- */
- async fetchUser() {
+ async fetchUser(): Promise {
try {
- let token = await this.tokenManager.getAccessToken();
+ const token = await this.tokenManager.getAccessToken();
if (!token) return;
const user = await http.get(
`${constants.API_HOST}${ENDPOINTS.user}`,
@@ -315,15 +335,15 @@ class UserManager {
}
}
- changePassword(oldPassword, newPassword) {
+ changePassword(oldPassword: string, newPassword: string) {
return this._updatePassword("change_password", {
old_password: oldPassword,
new_password: newPassword
});
}
- async changeMarketingConsent(enabled) {
- let token = await this.tokenManager.getAccessToken();
+ async changeMarketingConsent(enabled: boolean) {
+ const token = await this.tokenManager.getAccessToken();
if (!token) return;
await http.patch(
@@ -336,16 +356,16 @@ class UserManager {
);
}
- resetPassword(newPassword) {
+ resetPassword(newPassword: string) {
return this._updatePassword("reset_password", {
new_password: newPassword
});
}
- async getEncryptionKey() {
+ async getEncryptionKey(): Promise {
const user = await this.getUser();
if (!user) return;
- const key = await this._storage.getCryptoKey(`_uk_@${user.email}`);
+ const key = await this.db.storage().getCryptoKey(`_uk_@${user.email}`);
if (!key) return;
return { key, salt: user.salt };
}
@@ -356,39 +376,40 @@ class UserManager {
if (!user) return;
if (!user.attachmentsKey) {
- let token = await this.tokenManager.getAccessToken();
+ const token = await this.tokenManager.getAccessToken();
user = await http.get(`${constants.API_HOST}${ENDPOINTS.user}`, token);
}
+ if (!user) return;
const userEncryptionKey = await this.getEncryptionKey();
if (!userEncryptionKey) return;
if (!user.attachmentsKey) {
- const key = await this._storage.generateRandomKey();
- user.attachmentsKey = await this._storage.encrypt(
- userEncryptionKey,
- JSON.stringify(key)
- );
+ const key = await this.db.crypto().generateRandomKey();
+ user.attachmentsKey = await this.db
+ .storage()
+ .encrypt(userEncryptionKey, JSON.stringify(key));
await this.updateUser(user);
return key;
}
- const plainData = await this._storage.decrypt(
- userEncryptionKey,
- user.attachmentsKey
- );
+ const plainData = await this.db
+ .storage()
+ .decrypt(userEncryptionKey, user.attachmentsKey);
+ if (!plainData) return;
return JSON.parse(plainData);
} catch (e) {
console.error(e);
- throw new Error(
- `Could not get attachments encryption key. Please make sure you have Internet access. Error: ${e.message}`
- );
+ if (e instanceof Error)
+ throw new Error(
+ `Could not get attachments encryption key. Please make sure you have Internet access. Error: ${e.message}`
+ );
}
}
- async sendVerificationEmail(newEmail) {
- let token = await this.tokenManager.getAccessToken();
+ async sendVerificationEmail(newEmail: string) {
+ const token = await this.tokenManager.getAccessToken();
if (!token) return;
await http.post(
`${constants.AUTH_HOST}${ENDPOINTS.verifyUser}`,
@@ -397,7 +418,7 @@ class UserManager {
);
}
- async changeEmail(newEmail, password, code) {
+ async changeEmail(newEmail: string, password: string, code: string) {
const token = await this.tokenManager.getAccessToken();
if (!token) return;
@@ -411,39 +432,47 @@ class UserManager {
{
type: "change_email",
new_email: newEmail,
- password: await this._storage.hash(password, email),
+ password: await this.db.storage().hash(password, email),
verification_code: code
},
token
);
- await this._storage.deriveCryptoKey(`_uk_@${newEmail}`, {
+ await this.db.storage().deriveCryptoKey(`_uk_@${newEmail}`, {
password,
salt: user.salt
});
}
- recoverAccount(email) {
+ recoverAccount(email: string) {
return http.post(`${constants.AUTH_HOST}${ENDPOINTS.recoverAccount}`, {
email,
client_id: "notesnook"
});
}
- async verifyPassword(password) {
+ async verifyPassword(password: string) {
try {
const user = await this.getUser();
- if (!user) return false;
const key = await this.getEncryptionKey();
- const cipher = await this._storage.encrypt(key, "notesnook");
- const plainText = await this._storage.decrypt({ password }, cipher);
+ if (!user || !key) return false;
+
+ const cipher = await this.db.storage().encrypt(key, "notesnook");
+ const plainText = await this.db.storage().decrypt({ password }, cipher);
return plainText === "notesnook";
} catch (e) {
return false;
}
}
- async _updatePassword(type, data) {
+ async _updatePassword(
+ type: "change_password" | "reset_password",
+ data: {
+ new_password: string;
+ old_password?: string;
+ encryptionKey?: SerializedKey;
+ }
+ ) {
const token = await this.tokenManager.getAccessToken();
const user = await this.getUser();
if (!token || !user) throw new Error("You are not logged in.");
@@ -461,31 +490,30 @@ class UserManager {
await this.clearSessions();
- if (data.encryptionKey) await this._db.sync({ type: "fetch", force: true });
+ if (data.encryptionKey) await this.db.sync({ type: "fetch", force: true });
- await this._storage.deriveCryptoKey(`_uk_@${email}`, {
+ await this.db.storage().deriveCryptoKey(`_uk_@${email}`, {
password: new_password,
salt
});
if (!(await this.resetUser(false))) return;
- await this._db.sync({ type: "send", force: true });
+ await this.db.sync({ type: "send", force: true });
if (attachmentsKey) {
const userEncryptionKey = await this.getEncryptionKey();
if (!userEncryptionKey) return;
- user.attachmentsKey = await this._storage.encrypt(
- userEncryptionKey,
- JSON.stringify(attachmentsKey)
- );
+ user.attachmentsKey = await this.db
+ .storage()
+ .encrypt(userEncryptionKey, JSON.stringify(attachmentsKey));
await this.updateUser(user);
}
if (old_password)
- old_password = await this._storage.hash(old_password, email);
+ old_password = await this.db.storage().hash(old_password, email);
if (new_password)
- new_password = await this._storage.hash(new_password, email);
+ new_password = await this.db.storage().hash(new_password, email);
await http.patch(
`${constants.AUTH_HOST}${ENDPOINTS.patchUser}`,
diff --git a/packages/core/src/api/vault.js b/packages/core/src/api/vault.js
deleted file mode 100644
index 8eeb81238..000000000
--- a/packages/core/src/api/vault.js
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-This file is part of the Notesnook project (https://notesnook.com/)
-
-Copyright (C) 2023 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-import { CHECK_IDS, EV, EVENTS, checkIsUserPremium } from "../common";
-import { tinyToTiptap } from "../migrations";
-
-const ERASE_TIME = 1000 * 60 * 30;
-var ERASER_TIMEOUT = null;
-export default class Vault {
- get _password() {
- return this._vaultPassword;
- }
-
- set _password(value) {
- this._vaultPassword = value;
- if (value) {
- this._startEraser();
- }
- }
-
- _startEraser() {
- clearTimeout(ERASER_TIMEOUT);
- ERASER_TIMEOUT = setTimeout(() => {
- this._password = null;
- EV.publish(EVENTS.vaultLocked);
- }, ERASE_TIME);
- }
-
- /**
- *
- * @param {import('./index').default} db
- */
- constructor(db) {
- this._db = db;
- this._storage = db.storage;
- this._key = "svvaads1212#2123";
- this._vaultPassword = null;
- this.ERRORS = {
- noVault: "ERR_NO_VAULT",
- vaultLocked: "ERR_VAULT_LOCKED",
- wrongPassword: "ERR_WRONG_PASSWORD"
- };
- EV.subscribe(EVENTS.userLoggedOut, () => {
- this._password = null;
- });
- }
-
- get unlocked() {
- return !!this._vaultPassword;
- }
-
- /**
- * Creates a new vault
- * @param {string} password The password
- * @returns {Promise}
- */
- async create(password) {
- if (!(await checkIsUserPremium(CHECK_IDS.vaultAdd))) return;
-
- const vaultKey = await this._getKey();
- if (!vaultKey || !vaultKey.cipher || !vaultKey.iv) {
- const encryptedData = await this._storage.encrypt(
- { password },
- this._key
- );
- await this._setKey(encryptedData);
- this._password = password;
- }
- return true;
- }
-
- /**
- * Unlocks the vault with the given password
- * @param {string} password The password
- * @throws ERR_NO_VAULT | ERR_WRONG_PASSWORD
- * @returns {Promise}
- */
- async unlock(password) {
- const vaultKey = await this._getKey();
- if (!(await this.exists(vaultKey))) throw new Error(this.ERRORS.noVault);
- try {
- await this._storage.decrypt({ password }, vaultKey);
- } catch (e) {
- throw new Error(this.ERRORS.wrongPassword);
- }
- this._password = password;
- return true;
- }
-
- async changePassword(oldPassword, newPassword) {
- if (await this.unlock(oldPassword)) {
- await this._db.notes.init();
-
- const contentItems = [];
- for (const note of this._db.notes.locked) {
- try {
- let encryptedContent = await this._db.content.raw(note.contentId);
- let content = await this.decryptContent(
- encryptedContent,
- oldPassword
- );
- contentItems.push({
- ...content,
- id: note.contentId,
- noteId: note.id
- });
- } catch (e) {
- throw new Error(
- `Could not decrypt content of note ${note.id}. Error: ${e.message}`
- );
- }
- }
-
- for (const content of contentItems) {
- await this._encryptContent(
- content.id,
- null,
- content.data,
- content.type,
- newPassword
- );
- }
-
- await this._storage.remove("vaultKey");
- await this.create(newPassword);
- }
- }
-
- async clear(password) {
- if (await this.unlock(password)) {
- await this._db.notes.init();
- for (var note of this._db.notes.locked) {
- await this._unlockNote(note, password, true);
- }
- }
- }
-
- async delete(deleteAllLockedNotes = false) {
- if (deleteAllLockedNotes) {
- await this._db.notes.init();
- await this._db.notes.remove(
- ...this._db.notes.locked.map((note) => note.id)
- );
- }
- await this._storage.remove("vaultKey");
- this._password = null;
- }
-
- /**
- * Locks (add to vault) a note
- * @param {string} noteId The id of the note to lock
- */
- async add(noteId) {
- if (!(await checkIsUserPremium(CHECK_IDS.vaultAdd))) return;
-
- await this._check();
- await this._lockNote({ id: noteId }, this._password);
- await this._db.noteHistory.clearSessions(noteId);
- }
-
- /**
- * Permanently unlocks (remove from vault) a note
- * @param {string} noteId The note id
- * @param {string} password The password to unlock note with
- */
- async remove(noteId, password) {
- const note = this._db.notes.note(noteId);
- if (!note) return;
- await this._unlockNote(note.data, password, true);
-
- if (!(await this.exists())) await this.create(this.password);
- }
-
- /**
- * Temporarily unlock (open) a note
- * @param {string} noteId The note id
- * @param {string} password The password to open note with
- */
- async open(noteId, password) {
- const note = this._db.notes.note(noteId);
- if (!note) return;
-
- const unlockedNote = await this._unlockNote(note.data, password, false);
- this._password = password;
- if (!(await this.exists())) await this.create(password);
- return unlockedNote;
- }
-
- /**
- * Saves a note in the vault
- * @param {{Object}} note The note to save into the vault
- */
- async save(note) {
- if (!note) return;
- await this._check();
- // roll over erase timer
- this._startEraser();
- return await this._lockNote(note, this._password);
- }
-
- async exists(vaultKey = undefined) {
- if (!vaultKey) vaultKey = await this._getKey();
- return vaultKey && vaultKey.cipher && vaultKey.iv;
- }
-
- // Private & internal methods
-
- /** @private */
- _locked() {
- return !this._password || !this._password.length;
- }
-
- /** @private */
- async _check() {
- if (!(await this.exists())) {
- throw new Error(this.ERRORS.noVault);
- }
-
- if (this._locked()) {
- throw new Error(this.ERRORS.vaultLocked);
- }
- }
-
- /** @private */
- async _encryptContent(contentId, sessionId, content, type, password) {
- let encryptedContent = await this._storage.encrypt(
- { password },
- JSON.stringify(content)
- );
-
- await this._db.content.add({
- id: contentId,
- sessionId,
- data: encryptedContent,
- type
- });
- }
-
- async decryptContent(encryptedContent, password = null) {
- if (!password) {
- await this._check();
- password = this._password;
- }
-
- if (encryptedContent.noteId && typeof encryptedContent.data !== "object") {
- await this._db.notes.add({
- id: encryptedContent.noteId,
- locked: false
- });
- return encryptedContent;
- }
-
- let decryptedContent = await this._storage.decrypt(
- { password },
- encryptedContent.data
- );
-
- const content = {
- type: encryptedContent.type,
- data: JSON.parse(decryptedContent)
- };
-
- // #MIGRATION: convert tiny to tiptap
- if (content.type === "tiny") {
- content.type = "tiptap";
- content.data = tinyToTiptap(content.data);
- }
-
- return content;
- }
-
- /** @private */
- async _lockNote(note, password) {
- let { id, content: { type, data } = {}, sessionId, title } = note;
-
- note = this._db.notes.note(id);
- if (!note) return;
-
- note = note.data;
- const contentId = note.contentId;
- if (!contentId) throw new Error("Cannot lock note because it is empty.");
-
- // Case: when note is being newly locked
- if (!note.locked && (!data || !type)) {
- let content = await this._db.content.raw(contentId, false);
- // NOTE:
- // At this point, the note already has all the attachments extracted
- // so we should just encrypt it as normal.
- data = content.data;
- type = content.type;
- } else if (data && type) {
- const content = await this._db.content.extractAttachments({
- data,
- type,
- noteId: id
- });
- data = content.data;
- type = content.type;
- }
-
- if (data && type)
- await this._encryptContent(contentId, sessionId, data, type, password);
-
- return await this._db.notes.add({
- id,
- locked: true,
- headline: "",
- title: title || note.title,
- favorite: note.favorite,
- localOnly: note.localOnly,
- readonly: note.readonly,
- dateEdited: Date.now()
- });
- }
-
- /** @private */
- async _unlockNote(note, password, perm = false) {
- let encryptedContent = await this._db.content.raw(note.contentId);
- let content = await this.decryptContent(encryptedContent, password);
-
- if (perm) {
- await this._db.notes.add({
- id: note.id,
- locked: false,
- headline: note.headline,
- contentId: note.contentId,
- content
- });
- // await this._db.content.add({ id: note.contentId, data: content });
- return;
- }
-
- return {
- ...note,
- content
- };
- }
-
- /** @inner */
- async _getKey() {
- return await this._storage.read("vaultKey");
- }
-
- /** @inner */
- async _setKey(vaultKey) {
- if (!vaultKey) return;
- await this._storage.write("vaultKey", vaultKey);
- }
-}
diff --git a/packages/core/src/api/vault.ts b/packages/core/src/api/vault.ts
new file mode 100644
index 000000000..c90a0294a
--- /dev/null
+++ b/packages/core/src/api/vault.ts
@@ -0,0 +1,378 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+import { Cipher } from "@notesnook/crypto";
+import Database from ".";
+import { CHECK_IDS, EV, EVENTS, checkIsUserPremium } from "../common";
+import { tinyToTiptap } from "../migrations";
+import { isCipher } from "../database/crypto";
+import { EncryptedContentItem, Note, isDeleted } from "../types";
+import {
+ EMPTY_CONTENT,
+ isEncryptedContent,
+ isUnencryptedContent
+} from "../collections/content";
+import { NoteContent } from "../collections/session-content";
+
+const ERRORS = {
+ noVault: "ERR_NO_VAULT",
+ vaultLocked: "ERR_VAULT_LOCKED",
+ wrongPassword: "ERR_WRONG_PASSWORD"
+};
+const ERASE_TIME = 1000 * 60 * 30;
+export default class Vault {
+ vaultPassword?: string;
+ erasureTimeout = 0;
+ key = "svvaads1212#2123";
+
+ private get password() {
+ return this.vaultPassword;
+ }
+
+ private set password(value) {
+ this.vaultPassword = value;
+ if (value) {
+ this.startEraser();
+ }
+ }
+
+ private startEraser() {
+ clearTimeout(this.erasureTimeout);
+ this.erasureTimeout = setTimeout(() => {
+ this.password = undefined;
+ EV.publish(EVENTS.vaultLocked);
+ }, ERASE_TIME) as unknown as number;
+ }
+
+ constructor(private readonly db: Database) {
+ this.password = undefined;
+ EV.subscribe(EVENTS.userLoggedOut, () => {
+ this.password = undefined;
+ });
+ }
+
+ get unlocked() {
+ return !!this.vaultPassword;
+ }
+
+ async create(password: string) {
+ if (!(await checkIsUserPremium(CHECK_IDS.vaultAdd))) return;
+
+ const vaultKey = await this.getKey();
+ if (!vaultKey || !isCipher(vaultKey)) {
+ const encryptedData = await this.db
+ .storage()
+ .encrypt({ password }, this.key);
+ await this.setKey(encryptedData);
+ this.password = password;
+ }
+ return true;
+ }
+
+ async unlock(password: string) {
+ const vaultKey = await this.getKey();
+ if (!vaultKey || !(await this.exists(vaultKey)))
+ throw new Error(ERRORS.noVault);
+ try {
+ await this.db.storage().decrypt({ password }, vaultKey);
+ } catch (e) {
+ throw new Error(ERRORS.wrongPassword);
+ }
+ this.password = password;
+ return true;
+ }
+
+ async changePassword(oldPassword: string, newPassword: string) {
+ if (await this.unlock(oldPassword)) {
+ const contentItems = [];
+ for (const note of this.db.notes.locked) {
+ if (!note.contentId) continue;
+ const encryptedContent = await this.db.content.raw(note.contentId);
+ if (
+ !encryptedContent ||
+ isDeleted(encryptedContent) ||
+ !isEncryptedContent(encryptedContent)
+ )
+ continue;
+
+ try {
+ const content = await this.decryptContent(
+ encryptedContent,
+ oldPassword
+ );
+ contentItems.push({
+ ...content,
+ id: note.contentId,
+ noteId: note.id
+ });
+ } catch (e) {
+ console.error(e);
+ throw new Error(
+ `Could not decrypt content of note ${note.id}. Error: ${
+ (e as Error).message
+ }`
+ );
+ }
+ }
+
+ for (const content of contentItems) {
+ await this.encryptContent(content, newPassword, content.id);
+ }
+
+ await this.db.storage().remove("vaultKey");
+ await this.create(newPassword);
+ }
+ }
+
+ async clear(password: string) {
+ if (await this.unlock(password)) {
+ await this.db.notes.init();
+ for (const note of this.db.notes.locked) {
+ await this.unlockNote(note, password, true);
+ }
+ }
+ }
+
+ async delete(deleteAllLockedNotes = false) {
+ if (deleteAllLockedNotes) {
+ await this.db.notes.init();
+ await this.db.notes.remove(
+ ...this.db.notes.locked.map((note) => note.id)
+ );
+ }
+ await this.db.storage().remove("vaultKey");
+ this.password = undefined;
+ }
+
+ /**
+ * Locks (add to vault) a note
+ */
+ async add(noteId: string) {
+ if (!(await checkIsUserPremium(CHECK_IDS.vaultAdd))) return;
+
+ await this.lockNote({ id: noteId }, await this.getVaultPassword());
+ await this.db.noteHistory.clearSessions(noteId);
+ }
+
+ /**
+ * Permanently unlocks (remove from vault) a note
+ */
+ async remove(noteId: string, password: string) {
+ const note = this.db.notes.note(noteId);
+ if (!note) return;
+ await this.unlockNote(note.data, password, true);
+
+ if (!(await this.exists())) await this.create(password);
+ }
+
+ /**
+ * Temporarily unlock (open) a note
+ */
+ async open(noteId: string, password: string) {
+ const note = this.db.notes.note(noteId);
+ if (!note) return;
+
+ const unlockedNote = await this.unlockNote(note.data, password, false);
+ this.password = password;
+ if (!(await this.exists())) await this.create(password);
+ return unlockedNote;
+ }
+
+ /**
+ * Saves a note in the vault
+ */
+ async save(
+ note: Partial; sessionId: string }> & {
+ id: string;
+ }
+ ) {
+ if (!note) return;
+ // roll over erase timer
+ this.startEraser();
+ return await this.lockNote(note, await this.getVaultPassword());
+ }
+
+ async exists(vaultKey?: Cipher) {
+ if (!vaultKey) vaultKey = await this.getKey();
+ return vaultKey && isCipher(vaultKey);
+ }
+
+ // Private & internal methods
+
+ private async getVaultPassword() {
+ if (!(await this.exists())) {
+ throw new Error(ERRORS.noVault);
+ }
+
+ if (!this.password || !this.password.length) {
+ throw new Error(ERRORS.vaultLocked);
+ }
+
+ return this.password;
+ }
+
+ private async encryptContent(
+ content: NoteContent,
+ password: string,
+ contentId?: string,
+ sessionId?: string
+ ) {
+ const encryptedContent = await this.db
+ .storage()
+ .encrypt({ password }, JSON.stringify(content.data));
+
+ await this.db.content.add({
+ id: contentId,
+ sessionId,
+ data: encryptedContent,
+ type: content.type
+ });
+ }
+
+ async decryptContent(
+ encryptedContent: EncryptedContentItem,
+ password?: string
+ ) {
+ if (!password) password = await this.getVaultPassword();
+
+ if (
+ encryptedContent.noteId &&
+ typeof encryptedContent.data !== "object" &&
+ !isCipher(encryptedContent.data)
+ ) {
+ await this.db.notes.add({
+ id: encryptedContent.noteId,
+ locked: false
+ });
+ return { data: encryptedContent.data, type: encryptedContent.type };
+ }
+
+ const decryptedContent = await this.db
+ .storage()
+ .decrypt({ password }, encryptedContent.data);
+
+ const content: NoteContent = {
+ type: encryptedContent.type,
+ data: JSON.parse(decryptedContent)
+ };
+
+ // #MIGRATION: convert tiny to tiptap
+ if (content.type === "tiny") {
+ content.type = "tiptap";
+ content.data = tinyToTiptap(content.data);
+ }
+
+ return content;
+ }
+
+ private async lockNote(
+ item: Partial; sessionId: string }> & {
+ id: string;
+ },
+ password: string
+ ) {
+ const { id, content, sessionId, title } = item;
+ let { type, data } = content || {};
+
+ const note = this.db.notes.note(id);
+ if (!note) return;
+
+ const contentId = note.contentId;
+ // if (!contentId) throw new Error("Cannot lock note because it is empty.");
+
+ // Case: when note is being newly locked
+ if (!note.locked && (!data || !type) && !!contentId) {
+ const rawContent = await this.db.content.raw(contentId);
+ if (
+ !rawContent ||
+ isDeleted(rawContent) ||
+ !isUnencryptedContent(rawContent)
+ )
+ return await this.db.notes.add({
+ id,
+ locked: true
+ });
+ // NOTE:
+ // At this point, the note already has all the attachments extracted
+ // so we should just encrypt it as normal.
+ data = rawContent.data;
+ type = rawContent.type;
+ } else if (data && type) {
+ const content = await this.db.content.extractAttachments({
+ ...EMPTY_CONTENT(id),
+ data,
+ type
+ });
+ data = content.data;
+ type = content.type;
+ }
+
+ if (data && type)
+ await this.encryptContent({ data, type }, password, contentId, sessionId);
+
+ return await this.db.notes.add({
+ id,
+ locked: true,
+ headline: "",
+ title: title || note.title,
+ favorite: note.data.favorite,
+ localOnly: note.data.localOnly,
+ readonly: note.data.readonly,
+ dateEdited: Date.now()
+ });
+ }
+
+ private async unlockNote(note: Note, password: string, perm = false) {
+ if (!note.contentId) return;
+
+ const encryptedContent = await this.db.content.raw(note.contentId);
+ if (
+ !encryptedContent ||
+ isDeleted(encryptedContent) ||
+ !isEncryptedContent(encryptedContent)
+ )
+ return;
+ const content = await this.decryptContent(encryptedContent, password);
+
+ if (perm) {
+ await this.db.notes.add({
+ id: note.id,
+ locked: false,
+ headline: note.headline,
+ contentId: note.contentId,
+ content
+ });
+ // await this.db.content.add({ id: note.contentId, data: content });
+ return;
+ }
+
+ return {
+ ...note,
+ content
+ };
+ }
+
+ async getKey() {
+ return await this.db.storage().read("vaultKey");
+ }
+
+ async setKey(vaultKey: Cipher) {
+ await this.db.storage().write("vaultKey", vaultKey);
+ }
+}
diff --git a/packages/core/src/collections/attachments.js b/packages/core/src/collections/attachments.ts
similarity index 54%
rename from packages/core/src/collections/attachments.js
rename to packages/core/src/collections/attachments.ts
index bff5ad0ee..0d48284be 100644
--- a/packages/core/src/collections/attachments.js
+++ b/packages/core/src/collections/attachments.ts
@@ -17,27 +17,54 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import Collection from "./collection";
+import { ICollection } from "./collection";
import { getId } from "../utils/id";
import { deleteItem, hasItem } from "../utils/array";
import { EV, EVENTS } from "../common";
import dataurl from "../utils/dataurl";
import dayjs from "dayjs";
-import setManipulator from "../utils/set";
+import { set } from "../utils/set";
import {
getFileNameWithExtension,
isImage,
isWebClip
} from "../utils/filename";
+import { Cipher, DataFormat, SerializedKey } from "@notesnook/crypto";
+import { CachedCollection } from "../database/cached-collection";
+import { Output } from "../interfaces";
+import {
+ Attachment,
+ AttachmentMetadata,
+ MaybeDeletedItem,
+ isDeleted
+} from "../types";
+import Database from "../api";
-export default class Attachments extends Collection {
- constructor(db, name, cached) {
- super(db, name, cached);
+export class Attachments implements ICollection {
+ name = "attachments";
+ key: Cipher<"base64"> | null = null;
+ private readonly collection: CachedCollection<"attachments", Attachment>;
+ constructor(private readonly db: Database) {
+ this.collection = new CachedCollection(
+ db.storage,
+ "attachments",
+ db.eventManager
+ );
this.key = null;
EV.subscribe(
EVENTS.fileDownloaded,
- async ({ success, filename, groupId, eventData }) => {
+ async ({
+ success,
+ filename,
+ groupId,
+ eventData
+ }: {
+ success: boolean;
+ filename: string;
+ groupId: string;
+ eventData: Record;
+ }) => {
if (!success || !eventData || !eventData.readOnDownload) return;
const attachment = this.attachment(filename);
if (!attachment || !attachment.metadata) return;
@@ -54,29 +81,45 @@ export default class Attachments extends Collection {
}
);
- EV.subscribe(EVENTS.fileUploaded, async ({ success, error, filename }) => {
- const attachment = this.attachment(filename);
- if (!attachment) return;
- if (success) await this.markAsUploaded(attachment.id);
- else
- await this.markAsFailed(
- attachment.id,
- error || "Failed to upload attachment."
- );
- });
+ EV.subscribe(
+ EVENTS.fileUploaded,
+ async ({
+ success,
+ error,
+ filename
+ }: {
+ success: boolean;
+ filename: string;
+ error: string;
+ }) => {
+ const attachment = this.attachment(filename);
+ if (!attachment) return;
+ if (success) await this.markAsUploaded(attachment.id);
+ else
+ await this.markAsFailed(
+ attachment.id,
+ error || "Failed to upload attachment."
+ );
+ }
+ );
}
- merge(localAttachment, remoteAttachment) {
- if (remoteAttachment.deleted) return remoteAttachment;
+ async init() {
+ await this.collection.init();
+ }
+
+ merge(
+ localAttachment: MaybeDeletedItem,
+ remoteAttachment: MaybeDeletedItem
+ ) {
+ if (isDeleted(remoteAttachment)) return remoteAttachment;
if (
- !localAttachment ||
- remoteAttachment.dateModified > localAttachment.dateModified
- )
- return remoteAttachment;
-
- if (localAttachment && localAttachment.noteIds) {
- remoteAttachment.noteIds = setManipulator.union(
+ localAttachment &&
+ !isDeleted(localAttachment) &&
+ localAttachment.noteIds
+ ) {
+ remoteAttachment.noteIds = set.union(
remoteAttachment.noteIds,
localAttachment.noteIds
);
@@ -86,40 +129,33 @@ export default class Attachments extends Collection {
return remoteAttachment;
}
- /**
- *
- * @param {{
- * iv: string,
- * length: number,
- * alg: string,
- * hash: string,
- * hashType: string,
- * filename: string,
- * type: string,
- * salt: string,
- * chunkSize: number,
- * key: {}
- * }} attachmentArg
- * @param {string} noteId Optional as attachments will be parsed at extraction time
- * @returns
- */
- async add(attachmentArg, noteId = undefined) {
- if (!attachmentArg) return console.error("attachment cannot be undefined");
- if (!attachmentArg.hash) throw new Error("Please provide attachment hash.");
+ async add(
+ item: Partial<
+ Omit & {
+ key: SerializedKey;
+ }
+ > & {
+ metadata: Partial & { hash: string };
+ }
+ ) {
+ if (!item) return console.error("attachment cannot be undefined");
+ if (!item.metadata.hash) throw new Error("Please provide attachment hash.");
- const oldAttachment =
- this.all.find((a) => a.metadata?.hash === attachmentArg.hash) || {};
- let id = oldAttachment.id || getId();
-
- const noteIds = oldAttachment.noteIds || [];
- if (noteId && !noteIds.includes(noteId)) noteIds.push(noteId);
+ const oldAttachment = this.all.find(
+ (a) => a.metadata.hash === item.metadata?.hash
+ );
+ const id = oldAttachment?.id || getId();
+ const noteIds = set.union(oldAttachment?.noteIds || [], item.noteIds || []);
+ const encryptedKey = item.key
+ ? await this.encryptKey(item.key)
+ : oldAttachment?.key;
const attachment = {
...oldAttachment,
- ...oldAttachment.metadata,
- ...attachmentArg,
+ ...oldAttachment?.metadata,
+ ...item,
noteIds,
- key: attachmentArg.key || oldAttachment.key
+ key: encryptedKey
};
const {
@@ -154,10 +190,7 @@ export default class Attachments extends Collection {
return;
}
- const encryptedKey = attachmentArg.key
- ? await this._encryptKey(attachmentArg.key)
- : key;
- const attachmentItem = {
+ return this.collection.add({
type: "attachment",
id,
noteIds,
@@ -165,7 +198,7 @@ export default class Attachments extends Collection {
salt,
length,
alg,
- key: encryptedKey,
+ key,
chunkSize,
metadata: {
hash,
@@ -174,36 +207,36 @@ export default class Attachments extends Collection {
type: type || "application/octet-stream"
},
dateCreated: attachment.dateCreated || Date.now(),
- dateModified: attachment.dateModified,
+ dateModified: attachment.dateModified || Date.now(),
dateUploaded: attachment.dateUploaded,
dateDeleted: undefined,
failed: attachment.failed
- };
- return this._collection.addItem(attachmentItem);
+ });
}
async generateKey() {
await this._getEncryptionKey();
- return await this._db.storage.generateRandomKey();
+ return await this.db.crypto().generateRandomKey();
}
- async decryptKey(key) {
+ async decryptKey(key: Cipher<"base64">): Promise {
const encryptionKey = await this._getEncryptionKey();
- const plainData = await this._db.storage.decrypt(encryptionKey, key);
+ const plainData = await this.db.storage().decrypt(encryptionKey, key);
+ if (!plainData) return null;
return JSON.parse(plainData);
}
- async delete(hashOrId, noteId) {
+ async delete(hashOrId: string, noteId: string) {
const attachment = this.attachment(hashOrId);
if (!attachment || !deleteItem(attachment.noteIds, noteId)) return;
if (!attachment.noteIds.length) {
attachment.dateDeleted = Date.now();
EV.publish(EVENTS.attachmentDeleted, attachment);
}
- return await this._collection.updateItem(attachment);
+ return await this.collection.update(attachment);
}
- async remove(hashOrId, localOnly) {
+ async remove(hashOrId: string, localOnly: boolean) {
const attachment = this.attachment(hashOrId);
if (!attachment || !attachment.metadata) return false;
@@ -211,50 +244,46 @@ export default class Attachments extends Collection {
throw new Error("This attachment is inside a locked note.");
if (
- await this._db.fs.deleteFile(
- attachment.metadata.hash,
- localOnly || !attachment.dateUploaded
- )
+ await this.db
+ .fs()
+ .deleteFile(
+ attachment.metadata.hash,
+ localOnly || !attachment.dateUploaded
+ )
) {
if (!localOnly) {
await this.detach(attachment);
}
- await this._collection.removeItem(attachment.id);
+ await this.collection.remove(attachment.id);
return true;
}
return false;
}
- async detach(attachment) {
- await this._db.notes.init();
+ async detach(attachment: Attachment) {
for (const noteId of attachment.noteIds) {
- const note = this._db.notes.note(noteId);
- if (!note) continue;
- const contentId = note.data.contentId;
- await this._db.content.removeAttachments(contentId, [
+ const note = this.db.notes.note(noteId);
+ if (!note || !note.data.contentId) continue;
+ await this.db.content.removeAttachments(note.data.contentId, [
attachment.metadata.hash
]);
}
}
- async _canDetach(attachment) {
- await this._db.notes.init();
+ async _canDetach(attachment: Attachment) {
for (const noteId of attachment.noteIds) {
- const note = this._db.notes.note(noteId);
+ const note = this.db.notes?.note(noteId);
if (note && note.data.locked) return false;
}
return true;
}
- /**
- * Get specified type of attachments of a note
- * @param {string} noteId
- * @param {"files"|"images"|"webclips"|"all"} type
- * @returns {Array}
- */
- ofNote(noteId, type) {
- let attachments = [];
+ ofNote(
+ noteId: string,
+ type: "files" | "images" | "webclips" | "all"
+ ): Attachment[] {
+ let attachments: Attachment[] = [];
if (type === "files") attachments = this.files;
else if (type === "images") attachments = this.images;
@@ -266,86 +295,95 @@ export default class Attachments extends Collection {
);
}
- exists(hash) {
- const attachment = this.all.find((a) => a.metadata?.hash === hash);
+ exists(hash: string) {
+ const attachment = this.all.find((a) => a.metadata.hash === hash);
return !!attachment;
}
- /**
- * @param {string} hash
- * @param {"base64" | "text"} outputType
- * @returns {Promise} dataurl formatted string
- */
- async read(hash, outputType) {
- const attachment = this.all.find((a) => a.metadata?.hash === hash);
+ async read(
+ hash: string,
+ outputType: TOutputFormat
+ ): Promise