From a50c481da9b039211f481880e3a8497064f4bfcf Mon Sep 17 00:00:00 2001 From: Shane Osbourne Date: Thu, 3 Oct 2024 17:47:11 -0400 Subject: [PATCH] move remaining tests to playwright --- integration-test/config.js | 12 - integration-test/helpers/harness.js | 259 ++- .../pages/runtimeChecks/index.html | 6 - .../pages/runtimeChecks/script.js | 12 - .../pages/runtimeChecks/script2.js | 2 - integration-test/test-cookie.js | 36 +- integration-test/test-fingerprint.js | 228 +-- integration-test/test-navigator-interface.js | 25 +- integration-test/test-pages.js | 38 +- .../{pages => test-pages}/blank.html | 0 .../{pages => test-pages}/index.html | 0 integration-test/test-utils.js | 25 +- integration-test/test-web-compat.js | 547 +++-- package-lock.json | 1800 +---------------- package.json | 3 +- playwright.config.js | 10 +- scripts/server.mjs | 10 + tsconfig.json | 1 - 18 files changed, 522 insertions(+), 2492 deletions(-) delete mode 100644 integration-test/config.js delete mode 100644 integration-test/pages/runtimeChecks/index.html delete mode 100644 integration-test/pages/runtimeChecks/script.js delete mode 100644 integration-test/pages/runtimeChecks/script2.js rename integration-test/{pages => test-pages}/blank.html (100%) rename integration-test/{pages => test-pages}/index.html (100%) create mode 100644 scripts/server.mjs diff --git a/integration-test/config.js b/integration-test/config.js deleted file mode 100644 index dc9fd7c9c8..0000000000 --- a/integration-test/config.js +++ /dev/null @@ -1,12 +0,0 @@ -export default { - spec_dir: 'integration-test', - jsLoader: 'import', - spec_files: [ - '**/*.js', - '!test-pages/**/*.js', - '!pages/**/*.js', - '!playwright/**/*.js', - '!extension/**/*.js' - ], - random: false -} diff --git a/integration-test/helpers/harness.js b/integration-test/helpers/harness.js index af29ede84d..2d4a5a5601 100644 --- a/integration-test/helpers/harness.js +++ b/integration-test/helpers/harness.js @@ -1,150 +1,133 @@ -import * as fs from 'fs' -import * as os from 'os' -import * as path from 'path' -import * as http from 'http' -import puppeteer from 'puppeteer' -import { spawnSync } from 'child_process' - -jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000 -if (process.env.KEEP_OPEN) { - jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000 * 1000 -} +import { mkdtempSync, rmSync } from 'node:fs' +import { tmpdir } from 'os' +import { join } from 'path' +import { chromium, firefox } from '@playwright/test' +import { fork } from 'node:child_process' const DATA_DIR_PREFIX = 'ddg-temp-' -export async function setup (ops = {}) { - const { withExtension = false } = ops - const tmpDirPrefix = path.join(os.tmpdir(), DATA_DIR_PREFIX) - const dataDir = fs.mkdtempSync(tmpDirPrefix) - const args = [ - `--user-data-dir=${dataDir}` - ] - if (withExtension) { - args.push('--disable-extensions-except=integration-test/extension') - args.push('--load-extension=integration-test/extension') - } - - // github actions - if (process.env.CI) { - args.push('--no-sandbox') - } - - const puppeteerOps = { - args, - headless: false - } - - const browser = await puppeteer.launch(puppeteerOps) - const servers = [] - - async function teardown () { - if (process.env.KEEP_OPEN) { - return new Promise((resolve) => { - browser.on('disconnected', async () => { - await teardownInternal() - // @ts-expect-error - error TS2810: Expected 1 argument, but got 0. 'new Promise()' - resolve() +/** + * A single place + * @param {typeof import("@playwright/test").test} test + */ +export function testContext (test) { + return test.extend({ + context: async ({ browserName }, use) => { + const tmpDirPrefix = join(tmpdir(), DATA_DIR_PREFIX) + const dataDir = mkdtempSync(tmpDirPrefix) + const browserTypes = { chromium, firefox } + + const launchOptions = { + devtools: true, + headless: false, + viewport: { + width: 1920, + height: 1080 + }, + args: [ + '--disable-extensions-except=integration-test/extension', + '--load-extension=integration-test/extension' + ] + } + + const context = await browserTypes[browserName].launchPersistentContext( + dataDir, + launchOptions + ) + + // actually run the tests + await use(context) + + // clean up + await context.close() + + // Clean up temporary data directory + rmSync(dataDir, { recursive: true, force: true }) + }, + altServerPort: async ({ browserName }, use) => { + console.log('browserName:', browserName) + const serverScript = fork('./scripts/server.mjs', { + env: { + ...process.env, + SERVER_DIR: 'integration-test/test-pages', + SERVER_PORT: '8383' + } + }) + const opened = new Promise((resolve, reject) => { + serverScript.on('message', (/** @type {any} */resp) => { + if (typeof resp.port === 'number') { + resolve(resp.port) + } else { + reject(resp.port) + } }) }) - } else { - await teardownInternal() - } - } - - async function teardownInternal () { - await Promise.all(servers.map(server => server.close())) - await browser.close() - - // necessary so e.g. local storage - // doesn't carry over between test runs - spawnSync('rm', ['-rf', dataDir]) - } - - /** - * @param {number|string} [port] - * @returns {http.Server} - */ - function setupServer (port) { - return _startupServerInternal('../pages', port) - } - - /** - * @param {number|string} [port] - * @returns {http.Server} - */ - function setupIntegrationPagesServer (port) { - return _startupServerInternal('../test-pages', port) - } - - /** - * @param {string} pathName - * @param {number|string} [port] - * @returns {http.Server} - */ - function _startupServerInternal (pathName, port) { - const server = http.createServer(function (req, res) { - // @ts-expect-error - error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string | URL'. - const url = new URL(req.url, `http://${req.headers.host}`) - const importUrl = new URL(import.meta.url) - const dirname = importUrl.pathname.replace(/\/[^/]*$/, '') - const pathname = path.join(dirname, pathName, url.pathname) - - fs.readFile(pathname, (err, data) => { - if (err) { - res.writeHead(404) - res.end(JSON.stringify(err)) - return - } - res.writeHead(200) - res.end(data) + const closed = new Promise((resolve, reject) => { + serverScript.on('close', (err) => { + if (err) { + reject(new Error('server did not exit, code: ' + err)) + } else { + resolve(null) + } + }) + serverScript.on('error', () => { + reject(new Error('server errored')) + }) }) - }).listen(port) - servers.push(server) - return server - } - /** - * A wrapper around page.goto() that supports sending additional - * arguments to content-scope's init methods + waits for a known - * indicators to avoid race conditions - * - * @param {import("puppeteer").Page} page - * @param {string} urlString - * @param {Record} [args] - * @returns {Promise} - */ - async function gotoAndWait (page, urlString, args = {}, evalBeforeInit = null) { - const url = new URL(urlString) - - // Append the flag so that the script knows to wait for incoming args. - url.searchParams.append('wait-for-init-args', 'true') - - await page.goto(url.href) - - // wait until contentScopeFeatures.load() has completed - await page.waitForFunction(() => { - // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f - return window.__content_scope_status === 'loaded' - }) - - if (evalBeforeInit) { - await page.evaluate(evalBeforeInit) + const port = await opened + await use(port) + serverScript.kill() + await closed } + }) +} - const evalString = ` - const detail = ${JSON.stringify(args)} - const evt = new CustomEvent('content-scope-init-args', { detail }) - document.dispatchEvent(evt) - ` - await page.evaluate(evalString) - - // wait until contentScopeFeatures.init(args) has completed - await page.waitForFunction(() => { - window.dispatchEvent(new Event('content-scope-init-complete')) - // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f - return window.__content_scope_status === 'initialized' - }) +/** + * A wrapper around page.goto() that supports sending additional + * arguments to content-scope's init methods + waits for a known + * indicators to avoid race conditions + * + * @param {import("@playwright/test").Page} page + * @param {string} urlString + * @param {Record} [args] + * @param {string|null} [evalBeforeInit] + * @returns {Promise} + */ +export async function gotoAndWait (page, urlString, args = {}, evalBeforeInit = null) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [_, search] = urlString.split('?') + const searchParams = new URLSearchParams(search) + + // Append the flag so that the script knows to wait for incoming args. + searchParams.append('wait-for-init-args', 'true') + + await page.goto(urlString + '?' + searchParams.toString()) + + // wait until contentScopeFeatures.load() has completed + await page.waitForFunction(() => { + // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f + return window.__content_scope_status === 'loaded' + }) + + if (evalBeforeInit) { + await page.evaluate(evalBeforeInit) } - return { browser, teardown, setupServer, setupIntegrationPagesServer, gotoAndWait } + const evalString = ` + ;(() => { + const detail = ${JSON.stringify(args)} + const evt = new CustomEvent('content-scope-init-args', { detail }) + document.dispatchEvent(evt); + })(); + ` + + await page.evaluate(evalString) + + // wait until contentScopeFeatures.init(args) has completed + await page.waitForFunction(() => { + window.dispatchEvent(new Event('content-scope-init-complete')) + // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f + return window.__content_scope_status === 'initialized' + }) } diff --git a/integration-test/pages/runtimeChecks/index.html b/integration-test/pages/runtimeChecks/index.html deleted file mode 100644 index 309310886a..0000000000 --- a/integration-test/pages/runtimeChecks/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -

Check for stack tracing

- - - diff --git a/integration-test/pages/runtimeChecks/script.js b/integration-test/pages/runtimeChecks/script.js deleted file mode 100644 index b559b232a0..0000000000 --- a/integration-test/pages/runtimeChecks/script.js +++ /dev/null @@ -1,12 +0,0 @@ -function init () { - window.script1Ran = true - const script = document.createElement('script') - script.src = './script2.js' - script.id = 'script2' - script.setAttribute('magicalAttribute', 'yes') - document.body.appendChild(script) -} -// Wait for setup -window.addEventListener('initialize', () => { - init() -}) diff --git a/integration-test/pages/runtimeChecks/script2.js b/integration-test/pages/runtimeChecks/script2.js deleted file mode 100644 index f82ae9bf59..0000000000 --- a/integration-test/pages/runtimeChecks/script2.js +++ /dev/null @@ -1,2 +0,0 @@ -window.script2Ran = true -window.dispatchEvent(new CustomEvent('initializeFinished')) diff --git a/integration-test/test-cookie.js b/integration-test/test-cookie.js index 3f4b91e112..2b501532bd 100644 --- a/integration-test/test-cookie.js +++ b/integration-test/test-cookie.js @@ -1,22 +1,11 @@ -import { setup } from './helpers/harness.js' +import { test as base, expect } from '@playwright/test' +import { gotoAndWait, testContext } from './helpers/harness.js' -describe('Cookie protection tests', () => { - let browser - let teardown - let setupServer - - beforeAll(async () => { - ({ browser, teardown, setupServer } = await setup()) - setupServer('8080') - }) - afterAll(async () => { - await teardown() - }) - - it('should restrict the expiry of first-party cookies', async () => { - const page = await browser.newPage() - await page.goto('http://localhost:8080/index.html') +const test = testContext(base) +test.describe('Cookie protection tests', () => { + test('should restrict the expiry of first-party cookies', async ({ page }) => { + await gotoAndWait(page, '/index.html') const result = await page.evaluate(async () => { document.cookie = 'test=1; expires=Wed, 21 Aug 2040 20:00:00 UTC;' // wait for a tick, as cookie modification happens in a promise @@ -30,9 +19,8 @@ describe('Cookie protection tests', () => { expect(result.expires).toBeLessThan(Date.now() + 605_000_000) }) - it('non-string cookie values do not bypass protection', async () => { - const page = await browser.newPage() - await page.goto('http://localhost:8080/index.html') + test('non-string cookie values do not bypass protection', async ({ page }) => { + await gotoAndWait(page, '/index.html') const result = await page.evaluate(async () => { // @ts-expect-error - Invalid argument to document.cookie on purpose for test @@ -53,11 +41,11 @@ describe('Cookie protection tests', () => { expect(result.expires).toBeLessThan(Date.now() + 605_000_000) }) - it('Erroneous values do not throw', async () => { - const page = await browser.newPage() - await page.goto('http://localhost:8080/index.html') - + test('Erroneous values do not throw', async ({ page }) => { + await gotoAndWait(page, '/index.html') const result = await page.evaluate(async () => { + document.cookie = 'a=b; expires=Wed, 21 Aug 2040 20:00:00 UTC;' + // @ts-expect-error - Invalid argument to document.cookie on purpose for test document.cookie = null diff --git a/integration-test/test-fingerprint.js b/integration-test/test-fingerprint.js index 27abd32ba7..7154e870b5 100644 --- a/integration-test/test-fingerprint.js +++ b/integration-test/test-fingerprint.js @@ -1,8 +1,10 @@ /** * Tests for fingerprint defenses. Ensure that fingerprinting is actually being blocked. */ +import { test as base, expect } from '@playwright/test' +import { testContext } from './helpers/harness.js' -import { setup } from './helpers/harness.js' +const test = testContext(base) const expectedFingerprintValues = { availTop: 0, @@ -17,170 +19,118 @@ const expectedFingerprintValues = { const pagePath = '/index.html' const tests = [ - { url: `localhost:8080${pagePath}` }, - { url: `127.0.0.1:8383${pagePath}` } + { url: `http://localhost:3220${pagePath}` }, + { url: `http://127.0.0.1:8383${pagePath}` } ] function testFPValues (values) { for (const [name, prop] of Object.entries(values)) { - expect(prop).withContext(`${name}`).toEqual(expectedFingerprintValues[name]) + expect(prop).toEqual(expectedFingerprintValues[name]) } } -describe('Fingerprint Defense Tests', () => { - let browser - let teardown - let setupServer - beforeAll(async () => { - ({ browser, teardown, setupServer } = await setup()) - - setupServer('8080') - setupServer('8383') - }) - afterAll(async () => { - await teardown() +test.describe.serial('All Fingerprint Defense Tests (must run in serial)', () => { + test.describe.serial('Fingerprint Defense Tests', () => { + for (const _test of tests) { + test(`${_test.url} should include anti-fingerprinting code`, async ({ page, altServerPort }) => { + console.log('running:', altServerPort) + await page.goto(_test.url) + const values = await page.evaluate(() => { + return { + // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f + availTop: screen.availTop, + // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f + availLeft: screen.availLeft, + // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f + wAvailTop: window.screen.availTop, + // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f + wAvailLeft: window.screen.availLeft, + colorDepth: screen.colorDepth, + pixelDepth: screen.pixelDepth, + productSub: navigator.productSub, + vendorSub: navigator.vendorSub + } + }) + testFPValues(values) + + await page.close() + }) + } }) - for (const test of tests) { - it(`${test.url} should include anti-fingerprinting code`, async () => { - const page = await browser.newPage() - - try { - await page.goto(`http://${test.url}`) - } catch (e) { - // timed out waiting for page to load, let's try running the test anyway - } - const values = await page.evaluate(() => { - return { + test.describe.serial('First Party Fingerprint Randomization', () => { + /** + * @param {import("@playwright/test").Page} page + * @param {tests[number]} test + */ + async function runTest (page, test) { + await page.goto(test.url) + await page.addScriptTag({ path: 'node_modules/@fingerprintjs/fingerprintjs/dist/fp.js' }) + + const fingerprint = await page.evaluate(() => { + /* global FingerprintJS */ + return (async () => { // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f - availTop: screen.availTop, - // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f - availLeft: screen.availLeft, - // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f - wAvailTop: window.screen.availTop, - // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f - wAvailLeft: window.screen.availLeft, - colorDepth: screen.colorDepth, - pixelDepth: screen.pixelDepth, - productSub: navigator.productSub, - vendorSub: navigator.vendorSub - } + const fp = await FingerprintJS.load() + return fp.get() + })() }) - testFPValues(values) - - await page.close() - }) - } -}) - -describe('First Party Fingerprint Randomization', () => { - let browser - let teardown - let setupServer - beforeAll(async () => { - ({ browser, setupServer, teardown } = await setup()) - - setupServer('8080') - setupServer('8383') - }) - afterAll(async () => { - await teardown() - }) - - async function runTest (test) { - const page = await browser.newPage() - - try { - await page.goto(`http://${test.url}`) - } catch (e) { - // timed out waiting for page to load, let's try running the test anyway - } - - await page.addScriptTag({ path: 'node_modules/@fingerprintjs/fingerprintjs/dist/fp.js' }) - const fingerprint = await page.evaluate(() => { - /* global FingerprintJS */ - return (async () => { - // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f - const fp = await FingerprintJS.load() - return fp.get() - })() - }) - - await page.close() - - return { - canvas: fingerprint.components.canvas.value, - plugin: fingerprint.components.plugins.value + return { + canvas: fingerprint.components.canvas.value, + plugin: fingerprint.components.plugins.value + } } - } - - for (const testCase of tests) { - it('Fingerprints should not change amongst page loads', async () => { - const result = await runTest(testCase) - - const result2 = await runTest(testCase) - expect(result.canvas).toEqual(result2.canvas) - expect(result.plugin).toEqual(result2.plugin) - }) - } - - it('Fingerprints should not match across first parties', async () => { - const canvas = new Set() - const plugin = new Set() for (const testCase of tests) { - const result = await runTest(testCase) + test(`Fingerprints should not change amongst page loads test ${testCase.url}`, async ({ page, altServerPort }) => { + console.log('running:', altServerPort) + const result = await runTest(page, testCase) - // Add the fingerprints to a set, if the result doesn't match it won't be added - canvas.add(JSON.stringify(result.canvas)) - plugin.add(JSON.stringify(result.plugin)) + const result2 = await runTest(page, testCase) + expect(result.canvas).toEqual(result2.canvas) + expect(result.plugin).toEqual(result2.plugin) + }) } - // Ensure that the number of test pages match the number in the set - expect(canvas.size).toEqual(tests.length) - expect(plugin.size).toEqual(1) - }) -}) + test('Fingerprints should not match across first parties', async ({ page, altServerPort }) => { + console.log('running:', altServerPort) + const canvas = new Set() + const plugin = new Set() -describe('Verify injected script is not visible to the page', () => { - let browser - let teardown - let setupServer - beforeAll(async () => { - ({ browser, setupServer, teardown } = await setup()) + for (const testCase of tests) { + const result = await runTest(page, testCase) - setupServer('8080') - setupServer('8383') - }) - afterAll(async () => { - await teardown() + // Add the fingerprints to a set, if the result doesn't match it won't be added + canvas.add(JSON.stringify(result.canvas)) + plugin.add(JSON.stringify(result.plugin)) + } + + // Ensure that the number of test pages match the number in the set + expect(canvas.size).toEqual(tests.length) + expect(plugin.size).toEqual(1) + }) }) - tests.forEach(test => { - it('Fingerprints should not match across first parties', async () => { - const page = await browser.newPage(pagePath) + test.describe.serial('Verify injected script is not visible to the page', () => { + tests.forEach(testCase => { + test(`Fingerprints should not match across first parties ${testCase.url}`, async ({ page, altServerPort }) => { + console.log('running:', altServerPort) + await page.goto(testCase.url) - try { - await page.goto(`http://${test.url}`) - } catch (e) { - // timed out waiting for page to load, let's try running the test anyway - } + // give it another second just to be sure + await page.waitForTimeout(1000) - // give it another second just to be sure - await page.waitForTimeout(1000) + const sjclVal = await page.evaluate(() => { + if ('sjcl' in window) { + return 'visible' + } else { + return 'invisible' + } + }) - const sjclVal = await page.evaluate(() => { - if ('sjcl' in window) { - return 'visible' - } else { - return 'invisible' - } + expect(sjclVal).toEqual('invisible') }) - - await page.close() - - expect(sjclVal).toEqual('invisible') }) }) }) diff --git a/integration-test/test-navigator-interface.js b/integration-test/test-navigator-interface.js index 5260e8bbd3..87bbb70f6b 100644 --- a/integration-test/test-navigator-interface.js +++ b/integration-test/test-navigator-interface.js @@ -1,27 +1,14 @@ /** * Tests for injecting navigator.duckduckgo into the page */ -import { setup } from './helpers/harness.js' +import { test as base, expect } from '@playwright/test' +import { gotoAndWait, testContext } from './helpers/harness.js' -describe('Ensure navigator interface is injected', () => { - let browser - let server - let teardown - let setupServer - let gotoAndWait - beforeAll(async () => { - ({ browser, setupServer, teardown, gotoAndWait } = await setup({ withExtension: true })) - server = setupServer() - }) - afterAll(async () => { - await server?.close() - await teardown() - }) +const test = testContext(base) - it('should expose navigator.navigator.isDuckDuckGo(): Promise and platform === "extension"', async () => { - const port = server.address().port - const page = await browser.newPage() - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { platform: { name: 'extension' } }) +test.describe('Ensure navigator interface is injected', () => { + test('should expose navigator.navigator.isDuckDuckGo(): Promise and platform === "extension"', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { platform: { name: 'extension' } }) const isDuckDuckGoResult = await page.evaluate( () => { // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f diff --git a/integration-test/test-pages.js b/integration-test/test-pages.js index 700d4ee971..c6fe91f5fd 100644 --- a/integration-test/test-pages.js +++ b/integration-test/test-pages.js @@ -1,37 +1,24 @@ /** * Tests for runtime checks */ -import { processConfig } from '../src/utils.js' -import { setup } from './helpers/harness.js' import * as fs from 'fs' +import { test as base, expect } from '@playwright/test' +import { processConfig } from '../src/utils.js' import polyfillProcessGlobals from '../unit-test/helpers/pollyfil-for-process-globals.js' +import { gotoAndWait, testContext } from './helpers/harness.js' -describe('Test integration pages', () => { - let browser - let server - let teardown - let setupIntegrationPagesServer - let gotoAndWait - beforeAll(async () => { - ({ browser, setupIntegrationPagesServer, teardown, gotoAndWait } = await setup({ withExtension: true })) - server = setupIntegrationPagesServer() - }) - afterAll(async () => { - await server?.close() - await teardown() - }) +const test = testContext(base) +test.describe('Test integration pages', () => { /** + * @param {import("@playwright/test").Page} page * @param {string} pageName * @param {string} configPath * @param {string} [evalBeforeInit] */ - async function testPage (pageName, configPath, evalBeforeInit) { - const port = server.address().port - const page = await browser.newPage() - const res = fs.readFileSync(configPath) - // @ts-expect-error - JSON.parse returns any - const config = JSON.parse(res) + async function testPage (page, pageName, configPath, evalBeforeInit) { + const res = fs.readFileSync(configPath, 'utf8') + const config = JSON.parse(res.toString()) polyfillProcessGlobals() /** @type {import('../src/utils.js').UserPreferences} */ @@ -43,7 +30,7 @@ describe('Test integration pages', () => { } const processedConfig = processConfig(config, /* userList */ [], /* preferences */ userPreferences/*, platformSpecificFeatures = [] */) - await gotoAndWait(page, `http://localhost:${port}/${pageName}?automation=true`, processedConfig, evalBeforeInit) + await gotoAndWait(page, `/${pageName}?automation=true`, processedConfig, evalBeforeInit) // Check page results const pageResults = await page.evaluate( () => { @@ -66,13 +53,14 @@ describe('Test integration pages', () => { ) for (const key in pageResults) { for (const result of pageResults[key]) { - expect(result.result).withContext(key + ':\n ' + result.name).toEqual(result.expected) + expect(result.result).toEqual(result.expected) } } } - it('Web compat shims correctness', async () => { + test('Web compat shims correctness', async ({ page }) => { await testPage( + page, 'webcompat/pages/shims.html', `${process.cwd()}/integration-test/test-pages/webcompat/config/shims.json` ) diff --git a/integration-test/pages/blank.html b/integration-test/test-pages/blank.html similarity index 100% rename from integration-test/pages/blank.html rename to integration-test/test-pages/blank.html diff --git a/integration-test/pages/index.html b/integration-test/test-pages/index.html similarity index 100% rename from integration-test/pages/index.html rename to integration-test/test-pages/index.html diff --git a/integration-test/test-utils.js b/integration-test/test-utils.js index b257494a31..97d69e6ab9 100644 --- a/integration-test/test-utils.js +++ b/integration-test/test-utils.js @@ -1,27 +1,14 @@ /** * Tests for utils */ -import { setup } from './helpers/harness.js' +import { test as base, expect } from '@playwright/test' +import { gotoAndWait, testContext } from './helpers/harness.js' -describe('Ensure utils behave as expected', () => { - let browser - let server - let teardown - let setupServer - let gotoAndWait - beforeAll(async () => { - ({ browser, setupServer, teardown, gotoAndWait } = await setup({ withExtension: true })) - server = setupServer() - }) - afterAll(async () => { - await server?.close() - await teardown() - }) +const test = testContext(base) - it('should toString DDGProxy correctly', async () => { - const port = server.address().port - const page = await browser.newPage() - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { platform: { name: 'extension' } }) +test.describe('Ensure utils behave as expected', () => { + test('should toString DDGProxy correctly', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { platform: { name: 'extension' } }) const toStringResult = await page.evaluate('HTMLCanvasElement.prototype.getContext.toString()') expect(toStringResult).toEqual('function getContext() { [native code] }') diff --git a/integration-test/test-web-compat.js b/integration-test/test-web-compat.js index 5bd602866b..1c97cbc0bc 100644 --- a/integration-test/test-web-compat.js +++ b/integration-test/test-web-compat.js @@ -1,34 +1,17 @@ -/** - * Tests for injecting navigator.duckduckgo into the page - */ -import { setup } from './helpers/harness.js' - -describe('Ensure safari interface is injected', () => { - let browser - let server - let teardown - let setupServer - let gotoAndWait - beforeAll(async () => { - ({ browser, setupServer, teardown, gotoAndWait } = await setup({ withExtension: true })) - server = setupServer() - }) - afterAll(async () => { - await server?.close() - await teardown() - }) +import { gotoAndWait, testContext } from './helpers/harness.js' +import { test as base, expect } from '@playwright/test' - it('should expose window.safari when enabled', async () => { - const port = server.address().port - const page = await browser.newPage() +const test = testContext(base) - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { site: { enabledFeatures: [] } }) +test.describe('Ensure safari interface is injected', () => { + test('should expose window.safari when enabled', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: [] } }) const noSafari = await page.evaluate(() => { return 'safari' in window }) expect(noSafari).toEqual(false) - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, @@ -80,24 +63,8 @@ describe('Ensure safari interface is injected', () => { }) }) -describe('Ensure Notification interface is injected', () => { - let browser - let server - let teardown - let setupServer - let gotoAndWait - beforeAll(async () => { - ({ browser, setupServer, teardown, gotoAndWait } = await setup({ withExtension: true })) - server = setupServer() - }) - afterAll(async () => { - await server?.close() - await teardown() - }) - - it('should expose window.Notification when enabled', async () => { - const port = server.address().port - const page = await browser.newPage() +test.describe('Ensure Notification interface is injected', () => { + test('should expose window.Notification when enabled', async ({ page }) => { // Fake the Notification API not existing in this browser const removeNotificationScript = ` delete window.Notification @@ -113,19 +80,19 @@ describe('Ensure Notification interface is injected', () => { } return out } - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { site: { enabledFeatures: [] } }) + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: [] } }) const initialNotification = await page.evaluate(checkForNotification) // Base implementation of the test env should have it. expect(initialNotification).toEqual(true) const initialDescriptorSerialization = await page.evaluate(checkObjectDescriptorSerializedValue) - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { site: { enabledFeatures: [] } }, removeNotificationScript) + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: [] } }, removeNotificationScript) const noNotification = await page.evaluate(() => { return 'Notification' in window }) expect(noNotification).toEqual(false) - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, @@ -159,21 +126,7 @@ describe('Ensure Notification interface is injected', () => { }) }) -describe('Permissions API', () => { - let browser - let server - let teardown - let setupServer - let gotoAndWait - beforeAll(async () => { - ({ browser, setupServer, teardown, gotoAndWait } = await setup({ withExtension: true })) - server = setupServer() - }) - afterAll(async () => { - await server?.close() - await teardown() - }) - +test.describe('Permissions API', () => { // Fake the Permission API not existing in this browser const removePermissionsScript = ` Object.defineProperty(window.navigator, 'permissions', { writable: true, value: undefined }) @@ -187,31 +140,26 @@ describe('Permissions API', () => { return descriptor === undefined } - describe('disabled feature', () => { - it('should not expose permissions API', async () => { - const port = server.address().port - const page = await browser.newPage() - - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { site: { enabledFeatures: [] } }) + test.describe('disabled feature', () => { + test('should not expose permissions API', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: [] } }) const initialPermissions = await page.evaluate(checkForPermissions) // Base implementation of the test env should have it. expect(initialPermissions).toEqual(true) const initialDescriptorSerialization = await page.evaluate(checkObjectDescriptorIsNotPresent) expect(initialDescriptorSerialization).toEqual(true) - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { site: { enabledFeatures: [] } }, removePermissionsScript) + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: [] } }, removePermissionsScript) const noPermissions = await page.evaluate(checkForPermissions) expect(noPermissions).toEqual(false) }) }) - describe('enabled feature', () => { - let port - let page - - beforeAll(async () => { - port = server.address().port - page = await browser.newPage() - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test.describe('enabled feature', () => { + /** + * @param {import("@playwright/test").Page} page + */ + async function before (page) { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, @@ -233,9 +181,13 @@ describe('Permissions API', () => { } } }, removePermissionsScript) - }) - - async function checkPermission (name) { + } + /** + * @param {import("@playwright/test").Page} page + * @param {any} name + * @return {Promise<{result: any, message: *}>} + */ + async function checkPermission (page, name) { const payload = `window.navigator.permissions.query(${JSON.stringify({ name })})` const result = await page.evaluate(payload).catch((e) => { return { threw: e } @@ -245,27 +197,32 @@ describe('Permissions API', () => { }) return { result, message } } - it('should expose window.navigator.permissions when enabled', async () => { + test('should expose window.navigator.permissions when enabled', async ({ page }) => { + await before(page) const hasPermissions = await page.evaluate(checkForPermissions) expect(hasPermissions).toEqual(true) const modifiedDescriptorSerialization = await page.evaluate(checkObjectDescriptorIsNotPresent) // This fails in a test condition purely because we have to add a descriptor to modify the prop expect(modifiedDescriptorSerialization).toEqual(false) }) - it('should throw error when permission not supported', async () => { - const { result } = await checkPermission('notexistent') + test('should throw error when permission not supported', async ({ page }) => { + await before(page) + const { result } = await checkPermission(page, 'notexistent') expect(result.threw).not.toBeUndefined() expect(result.threw.message).toContain('notexistent') }) - it('should return prompt by default', async () => { - const { result } = await checkPermission('geolocation') - expect(result).toEqual(jasmine.objectContaining({ name: 'geolocation', state: 'prompt' })) + test('should return prompt by default', async ({ page }) => { + await before(page) + const { result } = await checkPermission(page, 'geolocation') + expect(result).toMatchObject({ name: 'geolocation', state: 'prompt' }) }) - it('should return updated name when configured', async () => { - const { result } = await checkPermission('push') - expect(result).toEqual(jasmine.objectContaining({ name: 'notifications', state: 'prompt' })) + test('should return updated name when configured', async ({ page }) => { + await before(page) + const { result } = await checkPermission(page, 'push') + expect(result).toMatchObject({ name: 'notifications', state: 'prompt' }) }) - it('should propagate result from native when configured', async () => { + test('should propagate result from native when configured', async ({ page }) => { + await before(page) // Fake result from native await page.evaluate(() => { globalThis.cssMessaging.impl.request = (req) => { @@ -273,52 +230,49 @@ describe('Permissions API', () => { return Promise.resolve({ state: 'granted' }) } }) - const { result, message } = await checkPermission('camera') - expect(result).toEqual(jasmine.objectContaining({ name: 'video_capture', state: 'granted' })) - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'permissionsQuery', params: { name: 'camera' } })) - }) - it('should default to prompt when native sends unexpected response', async () => { + const { result, message } = await checkPermission(page, 'camera') + expect(result).toMatchObject({ name: 'video_capture', state: 'granted' }) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'permissionsQuery', params: { name: 'camera' } }) + }) + test('should default to prompt when native sends unexpected response', async ({ page }) => { + await before(page) + page.on('console', msg => { + console.log(`PAGE LOG: ${msg.text()}`) + }) + await page.evaluate(() => { - globalThis.cssMessaging.impl.request = () => { + globalThis.cssMessaging.impl.request = (message) => { + globalThis.shareReq = message return Promise.resolve({ noState: 'xxx' }) } }) - const { result, message } = await checkPermission('camera') - expect(result).toEqual(jasmine.objectContaining({ name: 'video_capture', state: 'prompt' })) - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'permissionsQuery', params: { name: 'camera' } })) + const { result, message } = await checkPermission(page, 'camera') + expect(result).toMatchObject({ name: 'video_capture', state: 'prompt' }) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'permissionsQuery', params: { name: 'camera' } }) }) - it('should default to prompt when native error occurs', async () => { + test('should default to prompt when native error occurs', async ({ page }) => { + await before(page) await page.evaluate(() => { - globalThis.cssMessaging.impl.request = () => { + globalThis.cssMessaging.impl.request = (message) => { + globalThis.shareReq = message return Promise.reject(new Error('something wrong')) } }) - const { result, message } = await checkPermission('camera') - expect(result).toEqual(jasmine.objectContaining({ name: 'video_capture', state: 'prompt' })) - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'permissionsQuery', params: { name: 'camera' } })) + const { result, message } = await checkPermission(page, 'camera') + expect(result).toMatchObject({ name: 'video_capture', state: 'prompt' }) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'permissionsQuery', params: { name: 'camera' } }) }) }) }) -describe('ScreenOrientation API', () => { - let browser - let server - let teardown - let setupServer - let gotoAndWait - let port - let page - beforeAll(async () => { - ({ browser, setupServer, teardown, gotoAndWait } = await setup({ withExtension: true })) - server = setupServer() - }) - afterAll(async () => { - await server?.close() - await teardown() - }) - - describe('disabled feature', () => { - async function checkLockThrows (orientation) { +test.describe('ScreenOrientation API', () => { + test.describe('disabled feature', () => { + /** + * @param {import("@playwright/test").Page} page + * @param {any} orientation + * @return {Promise} + */ + async function checkLockThrows (page, orientation) { const payload = `screen.orientation.lock(${JSON.stringify(orientation)})` const result = await page.evaluate(payload).catch((e) => { return { threw: e } @@ -326,26 +280,18 @@ describe('ScreenOrientation API', () => { return result } - it(' should not fix screenOrientation API', async () => { - port = server.address().port - page = await browser.newPage() - + test(' should not fix screenOrientation API', async ({ page }) => { // no screenLock setting - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { site: { enabledFeatures: ['webCompat'] } }) - const result = await checkLockThrows('landscape') + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] } }) + const result = await checkLockThrows(page, 'landscape') expect(result.threw).not.toBeUndefined() - expect(result.threw.message).toEqual('screen.orientation.lock() is not available on this device.') + expect(result.threw.message).toContain('screen.orientation.lock() is not available on this device.') }) }) - describe('enabled feature', () => { - let port - let page - - beforeAll(async () => { - port = server.address().port - page = await browser.newPage() - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test.describe('enabled feature', () => { + async function beforeAll (page) { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, @@ -355,9 +301,13 @@ describe('ScreenOrientation API', () => { } } }) - }) + } - async function checkLock (orientation) { + /** + * @param {import("@playwright/test").Page} page + * @param {any} orientation + */ + async function checkLock (page, orientation) { const payload = `screen.orientation.lock(${JSON.stringify(orientation)})` const result = await page.evaluate(payload).catch((e) => { return { threw: e } @@ -368,7 +318,10 @@ describe('ScreenOrientation API', () => { return { result, message } } - async function checkUnlock () { + /** + * @param {import("@playwright/test").Page} page + */ + async function checkUnlock (page) { const payload = 'screen.orientation.unlock()' const result = await page.evaluate(payload).catch((e) => { return { threw: e } @@ -379,61 +332,68 @@ describe('ScreenOrientation API', () => { return { result, message } } - it('should err out when orientation not provided', async () => { - const { result } = await checkLock() + test('should err out when orientation not provided', async ({ page }) => { + await beforeAll(page) + const { result } = await checkLock(page, undefined) expect(result.threw).not.toBeUndefined() expect(result.threw.message).toContain("Failed to execute 'lock' on 'ScreenOrientation': 1 argument required, but only 0 present") }) - it('should err out when orientation of unexpected type', async () => { - const { result } = await checkLock({}) + test('should err out when orientation of unexpected type', async ({ page }) => { + await beforeAll(page) + const { result } = await checkLock(page, {}) expect(result.threw).not.toBeUndefined() expect(result.threw.message).toContain('not a valid enum value of type OrientationLockType') }) - it('should err out when orientation of unexpected value', async () => { - const { result } = await checkLock('xxx') + test('should err out when orientation of unexpected value', async ({ page }) => { + await beforeAll(page) + const { result } = await checkLock(page, 'xxx') expect(result.threw).not.toBeUndefined() expect(result.threw.message).toContain('not a valid enum value of type OrientationLockType') }) - it('should propagate native TypeError', async () => { + test('should propagate native TypeError', async ({ page }) => { + await beforeAll(page) await page.evaluate(() => { globalThis.cssMessaging.impl.request = () => { return Promise.resolve({ failure: { name: 'TypeError', message: 'some error message' } }) } }) - const { result } = await checkLock('landscape') + const { result } = await checkLock(page, 'landscape') expect(result.threw).not.toBeUndefined() expect(result.threw.message).toContain('some error message') }) - it('should propagate native InvalidStateError', async () => { + test('should propagate native InvalidStateError', async ({ page }) => { + await beforeAll(page) await page.evaluate(() => { globalThis.cssMessaging.impl.request = () => { return Promise.resolve({ failure: { name: 'InvalidStateError', message: 'some error message' } }) } }) - const { result } = await checkLock('landscape') + const { result } = await checkLock(page, 'landscape') expect(result.threw).not.toBeUndefined() expect(result.threw.message).toContain('some error message') }) - it('should propagate native default error', async () => { + test('should propagate native default error', async ({ page }) => { + await beforeAll(page) await page.evaluate(() => { globalThis.cssMessaging.impl.request = () => { return Promise.resolve({ failure: { name: 'xxx', message: 'some error message' } }) } }) - const { result } = await checkLock('landscape') + const { result } = await checkLock(page, 'landscape') expect(result.threw).not.toBeUndefined() expect(result.threw.message).toContain('some error message') }) - it('should fix screenOrientation API', async () => { + test('should fix screenOrientation API', async ({ page }) => { + await beforeAll(page) await page.evaluate(() => { globalThis.cssMessaging.impl.request = (req) => { globalThis.lockReq = req @@ -441,12 +401,13 @@ describe('ScreenOrientation API', () => { } }) - const { result, message } = await checkLock('landscape') + const { result, message } = await checkLock(page, 'landscape') expect(result).toBeUndefined() - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'screenLock', params: { orientation: 'landscape' } })) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'screenLock', params: { orientation: 'landscape' } }) }) - it('should send message on unlock', async () => { + test('should send message on unlock', async ({ page }) => { + await beforeAll(page) await page.evaluate(() => { globalThis.cssMessaging.impl.request = (req) => { globalThis.lockReq = req @@ -454,28 +415,14 @@ describe('ScreenOrientation API', () => { } }) - const { result, message } = await checkUnlock() + const { result, message } = await checkUnlock(page) expect(result).toBeUndefined() - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'screenUnlock' })) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'screenUnlock' }) }) }) }) -describe('Web Share API', () => { - let browser - let server - let teardown - let setupServer - let gotoAndWait - beforeAll(async () => { - ({ browser, setupServer, teardown, gotoAndWait } = await setup({ withExtension: true })) - server = setupServer() - }) - afterAll(async () => { - await server?.close() - await teardown() - }) - +test.describe('Web Share API', () => { function checkForCanShare () { return 'canShare' in navigator } @@ -483,11 +430,9 @@ describe('Web Share API', () => { return 'share' in navigator } - describe('disabled feature', () => { - it('should not expose navigator.canShare() and navigator.share()', async () => { - const port = server.address().port - const page = await browser.newPage() - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { site: { enabledFeatures: [] } }) + test.describe('disabled feature', () => { + test('should not expose navigator.canShare() and navigator.share()', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: [] } }) const noCanShare = await page.evaluate(checkForCanShare) const noShare = await page.evaluate(checkForShare) // Base implementation of the test env should not have it (it's only available on mobile) @@ -496,11 +441,9 @@ describe('Web Share API', () => { }) }) - describe('disabled sub-feature', () => { - it('should not expose navigator.canShare() and navigator.share()', async () => { - const port = server.address().port - const page = await browser.newPage() - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test.describe('disabled sub-feature', () => { + test('should not expose navigator.canShare() and navigator.share()', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, @@ -518,14 +461,9 @@ describe('Web Share API', () => { }) }) - describe('enabled feature', () => { - let port - let page - - beforeAll(async () => { - port = server.address().port - page = await browser.newPage() - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test.describe('enabled feature', () => { + async function navigate (page) { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, @@ -535,38 +473,43 @@ describe('Web Share API', () => { } } }) - }) + } - it('should expose navigator.canShare() and navigator.share() when enabled', async () => { + test('should expose navigator.canShare() and navigator.share() when enabled', async ({ page }) => { + await navigate(page) const hasCanShare = await page.evaluate(checkForCanShare) const hasShare = await page.evaluate(checkForShare) expect(hasCanShare).toEqual(true) expect(hasShare).toEqual(true) }) - describe('navigator.canShare()', () => { - it('should not let you share files', async () => { + test.describe('navigator.canShare()', () => { + test('should not let you share files', async ({ page }) => { + await navigate(page) const refuseFileShare = await page.evaluate(() => { return navigator.canShare({ text: 'xxx', files: [] }) }) expect(refuseFileShare).toEqual(false) }) - it('should not let you share non-http urls', async () => { + test('should not let you share non-http urls', async ({ page }) => { + await navigate(page) const refuseShare = await page.evaluate(() => { return navigator.canShare({ url: 'chrome://bla' }) }) expect(refuseShare).toEqual(false) }) - it('should allow relative links', async () => { + test('should allow relative links', async ({ page }) => { + await navigate(page) const allowShare = await page.evaluate(() => { return navigator.canShare({ url: 'bla' }) }) expect(allowShare).toEqual(true) }) - it('should support only the specific fields', async () => { + test('should support only the specific fields', async ({ page }) => { + await navigate(page) const refuseShare = await page.evaluate(() => { // eslint-disable-next-line // @ts-ignore intentionally malformed data @@ -575,7 +518,8 @@ describe('Web Share API', () => { expect(refuseShare).toEqual(false) }) - it('should let you share stuff', async () => { + test('should let you share stuff', async ({ page }) => { + await navigate(page) let canShare = await page.evaluate(() => { return navigator.canShare({ url: 'http://example.com' }) }) @@ -598,94 +542,122 @@ describe('Web Share API', () => { }) }) - describe('navigator.share()', () => { - describe('(no errors from Android)', () => { - beforeEach(async () => { - await page.evaluate(() => { - globalThis.shareReq = null - globalThis.cssMessaging.impl.request = (req) => { - globalThis.shareReq = req - return Promise.resolve({}) - } - }) + test.describe('navigator.share()', () => { + async function beforeEach (page) { + await page.evaluate(() => { + globalThis.shareReq = null + globalThis.cssMessaging.impl.request = (req) => { + globalThis.shareReq = req + return Promise.resolve({}) + } }) - - async function checkShare (data) { + } + test.describe('(no errors from Android)', () => { + /** + * @param {import("@playwright/test").Page} page + * @param {any} data + * @return {Promise} + */ + async function checkShare (page, data) { const payload = `navigator.share(${JSON.stringify(data)})` const result = await page.evaluate(payload).catch((e) => { return { threw: e } }) + console.log('check share') const message = await page.evaluate(() => { + console.log('did read?') return globalThis.shareReq }) return { result, message } } - it('should let you share text', async () => { - const { result, message } = await checkShare({ text: 'xxx' }) - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'webShare', params: { text: 'xxx' } })) + test('should let you share text', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { text: 'xxx' }) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'webShare', params: { text: 'xxx' } }) expect(result).toBeUndefined() }) - it('should let you share url', async () => { - const { result, message } = await checkShare({ url: 'http://example.com' }) - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'webShare', params: { url: 'http://example.com/' } })) + test('should let you share url', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { url: 'http://example.com' }) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'webShare', params: { url: 'http://example.com/' } }) expect(result).toBeUndefined() }) - it('should let you share title alone', async () => { - const { result, message } = await checkShare({ title: 'xxx' }) - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'webShare', params: { title: 'xxx', text: '' } })) + test('should let you share title alone', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { title: 'xxx' }) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'webShare', params: { title: 'xxx', text: '' } }) expect(result).toBeUndefined() }) - it('should let you share title and text', async () => { - const { result, message } = await checkShare({ title: 'xxx', text: 'yyy' }) - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'webShare', params: { title: 'xxx', text: 'yyy' } })) + test('should let you share title and text', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { title: 'xxx', text: 'yyy' }) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'webShare', params: { title: 'xxx', text: 'yyy' } }) expect(result).toBeUndefined() }) - it('should let you share title and url', async () => { - const { result, message } = await checkShare({ title: 'xxx', url: 'http://example.com' }) - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'webShare', params: { title: 'xxx', url: 'http://example.com/' } })) + test('should let you share title and url', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { title: 'xxx', url: 'http://example.com' }) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'webShare', params: { title: 'xxx', url: 'http://example.com/' } }) expect(result).toBeUndefined() }) - it('should combine text and url when both are present', async () => { - const { result, message } = await checkShare({ text: 'xxx', url: 'http://example.com' }) - expect(message).toEqual(jasmine.objectContaining({ featureName: 'webCompat', method: 'webShare', params: { text: 'xxx http://example.com/' } })) + test('should combine text and url when both are present', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { text: 'xxx', url: 'http://example.com' }) + expect(message).toMatchObject({ featureName: 'webCompat', method: 'webShare', params: { text: 'xxx http://example.com/' } }) expect(result).toBeUndefined() }) - it('should throw when sharing files', async () => { - const { result, message } = await checkShare({ title: 'title', files: [] }) + test('should throw when sharing files', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { title: 'title', files: [] }) expect(message).toBeNull() - expect(result.threw.message).toEqual('Invalid share data') - expect(result.threw.name).toEqual('TypeError') + expect(result.threw.message).toContain('TypeError: Invalid share data') }) - it('should throw when sharing non-http urls', async () => { - const { result, message } = await checkShare({ url: 'chrome://bla' }) + test('should throw when sharing non-http urls', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { url: 'chrome://bla' }) expect(message).toBeNull() - expect(result.threw.message).toEqual('Invalid share data') - expect(result.threw.name).toEqual('TypeError') + expect(result.threw.message).toContain('TypeError: Invalid share data') }) - it('should handle relative urls', async () => { - const { result, message } = await checkShare({ url: 'bla' }) + test('should handle relative urls', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { url: 'bla' }) expect(message.params.url).toMatch(/^http:\/\/localhost:\d+\/bla$/) expect(result).toBeUndefined() }) - it('should treat empty url as relative', async () => { - const { result, message } = await checkShare({ url: '' }) + test('should treat empty url as relative', async ({ page }) => { + await navigate(page) + await beforeEach(page) + const { result, message } = await checkShare(page, { url: '' }) expect(message.params.url).toMatch(/^http:\/\/localhost:\d+\//) expect(result).toBeUndefined() }) }) - describe('(handling errors from Android)', () => { - it('should handle messaging error', async () => { + test.describe('(handling errors from Android)', () => { + test('should handle messaging error', async ({ page }) => { + // page.on('console', (msg) => console.log(msg.type(), msg.text())) + await navigate(page) + await beforeEach(page) + await page.evaluate(() => { globalThis.cssMessaging.impl.request = () => { return Promise.reject(new Error('something wrong')) @@ -694,11 +666,14 @@ describe('Web Share API', () => { const result = await page.evaluate('navigator.share({ text: "xxx" })').catch((e) => { return { threw: e } }) - expect(result.threw.message).toEqual('something wrong') - expect(result.threw.name).toEqual('DOMException') + + expect(result.threw.message).toContain('something wrong') + expect(result.threw.message).toContain('DOMException') }) - it('should handle soft failures', async () => { + test('should handle soft failures', async ({ page }) => { + await navigate(page) + await beforeEach(page) await page.evaluate(() => { globalThis.cssMessaging.impl.request = () => { return Promise.resolve({ failure: { name: 'AbortError', message: 'some error message' } }) @@ -708,55 +683,33 @@ describe('Web Share API', () => { return { threw: e } }) console.error(result.threw) - expect(result.threw.message).toEqual('some error message') - expect(result.threw.name).toEqual('DOMException') + expect(result.threw.message).toContain('some error message') + expect(result.threw.message).toContain('DOMException') }) }) }) }) }) -describe('Viewport fixes', () => { - let browser - let server - let teardown - let setupServer - let gotoAndWait - let port - let page - - beforeAll(async () => { - ({ browser, setupServer, teardown, gotoAndWait } = await setup({ withExtension: true })) - server = setupServer() - }) - afterAll(async () => { - await server?.close() - await teardown() - }) - - beforeEach(async () => { - port = server.address().port - page = await browser.newPage() - }) - +test.describe('Viewport fixes', () => { function getViewportValue () { return document.querySelector('meta[name="viewport"]')?.getAttribute('content') } - it('should not change viewport if disabled', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { site: { enabledFeatures: [] } }, 'document.head.innerHTML += \'\'') + test('should not change viewport if disabled', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: [] } }, 'document.head.innerHTML += \'\'') const initialViewportValue = await page.evaluate(getViewportValue) // Base implementation of the test env should have it. expect(initialViewportValue).toEqual('width=device-width') // We don't make a change if disabled - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { site: { enabledFeatures: [] } }) + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: [] } }) const viewportValue = await page.evaluate(getViewportValue) expect(viewportValue).toBeUndefined() }) - it('should respect forced zoom', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test('should respect forced zoom', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: 'enabled' } }, desktopModeEnabled: false, @@ -767,9 +720,9 @@ describe('Viewport fixes', () => { expect(viewportValue).toEqual('initial-scale=1, user-scalable=yes, maximum-scale=10, width=device-width') }) - describe('Desktop mode off', () => { - it('should respect the forcedMobileValue config', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test.describe('Desktop mode off', () => { + test('should respect the forcedMobileValue config', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: { state: 'enabled', forcedMobileValue: 'bla, bla, bla' } } }, desktopModeEnabled: false @@ -778,8 +731,8 @@ describe('Viewport fixes', () => { expect(viewportValue).toEqual('bla, bla, bla') }) - it('should force wide viewport if the meta tag is not present', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test('should force wide viewport if the meta tag is not present', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: 'enabled' } }, desktopModeEnabled: false @@ -790,8 +743,8 @@ describe('Viewport fixes', () => { expect(viewportValue).toEqual(`width=${expectedWidth}, initial-scale=${(width / expectedWidth).toFixed(3)}, user-scalable=yes`) }) - it('should respect forced zoom', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test('should respect forced zoom', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: 'enabled' } }, desktopModeEnabled: false, @@ -803,8 +756,8 @@ describe('Viewport fixes', () => { expect(viewportValue).toEqual(`initial-scale=${(width / expectedWidth).toFixed(3)}, user-scalable=yes, maximum-scale=10, width=${expectedWidth}`) }) - it('should fix the WebView edge case', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test('should fix the WebView edge case', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: 'enabled' } }, desktopModeEnabled: false @@ -813,8 +766,8 @@ describe('Viewport fixes', () => { expect(viewportValue).toEqual('width=device-width, initial-scale=1.00001, something-something') }) - it('should ignore the character case in the viewport tag', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test('should ignore the character case in the viewport tag', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: 'enabled' } }, desktopModeEnabled: false @@ -824,9 +777,9 @@ describe('Viewport fixes', () => { }) }) - describe('Desktop mode on', () => { - it('should respect the forcedDesktopValue config', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test.describe('Desktop mode on', () => { + test('should respect the forcedDesktopValue config', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: { state: 'enabled', forcedDesktopValue: 'bla, bla, bla' } } }, desktopModeEnabled: true @@ -835,8 +788,8 @@ describe('Viewport fixes', () => { expect(viewportValue).toEqual('bla, bla, bla') }) - it('should force wide viewport, ignoring the viewport tag', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test('should force wide viewport, ignoring the viewport tag', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: 'enabled' } }, desktopModeEnabled: true @@ -847,8 +800,8 @@ describe('Viewport fixes', () => { expect(viewportValue).toEqual(`width=${expectedWidth}, initial-scale=${(width / expectedWidth).toFixed(3)}, user-scalable=yes, something-something`) }) - it('should force wide viewport, ignoring the viewport tag 2', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test('should force wide viewport, ignoring the viewport tag 2', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: 'enabled' } }, desktopModeEnabled: true @@ -859,8 +812,8 @@ describe('Viewport fixes', () => { expect(viewportValue).toEqual(`width=${expectedWidth}, initial-scale=${(width / expectedWidth).toFixed(3)}, user-scalable=yes, something-something`) }) - it('should respect forced zoom', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test('should respect forced zoom', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: 'enabled' } }, desktopModeEnabled: true, @@ -872,8 +825,8 @@ describe('Viewport fixes', () => { expect(viewportValue).toEqual(`initial-scale=${(width / expectedWidth).toFixed(3)}, user-scalable=yes, maximum-scale=10, width=${expectedWidth}, something-something`) }) - it('should ignore the character case in the viewport tag', async () => { - await gotoAndWait(page, `http://localhost:${port}/blank.html`, { + test('should ignore the character case in the viewport tag', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: ['webCompat'] }, featureSettings: { webCompat: { viewportWidth: 'enabled' } }, desktopModeEnabled: true diff --git a/package-lock.json b/package-lock.json index 9021175010..b298ce89bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,6 @@ "jasmine": "^5.3.0", "json-schema-to-typescript": "^13.1.2", "minimist": "^1.2.8", - "puppeteer": "^21.4.1", "rollup": "^3.29.4", "rollup-plugin-import-css": "^3.5.2", "rollup-plugin-svg-import": "^2.1.0", @@ -56,184 +55,6 @@ "node": ">=0.10.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@bcherny/json-schema-ref-parser": { "version": "10.0.5-fork", "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", @@ -887,27 +708,6 @@ "node": ">=16" } }, - "node_modules/@puppeteer/browsers": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.8.0.tgz", - "integrity": "sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==", - "dev": true, - "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "progress": "2.0.3", - "proxy-agent": "6.3.1", - "tar-fs": "3.0.4", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.2" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=16.3.0" - } - }, "node_modules/@rive-app/canvas-single": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/@rive-app/canvas-single/-/canvas-single-2.9.3.tgz", @@ -1050,12 +850,6 @@ } } }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true - }, "node_modules/@types/chrome": { "version": "0.0.248", "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.248.tgz", @@ -1157,16 +951,6 @@ "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, - "node_modules/@types/yauzl": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.2.tgz", - "integrity": "sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", @@ -1566,18 +1350,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1762,18 +1534,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dev": true, - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", @@ -1795,38 +1555,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", - "dev": true - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -1845,15 +1579,6 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "node_modules/basic-ftp": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz", - "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1876,39 +1601,6 @@ "node": ">=8" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", @@ -1976,19 +1668,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chromium-bidi": { - "version": "0.4.32", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.32.tgz", - "integrity": "sha512-RJnw0PW3sNdx1WclINVfVVx8JUH+tWTHZNpnEzlcM+Qgvf40dUH34U7gJq+cc/0LE+rbPxeT6ldqWrCbUf4jeg==", - "dev": true, - "dependencies": { - "mitt": "3.0.1", - "urlpattern-polyfill": "9.0.0" - }, - "peerDependencies": { - "devtools-protocol": "*" - } - }, "node_modules/classnames": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", @@ -2010,20 +1689,6 @@ "node": ">=0.10" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2100,41 +1765,6 @@ "node": ">= 0.4.0" } }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dev": true, - "dependencies": { - "node-fetch": "^2.6.12" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2159,15 +1789,6 @@ "type": "^1.0.1" } }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", - "dev": true, - "engines": { - "node": ">= 14" - } - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2231,26 +1852,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "dev": true, - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/devtools-protocol": { - "version": "0.0.1191157", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1191157.tgz", - "integrity": "sha512-Fu2mUhX7zkzLHMJZk5wQTiHdl1eJrhK0GypUoSzogUt51MmYEv/46pCz4PtGGFlr0f2ZyYDzzx5CPtbEkuvcTA==", - "dev": true - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -2372,15 +1973,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -2390,15 +1982,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-abstract": { "version": "1.22.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", @@ -2577,15 +2160,6 @@ "@esbuild/win32-x64": "0.19.5" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/escape-goat": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", @@ -2610,27 +2184,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, "node_modules/eslint": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", @@ -3134,23 +2687,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", - "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", + "node_modules/esquery": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", + "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3226,26 +2766,6 @@ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", "dev": true }, - "node_modules/extract-zip": { - "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, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, "node_modules/fast-check": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.14.0.tgz", @@ -3274,12 +2794,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -3317,15 +2831,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fd-slicer": { - "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, - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -3449,20 +2954,6 @@ "node": ">=12.20.0" } }, - "node_modules/fs-extra": { - "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, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3519,15 +3010,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", @@ -3555,21 +3037,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-stream": { - "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, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -3586,21 +3053,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-uri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", - "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", - "dev": true, - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.0", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3714,12 +3166,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3857,19 +3303,6 @@ "node": ">=8.0.0" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/http-server": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", @@ -3897,19 +3330,6 @@ "node": ">=12" } }, - "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -3922,26 +3342,6 @@ "node": ">=0.10.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -4011,12 +3411,6 @@ "node": ">= 0.4" } }, - "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", - "dev": true - }, "node_modules/is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -4031,12 +3425,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -4390,12 +3778,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -4408,12 +3790,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "node_modules/json-schema-to-typescript": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-13.1.2.tgz", @@ -4484,15 +3860,6 @@ "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4506,12 +3873,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -4652,12 +4013,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true - }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -4670,12 +4025,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4699,15 +4048,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -4879,39 +4219,6 @@ "node": ">= 0.8.0" } }, - "node_modules/pac-proxy-agent": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", - "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", - "dev": true, - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "pac-resolver": "^7.0.0", - "socks-proxy-agent": "^8.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", - "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", - "dev": true, - "dependencies": { - "degenerator": "^5.0.0", - "ip": "^1.1.8", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", @@ -4938,24 +4245,6 @@ "xregexp": "^3.1.1" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -5011,12 +4300,6 @@ "node": ">=8" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -5115,59 +4398,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "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, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proxy-agent": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", - "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-agent/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5177,38 +4407,6 @@ "node": ">=6" } }, - "node_modules/puppeteer": { - "version": "21.4.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.4.1.tgz", - "integrity": "sha512-opJqQeYMjAB3ICG8lCF3wtSs9k05dozmrEMrHgo3ZWbISiy8qbv/yAJz/6Io221qSh3yURfVf6Z7crrlzKZjLQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@puppeteer/browsers": "1.8.0", - "cosmiconfig": "8.3.6", - "puppeteer-core": "21.4.1" - }, - "engines": { - "node": ">=16.3.0" - } - }, - "node_modules/puppeteer-core": { - "version": "21.4.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.4.1.tgz", - "integrity": "sha512-Lh0e+oGhUquxVOi1U701gTfFLFvw5gDBFh3CWpnfAvtItmyZKUce4R54VNfOJfi+KKnzhVPdB/lDrg65gdRIng==", - "dev": true, - "dependencies": { - "@puppeteer/browsers": "1.8.0", - "chromium-bidi": "0.4.32", - "cross-fetch": "4.0.0", - "debug": "4.3.4", - "devtools-protocol": "0.0.1191157", - "ws": "8.14.2" - }, - "engines": { - "node": ">=16.3.0" - } - }, "node_modules/pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -5260,12 +4458,6 @@ } ] }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", @@ -5295,15 +4487,6 @@ "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -5599,74 +4782,10 @@ "node": ">=8" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "dev": true, - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", - "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "socks": "^2.7.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/socks/node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/special-pages": { "resolved": "packages/special-pages", "link": true }, - "node_modules/streamx": { - "version": "2.15.2", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.2.tgz", - "integrity": "sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg==", - "dev": true, - "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - } - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -5811,28 +4930,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dev": true, - "dependencies": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "node_modules/tar-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", - "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -5860,12 +4957,6 @@ "node": ">=0.8" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "node_modules/timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", @@ -6110,16 +5201,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "node_modules/union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -6132,15 +5213,6 @@ "node": ">= 0.8.0" } }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -6156,12 +5228,6 @@ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true }, - "node_modules/urlpattern-polyfill": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", - "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", - "dev": true - }, "node_modules/valid-data-url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", @@ -6299,23 +5365,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", @@ -6340,84 +5389,17 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/xregexp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-3.2.0.tgz", "integrity": "sha512-tWodXkrdYZPGadukpkmhKAbyp37CV5ZiFHacIVPhRZ4/sSt7qtOYHLv2dAqcPN0mBsViY2Qai9JkO7v2TBP6hg==" }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -6459,149 +5441,6 @@ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true }, - "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "@bcherny/json-schema-ref-parser": { "version": "10.0.5-fork", "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", @@ -6971,21 +5810,6 @@ "playwright": "1.40.1" } }, - "@puppeteer/browsers": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.8.0.tgz", - "integrity": "sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==", - "dev": true, - "requires": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "progress": "2.0.3", - "proxy-agent": "6.3.1", - "tar-fs": "3.0.4", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.2" - } - }, "@rive-app/canvas-single": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/@rive-app/canvas-single/-/canvas-single-2.9.3.tgz", @@ -7074,12 +5898,6 @@ "picomatch": "^2.3.1" } }, - "@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true - }, "@types/chrome": { "version": "0.0.248", "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.248.tgz", @@ -7181,16 +5999,6 @@ "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, - "@types/yauzl": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.2.tgz", - "integrity": "sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, "@typescript-eslint/eslint-plugin": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", @@ -7419,15 +6227,6 @@ "dev": true, "requires": {} }, - "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "dev": true, - "requires": { - "debug": "^4.3.4" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -7557,16 +6356,7 @@ "es-abstract": "^1.22.1", "get-intrinsic": "^1.2.1", "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - } - }, - "ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dev": true, - "requires": { - "tslib": "^2.0.1" + "is-shared-array-buffer": "^1.0.2" } }, "async": { @@ -7584,24 +6374,12 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, - "b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", - "dev": true - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, "basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -7619,12 +6397,6 @@ } } }, - "basic-ftp": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz", - "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==", - "dev": true - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -7644,22 +6416,6 @@ "fill-range": "^7.0.1" } }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, "builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", @@ -7709,16 +6465,6 @@ "supports-color": "^7.1.0" } }, - "chromium-bidi": { - "version": "0.4.32", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.32.tgz", - "integrity": "sha512-RJnw0PW3sNdx1WclINVfVVx8JUH+tWTHZNpnEzlcM+Qgvf40dUH34U7gJq+cc/0LE+rbPxeT6ldqWrCbUf4jeg==", - "dev": true, - "requires": { - "mitt": "3.0.1", - "urlpattern-polyfill": "9.0.0" - } - }, "classnames": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", @@ -7737,17 +6483,6 @@ "timers-ext": "^0.1.7" } }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7809,27 +6544,6 @@ "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", "dev": true }, - "cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "requires": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - } - }, - "cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dev": true, - "requires": { - "node-fetch": "^2.6.12" - } - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -7851,12 +6565,6 @@ "type": "^1.0.1" } }, - "data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", - "dev": true - }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -7900,23 +6608,6 @@ "object-keys": "^1.1.1" } }, - "degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "dev": true, - "requires": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - } - }, - "devtools-protocol": { - "version": "0.0.1191157", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1191157.tgz", - "integrity": "sha512-Fu2mUhX7zkzLHMJZk5wQTiHdl1eJrhK0GypUoSzogUt51MmYEv/46pCz4PtGGFlr0f2ZyYDzzx5CPtbEkuvcTA==", - "dev": true - }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8006,30 +6697,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, "es-abstract": { "version": "1.22.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", @@ -8182,12 +6855,6 @@ "@esbuild/win32-x64": "0.19.5" } }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, "escape-goat": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", @@ -8200,18 +6867,6 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "source-map": "~0.6.1" - } - }, "eslint": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", @@ -8561,12 +7216,6 @@ "eslint-visitor-keys": "^3.4.1" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "esquery": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", @@ -8636,18 +7285,6 @@ } } }, - "extract-zip": { - "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, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, "fast-check": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.14.0.tgz", @@ -8663,12 +7300,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, "fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -8703,15 +7334,6 @@ "reusify": "^1.0.4" } }, - "fd-slicer": { - "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, - "requires": { - "pend": "~1.2.0" - } - }, "fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -8790,17 +7412,6 @@ "fetch-blob": "^3.1.2" } }, - "fs-extra": { - "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, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -8838,12 +7449,6 @@ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, "get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", @@ -8862,15 +7467,6 @@ "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true }, - "get-stream": { - "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, - "requires": { - "pump": "^3.0.0" - } - }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -8881,18 +7477,6 @@ "get-intrinsic": "^1.1.1" } }, - "get-uri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", - "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", - "dev": true, - "requires": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.0", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - } - }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -8966,12 +7550,6 @@ "get-intrinsic": "^1.1.3" } }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -9067,16 +7645,6 @@ "requires-port": "^1.0.0" } }, - "http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "requires": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - } - }, "http-server": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", @@ -9098,16 +7666,6 @@ "url-join": "^4.0.1" } }, - "https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "dev": true, - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -9117,12 +7675,6 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -9177,12 +7729,6 @@ "side-channel": "^1.0.4" } }, - "ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", - "dev": true - }, "is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -9194,12 +7740,6 @@ "is-typed-array": "^1.1.10" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -9448,12 +7988,6 @@ "integrity": "sha512-zsOmeBKESky4toybvWEikRiZ0jHoBEu79wNArLfMdSnlLMZx3Xcp6CSm2sUcYyoJC+Uyj8LBJap/MUbVSfJ27g==", "dev": true }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -9463,12 +7997,6 @@ "argparse": "^2.0.1" } }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "json-schema-to-typescript": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-13.1.2.tgz", @@ -9526,15 +8054,6 @@ "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -9545,12 +8064,6 @@ "type-check": "~0.4.0" } }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -9661,12 +8174,6 @@ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true }, - "mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true - }, "mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -9676,12 +8183,6 @@ "minimist": "^1.2.6" } }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -9705,12 +8206,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "dev": true - }, "next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -9825,33 +8320,6 @@ "type-check": "^0.4.0" } }, - "pac-proxy-agent": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", - "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", - "dev": true, - "requires": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "pac-resolver": "^7.0.0", - "socks-proxy-agent": "^8.0.2" - } - }, - "pac-resolver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", - "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", - "dev": true, - "requires": { - "degenerator": "^5.0.0", - "ip": "^1.1.8", - "netmask": "^2.0.2" - } - }, "package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", @@ -9875,18 +8343,6 @@ "xregexp": "^3.1.1" } }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -9929,12 +8385,6 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -9996,83 +8446,12 @@ "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "proxy-agent": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", - "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", - "dev": true, - "requires": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" - }, - "dependencies": { - "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true - } - } - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, - "puppeteer": { - "version": "21.4.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.4.1.tgz", - "integrity": "sha512-opJqQeYMjAB3ICG8lCF3wtSs9k05dozmrEMrHgo3ZWbISiy8qbv/yAJz/6Io221qSh3yURfVf6Z7crrlzKZjLQ==", - "dev": true, - "requires": { - "@puppeteer/browsers": "1.8.0", - "cosmiconfig": "8.3.6", - "puppeteer-core": "21.4.1" - } - }, - "puppeteer-core": { - "version": "21.4.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.4.1.tgz", - "integrity": "sha512-Lh0e+oGhUquxVOi1U701gTfFLFvw5gDBFh3CWpnfAvtItmyZKUce4R54VNfOJfi+KKnzhVPdB/lDrg65gdRIng==", - "dev": true, - "requires": { - "@puppeteer/browsers": "1.8.0", - "chromium-bidi": "0.4.32", - "cross-fetch": "4.0.0", - "debug": "4.3.4", - "devtools-protocol": "0.0.1191157", - "ws": "8.14.2" - } - }, "pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -10094,12 +8473,6 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, - "queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, "regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", @@ -10117,12 +8490,6 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -10324,48 +8691,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true - }, - "socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "dev": true, - "requires": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "dependencies": { - "ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true - } - } - }, - "socks-proxy-agent": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", - "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", - "dev": true, - "requires": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "socks": "^2.7.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - }, "special-pages": { "version": "file:packages/special-pages", "requires": { @@ -10379,16 +8704,6 @@ "web-resource-inliner": "^6.0.1" } }, - "streamx": { - "version": "2.15.2", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.2.tgz", - "integrity": "sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg==", - "dev": true, - "requires": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - } - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -10489,28 +8804,6 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, - "tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dev": true, - "requires": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "tar-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", - "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", - "dev": true, - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -10535,12 +8828,6 @@ "thenify": ">= 3.1.0 < 4" } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", @@ -10724,16 +9011,6 @@ "which-boxed-primitive": "^1.0.2" } }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -10743,12 +9020,6 @@ "qs": "^6.4.0" } }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -10764,12 +9035,6 @@ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true }, - "urlpattern-polyfill": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", - "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", - "dev": true - }, "valid-data-url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", @@ -10876,17 +9141,6 @@ "has-tostringtag": "^1.0.0" } }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, "wrap-ansi-cjs": { "version": "npm:wrap-ansi@7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -10904,61 +9158,17 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", - "dev": true, - "requires": {} - }, "xregexp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-3.2.0.tgz", "integrity": "sha512-tWodXkrdYZPGadukpkmhKAbyp37CV5ZiFHacIVPhRZ4/sSt7qtOYHLv2dAqcPN0mBsViY2Qai9JkO7v2TBP6hg==" }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 4152a73c88..45721ab3c5 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "lint-no-output-globals": "eslint --no-eslintrc --config=build-output.eslintrc --no-ignore Sources/ContentScopeScripts/dist/contentScope.js", "lint-fix": "eslint . --fix && npm run tsc", "test-unit": "jasmine --config=unit-test/config.json", - "test-int": "npm run build-integration && jasmine --config=integration-test/config.js", + "test-int": "npm run build-integration && npm run playwright", "test-int-x": "xvfb-run --server-args='-screen 0 1024x768x24' npm run test-int", "test-clean-tree": "npm run build && sh scripts/check-for-changes.sh", "test": "npm run lint && npm run lint-no-output-globals && npm run test-unit && npm run test-int && npm run playwright", @@ -80,7 +80,6 @@ "jasmine": "^5.3.0", "json-schema-to-typescript": "^13.1.2", "minimist": "^1.2.8", - "puppeteer": "^21.4.1", "rollup": "^3.29.4", "rollup-plugin-import-css": "^3.5.2", "rollup-plugin-svg-import": "^2.1.0", diff --git a/playwright.config.js b/playwright.config.js index fdc33a17ff..5cf84c22ea 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -46,7 +46,15 @@ export default defineConfig({ }, { name: 'chrome', - testMatch: 'integration-test/playwright/remote-pages.spec.js', + testMatch: [ + 'integration-test/playwright/remote-pages.spec.js', + 'integration-test/test-cookie.js', + 'integration-test/test-fingerprint.js', + 'integration-test/test-navigator-interface.js', + 'integration-test/test-pages.js', + 'integration-test/test-utils.js', + 'integration-test/test-web-compat.js' + ], use: { injectName: 'chrome', platform: 'extension', ...devices['Desktop Chrome'] } }, { diff --git a/scripts/server.mjs b/scripts/server.mjs new file mode 100644 index 0000000000..a31a0c6d84 --- /dev/null +++ b/scripts/server.mjs @@ -0,0 +1,10 @@ +import { createServer } from "http-server"; + +const server = createServer({ root: process.env.SERVER_DIR }); +server.listen(process.env.SERVER_PORT); +server.server.on('listening', () => { + process.send?.({port: server.server.address().port}); +}) +server.server.on('error', () => { + process.exit(1) +}) diff --git a/tsconfig.json b/tsconfig.json index 1ea7addfab..dea672691d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,7 +27,6 @@ "./src/features/duckplayer/duckplayer-settings.ts" ], "exclude": [ - "integration-test/pages", "integration-test/test-pages", "integration-test/extension", "packages/special-pages/pages/**/public",