From 2e700255c6b85cf58edf378788a6685d3aa9b658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robson=20J=C3=BAnior?= Date: Wed, 29 Jul 2026 00:54:56 -0300 Subject: [PATCH 1/4] chore: enable unused-imports and vue/no-reserved-component-names eslint rules --- eslint.config.js | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index b5d6a1657..4fa8f17ab 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -79,7 +79,7 @@ export default [ 'vue/component-definition-name-casing': ['error', 'PascalCase'], 'vue/component-name-in-template-casing': ['error', 'PascalCase'], 'vue/component-tags-order': ['error', { order: ['script[setup]', 'template', 'style'] }], - 'vue/multi-word-component-names': 'off', // Allow flexibility in component naming + 'vue/multi-word-component-names': 'off', 'vue/no-arrow-functions-in-watch': 'error', 'vue/no-async-in-computed-properties': 'error', 'vue/no-child-content': 'error', @@ -101,11 +101,11 @@ export default [ shallowOnly: false } ], - // "vue/no-reserved-component-names": ['error', { - // "disallowVueBuiltInComponents": false, - // "disallowVue3BuiltInComponents": false, - // "htmlElementCaseSensitive": false, - // }], + "vue/no-reserved-component-names": ['error', { + "disallowVueBuiltInComponents": true, + "disallowVue3BuiltInComponents": true, + "htmlElementCaseSensitive": true, + }], 'vue/no-restricted-syntax': 'error', 'vue/no-reserved-keys': [ 'error', @@ -117,14 +117,14 @@ export default [ 'vue/no-reserved-props': [ 'error', { - vueVersion: 3 // or 2 + vueVersion: 3 } ], 'vue/no-unused-vars': 'error', 'vue/v-if-else-key': 'error', 'vue/no-ref-as-operand': 'error', 'vue/no-side-effects-in-computed-properties': 'error', - 'vue/no-v-html': 'error', // Security + 'vue/no-v-html': 'error', 'vue/require-default-prop': 'error', 'vue/require-explicit-emits': 'error', 'vue/template-curly-spacing': 'error', @@ -136,10 +136,20 @@ export default [ 'vuejs-accessibility/click-events-have-key-events': 'error', // TypeScript - 'no-unused-vars': 'off', // 'error', - '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'off', // '@typescript-eslint/explicit-module-boundary-types': 'error', '@typescript-eslint/no-explicit-any': 'error', + 'unused-imports/no-unused-imports': 'error', + 'unused-imports/no-unused-vars': [ + 'error', + { + vars: 'all', + varsIgnorePattern: '^_', + args: 'after-used', + argsIgnorePattern: '^_' + } + ], // Import organization 'simple-import-sort/imports': 'error', @@ -149,7 +159,7 @@ export default [ 'import/no-duplicates': 'error', // Clean code - 'no-console': ['error', { allow: ['warn', 'error'] }], // Prevent console.log in production code + 'no-console': ['error', { allow: ['warn', 'error'] }], 'no-debugger': 'error', 'prefer-const': 'error' }, From ac037fe6848d2d1ff6f453330ee9d9bd4474c2cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robson=20J=C3=BAnior?= Date: Wed, 29 Jul 2026 00:54:59 -0300 Subject: [PATCH 2/4] chore(webkit): include .mjs in lint/format globs and format test .mjs files --- packages/webkit/package.json | 8 ++++---- packages/webkit/test/mcp/queries.test.mjs | 5 ++--- .../webkit/test/standards/authoring-docs.test.mjs | 15 ++++++++++----- packages/webkit/test/standards/invariant.test.mjs | 3 +-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/webkit/package.json b/packages/webkit/package.json index 6b0c002bb..ae8a5bab0 100644 --- a/packages/webkit/package.json +++ b/packages/webkit/package.json @@ -15,10 +15,10 @@ "scripts": { "clean": "rm -rf dist/", "pack:check": "! npm pack --dry-run 2>&1 | grep -E '\\.test\\.(ts|js)|src/test/'", - "format": "prettier --write \"**/*.{js,ts,vue,css,json,md}\"", - "format:check": "prettier --check \"**/*.{js,ts,vue,css,json,md}\"", - "lint": "eslint src --ext .js,.ts,.vue --max-warnings 0", - "lint:fix": "eslint src --ext .js,.ts,.vue --fix", + "format": "prettier --write \"**/*.{js,mjs,ts,vue,css,json,md}\"", + "format:check": "prettier --check \"**/*.{js,mjs,ts,vue,css,json,md}\"", + "lint": "eslint src --ext .js,.mjs,.ts,.vue --max-warnings 0", + "lint:fix": "eslint src --ext .js,.mjs,.ts,.vue --fix", "lint:style": "stylelint \"src/**/*.{css,scss,vue}\"", "lint:style:fix": "stylelint \"src/**/*.{css,scss,vue}\" --fix", "type-check": "vue-tsc --noEmit", diff --git a/packages/webkit/test/mcp/queries.test.mjs b/packages/webkit/test/mcp/queries.test.mjs index 888d51053..2eb0c6770 100644 --- a/packages/webkit/test/mcp/queries.test.mjs +++ b/packages/webkit/test/mcp/queries.test.mjs @@ -105,9 +105,8 @@ test('listTokens surfaces the animations catalog with timing + use-when', () => }) test('every animate-* utility has a useWhen entry (guidance stays in sync with the catalog)', async () => { - const { animate, useWhen } = await import( - '../../../theme/src/tokens/primitives/animations/animate.js' - ) + const { animate, useWhen } = + await import('../../../theme/src/tokens/primitives/animations/animate.js') for (const name of Object.keys(animate)) { assert.ok( typeof useWhen[name] === 'string' && useWhen[name].length > 0, diff --git a/packages/webkit/test/standards/authoring-docs.test.mjs b/packages/webkit/test/standards/authoring-docs.test.mjs index 007dc90a6..eab942cf2 100644 --- a/packages/webkit/test/standards/authoring-docs.test.mjs +++ b/packages/webkit/test/standards/authoring-docs.test.mjs @@ -8,7 +8,10 @@ import assert from 'node:assert/strict' import { scanDoc, docFileKind } from '../../../../.claude/hooks/_lib/authoring-docs-checks.mjs' -const ids = (rel, content) => scanDoc(rel, content).map((v) => v.id).sort() +const ids = (rel, content) => + scanDoc(rel, content) + .map((v) => v.id) + .sort() test('docFileKind resolves each population and skips non-governed paths', () => { assert.deepEqual(docFileKind('.claude/skills/add-animation/SKILL.md'), { @@ -27,10 +30,12 @@ test('docFileKind resolves each population and skips non-governed paths', () => docFileKind('packages/webkit/cli-templates/claude/skills/webkit-usage/SKILL.md'), { kind: 'skill', variant: 'consumer', scope: 'general', unit: 'webkit-usage' } ) - assert.deepEqual( - docFileKind('packages/webkit/cli-templates/claude/agents/webkit-expert.md'), - { kind: 'agent', variant: 'consumer', scope: 'general', unit: 'webkit-expert' } - ) + assert.deepEqual(docFileKind('packages/webkit/cli-templates/claude/agents/webkit-expert.md'), { + kind: 'agent', + variant: 'consumer', + scope: 'general', + unit: 'webkit-expert' + }) // not governed assert.equal(docFileKind('.claude/agents/_README.md'), null) assert.equal(docFileKind('.claude/skills/add-animation/references/foo.md'), null) diff --git a/packages/webkit/test/standards/invariant.test.mjs b/packages/webkit/test/standards/invariant.test.mjs index 773a1390c..f072a7377 100644 --- a/packages/webkit/test/standards/invariant.test.mjs +++ b/packages/webkit/test/standards/invariant.test.mjs @@ -54,8 +54,7 @@ const frontmatterOf = (content) => { const m = content.match(/^---\n([\s\S]*?)\n---/) return m ? m[1] : '' } -const enforcedByOf = (rel) => - parseEnforcedBy(frontmatterOf(readFileSync(join(ROOT, rel), 'utf-8'))) +const enforcedByOf = (rel) => parseEnforcedBy(frontmatterOf(readFileSync(join(ROOT, rel), 'utf-8'))) test('every rule doc is registered as a standard, and every standard has a rule doc', () => { const rules = new Set(ruleIds) From 2556ee5bd8819fe3a47683dde44e34270883fd24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robson=20J=C3=BAnior?= Date: Wed, 29 Jul 2026 01:11:40 -0300 Subject: [PATCH 3/4] chore: update lint canaries for unused-imports and vue/no-reserved-component-names --- lint-canaries/README.md | 6 +- .../import-hygiene/no-unused-imports.ts | 6 ++ .../eslint/typescript/no-unused-vars.ts | 14 ++--- .../no-reserved-component-names.vue | 9 +++ lint-canaries/index.js | 10 +++- packages/webkit/docs/DOC_LINTS.md | 60 +++++++++++++++---- 6 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 lint-canaries/eslint/import-hygiene/no-unused-imports.ts create mode 100644 lint-canaries/eslint/vue-correctness/no-reserved-component-names.vue diff --git a/lint-canaries/README.md b/lint-canaries/README.md index d9f1fa3f4..7ff5f4bc4 100644 --- a/lint-canaries/README.md +++ b/lint-canaries/README.md @@ -33,15 +33,15 @@ lint-canaries/ eslint/ vue-correctness/ # DOC_LINTS §2 — one .vue per vue/* rule accessibility/ # §3 — vuejs-accessibility/* - typescript/ # §4 — @typescript-eslint/* - import-hygiene/ # §5 — simple-import-sort/*, import/* + typescript/ # §4 — @typescript-eslint/*, unused-imports/no-unused-vars + import-hygiene/ # §5 — simple-import-sort/*, import/*, unused-imports/no-unused-imports clean-code/ # §6 — no-console, no-debugger, prefer-const stylelint/ # §7 — one .css per rule prettier/ # §8 — files that must stay "unformatted" commitlint/ # §10 — one wrong commit message per .txt ``` -54 canaries: 37 ESLint · 8 Stylelint · 2 Prettier · 7 commitlint. +56 canaries: 39 ESLint · 8 Stylelint · 2 Prettier · 7 commitlint. ## Why these files never break the normal pipeline diff --git a/lint-canaries/eslint/import-hygiene/no-unused-imports.ts b/lint-canaries/eslint/import-hygiene/no-unused-imports.ts new file mode 100644 index 000000000..1c5e182da --- /dev/null +++ b/lint-canaries/eslint/import-hygiene/no-unused-imports.ts @@ -0,0 +1,6 @@ +// CANARY — must keep failing unused-imports/no-unused-imports. +// `computed` is imported and never used — the one unused-code case +// `lint:fix` deletes automatically. +import { computed, ref } from 'vue' + +export const count = ref(0) diff --git a/lint-canaries/eslint/typescript/no-unused-vars.ts b/lint-canaries/eslint/typescript/no-unused-vars.ts index 6e65ca65a..bf34a168e 100644 --- a/lint-canaries/eslint/typescript/no-unused-vars.ts +++ b/lint-canaries/eslint/typescript/no-unused-vars.ts @@ -1,8 +1,8 @@ -// CANARY — must keep failing @typescript-eslint/no-unused-vars. -// `computed` is imported and never used; `event` is an unused parameter -// without the `_` prefix that would mark it intentional. -import { computed, ref } from 'vue' - -export function onSelect(event: MouseEvent, item: { label: string }) { - return ref(item.label) +// CANARY — must keep failing unused-imports/no-unused-vars. +// `orphan` is assigned and never used, without the `_` prefix that would +// mark it intentional. (Unused IMPORTS are guarded separately by +// eslint/import-hygiene/no-unused-imports.ts.) +export function onSelect(item: { label: string }) { + const orphan = item.label + return item } diff --git a/lint-canaries/eslint/vue-correctness/no-reserved-component-names.vue b/lint-canaries/eslint/vue-correctness/no-reserved-component-names.vue new file mode 100644 index 000000000..45142e915 --- /dev/null +++ b/lint-canaries/eslint/vue-correctness/no-reserved-component-names.vue @@ -0,0 +1,9 @@ + + + diff --git a/lint-canaries/index.js b/lint-canaries/index.js index 799974096..207adadb7 100644 --- a/lint-canaries/index.js +++ b/lint-canaries/index.js @@ -78,6 +78,10 @@ const ESLINT_CANARIES = [ { file: 'eslint/vue-correctness/no-mutating-props.vue', rule: 'vue/no-mutating-props' }, { file: 'eslint/vue-correctness/no-reserved-keys.vue', rule: 'vue/no-reserved-keys' }, { file: 'eslint/vue-correctness/no-reserved-props.vue', rule: 'vue/no-reserved-props' }, + { + file: 'eslint/vue-correctness/no-reserved-component-names.vue', + rule: 'vue/no-reserved-component-names' + }, { file: 'eslint/vue-correctness/no-unused-vars.vue', rule: 'vue/no-unused-vars' }, { file: 'eslint/vue-correctness/v-if-else-key.vue', rule: 'vue/v-if-else-key' }, { file: 'eslint/vue-correctness/no-ref-as-operand.vue', rule: 'vue/no-ref-as-operand' }, @@ -98,7 +102,7 @@ const ESLINT_CANARIES = [ rule: 'vuejs-accessibility/click-events-have-key-events' }, // ESLint — TypeScript - { file: 'eslint/typescript/no-unused-vars.ts', rule: '@typescript-eslint/no-unused-vars' }, + { file: 'eslint/typescript/no-unused-vars.ts', rule: 'unused-imports/no-unused-vars' }, { file: 'eslint/typescript/no-explicit-any.ts', rule: '@typescript-eslint/no-explicit-any' }, // ESLint — Import hygiene { file: 'eslint/import-hygiene/sorted-imports.ts', rule: 'simple-import-sort/imports' }, @@ -106,6 +110,10 @@ const ESLINT_CANARIES = [ { file: 'eslint/import-hygiene/first.ts', rule: 'import/first' }, { file: 'eslint/import-hygiene/newline-after-import.ts', rule: 'import/newline-after-import' }, { file: 'eslint/import-hygiene/no-duplicates.ts', rule: 'import/no-duplicates' }, + { + file: 'eslint/import-hygiene/no-unused-imports.ts', + rule: 'unused-imports/no-unused-imports' + }, // ESLint — Clean code { file: 'eslint/clean-code/no-console.ts', rule: 'no-console' }, { file: 'eslint/clean-code/no-debugger.ts', rule: 'no-debugger' }, diff --git a/packages/webkit/docs/DOC_LINTS.md b/packages/webkit/docs/DOC_LINTS.md index 87f5ac360..572be7efa 100644 --- a/packages/webkit/docs/DOC_LINTS.md +++ b/packages/webkit/docs/DOC_LINTS.md @@ -442,6 +442,26 @@ export default { ``` +### `vue/no-reserved-component-names` — no HTML / Vue built-in shadowing + +A component cannot take a name Vue or HTML already owns: Vue 2/3 built-ins are banned outright (`disallowVueBuiltInComponents` / `disallowVue3BuiltInComponents`), and HTML element names are checked **case-sensitively** (`htmlElementCaseSensitive: true`) — deliberate, so the DS's PascalCase roots (`Table`, `Button`, `Link`) stay valid while a literal lowercase `table` is rejected. + +**❌ Wrong** + +```vue + +``` + +**✅ Correct** + +```vue + +``` + ### `vue/no-unused-vars` Unused `v-for` / scope variables are dead code in the template. @@ -781,27 +801,24 @@ Anything clickable must be keyboard-operable. ## 4. ESLint — TypeScript -### `@typescript-eslint/no-unused-vars` (`argsIgnorePattern: '^_'`) +### `unused-imports/no-unused-vars` (`varsIgnorePattern: '^_'`, `argsIgnorePattern: '^_'`) -Dead imports, variables, and parameters are errors. An **intentionally** unused argument is spelled with a leading underscore. (Core `no-unused-vars` is off in favor of this TS-aware version.) +Dead variables and parameters are errors. An **intentionally** unused one is spelled with a leading underscore. (Core `no-unused-vars` and `@typescript-eslint/no-unused-vars` are both off in favor of the `unused-imports` pair, which splits unused **imports** into their own auto-fixable rule — §5.) **❌ Wrong** ```ts -import { computed, ref } from 'vue' // computed never used - -function onSelect(event: MouseEvent, item: Item) { - select(item) // event unused → error +function onSelect(item: Item, event: MouseEvent) { + const orphan = item.label // assigned, never used → error + return select(item) // trailing `event` unused → error } ``` **✅ Correct** ```ts -import { ref } from 'vue' - -function onSelect(_event: MouseEvent, item: Item) { - select(item) +function onSelect(item: Item, _event: MouseEvent) { + return select(item) } ``` @@ -934,6 +951,26 @@ import { useAttrs } from 'vue' import { computed, useAttrs } from 'vue' ``` +### `unused-imports/no-unused-imports` + +An import nothing uses is dead code — and the one unused-code case `lint:fix` deletes automatically (plain unused variables — §4 — only report; they are never auto-removed). + +**❌ Wrong** + +```ts +import { computed, ref } from 'vue' // computed never used + +export const count = ref(0) +``` + +**✅ Correct** + +```ts +import { ref } from 'vue' + +export const count = ref(0) +``` + --- ## 6. ESLint — Clean code @@ -1544,6 +1581,3 @@ A `.vue` whose props / events / slots / name / testid / animations diverge from Honest edges of the config: - **`vue/no-restricted-syntax`** is enabled with no selectors — it restricts nothing until selectors are added. -- **`vue/no-reserved-component-names`** is commented out in `eslint.config.js`. -- **`eslint-plugin-unused-imports`** is registered but none of its rules are enabled — unused imports are caught indirectly by `@typescript-eslint/no-unused-vars` (not auto-fixed on `lint:fix`). -- **`packages/webkit` `lint` script** passes `--ext .js,.js,.vue` (`.ts` missing, `.js` doubled) — plain `.ts` files are still covered by lint-staged and CI, which pass explicit extensions. From 081020a57dd823762d611a0e7d68b9d826a1359a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robson=20J=C3=BAnior?= Date: Wed, 29 Jul 2026 01:22:51 -0300 Subject: [PATCH 4/4] chore: adopt globals package for eslint language options --- eslint.config.js | 41 ++---------------- package.json | 1 + pnpm-lock.yaml | 106 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 100 insertions(+), 48 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 4fa8f17ab..6a9f361a9 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,6 @@ import js from '@eslint/js' import vue from 'eslint-plugin-vue' +import globals from 'globals' import typescript from '@typescript-eslint/eslint-plugin' import typescriptParser from '@typescript-eslint/parser' import vueParser from 'vue-eslint-parser' @@ -22,44 +23,8 @@ export default [ sourceType: 'module' }, globals: { - // Browser globals - window: 'readonly', - document: 'readonly', - navigator: 'readonly', - console: 'readonly', - fetch: 'readonly', - localStorage: 'readonly', - setTimeout: 'readonly', - clearTimeout: 'readonly', - setInterval: 'readonly', - clearInterval: 'readonly', - ResizeObserver: 'readonly', - requestAnimationFrame: 'readonly', - cancelAnimationFrame: 'readonly', - Element: 'readonly', - SVGElement: 'readonly', - HTMLElement: 'readonly', - HTMLAnchorElement: 'readonly', - HTMLButtonElement: 'readonly', - HTMLSelectElement: 'readonly', - HTMLInputElement: 'readonly', - HTMLOptionElement: 'readonly', - HTMLTextAreaElement: 'readonly', - HTMLLabelElement: 'readonly', - MouseEvent: 'readonly', - KeyboardEvent: 'readonly', - Event: 'readonly', - Node: 'readonly', - // Node globals - process: 'readonly', - __dirname: 'readonly', - __filename: 'readonly', - require: 'readonly', - module: 'readonly', - // ES2022 globals - Promise: 'readonly', - Symbol: 'readonly', - Reflect: 'readonly' + ...globals.browser, + ...globals.node } }, plugins: { diff --git a/package.json b/package.json index 1621998de..321bd2861 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "eslint-plugin-unused-imports": "^4.4.1", "eslint-plugin-vue": "^9", "eslint-plugin-vuejs-accessibility": "^2.5.0", + "globals": "^17.8.0", "husky": "^9.1.7", "lint-staged": "^16.4.0", "postcss": "^8.5.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9cdabb806..44f5ce4b3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,7 +75,10 @@ importers: version: 9.33.0(eslint@9.39.5(jiti@1.21.7)) eslint-plugin-vuejs-accessibility: specifier: ^2.5.0 - version: 2.5.0(eslint@9.39.5(jiti@1.21.7))(globals@14.0.0) + version: 2.5.0(eslint@9.39.5(jiti@1.21.7))(globals@17.8.0) + globals: + specifier: ^17.8.0 + version: 17.8.0 husky: specifier: ^9.1.7 version: 9.1.7 @@ -291,13 +294,13 @@ importers: version: 8.1.0(@vue/compiler-dom@3.5.40)(@vue/compiler-sfc@3.5.40)(@vue/server-renderer@3.5.40)(vue@3.5.40(typescript@6.0.3)) '@vitejs/plugin-vue': specifier: ^5.2.4 - version: 5.2.4(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) + version: 5.2.4(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) '@vitest/browser': specifier: ^4.1.9 - version: 4.1.10(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10) + version: 4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10) '@vitest/browser-playwright': specifier: ^4.1.9 - version: 4.1.10(playwright@1.61.1)(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10) + version: 4.1.10(playwright@1.61.1)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10) '@vitest/coverage-v8': specifier: ^4.1.9 version: 4.1.10(@vitest/browser@4.1.10)(vitest@4.1.10) @@ -318,7 +321,7 @@ importers: version: 17.14.0(typescript@6.0.3) vitest: specifier: ^4.1.9 - version: 4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) vue: specifier: ^3.5.29 version: 3.5.40(typescript@6.0.3) @@ -3726,6 +3729,10 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} + globals@17.8.0: + resolution: {integrity: sha512-Zz/LMDZScFmkakeL2cTHzf+PbWKdpU3uclqkZT7TjDG58j5WPt0PpA+n9uPI24fZtlw07q0OtEi84K+umsRzqQ==} + engines: {node: '>=18'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -8453,11 +8460,29 @@ snapshots: vite: 8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0) vue: 3.5.40(typescript@5.9.3) + '@vitejs/plugin-vue@5.2.4(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': + dependencies: + vite: 8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0) + vue: 3.5.40(typescript@6.0.3) + '@vitejs/plugin-vue@5.2.4(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': dependencies: vite: 8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0) vue: 3.5.40(typescript@6.0.3) + '@vitest/browser-playwright@4.1.10(playwright@1.61.1)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10)': + dependencies: + '@vitest/browser': 4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10) + '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) + playwright: 1.61.1 + tinyrainbow: 3.1.0 + vitest: 4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + '@vitest/browser-playwright@4.1.10(playwright@1.61.1)(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10)': dependencies: '@vitest/browser': 4.1.10(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10) @@ -8470,6 +8495,24 @@ snapshots: - msw - utf-8-validate - vite + optional: true + + '@vitest/browser@4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10)': + dependencies: + '@blazediff/core': 1.9.1 + '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) + '@vitest/utils': 4.1.10 + magic-string: 0.30.21 + pngjs: 7.0.0 + sirv: 3.0.2 + tinyrainbow: 3.1.0 + vitest: 4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) + ws: 8.21.1 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite '@vitest/browser@4.1.10(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10)': dependencies: @@ -8487,6 +8530,7 @@ snapshots: - msw - utf-8-validate - vite + optional: true '@vitest/coverage-v8@4.1.10(@vitest/browser@4.1.10)(vitest@4.1.10)': dependencies: @@ -8500,9 +8544,9 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.0 - vitest: 4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) + vitest: 4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) optionalDependencies: - '@vitest/browser': 4.1.10(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10) + '@vitest/browser': 4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10) '@vitest/expect@2.0.5': dependencies: @@ -8520,6 +8564,14 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 + '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.10 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0) + '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 @@ -8567,7 +8619,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vitest: 4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) + vitest: 4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) '@vitest/utils@2.0.5': dependencies: @@ -9982,11 +10034,11 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-vuejs-accessibility@2.5.0(eslint@9.39.5(jiti@1.21.7))(globals@14.0.0): + eslint-plugin-vuejs-accessibility@2.5.0(eslint@9.39.5(jiti@1.21.7))(globals@17.8.0): dependencies: aria-query: 5.3.2 eslint: 9.39.5(jiti@1.21.7) - globals: 14.0.0 + globals: 17.8.0 vue-eslint-parser: 10.4.1(eslint@9.39.5(jiti@1.21.7)) transitivePeerDependencies: - supports-color @@ -10536,6 +10588,8 @@ snapshots: globals@14.0.0: {} + globals@17.8.0: {} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -13470,6 +13524,38 @@ snapshots: sass: 1.101.0 yaml: 2.9.0 + vitest@4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + es-module-lexer: 2.3.1 + expect-type: 1.4.0 + magic-string: 0.30.21 + obug: 2.1.4 + pathe: 2.0.3 + picomatch: 4.0.5 + std-env: 4.2.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 26.1.1 + '@vitest/browser-playwright': 4.1.10(playwright@1.61.1)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.25.12)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0))(vitest@4.1.10) + '@vitest/coverage-v8': 4.1.10(@vitest/browser@4.1.10)(vitest@4.1.10) + '@vitest/ui': 4.1.10(vitest@4.1.10) + happy-dom: 20.10.6 + jsdom: 24.1.3 + transitivePeerDependencies: + - msw + vitest@4.1.10(@types/node@26.1.1)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(happy-dom@20.10.6)(jsdom@24.1.3)(vite@8.1.5(@types/node@26.1.1)(jiti@2.7.0)(sass@1.101.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.10