From 2f7afa85563da3afa5ae6ac542bae3cdf8eb8397 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Fri, 18 Jul 2025 12:44:45 +0500 Subject: [PATCH 01/19] web: update readonly edited note snapshots for linux & windows --- .../readonly-edited-note-Chromium-linux.txt | 2 +- .../readonly-edited-note-Chromium-win32.txt | 2 +- .../readonly-edited-note-Firefox-win32.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-linux.txt b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-linux.txt index c3b87e7de..e0a7dd5d3 100644 --- a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-linux.txt +++ b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-linux.txt @@ -1 +1 @@ -This is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1An edit I made \ No newline at end of file +An edit I madeThis is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1 diff --git a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-win32.txt b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-win32.txt index c3b87e7de..e0a7dd5d3 100644 --- a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-win32.txt +++ b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-win32.txt @@ -1 +1 @@ -This is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1An edit I made \ No newline at end of file +An edit I madeThis is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1 diff --git a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Firefox-win32.txt b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Firefox-win32.txt index c3b87e7de..8fdeb8f1c 100644 --- a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Firefox-win32.txt +++ b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Firefox-win32.txt @@ -1 +1 @@ -This is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1An edit I made \ No newline at end of file +An edit I madeThis is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1 \ No newline at end of file From 0a0495f1a7cad1f237c9a9f6dc066cec32d59a00 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Fri, 18 Jul 2025 12:51:11 +0500 Subject: [PATCH 02/19] config: include `editor/src/extensions/code-block/languages` to build output --- nx.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nx.json b/nx.json index fb139b23b..c1d0fcfc0 100644 --- a/nx.json +++ b/nx.json @@ -5,7 +5,8 @@ "outputs": [ "{projectRoot}/build", "{projectRoot}/dist", - "{projectRoot}/languages" + "{projectRoot}/languages", + "{projectRoot}/src/extensions/code-block/languages" ], "cache": true }, From be7f8d9916cdd4b3493630221f0b425655100b1e Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Fri, 18 Jul 2025 12:59:04 +0500 Subject: [PATCH 03/19] ci: run tests based on affected files on pr open --- .github/workflows/core.tests.yml | 6 ++++++ .github/workflows/desktop.tests.yml | 6 ++++++ .github/workflows/editor.tests.yml | 6 ++++++ .github/workflows/web.tests.yml | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/.github/workflows/core.tests.yml b/.github/workflows/core.tests.yml index 4e6793a0f..96596e36c 100644 --- a/.github/workflows/core.tests.yml +++ b/.github/workflows/core.tests.yml @@ -10,6 +10,12 @@ on: # re-run workflow if workflow file changes - ".github/workflows/core.tests.yml" pull_request: + branches: + - "master" + paths: + - "packages/core/**" + # re-run workflow if workflow file changes + - ".github/workflows/core.tests.yml" types: - "ready_for_review" - "opened" diff --git a/.github/workflows/desktop.tests.yml b/.github/workflows/desktop.tests.yml index 7067e9e26..02cdc0e08 100644 --- a/.github/workflows/desktop.tests.yml +++ b/.github/workflows/desktop.tests.yml @@ -10,6 +10,12 @@ on: # re-run workflow if workflow file changes - ".github/workflows/desktop.tests.yml" pull_request: + branches: + - "master" + paths: + - "app/desktop/**" + # re-run workflow if workflow file changes + - ".github/workflows/desktop.tests.yml" jobs: build: diff --git a/.github/workflows/editor.tests.yml b/.github/workflows/editor.tests.yml index 3c80f5f91..2bbe003d6 100644 --- a/.github/workflows/editor.tests.yml +++ b/.github/workflows/editor.tests.yml @@ -10,6 +10,12 @@ on: # re-run workflow if workflow file changes - ".github/workflows/editor.tests.yml" pull_request: + branches: + - "master" + paths: + - "packages/editor/**" + # re-run workflow if workflow file changes + - ".github/workflows/editor.tests.yml" types: - "ready_for_review" - "opened" diff --git a/.github/workflows/web.tests.yml b/.github/workflows/web.tests.yml index 1a642f15f..21430f710 100644 --- a/.github/workflows/web.tests.yml +++ b/.github/workflows/web.tests.yml @@ -10,6 +10,12 @@ on: # re-run workflow if workflow file changes - ".github/workflows/web.tests.yml" pull_request: + branches: + - "master" + paths: + - "apps/web/**" + # re-run workflow if workflow file changes + - ".github/workflows/web.tests.yml" types: - "ready_for_review" - "opened" From 249ce1ecbb6d7c12dc3b7bd0bef07bee1eb8d50f Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Fri, 18 Jul 2025 13:02:03 +0500 Subject: [PATCH 04/19] web: remove new line at eof in test snapshots --- .../readonly-edited-note-Chromium-linux.txt | 2 +- .../readonly-edited-note-Chromium-win32.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-linux.txt b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-linux.txt index e0a7dd5d3..8fdeb8f1c 100644 --- a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-linux.txt +++ b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-linux.txt @@ -1 +1 @@ -An edit I madeThis is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1 +An edit I madeThis is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1 \ No newline at end of file diff --git a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-win32.txt b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-win32.txt index e0a7dd5d3..8fdeb8f1c 100644 --- a/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-win32.txt +++ b/apps/web/__e2e__/editor.test.ts-snapshots/readonly-edited-note-Chromium-win32.txt @@ -1 +1 @@ -An edit I madeThis is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1 +An edit I madeThis is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1 \ No newline at end of file From 3bc7fc84f9834c40f13d82b4abbc8e2c9d8bb86c Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Fri, 18 Jul 2025 14:45:06 +0500 Subject: [PATCH 05/19] web: fix `if note is active in multiple tabs, moving the note to trash should close those tabs` test --- apps/web/__e2e__/tabs.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/web/__e2e__/tabs.test.ts b/apps/web/__e2e__/tabs.test.ts index 231ef26ee..0b18756e2 100644 --- a/apps/web/__e2e__/tabs.test.ts +++ b/apps/web/__e2e__/tabs.test.ts @@ -455,6 +455,7 @@ test("if note is active in multiple tabs, moving the note to trash should close title: "Note 1" }); await note?.contextMenu.openInNewTab(); + await page.waitForTimeout(1000); await note?.contextMenu.moveToTrash(); From 85a2d25c1b04d3f4e644b515f9bd47faf85e0e29 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Fri, 18 Jul 2025 15:06:59 +0500 Subject: [PATCH 06/19] web: wait for reminder dialog to close before proceeding in tests --- apps/web/__e2e__/models/utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/web/__e2e__/models/utils.ts b/apps/web/__e2e__/models/utils.ts index e07c46995..aa24381e3 100644 --- a/apps/web/__e2e__/models/utils.ts +++ b/apps/web/__e2e__/models/utils.ts @@ -91,6 +91,7 @@ export async function fillReminderDialog( } await confirmDialog(dialog); + await dialog.waitFor({ state: "hidden" }); } export async function fillItemDialog(page: Page, item: Item) { From e59820e3d6e89ac2d52003ead72e42ea8189a97b Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 19 Jul 2025 08:50:22 +0500 Subject: [PATCH 07/19] web: fix `adding a one-time reminder before current time should not be possible` --- apps/web/__e2e__/reminders.test.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/web/__e2e__/reminders.test.ts b/apps/web/__e2e__/reminders.test.ts index 7e6d3356b..e1c1d7284 100644 --- a/apps/web/__e2e__/reminders.test.ts +++ b/apps/web/__e2e__/reminders.test.ts @@ -53,16 +53,17 @@ test("adding a one-time reminder before current time should not be possible", as await app.goto(); const reminders = await app.goToReminders(); - await reminders.createReminder({ - ...ONE_TIME_REMINDER, - date: 0 - }); - - expect( - await app.toasts.waitForToast( + const result = await Promise.race([ + reminders.createReminder({ + ...ONE_TIME_REMINDER, + date: 0 + }), + app.toasts.waitForToast( "Reminder time cannot be earlier than the current time." ) - ).toBeTruthy(); + ]); + + expect(result).toBeTruthy(); }); for (const recurringMode of ["Daily", "Weekly", "Monthly"] as const) { From 0a607bce182f5ff3cab0e0cf43e60e5342ee2197 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 19 Jul 2025 08:51:29 +0500 Subject: [PATCH 08/19] web: increase app lock test timeouts --- apps/web/__e2e__/models/settings-view.model.ts | 4 ++-- apps/web/__e2e__/models/utils.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/web/__e2e__/models/settings-view.model.ts b/apps/web/__e2e__/models/settings-view.model.ts index 86567e5da..3ba69b6fd 100644 --- a/apps/web/__e2e__/models/settings-view.model.ts +++ b/apps/web/__e2e__/models/settings-view.model.ts @@ -162,9 +162,9 @@ export class SettingsViewModel { await appLockSwitch.click(); await fillPasswordDialog(this.page, userPassword); - await this.page.waitForTimeout(100); + await this.page.waitForTimeout(500); await fillConfirmPasswordDialog(this.page, appLockPassword); - await this.page.waitForTimeout(100); + await this.page.waitForTimeout(500); } async disableAppLock(appLockPassword: string) { diff --git a/apps/web/__e2e__/models/utils.ts b/apps/web/__e2e__/models/utils.ts index aa24381e3..1906c4afa 100644 --- a/apps/web/__e2e__/models/utils.ts +++ b/apps/web/__e2e__/models/utils.ts @@ -134,7 +134,6 @@ export async function fillConfirmPasswordDialog(page: Page, password: string) { export async function confirmDialog(dialog: Locator) { const dialogConfirm = dialog.locator(getTestId("dialog-yes")); await dialogConfirm.click(); - // await dialogConfirm.waitFor({ state: "detached" }); } export async function denyDialog(page: Page) { From 4948a8d7de2dc48db5ea3532dd5a99f3355a68df Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 19 Jul 2025 09:43:23 +0500 Subject: [PATCH 09/19] desktop: add test artifacts cleanup on test finish --- apps/desktop/__tests__/utils.ts | 54 +++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/apps/desktop/__tests__/utils.ts b/apps/desktop/__tests__/utils.ts index 62d254092..d1c2d2eb1 100644 --- a/apps/desktop/__tests__/utils.ts +++ b/apps/desktop/__tests__/utils.ts @@ -18,7 +18,7 @@ along with this program. If not, see . */ import { execSync } from "child_process"; -import { mkdir } from "fs/promises"; +import { mkdir, rm } from "fs/promises"; import { fileURLToPath } from "node:url"; import path from "path"; import { _electron as electron } from "playwright"; @@ -33,6 +33,8 @@ interface AppContext { app: import("playwright").ElectronApplication; page: import("playwright").Page; configPath: string; + userDataDir: string; + outputDir: string; relaunch: () => Promise; } @@ -60,23 +62,37 @@ export async function harness( }); } await ctx.app.close(); + await rm(ctx.userDataDir, { recursive: true, force: true }); + await rm(ctx.outputDir, { recursive: true, force: true }); }); await cb(ctx); } async function buildAndLaunchApp(options?: TestOptions): Promise { - const productName = makeid(10); - const executablePath = await buildApp({ ...options, productName }); - const { app, page, configPath } = await launchApp(executablePath); + const productName = `notesnooktest${makeid(10)}`; + const outputDir = path.join("test-artifacts", `${productName}-output`); + const executablePath = await buildApp({ + ...options, + productName, + outputDir + }); + const { app, page, configPath, userDataDir } = await launchApp( + executablePath + ); const ctx: AppContext = { app, page, configPath, + userDataDir, + outputDir, relaunch: async () => { - const { app, page, configPath } = await launchApp(executablePath); + const { app, page, configPath, userDataDir } = await launchApp( + executablePath + ); ctx.app = app; ctx.page = page; + ctx.userDataDir = userDataDir; ctx.configPath = configPath; } }; @@ -98,53 +114,53 @@ async function launchApp(executablePath: string) { const page = await app.firstWindow(); - const userDataDirectory = await app.evaluate((a) => { + const userDataDir = await app.evaluate((a) => { return a.app.getPath("userData"); }); - const configPath = path.join(userDataDirectory, "config.json"); + const configPath = path.join(userDataDir, "config.json"); return { app, page, - configPath + configPath, + userDataDir }; } async function buildApp({ version, - productName + productName, + outputDir }: { version?: string; productName: string; + outputDir: string; }) { - const buildRoot = path.join("test-artifacts", `${productName}-build`); - const output = path.join("test-artifacts", `${productName}-output`); - execSync(`npm run release -- --root ${buildRoot} --skip-tsc-build`, { - stdio: IS_DEBUG ? "inherit" : "ignore" - }); - const args = [ + "electron-builder", + "--dir", + `--${process.arch}`, `--config electron-builder.config.js`, `--c.extraMetadata.productName=${productName}`, + `--c.compression=store`, "--publish=never" ]; if (version) args.push(`--c.extraMetadata.version=${version}`); - execSync(`npx electron-builder --dir --${process.arch} ${args.join(" ")}`, { + execSync(`npx ${args.join(" ")}`, { stdio: IS_DEBUG ? "inherit" : "ignore", env: { ...process.env, NOTESNOOK_STAGING: "true", - NN_BUILD_ROOT: buildRoot, NN_PRODUCT_NAME: productName, NN_APP_ID: `com.notesnook.test.${productName}`, - NN_OUTPUT_DIR: output + NN_OUTPUT_DIR: outputDir } }); return path.join( __dirname, "..", - output, + outputDir, process.platform === "linux" ? process.arch === "arm64" ? "linux-arm64-unpacked" From ab4092c0887ac48f48c2e54dfc7c4d9ed72cb934 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 19 Jul 2025 09:43:39 +0500 Subject: [PATCH 10/19] desktop: fix dialog skipping in tests --- apps/desktop/__tests__/auto-updates.test.ts | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/apps/desktop/__tests__/auto-updates.test.ts b/apps/desktop/__tests__/auto-updates.test.ts index 6387fdd8c..ef36cbc37 100644 --- a/apps/desktop/__tests__/auto-updates.test.ts +++ b/apps/desktop/__tests__/auto-updates.test.ts @@ -228,19 +228,19 @@ test("downgrade to stable on switching to stable release track", async (t) => { }); async function skipDialog(page: Page) { - await page - .waitForSelector(".ReactModal__Content", { - timeout: 1000 - }) - .catch(() => {}) - .then(async () => { - const positiveButton = page.locator( - "button[data-role='positive-button']" - ); - const negativeButton = page.locator( - "button[data-role='negative-button']" - ); - if (await positiveButton.isVisible()) await positiveButton.click(); - else if (await negativeButton.isVisible()) await negativeButton.click(); - }); + try { + const dialog = page.locator(".ReactModal__Content"); + const positiveButton = dialog.locator( + "button[data-role='positive-button']" + ); + const negativeButton = dialog.locator( + "button[data-role='negative-button']" + ); + if (await positiveButton.isVisible()) + await positiveButton.click({ timeout: 2000 }); + else if (await negativeButton.isVisible()) + await negativeButton.click({ timeout: 2000 }); + } catch (e) { + // ignore error + } } From 69776f26d84b1bdb173a28403f017959577481f0 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 19 Jul 2025 11:01:42 +0500 Subject: [PATCH 11/19] desktop: upgrade to vitest 3 --- apps/desktop/package-lock.json | 1596 ++++++++++++++++++++++++++------ apps/desktop/package.json | 2 +- 2 files changed, 1303 insertions(+), 295 deletions(-) diff --git a/apps/desktop/package-lock.json b/apps/desktop/package-lock.json index d64563965..10d24ae07 100644 --- a/apps/desktop/package-lock.json +++ b/apps/desktop/package-lock.json @@ -40,7 +40,7 @@ "slugify": "1.6.6", "tree-kill": "^1.2.2", "undici": "^7.8.0", - "vitest": "2.1.8" + "vitest": "^3.2.4" }, "optionalDependencies": { "dmg-license": "^1.0.11" @@ -234,7 +234,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", - "dev": true, "license": "MIT", "dependencies": { "debug": "^4.1.1", @@ -617,6 +616,72 @@ "node": ">= 10.0.0" } }, + "node_modules/@electron/windows-sign": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", + "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "cross-dirname": "^0.1.0", + "debug": "^4.3.4", + "fs-extra": "^11.1.1", + "minimist": "^1.2.8", + "postject": "^1.0.0-alpha.6" + }, + "bin": { + "electron-windows-sign": "bin/electron-windows-sign.js" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/windows-sign/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/windows-sign/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/windows-sign/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -906,6 +971,23 @@ "node": ">=12" } }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.7.tgz", + "integrity": "sha512-bwXGEU4ua45+u5Ci/a55B85KWaDSRS8NPOHtxy2e3etDjbz23wlry37Ffzapz69JAGGc4089TBo+dGzydQmydg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/netbsd-x64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", @@ -923,6 +1005,23 @@ "node": ">=12" } }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.7.tgz", + "integrity": "sha512-bTJ50aoC+WDlDGBReWYiObpYvQfMjBNlKztqoNUL0iUkYtwLkBQQeEsTq/I1KyjsKA5tyov6VZaPb8UdD6ci6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/openbsd-x64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", @@ -940,6 +1039,23 @@ "node": ">=12" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.7.tgz", + "integrity": "sha512-5VTtExUrWwHHEUZ/N+rPlHDwVFQ5aME7vRJES8+iQ0xC/bMYckfJ0l2n3yGIfRoXcK/wq4oXSItZAz5wslTKGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", @@ -1131,6 +1247,101 @@ "@jimp/custom": ">=0.3.5" } }, + "node_modules/@jimp/core": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.12.tgz", + "integrity": "sha512-l0RR0dOPyzMKfjUW1uebzueFEDtCOj9fN6pyTYWWOM/VS4BciXQ1VVrJs8pO3kycGYZxncRKhCoygbNr8eEZQA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jimp/utils": "^0.22.12", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "exif-parser": "^0.1.12", + "file-type": "^16.5.4", + "isomorphic-fetch": "^3.0.0", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.6.0" + } + }, + "node_modules/@jimp/core/node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/@jimp/core/node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@jimp/core/node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@jimp/core/node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@jimp/custom": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.12.tgz", + "integrity": "sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jimp/core": "^0.22.12" + } + }, "node_modules/@jimp/utils": { "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz", @@ -1141,9 +1352,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", "dev": true, "license": "MIT" }, @@ -1338,9 +1549,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.2.tgz", - "integrity": "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz", + "integrity": "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==", "cpu": [ "arm" ], @@ -1352,9 +1563,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.2.tgz", - "integrity": "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz", + "integrity": "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==", "cpu": [ "arm64" ], @@ -1366,9 +1577,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.2.tgz", - "integrity": "sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz", + "integrity": "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==", "cpu": [ "arm64" ], @@ -1380,9 +1591,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.2.tgz", - "integrity": "sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz", + "integrity": "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==", "cpu": [ "x64" ], @@ -1394,9 +1605,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.2.tgz", - "integrity": "sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz", + "integrity": "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==", "cpu": [ "arm64" ], @@ -1408,9 +1619,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.2.tgz", - "integrity": "sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz", + "integrity": "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==", "cpu": [ "x64" ], @@ -1422,9 +1633,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.2.tgz", - "integrity": "sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz", + "integrity": "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==", "cpu": [ "arm" ], @@ -1436,9 +1647,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.2.tgz", - "integrity": "sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz", + "integrity": "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==", "cpu": [ "arm" ], @@ -1450,9 +1661,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.2.tgz", - "integrity": "sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz", + "integrity": "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==", "cpu": [ "arm64" ], @@ -1464,9 +1675,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.2.tgz", - "integrity": "sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz", + "integrity": "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==", "cpu": [ "arm64" ], @@ -1478,9 +1689,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.2.tgz", - "integrity": "sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz", + "integrity": "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==", "cpu": [ "loong64" ], @@ -1492,9 +1703,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.2.tgz", - "integrity": "sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz", + "integrity": "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==", "cpu": [ "ppc64" ], @@ -1506,9 +1717,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.2.tgz", - "integrity": "sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz", + "integrity": "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==", "cpu": [ "riscv64" ], @@ -1520,9 +1731,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.2.tgz", - "integrity": "sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz", + "integrity": "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==", "cpu": [ "riscv64" ], @@ -1534,9 +1745,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.2.tgz", - "integrity": "sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz", + "integrity": "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==", "cpu": [ "s390x" ], @@ -1548,9 +1759,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", - "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz", + "integrity": "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==", "cpu": [ "x64" ], @@ -1562,9 +1773,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.2.tgz", - "integrity": "sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz", + "integrity": "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==", "cpu": [ "x64" ], @@ -1576,9 +1787,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.2.tgz", - "integrity": "sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz", + "integrity": "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==", "cpu": [ "arm64" ], @@ -1590,9 +1801,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.2.tgz", - "integrity": "sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz", + "integrity": "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==", "cpu": [ "ia32" ], @@ -1604,9 +1815,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.2.tgz", - "integrity": "sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz", + "integrity": "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==", "cpu": [ "x64" ], @@ -1627,7 +1838,6 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -1650,7 +1860,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, "license": "MIT", "dependencies": { "defer-to-connect": "^2.0.0" @@ -1700,7 +1909,6 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, "license": "MIT", "dependencies": { "@types/http-cache-semantics": "*", @@ -1709,6 +1917,16 @@ "@types/responselike": "^1.0.0" } }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -1719,10 +1937,17 @@ "@types/ms": "*" } }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -1740,14 +1965,12 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "dev": true, "license": "MIT" }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -1764,7 +1987,6 @@ "version": "22.15.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz", "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", - "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -1785,7 +2007,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -1819,7 +2040,6 @@ "version": "2.10.3", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -1827,38 +2047,39 @@ } }, "node_modules/@vitest/expect": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.8.tgz", - "integrity": "sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.8", - "@vitest/utils": "2.1.8", - "chai": "^5.1.2", - "tinyrainbow": "^1.2.0" + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.8.tgz", - "integrity": "sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.8", + "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", - "magic-string": "^0.30.12" + "magic-string": "^0.30.17" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "peerDependenciesMeta": { "msw": { @@ -1870,96 +2091,71 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", - "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^1.2.0" + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.8.tgz", - "integrity": "sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "2.1.8", - "pathe": "^1.1.2" + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.8.tgz", - "integrity": "sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.8", - "magic-string": "^0.30.12", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", - "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^1.2.0" + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.8.tgz", - "integrity": "sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^3.0.2" + "tinyspy": "^4.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.8.tgz", - "integrity": "sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.8", - "loupe": "^3.1.2", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils/node_modules/@vitest/pretty-format": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", - "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^1.2.0" + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -1989,6 +2185,19 @@ "dev": true, "license": "ISC" }, + "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", + "peer": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/agent-base": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", @@ -2077,6 +2286,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", + "license": "MIT", + "peer": true + }, "node_modules/app-builder-bin": { "version": "5.0.0-alpha.12", "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz", @@ -2323,7 +2539,6 @@ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, "license": "MIT", "optional": true }, @@ -2365,7 +2580,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, "license": "MIT", "engines": { "node": "*" @@ -2543,7 +2757,6 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10.6.0" @@ -2553,7 +2766,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, "license": "MIT", "dependencies": { "clone-response": "^1.0.2", @@ -2583,9 +2795,9 @@ } }, "node_modules/chai": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", - "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", + "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==", "dev": true, "license": "MIT", "dependencies": { @@ -2596,7 +2808,7 @@ "pathval": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/chalk": { @@ -2756,7 +2968,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, "license": "MIT", "dependencies": { "mimic-response": "^1.0.0" @@ -2898,6 +3109,15 @@ "buffer": "^5.1.0" } }, + "node_modules/cross-dirname": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cross-dirname/-/cross-dirname-0.1.0.tgz", + "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -3032,7 +3252,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -3042,7 +3261,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -3061,7 +3279,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -3099,7 +3316,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, "license": "MIT", "optional": true }, @@ -3291,7 +3507,6 @@ "version": "34.5.6", "resolved": "https://registry.npmjs.org/electron/-/electron-34.5.6.tgz", "integrity": "sha512-cmP0CDnWFwyZrzn72AXS9oJiOjNIRPgKpGO2ykz3Syo+9B2RJ9WQzxOKkpntcWE5/nRsyFkRUCMTgGo3uNvCxQ==", - "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -3332,6 +3547,19 @@ "node": ">=14.0.0" } }, + "node_modules/electron-builder-squirrel-windows": { + "version": "26.0.12", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.0.12.tgz", + "integrity": "sha512-kpwXM7c/ayRUbYVErQbsZ0nQZX4aLHQrPEG9C4h9vuJCXylwFH8a7Jgi2VpKIObzCXO7LKHiCw4KdioFLFOgqA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "app-builder-lib": "26.0.12", + "builder-util": "26.0.11", + "electron-winstaller": "5.4.0" + } + }, "node_modules/electron-builder/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -3502,11 +3730,48 @@ "node": ">= 10.0.0" } }, + "node_modules/electron-winstaller": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.4.0.tgz", + "integrity": "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@electron/asar": "^3.2.1", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "lodash": "^4.17.21", + "temp": "^0.9.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "@electron/windows-sign": "^1.1.2" + } + }, + "node_modules/electron-winstaller/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/electron/node_modules/@types/node": { "version": "20.17.47", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.47.tgz", "integrity": "sha512-3dLX0Upo1v7RvUimvxLeXqwrfyKxUINk0EAM83swP2mlSUcwV73sZy8XhNz8bcZ3VbsfQyC/y6jRdL5tgCNpDQ==", - "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.19.2" @@ -3516,7 +3781,6 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, "license": "MIT" }, "node_modules/emoji-regex": { @@ -3529,7 +3793,6 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -3549,7 +3812,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3566,7 +3828,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3576,7 +3838,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3622,7 +3884,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, "license": "MIT", "optional": true }, @@ -3678,7 +3939,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -3698,6 +3958,32 @@ "@types/estree": "^1.0.0" } }, + "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", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==", + "peer": true + }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -3728,7 +4014,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "debug": "^4.1.1", @@ -3773,12 +4058,26 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, "license": "MIT", "dependencies": { "pend": "~1.2.0" } }, + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/file-type": { "version": "19.6.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-19.6.0.tgz", @@ -3898,7 +4197,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -4006,7 +4304,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, "license": "MIT", "dependencies": { "pump": "^3.0.0" @@ -4074,7 +4371,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, "license": "BSD-3-Clause", "optional": true, "dependencies": { @@ -4093,7 +4389,6 @@ "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, "license": "ISC", "optional": true, "bin": { @@ -4107,7 +4402,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -4125,7 +4419,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4138,7 +4432,6 @@ "version": "11.8.6", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, "license": "MIT", "dependencies": { "@sindresorhus/is": "^4.0.0", @@ -4180,7 +4473,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -4249,7 +4541,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "dev": true, "license": "BSD-2-Clause" }, "node_modules/http-proxy-agent": { @@ -4270,7 +4561,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, "license": "MIT", "dependencies": { "quick-lru": "^5.1.1", @@ -4342,7 +4632,7 @@ "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, + "devOptional": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -4520,6 +4810,17 @@ "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==", + "license": "MIT", + "peer": true, + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -4591,6 +4892,13 @@ "integrity": "sha512-5obBtsz9301ULlsgggLg542s/jqtddfOpV5KJc4hajc9JV8GeY2gZHSVpYBn4nWqAUTJ9v+xwtbJ1mIBgIH5Vw==", "license": "MIT" }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -4614,7 +4922,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { @@ -4628,7 +4935,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, "license": "ISC", "optional": true }, @@ -4649,7 +4955,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -4659,7 +4964,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" @@ -4709,9 +5013,9 @@ } }, "node_modules/loupe": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", - "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz", + "integrity": "sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==", "dev": true, "license": "MIT" }, @@ -4719,7 +5023,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4832,7 +5135,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -4902,7 +5204,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -5152,6 +5453,27 @@ "node": ">=10" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "peer": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", @@ -5184,7 +5506,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -5210,7 +5531,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -5270,7 +5590,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5370,16 +5689,16 @@ } }, "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, "node_modules/pathval": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", - "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { @@ -5418,7 +5737,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, "license": "MIT" }, "node_modules/picocolors": { @@ -5428,6 +5746,42 @@ "dev": true, "license": "ISC" }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pixelmatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", + "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", + "license": "ISC", + "peer": true, + "dependencies": { + "pngjs": "^3.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/pixelmatch/node_modules/pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/playwright": { "version": "1.48.2", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", @@ -5485,9 +5839,9 @@ } }, "node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -5505,7 +5859,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -5513,6 +5867,36 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postject": { + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", + "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "commander": "^9.4.0" + }, + "bin": { + "postject": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/postject/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, "node_modules/prebuild-install": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", @@ -5617,11 +6001,20 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -5672,7 +6065,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -5723,6 +6115,65 @@ "node": ">= 6" } }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", + "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": "^4.7.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "peer": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -5774,14 +6225,12 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true, "license": "MIT" }, "node_modules/responselike": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, "license": "MIT", "dependencies": { "lowercase-keys": "^2.0.0" @@ -5835,7 +6284,6 @@ "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, "license": "BSD-3-Clause", "optional": true, "dependencies": { @@ -5851,13 +6299,13 @@ } }, "node_modules/rollup": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.2.tgz", - "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.1.tgz", + "integrity": "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.7" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -5867,26 +6315,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.40.2", - "@rollup/rollup-android-arm64": "4.40.2", - "@rollup/rollup-darwin-arm64": "4.40.2", - "@rollup/rollup-darwin-x64": "4.40.2", - "@rollup/rollup-freebsd-arm64": "4.40.2", - "@rollup/rollup-freebsd-x64": "4.40.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.40.2", - "@rollup/rollup-linux-arm-musleabihf": "4.40.2", - "@rollup/rollup-linux-arm64-gnu": "4.40.2", - "@rollup/rollup-linux-arm64-musl": "4.40.2", - "@rollup/rollup-linux-loongarch64-gnu": "4.40.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.40.2", - "@rollup/rollup-linux-riscv64-gnu": "4.40.2", - "@rollup/rollup-linux-riscv64-musl": "4.40.2", - "@rollup/rollup-linux-s390x-gnu": "4.40.2", - "@rollup/rollup-linux-x64-gnu": "4.40.2", - "@rollup/rollup-linux-x64-musl": "4.40.2", - "@rollup/rollup-win32-arm64-msvc": "4.40.2", - "@rollup/rollup-win32-ia32-msvc": "4.40.2", - "@rollup/rollup-win32-x64-msvc": "4.40.2", + "@rollup/rollup-android-arm-eabi": "4.45.1", + "@rollup/rollup-android-arm64": "4.45.1", + "@rollup/rollup-darwin-arm64": "4.45.1", + "@rollup/rollup-darwin-x64": "4.45.1", + "@rollup/rollup-freebsd-arm64": "4.45.1", + "@rollup/rollup-freebsd-x64": "4.45.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.45.1", + "@rollup/rollup-linux-arm-musleabihf": "4.45.1", + "@rollup/rollup-linux-arm64-gnu": "4.45.1", + "@rollup/rollup-linux-arm64-musl": "4.45.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.45.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1", + "@rollup/rollup-linux-riscv64-gnu": "4.45.1", + "@rollup/rollup-linux-riscv64-musl": "4.45.1", + "@rollup/rollup-linux-s390x-gnu": "4.45.1", + "@rollup/rollup-linux-x64-gnu": "4.45.1", + "@rollup/rollup-linux-x64-musl": "4.45.1", + "@rollup/rollup-win32-arm64-msvc": "4.45.1", + "@rollup/rollup-win32-ia32-msvc": "4.45.1", + "@rollup/rollup-win32-x64-msvc": "4.45.1", "fsevents": "~2.3.2" } }, @@ -5924,7 +6372,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/sanitize-filename": { @@ -5947,7 +6395,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -5957,7 +6404,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, "license": "MIT", "optional": true }, @@ -5965,7 +6411,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -6200,7 +6645,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause" }, "node_modules/sqlite-better-trigram": { @@ -6498,6 +6943,19 @@ "node": ">=0.10.0" } }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/strtok3": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-9.1.1.tgz", @@ -6519,7 +6977,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, "license": "Apache-2.0", "dependencies": { "debug": "^4.1.0" @@ -6603,6 +7060,21 @@ "node": ">=8" } }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/temp-file": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", @@ -6652,6 +7124,35 @@ "node": ">= 10.0.0" } }, + "node_modules/temp/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/tiny-async-pool": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz", @@ -6685,6 +7186,13 @@ "dev": true, "license": "MIT" }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "license": "MIT", + "peer": true + }, "node_modules/tinyexec": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", @@ -6692,10 +7200,27 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/tinypool": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", - "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "dev": true, "license": "MIT", "engines": { @@ -6703,9 +7228,9 @@ } }, "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", "dev": true, "license": "MIT", "engines": { @@ -6713,9 +7238,9 @@ } }, "node_modules/tinyspy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", - "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", + "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", "dev": true, "license": "MIT", "engines": { @@ -6768,6 +7293,13 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT", + "peer": true + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -6811,7 +7343,6 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, "license": "(MIT OR CC0-1.0)", "optional": true, "engines": { @@ -6870,7 +7401,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "devOptional": true, "license": "MIT" }, "node_modules/unique-filename": { @@ -6903,7 +7433,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 4.0.0" @@ -6954,21 +7483,24 @@ } }, "node_modules/vite": { - "version": "5.4.19", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", - "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.5.tgz", + "integrity": "sha512-1mncVwJxy2C9ThLwz0+2GKZyEXuC3MyWtAAlNftlZZXZDP3AJt5FmwcMit/IGGaNZ8ZOB2BNO/HFUB+CpN0NQw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.25.0", + "fdir": "^6.4.6", + "picomatch": "^4.0.2", + "postcss": "^8.5.6", + "rollup": "^4.40.0", + "tinyglobby": "^0.2.14" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -6977,19 +7509,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -7010,32 +7548,471 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, "node_modules/vite-node": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.8.tgz", - "integrity": "sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.3.7", - "es-module-lexer": "^1.5.4", - "pathe": "^1.1.2", - "vite": "^5.0.0" + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.7.tgz", + "integrity": "sha512-uD0kKFHh6ETr8TqEtaAcV+dn/2qnYbH/+8wGEdY70Qf7l1l/jmBUbrmQqwiPKAQE6cOQ7dTj6Xr0HzQDGHyceQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.7.tgz", + "integrity": "sha512-Jhuet0g1k9rAJHrXGIh7sFknFuT4sfytYZpZpuZl7YKDhnPByVAm5oy2LEBmMbuYf3ejWVYCc2seX81Mk+madA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.7.tgz", + "integrity": "sha512-p0ohDnwyIbAtztHTNUTzN5EGD/HJLs1bwysrOPgSdlIA6NDnReoVfoCyxG6W1d85jr2X80Uq5KHftyYgaK9LPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.7.tgz", + "integrity": "sha512-mMxIJFlSgVK23HSsII3ZX9T2xKrBCDGyk0qiZnIW10LLFFtZLkFD6imZHu7gUo2wkNZwS9Yj3mOtZD3ZPcjCcw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.7.tgz", + "integrity": "sha512-jyOFLGP2WwRwxM8F1VpP6gcdIJc8jq2CUrURbbTouJoRO7XCkU8GdnTDFIHdcifVBT45cJlOYsZ1kSlfbKjYUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.7.tgz", + "integrity": "sha512-m9bVWqZCwQ1BthruifvG64hG03zzz9gE2r/vYAhztBna1/+qXiHyP9WgnyZqHgGeXoimJPhAmxfbeU+nMng6ZA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.7.tgz", + "integrity": "sha512-Bss7P4r6uhr3kDzRjPNEnTm/oIBdTPRNQuwaEFWT/uvt6A1YzK/yn5kcx5ZxZ9swOga7LqeYlu7bDIpDoS01bA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.7.tgz", + "integrity": "sha512-S3BFyjW81LXG7Vqmr37ddbThrm3A84yE7ey/ERBlK9dIiaWgrjRlre3pbG7txh1Uaxz8N7wGGQXmC9zV+LIpBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.7.tgz", + "integrity": "sha512-JZMIci/1m5vfQuhKoFXogCKVYVfYQmoZJg8vSIMR4TUXbF+0aNlfXH3DGFEFMElT8hOTUF5hisdZhnrZO/bkDw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.7.tgz", + "integrity": "sha512-HfQZQqrNOfS1Okn7PcsGUqHymL1cWGBslf78dGvtrj8q7cN3FkapFgNA4l/a5lXDwr7BqP2BSO6mz9UremNPbg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.7.tgz", + "integrity": "sha512-9Jex4uVpdeofiDxnwHRgen+j6398JlX4/6SCbbEFEXN7oMO2p0ueLN+e+9DdsdPLUdqns607HmzEFnxwr7+5wQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.7.tgz", + "integrity": "sha512-TG1KJqjBlN9IHQjKVUYDB0/mUGgokfhhatlay8aZ/MSORMubEvj/J1CL8YGY4EBcln4z7rKFbsH+HeAv0d471w==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.7.tgz", + "integrity": "sha512-Ty9Hj/lx7ikTnhOfaP7ipEm/ICcBv94i/6/WDg0OZ3BPBHhChsUbQancoWYSO0WNkEiSW5Do4febTTy4x1qYQQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.7.tgz", + "integrity": "sha512-MrOjirGQWGReJl3BNQ58BLhUBPpWABnKrnq8Q/vZWWwAB1wuLXOIxS2JQ1LT3+5T+3jfPh0tyf5CpbyQHqnWIQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.7.tgz", + "integrity": "sha512-9pr23/pqzyqIZEZmQXnFyqp3vpa+KBk5TotfkzGMqpw089PGm0AIowkUppHB9derQzqniGn3wVXgck19+oqiOw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.7.tgz", + "integrity": "sha512-4dP11UVGh9O6Y47m8YvW8eoA3r8qL2toVZUbBKyGta8j6zdw1cn9F/Rt59/Mhv0OgY68pHIMjGXWOUaykCnx+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.7.tgz", + "integrity": "sha512-ghJMAJTdw/0uhz7e7YnpdX1xVn7VqA0GrWrAO2qKMuqbvgHT2VZiBv1BQ//VcHsPir4wsL3P2oPggfKPzTKoCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.7.tgz", + "integrity": "sha512-tUZRvLtgLE5OyN46sPSYlgmHoBS5bx2URSrgZdW1L1teWPYVmXh+QN/sKDqkzBo/IHGcKcHLKDhBeVVkO7teEA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.7.tgz", + "integrity": "sha512-TA9XfJrgzAipFUU895jd9j2SyDh9bbNkK2I0gHcvqb/o84UeQkBpi/XmYX3cO1q/9hZokdcDqQxIi6uLVrikxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.7.tgz", + "integrity": "sha512-umkbn7KTxsexhv2vuuJmj9kggd4AEtL32KodkJgfhNOHMPtQ55RexsaSrMb+0+jp9XL4I4o2y91PZauVN4cH3A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.7.tgz", + "integrity": "sha512-j20JQGP/gz8QDgzl5No5Gr4F6hurAZvtkFxAKhiv2X49yi/ih8ECK4Y35YnjlMogSKJk931iNMcd35BtZ4ghfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.7.tgz", + "integrity": "sha512-4qZ6NUfoiiKZfLAXRsvFkA0hoWVM+1y2bSHXHkpdLAs/+r0LgwqYohmfZCi985c6JWHhiXP30mgZawn/XrqAkQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.7.tgz", + "integrity": "sha512-FaPsAHTwm+1Gfvn37Eg3E5HIpfR3i6x1AIcla/MkqAIupD4BW3MrSeUqfoTzwwJhk3WE2/KqUn4/eenEJC76VA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.7.tgz", + "integrity": "sha512-daJB0q2dmTzo90L9NjRaohhRWrCzYxWNFTjEi72/h+p5DcY3yn4MacWfDakHmaBaDzDiuLJsCh0+6LK/iX+c+Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.7", + "@esbuild/android-arm": "0.25.7", + "@esbuild/android-arm64": "0.25.7", + "@esbuild/android-x64": "0.25.7", + "@esbuild/darwin-arm64": "0.25.7", + "@esbuild/darwin-x64": "0.25.7", + "@esbuild/freebsd-arm64": "0.25.7", + "@esbuild/freebsd-x64": "0.25.7", + "@esbuild/linux-arm": "0.25.7", + "@esbuild/linux-arm64": "0.25.7", + "@esbuild/linux-ia32": "0.25.7", + "@esbuild/linux-loong64": "0.25.7", + "@esbuild/linux-mips64el": "0.25.7", + "@esbuild/linux-ppc64": "0.25.7", + "@esbuild/linux-riscv64": "0.25.7", + "@esbuild/linux-s390x": "0.25.7", + "@esbuild/linux-x64": "0.25.7", + "@esbuild/netbsd-arm64": "0.25.7", + "@esbuild/netbsd-x64": "0.25.7", + "@esbuild/openbsd-arm64": "0.25.7", + "@esbuild/openbsd-x64": "0.25.7", + "@esbuild/openharmony-arm64": "0.25.7", + "@esbuild/sunos-x64": "0.25.7", + "@esbuild/win32-arm64": "0.25.7", + "@esbuild/win32-ia32": "0.25.7", + "@esbuild/win32-x64": "0.25.7" + } + }, "node_modules/vite/node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -7052,47 +8029,51 @@ } }, "node_modules/vitest": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.8.tgz", - "integrity": "sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "2.1.8", - "@vitest/mocker": "2.1.8", - "@vitest/pretty-format": "^2.1.8", - "@vitest/runner": "2.1.8", - "@vitest/snapshot": "2.1.8", - "@vitest/spy": "2.1.8", - "@vitest/utils": "2.1.8", - "chai": "^5.1.2", - "debug": "^4.3.7", - "expect-type": "^1.1.0", - "magic-string": "^0.30.12", - "pathe": "^1.1.2", - "std-env": "^3.8.0", + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", "tinybench": "^2.9.0", - "tinyexec": "^0.3.1", - "tinypool": "^1.0.1", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.1.8", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.8", - "@vitest/ui": "2.1.8", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, @@ -7100,6 +8081,9 @@ "@edge-runtime/vm": { "optional": true }, + "@types/debug": { + "optional": true + }, "@types/node": { "optional": true }, @@ -7127,6 +8111,31 @@ "defaults": "^1.0.3" } }, + "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", + "peer": true + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT", + "peer": true + }, + "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", + "peer": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7259,7 +8268,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 9710f5caa..0216fa02b 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -55,7 +55,7 @@ "slugify": "1.6.6", "tree-kill": "^1.2.2", "undici": "^7.8.0", - "vitest": "2.1.8" + "vitest": "^3.2.4" }, "optionalDependencies": { "dmg-license": "^1.0.11" From fe1e3bb84763f973ff5629b0ad00aa20b3a6817a Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 19 Jul 2025 11:01:57 +0500 Subject: [PATCH 12/19] desktop: migrate tests to vitest 3 --- apps/desktop/__tests__/auto-updates.test.ts | 348 ++++++++++---------- apps/desktop/__tests__/launch.test.ts | 30 +- apps/desktop/__tests__/utils.ts | 45 +-- 3 files changed, 212 insertions(+), 211 deletions(-) diff --git a/apps/desktop/__tests__/auto-updates.test.ts b/apps/desktop/__tests__/auto-updates.test.ts index ef36cbc37..cab7a2ca0 100644 --- a/apps/desktop/__tests__/auto-updates.test.ts +++ b/apps/desktop/__tests__/auto-updates.test.ts @@ -17,214 +17,210 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -import { test } from "vitest"; -import { harness } from "./utils.js"; +import { test, testCleanup } from "./utils.js"; import { writeFile } from "fs/promises"; import { Page } from "playwright"; import { gt, lt } from "semver"; +import { describe } from "vitest"; -test("update starts downloading if version is outdated", async (t) => { - await harness( - t, - async ({ page }) => { - await page.waitForSelector("#authForm"); +test("update starts downloading if version is outdated", async ({ + ctx: { page }, + expect, + onTestFinished +}) => { + onTestFinished(testCleanup); - t.expect( - await page.getByRole("button", { name: "Create account" }).isVisible() - ).toBe(true); + await page.waitForSelector("#authForm"); + expect( + await page.getByRole("button", { name: "Create account" }).isVisible() + ).toBe(true); - await page - .getByRole("button", { name: "Skip & go directly to the app" }) - .click(); + await page + .getByRole("button", { name: "Skip & go directly to the app" }) + .click(); - await skipDialog(page); + await skipDialog(page); - await page.waitForSelector(".ProseMirror"); + await page.waitForSelector(".ProseMirror"); - await page - .locator(".theme-scope-statusBar") - .getByRole("button", { name: /updating/i }) - .waitFor({ state: "attached" }); - }, - { version: "3.0.0" } - ); + await page + .locator(".theme-scope-statusBar") + .getByRole("button", { name: /updating/i }) + .waitFor({ state: "attached" }); }); -test("update is only shown if version is outdated and auto updates are disabled", async (t) => { - await harness( - t, - async (ctx) => { - await ctx.app.close(); - await writeFile( - ctx.configPath, - JSON.stringify({ - automaticUpdates: false - }) - ); +test("update is only shown if version is outdated and auto updates are disabled", async ({ + ctx, + expect, + onTestFinished +}) => { + onTestFinished(testCleanup); - await ctx.relaunch(); + await ctx.app.close(); + await writeFile( + ctx.configPath, + JSON.stringify({ + automaticUpdates: false + }) + ); - const { page } = ctx; + await ctx.relaunch(); - await page.waitForSelector("#authForm"); + const { page } = ctx; - t.expect( - await page.getByRole("button", { name: "Create account" }).isVisible() - ).toBe(true); + await page.waitForSelector("#authForm"); - await page - .getByRole("button", { name: "Skip & go directly to the app" }) - .click(); + expect( + await page.getByRole("button", { name: "Create account" }).isVisible() + ).toBe(true); - await skipDialog(page); + await page + .getByRole("button", { name: "Skip & go directly to the app" }) + .click(); - await page.waitForSelector(".ProseMirror"); + await skipDialog(page); + await page.waitForSelector(".ProseMirror"); + + await page + .locator(".theme-scope-statusBar") + .getByRole("button", { name: /available/i }) + .waitFor({ state: "attached" }); +}); + +describe("update to stable if it is newer", () => { + test.scoped({ options: { version: "3.0.0-beta.0" } }); + test("test", async ({ ctx, expect, onTestFinished }) => { + onTestFinished(testCleanup); + + await ctx.app.close(); + await writeFile( + ctx.configPath, + JSON.stringify({ + automaticUpdates: false, + releaseTrack: "beta" + }) + ); + + await ctx.relaunch(); + + const { page } = ctx; + + await page.waitForSelector("#authForm"); + + expect( + await page.getByRole("button", { name: "Create account" }).isVisible() + ).toBe(true); + + await page + .getByRole("button", { name: "Skip & go directly to the app" }) + .click(); + + await skipDialog(page); + + await page.waitForSelector(".ProseMirror"); + + const updateButton = page + .locator(".theme-scope-statusBar") + .getByRole("button", { name: /available/i }); + await updateButton.waitFor({ state: "visible" }); + const content = await updateButton.textContent(); + const version = content?.split(" ")?.[0] || ""; + expect(gt(version, "3.0.0-beta.0")).toBe(true); + }); +}); + +describe("update is not available if it latest stable version is older", () => { + test.scoped({ options: { version: "99.0.0-beta.0" } }); + test("test", async ({ ctx, expect, onTestFinished }) => { + onTestFinished(testCleanup); + + await ctx.app.close(); + await writeFile( + ctx.configPath, + JSON.stringify({ + automaticUpdates: false, + releaseTrack: "beta" + }) + ); + + await ctx.relaunch(); + + const { page } = ctx; + + await page.waitForSelector("#authForm"); + + expect( + await page.getByRole("button", { name: "Create account" }).isVisible() + ).toBe(true); + + await page + .getByRole("button", { name: "Skip & go directly to the app" }) + .click(); + + await skipDialog(page); + + await page.waitForSelector(".ProseMirror"); + + await page + .locator(".theme-scope-statusBar") + .getByRole("button", { name: /checking for updates/i }) + .waitFor({ state: "hidden" }); + + expect( await page .locator(".theme-scope-statusBar") .getByRole("button", { name: /available/i }) - .waitFor({ state: "attached" }); - }, - { version: "3.0.0" } - ); + .isHidden() + ).toBe(true); + }); }); -test("update to stable if it is newer", async (t) => { - await harness( - t, - async (ctx) => { - await ctx.app.close(); - await writeFile( - ctx.configPath, - JSON.stringify({ - automaticUpdates: false, - releaseTrack: "beta" - }) - ); +describe("downgrade to stable on switching to stable release track", () => { + test.scoped({ options: { version: "99.0.0-beta.0" } }); + test("test", async ({ ctx, expect, onTestFinished }) => { + onTestFinished(testCleanup); - await ctx.relaunch(); + await ctx.app.close(); + await writeFile( + ctx.configPath, + JSON.stringify({ + automaticUpdates: false, + releaseTrack: "stable" + }) + ); - const { page } = ctx; + await ctx.relaunch(); - await page.waitForSelector("#authForm"); + const { page } = ctx; - t.expect( - await page.getByRole("button", { name: "Create account" }).isVisible() - ).toBe(true); + await page.waitForSelector("#authForm"); - await page - .getByRole("button", { name: "Skip & go directly to the app" }) - .click(); + expect( + await page.getByRole("button", { name: "Create account" }).isVisible() + ).toBe(true); - await skipDialog(page); + await page + .getByRole("button", { name: "Skip & go directly to the app" }) + .click(); - await page.waitForSelector(".ProseMirror"); + await skipDialog(page); - const updateButton = page - .locator(".theme-scope-statusBar") - .getByRole("button", { name: /available/i }); - await updateButton.waitFor({ state: "visible" }); - const content = await updateButton.textContent(); - const version = content?.split(" ")?.[0] || ""; - t.expect(gt(version, "3.0.0-beta.0")).toBe(true); - }, - { version: "3.0.0-beta.0" } - ); -}); + await page.waitForSelector(".ProseMirror"); -test("update is not available if it latest stable version is older", async (t) => { - await harness( - t, - async (ctx) => { - await ctx.app.close(); - await writeFile( - ctx.configPath, - JSON.stringify({ - automaticUpdates: false, - releaseTrack: "beta" - }) - ); + await page + .locator(".theme-scope-statusBar") + .getByRole("button", { name: /checking for updates/i }) + .waitFor({ state: "hidden" }); - await ctx.relaunch(); - - const { page } = ctx; - - await page.waitForSelector("#authForm"); - - t.expect( - await page.getByRole("button", { name: "Create account" }).isVisible() - ).toBe(true); - - await page - .getByRole("button", { name: "Skip & go directly to the app" }) - .click(); - - await skipDialog(page); - - await page.waitForSelector(".ProseMirror"); - - await page - .locator(".theme-scope-statusBar") - .getByRole("button", { name: /checking for updates/i }) - .waitFor({ state: "hidden" }); - - t.expect( - await page - .locator(".theme-scope-statusBar") - .getByRole("button", { name: /available/i }) - .isHidden() - ).toBe(true); - }, - { version: "99.0.0-beta.0" } - ); -}); - -test("downgrade to stable on switching to stable release track", async (t) => { - await harness( - t, - async (ctx) => { - await ctx.app.close(); - await writeFile( - ctx.configPath, - JSON.stringify({ - automaticUpdates: false, - releaseTrack: "stable" - }) - ); - - await ctx.relaunch(); - - const { page } = ctx; - - await page.waitForSelector("#authForm"); - - t.expect( - await page.getByRole("button", { name: "Create account" }).isVisible() - ).toBe(true); - - await page - .getByRole("button", { name: "Skip & go directly to the app" }) - .click(); - - await skipDialog(page); - - await page.waitForSelector(".ProseMirror"); - - await page - .locator(".theme-scope-statusBar") - .getByRole("button", { name: /checking for updates/i }) - .waitFor({ state: "hidden" }); - - const updateButton = page - .locator(".theme-scope-statusBar") - .getByRole("button", { name: /available/i }); - await updateButton.waitFor({ state: "visible" }); - const content = await updateButton.textContent(); - const version = content?.split(" ")?.[0] || ""; - t.expect(lt(version, "99.0.0-beta.0")).toBe(true); - }, - { version: "99.0.0-beta.0" } - ); + const updateButton = page + .locator(".theme-scope-statusBar") + .getByRole("button", { name: /available/i }); + await updateButton.waitFor({ state: "visible" }); + const content = await updateButton.textContent(); + const version = content?.split(" ")?.[0] || ""; + expect(lt(version, "99.0.0-beta.0")).toBe(true); + }); }); async function skipDialog(page: Page) { @@ -237,9 +233,9 @@ async function skipDialog(page: Page) { "button[data-role='negative-button']" ); if (await positiveButton.isVisible()) - await positiveButton.click({ timeout: 2000 }); + await positiveButton.click({ timeout: 1000 }); else if (await negativeButton.isVisible()) - await negativeButton.click({ timeout: 2000 }); + await negativeButton.click({ timeout: 1000 }); } catch (e) { // ignore error } diff --git a/apps/desktop/__tests__/launch.test.ts b/apps/desktop/__tests__/launch.test.ts index 938a0ed01..0617be6df 100644 --- a/apps/desktop/__tests__/launch.test.ts +++ b/apps/desktop/__tests__/launch.test.ts @@ -17,22 +17,24 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -import { test } from "vitest"; -import { harness } from "./utils.js"; -import assert from "assert"; +import { testCleanup, test } from "./utils.js"; -test("make sure app loads", async (t) => { - await harness(t, async ({ page }) => { - await page.waitForSelector("#authForm"); +test("make sure app loads", async ({ + ctx: { page }, + expect, + onTestFinished +}) => { + onTestFinished(testCleanup); - assert.ok( - await page.getByRole("button", { name: "Create account" }).isVisible() - ); + await page.waitForSelector("#authForm"); - await page - .getByRole("button", { name: "Skip & go directly to the app" }) - .click(); + expect( + await page.getByRole("button", { name: "Create account" }).isVisible() + ).toBe(true); - await page.waitForSelector(".ProseMirror"); - }); + await page + .getByRole("button", { name: "Skip & go directly to the app" }) + .click(); + + await page.waitForSelector(".ProseMirror"); }); diff --git a/apps/desktop/__tests__/utils.ts b/apps/desktop/__tests__/utils.ts index d1c2d2eb1..c4d31f0a2 100644 --- a/apps/desktop/__tests__/utils.ts +++ b/apps/desktop/__tests__/utils.ts @@ -23,7 +23,7 @@ import { fileURLToPath } from "node:url"; import path from "path"; import { _electron as electron } from "playwright"; import slugify from "slugify"; -import { TaskContext } from "vitest"; +import { test as vitestTest, TestContext } from "vitest"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -42,31 +42,34 @@ interface TestOptions { version: string; } -export async function harness( - t: TaskContext, - cb: (ctx: AppContext) => Promise, - options?: TestOptions -) { - const ctx = await buildAndLaunchApp(options); +interface Fixtures { + options: TestOptions; + ctx: AppContext; +} - t.onTestFinished(async (result) => { - if (result.state === "fail") { - await mkdir("test-results", { recursive: true }); - await ctx.page.screenshot({ - path: path.join( - "test-results", - `${slugify(t.task.name)}-${process.platform}-${ - process.arch - }-error.png` - ) - }); - } +export const test = vitestTest.extend({ + options: { version: "3.0.0" } as TestOptions, + ctx: async ({ options }, use) => { + const ctx = await buildAndLaunchApp(options); + await use(ctx); await ctx.app.close(); await rm(ctx.userDataDir, { recursive: true, force: true }); await rm(ctx.outputDir, { recursive: true, force: true }); - }); + } +}); - await cb(ctx); +export async function testCleanup(context: TestContext) { + if (context.task.result?.state === "fail") { + await mkdir("test-results", { recursive: true }); + await (context.task.context as unknown as Fixtures).ctx.page.screenshot({ + path: path.join( + "test-results", + `${slugify(context.task.name)}-${process.platform}-${ + process.arch + }-error.png` + ) + }); + } } async function buildAndLaunchApp(options?: TestOptions): Promise { From ec48f2350d4a69758bd98d58b8d408c08eb7727e Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 19 Jul 2025 11:02:32 +0500 Subject: [PATCH 13/19] desktop: run tests sequentially this is required since each test builds a new app and on linux & windows that can cause issues if done in parallel --- apps/desktop/vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/desktop/vitest.config.ts b/apps/desktop/vitest.config.ts index eacce4391..e3de1b3d9 100644 --- a/apps/desktop/vitest.config.ts +++ b/apps/desktop/vitest.config.ts @@ -23,7 +23,7 @@ export default defineConfig({ test: { testTimeout: process.env.CI ? 120 * 1000 : 120 * 1000, sequence: { - concurrent: true, + concurrent: false, shuffle: true }, dir: "./__tests__/", From 21978c4c1d8091e0aaaed8f70779d37678a6c5a3 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 19 Jul 2025 12:32:22 +0500 Subject: [PATCH 14/19] desktop: patch better-sqlite3-multiple-ciphers on each test build --- apps/desktop/__tests__/utils.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/desktop/__tests__/utils.ts b/apps/desktop/__tests__/utils.ts index c4d31f0a2..aaaa9dc2f 100644 --- a/apps/desktop/__tests__/utils.ts +++ b/apps/desktop/__tests__/utils.ts @@ -18,12 +18,13 @@ along with this program. If not, see . */ import { execSync } from "child_process"; -import { mkdir, rm } from "fs/promises"; +import { mkdir, rm, rmdir } from "fs/promises"; import { fileURLToPath } from "node:url"; import path from "path"; import { _electron as electron } from "playwright"; import slugify from "slugify"; import { test as vitestTest, TestContext } from "vitest"; +import { patchBetterSQLite3 } from "../scripts/patch-better-sqlite3.mjs"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -53,8 +54,8 @@ export const test = vitestTest.extend({ const ctx = await buildAndLaunchApp(options); await use(ctx); await ctx.app.close(); - await rm(ctx.userDataDir, { recursive: true, force: true }); - await rm(ctx.outputDir, { recursive: true, force: true }); + await rmdir(ctx.userDataDir, { recursive: true }); + await rmdir(ctx.outputDir, { recursive: true }); } }); @@ -160,6 +161,8 @@ async function buildApp({ } }); + await patchBetterSQLite3(); + return path.join( __dirname, "..", From b30110a48a5b932ffe03ecb7c9318ec5fd334b57 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Sat, 19 Jul 2025 15:05:24 +0500 Subject: [PATCH 15/19] desktop: add support for running tests in parallel we do this by copying the build directory instead of building it over and over again for each test. This also makes the tests super fast. --- apps/desktop/__tests__/utils.ts | 190 +++++++++++++++++++++++--------- apps/desktop/package.json | 4 +- apps/desktop/src/main.ts | 1 + apps/desktop/src/overrides.ts | 35 ++++++ apps/desktop/vitest.config.ts | 2 +- 5 files changed, 178 insertions(+), 54 deletions(-) create mode 100644 apps/desktop/src/overrides.ts diff --git a/apps/desktop/__tests__/utils.ts b/apps/desktop/__tests__/utils.ts index aaaa9dc2f..658ab768f 100644 --- a/apps/desktop/__tests__/utils.ts +++ b/apps/desktop/__tests__/utils.ts @@ -18,13 +18,14 @@ along with this program. If not, see . */ import { execSync } from "child_process"; -import { mkdir, rm, rmdir } from "fs/promises"; +import { cp, mkdir, readFile, rm, rmdir, writeFile } from "fs/promises"; import { fileURLToPath } from "node:url"; -import path from "path"; +import path, { join, resolve } from "path"; import { _electron as electron } from "playwright"; import slugify from "slugify"; import { test as vitestTest, TestContext } from "vitest"; import { patchBetterSQLite3 } from "../scripts/patch-better-sqlite3.mjs"; +import { existsSync } from "fs"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -53,16 +54,14 @@ export const test = vitestTest.extend({ ctx: async ({ options }, use) => { const ctx = await buildAndLaunchApp(options); await use(ctx); - await ctx.app.close(); - await rmdir(ctx.userDataDir, { recursive: true }); - await rmdir(ctx.outputDir, { recursive: true }); } }); export async function testCleanup(context: TestContext) { + const ctx = (context.task.context as unknown as Fixtures).ctx; if (context.task.result?.state === "fail") { await mkdir("test-results", { recursive: true }); - await (context.task.context as unknown as Fixtures).ctx.page.screenshot({ + await ctx.page.screenshot({ path: path.join( "test-results", `${slugify(context.task.name)}-${process.platform}-${ @@ -71,6 +70,9 @@ export async function testCleanup(context: TestContext) { ) }); } + await ctx.app.close(); + await rmdir(ctx.userDataDir, { recursive: true }); + await rmdir(ctx.outputDir, { recursive: true }); } async function buildAndLaunchApp(options?: TestOptions): Promise { @@ -78,11 +80,11 @@ async function buildAndLaunchApp(options?: TestOptions): Promise { const outputDir = path.join("test-artifacts", `${productName}-output`); const executablePath = await buildApp({ ...options, - productName, outputDir }); const { app, page, configPath, userDataDir } = await launchApp( - executablePath + executablePath, + productName ); const ctx: AppContext = { app, @@ -92,7 +94,8 @@ async function buildAndLaunchApp(options?: TestOptions): Promise { outputDir, relaunch: async () => { const { app, page, configPath, userDataDir } = await launchApp( - executablePath + executablePath, + productName ); ctx.app = app; ctx.page = page; @@ -103,25 +106,31 @@ async function buildAndLaunchApp(options?: TestOptions): Promise { return ctx; } -async function launchApp(executablePath: string) { +async function launchApp(executablePath: string, packageName: string) { + const userDataDir = resolve( + __dirname, + "..", + "test-artifacts", + "user_data_dirs", + packageName + ); const app = await electron.launch({ executablePath, args: IS_DEBUG ? [] : ["--hidden"], - env: - process.platform === "linux" + env: { + ...(process.platform === "linux" ? { ...(process.env as Record), APPIMAGE: "true" } - : (process.env as Record) + : (process.env as Record)), + CUSTOM_USER_DATA_DIR: userDataDir + } }); const page = await app.firstWindow(); - const userDataDir = await app.evaluate((a) => { - return a.app.getPath("userData"); - }); - const configPath = path.join(userDataDir, "config.json"); + const configPath = path.join(userDataDir, "UserData", "config.json"); return { app, page, @@ -132,54 +141,131 @@ async function launchApp(executablePath: string) { async function buildApp({ version, - productName, outputDir }: { version?: string; - productName: string; outputDir: string; }) { - const args = [ - "electron-builder", - "--dir", - `--${process.arch}`, - `--config electron-builder.config.js`, - `--c.extraMetadata.productName=${productName}`, - `--c.compression=store`, - "--publish=never" - ]; - if (version) args.push(`--c.extraMetadata.version=${version}`); + const productName = `NotesnookTestHarness`; + const sourceDir = resolve("output", productName); + if (!existsSync(sourceDir)) { + const args = [ + "electron-builder", + "--dir", + `--${process.arch}`, + `--config electron-builder.config.js`, + `--c.extraMetadata.productName=${productName}`, + `--c.compression=store`, + "--publish=never" + ]; + if (version) args.push(`--c.extraMetadata.version=${version}`); - execSync(`npx ${args.join(" ")}`, { - stdio: IS_DEBUG ? "inherit" : "ignore", - env: { - ...process.env, - NOTESNOOK_STAGING: "true", - NN_PRODUCT_NAME: productName, - NN_APP_ID: `com.notesnook.test.${productName}`, - NN_OUTPUT_DIR: outputDir - } - }); + execSync(`npx ${args.join(" ")}`, { + stdio: IS_DEBUG ? "inherit" : "ignore", + env: { + ...process.env, + NOTESNOOK_STAGING: "true", + NN_PRODUCT_NAME: productName, + NN_APP_ID: `com.notesnook.test.${productName}`, + NN_OUTPUT_DIR: sourceDir + } + }); + } + return process.platform === "win32" + ? await copyBuildWindows(sourceDir, outputDir, productName, version) + : process.platform === "darwin" + ? await copyBuildMacOS(sourceDir, outputDir, productName, version) + : await copyBuildLinux(sourceDir, outputDir, productName, version); +} - await patchBetterSQLite3(); +async function copyBuildLinux( + sourceDir: string, + outputDir: string, + productName: string, + version?: string +) { + const platformDir = + process.arch === "arm64" ? "linux-arm64-unpacked" : "linux-unpacked"; + const appDir = await copyBuild( + sourceDir, + outputDir, + platformDir, + "resources", + version + ); + return resolve(__dirname, "..", appDir, productName); +} - return path.join( +async function copyBuildWindows( + sourceDir: string, + outputDir: string, + productName: string, + version?: string +) { + const platformDir = + process.arch === "arm64" ? "win-arm64-unpacked" : "win-unpacked"; + const appDir = await copyBuild( + sourceDir, + outputDir, + platformDir, + "resources", + version + ); + return resolve(__dirname, "..", appDir, `${productName}.exe`); +} + +async function copyBuildMacOS( + sourceDir: string, + outputDir: string, + productName: string, + version?: string +) { + const platformDir = process.arch === "arm64" ? "mac-arm64" : "mac"; + const appDir = await copyBuild( + sourceDir, + outputDir, + platformDir, + join(`${productName}.app`, "Contents", "Resources"), + version + ); + return resolve( __dirname, "..", - outputDir, - process.platform === "linux" - ? process.arch === "arm64" - ? "linux-arm64-unpacked" - : "linux-unpacked" - : process.platform === "darwin" - ? process.arch === "arm64" - ? `mac-arm64/${productName}.app/Contents/MacOS/` - : `mac/${productName}.app/Contents/MacOS/` - : "win-unpacked", - process.platform === "win32" ? `${productName}.exe` : productName + appDir, + `${productName}.app`, + "Contents", + "MacOS", + productName ); } +async function copyBuild( + sourceDir: string, + outputDir: string, + platformDir: string, + resourcesDir: string, + version?: string +) { + const appDir = outputDir; + await cp(join(sourceDir, platformDir), outputDir, { + recursive: true, + preserveTimestamps: true, + verbatimSymlinks: true, + dereference: false, + force: true + }); + + const packageJsonPath = join(appDir, resourcesDir, "app", "package.json"); + + const packageJson = JSON.parse(await readFile(packageJsonPath, "utf-8")); + if (version) { + packageJson.version = version; + await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2)); + } + + return appDir; +} + function makeid(length: number) { let result = ""; const characters = diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 0216fa02b..ef3edae32 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -8,7 +8,9 @@ "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "types": "./dist/types/index.d.ts", - "sideEffects": false, + "sideEffects": [ + "src/overrides.ts" + ], "exports": { ".": { "require": { diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 83b78ac44..f4d44000a 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +import "./overrides"; import { app, BrowserWindow, nativeTheme, shell } from "electron"; import { isDevelopment } from "./utils"; import { registerProtocol, PROTOCOL_URL } from "./utils/protocol"; diff --git a/apps/desktop/src/overrides.ts b/apps/desktop/src/overrides.ts new file mode 100644 index 000000000..721dbfb43 --- /dev/null +++ b/apps/desktop/src/overrides.ts @@ -0,0 +1,35 @@ +/* +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 { app } from "electron"; +import path from "path"; + +if (process.env.CUSTOM_USER_DATA_DIR) { + app.setPath( + "appData", + path.join(process.env.CUSTOM_USER_DATA_DIR, "AppData") + ); + app.setPath( + "userData", + path.join(process.env.CUSTOM_USER_DATA_DIR, "UserData") + ); + app.setPath( + "documents", + path.join(process.env.CUSTOM_USER_DATA_DIR, "Documents") + ); +} diff --git a/apps/desktop/vitest.config.ts b/apps/desktop/vitest.config.ts index e3de1b3d9..eacce4391 100644 --- a/apps/desktop/vitest.config.ts +++ b/apps/desktop/vitest.config.ts @@ -23,7 +23,7 @@ export default defineConfig({ test: { testTimeout: process.env.CI ? 120 * 1000 : 120 * 1000, sequence: { - concurrent: false, + concurrent: true, shuffle: true }, dir: "./__tests__/", From 70fd03820759279e82e027f036b42da69fecd9b8 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Mon, 21 Jul 2025 08:57:16 +0500 Subject: [PATCH 16/19] desktop: add build retrying when running tests --- apps/desktop/__tests__/utils.ts | 43 +++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/apps/desktop/__tests__/utils.ts b/apps/desktop/__tests__/utils.ts index 658ab768f..90d0d33ac 100644 --- a/apps/desktop/__tests__/utils.ts +++ b/apps/desktop/__tests__/utils.ts @@ -18,13 +18,12 @@ along with this program. If not, see . */ import { execSync } from "child_process"; -import { cp, mkdir, readFile, rm, rmdir, writeFile } from "fs/promises"; +import { cp, mkdir, readFile, rm, writeFile } from "fs/promises"; import { fileURLToPath } from "node:url"; import path, { join, resolve } from "path"; import { _electron as electron } from "playwright"; import slugify from "slugify"; import { test as vitestTest, TestContext } from "vitest"; -import { patchBetterSQLite3 } from "../scripts/patch-better-sqlite3.mjs"; import { existsSync } from "fs"; const __filename = fileURLToPath(import.meta.url); @@ -71,8 +70,8 @@ export async function testCleanup(context: TestContext) { }); } await ctx.app.close(); - await rmdir(ctx.userDataDir, { recursive: true }); - await rmdir(ctx.outputDir, { recursive: true }); + await rm(ctx.userDataDir, { force: true, recursive: true }); + await rm(ctx.outputDir, { force: true, recursive: true }); } async function buildAndLaunchApp(options?: TestOptions): Promise { @@ -139,6 +138,7 @@ async function launchApp(executablePath: string, packageName: string) { }; } +let MAX_RETRIES = 3; async function buildApp({ version, outputDir @@ -159,17 +159,23 @@ async function buildApp({ "--publish=never" ]; if (version) args.push(`--c.extraMetadata.version=${version}`); - - execSync(`npx ${args.join(" ")}`, { - stdio: IS_DEBUG ? "inherit" : "ignore", - env: { - ...process.env, - NOTESNOOK_STAGING: "true", - NN_PRODUCT_NAME: productName, - NN_APP_ID: `com.notesnook.test.${productName}`, - NN_OUTPUT_DIR: sourceDir - } - }); + try { + execSync(`npx ${args.join(" ")}`, { + stdio: IS_DEBUG ? "inherit" : "ignore", + env: { + ...process.env, + NOTESNOOK_STAGING: "true", + NN_PRODUCT_NAME: productName, + NN_APP_ID: `com.notesnook.test.${productName}`, + NN_OUTPUT_DIR: sourceDir + } + }); + } catch (e) { + if (--MAX_RETRIES) { + console.log("retrying..."); + return await buildApp({ outputDir, version }); + } else throw e; + } } return process.platform === "win32" ? await copyBuildWindows(sourceDir, outputDir, productName, version) @@ -193,7 +199,12 @@ async function copyBuildLinux( "resources", version ); - return resolve(__dirname, "..", appDir, productName); + return resolve( + __dirname, + "..", + appDir, + productName.toLowerCase().replace(/\s+/g, "-") + ); } async function copyBuildWindows( From 578bc6e546576303f6285c529ad790a4a922f7ad Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Mon, 21 Jul 2025 09:19:53 +0500 Subject: [PATCH 17/19] desktop: build app only once during tests --- apps/desktop/__tests__/auto-updates.test.ts | 2 +- apps/desktop/__tests__/global-setup.ts | 24 +++++ apps/desktop/__tests__/launch.test.ts | 2 +- apps/desktop/__tests__/test-override.ts | 50 ++++++++++ apps/desktop/__tests__/utils.ts | 102 +++++++------------- apps/desktop/vitest.config.ts | 1 + 6 files changed, 113 insertions(+), 68 deletions(-) create mode 100644 apps/desktop/__tests__/global-setup.ts create mode 100644 apps/desktop/__tests__/test-override.ts diff --git a/apps/desktop/__tests__/auto-updates.test.ts b/apps/desktop/__tests__/auto-updates.test.ts index cab7a2ca0..e70e0bb2a 100644 --- a/apps/desktop/__tests__/auto-updates.test.ts +++ b/apps/desktop/__tests__/auto-updates.test.ts @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -import { test, testCleanup } from "./utils.js"; +import { testCleanup, test } from "./test-override.js"; import { writeFile } from "fs/promises"; import { Page } from "playwright"; import { gt, lt } from "semver"; diff --git a/apps/desktop/__tests__/global-setup.ts b/apps/desktop/__tests__/global-setup.ts new file mode 100644 index 000000000..28337fce0 --- /dev/null +++ b/apps/desktop/__tests__/global-setup.ts @@ -0,0 +1,24 @@ +/* +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 { buildApp } from "./utils"; + +export default async function setup() { + await buildApp(); +} diff --git a/apps/desktop/__tests__/launch.test.ts b/apps/desktop/__tests__/launch.test.ts index 0617be6df..fd576a86f 100644 --- a/apps/desktop/__tests__/launch.test.ts +++ b/apps/desktop/__tests__/launch.test.ts @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -import { testCleanup, test } from "./utils.js"; +import { testCleanup, test } from "./test-override.js"; test("make sure app loads", async ({ ctx: { page }, diff --git a/apps/desktop/__tests__/test-override.ts b/apps/desktop/__tests__/test-override.ts new file mode 100644 index 000000000..92fe56612 --- /dev/null +++ b/apps/desktop/__tests__/test-override.ts @@ -0,0 +1,50 @@ +/* +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 { test as vitestTest, TestContext } from "vitest"; +import { buildAndLaunchApp, Fixtures, TestOptions } from "./utils"; +import { mkdir, rm } from "fs/promises"; +import path from "path"; +import slugify from "slugify"; + +export const test = vitestTest.extend({ + options: { version: "3.0.0" } as TestOptions, + ctx: async ({ options }, use) => { + const ctx = await buildAndLaunchApp(options); + await use(ctx); + } +}); + +export async function testCleanup(context: TestContext) { + const ctx = (context.task.context as unknown as Fixtures).ctx; + if (context.task.result?.state === "fail") { + await mkdir("test-results", { recursive: true }); + await ctx.page.screenshot({ + path: path.join( + "test-results", + `${slugify(context.task.name)}-${process.platform}-${ + process.arch + }-error.png` + ) + }); + } + await ctx.app.close(); + await rm(ctx.userDataDir, { force: true, recursive: true }); + await rm(ctx.outputDir, { force: true, recursive: true }); +} diff --git a/apps/desktop/__tests__/utils.ts b/apps/desktop/__tests__/utils.ts index 90d0d33ac..b4ecaf155 100644 --- a/apps/desktop/__tests__/utils.ts +++ b/apps/desktop/__tests__/utils.ts @@ -18,19 +18,19 @@ along with this program. If not, see . */ import { execSync } from "child_process"; -import { cp, mkdir, readFile, rm, writeFile } from "fs/promises"; +import { cp, readFile, writeFile } from "fs/promises"; import { fileURLToPath } from "node:url"; import path, { join, resolve } from "path"; import { _electron as electron } from "playwright"; -import slugify from "slugify"; -import { test as vitestTest, TestContext } from "vitest"; import { existsSync } from "fs"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const IS_DEBUG = process.env.NN_DEBUG === "true" || process.env.CI === "true"; +const productName = `NotesnookTestHarness`; +const SOURCE_DIR = resolve("output", productName); -interface AppContext { +export interface AppContext { app: import("playwright").ElectronApplication; page: import("playwright").Page; configPath: string; @@ -39,45 +39,21 @@ interface AppContext { relaunch: () => Promise; } -interface TestOptions { +export interface TestOptions { version: string; } -interface Fixtures { +export interface Fixtures { options: TestOptions; ctx: AppContext; } -export const test = vitestTest.extend({ - options: { version: "3.0.0" } as TestOptions, - ctx: async ({ options }, use) => { - const ctx = await buildAndLaunchApp(options); - await use(ctx); - } -}); - -export async function testCleanup(context: TestContext) { - const ctx = (context.task.context as unknown as Fixtures).ctx; - if (context.task.result?.state === "fail") { - await mkdir("test-results", { recursive: true }); - await ctx.page.screenshot({ - path: path.join( - "test-results", - `${slugify(context.task.name)}-${process.platform}-${ - process.arch - }-error.png` - ) - }); - } - await ctx.app.close(); - await rm(ctx.userDataDir, { force: true, recursive: true }); - await rm(ctx.outputDir, { force: true, recursive: true }); -} - -async function buildAndLaunchApp(options?: TestOptions): Promise { +export async function buildAndLaunchApp( + options?: TestOptions +): Promise { const productName = `notesnooktest${makeid(10)}`; const outputDir = path.join("test-artifacts", `${productName}-output`); - const executablePath = await buildApp({ + const executablePath = await copyBuild({ ...options, outputDir }); @@ -139,16 +115,8 @@ async function launchApp(executablePath: string, packageName: string) { } let MAX_RETRIES = 3; -async function buildApp({ - version, - outputDir -}: { - version?: string; - outputDir: string; -}) { - const productName = `NotesnookTestHarness`; - const sourceDir = resolve("output", productName); - if (!existsSync(sourceDir)) { +export async function buildApp(version?: string) { + if (!existsSync(SOURCE_DIR)) { const args = [ "electron-builder", "--dir", @@ -167,33 +135,40 @@ async function buildApp({ NOTESNOOK_STAGING: "true", NN_PRODUCT_NAME: productName, NN_APP_ID: `com.notesnook.test.${productName}`, - NN_OUTPUT_DIR: sourceDir + NN_OUTPUT_DIR: SOURCE_DIR } }); } catch (e) { if (--MAX_RETRIES) { console.log("retrying..."); - return await buildApp({ outputDir, version }); + return await buildApp(version); } else throw e; } } - return process.platform === "win32" - ? await copyBuildWindows(sourceDir, outputDir, productName, version) - : process.platform === "darwin" - ? await copyBuildMacOS(sourceDir, outputDir, productName, version) - : await copyBuildLinux(sourceDir, outputDir, productName, version); } -async function copyBuildLinux( - sourceDir: string, +async function copyBuild({ + version, + outputDir +}: { + version?: string; + outputDir: string; +}) { + return process.platform === "win32" + ? await makeBuildCopyWindows(outputDir, productName, version) + : process.platform === "darwin" + ? await makeBuildCopyMacOS(outputDir, productName, version) + : await makeBuildCopyLinux(outputDir, productName, version); +} + +async function makeBuildCopyLinux( outputDir: string, productName: string, version?: string ) { const platformDir = process.arch === "arm64" ? "linux-arm64-unpacked" : "linux-unpacked"; - const appDir = await copyBuild( - sourceDir, + const appDir = await makeBuildCopy( outputDir, platformDir, "resources", @@ -207,16 +182,14 @@ async function copyBuildLinux( ); } -async function copyBuildWindows( - sourceDir: string, +async function makeBuildCopyWindows( outputDir: string, productName: string, version?: string ) { const platformDir = process.arch === "arm64" ? "win-arm64-unpacked" : "win-unpacked"; - const appDir = await copyBuild( - sourceDir, + const appDir = await makeBuildCopy( outputDir, platformDir, "resources", @@ -225,15 +198,13 @@ async function copyBuildWindows( return resolve(__dirname, "..", appDir, `${productName}.exe`); } -async function copyBuildMacOS( - sourceDir: string, +async function makeBuildCopyMacOS( outputDir: string, productName: string, version?: string ) { const platformDir = process.arch === "arm64" ? "mac-arm64" : "mac"; - const appDir = await copyBuild( - sourceDir, + const appDir = await makeBuildCopy( outputDir, platformDir, join(`${productName}.app`, "Contents", "Resources"), @@ -250,15 +221,14 @@ async function copyBuildMacOS( ); } -async function copyBuild( - sourceDir: string, +async function makeBuildCopy( outputDir: string, platformDir: string, resourcesDir: string, version?: string ) { const appDir = outputDir; - await cp(join(sourceDir, platformDir), outputDir, { + await cp(join(SOURCE_DIR, platformDir), outputDir, { recursive: true, preserveTimestamps: true, verbatimSymlinks: true, diff --git a/apps/desktop/vitest.config.ts b/apps/desktop/vitest.config.ts index eacce4391..0541e15bf 100644 --- a/apps/desktop/vitest.config.ts +++ b/apps/desktop/vitest.config.ts @@ -26,6 +26,7 @@ export default defineConfig({ concurrent: true, shuffle: true }, + globalSetup: "./__tests__/global-setup.ts", dir: "./__tests__/", exclude: [ "**/node_modules/**", From 0f6622360c7f33c912be4e7fe22c52f436daaa0d Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Mon, 21 Jul 2025 09:28:26 +0500 Subject: [PATCH 18/19] desktop: ignore error on failure to remove test artifacts --- apps/desktop/__tests__/test-override.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/apps/desktop/__tests__/test-override.ts b/apps/desktop/__tests__/test-override.ts index 92fe56612..698c65d9f 100644 --- a/apps/desktop/__tests__/test-override.ts +++ b/apps/desktop/__tests__/test-override.ts @@ -45,6 +45,20 @@ export async function testCleanup(context: TestContext) { }); } await ctx.app.close(); - await rm(ctx.userDataDir, { force: true, recursive: true }); - await rm(ctx.outputDir, { force: true, recursive: true }); + await rm(ctx.userDataDir, { + force: true, + recursive: true, + maxRetries: 3, + retryDelay: 5000 + }).catch(() => { + /*ignore */ + }); + await rm(ctx.outputDir, { + force: true, + recursive: true, + maxRetries: 3, + retryDelay: 5000 + }).catch(() => { + /*ignore */ + }); } From a7c857fb710e022e12db97f80afc8fde2629f6eb Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Mon, 21 Jul 2025 09:35:39 +0500 Subject: [PATCH 19/19] desktop: increase `hookTimeout` ton 120 seconds --- apps/desktop/vitest.config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/desktop/vitest.config.ts b/apps/desktop/vitest.config.ts index 0541e15bf..539e268a9 100644 --- a/apps/desktop/vitest.config.ts +++ b/apps/desktop/vitest.config.ts @@ -21,7 +21,8 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ test: { - testTimeout: process.env.CI ? 120 * 1000 : 120 * 1000, + testTimeout: 120 * 1000, + hookTimeout: 120 * 1000, sequence: { concurrent: true, shuffle: true