diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 540337213..000000000 --- a/.eslintignore +++ /dev/null @@ -1,14 +0,0 @@ -build/ -docs/ -injected/lib -Sources/ContentScopeScripts/dist/ -injected/integration-test/extension/contentScope.js -injected/integration-test/test-pages/duckplayer/scripts/dist -special-pages/pages/**/public -special-pages/playwright-report/ -special-pages/test-results/ -special-pages/types/ -special-pages/messages/ -/playwright-report -/test-results -injected/src/types diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 2992fb545..000000000 --- a/.eslintrc +++ /dev/null @@ -1,38 +0,0 @@ -{ - "extends": ["standard", "plugin:@typescript-eslint/recommended"], - "root": true, - "parserOptions": { - "ecmaVersion": "latest", - "project": "./tsconfig.json" - }, - "parser": "@typescript-eslint/parser", - "plugins": ["promise","@typescript-eslint"], - "globals": { - "$USER_PREFERENCES$": "readonly", - "$USER_UNPROTECTED_DOMAINS$": "readonly", - "$CONTENT_SCOPE$": "readonly", - "$BUNDLED_CONFIG$": "readonly", - "windowsInteropPostMessage": "readonly", - "windowsInteropAddEventListener": "readonly", - "windowsInteropRemoveEventListener": "readonly" - }, - "rules": { - "no-restricted-syntax": [ - "error", - { - "selector": "MethodDefinition[key.type='PrivateIdentifier']", - "message": "Private methods are currently unsupported in older WebKit and ESR Firefox" - } - ], - "indent": ["error", 4], - "require-await": ["error"], - "promise/prefer-await-to-then": ["error"], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/no-unused-vars": "error" - }, - "env": { - "webextensions": true, - "browser": true, - "jasmine": true - } -} diff --git a/.github/scripts/diff-directories.js b/.github/scripts/diff-directories.js index fd1650f3e..465a0afc4 100644 --- a/.github/scripts/diff-directories.js +++ b/.github/scripts/diff-directories.js @@ -46,7 +46,7 @@ function displayDiffs (dir1Files, dir2Files, isOpen) { } for (const [filePath, fileContent] of Object.entries(dir1Files)) { let diffOut = '' - let compareOut = undefined + let compareOut if (filePath in dir2Files) { const fileOut = fileContent const file2Out = dir2Files[filePath] @@ -71,7 +71,7 @@ function displayDiffs (dir1Files, dir2Files, isOpen) { const rollup = rollupGrouping[key] let outString = ` ` - let title = key + const title = key if (rollup.files.length) { for (const file of rollup.files) { outString += `- ${file}\n` @@ -84,7 +84,7 @@ function displayDiffs (dir1Files, dir2Files, isOpen) { } function renderDetails (section, text, isOpen) { - if (section == 'dist') { + if (section === 'dist') { section = 'apple' } const open = section !== 'integration' ? 'open' : '' @@ -119,6 +119,6 @@ sortFiles(readFilesRecursively(dir1 + sourcesOutput), 'dir1') sortFiles(readFilesRecursively(dir2 + sourcesOutput), 'dir2') -//console.log(Object.keys(files)) +// console.log(Object.keys(files)) const fileOut = displayDiffs(sections.dir1, sections.dir2, true) console.log(fileOut) \ No newline at end of file diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 6062eb755..5991d16f8 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@v4 - name: Use Node.js 20 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 20.x - uses: actions/cache@v4 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eed4eef6f..4d4a5934e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' @@ -75,7 +75,7 @@ jobs: run: | ls -la ${{ github.workspace }}/CHANGELOG.txt cat ${{ github.workspace }}/CHANGELOG.txt - + - name: Create Release uses: softprops/action-gh-release@v2 env: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0c055af33..c0fa120c8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Use Node.js 20 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 20.x - uses: actions/cache@v4 @@ -43,7 +43,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Use Node.js 20 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 20.x - uses: actions/cache@v4 @@ -86,7 +86,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Use Node.js 20 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 20.x - name: Cache build outputs diff --git a/.stylelintrc.json b/.stylelintrc.json index 71443bfa3..3d344459f 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -32,9 +32,10 @@ "keyframes-name-pattern": null, "block-no-empty": null, "selector-id-pattern": null, + "selector-pseudo-class-no-unknown": null, "declaration-block-no-shorthand-property-overrides": null, "font-family-no-missing-generic-family-keyword": null, "font-family-name-quotes": null, "value-no-vendor-prefix": null } -} \ No newline at end of file +} diff --git a/build-output.eslint.config.js b/build-output.eslint.config.js new file mode 100644 index 000000000..833e9a0c1 --- /dev/null +++ b/build-output.eslint.config.js @@ -0,0 +1,14 @@ +// this belongs to the injected/ package, but eslint has issues with linting files outside of the base directory: +// https://github.com/eslint/eslint/discussions/18806#discussioncomment-10848750 + +export default [ + { + languageOptions: { + ecmaVersion: "latest", + sourceType: "script", + }, + rules: { + "no-implicit-globals": "error", + } + } +]; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..c636ad174 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,104 @@ +import tseslint from 'typescript-eslint'; +import ddgConfig from "@duckduckgo/eslint-config"; +import globals from "globals"; + +// @ts-check +export default tseslint.config( + ...ddgConfig, + ...tseslint.configs.recommended, + { + ignores: [ + "**/build/", + "**/docs/", + "injected/lib", + "Sources/ContentScopeScripts/dist/", + "injected/integration-test/extension/contentScope.js", + "injected/integration-test/test-pages/duckplayer/scripts/dist", + "special-pages/pages/**/public", + "special-pages/playwright-report/", + "special-pages/test-results/", + "special-pages/types/", + "special-pages/messages/", + "playwright-report", + "test-results", + "injected/src/types", + ], + }, + { + languageOptions: { + globals: { + $USER_PREFERENCES$: "readonly", + $USER_UNPROTECTED_DOMAINS$: "readonly", + $CONTENT_SCOPE$: "readonly", + $BUNDLED_CONFIG$: "readonly", + }, + + ecmaVersion: "latest", + sourceType: "script", + }, + + rules: { + "no-restricted-syntax": ["error", { + selector: "MethodDefinition[key.type='PrivateIdentifier']", + message: "Private methods are currently unsupported in older WebKit and ESR Firefox", + }], + + "require-await": ["error"], + "promise/prefer-await-to-then": ["error"], + "@typescript-eslint/no-unused-vars": ["error", { + args: "none", + caughtErrors: "none", + ignoreRestSiblings: true, + vars: "all" + }], + }, + }, + { + ignores: ["injected/integration-test/test-pages/**", "injected/integration-test/extension/**"], + languageOptions: { + parserOptions: { + projectService: { + allowDefaultProject: ['eslint.config.js', 'build-output.eslint.config.js'], + }, + } + }, + rules: { + "@typescript-eslint/await-thenable": "error", + }, + }, + { + files: ["**/scripts/*.js", "**/*.mjs", "**/unit-test/**/*.js", "**/integration-test/**/*.spec.js"], + languageOptions: { + globals: { + ...globals.node, + } + } + }, + { + files: ["injected/**/*.js"], + languageOptions: { + globals: { + windowsInteropPostMessage: "readonly", + windowsInteropAddEventListener: "readonly", + windowsInteropRemoveEventListener: "readonly", + } + } + }, + { + files: ["**/unit-test/*.js"], + languageOptions: { + globals: { + ...globals.jasmine, + } + } + }, + { + ignores: ["**/scripts/*.js"], + languageOptions: { + globals: { + ...globals.browser, + ...globals.webextensions, + } + } + } +); diff --git a/injected/build-output.eslintrc b/injected/build-output.eslintrc deleted file mode 100644 index cf788cf14..000000000 --- a/injected/build-output.eslintrc +++ /dev/null @@ -1,12 +0,0 @@ -{ - "root": true, - "plugins": ["promise", "@typescript-eslint", "eslint-plugin-n"], - "parserOptions": { - "ecmaVersion": "latest", - }, - "rules": { - "no-implicit-globals": "error", - "typescript-eslint/ban-ts-comment": "off", - "promise/prefer-await-to-then": "off", - } -} diff --git a/injected/integration-test/.eslintrc b/injected/integration-test/.eslintrc deleted file mode 100644 index eed473ae6..000000000 --- a/injected/integration-test/.eslintrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "parserOptions": { - "project": null - }, - "rules": { - "@typescript-eslint/await-thenable": "off" - } -} \ No newline at end of file diff --git a/injected/integration-test/autofill-password-import.spec.js b/injected/integration-test/autofill-password-import.spec.js index d9bca0403..3957d92cf 100644 --- a/injected/integration-test/autofill-password-import.spec.js +++ b/injected/integration-test/autofill-password-import.spec.js @@ -97,7 +97,7 @@ export class AutofillPasswordImportSpec { * @param {string} selector */ async waitForAnimation (selector) { - const locator = await this.page.locator(selector) + const locator = this.page.locator(selector) return await locator.evaluate((el) => { if (el != null) { return el.getAnimations().some((animation) => animation.playState === 'running') @@ -112,7 +112,7 @@ export class AutofillPasswordImportSpec { * @param {string} text */ async clickOnElement (text) { - const element = await this.page.getByText(text) + const element = this.page.getByText(text) await element.click() } } diff --git a/injected/integration-test/duckplayer.spec.js b/injected/integration-test/duckplayer.spec.js index af7aa14ac..4dd019eb6 100644 --- a/injected/integration-test/duckplayer.spec.js +++ b/injected/integration-test/duckplayer.spec.js @@ -39,7 +39,7 @@ test.describe('Thumbnail Overlays', () => { const navigation = overlays.requestWillFail() await overlays.clicksFirstShortsThumbnail() const url = await navigation - await overlays.opensShort(url) + overlays.opensShort(url) }) test('Overlays don\'t show on thumbnails when disabled', async ({ page }, workerInfo) => { const overlays = DuckplayerOverlays.create(page, workerInfo) diff --git a/injected/integration-test/fingerprint.spec.js b/injected/integration-test/fingerprint.spec.js index 6243ff73a..f35a80f6d 100644 --- a/injected/integration-test/fingerprint.spec.js +++ b/injected/integration-test/fingerprint.spec.js @@ -5,6 +5,7 @@ import { test as base, expect } from '@playwright/test' import { testContextForExtension } from './helpers/harness.js' import { createRequire } from 'node:module' +// eslint-disable-next-line no-redeclare const require = createRequire(import.meta.url) const test = testContextForExtension(base) diff --git a/injected/integration-test/helpers/harness.js b/injected/integration-test/helpers/harness.js index fd149e7c1..58cc1e8b6 100644 --- a/injected/integration-test/helpers/harness.js +++ b/injected/integration-test/helpers/harness.js @@ -1,3 +1,4 @@ +/* global process */ import { mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'os' import { join } from 'path' @@ -92,9 +93,10 @@ export function testContextForExtension (test) { * @param {string} urlString * @param {Record} [args] * @param {string|null} [evalBeforeInit] + * @param {"extension" | "script"} [kind] - if 'extension', the script will be loaded separately. if 'script' we'll append a script tag * @returns {Promise} */ -export async function gotoAndWait (page, urlString, args = {}, evalBeforeInit = null) { +export async function gotoAndWait (page, urlString, args = {}, evalBeforeInit = null, kind = 'extension') { // eslint-disable-next-line @typescript-eslint/no-unused-vars const [_, search] = urlString.split('?') const searchParams = new URLSearchParams(search) @@ -104,6 +106,12 @@ export async function gotoAndWait (page, urlString, args = {}, evalBeforeInit = await page.goto(urlString + '?' + searchParams.toString()) + if (kind === 'script') { + await page.addScriptTag({ + url: './build/contentScope.js' + }) + } + // wait until contentScopeFeatures.load() has completed await page.waitForFunction(() => { // @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f diff --git a/injected/integration-test/page-objects/broker-protection.js b/injected/integration-test/page-objects/broker-protection.js index ac0f952d8..acfcd525f 100644 --- a/injected/integration-test/page-objects/broker-protection.js +++ b/injected/integration-test/page-objects/broker-protection.js @@ -265,10 +265,12 @@ export class BrokerProtectionPage { * @param {object} response */ isErrorMessage (response) { + // eslint-disable-next-line no-unsafe-optional-chaining expect('error' in response[0].payload?.params?.result).toBe(true) } isSuccessMessage (response) { + // eslint-disable-next-line no-unsafe-optional-chaining expect('success' in response[0].payload?.params?.result).toBe(true) } diff --git a/injected/integration-test/page-objects/duckplayer-overlays.js b/injected/integration-test/page-objects/duckplayer-overlays.js index e83043d23..7d70afa6b 100644 --- a/injected/integration-test/page-objects/duckplayer-overlays.js +++ b/injected/integration-test/page-objects/duckplayer-overlays.js @@ -110,7 +110,7 @@ export class DuckplayerOverlays { * @return {Promise} */ async clicksFirstThumbnail () { - const elem = await this.page.locator('a[href^="/watch?v"]:has(img)').first() + const elem = this.page.locator('a[href^="/watch?v"]:has(img)').first() const link = await elem.getAttribute('href') if (!link) throw new Error('link must exist') await elem.click({ force: true }) diff --git a/injected/integration-test/test-pages/shared/utils.js b/injected/integration-test/test-pages/shared/utils.js index 52e14984f..415ea176d 100644 --- a/injected/integration-test/test-pages/shared/utils.js +++ b/injected/integration-test/test-pages/shared/utils.js @@ -16,7 +16,6 @@ function buildTableCell (value, tagName = 'td') { * @param {Record} results The results to build the table for. * @return {Element} The table element. */ -// eslint-disable-next-line no-unused-vars function buildResultTable (results) { const table = document.createElement('table') table.className = 'results' diff --git a/injected/integration-test/type-helpers.mjs b/injected/integration-test/type-helpers.mjs index 127412e87..87091e402 100644 --- a/injected/integration-test/type-helpers.mjs +++ b/injected/integration-test/type-helpers.mjs @@ -59,7 +59,7 @@ export class Build { const path = this.switch({ windows: () => '../build/windows/contentScope.js', android: () => '../build/android/contentScope.js', - 'apple': () => '../Sources/ContentScopeScripts/dist/contentScope.js', + apple: () => '../Sources/ContentScopeScripts/dist/contentScope.js', 'apple-isolated': () => '../Sources/ContentScopeScripts/dist/contentScopeIsolated.js', 'android-autofill-password-import': () => '../build/android/autofillPasswordImport.js' }) diff --git a/injected/integration-test/web-compat-android.spec.js b/injected/integration-test/web-compat-android.spec.js new file mode 100644 index 000000000..bb9fab14f --- /dev/null +++ b/injected/integration-test/web-compat-android.spec.js @@ -0,0 +1,272 @@ +import { gotoAndWait } from './helpers/harness.js' +import { test, expect } from '@playwright/test' + +test.describe('Web Share API', () => { + function checkForCanShare () { + return 'canShare' in navigator + } + function checkForShare () { + return 'share' in navigator + } + + test.describe('disabled feature', () => { + test('should not expose navigator.canShare() and navigator.share()', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { site: { enabledFeatures: [] } }, null, 'script') + 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) + expect(noCanShare).toEqual(false) + expect(noShare).toEqual(false) + }) + }) + + test.describe('disabled sub-feature', () => { + test('should not expose navigator.canShare() and navigator.share()', async ({ page }) => { + await gotoAndWait(page, '/blank.html', { + site: { + enabledFeatures: ['webCompat'] + }, + featureSettings: { + webCompat: { + // no webShare + } + } + }, null, 'script') + 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) + expect(noCanShare).toEqual(false) + expect(noShare).toEqual(false) + }) + }) + + test.describe('enabled feature', () => { + async function navigate (page) { + page.on('console', console.log) + await gotoAndWait(page, '/blank.html', { + site: { + enabledFeatures: ['webCompat'] + }, + featureSettings: { + webCompat: { + webShare: 'enabled' + } + } + }, null, 'script') + } + + 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) + }) + + 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) + }) + + 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) + }) + + test('should allow relative links', async ({ page }) => { + await navigate(page) + const allowShare = await page.evaluate(() => { + return navigator.canShare({ url: 'bla' }) + }) + expect(allowShare).toEqual(true) + }) + + 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 + return navigator.canShare({ foo: 'bar' }) + }) + expect(refuseShare).toEqual(false) + }) + + test('should let you share stuff', async ({ page }) => { + await navigate(page) + let canShare = await page.evaluate(() => { + return navigator.canShare({ url: 'http://example.com' }) + }) + expect(canShare).toEqual(true) + + canShare = await page.evaluate(() => { + return navigator.canShare({ text: 'the grass was greener' }) + }) + expect(canShare).toEqual(true) + + canShare = await page.evaluate(() => { + return navigator.canShare({ title: 'the light was brighter' }) + }) + expect(canShare).toEqual(true) + + canShare = await page.evaluate(() => { + return navigator.canShare({ text: 'with friends surrounded', title: 'the nights of wonder' }) + }) + expect(canShare).toEqual(true) + }) + }) + + 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({}) + } + }) + } + 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', result) + const message = await page.evaluate(() => { + console.log('did read?') + return globalThis.shareReq + }) + return { result, message } + } + + 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() + }) + + 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() + }) + + 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() + }) + + 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() + }) + + 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() + }) + + 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() + }) + + 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).toContain('TypeError: Invalid share data') + }) + + 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).toContain('TypeError: Invalid share data') + }) + + 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() + }) + + 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() + }) + }) + + 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')) + } + }) + const result = await page.evaluate('navigator.share({ text: "xxx" })').catch((e) => { + return { threw: e } + }) + + // In page context, it should be a DOMException with name DataError, but page.evaluate() serializes everything in the message + expect(result.threw.message).toContain('DataError: something wrong') + }) + + 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' } }) + } + }) + const result = await page.evaluate('navigator.share({ text: "xxx" })').catch((e) => { + return { threw: e } + }) + + // In page context, it should be a DOMException with name AbortError, but page.evaluate() serializes everything in the message + expect(result.threw.message).toContain('AbortError: some error message') + }) + }) + }) + }) +}) diff --git a/injected/integration-test/web-compat.spec.js b/injected/integration-test/web-compat.spec.js index 19f5440d4..497633c7b 100644 --- a/injected/integration-test/web-compat.spec.js +++ b/injected/integration-test/web-compat.spec.js @@ -422,275 +422,6 @@ test.describe('ScreenOrientation API', () => { }) }) -test.describe('Web Share API', () => { - function checkForCanShare () { - return 'canShare' in navigator - } - function checkForShare () { - return 'share' in navigator - } - - 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) - expect(noCanShare).toEqual(false) - expect(noShare).toEqual(false) - }) - }) - - test.describe('disabled sub-feature', () => { - test('should not expose navigator.canShare() and navigator.share()', async ({ page }) => { - await gotoAndWait(page, '/blank.html', { - site: { - enabledFeatures: ['webCompat'] - }, - featureSettings: { - webCompat: { - // no webShare - } - } - }) - 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) - expect(noCanShare).toEqual(false) - expect(noShare).toEqual(false) - }) - }) - - test.describe('enabled feature', () => { - async function navigate (page) { - await gotoAndWait(page, '/blank.html', { - site: { - enabledFeatures: ['webCompat'] - }, - featureSettings: { - webCompat: { - webShare: 'enabled' - } - } - }) - } - - 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) - }) - - 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) - }) - - 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) - }) - - test('should allow relative links', async ({ page }) => { - await navigate(page) - const allowShare = await page.evaluate(() => { - return navigator.canShare({ url: 'bla' }) - }) - expect(allowShare).toEqual(true) - }) - - 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 - return navigator.canShare({ foo: 'bar' }) - }) - expect(refuseShare).toEqual(false) - }) - - test('should let you share stuff', async ({ page }) => { - await navigate(page) - let canShare = await page.evaluate(() => { - return navigator.canShare({ url: 'http://example.com' }) - }) - expect(canShare).toEqual(true) - - canShare = await page.evaluate(() => { - return navigator.canShare({ text: 'the grass was greener' }) - }) - expect(canShare).toEqual(true) - - canShare = await page.evaluate(() => { - return navigator.canShare({ title: 'the light was brighter' }) - }) - expect(canShare).toEqual(true) - - canShare = await page.evaluate(() => { - return navigator.canShare({ text: 'with friends surrounded', title: 'the nights of wonder' }) - }) - expect(canShare).toEqual(true) - }) - }) - - 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({}) - } - }) - } - 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 } - } - - 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() - }) - - 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() - }) - - 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() - }) - - 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() - }) - - 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() - }) - - 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() - }) - - 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).toContain('TypeError: Invalid share data') - }) - - 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).toContain('TypeError: Invalid share data') - }) - - 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() - }) - - 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() - }) - }) - - 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')) - } - }) - const result = await page.evaluate('navigator.share({ text: "xxx" })').catch((e) => { - return { threw: e } - }) - - expect(result.threw.message).toContain('something wrong') - expect(result.threw.message).toContain('DOMException') - }) - - 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' } }) - } - }) - const result = await page.evaluate('navigator.share({ text: "xxx" })').catch((e) => { - return { threw: e } - }) - console.error(result.threw) - expect(result.threw.message).toContain('some error message') - expect(result.threw.message).toContain('DOMException') - }) - }) - }) - }) -}) - test.describe('Viewport fixes', () => { function getViewportValue () { return document.querySelector('meta[name="viewport"]')?.getAttribute('content') diff --git a/injected/package.json b/injected/package.json index faa440868..bceef8bd6 100644 --- a/injected/package.json +++ b/injected/package.json @@ -15,8 +15,6 @@ "build-integration": "node scripts/entry-points.js --platform integration", "build-types": "node scripts/types.mjs", "bundle-trackers": "node scripts/bundleTrackers.mjs --output ../build/tracker-lookup.json", - "lint": "npm run lint-no-output-globals", - "lint-no-output-globals": "eslint --no-eslintrc --config=build-output.eslintrc --no-ignore ../Sources/ContentScopeScripts/dist/contentScope.js", "test-unit": "jasmine --config=unit-test/config.json", "test-int": "npm run build-integration && npm run playwright", "test-int-x": "xvfb-run --server-args='-screen 0 1024x768x24' npm run test-int", @@ -33,7 +31,7 @@ }, "type": "module", "dependencies": { - "immutable-json-patch": "^5.1.3", + "immutable-json-patch": "^6.0.1", "parse-address": "^1.1.2", "seedrandom": "^3.0.5", "sjcl": "^1.0.8" @@ -41,19 +39,19 @@ "devDependencies": { "@canvas/image-data": "^1.0.0", "@fingerprintjs/fingerprintjs": "^4.5.1", - "@rollup/plugin-commonjs": "^26.0.1", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-replace": "^5.0.7", - "@types/chrome": "^0.0.278", + "@rollup/plugin-commonjs": "^28.0.1", + "@rollup/plugin-node-resolve": "^15.3.0", + "@rollup/plugin-replace": "^6.0.1", + "@types/chrome": "^0.0.279", "@types/jasmine": "^5.1.4", - "@types/node": "^22.7.7", + "@types/node": "^22.8.6", "@typescript-eslint/eslint-plugin": "^6.9.1", "config-builder": "github:duckduckgo/privacy-configuration#1729260354597", "fast-check": "^3.22.0", "jasmine": "^5.4.0", "minimist": "^1.2.8", - "rollup": "^3.29.5", - "rollup-plugin-import-css": "^3.5.2", - "rollup-plugin-svg-import": "^2.1.0" + "rollup": "^4.24.3", + "rollup-plugin-import-css": "^3.5.6", + "rollup-plugin-svg-import": "^3.0.0" } } diff --git a/injected/playwright-e2e.config.js b/injected/playwright-e2e.config.js index 981615675..a7d39bb80 100644 --- a/injected/playwright-e2e.config.js +++ b/injected/playwright-e2e.config.js @@ -1,3 +1,4 @@ +/* global process */ import { defineConfig } from '@playwright/test' import { dirname, join } from 'node:path' const __dirname = dirname(new URL(import.meta.url).pathname) diff --git a/injected/playwright.config.js b/injected/playwright.config.js index a1353ca5a..89c112da3 100644 --- a/injected/playwright.config.js +++ b/injected/playwright.config.js @@ -1,3 +1,4 @@ +/* global process */ import { defineConfig, devices } from '@playwright/test' export default defineConfig({ @@ -40,7 +41,8 @@ export default defineConfig({ { name: 'android', testMatch: [ - 'integration-test/duckplayer-mobile.spec.js' + 'integration-test/duckplayer-mobile.spec.js', + 'integration-test/web-compat-android.spec.js' ], use: { injectName: 'android', platform: 'android', ...devices['Galaxy S5'] } }, diff --git a/injected/scripts/bundleTrackers.mjs b/injected/scripts/bundleTrackers.mjs index b204aba14..29a9a030c 100644 --- a/injected/scripts/bundleTrackers.mjs +++ b/injected/scripts/bundleTrackers.mjs @@ -1,3 +1,4 @@ +// eslint-disable-next-line no-redeclare import fetch from 'node-fetch' import { parseArgs, write } from '../../scripts/script-utils.js' diff --git a/injected/scripts/types.mjs b/injected/scripts/types.mjs index c04c1c86d..9cc240190 100644 --- a/injected/scripts/types.mjs +++ b/injected/scripts/types.mjs @@ -5,6 +5,7 @@ import { buildTypes } from "../../types-generator/build-types.mjs"; const injectRoot = join(cwd(import.meta.url), '..') +// eslint-disable-next-line no-redeclare const require = createRequire(import.meta.url); const configBuilderRoot = dirname(require.resolve("config-builder")); @@ -42,6 +43,7 @@ const injectSchemaMapping = { if (isLaunchFile(import.meta.url)) { buildTypes(injectSchemaMapping) + // eslint-disable-next-line promise/prefer-await-to-then .catch((error) => { console.error(error) process.exit(1) diff --git a/injected/src/captured-globals.js b/injected/src/captured-globals.js index c4f682938..e64ec34a5 100644 --- a/injected/src/captured-globals.js +++ b/injected/src/captured-globals.js @@ -1,3 +1,4 @@ +/* eslint-disable no-redeclare */ export const Set = globalThis.Set export const Reflect = globalThis.Reflect export const customElementsGet = globalThis.customElements?.get.bind(globalThis.customElements) diff --git a/injected/src/content-feature.js b/injected/src/content-feature.js index 3460ff7c8..bd570ffbe 100644 --- a/injected/src/content-feature.js +++ b/injected/src/content-feature.js @@ -2,6 +2,7 @@ import { camelcase, matchHostname, processAttr, computeEnabledFeatures, parseFea import { immutableJSONPatch } from 'immutable-json-patch' import { PerformanceMonitor } from './performance.js' import { defineProperty, shimInterface, shimProperty, wrapMethod, wrapProperty, wrapToString } from './wrapper-utils.js' +// eslint-disable-next-line no-redeclare import { Proxy, Reflect } from './captured-globals.js' import { Messaging, MessagingContext } from '../../messaging/index.js' import { extensionConstructMessagingConfig } from './sendmessage-transport.js' @@ -28,8 +29,10 @@ export default class ContentFeature { /** @type {boolean | undefined} */ #documentOriginIsTracker /** @type {Record | undefined} */ + // eslint-disable-next-line no-unused-private-class-members #bundledfeatureSettings /** @type {import('../../messaging').Messaging} */ + // eslint-disable-next-line no-unused-private-class-members #messaging /** @type {boolean} */ #isDebugFlagSet = false @@ -214,7 +217,7 @@ export default class ContentFeature { }) } - // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function + init (args) { } @@ -227,7 +230,7 @@ export default class ContentFeature { this.measure() } - // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function + load (args) { } @@ -296,7 +299,7 @@ export default class ContentFeature { } } - // eslint-disable-next-line @typescript-eslint/no-empty-function + update () { } diff --git a/injected/src/features/broker-protection/actions/extract.js b/injected/src/features/broker-protection/actions/extract.js index eff9e9fef..6d84ae526 100644 --- a/injected/src/features/broker-protection/actions/extract.js +++ b/injected/src/features/broker-protection/actions/extract.js @@ -63,7 +63,7 @@ export async function extract (action, userData, root = document) { const filtered = await Promise.all(filteredPromises) // omit the DOM node from data transfer - // eslint-disable-next-line @typescript-eslint/no-unused-vars + const debugResults = extractResult.results.map((result) => result.asData()) return new SuccessResponse({ diff --git a/injected/src/features/broker-protection/extractors/age.js b/injected/src/features/broker-protection/extractors/age.js index bf49ad6c3..4a098747c 100644 --- a/injected/src/features/broker-protection/extractors/age.js +++ b/injected/src/features/broker-protection/extractors/age.js @@ -9,7 +9,7 @@ export class AgeExtractor { * @param {string[]} strs * @param {import('../actions/extract.js').ExtractorParams} _extractorParams */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + extract (strs, _extractorParams) { if (!strs[0]) return null return strs[0].match(/\d+/)?.[0] ?? null diff --git a/injected/src/features/broker-protection/extractors/name.js b/injected/src/features/broker-protection/extractors/name.js index b85e74f04..36470e88d 100644 --- a/injected/src/features/broker-protection/extractors/name.js +++ b/injected/src/features/broker-protection/extractors/name.js @@ -10,7 +10,7 @@ export class NameExtractor { * @param {string[]} strs * @param {import('../actions/extract.js').ExtractorParams} _extractorParams */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + extract (strs, _extractorParams) { if (!strs[0]) return null return strs[0].replace(/\n/g, ' ').trim() diff --git a/injected/src/features/broker-protection/types.js b/injected/src/features/broker-protection/types.js index f131d6fbb..193de0864 100644 --- a/injected/src/features/broker-protection/types.js +++ b/injected/src/features/broker-protection/types.js @@ -79,7 +79,7 @@ export class Extractor { * @param {import("./actions/extract").ExtractorParams} extractorParams * @return {JsonValue} */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + extract (noneEmptyStringArray, extractorParams) { throw new Error('must implement extract') } @@ -94,7 +94,7 @@ export class AsyncProfileTransform { * @param {Record} profileParams - the original action params from `action.profile` * @return {Promise>} */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + transform (profile, profileParams) { throw new Error('must implement extract') } diff --git a/injected/src/features/click-to-load.js b/injected/src/features/click-to-load.js index 6562bc623..1b7763add 100644 --- a/injected/src/features/click-to-load.js +++ b/injected/src/features/click-to-load.js @@ -1887,7 +1887,7 @@ export default class ClickToLoad extends ContentFeature { }) // Listen to message from Platform letting CTL know that we're ready to // replace elements in the page - // eslint-disable-next-line promise/prefer-await-to-then + this.messaging.subscribe( 'displayClickToLoadPlaceholders', // TODO: Pass `message.options.ruleAction` through, that way only diff --git a/injected/src/features/click-to-load/components/ctl-placeholder-blocked.js b/injected/src/features/click-to-load/components/ctl-placeholder-blocked.js index 495319a24..f88106943 100644 --- a/injected/src/features/click-to-load/components/ctl-placeholder-blocked.js +++ b/injected/src/features/click-to-load/components/ctl-placeholder-blocked.js @@ -113,6 +113,7 @@ export class DDGCtlPlaceholderBlockedElement extends HTMLElement { /** * Append both to the shadow root */ + // eslint-disable-next-line @typescript-eslint/no-unused-expressions feedbackLink && this.placeholderBlocked.appendChild(feedbackLink) shadow.appendChild(this.placeholderBlocked) shadow.appendChild(style) diff --git a/injected/src/features/cookie.js b/injected/src/features/cookie.js index efcfe52ac..0d6aa9432 100644 --- a/injected/src/features/cookie.js +++ b/injected/src/features/cookie.js @@ -45,6 +45,7 @@ let loadedPolicyResolve * @param {any} ctx */ function debugHelper (action, reason, ctx) { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions cookiePolicy.debug && postDebugMessage('jscookie', { action, reason, diff --git a/injected/src/features/duck-player.js b/injected/src/features/duck-player.js index 0e1c6eb62..13c7019a4 100644 --- a/injected/src/features/duck-player.js +++ b/injected/src/features/duck-player.js @@ -59,7 +59,7 @@ import { Environment, initOverlays } from './duckplayer/overlays.js' * @internal */ export default class DuckPlayerFeature extends ContentFeature { - // eslint-disable-next-line @typescript-eslint/no-unused-vars + init (args) { /** * This feature never operates in a frame diff --git a/injected/src/features/fingerprinting-screen-size.js b/injected/src/features/fingerprinting-screen-size.js index 0a5aa7cfe..3e4aa99fb 100644 --- a/injected/src/features/fingerprinting-screen-size.js +++ b/injected/src/features/fingerprinting-screen-size.js @@ -65,7 +65,7 @@ export default class FingerprintingScreenSize extends ContentFeature { try { this.defineProperty(globalThis, property, { get: () => value, - // eslint-disable-next-line @typescript-eslint/no-empty-function + set: () => {}, configurable: true, enumerable: true diff --git a/injected/src/features/web-compat.js b/injected/src/features/web-compat.js index 8d5c924c7..79897357d 100644 --- a/injected/src/features/web-compat.js +++ b/injected/src/features/web-compat.js @@ -1,4 +1,5 @@ import ContentFeature from '../content-feature.js' +// eslint-disable-next-line no-redeclare import { URL } from '../captured-globals.js' /** diff --git a/injected/src/performance.js b/injected/src/performance.js index 85124dc70..ada6bc91c 100644 --- a/injected/src/performance.js +++ b/injected/src/performance.js @@ -30,6 +30,7 @@ export class PerformanceMonitor { /** * Tiny wrapper around performance.mark and performance.measure */ +// eslint-disable-next-line no-redeclare export class PerformanceMark { /** * @param {string} name diff --git a/injected/src/utils.js b/injected/src/utils.js index ca0899bb3..019a18099 100644 --- a/injected/src/utils.js +++ b/injected/src/utils.js @@ -1,8 +1,9 @@ +/* eslint-disable no-redeclare, no-global-assign */ /* global cloneInto, exportFunction, mozProxies */ import { Set } from './captured-globals.js' // Only use globalThis for testing this breaks window.wrappedJSObject code in Firefox -// eslint-disable-next-line no-global-assign + let globalObj = typeof window === 'undefined' ? globalThis : window let Error = globalObj.Error let messageSecret @@ -284,7 +285,7 @@ const functionMap = { // eslint-disable-next-line no-debugger debugger }, - // eslint-disable-next-line @typescript-eslint/no-empty-function + noop: () => { } } diff --git a/injected/unit-test/canvas.js b/injected/unit-test/canvas.js index a5be4ad77..18da139f3 100644 --- a/injected/unit-test/canvas.js +++ b/injected/unit-test/canvas.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line no-redeclare import ImageData from '@canvas/image-data' import { modifyPixelData } from '../src/canvas.js' diff --git a/injected/unit-test/content-feature.js b/injected/unit-test/content-feature.js index 7258bf8e6..d471bf5de 100644 --- a/injected/unit-test/content-feature.js +++ b/injected/unit-test/content-feature.js @@ -55,7 +55,7 @@ describe('ContentFeature class', () => { // eslint-disable-next-line // @ts-ignore partial mock messaging = { - // eslint-disable-next-line + notify (name, data) {} } } diff --git a/injected/unit-test/messaging.js b/injected/unit-test/messaging.js index 1ca9b266a..14059045e 100644 --- a/injected/unit-test/messaging.js +++ b/injected/unit-test/messaging.js @@ -15,7 +15,7 @@ describe('Messaging Transports', () => { messaging.request('helloWorld', { foo: 'bar' }) // grab the auto-generated `id` field - const [requestMessage] = spy.calls.first()?.args + const [requestMessage] = spy.calls.first()?.args ?? [] expect(typeof requestMessage.id).toBe('string') expect(requestMessage.id.length).toBeGreaterThan(0) @@ -206,16 +206,16 @@ describe('Android', () => { function createMessaging () { /** @type {import("@duckduckgo/messaging").MessagingTransport} */ const transport = { - // eslint-disable-next-line @typescript-eslint/no-unused-vars + notify (msg) { // test }, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + request: (_msg) => { // test return Promise.resolve(null) }, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + subscribe (_msg) { // test return () => { diff --git a/messaging/index.js b/messaging/index.js index 356085f03..de1133965 100644 --- a/messaging/index.js +++ b/messaging/index.js @@ -133,7 +133,7 @@ export class MessagingTransport { * @param {NotificationMessage} msg * @returns {void} */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + notify (msg) { throw new Error("must implement 'notify'") } @@ -143,7 +143,7 @@ export class MessagingTransport { * @param {{signal?: AbortSignal}} [options] * @return {Promise} */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + request (msg, options = {}) { throw new Error('must implement') } @@ -153,7 +153,7 @@ export class MessagingTransport { * @param {(value: unknown) => void} callback * @return {() => void} */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + subscribe (msg, callback) { throw new Error('must implement') } diff --git a/messaging/lib/examples/payloads.js b/messaging/lib/examples/payloads.js index ed486340d..9273f61bd 100644 --- a/messaging/lib/examples/payloads.js +++ b/messaging/lib/examples/payloads.js @@ -52,7 +52,7 @@ const messageResponseError = { * This is the payload response for a subscriptionEvent * @type {SubscriptionEvent} */ -const event = { +const myEvent = { context: 'contentScopeScripts', featureName: 'duckPlayerOverlays', subscriptionName: 'setUserValues', diff --git a/messaging/lib/test-utils.mjs b/messaging/lib/test-utils.mjs index 2bc17b3a5..4093bd620 100644 --- a/messaging/lib/test-utils.mjs +++ b/messaging/lib/test-utils.mjs @@ -24,9 +24,9 @@ export function mockWindowsMessaging(params) { } } const listeners = [] - // @ts-ignore + // @ts-expect-error mocking is intentional window.chrome = {}; - // @ts-ignore + // @ts-expect-error mocking is intentional window.chrome.webview = { /** * @param {AnyWindowsMessage} input @@ -87,7 +87,6 @@ export function mockWindowsMessaging(params) { result: response, context: msg.context, featureName: msg.featureName, - // @ts-ignore - shane: fix this id: msg.id, }, }) @@ -134,7 +133,7 @@ export function mockWebkitMessaging(params) { }))) // force a 'tick' to allow tests to reset mocks before reading responses - await new Promise(res => setTimeout(res, 0)); + await new Promise(resolve => setTimeout(resolve, 0)); // if it's a notification, simulate the empty response and don't check for a response if (!('id' in msg)) { @@ -152,7 +151,6 @@ export function mockWebkitMessaging(params) { result: response, context: msg.context, featureName: msg.featureName, - // @ts-ignore - shane: fix this id: msg.id, } @@ -185,6 +183,7 @@ export function mockAndroidMessaging(params) { * @param {string} secret * @return {Promise} */ + // eslint-disable-next-line require-await process: async (jsonString, secret) => { /** @type {RequestMessage | NotificationMessage} */ @@ -210,11 +209,10 @@ export function mockAndroidMessaging(params) { result: response, context: msg.context, featureName: msg.featureName, - // @ts-ignore - shane: fix this id: msg.id, } - globalThis['messageCallback']?.(secret, r); + globalThis.messageCallback?.(secret, r); } } } @@ -260,7 +258,7 @@ export function readOutgoingMessages() { * @param {Record} replacements */ export function wrapWindowsScripts(js, replacements) { - for (let [find, replace] of Object.entries(replacements)) { + for (const [find, replace] of Object.entries(replacements)) { js = js.replace(find, JSON.stringify(replace)); } return ` @@ -286,7 +284,7 @@ export function wrapWindowsScripts(js, replacements) { * @param {Record} replacements */ export function wrapWebkitScripts(js, replacements) { - for (let [find, replace] of Object.entries(replacements)) { + for (const [find, replace] of Object.entries(replacements)) { js = js.replace(find, JSON.stringify(replace)); } return js; @@ -308,7 +306,7 @@ export function simulateSubscriptionMessage(params) { } switch (params.injectName) { case "windows": { - // @ts-expect-error + // @ts-expect-error DDG custom global const fn = window.chrome?.webview?.postMessage || window.windowsInteropPostMessage; fn(subscriptionEvent) break; diff --git a/messaging/lib/webkit.js b/messaging/lib/webkit.js index 73573b0dd..33adeafd7 100644 --- a/messaging/lib/webkit.js +++ b/messaging/lib/webkit.js @@ -189,7 +189,7 @@ export class WebkitMessagingTransport { * @param {any[]} args */ value: (...args) => { - // eslint-disable-next-line n/no-callback-literal + callback(...args) delete this.globals.window[randomMethodName] } diff --git a/messaging/lib/windows.js b/messaging/lib/windows.js index 0af6fb525..33d7d8944 100644 --- a/messaging/lib/windows.js +++ b/messaging/lib/windows.js @@ -169,13 +169,13 @@ export class WindowsMessagingTransport { } // console.log('DEBUG: handler setup', { config, comparator }) - // eslint-disable-next-line no-undef + this.config.methods.addEventListener('message', idHandler) options?.signal?.addEventListener('abort', abortHandler) teardown = () => { // console.log('DEBUG: handler teardown', { config, comparator }) - // eslint-disable-next-line no-undef + this.config.methods.removeEventListener('message', idHandler) options?.signal?.removeEventListener('abort', abortHandler) } diff --git a/package-lock.json b/package-lock.json index aee01ef03..eae356e9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,24 +14,23 @@ "types-generator" ], "devDependencies": { - "@typescript-eslint/eslint-plugin": "^6.9.1", - "eslint": "^8.57.1", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^6.1.1", + "@duckduckgo/eslint-config": "github:duckduckgo/eslint-config#51dc868a4342379d6aec1d0f4214156e7046d5f6", + "@playwright/test": "^1.48.2", + "@types/eslint__js": "^8.42.3", + "eslint": "^9.13.0", "minimist": "^1.2.8", "stylelint": "^15.11.0", "stylelint-config-standard": "^34.0.0", "stylelint-csstree-validator": "^3.0.0", "typedoc": "^0.26.10", - "typescript": "^5.6.3" + "typescript": "^5.6.3", + "typescript-eslint": "^8.12.2" } }, "injected": { "hasInstallScript": true, "dependencies": { - "immutable-json-patch": "^5.1.3", + "immutable-json-patch": "^6.0.1", "parse-address": "^1.1.2", "seedrandom": "^3.0.5", "sjcl": "^1.0.8" @@ -39,20 +38,217 @@ "devDependencies": { "@canvas/image-data": "^1.0.0", "@fingerprintjs/fingerprintjs": "^4.5.1", - "@rollup/plugin-commonjs": "^26.0.1", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-replace": "^5.0.7", - "@types/chrome": "^0.0.278", + "@rollup/plugin-commonjs": "^28.0.1", + "@rollup/plugin-node-resolve": "^15.3.0", + "@rollup/plugin-replace": "^6.0.1", + "@types/chrome": "^0.0.279", "@types/jasmine": "^5.1.4", - "@types/node": "^22.7.7", + "@types/node": "^22.8.6", "@typescript-eslint/eslint-plugin": "^6.9.1", - "config-builder": "git+ssh://git@github.com/duckduckgo/privacy-configuration.git#207bcafcd8d67d0530569f7efcf84463194b999b", + "config-builder": "github:duckduckgo/privacy-configuration#1729260354597", "fast-check": "^3.22.0", "jasmine": "^5.4.0", "minimist": "^1.2.8", - "rollup": "^3.29.5", - "rollup-plugin-import-css": "^3.5.2", - "rollup-plugin-svg-import": "^2.1.0" + "rollup": "^4.24.3", + "rollup-plugin-import-css": "^3.5.6", + "rollup-plugin-svg-import": "^3.0.0" + } + }, + "injected/node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "injected/node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "injected/node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "peer": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "injected/node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "injected/node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "injected/node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "injected/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" } }, "messaging": { @@ -300,14 +496,46 @@ "postcss-selector-parser": "^6.0.13" } }, + "node_modules/@duckduckgo/eslint-config": { + "version": "1.0.0", + "resolved": "git+ssh://git@github.com/duckduckgo/eslint-config.git#51dc868a4342379d6aec1d0f4214156e7046d5f6", + "integrity": "sha512-4LiMeyUHFI/sBat9IWu0kVE4CbYhVOQ0dSIBETTBxvAOvolVARZZZ7tlsaag6/5EU2gvHwTRLSVTOVUhLdzBRA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@eslint/js": "^9.13.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-n": "^17.11.1", + "eslint-plugin-promise": "^7.1.0" + }, + "peerDependencies": { + "eslint": ">= 9" + } + }, "node_modules/@duckduckgo/messaging": { "resolved": "messaging", "link": true }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", - "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", "cpu": [ "arm" ], @@ -317,13 +545,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", - "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", "cpu": [ "arm64" ], @@ -333,13 +561,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", - "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", "cpu": [ "x64" ], @@ -349,13 +577,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", - "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", "cpu": [ "arm64" ], @@ -365,13 +593,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", - "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", "cpu": [ "x64" ], @@ -381,13 +609,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", - "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", "cpu": [ "arm64" ], @@ -397,13 +625,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", - "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", "cpu": [ "x64" ], @@ -413,13 +641,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", - "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", "cpu": [ "arm" ], @@ -429,13 +657,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", - "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", "cpu": [ "arm64" ], @@ -445,13 +673,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", - "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", "cpu": [ "ia32" ], @@ -461,13 +689,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", - "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", "cpu": [ "loong64" ], @@ -477,13 +705,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", - "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", "cpu": [ "mips64el" ], @@ -493,13 +721,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", - "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", "cpu": [ "ppc64" ], @@ -509,13 +737,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", - "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", "cpu": [ "riscv64" ], @@ -525,13 +753,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", - "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", "cpu": [ "s390x" ], @@ -541,13 +769,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", - "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", "cpu": [ "x64" ], @@ -557,13 +785,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", - "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", "cpu": [ "x64" ], @@ -573,13 +801,29 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", - "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", "cpu": [ "x64" ], @@ -589,13 +833,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", - "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", "cpu": [ "x64" ], @@ -605,13 +849,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", - "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", "cpu": [ "arm64" ], @@ -621,13 +865,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", - "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", "cpu": [ "ia32" ], @@ -637,13 +881,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", - "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", "cpu": [ "x64" ], @@ -653,7 +897,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -672,19 +916,43 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -704,12 +972,34 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", + "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", + "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", + "dev": true, + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@fingerprintjs/fingerprintjs": { @@ -726,12 +1016,35 @@ "resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.2.tgz", "integrity": "sha512-SwPWfeRa5veb1hOIBMdzI+73te5puUBHmqqaF1Bu7FjvxlYSz/kJcZKSa9Cg60zL0uRNeJL2SbRxV6Jp6Q1nFQ==" }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "peer": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", @@ -759,7 +1072,21 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", - "dev": true + "dev": true, + "peer": true + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -915,37 +1242,39 @@ } }, "node_modules/@playwright/test": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.40.1.tgz", - "integrity": "sha512-EaaawMTOeEItCRvfmkI9v6rBkF1svM8wjl/YPRrg2N2Wmp+4qJYkWtJsbew1szfKKDm6fPLy4YAanBhIlf9dWw==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "playwright": "1.40.1" + "playwright": "1.48.2" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@rive-app/canvas-single": { - "version": "2.21.7", - "resolved": "https://registry.npmjs.org/@rive-app/canvas-single/-/canvas-single-2.21.7.tgz", - "integrity": "sha512-6qswkh/o0lRZFslrGYF4xUZbP9D1SBIVfEiRBFPaoUfHh4d6rHZrE+Oifik+kjT+JCMfyD/pWAorn1GtfvJq5A==" + "version": "2.23.3", + "resolved": "https://registry.npmjs.org/@rive-app/canvas-single/-/canvas-single-2.23.3.tgz", + "integrity": "sha512-smy7iudTwslPCAEWC776FNtRhPErUnG8eoC00j8CSn47YiD3mBBNxRid2Ejj3smbfk2X4z/o1icUvXVjMXmSdA==" }, "node_modules/@rollup/plugin-commonjs": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-26.0.1.tgz", - "integrity": "sha512-UnsKoZK6/aGIH6AdkptXhNvhaqftcjq3zZdT+LY5Ftms6JR06nADcDsYp5hTU9E2lbJUEOhdlY5J4DNTneM+jQ==", + "version": "28.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz", + "integrity": "sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", - "glob": "^10.4.1", + "fdir": "^6.2.0", "is-reference": "1.2.1", - "magic-string": "^0.30.3" + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" }, "engines": { "node": ">=16.0.0 || 14 >= 14.17" @@ -959,60 +1288,41 @@ } } }, - "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "node_modules/@rollup/plugin-commonjs/node_modules/fdir": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "peerDependencies": { + "picomatch": "^3 || ^4" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/@rollup/plugin-commonjs/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.2.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", - "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", + "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", "resolve": "^1.22.1" }, @@ -1029,9 +1339,9 @@ } }, "node_modules/@rollup/plugin-replace": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.7.tgz", - "integrity": "sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-6.0.1.tgz", + "integrity": "sha512-2sPh9b73dj5IxuMmDAsQWVFT7mR+yoHweBaXG2W/R8vQ+IWZlnaI7BR7J6EguVQUp1hd8Z7XuozpDjEKQAAC2Q==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -1071,11 +1381,246 @@ } } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz", + "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz", + "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz", + "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz", + "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz", + "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz", + "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz", + "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz", + "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz", + "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz", + "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz", + "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz", + "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz", + "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz", + "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz", + "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz", + "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz", + "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz", + "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@shikijs/core": { "version": "1.22.0", @@ -1134,19 +1679,40 @@ "license": "MIT" }, "node_modules/@types/chrome": { - "version": "0.0.278", - "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.278.tgz", - "integrity": "sha512-PDIJodOu7o54PpSOYLybPW/MDZBCjM1TKgf31I3Q/qaEbNpIH09rOM3tSEH3N7Q+FAqb1933LhF8ksUPYeQLNg==", + "version": "0.0.279", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.279.tgz", + "integrity": "sha512-wl0IxQ2OQiMazPZM5LimHQ7Jwd72/O8UvvzyptplXT2S4eUqXH5C0n8S+v8PtKhyX89p0igCPpNy3Bwksyk57g==", "dev": true, "dependencies": { "@types/filesystem": "*", "@types/har-format": "*" } }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint__js": { + "version": "8.42.3", + "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz", + "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*" + } + }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/filesystem": { @@ -1196,7 +1762,8 @@ "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/lodash": { "version": "4.17.9", @@ -1222,12 +1789,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.7.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.7.tgz", - "integrity": "sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==", + "version": "22.8.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.6.tgz", + "integrity": "sha512-tosuJYKrIqjQIlVCM4PEGxOmyg3FCPa/fViuJChnGeEIhjA46oy8FMVoF9su1/v8PNs2a8Q0iFNyOx0uOF91nw==", "dev": true, "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.19.8" } }, "node_modules/@types/normalize-package-data": { @@ -1244,46 +1811,119 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.12.2.tgz", + "integrity": "sha512-gQxbxM8mcxBwaEmWdtLCIGLfixBMHhQjBqR8sVWNTPpcj45WlYL2IObS/DNMLH1DBP0n8qz+aiiLTGfopPEebw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/type-utils": "8.12.2", + "@typescript-eslint/utils": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", "dev": true, - "license": "MIT" + "dependencies": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, - "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", - "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", + "node_modules/@typescript-eslint/parser": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.12.2.tgz", + "integrity": "sha512-MrvlXNfGPLH3Z+r7Tk+Z5moZAc0dzdVjTgUgwsdGweH7lydysQsnSww3nAmsq8blFuRD5VRlAr9YdEFw3e6PBw==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/type-utils": "6.9.1", - "@typescript-eslint/utils": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/typescript-estree": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", + "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1291,91 +1931,113 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", - "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1" + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@typescript-eslint/parser": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz", - "integrity": "sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", "dev": true, - "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", - "debug": "^4.3.4" + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "engines": { + "node": ">=16 || 14 >=14.17" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", - "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, - "peer": true, "dependencies": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1386,26 +2048,23 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", - "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.12.2.tgz", + "integrity": "sha512-bwuU4TAogPI+1q/IJSKuD4shBLc/d2vGcRT588q+jzayQyjVK2X6v/fbR4InY2U2sgf8MEvVCqEWUzYzgBNcGQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.9.1", - "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/typescript-estree": "8.12.2", + "@typescript-eslint/utils": "8.12.2", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -1413,12 +2072,12 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1426,21 +2085,22 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", - "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1453,28 +2113,51 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/types": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", - "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, - "peer": true, "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -1484,17 +2167,17 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", - "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, - "peer": true, "dependencies": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, @@ -1511,42 +2194,63 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", - "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.12.2.tgz", + "integrity": "sha512-UTTuDIX3fkfAz6iSVa5rTuSfWIYZ6ATtEocQ/umkRSyC9O919lbZ8dcH7mysshrCdrAM03skJOEYaBugxN+M6A==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/typescript-estree": "6.9.1", - "semver": "^7.5.4" + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/typescript-estree": "8.12.2" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", - "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1" + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1554,12 +2258,12 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1567,21 +2271,22 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", - "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1594,30 +2299,53 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", - "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, - "peer": true, "dependencies": { - "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -1635,9 +2363,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1715,6 +2443,7 @@ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -1731,6 +2460,7 @@ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -1760,6 +2490,7 @@ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -1780,6 +2511,7 @@ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -1798,6 +2530,7 @@ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -1816,6 +2549,7 @@ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -1867,6 +2601,7 @@ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -1923,28 +2658,6 @@ "node": ">=8" } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "peer": true, - "dependencies": { - "semver": "^7.0.0" - } - }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -2068,9 +2781,9 @@ } }, "node_modules/classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, "node_modules/color-convert": { "version": "2.0.1", @@ -2249,6 +2962,7 @@ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -2266,6 +2980,7 @@ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -2283,6 +2998,7 @@ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -2399,6 +3115,7 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -2452,6 +3169,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -2556,6 +3274,20 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -2580,6 +3312,7 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -2661,6 +3394,7 @@ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -2673,6 +3407,7 @@ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -2687,6 +3422,7 @@ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.0" } @@ -2696,6 +3432,7 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -2709,40 +3446,42 @@ } }, "node_modules/esbuild": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", - "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/android-arm": "0.19.5", - "@esbuild/android-arm64": "0.19.5", - "@esbuild/android-x64": "0.19.5", - "@esbuild/darwin-arm64": "0.19.5", - "@esbuild/darwin-x64": "0.19.5", - "@esbuild/freebsd-arm64": "0.19.5", - "@esbuild/freebsd-x64": "0.19.5", - "@esbuild/linux-arm": "0.19.5", - "@esbuild/linux-arm64": "0.19.5", - "@esbuild/linux-ia32": "0.19.5", - "@esbuild/linux-loong64": "0.19.5", - "@esbuild/linux-mips64el": "0.19.5", - "@esbuild/linux-ppc64": "0.19.5", - "@esbuild/linux-riscv64": "0.19.5", - "@esbuild/linux-s390x": "0.19.5", - "@esbuild/linux-x64": "0.19.5", - "@esbuild/netbsd-x64": "0.19.5", - "@esbuild/openbsd-x64": "0.19.5", - "@esbuild/sunos-x64": "0.19.5", - "@esbuild/win32-arm64": "0.19.5", - "@esbuild/win32-ia32": "0.19.5", - "@esbuild/win32-x64": "0.19.5" + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" } }, "node_modules/escape-goat": { @@ -2770,87 +3509,80 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", + "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.13.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-standard": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", - "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", - "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" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true } - ], + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.4" + }, "engines": { - "node": ">=12.0.0" + "node": ">=12" }, "peerDependencies": { - "eslint": "^8.0.1", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", - "eslint-plugin-promise": "^6.0.0" + "eslint": ">=6.0.0" } }, "node_modules/eslint-import-resolver-node": { @@ -2858,6 +3590,7 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -2869,6 +3602,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -2878,6 +3612,7 @@ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -2895,27 +3630,31 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" }, "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "eslint": ">=4.19.1" + "eslint": ">=8" } }, "node_modules/eslint-plugin-import": { @@ -2923,6 +3662,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, + "license": "MIT", "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.8", @@ -2956,6 +3696,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -2965,6 +3706,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -2977,202 +3719,212 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/eslint-plugin-n": { - "version": "15.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.6.1.tgz", - "integrity": "sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA==", + "version": "17.12.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.12.0.tgz", + "integrity": "sha512-zNAtz/erDn0v78bIY3MASSQlyaarV4IOTvP5ldHsqblRFrXriikB6ghkDTkHjUad+nMRrIbOy9euod2azjRfBg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "builtins": "^5.0.1", - "eslint-plugin-es": "^4.1.0", - "eslint-utils": "^3.0.0", - "ignore": "^5.1.1", - "is-core-module": "^2.11.0", - "minimatch": "^3.1.2", - "resolve": "^1.22.1", - "semver": "^7.3.8" + "@eslint-community/eslint-utils": "^4.4.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "ignore": "^5.3.2", + "minimatch": "^9.0.5", + "semver": "^7.6.3" }, "engines": { - "node": ">=12.22.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": ">=8.23.0" } }, - "node_modules/eslint-plugin-n/node_modules/eslint-plugin-es": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", - "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", + "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8.10.0" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-n/node_modules/eslint-plugin-es/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=6" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint-plugin-n/node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/eslint-plugin-promise": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-7.1.0.tgz", + "integrity": "sha512-8trNmPxdAy3W620WKDpaS65NlM5yAumod6XeC4LOb+jxlkG4IVcp68c6dXY2ev+uT4U1PtG57YDV6EGAXN0GbQ==", "dev": true, - "peer": true, + "license": "ISC", "engines": { - "node": ">=4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/eslint-plugin-n/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "peer": true, "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-plugin-n/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "node_modules/eslint/node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=8.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/eslint/node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": ">=6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/eslint/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, "engines": { - "node": ">=4" + "node": ">=16.0.0" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/eslint/node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, - "funding": { - "url": "https://opencollective.com/eslint" + "engines": { + "node": ">=16" } }, "node_modules/eslint/node_modules/glob-parent": { @@ -3187,11 +3939,24 @@ "node": ">=10.13.0" } }, + "node_modules/eslint/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "peer": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -3205,9 +3970,9 @@ } }, "node_modules/esquery": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", - "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3287,9 +4052,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3368,6 +4133,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "peer": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -3451,6 +4217,7 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } @@ -3517,6 +4284,7 @@ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3535,6 +4303,7 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3563,6 +4332,7 @@ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -3575,6 +4345,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3653,6 +4436,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -3664,12 +4448,14 @@ } }, "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, + "license": "MIT", "dependencies": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -3717,6 +4503,13 @@ "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, + "license": "ISC" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3738,6 +4531,7 @@ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3792,6 +4586,7 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -3979,18 +4774,18 @@ } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/immutable-json-patch": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/immutable-json-patch/-/immutable-json-patch-5.1.3.tgz", - "integrity": "sha512-95AsF9hJTPpwtBGAnHmw57PASL672tb+vGHR5xLhH2VPuHSsLho7grjlfgQ65DIhHP+UmLCjdmuuA6L1ndJbZg==" + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/immutable-json-patch/-/immutable-json-patch-6.0.1.tgz", + "integrity": "sha512-BHL/cXMjwFZlTOffiWNdY8ZTvNyYLrutCnWxrcKPHr5FqpAb6vsO6WWSPnVSys3+DruFN6lhHJJPHi8uELQL5g==" }, "node_modules/import-fresh": { "version": "3.3.0", @@ -4072,6 +4867,7 @@ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -4086,6 +4882,7 @@ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -4109,6 +4906,7 @@ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -4121,6 +4919,7 @@ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -4132,26 +4931,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4179,6 +4964,7 @@ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, + "license": "MIT", "dependencies": { "is-typed-array": "^1.1.13" }, @@ -4194,6 +4980,7 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -4245,6 +5032,7 @@ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4266,6 +5054,7 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -4281,6 +5070,7 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -4319,6 +5109,7 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -4335,6 +5126,7 @@ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7" }, @@ -4350,6 +5142,7 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -4365,6 +5158,7 @@ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -4380,6 +5174,7 @@ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, + "license": "MIT", "dependencies": { "which-typed-array": "^1.1.14" }, @@ -4395,6 +5190,7 @@ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -4406,7 +5202,8 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", @@ -4609,6 +5406,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -5171,6 +5969,7 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -5180,6 +5979,7 @@ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -5198,6 +5998,7 @@ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -5216,6 +6017,7 @@ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -5230,6 +6032,7 @@ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -5452,33 +6255,35 @@ } }, "node_modules/playwright": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.40.1.tgz", - "integrity": "sha512-2eHI7IioIpQ0bS1Ovg/HszsN/XKNwEG1kbzSDDmADpclKc7CyqkHw7Mg2JCz/bbCxg25QUPcjksoMW7JcIFQmw==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.40.1" + "playwright-core": "1.48.2" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.40.1.tgz", - "integrity": "sha512-+hkOycxPiV534c4HhpfX6yrlawqVUzITRKwHAmYfmsVreltEl6fAZJ3DPfLMOODw0H3s1Itd6MDCWmP1fl/QvQ==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", "dev": true, + "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/portfinder": { @@ -5509,6 +6314,7 @@ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -5806,6 +6612,7 @@ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -5819,18 +6626,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -5873,6 +6668,16 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -5899,25 +6704,46 @@ } }, "node_modules/rollup": { - "version": "3.29.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", - "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", + "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.3", + "@rollup/rollup-android-arm64": "4.24.3", + "@rollup/rollup-darwin-arm64": "4.24.3", + "@rollup/rollup-darwin-x64": "4.24.3", + "@rollup/rollup-freebsd-arm64": "4.24.3", + "@rollup/rollup-freebsd-x64": "4.24.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", + "@rollup/rollup-linux-arm-musleabihf": "4.24.3", + "@rollup/rollup-linux-arm64-gnu": "4.24.3", + "@rollup/rollup-linux-arm64-musl": "4.24.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", + "@rollup/rollup-linux-riscv64-gnu": "4.24.3", + "@rollup/rollup-linux-s390x-gnu": "4.24.3", + "@rollup/rollup-linux-x64-gnu": "4.24.3", + "@rollup/rollup-linux-x64-musl": "4.24.3", + "@rollup/rollup-win32-arm64-msvc": "4.24.3", + "@rollup/rollup-win32-ia32-msvc": "4.24.3", + "@rollup/rollup-win32-x64-msvc": "4.24.3", "fsevents": "~2.3.2" } }, "node_modules/rollup-plugin-import-css": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-import-css/-/rollup-plugin-import-css-3.5.2.tgz", - "integrity": "sha512-zAkG73dG0n03xtHkqnmcvo/bjlmO9wA/YFnMHWz8XPycYsOZNmnovbTnxRP6tj7vUskdgoCW4f+zNBXqHqc5EA==", + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/rollup-plugin-import-css/-/rollup-plugin-import-css-3.5.6.tgz", + "integrity": "sha512-a+EVWlL8hGRrrAAa5Ds791sIxBxson5DCYeXAwWqYm+ITziUpmiFTR5czS7EEkuw1k7IZj1lGnHnuCVo0tmxzg==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.4" @@ -5930,18 +6756,18 @@ } }, "node_modules/rollup-plugin-svg-import": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-svg-import/-/rollup-plugin-svg-import-2.1.0.tgz", - "integrity": "sha512-uHTYG/shURfBvX2wieST5898uvKBnhE6XuhFDGlNzr0HSMNGEapo/oT9u7Xogr4bgpAvhL1hsdZGdWXA1X1N1g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svg-import/-/rollup-plugin-svg-import-3.0.0.tgz", + "integrity": "sha512-5fUESTM5hdqJojrwO53JQUO7NespLNx4iLeMsToQfuaGGqGT5sz85Ns5gCDNxLO6yBPbn7p0A/6YA+Rq3clg4Q==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" }, "peerDependencies": { - "rollup": "^2.0.0||^3.0.0" + "rollup": "^3.0.0||^4.0.0" } }, "node_modules/run-parallel": { @@ -5972,6 +6798,7 @@ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -5990,6 +6817,7 @@ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -6020,13 +6848,11 @@ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -6056,6 +6882,7 @@ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -6258,6 +7085,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -6276,6 +7104,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -6290,6 +7119,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -6347,6 +7177,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -6609,6 +7440,16 @@ "dev": true, "license": "MIT" }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -6678,12 +7519,12 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" @@ -6694,6 +7535,7 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -6724,6 +7566,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, @@ -6736,6 +7579,7 @@ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -6750,6 +7594,7 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -6769,6 +7614,7 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -6789,6 +7635,7 @@ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -6871,6 +7718,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.12.2.tgz", + "integrity": "sha512-UbuVUWSrHVR03q9CWx+JDHeO6B/Hr9p4U5lRH++5tq/EbFq1faYZe50ZSBePptgfIKLEti0aPQ3hFgnPVcd8ZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.12.2", + "@typescript-eslint/parser": "8.12.2", + "@typescript-eslint/utils": "8.12.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", @@ -6883,6 +7754,7 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -7143,6 +8015,7 @@ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -7159,6 +8032,7 @@ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -7297,14 +8171,13 @@ "license": "ISC", "dependencies": { "@formkit/auto-animate": "^0.8.2", - "@rive-app/canvas-single": "^2.21.7", - "classnames": "^2.3.2", + "@rive-app/canvas-single": "^2.23.3", + "classnames": "^2.5.1", "preact": "^10.24.3" }, "devDependencies": { "@duckduckgo/messaging": "*", - "@playwright/test": "^1.40.1", - "esbuild": "^0.19.5", + "esbuild": "^0.24.0", "fast-check": "^3.22.0", "http-server": "^14.1.1", "web-resource-inliner": "^6.0.1" @@ -7455,160 +8328,186 @@ "dev": true, "requires": {} }, + "@duckduckgo/eslint-config": { + "version": "git+ssh://git@github.com/duckduckgo/eslint-config.git#51dc868a4342379d6aec1d0f4214156e7046d5f6", + "integrity": "sha512-4LiMeyUHFI/sBat9IWu0kVE4CbYhVOQ0dSIBETTBxvAOvolVARZZZ7tlsaag6/5EU2gvHwTRLSVTOVUhLdzBRA==", + "dev": true, + "from": "@duckduckgo/eslint-config@github:duckduckgo/eslint-config#51dc868a4342379d6aec1d0f4214156e7046d5f6", + "requires": { + "@eslint/js": "^9.13.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-n": "^17.11.1", + "eslint-plugin-promise": "^7.1.0" + } + }, "@duckduckgo/messaging": { "version": "file:messaging" }, + "@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "dev": true, + "optional": true + }, "@esbuild/android-arm": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", - "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", - "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", - "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", - "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", - "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", - "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", - "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", - "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", - "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", - "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", - "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", - "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", - "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", - "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", - "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", - "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", - "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", - "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", - "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", - "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", - "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", - "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", "dev": true, "optional": true }, @@ -7622,9 +8521,26 @@ } }, "@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true + }, + "@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "requires": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + } + }, + "@eslint/core": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", "dev": true }, "@eslint/eslintrc": { @@ -7632,6 +8548,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "peer": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -7645,11 +8562,26 @@ } }, "@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", + "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", + "dev": true + }, + "@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "dev": true }, + "@eslint/plugin-kit": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", + "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", + "dev": true, + "requires": { + "levn": "^0.4.1" + } + }, "@fingerprintjs/fingerprintjs": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/@fingerprintjs/fingerprintjs/-/fingerprintjs-4.5.1.tgz", @@ -7664,11 +8596,28 @@ "resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.2.tgz", "integrity": "sha512-SwPWfeRa5veb1hOIBMdzI+73te5puUBHmqqaF1Bu7FjvxlYSz/kJcZKSa9Cg60zL0uRNeJL2SbRxV6Jp6Q1nFQ==" }, + "@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true + }, + "@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "requires": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + } + }, "@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "dev": true, + "peer": true, "requires": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", @@ -7685,6 +8634,13 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "dev": true, + "peer": true + }, + "@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true }, "@isaacs/cliui": { @@ -7798,85 +8754,66 @@ "optional": true }, "@playwright/test": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.40.1.tgz", - "integrity": "sha512-EaaawMTOeEItCRvfmkI9v6rBkF1svM8wjl/YPRrg2N2Wmp+4qJYkWtJsbew1szfKKDm6fPLy4YAanBhIlf9dWw==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", "dev": true, "requires": { - "playwright": "1.40.1" + "playwright": "1.48.2" } }, "@rive-app/canvas-single": { - "version": "2.21.7", - "resolved": "https://registry.npmjs.org/@rive-app/canvas-single/-/canvas-single-2.21.7.tgz", - "integrity": "sha512-6qswkh/o0lRZFslrGYF4xUZbP9D1SBIVfEiRBFPaoUfHh4d6rHZrE+Oifik+kjT+JCMfyD/pWAorn1GtfvJq5A==" + "version": "2.23.3", + "resolved": "https://registry.npmjs.org/@rive-app/canvas-single/-/canvas-single-2.23.3.tgz", + "integrity": "sha512-smy7iudTwslPCAEWC776FNtRhPErUnG8eoC00j8CSn47YiD3mBBNxRid2Ejj3smbfk2X4z/o1icUvXVjMXmSdA==" }, "@rollup/plugin-commonjs": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-26.0.1.tgz", - "integrity": "sha512-UnsKoZK6/aGIH6AdkptXhNvhaqftcjq3zZdT+LY5Ftms6JR06nADcDsYp5hTU9E2lbJUEOhdlY5J4DNTneM+jQ==", + "version": "28.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz", + "integrity": "sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", - "glob": "^10.4.1", + "fdir": "^6.2.0", "is-reference": "1.2.1", - "magic-string": "^0.30.3" + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" }, "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "fdir": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - } + "requires": {} }, - "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } + "picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true } } }, "@rollup/plugin-node-resolve": { - "version": "15.2.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", - "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", + "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", "resolve": "^1.22.1" } }, "@rollup/plugin-replace": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.7.tgz", - "integrity": "sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-6.0.1.tgz", + "integrity": "sha512-2sPh9b73dj5IxuMmDAsQWVFT7mR+yoHweBaXG2W/R8vQ+IWZlnaI7BR7J6EguVQUp1hd8Z7XuozpDjEKQAAC2Q==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", @@ -7894,6 +8831,132 @@ "picomatch": "^2.3.1" } }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz", + "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz", + "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz", + "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz", + "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz", + "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz", + "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz", + "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz", + "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz", + "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz", + "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz", + "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz", + "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz", + "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz", + "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz", + "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz", + "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz", + "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz", + "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==", + "dev": true, + "optional": true + }, "@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -7952,19 +9015,38 @@ "dev": true }, "@types/chrome": { - "version": "0.0.278", - "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.278.tgz", - "integrity": "sha512-PDIJodOu7o54PpSOYLybPW/MDZBCjM1TKgf31I3Q/qaEbNpIH09rOM3tSEH3N7Q+FAqb1933LhF8ksUPYeQLNg==", + "version": "0.0.279", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.279.tgz", + "integrity": "sha512-wl0IxQ2OQiMazPZM5LimHQ7Jwd72/O8UvvzyptplXT2S4eUqXH5C0n8S+v8PtKhyX89p0igCPpNy3Bwksyk57g==", "dev": true, "requires": { "@types/filesystem": "*", "@types/har-format": "*" } }, + "@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint__js": { + "version": "8.42.3", + "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz", + "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==", + "dev": true, + "requires": { + "@types/eslint": "*" + } + }, "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "@types/filesystem": { @@ -8037,12 +9119,12 @@ "dev": true }, "@types/node": { - "version": "22.7.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.7.tgz", - "integrity": "sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==", + "version": "22.8.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.6.tgz", + "integrity": "sha512-tosuJYKrIqjQIlVCM4PEGxOmyg3FCPa/fViuJChnGeEIhjA46oy8FMVoF9su1/v8PNs2a8Q0iFNyOx0uOF91nw==", "dev": true, "requires": { - "undici-types": "~6.19.2" + "undici-types": "~6.19.8" } }, "@types/normalize-package-data": { @@ -8058,9 +9140,9 @@ "dev": true }, "@types/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "@types/unist": { @@ -8070,211 +9152,322 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", - "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.12.2.tgz", + "integrity": "sha512-gQxbxM8mcxBwaEmWdtLCIGLfixBMHhQjBqR8sVWNTPpcj45WlYL2IObS/DNMLH1DBP0n8qz+aiiLTGfopPEebw==", "dev": true, "requires": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/type-utils": "6.9.1", - "@typescript-eslint/utils": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/type-utils": "8.12.2", + "@typescript-eslint/utils": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", - "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1" + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" } }, "@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", "dev": true }, "@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" } } } }, "@typescript-eslint/parser": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz", - "integrity": "sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.12.2.tgz", + "integrity": "sha512-MrvlXNfGPLH3Z+r7Tk+Z5moZAc0dzdVjTgUgwsdGweH7lydysQsnSww3nAmsq8blFuRD5VRlAr9YdEFw3e6PBw==", "dev": true, - "peer": true, "requires": { - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/typescript-estree": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" + } + }, + "@typescript-eslint/types": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@typescript-eslint/scope-manager": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", - "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, - "peer": true, "requires": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" } }, "@typescript-eslint/type-utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", - "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.12.2.tgz", + "integrity": "sha512-bwuU4TAogPI+1q/IJSKuD4shBLc/d2vGcRT588q+jzayQyjVK2X6v/fbR4InY2U2sgf8MEvVCqEWUzYzgBNcGQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.9.1", - "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/typescript-estree": "8.12.2", + "@typescript-eslint/utils": "8.12.2", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "dependencies": { "@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", - "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" + "brace-expansion": "^2.0.1" } } } }, "@typescript-eslint/types": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", - "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", - "dev": true, - "peer": true + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", - "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, - "peer": true, "requires": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@typescript-eslint/utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", - "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.12.2.tgz", + "integrity": "sha512-UTTuDIX3fkfAz6iSVa5rTuSfWIYZ6ATtEocQ/umkRSyC9O919lbZ8dcH7mysshrCdrAM03skJOEYaBugxN+M6A==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/typescript-estree": "6.9.1", - "semver": "^7.5.4" + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/typescript-estree": "8.12.2" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", - "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1" + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" } }, "@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", - "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" } } } }, "@typescript-eslint/visitor-keys": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", - "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, - "peer": true, "requires": { - "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" } }, @@ -8285,9 +9478,9 @@ "dev": true }, "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true }, "acorn-jsx": { @@ -8492,22 +9685,6 @@ "fill-range": "^7.0.1" } }, - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true - }, - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "peer": true, - "requires": { - "semver": "^7.0.0" - } - }, "call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -8582,9 +9759,9 @@ "dev": true }, "classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, "color-convert": { "version": "2.0.1", @@ -8839,6 +10016,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "peer": true, "requires": { "esutils": "^2.0.2" } @@ -8914,6 +10092,16 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -9039,33 +10227,35 @@ } }, "esbuild": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", - "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.19.5", - "@esbuild/android-arm64": "0.19.5", - "@esbuild/android-x64": "0.19.5", - "@esbuild/darwin-arm64": "0.19.5", - "@esbuild/darwin-x64": "0.19.5", - "@esbuild/freebsd-arm64": "0.19.5", - "@esbuild/freebsd-x64": "0.19.5", - "@esbuild/linux-arm": "0.19.5", - "@esbuild/linux-arm64": "0.19.5", - "@esbuild/linux-ia32": "0.19.5", - "@esbuild/linux-loong64": "0.19.5", - "@esbuild/linux-mips64el": "0.19.5", - "@esbuild/linux-ppc64": "0.19.5", - "@esbuild/linux-riscv64": "0.19.5", - "@esbuild/linux-s390x": "0.19.5", - "@esbuild/linux-x64": "0.19.5", - "@esbuild/netbsd-x64": "0.19.5", - "@esbuild/openbsd-x64": "0.19.5", - "@esbuild/sunos-x64": "0.19.5", - "@esbuild/win32-arm64": "0.19.5", - "@esbuild/win32-ia32": "0.19.5", - "@esbuild/win32-x64": "0.19.5" + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" } }, "escape-goat": { @@ -9081,51 +10271,111 @@ "dev": true }, "eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", + "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.13.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "dependencies": { + "@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true + }, + "espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "requires": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + } + }, + "file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "requires": { + "flat-cache": "^4.0.0" + } + }, + "flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "requires": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + } + }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -9134,15 +10384,23 @@ "requires": { "is-glob": "^4.0.3" } + }, + "globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true } } }, - "eslint-config-standard": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", - "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", + "eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, - "requires": {} + "requires": { + "semver": "^7.5.4" + } }, "eslint-import-resolver-node": { "version": "0.3.9", @@ -9186,14 +10444,15 @@ } } }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", "dev": true, "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" } }, "eslint-plugin-import": { @@ -9250,97 +10509,51 @@ } }, "eslint-plugin-n": { - "version": "15.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.6.1.tgz", - "integrity": "sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA==", + "version": "17.12.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.12.0.tgz", + "integrity": "sha512-zNAtz/erDn0v78bIY3MASSQlyaarV4IOTvP5ldHsqblRFrXriikB6ghkDTkHjUad+nMRrIbOy9euod2azjRfBg==", "dev": true, - "peer": true, "requires": { - "builtins": "^5.0.1", - "eslint-plugin-es": "^4.1.0", - "eslint-utils": "^3.0.0", - "ignore": "^5.1.1", - "is-core-module": "^2.11.0", - "minimatch": "^3.1.2", - "resolve": "^1.22.1", - "semver": "^7.3.8" + "@eslint-community/eslint-utils": "^4.4.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "ignore": "^5.3.2", + "minimatch": "^9.0.5", + "semver": "^7.6.3" }, "dependencies": { - "eslint-plugin-es": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", - "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "peer": true, "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "peer": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "peer": true - } + "balanced-match": "^1.0.0" } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "globals": { + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", + "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", + "dev": true + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "peer": true, "requires": { - "eslint-visitor-keys": "^2.0.0" + "brace-expansion": "^2.0.1" } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "peer": true - } - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true } } }, "eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-7.1.0.tgz", + "integrity": "sha512-8trNmPxdAy3W620WKDpaS65NlM5yAumod6XeC4LOb+jxlkG4IVcp68c6dXY2ev+uT4U1PtG57YDV6EGAXN0GbQ==", "dev": true, "requires": {} }, @@ -9349,28 +10562,12 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "peer": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, "eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -9382,6 +10579,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "peer": true, "requires": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -9389,9 +10587,9 @@ } }, "esquery": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", - "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -9446,9 +10644,9 @@ "dev": true }, "fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -9506,6 +10704,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "peer": true, "requires": { "flat-cache": "^3.0.4" } @@ -9641,6 +10840,15 @@ "get-intrinsic": "^1.2.4" } }, + "get-tsconfig": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -9700,17 +10908,19 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "peer": true, "requires": { "type-fest": "^0.20.2" } }, "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "requires": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" } }, "globby": { @@ -9742,6 +10952,12 @@ "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", @@ -9923,15 +11139,15 @@ } }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true }, "immutable-json-patch": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/immutable-json-patch/-/immutable-json-patch-5.1.3.tgz", - "integrity": "sha512-95AsF9hJTPpwtBGAnHmw57PASL672tb+vGHR5xLhH2VPuHSsLho7grjlfgQ65DIhHP+UmLCjdmuuA6L1ndJbZg==" + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/immutable-json-patch/-/immutable-json-patch-6.0.1.tgz", + "integrity": "sha512-BHL/cXMjwFZlTOffiWNdY8ZTvNyYLrutCnWxrcKPHr5FqpAb6vsO6WWSPnVSys3+DruFN6lhHJJPHi8uELQL5g==" }, "import-fresh": { "version": "3.3.0", @@ -9988,24 +11204,150 @@ "requires": { "@canvas/image-data": "^1.0.0", "@fingerprintjs/fingerprintjs": "^4.5.1", - "@rollup/plugin-commonjs": "^26.0.1", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-replace": "^5.0.7", - "@types/chrome": "^0.0.278", + "@rollup/plugin-commonjs": "^28.0.1", + "@rollup/plugin-node-resolve": "^15.3.0", + "@rollup/plugin-replace": "^6.0.1", + "@types/chrome": "^0.0.279", "@types/jasmine": "^5.1.4", - "@types/node": "^22.7.7", + "@types/node": "^22.8.6", "@typescript-eslint/eslint-plugin": "^6.9.1", - "config-builder": "git+ssh://git@github.com/duckduckgo/privacy-configuration.git#207bcafcd8d67d0530569f7efcf84463194b999b", + "config-builder": "github:duckduckgo/privacy-configuration#1729260354597", "fast-check": "^3.22.0", - "immutable-json-patch": "^5.1.3", + "immutable-json-patch": "^6.0.1", "jasmine": "^5.4.0", "minimist": "^1.2.8", "parse-address": "^1.1.2", - "rollup": "^3.29.5", - "rollup-plugin-import-css": "^3.5.2", - "rollup-plugin-svg-import": "^2.1.0", + "rollup": "^4.24.3", + "rollup-plugin-import-css": "^3.5.6", + "rollup-plugin-svg-import": "^3.0.0", "seedrandom": "^3.0.5", "sjcl": "^1.0.8" + }, + "dependencies": { + "@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "peer": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "peer": true, + "requires": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + } + }, + "eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "dev": true, + "peer": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "peer": true, + "requires": { + "is-glob": "^4.0.3" + } + } } }, "internal-slot": { @@ -10054,15 +11396,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "requires": { - "builtin-modules": "^3.3.0" - } - }, "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -10148,7 +11481,8 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true + "dev": true, + "peer": true }, "is-plain-obj": { "version": "1.1.0", @@ -10954,19 +12288,19 @@ "dev": true }, "playwright": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.40.1.tgz", - "integrity": "sha512-2eHI7IioIpQ0bS1Ovg/HszsN/XKNwEG1kbzSDDmADpclKc7CyqkHw7Mg2JCz/bbCxg25QUPcjksoMW7JcIFQmw==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", "dev": true, "requires": { "fsevents": "2.3.2", - "playwright-core": "1.40.1" + "playwright-core": "1.48.2" } }, "playwright-core": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.40.1.tgz", - "integrity": "sha512-+hkOycxPiV534c4HhpfX6yrlawqVUzITRKwHAmYfmsVreltEl6fAZJ3DPfLMOODw0H3s1Itd6MDCWmP1fl/QvQ==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", "dev": true }, "portfinder": { @@ -11166,12 +12500,6 @@ "set-function-name": "^2.0.2" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -11201,6 +12529,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -11217,27 +12551,46 @@ } }, "rollup": { - "version": "3.29.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", - "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", - "dev": true, - "requires": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", + "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.24.3", + "@rollup/rollup-android-arm64": "4.24.3", + "@rollup/rollup-darwin-arm64": "4.24.3", + "@rollup/rollup-darwin-x64": "4.24.3", + "@rollup/rollup-freebsd-arm64": "4.24.3", + "@rollup/rollup-freebsd-x64": "4.24.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", + "@rollup/rollup-linux-arm-musleabihf": "4.24.3", + "@rollup/rollup-linux-arm64-gnu": "4.24.3", + "@rollup/rollup-linux-arm64-musl": "4.24.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", + "@rollup/rollup-linux-riscv64-gnu": "4.24.3", + "@rollup/rollup-linux-s390x-gnu": "4.24.3", + "@rollup/rollup-linux-x64-gnu": "4.24.3", + "@rollup/rollup-linux-x64-musl": "4.24.3", + "@rollup/rollup-win32-arm64-msvc": "4.24.3", + "@rollup/rollup-win32-ia32-msvc": "4.24.3", + "@rollup/rollup-win32-x64-msvc": "4.24.3", + "@types/estree": "1.0.6", "fsevents": "~2.3.2" } }, "rollup-plugin-import-css": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-import-css/-/rollup-plugin-import-css-3.5.2.tgz", - "integrity": "sha512-zAkG73dG0n03xtHkqnmcvo/bjlmO9wA/YFnMHWz8XPycYsOZNmnovbTnxRP6tj7vUskdgoCW4f+zNBXqHqc5EA==", + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/rollup-plugin-import-css/-/rollup-plugin-import-css-3.5.6.tgz", + "integrity": "sha512-a+EVWlL8hGRrrAAa5Ds791sIxBxson5DCYeXAwWqYm+ITziUpmiFTR5czS7EEkuw1k7IZj1lGnHnuCVo0tmxzg==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.4" } }, "rollup-plugin-svg-import": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-svg-import/-/rollup-plugin-svg-import-2.1.0.tgz", - "integrity": "sha512-uHTYG/shURfBvX2wieST5898uvKBnhE6XuhFDGlNzr0HSMNGEapo/oT9u7Xogr4bgpAvhL1hsdZGdWXA1X1N1g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svg-import/-/rollup-plugin-svg-import-3.0.0.tgz", + "integrity": "sha512-5fUESTM5hdqJojrwO53JQUO7NespLNx4iLeMsToQfuaGGqGT5sz85Ns5gCDNxLO6yBPbn7p0A/6YA+Rq3clg4Q==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1" @@ -11293,13 +12646,10 @@ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" }, "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true }, "set-function-length": { "version": "1.2.2", @@ -11444,10 +12794,9 @@ "requires": { "@duckduckgo/messaging": "*", "@formkit/auto-animate": "^0.8.2", - "@playwright/test": "^1.40.1", - "@rive-app/canvas-single": "^2.21.7", - "classnames": "^2.3.2", - "esbuild": "^0.19.5", + "@rive-app/canvas-single": "^2.23.3", + "classnames": "^2.5.1", + "esbuild": "^0.24.0", "fast-check": "^3.22.0", "http-server": "^14.1.1", "preact": "^10.24.3", @@ -11725,6 +13074,12 @@ } } }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -11774,9 +13129,9 @@ "dev": true }, "ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "requires": {} }, @@ -11811,7 +13166,8 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "dev": true, + "peer": true }, "typed-array-buffer": { "version": "1.0.2", @@ -11912,6 +13268,17 @@ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true }, + "typescript-eslint": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.12.2.tgz", + "integrity": "sha512-UbuVUWSrHVR03q9CWx+JDHeO6B/Hr9p4U5lRH++5tq/EbFq1faYZe50ZSBePptgfIKLEti0aPQ3hFgnPVcd8ZQ==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "8.12.2", + "@typescript-eslint/parser": "8.12.2", + "@typescript-eslint/utils": "8.12.2" + } + }, "uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", diff --git a/package.json b/package.json index dbda1888f..e8d99d22a 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "docs-watch": "typedoc --watch", "tsc": "tsc", "tsc-watch": "tsc --watch", - "lint": "eslint . && npm run tsc", + "lint": "eslint . && npm run tsc && npm run lint-no-output-globals", + "lint-no-output-globals": "eslint --no-inline-config --config build-output.eslint.config.js Sources/ContentScopeScripts/dist/contentScope.js", "postlint": "npm run lint --workspaces --if-present", "lint-fix": "eslint . --fix && npm run tsc", "stylelint": "npx stylelint \"**/*.css\"", @@ -31,19 +32,17 @@ "messaging", "types-generator" ], - "dependencies": {}, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^6.9.1", - "eslint": "^8.57.1", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^6.1.1", + "@duckduckgo/eslint-config": "github:duckduckgo/eslint-config#51dc868a4342379d6aec1d0f4214156e7046d5f6", + "@types/eslint__js": "^8.42.3", + "eslint": "^9.13.0", + "minimist": "^1.2.8", "stylelint": "^15.11.0", "stylelint-config-standard": "^34.0.0", "stylelint-csstree-validator": "^3.0.0", - "minimist": "^1.2.8", "typedoc": "^0.26.10", - "typescript": "^5.6.3" + "typescript": "^5.6.3", + "typescript-eslint": "^8.12.2", + "@playwright/test": "^1.48.2" } } diff --git a/special-pages/index.mjs b/special-pages/index.mjs index 247cdf4d2..a89d0dda7 100644 --- a/special-pages/index.mjs +++ b/special-pages/index.mjs @@ -20,40 +20,40 @@ const DEBUG = Boolean(args.debug); export const support = { /** @type {Partial>} */ duckplayer: { - 'integration': ['copy', 'build-js'], - 'windows': ['copy', 'build-js'], - 'apple': ['copy', 'build-js', 'inline-html'], - 'android': ['copy', 'build-js'] + integration: ['copy', 'build-js'], + windows: ['copy', 'build-js'], + apple: ['copy', 'build-js', 'inline-html'], + android: ['copy', 'build-js'] }, /** @type {Partial>} */ errorpage: { - 'integration': ['copy'], - 'apple': ['copy', 'inline-html'], + integration: ['copy'], + apple: ['copy', 'inline-html'], }, /** @type {Partial>} */ onboarding: { - 'integration': ['copy', 'build-js'], - 'windows': ['copy', 'build-js'], - 'apple': ['copy', 'build-js'], + integration: ['copy', 'build-js'], + windows: ['copy', 'build-js'], + apple: ['copy', 'build-js'], }, /** @type {Partial>} */ example: { - 'integration': ['copy', 'build-js'] + integration: ['copy', 'build-js'] }, /** @type {Partial>} */ 'release-notes': { - 'integration': ['copy', 'build-js'], - 'apple': ['copy', 'build-js'], + integration: ['copy', 'build-js'], + apple: ['copy', 'build-js'], }, /** @type {Partial>} */ 'special-error': { - 'integration': ['copy', 'build-js'], - 'apple': ['copy', 'build-js', 'inline-html'], + integration: ['copy', 'build-js'], + apple: ['copy', 'build-js', 'inline-html'], }, /** @type {Partial>} */ 'new-tab': { - 'integration': ['copy', 'build-js'], - 'windows': ['copy', 'build-js'], + integration: ['copy', 'build-js'], + windows: ['copy', 'build-js'], }, } @@ -81,7 +81,7 @@ for (const [pageName, injectNames] of Object.entries(support)) { const pageOutputDirectory = join(buildDir, 'pages', pageName) - for (let job of jobs) { + for (const job of jobs) { if (job === 'copy') { copyJobs.push({ src: pageSrc, diff --git a/special-pages/messages/new-tab/contextMenu.notify.json b/special-pages/messages/new-tab/contextMenu.notify.json new file mode 100644 index 000000000..43e576967 --- /dev/null +++ b/special-pages/messages/new-tab/contextMenu.notify.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": ["visibilityMenuItems"], + "properties": { + "visibilityMenuItems": { + "type": "array", + "items": { + "type": "object", + "title": "Visibility Menu Item", + "required": ["id", "title"], + "properties": { + "id": { + "type": "string" + }, + "title": { + "description": "Translated name of the section", + "type": "string" + } + } + } + } + } +} diff --git a/special-pages/messages/new-tab/examples/widgets.js b/special-pages/messages/new-tab/examples/widgets.js index 569583b01..2ec7a1daa 100644 --- a/special-pages/messages/new-tab/examples/widgets.js +++ b/special-pages/messages/new-tab/examples/widgets.js @@ -34,16 +34,19 @@ const widgetConfig = { */ const initialSetupResponse = { widgets: [ - { "id": "weatherWidget" }, - { "id": "newsWidget" } + { "id": "updateNotification" }, + { "id": "rmf" }, + { "id": "favorites" }, + { "id": "privacyStats" } ], widgetConfigs: [ - { "id": "weatherWidget", "visibility": "visible" }, - { "id": "newsWidget", "visibility": "visible" } + { "id": "favorites", "visibility": "visible" }, + { "id": "privacyStats", "visibility": "visible" } ], env: 'production', locale: 'en', - platform: {name: 'windows'} + platform: { name: 'windows' }, + updateNotification: { content: null } } export {} diff --git a/special-pages/messages/new-tab/initialSetup.response.json b/special-pages/messages/new-tab/initialSetup.response.json index c465c9e43..2bb750405 100644 --- a/special-pages/messages/new-tab/initialSetup.response.json +++ b/special-pages/messages/new-tab/initialSetup.response.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", - "required": ["widgets", "widgetConfigs", "locale", "env", "platform"], + "required": ["widgets", "widgetConfigs", "locale", "env", "platform", "updateNotification"], "properties": { "widgets": { "$ref": "./types/widget-list.json" @@ -25,6 +25,16 @@ "enum": ["macos", "windows", "android", "ios", "integration"] } } + }, + "updateNotification": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "types/update-notification.json" + } + ] } } } diff --git a/special-pages/messages/new-tab/types/update-notification.json b/special-pages/messages/new-tab/types/update-notification.json new file mode 100644 index 000000000..6ebfae833 --- /dev/null +++ b/special-pages/messages/new-tab/types/update-notification.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "title": "Update Notification Data", + "required": ["content"], + "properties": { + "content": { + "oneOf": [ + { + "type": "null" + }, + { + "title": "Update Notification", + "required": ["version", "notes"], + "properties": { + "version": { + "type": "string" + }, + "notes": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + ] + } + } +} diff --git a/special-pages/messages/new-tab/updateNotification_dismiss.notify.json b/special-pages/messages/new-tab/updateNotification_dismiss.notify.json new file mode 100644 index 000000000..0af74a319 --- /dev/null +++ b/special-pages/messages/new-tab/updateNotification_dismiss.notify.json @@ -0,0 +1,3 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#" +} diff --git a/special-pages/messages/new-tab/updateNotification_onDataUpdate.subscribe.json b/special-pages/messages/new-tab/updateNotification_onDataUpdate.subscribe.json new file mode 100644 index 000000000..79940a08c --- /dev/null +++ b/special-pages/messages/new-tab/updateNotification_onDataUpdate.subscribe.json @@ -0,0 +1,8 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "allOf": [ + { + "$ref": "types/update-notification.json" + } + ] +} diff --git a/special-pages/package.json b/special-pages/package.json index be52188c1..14ac502ea 100644 --- a/special-pages/package.json +++ b/special-pages/package.json @@ -25,16 +25,15 @@ "license": "ISC", "devDependencies": { "@duckduckgo/messaging": "*", - "esbuild": "^0.19.5", - "@playwright/test": "^1.40.1", + "esbuild": "^0.24.0", "http-server": "^14.1.1", "web-resource-inliner": "^6.0.1", "fast-check": "^3.22.0" }, "dependencies": { "preact": "^10.24.3", - "classnames": "^2.3.2", + "classnames": "^2.5.1", "@formkit/auto-animate": "^0.8.2", - "@rive-app/canvas-single": "^2.21.7" + "@rive-app/canvas-single": "^2.23.3" } } diff --git a/special-pages/pages/duckplayer/app/features/iframe.js b/special-pages/pages/duckplayer/app/features/iframe.js index bae6b85af..0f6744076 100644 --- a/special-pages/pages/duckplayer/app/features/iframe.js +++ b/special-pages/pages/duckplayer/app/features/iframe.js @@ -14,7 +14,7 @@ export class IframeFeature { * @param {HTMLIFrameElement} iframe * @returns {(() => void) | null} */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + iframeDidLoad (iframe) { return () => { console.log('teardown') diff --git a/special-pages/pages/duckplayer/app/features/title-capture.js b/special-pages/pages/duckplayer/app/features/title-capture.js index 1e6a0fded..6a0c8bbdf 100644 --- a/special-pages/pages/duckplayer/app/features/title-capture.js +++ b/special-pages/pages/duckplayer/app/features/title-capture.js @@ -28,7 +28,7 @@ export class TitleCapture { } if (doc.title) { - // eslint-disable-next-line n/no-callback-literal + setter(doc.title) } if (win && doc) { diff --git a/special-pages/pages/new-tab/app/components/App.module.css b/special-pages/pages/new-tab/app/components/App.module.css index 76fb547cf..82acbcd45 100644 --- a/special-pages/pages/new-tab/app/components/App.module.css +++ b/special-pages/pages/new-tab/app/components/App.module.css @@ -8,15 +8,16 @@ body { font-size: var(--body-font-size); font-weight: var(--body-font-weight); line-height: var(--body-line-height); - padding-left: var(--sp-6); - padding-right: var(--sp-6); } .layout { padding-top: var(--sp-16); padding-bottom: var(--sp-16); - max-width: calc(504 * var(--px-in-rem)); margin-left: auto; margin-right: auto; } +:global(.layout-centered) { + margin-inline: auto; + max-width: calc(504 * var(--px-in-rem)); +} diff --git a/special-pages/pages/new-tab/app/components/Icons.js b/special-pages/pages/new-tab/app/components/Icons.js index 62b60e003..f6ff3266b 100644 --- a/special-pages/pages/new-tab/app/components/Icons.js +++ b/special-pages/pages/new-tab/app/components/Icons.js @@ -49,3 +49,13 @@ export function Shield () { ) } + +export function Cross () { + return ( + + + + ) +} diff --git a/special-pages/pages/new-tab/app/customizer/Customizer.js b/special-pages/pages/new-tab/app/customizer/Customizer.js index 74e5d8aa9..2314fa117 100644 --- a/special-pages/pages/new-tab/app/customizer/Customizer.js +++ b/special-pages/pages/new-tab/app/customizer/Customizer.js @@ -4,9 +4,10 @@ import styles from './Customizer.module.css' import { VisibilityMenu } from './VisibilityMenu.js' import { CustomizeIcon } from '../components/Icons.js' import cn from 'classnames' +import { useMessaging } from '../types.js' /** - * @import { Widgets, WidgetConfigItem, WidgetVisibility } from '../../../../types/new-tab.js' + * @import { Widgets, WidgetConfigItem, WidgetVisibility, VisibilityMenuItem } from '../../../../types/new-tab.js' */ /** @@ -16,6 +17,8 @@ export function Customizer () { const { setIsOpen, buttonRef, dropdownRef, isOpen } = useDropdown() const [rowData, setRowData] = useState(/** @type {VisibilityRowData[]} */([])) + useContextMenu() + /** * Dispatch an event every time the customizer is opened - this * allows widgets to register themselves and provide titles/icons etc. @@ -63,7 +66,7 @@ export function Customizer () { Customizer.OPEN_EVENT = 'ntp-customizer-open' Customizer.UPDATE_EVENT = 'ntp-customizer-update' -function getItems () { +export function getItems () { /** @type {VisibilityRowData[]} */ const next = [] const detail = { @@ -77,6 +80,32 @@ function getItems () { return next } +/** + * Forward the contextmenu event + */ +export function useContextMenu () { + const messaging = useMessaging() + useEffect(() => { + function handler (e) { + e.preventDefault() + e.stopImmediatePropagation() + const items = getItems() + /** @type {VisibilityMenuItem[]} */ + const simplified = items.map(item => { + return { + id: item.id, + title: item.title + } + }) + messaging.contextMenu({ visibilityMenuItems: simplified }) + } + document.body.addEventListener('contextmenu', handler) + return () => { + document.body.removeEventListener('contextmenu', handler) + } + }, [messaging]) +} + /** * @param {object} props * @param {string} [props.menuId] diff --git a/special-pages/pages/new-tab/app/docs.js b/special-pages/pages/new-tab/app/docs.js index bbb566d2b..3b278c671 100644 --- a/special-pages/pages/new-tab/app/docs.js +++ b/special-pages/pages/new-tab/app/docs.js @@ -1,11 +1,9 @@ /** - * - * - {@link WidgetConfigService} - * - {@link PrivacyStatsService} - * - {@link RMFService} + * @document ./new-tab.md + * @document ./widget-list/widget-config.md + * @document ./remote-messaging-framework/rmf.md + * @document ./update-notification/update-notification.md + * @document ./privacy-stats/privacy-stats.md * * @module NewTab Services */ -export * from './privacy-stats/privacy-stats.service.js' -export * from './widget-list/widget-config.service.js' -export * from './remote-messaging-framework/rmf.service.js' diff --git a/special-pages/pages/new-tab/app/favorites/Favorites.js b/special-pages/pages/new-tab/app/favorites/Favorites.js index 33062d5fa..1a4dc55cf 100644 --- a/special-pages/pages/new-tab/app/favorites/Favorites.js +++ b/special-pages/pages/new-tab/app/favorites/Favorites.js @@ -15,6 +15,8 @@ export function FavoritesCustomized () { return null } return ( -

Favourites here... (id: {id})

+
+

Favourites here... (id: {id})

+
) } diff --git a/special-pages/pages/new-tab/app/index.js b/special-pages/pages/new-tab/app/index.js index 3f04e3a7b..93267c80f 100644 --- a/special-pages/pages/new-tab/app/index.js +++ b/special-pages/pages/new-tab/app/index.js @@ -4,7 +4,7 @@ import { EnvironmentProvider, UpdateEnvironment } from '../../../shared/componen import { Fallback } from '../../../shared/components/Fallback/Fallback.jsx' import { ErrorBoundary } from '../../../shared/components/ErrorBoundary.js' import { SettingsProvider } from './settings.provider.js' -import { MessagingContext } from './types' +import { InitialSetupContext, MessagingContext } from './types' import { TranslationProvider } from '../../../shared/components/TranslationsProvider.js' import { WidgetConfigService } from './widget-list/widget-config.service.js' import enStrings from '../src/locales/en/newtab.json' @@ -91,13 +91,15 @@ export async function init (messaging, baseEnvironment) { }> - - - - - - - + + + + + + + + + diff --git a/special-pages/pages/new-tab/app/new-tab.md b/special-pages/pages/new-tab/app/new-tab.md new file mode 100644 index 000000000..e49a8a9b7 --- /dev/null +++ b/special-pages/pages/new-tab/app/new-tab.md @@ -0,0 +1,40 @@ +--- +title: New Tab Page +--- + +## Requests + +- {@link "NewTab Messages".InitialSetupRequest `initialSetup`} + - Returns {@link "NewTab Messages".InitialSetupResponse} + - See the `initialSetupResponse` section of [example of initial data](../../../messages/new-tab/examples/widgets.js) + +## Notifications + +- {@link "NewTab Messages".ContextMenuNotification `contextMenu`} + - Sent when the user right-clicks in the page + - Note: Other widgets might prevent this (and send their own, eg: favorites) + - Sends: {@link "NewTab Messages".ContextMenuNotify} + - Example: + +```json +{ + "visibilityMenuItems": [ + { + "id": "favorites", + "title": "Favorites" + }, + { + "id": "privacyStats", + "title": "Privacy Stats" + } + ] +} +``` + +- {@link "NewTab Messages".ReportInitExceptionNotification `reportInitException`} + - Sent when the application fails to initialize (for example, a JavaScript exception prevented it) + - Sends: `{ message: string }` - see {@link "NewTab Messages".ReportInitExceptionNotify} + +- {@link "NewTab Messages".ReportPageExceptionNotification `reportPageException`} + - Sent when the application failed after initialization (for example, a JavaScript exception prevented it) + - Sends: `{ message: string }` - see {@link "NewTab Messages".ReportPageExceptionNotify} diff --git a/special-pages/pages/new-tab/app/privacy-stats/PrivacyStats.js b/special-pages/pages/new-tab/app/privacy-stats/PrivacyStats.js index 3e0a899a6..cdbd6f588 100644 --- a/special-pages/pages/new-tab/app/privacy-stats/PrivacyStats.js +++ b/special-pages/pages/new-tab/app/privacy-stats/PrivacyStats.js @@ -1,4 +1,5 @@ import { h } from 'preact' +import cn from 'classnames' import styles from './PrivacyStats.module.css' import { useTypedTranslation } from '../types.js' import { useContext, useState, useId, useCallback } from 'preact/hooks' @@ -60,8 +61,9 @@ function PrivacyStatsConfigured ({ parentRef, expansion, data, toggle }) { // see: https://www.w3.org/WAI/ARIA/apg/patterns/accordion/examples/accordion/ const WIDGET_ID = useId() const TOGGLE_ID = useId() + return ( -
+
} [props.listAttrs] * @param {TrackerCompany[]} props.trackerCompanies */ +// eslint-disable-next-line no-redeclare export function Body ({ trackerCompanies, listAttrs = {} }) { const max = trackerCompanies[0]?.count ?? 0 const [formatter] = useState(() => new Intl.NumberFormat()) diff --git a/special-pages/pages/new-tab/app/privacy-stats/PrivacyStats.module.css b/special-pages/pages/new-tab/app/privacy-stats/PrivacyStats.module.css index 677f417f3..a54db52a4 100644 --- a/special-pages/pages/new-tab/app/privacy-stats/PrivacyStats.module.css +++ b/special-pages/pages/new-tab/app/privacy-stats/PrivacyStats.module.css @@ -7,6 +7,7 @@ align-items: start; grid-template-columns: auto; grid-row-gap: 18px; + width: 100%; @media screen and (prefers-color-scheme: dark) { border-color: var(--color-white-at-9); diff --git a/special-pages/pages/new-tab/app/privacy-stats/privacy-stats.md b/special-pages/pages/new-tab/app/privacy-stats/privacy-stats.md new file mode 100644 index 000000000..fc1093436 --- /dev/null +++ b/special-pages/pages/new-tab/app/privacy-stats/privacy-stats.md @@ -0,0 +1,35 @@ +--- +title: Privacy Stats +--- + +## Requests: +- {@link "NewTab Messages".StatsGetDataRequest `stats_getData`} + - Used to fetch the initial data (during the first render) + - returns {@link "NewTab Messages".PrivacyStatsData} + +- {@link "NewTab Messages".StatsGetDataRequest `stats_getConfig`} + - Used to fetch the initial config data (eg: expanded vs collapsed) + - returns {@link "NewTab Messages".StatsConfig} + +## Subscriptions: +- {@link "NewTab Messages".StatsOnDataUpdateSubscription `stats_onDataUpdate`}. + - The tracker/company data used in the feed. + - returns {@link "NewTab Messages".PrivacyStatsData} +- {@link "NewTab Messages".StatsOnDataUpdateSubscription `stats_onConfigUpdate`}. + - The widget config + - returns {@link "NewTab Messages".StatsConfig} + +## Notifications: +- {@link "NewTab Messages".StatsSetConfigNotification `stats_setConfig`} + - Sent when the user toggles the expansion of the stats + - sends {@link "NewTab Messages".StatsConfig} + - example payload: + ```json + { + "expansion": "collapsed" + } + ``` + +## Examples: +The following examples show the data types in JSON format: +[messages/new-tab/examples/stats.js](../../../../messages/new-tab/examples/stats.js) diff --git a/special-pages/pages/new-tab/app/privacy-stats/privacy-stats.service.js b/special-pages/pages/new-tab/app/privacy-stats/privacy-stats.service.js index e9ab6f20e..cce8ced8c 100644 --- a/special-pages/pages/new-tab/app/privacy-stats/privacy-stats.service.js +++ b/special-pages/pages/new-tab/app/privacy-stats/privacy-stats.service.js @@ -4,39 +4,6 @@ */ import { Service } from '../service.js' -/** - * ## Requests: - * - {@link "NewTab Messages".StatsGetDataRequest `stats_getData`} - * - Used to fetch the initial data (during the first render) - * - returns {@link "NewTab Messages".PrivacyStatsData} - * - * - {@link "NewTab Messages".StatsGetDataRequest `stats_getConfig`} - * - Used to fetch the initial config data (eg: expanded vs collapsed) - * - returns {@link "NewTab Messages".StatsConfig} - * - * ## Subscriptions: - * - {@link "NewTab Messages".StatsOnDataUpdateSubscription `stats_onDataUpdate`}. - * - The tracker/company data used in the feed. - * - returns {@link "NewTab Messages".PrivacyStatsData} - * - {@link "NewTab Messages".StatsOnDataUpdateSubscription `stats_onConfigUpdate`}. - * - The widget config - * - returns {@link "NewTab Messages".StatsConfig} - * - * ## Notifications: - * - {@link "NewTab Messages".StatsSetConfigNotification `stats_setConfig`} - * - Sent when the user toggles the expansion of the stats - * - sends {@link "NewTab Messages".StatsConfig} - * - example payload: - * ```json - * { - * "expansion": "collapsed" - * } - * ``` - * - * ## Examples: - * The following examples show the data types in JSON format: - * [messages/new-tab/examples/stats.js](../../../../messages/new-tab/examples/stats.js) - */ export class PrivacyStatsService { /** * @param {import("../../src/js/index.js").NewTabPage} ntp - The internal data feed, expected to have a `subscribe` method. diff --git a/special-pages/pages/new-tab/app/remote-messaging-framework/RemoteMessagingFramework.js b/special-pages/pages/new-tab/app/remote-messaging-framework/RemoteMessagingFramework.js index e86226950..a785dcd15 100644 --- a/special-pages/pages/new-tab/app/remote-messaging-framework/RemoteMessagingFramework.js +++ b/special-pages/pages/new-tab/app/remote-messaging-framework/RemoteMessagingFramework.js @@ -3,6 +3,7 @@ import cn from 'classnames' import styles from './RemoteMessagingFramework.module.css' import { useContext } from 'preact/hooks' import { RMFContext } from './RMFProvider.js' +import { Cross } from '../components/Icons.js' /** * @import { RMFMessage } from "../../../../types/new-tab" @@ -16,7 +17,7 @@ import { RMFContext } from './RMFProvider.js' export function RemoteMessagingFramework ({ message, primaryAction, secondaryAction, dismiss }) { const { id, messageType, titleText, descriptionText } = message return ( -
+
{messageType !== 'small' && message.icon && ( @@ -42,9 +43,8 @@ export function RemoteMessagingFramework ({ message, primaryAction, secondaryAct
)} + +
) diff --git a/special-pages/pages/new-tab/app/remote-messaging-framework/RemoteMessagingFramework.module.css b/special-pages/pages/new-tab/app/remote-messaging-framework/RemoteMessagingFramework.module.css index 087b9b0a9..850fbb6dd 100644 --- a/special-pages/pages/new-tab/app/remote-messaging-framework/RemoteMessagingFramework.module.css +++ b/special-pages/pages/new-tab/app/remote-messaging-framework/RemoteMessagingFramework.module.css @@ -9,7 +9,7 @@ align-items: flex-start; font-family: system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto; color: var(--color-black); - + width: 100%; &.icon { padding-left: var(--sp-2); @@ -192,4 +192,4 @@ color: var(--color-white-at-84); } } -} \ No newline at end of file +} diff --git a/special-pages/pages/new-tab/app/remote-messaging-framework/rmf.service.md b/special-pages/pages/new-tab/app/remote-messaging-framework/rmf.md similarity index 98% rename from special-pages/pages/new-tab/app/remote-messaging-framework/rmf.service.md rename to special-pages/pages/new-tab/app/remote-messaging-framework/rmf.md index eac5f2951..7b3176a71 100644 --- a/special-pages/pages/new-tab/app/remote-messaging-framework/rmf.service.md +++ b/special-pages/pages/new-tab/app/remote-messaging-framework/rmf.md @@ -44,4 +44,4 @@ title: Remote Messaging Framework ## Examples: The following examples show the data types in JSON format: -[messages/new-tab/examples/stats.js](../../../../messages/new-tab/examples/rmf.js) \ No newline at end of file +[messages/new-tab/examples/stats.js](../../../../messages/new-tab/examples/rmf.js) diff --git a/special-pages/pages/new-tab/app/remote-messaging-framework/rmf.service.js b/special-pages/pages/new-tab/app/remote-messaging-framework/rmf.service.js index fd1af55eb..6fb1f9a34 100644 --- a/special-pages/pages/new-tab/app/remote-messaging-framework/rmf.service.js +++ b/special-pages/pages/new-tab/app/remote-messaging-framework/rmf.service.js @@ -3,10 +3,6 @@ */ import { Service } from '../service.js' -/** - * @document ./rmf.service.md - */ - export class RMFService { /** * @param {import("../../src/js/index.js").NewTabPage} ntp - The internal data feed, expected to have a `subscribe` method. diff --git a/special-pages/pages/new-tab/app/types.js b/special-pages/pages/new-tab/app/types.js index 32d7e6b03..8c83518ea 100644 --- a/special-pages/pages/new-tab/app/types.js +++ b/special-pages/pages/new-tab/app/types.js @@ -4,6 +4,10 @@ import { TranslationContext } from '../../../shared/components/TranslationsProvi import json from '../src/locales/en/newtab.json' import { createContext } from 'preact' +/** + * @import { InitialSetupResponse } from "../../../types/new-tab.js"; + */ + /** * This is a wrapper to only allow keys from the default translation file * @type {() => { t: (key: keyof json, replacements?: Record) => string }} @@ -16,3 +20,6 @@ export function useTypedTranslation () { export const MessagingContext = createContext(/** @type {import("../src/js/index.js").NewTabPage} */({})) export const useMessaging = () => useContext(MessagingContext) + +export const InitialSetupContext = createContext(/** @type {InitialSetupResponse} */({})) +export const useInitialSetupData = () => useContext(InitialSetupContext) diff --git a/special-pages/pages/new-tab/app/update-notification/UpdateNotification.js b/special-pages/pages/new-tab/app/update-notification/UpdateNotification.js new file mode 100644 index 000000000..61899b418 --- /dev/null +++ b/special-pages/pages/new-tab/app/update-notification/UpdateNotification.js @@ -0,0 +1,99 @@ +import { h } from 'preact' +import cn from 'classnames' +import styles from './UpdateNotification.module.css' +import { useContext, useId, useRef } from 'preact/hooks' +import { UpdateNotificationContext } from './UpdateNotificationProvider.js' +import { useTypedTranslation } from '../types.js' +import { Trans } from '../../../../shared/components/TranslationsProvider.js' +import { Cross } from '../components/Icons.js' + +/** + * @param {object} props + * @param {string[]} props.notes + * @param {string} props.version + * @param {() => void} [props.dismiss] + */ + +export function UpdateNotification ({ notes, dismiss, version }) { + const { t } = useTypedTranslation() + + return ( +
+
+ {notes.length > 0 && } + {notes.length === 0 && } +
+
+ +
+
+ ) +} + +export function PulledUp ({ children }) { + return ( +
+ {children} +
+ ) +} + +export function WithNotes ({ notes, version }) { + const id = useId() + const ref = useRef(/** @type {HTMLDetailsElement|null} */(null)) + const { t } = useTypedTranslation() + const inlineLink = { + e.preventDefault() + if (!ref.current) return + ref.current.open = !ref.current.open + } + } + }} + /> + return ( +
+ {t('updateNotification_updated_version', { version })} {inlineLink} +
+
    + {notes.map((note, index) => { + return
  • {note}
  • + })} +
+
+
+ ) +} + +export function WithoutNotes ({ version }) { + const { t } = useTypedTranslation() + return ( +

{t('updateNotification_updated_version', { version })}

+ ) +} + +export function UpdateNotificationConsumer () { + const { state, dismiss } = useContext(UpdateNotificationContext) + + // `state.data.content` can be empty - meaning there's no message to display! + if (state.status === 'ready' && state.data.content) { + return ( + + + + ) + } + return null +} diff --git a/special-pages/pages/new-tab/app/update-notification/UpdateNotification.module.css b/special-pages/pages/new-tab/app/update-notification/UpdateNotification.module.css new file mode 100644 index 000000000..8c54785df --- /dev/null +++ b/special-pages/pages/new-tab/app/update-notification/UpdateNotification.module.css @@ -0,0 +1,126 @@ +.pulled { + margin-top: -40px; +} +.root { + border-bottom: 1px solid var(--ntp-surface-border-color); + position: relative; + min-height: var(--sp-10); + + &:hover { + .dismiss { + opacity: 1; + } + } + &:focus-within { + .dismiss { + opacity: 1; + } + } +} +.body { + position: relative; + text-align: center; +} + +.inlineLink { + text-decoration: none; + &:focus-visible { + text-decoration: underline; + } + &:focus { + outline: none + } + &:hover { + text-decoration: underline; + } + @media screen and (prefers-color-scheme: dark) { + color: white; + text-decoration: underline; + + &:hover { + text-decoration: none; + } + &:focus-visible { + outline: 1px dotted var(--ntp-focus-outline-color); + border-radius: 4px; + text-decoration: none; + } + } +} + +.summary { + list-style: none; +} + +.summary::-webkit-details-marker { + display: none; +} + +.dismiss { + opacity: 0; + transition: all .3s; + position: absolute; + top: -2px; + right: var(--sp-2); +} + +.detailsContent { + padding-inline: var(--sp-2); + padding-block: var(--sp-4); + text-align: left; +} + +.list { + margin-left: var(--sp-20); + li { + list-style: disc + } +} + +.dismissBtn { + height: 24px; + width: 24px; + padding: 0; + background-color: var(--ntp-background-color); + color: var(--color-black-at-60); + border: none; + border-radius: 50%; + position: relative; + cursor: pointer; + transition: background-color .3s; + + svg { + position: absolute; + top: 50%; + left: 50%; + transform: translateY(-50%) translateX(-50%); + } + + &:active { + background-color: var(--color-black-at-18); + color: var(--color-black-at-84); + } + + &:hover { + background-color: var(--color-black-at-9); + } + + &:focus-visible { + outline: 1px dotted var(--ntp-focus-outline-color); + outline-offset: 4px; + } + + @media screen and (prefers-color-scheme: dark) { + color: var(--color-white-at-60); + + &:hover { + background-color: var(--color-white-at-9); + } + + &:active { + background-color: var(--color-white-at-18); + color: var(--color-white-at-84); + } + } +} + diff --git a/special-pages/pages/new-tab/app/update-notification/UpdateNotificationProvider.js b/special-pages/pages/new-tab/app/update-notification/UpdateNotificationProvider.js new file mode 100644 index 000000000..5b1a38ae5 --- /dev/null +++ b/special-pages/pages/new-tab/app/update-notification/UpdateNotificationProvider.js @@ -0,0 +1,98 @@ +import { createContext, h } from 'preact' +import { useCallback, useEffect, useReducer, useRef } from 'preact/hooks' +import { useInitialSetupData, useMessaging } from '../types.js' +import { UpdateNotificationService } from './update-notification.service.js' +import { + reducer, + useDataSubscription +} from '../service.hooks.js' + +/** + * @typedef {import('../../../../types/new-tab.js').UpdateNotificationData} UpdateNotificationData + * @typedef {import('../service.hooks.js').State} State + * @typedef {import('../service.hooks.js').Events} Events + */ + +/** + * These are the values exposed to consumers. + */ +export const UpdateNotificationContext = createContext({ + /** @type {State} */ + state: { status: 'idle', data: null, config: null }, + /** @type {() => void} */ + dismiss: () => { + throw new Error('must implement dismiss') + } +}) + +export const UpdateNotificationDispatchContext = createContext(/** @type {import("preact/hooks").Dispatch} */({})) + +/** + * A data provider that will use `RMFService` to fetch data, subscribe + * to updates and modify state. + * + * @param {Object} props + * @param {import("preact").ComponentChild} props.children + */ +export function UpdateNotificationProvider (props) { + const { updateNotification } = useInitialSetupData() + if (updateNotification === null) { + return null + } + return ( + + {props.children} + + ) +} + +/** + * @param {Object} props + * @param {import("preact").ComponentChild} props.children + * @param {UpdateNotificationData} props.updateNotification + */ +function UpdateNotificationWithInitial ({ updateNotification, children }) { + const initial = /** @type {State} */({ + status: 'ready', + data: updateNotification, + config: undefined + }) + + // const [state, dispatch] = useReducer(withLog('RMFProvider', reducer), initial) + const [state, dispatch] = useReducer(reducer, initial) + + // create an instance of `RMFService` for the lifespan of this component. + const service = useService(updateNotification) + + // subscribe to data updates + useDataSubscription({ dispatch, service }) + + const dismiss = useCallback(() => { + service.current?.dismiss() + }, [service]) + + return ( + + + {children} + + + ) +} + +/** + * @param {UpdateNotificationData} initial + * @return {import("preact").RefObject} + */ +export function useService (initial) { + const service = useRef(/** @type {UpdateNotificationService|null} */(null)) + const ntp = useMessaging() + useEffect(() => { + const stats = new UpdateNotificationService(ntp, initial) + service.current = stats + return () => { + stats.destroy() + } + }, [ntp, initial]) + return service +} diff --git a/special-pages/pages/new-tab/app/update-notification/integration-tests/update-notification.spec.js b/special-pages/pages/new-tab/app/update-notification/integration-tests/update-notification.spec.js new file mode 100644 index 000000000..7bba5f290 --- /dev/null +++ b/special-pages/pages/new-tab/app/update-notification/integration-tests/update-notification.spec.js @@ -0,0 +1,34 @@ +import { test, expect } from '@playwright/test' +import { NewtabPage } from '../../../integration-tests/new-tab.page.js' + +test.describe('newtab update notifications', () => { + test('handles empty notes', async ({ page }, workerInfo) => { + const ntp = NewtabPage.create(page, workerInfo) + await ntp.reducedMotion() + await ntp.openPage({ updateNotification: 'empty' }) + + const calls1 = await ntp.mocks.waitForCallCount({ method: 'initialSetup', count: 1 }) + + expect(calls1.length).toBe(1) + const text = page.getByText('Browser Updated to version 1.65.0.') + await text.waitFor() + await page.getByRole('button', { name: 'Dismiss' }).click() + await ntp.mocks.waitForCallCount({ method: 'updateNotification_dismiss', count: 1 }) + await expect(text).not.toBeVisible() + }) + test('handles populated notes', async ({ page }, workerInfo) => { + const ntp = NewtabPage.create(page, workerInfo) + await ntp.reducedMotion() + await ntp.openPage({ updateNotification: 'populated' }) + + const calls1 = await ntp.mocks.waitForCallCount({ method: 'initialSetup', count: 1 }) + + expect(calls1.length).toBe(1) + + await page.getByText('Browser Updated to version 1.91. See what\'s new in this release.').waitFor() + await page.getByRole('link', { name: 'what\'s new' }).click() + await page.getByText('Bug fixes and improvements').waitFor() + await page.getByRole('button', { name: 'Dismiss' }).click() + await ntp.mocks.waitForCallCount({ method: 'updateNotification_dismiss', count: 1 }) + }) +}) diff --git a/special-pages/pages/new-tab/app/update-notification/mocks/update-notification.data.js b/special-pages/pages/new-tab/app/update-notification/mocks/update-notification.data.js new file mode 100644 index 000000000..710676eac --- /dev/null +++ b/special-pages/pages/new-tab/app/update-notification/mocks/update-notification.data.js @@ -0,0 +1,17 @@ +/** + * @type {Record}>} + */ +export const updateNotificationExamples = { + empty: { + content: { + version: '1.65.0', + notes: [] + } + }, + populated: { + content: { + notes: ['Bug fixes and improvements'], + version: '1.91' + } + } +} diff --git a/special-pages/pages/new-tab/app/update-notification/update-notification.md b/special-pages/pages/new-tab/app/update-notification/update-notification.md new file mode 100644 index 000000000..63e710551 --- /dev/null +++ b/special-pages/pages/new-tab/app/update-notification/update-notification.md @@ -0,0 +1,56 @@ +--- +title: Update Notification +--- + +## Initial Data + +- Add the key `updateNotification` to `initialSetup` +- The data takes the following form: {@link "NewTab Messages".UpdateNotificationData} +- Example from `initialSetup` + +*Signal there are no notes to show* +```json +{ + "...": "...", + "updateNotification": { + "content": null + } +} +``` + +Signal there are notes to show. + +```json +{ + "...": "...", + "updateNotification": { + "content": { + "version": "1.98.0", + "notes": ["Bug fixes and improvements"] + } + } +} +``` + +If your platform does not support Update Notifications, you can set this initial property to `null` + +```json +{ + "...": "...", + "updateNotification": null +} +``` + + +**NOTE**: `updateNotification` and it's field `content` are **required**. Set `content` to `null` to indicate +nothing to show. This mirrors how RMF is designed + +## Subscriptions: +- {@link "NewTab Messages".UpdateNotificationOnDataUpdateSubscription `updateNotification_onDataUpdate`}. + - Sends fresh {@link "NewTab Messages".UpdateNotificationData} whenever needed. + - For example, it might send `{ content: null }` to remove existing notes + - Or, it might send fresh at any point + +## Notifications: +- {@link "NewTab Messages".UpdateNotificationDismissNotification `updateNotification_dismiss`} + - Sent when the user chooses to dismiss the release notes diff --git a/special-pages/pages/new-tab/app/update-notification/update-notification.service.js b/special-pages/pages/new-tab/app/update-notification/update-notification.service.js new file mode 100644 index 000000000..a8730205b --- /dev/null +++ b/special-pages/pages/new-tab/app/update-notification/update-notification.service.js @@ -0,0 +1,49 @@ +/** + * @typedef {import("../../../../types/new-tab.js").UpdateNotificationData} UpdateNotificationData + */ +import { Service } from '../service.js' + +/** + * @document ./update-notification.service.md + */ + +export class UpdateNotificationService { + /** + * @param {import("../../src/js/index.js").NewTabPage} ntp - The internal data feed, expected to have a `subscribe` method. + * @param {UpdateNotificationData} initial + * @internal + */ + constructor (ntp, initial) { + this.ntp = ntp + /** @type {Service} */ + this.dataService = new Service({ + subscribe: (cb) => ntp.messaging.subscribe('updateNotification_onDataUpdate', cb) + }, initial) + } + + /** + * @internal + */ + destroy () { + this.dataService.destroy() + } + + /** + * @param {(evt: {data: UpdateNotificationData, source: 'manual' | 'subscription'}) => void} cb + * @internal + */ + onData (cb) { + return this.dataService.onData(cb) + } + + /** + * @internal + */ + dismiss () { + this.ntp.messaging.notify('updateNotification_dismiss') + // eslint-disable-next-line @typescript-eslint/no-unused-vars + this.dataService.update(_old => { + return { content: null } + }) + } +} diff --git a/special-pages/pages/new-tab/app/widget-list/WidgetList.js b/special-pages/pages/new-tab/app/widget-list/WidgetList.js index 238011abf..58fca0a0e 100644 --- a/special-pages/pages/new-tab/app/widget-list/WidgetList.js +++ b/special-pages/pages/new-tab/app/widget-list/WidgetList.js @@ -10,6 +10,8 @@ import { } from '../customizer/Customizer.js' import { RMFProvider } from '../remote-messaging-framework/RMFProvider.js' import { RMFConsumer } from '../remote-messaging-framework/RemoteMessagingFramework.js' +import { UpdateNotificationProvider } from '../update-notification/UpdateNotificationProvider.js' +import { UpdateNotificationConsumer } from '../update-notification/UpdateNotification.js' const widgetMap = { privacyStats: () => ( @@ -22,6 +24,11 @@ const widgetMap = { + ), + updateNotification: () => ( + + + ) } @@ -41,7 +48,7 @@ export function WidgetList () { ) } - console.warn('missing config for widget: ', widget) + console.warn('missing component for widget id:', widget) return null } return ( diff --git a/special-pages/pages/new-tab/app/widget-list/widget-config.md b/special-pages/pages/new-tab/app/widget-list/widget-config.md new file mode 100644 index 000000000..ed0d19a22 --- /dev/null +++ b/special-pages/pages/new-tab/app/widget-list/widget-config.md @@ -0,0 +1,26 @@ +--- +title: Widget Config +--- + +## InitialSetup: + +- Data for widgets should be provided as part of the {@link "NewTab Messages".InitialSetupResponse `initialSetup`} response. +- The following keys should be added (also see the example below) + - `widgets`: {@link "NewTab Messages".Widgets} + - `widgetConfigs`: {@link "NewTab Messages".WidgetConfigs} + +## Subscriptions: +- {@link "NewTab Messages".WidgetsOnConfigUpdatedSubscription `widgets_onConfigUpdated`} +- returns {@link "NewTab Messages".WidgetConfigs}. + + +## Notifications: +- {@link "NewTab Messages".WidgetsOnConfigUpdatedSubscription `widgets_setConfig`} +- sends {@link "NewTab Messages".WidgetConfigs} + + If the user toggles the visibility of a section in the frontend, then the entire structure is sent to the + native side. + +## Examples: +The following examples show the data types in JSON format: +[messages/new-tab/examples/stats.js](../../../../messages/new-tab/examples/widgets.js) diff --git a/special-pages/pages/new-tab/app/widget-list/widget-config.provider.js b/special-pages/pages/new-tab/app/widget-list/widget-config.provider.js index 7d01df279..66271e524 100644 --- a/special-pages/pages/new-tab/app/widget-list/widget-config.provider.js +++ b/special-pages/pages/new-tab/app/widget-list/widget-config.provider.js @@ -16,7 +16,7 @@ export const WidgetConfigContext = createContext({ widgetConfigItems: [], /** @type {(id:string) => void} */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + toggle: (_id) => { } @@ -68,7 +68,7 @@ const WidgetVisibilityContext = createContext({ visibility: /** @type {WidgetConfigItem['visibility']} */('visible'), id: /** @type {WidgetConfigItem['id']} */(''), /** @type {(id: string) => void} */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + toggle: (_id) => {}, /** @type {number} */ index: -1 diff --git a/special-pages/pages/new-tab/app/widget-list/widget-config.service.js b/special-pages/pages/new-tab/app/widget-list/widget-config.service.js index c52e81b7b..29f97586d 100644 --- a/special-pages/pages/new-tab/app/widget-list/widget-config.service.js +++ b/special-pages/pages/new-tab/app/widget-list/widget-config.service.js @@ -3,30 +3,6 @@ */ import { Service } from '../service.js' -/** - * ## InitialSetup: - * - * - Data for widgets should be provided as part of the {@link "NewTab Messages".InitialSetupResponse `initialSetup`} response. - * - The following keys should be added (also see the example below) - * - `widgets`: {@link "NewTab Messages".Widgets} - * - `widgetConfigs`: {@link "NewTab Messages".WidgetConfigs} - * - * ## Subscriptions: - * - {@link "NewTab Messages".WidgetsOnConfigUpdatedSubscription `widgets_onConfigUpdated`} - * - returns {@link "NewTab Messages".WidgetConfigs}. - * - * - * ## Notifications: - * - {@link "NewTab Messages".WidgetsOnConfigUpdatedSubscription `widgets_setConfig`} - * - sends {@link "NewTab Messages".WidgetConfigs} - * - * If the user toggles the visibility of a section in the frontend, then the entire structure is sent to the - * native side. - * - * ## Examples: - * The following examples show the data types in JSON format: - * [messages/new-tab/examples/stats.js](../../../../messages/new-tab/examples/widgets.js) - */ export class WidgetConfigService { /** * @param {import("../../src/js/index.js").NewTabPage} ntp - The internal data feed diff --git a/special-pages/pages/new-tab/integration-tests/new-tab.page.js b/special-pages/pages/new-tab/integration-tests/new-tab.page.js index b9fc0a374..e6859d6e8 100644 --- a/special-pages/pages/new-tab/integration-tests/new-tab.page.js +++ b/special-pages/pages/new-tab/integration-tests/new-tab.page.js @@ -34,7 +34,6 @@ export class NewtabPage { { id: 'privacyStats' } ], widgetConfigs: [ - { id: 'rmf', visibility: 'visible' }, { id: 'favorites', visibility: 'visible' }, { id: 'privacyStats', visibility: 'visible' } ], @@ -42,7 +41,8 @@ export class NewtabPage { locale: 'en', platform: { name: this.platform.name || 'windows' - } + }, + updateNotification: { content: null } }, stats_getConfig: {}, stats_getData: {}, @@ -61,9 +61,10 @@ export class NewtabPage { * @param {boolean} [params.willThrow] - Optional flag to simulate an exception * @param {number} [params.favoritesCount] - Optional flag to preload a list of favorites * @param {string} [params.rmf] - Optional flag to point to display=components view with certain rmf example visible + * @param {string} [params.updateNotification] - Optional flag to point to display=components view with certain rmf example visible * @param {string} [params.platformName] - Optional parameters for opening the page. */ - async openPage ({ mode = 'debug', platformName, willThrow = false, favoritesCount, rmf } = { }) { + async openPage ({ mode = 'debug', platformName, willThrow = false, favoritesCount, rmf, updateNotification } = { }) { await this.mocks.install() const searchParams = new URLSearchParams({ mode, willThrow: String(willThrow) }) @@ -79,6 +80,10 @@ export class NewtabPage { searchParams.set('platform', platformName) } + if (updateNotification !== undefined) { + searchParams.set('update-notification', updateNotification) + } + await this.page.goto('/new-tab' + '?' + searchParams.toString()) } diff --git a/special-pages/pages/new-tab/integration-tests/new-tab.spec.js b/special-pages/pages/new-tab/integration-tests/new-tab.spec.js index 8ac94ddd3..3b13607f6 100644 --- a/special-pages/pages/new-tab/integration-tests/new-tab.spec.js +++ b/special-pages/pages/new-tab/integration-tests/new-tab.spec.js @@ -62,4 +62,33 @@ test.describe('newtab widgets', () => { } }]) }) + test('context menu', async ({ page }, workerInfo) => { + const ntp = NewtabPage.create(page, workerInfo) + await ntp.reducedMotion() + await ntp.openPage() + + // wait for the menu, as a signal that the JS is ready + await page.getByRole('button', { name: 'Customize' }).waitFor() + + await page.locator('body').click({ button: 'right' }) + + const calls = await ntp.mocks.waitForCallCount({ method: 'contextMenu', count: 1 }) + expect(calls[0].payload).toStrictEqual({ + context: 'specialPages', + featureName: 'newTabPage', + method: 'contextMenu', + params: { + visibilityMenuItems: [ + { + id: 'favorites', + title: 'Favorites' + }, + { + id: 'privacyStats', + title: 'Privacy Stats' + } + ] + } + }) + }) }) diff --git a/special-pages/pages/new-tab/src/js/index.js b/special-pages/pages/new-tab/src/js/index.js index 14cd3632d..e63901a47 100644 --- a/special-pages/pages/new-tab/src/js/index.js +++ b/special-pages/pages/new-tab/src/js/index.js @@ -47,6 +47,14 @@ export class NewTabPage { reportPageException (params) { this.messaging.notify('reportPageException', params) } + + /** + * Sent when a right-click occurs, and wasn't intercepted by another widget + * @param {import('../../../../types/new-tab.js').ContextMenuNotify} params + */ + contextMenu (params) { + this.messaging.notify('contextMenu', params) + } } const baseEnvironment = new Environment() @@ -61,7 +69,7 @@ const messaging = createSpecialPageMessaging({ // only in integration environments if (baseEnvironment.injectName !== 'integration') return null let mock = null - // eslint-disable-next-line no-labels + // eslint-disable-next-line no-labels,no-unused-labels $INTEGRATION: mock = mockTransport() return mock } diff --git a/special-pages/pages/new-tab/src/js/mock-transport.js b/special-pages/pages/new-tab/src/js/mock-transport.js index 369c54000..97fb087de 100644 --- a/special-pages/pages/new-tab/src/js/mock-transport.js +++ b/special-pages/pages/new-tab/src/js/mock-transport.js @@ -2,9 +2,11 @@ import { TestTransportConfig } from '@duckduckgo/messaging' import { stats } from '../../app/privacy-stats/mocks/stats.js' import { rmfDataExamples } from '../../app/remote-messaging-framework/mocks/rmf.data.js' +import { updateNotificationExamples } from '../../app/update-notification/mocks/update-notification.data.js' /** * @typedef {import('../../../../types/new-tab').StatsConfig} StatsConfig + * @typedef {import('../../../../types/new-tab').UpdateNotificationData} UpdateNotificationData * @typedef {import('../../../../types/new-tab.js').NewTabMessages['subscriptions']['subscriptionEvent']} SubscriptionNames */ @@ -159,6 +161,18 @@ export function mockTransport () { } return () => {} } + case 'updateNotification_onDataUpdate': { + const update = url.searchParams.get('update-notification') + const delay = url.searchParams.get('update-notification-delay') + if (update && delay && update in updateNotificationExamples) { + const ms = parseInt(delay, 10) + const timeout = setTimeout(() => { + const message = updateNotificationExamples[update] + cb(message) + }, ms) + return () => clearTimeout(timeout) + } + } } return () => { } }, @@ -200,6 +214,7 @@ export function mockTransport () { } case 'initialSetup': { const widgetsFromStorage = read('widgets') || [ + { id: 'updateNotification' }, { id: 'rmf' }, { id: 'favorites' }, { id: 'privacyStats' } @@ -210,13 +225,25 @@ export function mockTransport () { { id: 'privacyStats', visibility: 'visible' } ] + /** @type {UpdateNotificationData} */ + let updateNotification = { content: null } + const isDelayed = url.searchParams.has('update-notification-delay') + + if (!isDelayed && url.searchParams.get('update-notification') === 'empty') { + updateNotification = updateNotificationExamples.empty + } + if (!isDelayed && url.searchParams.get('update-notification') === 'populated') { + updateNotification = updateNotificationExamples.populated + } + /** @type {import('../../../../types/new-tab.js').InitialSetupResponse} */ const initial = { widgets: widgetsFromStorage, widgetConfigs: widgetConfigFromStorage, platform: { name: 'integration' }, env: 'development', - locale: 'en' + locale: 'en', + updateNotification } return Promise.resolve(initial) diff --git a/special-pages/pages/new-tab/src/locales/en/newtab.json b/special-pages/pages/new-tab/src/locales/en/newtab.json index 4bf7e7910..d0693ddf5 100644 --- a/special-pages/pages/new-tab/src/locales/en/newtab.json +++ b/special-pages/pages/new-tab/src/locales/en/newtab.json @@ -60,5 +60,17 @@ "favorites_menu_title": { "title": "Favorites", "note": "Used as a toggle label in a page customization menu" + }, + "updateNotification_updated_version": { + "title": "Browser Updated to version {version}.", + "note": "Text to indicate which new version was updated. `version` will be formatted like `1.22.0`" + }, + "updateNotification_whats_new": { + "title": "See what's new in this release.", + "note": "The `` tag represents a toggle" + }, + "updateNotification_dismiss_btn": { + "title": "Dismiss", + "note": "Button label text for an action that removes the widget from the screen." } } diff --git a/special-pages/pages/onboarding/app/components/App.js b/special-pages/pages/onboarding/app/components/App.js index a00946fc3..d4b2ae01b 100644 --- a/special-pages/pages/onboarding/app/components/App.js +++ b/special-pages/pages/onboarding/app/components/App.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import { useContext, useRef } from 'preact/hooks' import styles from './App.module.css' diff --git a/special-pages/pages/onboarding/app/components/App2.js b/special-pages/pages/onboarding/app/components/App2.js index f7fbebc5b..db6a8b25a 100644 --- a/special-pages/pages/onboarding/app/components/App2.js +++ b/special-pages/pages/onboarding/app/components/App2.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import { useContext } from 'preact/hooks' import { GlobalContext, GlobalDispatch } from '../global' diff --git a/special-pages/pages/onboarding/app/components/Background.js b/special-pages/pages/onboarding/app/components/Background.js index 14b326c61..4027563e1 100644 --- a/special-pages/pages/onboarding/app/components/Background.js +++ b/special-pages/pages/onboarding/app/components/Background.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import styles from './Background.module.css' import cn from 'classnames' diff --git a/special-pages/pages/onboarding/app/components/ListItem.js b/special-pages/pages/onboarding/app/components/ListItem.js index 8f6f896db..06c18e1e8 100644 --- a/special-pages/pages/onboarding/app/components/ListItem.js +++ b/special-pages/pages/onboarding/app/components/ListItem.js @@ -3,7 +3,7 @@ import cn from 'classnames' import styles from './ListItem.module.css' import { Check } from './Icons' -// eslint-disable-next-line @typescript-eslint/no-unused-vars + export const availableIcons = /** @type {const} */ ([ 'bookmarks.png', 'browsing.png', diff --git a/special-pages/pages/onboarding/app/components/Typed.js b/special-pages/pages/onboarding/app/components/Typed.js index 8ddc2f8c6..7c3d6a9e6 100644 --- a/special-pages/pages/onboarding/app/components/Typed.js +++ b/special-pages/pages/onboarding/app/components/Typed.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import { useState, useEffect, useRef, useContext } from 'preact/hooks' diff --git a/special-pages/pages/onboarding/app/components/v3/Animation.js b/special-pages/pages/onboarding/app/components/v3/Animation.js index 1d98144ad..705f63305 100644 --- a/special-pages/pages/onboarding/app/components/v3/Animation.js +++ b/special-pages/pages/onboarding/app/components/v3/Animation.js @@ -21,6 +21,7 @@ export function SlideIn ({ children, onAnimationEnd }) { const animationEnd = useCallback(() => { setAnimationState('done') + // eslint-disable-next-line @typescript-eslint/no-unused-expressions onAnimationEnd && onAnimationEnd() }, [onAnimationEnd]) diff --git a/special-pages/pages/onboarding/app/components/v3/Background.js b/special-pages/pages/onboarding/app/components/v3/Background.js index 14b326c61..4027563e1 100644 --- a/special-pages/pages/onboarding/app/components/v3/Background.js +++ b/special-pages/pages/onboarding/app/components/v3/Background.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import styles from './Background.module.css' import cn from 'classnames' diff --git a/special-pages/pages/onboarding/app/components/v3/Heading.js b/special-pages/pages/onboarding/app/components/v3/Heading.js index d4392cf70..5ab7aa9e1 100644 --- a/special-pages/pages/onboarding/app/components/v3/Heading.js +++ b/special-pages/pages/onboarding/app/components/v3/Heading.js @@ -18,6 +18,7 @@ import styles from './Heading.module.css' */ export function Heading ({ title, subtitle, speechBubble = false, onTitleComplete, children }) { const onComplete = () => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions onTitleComplete && onTitleComplete() } const HeadingComponent = speechBubble ? SpeechBubble : PlainHeading @@ -55,6 +56,7 @@ function PlainHeading ({ title, subtitle, onComplete, children }) { const [typingDone, setTypingDone] = useState(false) const onTypingComplete = () => { setTypingDone(true) + // eslint-disable-next-line @typescript-eslint/no-unused-expressions onComplete && onComplete() } @@ -141,6 +143,7 @@ function SpeechBubble ({ title, subtitle, onComplete, children }) { const onTypingComplete = () => { setAnimationState('typing-done') + // eslint-disable-next-line @typescript-eslint/no-unused-expressions onComplete && onComplete() } @@ -190,6 +193,7 @@ export function TypedTitle ({ title, paused = true, onComplete }) { setTextIndex(value => (value += 1)) if (textIndex >= title.length - 1) { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions onComplete && onComplete() } } diff --git a/special-pages/pages/onboarding/app/components/v3/SettingsStep.js b/special-pages/pages/onboarding/app/components/v3/SettingsStep.js index 8d4b65a27..fffb27efd 100644 --- a/special-pages/pages/onboarding/app/components/v3/SettingsStep.js +++ b/special-pages/pages/onboarding/app/components/v3/SettingsStep.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import { useGlobalDispatch, useGlobalState } from '../../global' import { useTypedTranslation } from '../../types' diff --git a/special-pages/pages/onboarding/app/pages/CleanBrowsing.js b/special-pages/pages/onboarding/app/pages/CleanBrowsing.js index 17f969999..95591fec7 100644 --- a/special-pages/pages/onboarding/app/pages/CleanBrowsing.js +++ b/special-pages/pages/onboarding/app/pages/CleanBrowsing.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import { ListItem } from '../components/ListItem' import { BounceIn, Check, SlideUp } from '../components/Icons' diff --git a/special-pages/pages/onboarding/app/pages/PrivacyDefault.js b/special-pages/pages/onboarding/app/pages/PrivacyDefault.js index 1f67381dc..b703fc36b 100644 --- a/special-pages/pages/onboarding/app/pages/PrivacyDefault.js +++ b/special-pages/pages/onboarding/app/pages/PrivacyDefault.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import { ListItem } from '../components/ListItem' import { BounceIn, Check, SlideUp } from '../components/Icons' diff --git a/special-pages/pages/onboarding/app/pages/Summary.js b/special-pages/pages/onboarding/app/pages/Summary.js index 0c38000be..d480b0eed 100644 --- a/special-pages/pages/onboarding/app/pages/Summary.js +++ b/special-pages/pages/onboarding/app/pages/Summary.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import { Stack } from '../components/Stack' import { Launch, SlideUp } from '../components/Icons' diff --git a/special-pages/pages/release-notes/app/components/App.js b/special-pages/pages/release-notes/app/components/App.js index 8df343cbb..47c7ccbe4 100644 --- a/special-pages/pages/release-notes/app/components/App.js +++ b/special-pages/pages/release-notes/app/components/App.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { h } from 'preact' import { useEffect, useState } from 'preact/hooks' import { useMessaging } from '../index' diff --git a/special-pages/pages/release-notes/app/components/ReleaseNotes.js b/special-pages/pages/release-notes/app/components/ReleaseNotes.js index 257b5ed62..24114649e 100644 --- a/special-pages/pages/release-notes/app/components/ReleaseNotes.js +++ b/special-pages/pages/release-notes/app/components/ReleaseNotes.js @@ -1,8 +1,9 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import { Fragment, h } from 'preact' import { useMessaging } from '../index' import classNames from 'classnames' import { useTypedTranslation } from '../types' +// eslint-disable-next-line no-redeclare import { Text } from '../../../../shared/components/Text/Text' import { Card } from '../../../../shared/components/Card/Card' import { Button } from '../../../../shared/components/Button/Button' diff --git a/special-pages/pages/release-notes/src/js/index.js b/special-pages/pages/release-notes/src/js/index.js index 64fe7d73c..d0217db7c 100644 --- a/special-pages/pages/release-notes/src/js/index.js +++ b/special-pages/pages/release-notes/src/js/index.js @@ -105,7 +105,7 @@ const messaging = createSpecialPageMessaging({ // only in integration environments if (baseEnvironment.injectName !== 'integration') return null let mock = null - // eslint-disable-next-line no-labels + // eslint-disable-next-line no-labels, no-unused-labels $INTEGRATION: mock = mockTransport() return mock } diff --git a/special-pages/pages/release-notes/src/js/mock-transport.js b/special-pages/pages/release-notes/src/js/mock-transport.js index 4daa57d58..04581cc09 100644 --- a/special-pages/pages/release-notes/src/js/mock-transport.js +++ b/special-pages/pages/release-notes/src/js/mock-transport.js @@ -25,7 +25,7 @@ export function mockTransport () { } return new TestTransportConfig({ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + notify (_msg) { }, request (_msg) { diff --git a/special-pages/playwright.config.js b/special-pages/playwright.config.js index e14e74195..5f13da3a9 100644 --- a/special-pages/playwright.config.js +++ b/special-pages/playwright.config.js @@ -1,3 +1,4 @@ +/* global process */ import { defineConfig, devices } from '@playwright/test' export default defineConfig({ @@ -20,7 +21,8 @@ export default defineConfig({ testMatch: [ 'privacy-stats.spec.js', 'rmf.spec.js', - 'new-tab.spec.js' + 'new-tab.spec.js', + 'update-notification.spec.js' ], use: { ...devices['Desktop Chrome'], diff --git a/special-pages/shared/components/Text/Text.js b/special-pages/shared/components/Text/Text.js index 6ca49e853..f0fc58862 100644 --- a/special-pages/shared/components/Text/Text.js +++ b/special-pages/shared/components/Text/Text.js @@ -10,6 +10,7 @@ import styles from './Text.module.css' * @param {boolean} [props.strictSpacing] - Apply Design System letter spacing. Default: true * @param {import("preact").ComponentChild} [props.children] */ +// eslint-disable-next-line no-redeclare export function Text ({ as: Comp = 'p', variant, strictSpacing = true, className, children }) { return ( diff --git a/special-pages/shared/create-special-page-messaging.js b/special-pages/shared/create-special-page-messaging.js index 7ad91a695..febce6a36 100644 --- a/special-pages/shared/create-special-page-messaging.js +++ b/special-pages/shared/create-special-page-messaging.js @@ -66,7 +66,7 @@ export function createSpecialPageMessaging (opts) { /** * @param {import('@duckduckgo/messaging').RequestMessage} msg */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars + request: (msg) => { console.log(msg) if (msg.method === 'initialSetup') { diff --git a/special-pages/tests/duckplayer-screenshots.spec.js b/special-pages/tests/duckplayer-screenshots.spec.js index 7da7c5322..2848aa5f9 100644 --- a/special-pages/tests/duckplayer-screenshots.spec.js +++ b/special-pages/tests/duckplayer-screenshots.spec.js @@ -1,3 +1,4 @@ +/* global process */ import { expect, test } from '@playwright/test' import { DuckPlayerPage } from './page-objects/duck-player.js' diff --git a/special-pages/types.mjs b/special-pages/types.mjs index bf40c517a..d48af5421 100644 --- a/special-pages/types.mjs +++ b/special-pages/types.mjs @@ -1,3 +1,4 @@ +/* eslint-disable promise/prefer-await-to-then */ import { join } from "node:path"; import { cwd, isLaunchFile } from "../scripts/script-utils.js"; import { buildTypes } from "../types-generator/build-types.mjs"; diff --git a/special-pages/types/new-tab.ts b/special-pages/types/new-tab.ts index 675e9f2b7..3d87d9ebf 100644 --- a/special-pages/types/new-tab.ts +++ b/special-pages/types/new-tab.ts @@ -34,20 +34,40 @@ export type RMFIcon = "Announce" | "DDGAnnounce" | "CriticalUpdate" | "AppUpdate */ export interface NewTabMessages { notifications: + | ContextMenuNotification | ReportInitExceptionNotification | ReportPageExceptionNotification | RmfDismissNotification | RmfPrimaryActionNotification | RmfSecondaryActionNotification | StatsSetConfigNotification + | UpdateNotificationDismissNotification | WidgetsSetConfigNotification; requests: InitialSetupRequest | RmfGetDataRequest | StatsGetConfigRequest | StatsGetDataRequest; subscriptions: | RmfOnDataUpdateSubscription | StatsOnConfigUpdateSubscription | StatsOnDataUpdateSubscription + | UpdateNotificationOnDataUpdateSubscription | WidgetsOnConfigUpdatedSubscription; } +/** + * Generated from @see "../messages/new-tab/contextMenu.notify.json" + */ +export interface ContextMenuNotification { + method: "contextMenu"; + params: ContextMenuNotify; +} +export interface ContextMenuNotify { + visibilityMenuItems: VisibilityMenuItem[]; +} +export interface VisibilityMenuItem { + id: string; + /** + * Translated name of the section + */ + title: string; +} /** * Generated from @see "../messages/new-tab/reportInitException.notify.json" */ @@ -124,6 +144,12 @@ export interface ViewTransitions { export interface Auto { kind: "auto-animate"; } +/** + * Generated from @see "../messages/new-tab/updateNotification_dismiss.notify.json" + */ +export interface UpdateNotificationDismissNotification { + method: "updateNotification_dismiss"; +} /** * Generated from @see "../messages/new-tab/widgets_setConfig.notify.json" */ @@ -153,6 +179,7 @@ export interface InitialSetupResponse { platform: { name: "macos" | "windows" | "android" | "ios" | "integration"; }; + updateNotification: null | UpdateNotificationData; } export interface WidgetListItem { /** @@ -160,6 +187,13 @@ export interface WidgetListItem { */ id: string; } +export interface UpdateNotificationData { + content: null | UpdateNotification; +} +export interface UpdateNotification { + version: string; + notes: string[]; +} /** * Generated from @see "../messages/new-tab/rmf_getData.request.json" */ @@ -249,6 +283,13 @@ export interface StatsOnDataUpdateSubscription { subscriptionEvent: "stats_onDataUpdate"; params: PrivacyStatsData; } +/** + * Generated from @see "../messages/new-tab/updateNotification_onDataUpdate.subscribe.json" + */ +export interface UpdateNotificationOnDataUpdateSubscription { + subscriptionEvent: "updateNotification_onDataUpdate"; + params: UpdateNotificationData; +} /** * Generated from @see "../messages/new-tab/widgets_onConfigUpdated.subscribe.json" */ diff --git a/tsconfig.json b/tsconfig.json index 1f3354287..b3aed1e0a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,7 +30,8 @@ "injected", "injected/src/globals.d.ts", "injected/src/features/duckplayer/duckplayer-settings.ts", - "typedoc.js" + "typedoc.js", + ".github/scripts" ], "exclude": [ "injected/integration-test/test-pages", diff --git a/types-generator/build-types.mjs b/types-generator/build-types.mjs index 21a94fa17..373d48102 100644 --- a/types-generator/build-types.mjs +++ b/types-generator/build-types.mjs @@ -32,23 +32,23 @@ const ROOT = join(cwd(import.meta.url), '..') * @param {Record} mapping */ export async function buildTypes(mapping) { - for (let [featureName, manifest] of Object.entries(mapping)) { + for (const [featureName, manifest] of Object.entries(mapping)) { if (manifest.exclude) continue; if (manifest.kind === 'settings') { const typescript = await createTypesForSchemaFile(featureName, manifest.schema); - let content = typescript.replace(/\r\n/g, '\n') + const content = typescript.replace(/\r\n/g, '\n') write([manifest.types], content) console.log('✅ %s schema written to `%s` from schema `%s`', featureName, relative(ROOT, manifest.types), manifest.schema) } if (manifest.kind === 'messages') { // create a job for each sub-folder that contains schemas - const schemas = await createSchemasFromFiles(manifest.schemaDir) + const schemas = createSchemasFromFiles(manifest.schemaDir) // for each folder - for (let schema of schemas) { + for (const schema of schemas) { const typescript = await createTypesForSchemaMessages(schema.featureName, schema.schema, manifest.schemaDir) - let featurePath = manifest.resolve(schema.dirname) - let className = manifest.className(schema.topLevelType) + const featurePath = manifest.resolve(schema.dirname) + const className = manifest.className(schema.topLevelType) const messageTypes = createMessagingTypes(schema, { featurePath, className }) const content = [typescript.replace(/\r\n/g, '\n'), messageTypes].join('') const filename = schema.dirname + '.ts' diff --git a/types-generator/json-schema-fs.mjs b/types-generator/json-schema-fs.mjs index a6e668aa1..5f44750a2 100644 --- a/types-generator/json-schema-fs.mjs +++ b/types-generator/json-schema-fs.mjs @@ -34,20 +34,20 @@ export function createFileList(rootDir, featureDirName) { /** * @param {string} rootDir - * @return {Promise<{ + * @return {{ * schema: import("json-schema-to-typescript").JSONSchema; * featureName: string; * dirname: string; * topLevelType: string; - * }[]>} + * }[]} */ -export async function createSchemasFromFiles(rootDir) { +export function createSchemasFromFiles(rootDir) { const dirList = readdirSync(rootDir, { withFileTypes: true }); const dirs = dirList.filter(x => x.isDirectory()); const outputs = []; - for (let dir of dirs) { + for (const dir of dirs) { const fileList = createFileList(rootDir, dir.name); const valid = fileList.filter(x => x.valid); if (valid.length === 0) continue; @@ -73,6 +73,7 @@ export async function createSchemasFromFiles(rootDir) { export function isValidFileName(file) { if (!file.isFile()) return {result: false} if (!file.name.endsWith('json')) return {result: false} + // eslint-disable-next-line @typescript-eslint/no-unused-vars const [method, kind, ext] = file.name.split('.'); if (kind === 'request' || kind === 'response' || kind === 'notify' || kind === 'subscribe') { return { result: true, method, kind } diff --git a/types-generator/json-schema.mjs b/types-generator/json-schema.mjs index 011802a28..ff9dea3bb 100644 --- a/types-generator/json-schema.mjs +++ b/types-generator/json-schema.mjs @@ -1,18 +1,20 @@ -import {createFileList} from "./json-schema-fs.mjs"; +/** + * @typedef {import("./json-schema-fs.mjs").createFileList} createFileList + */ /** * @param {ReturnType[number]} file */ function title(file) { switch (file.kind) { - case "request": - case "response": - return file.method + '_' + file.kind - case "subscribe": - return file.method + '_' + "subscription" - case "notify": - return file.method + '_' + "notification" - default: return file.kind + case "request": + case "response": + return file.method + '_' + file.kind + case "subscribe": + return file.method + '_' + "subscription" + case "notify": + return file.method + '_' + "notification" + default: return file.kind } } @@ -41,14 +43,14 @@ function hasParams(schema) { */ function baseSchema(file) { return { - "type": "object", - "title": title(file), - "description": description(file), - "additionalProperties": false, - "required": ["method"], - "properties": { - "method": { - "const": file.method + type: "object", + title: title(file), + description: description(file), + additionalProperties: false, + required: ["method"], + properties: { + method: { + const: file.method }, } } @@ -58,14 +60,14 @@ function baseSchema(file) { */ function subscribeBaseSchema(file) { return { - "type": "object", - "title": title(file), - "description": description(file), - "additionalProperties": false, - "required": ["subscriptionEvent"], - "properties": { - "subscriptionEvent": { - "const": file.method + type: "object", + title: title(file), + description: description(file), + additionalProperties: false, + required: ["subscriptionEvent"], + properties: { + subscriptionEvent: { + const: file.method }, } } @@ -79,7 +81,7 @@ function createNotification(file) { const json = file.json; const base = baseSchema(file) if (hasParams(json)) { - base.properties.params = { "$ref": "./" + file.relative } + base.properties.params = { $ref: "./" + file.relative } base.required.push('params') } return base; @@ -92,7 +94,7 @@ function createNotification(file) { function createRequest(file, response) { const base = createNotification(file); if (response && response.valid) { - base.properties.result = { "$ref": "./" + response.relative } + base.properties.result = { $ref: "./" + response.relative } base.required.push('result') } return base; @@ -106,7 +108,7 @@ function createSubscription(file) { const json = file.json; const base = subscribeBaseSchema(file) if (hasParams(json)) { - base.properties.params = { "$ref": "./" + file.relative } + base.properties.params = { $ref: "./" + file.relative } base.required.push('params') } return base; @@ -122,7 +124,7 @@ export function generateSchema(featureName, fileList) { const requests = []; const subscriptions = []; - for (let file of fileList.filter(x => x.valid)) { + for (const file of fileList.filter(x => x.valid)) { if (file.valid === false) continue; // ts if (file.kind === 'notify') { notifications.push(createNotification(file)) @@ -137,14 +139,14 @@ export function generateSchema(featureName, fileList) { } const base = { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "title": featureName + "_messages", - "description": `Requests, Notifications and Subscriptions from the ${featureName} feature`, - "additionalProperties": false, - "properties": {}, + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + title: featureName + "_messages", + description: `Requests, Notifications and Subscriptions from the ${featureName} feature`, + additionalProperties: false, + properties: {}, /** @type {string[]} */ - "required": [] + required: [] } if (notifications.length) { @@ -171,9 +173,9 @@ export function generateSchema(featureName, fileList) { */ export function createMessagingTypes(job, { featurePath, className }) { const json = job.schema - const notifications = json.properties?.notifications?.oneOf?.length ?? 0 > 0; - const requests = json.properties?.requests?.oneOf?.length ?? 0 > 0; - const subscriptions = json.properties?.subscriptions?.oneOf?.length ?? 0 > 0; + const notifications = (json.properties?.notifications?.oneOf?.length ?? 0) > 0; + const requests = (json.properties?.requests?.oneOf?.length ?? 0) > 0; + const subscriptions = (json.properties?.subscriptions?.oneOf?.length ?? 0) > 0; const lines = []; if (notifications) { lines.push(`notify: import("@duckduckgo/messaging/lib/shared-types").MessagingBase<${job.topLevelType}>['notify']`)