diff --git a/package.json b/package.json index 011069f..951a0b7 100644 --- a/package.json +++ b/package.json @@ -1,37 +1,37 @@ { - "name": "@sheepdog/root", - "version": "0.0.1", - "private": true, - "description": "monorepo for @sheepdog code and docs", - "keywords": [], - "repository": { - "type": "git", - "url": "git@github.com:mainmatter/sheepdog.git" - }, - "license": "ISC", - "author": "", - "type": "module", - "scripts": { - "build:docs": "pnpm --dir packages/svelte build && pnpm --dir apps/docs build", - "dev": "pnpm --dir packages/svelte dev", - "dev:docs": "pnpm --dir apps/docs dev", - "format": "pnpm -r format", - "lint": "pnpm -r lint", - "test": "pnpm -r test -- --run" - }, - "devDependencies": { - "@gravityci/cli": "^0.0.7", - "eslint-config-prettier": "^10.0.0", - "eslint-plugin-svelte": "2.46.1", - "globals": "^15.2.0", - "prettier-plugin-svelte": "^3.2.3", - "release-plan": "^0.11.0", - "typescript": "^5.4.5", - "typescript-eslint": "^8.0.0" - }, - "packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0", - "volta": { - "node": "22.13.1", - "pnpm": "9.15.4" - } + "name": "@sheepdog/root", + "version": "0.0.1", + "private": true, + "description": "monorepo for @sheepdog code and docs", + "keywords": [], + "repository": { + "type": "git", + "url": "git@github.com:mainmatter/sheepdog.git" + }, + "license": "ISC", + "author": "", + "type": "module", + "scripts": { + "build:docs": "pnpm --dir packages/svelte build && pnpm --dir apps/docs build", + "dev": "pnpm --dir packages/svelte dev", + "dev:docs": "pnpm --dir apps/docs dev", + "format": "pnpm -r format", + "lint": "pnpm -r lint", + "test": "pnpm -r test -- --run" + }, + "devDependencies": { + "@gravityci/cli": "^0.0.7", + "eslint-config-prettier": "^10.0.0", + "eslint-plugin-svelte": "2.46.1", + "globals": "^15.2.0", + "prettier-plugin-svelte": "^3.2.3", + "release-plan": "^0.11.0", + "typescript": "^5.4.5", + "typescript-eslint": "^8.0.0" + }, + "packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0", + "volta": { + "node": "22.13.1", + "pnpm": "9.15.4" + } } diff --git a/packages/core/package.json b/packages/core/package.json index f40fbf7..3caffbb 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -16,7 +16,8 @@ "generate-expected-force": "tsm ./src/lib/tests/expected-transforms/generate-expected.ts -f" }, "files": [ - "dist" + "dist", + "!dist/tsconfig.tsbuildinfo" ], "exports": { ".": { diff --git a/packages/svelte/package.json b/packages/svelte/package.json index d8fbd75..5214c93 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -58,9 +58,9 @@ "devDependencies": { "@playwright/test": "^1.44.0", "@sveltejs/adapter-auto": "^4.0.0", - "@sveltejs/kit": "^2.5.8", + "@sveltejs/kit": "^2.13.0", "@sveltejs/package": "^2.3.1", - "@sveltejs/vite-plugin-svelte": "^5.0.1", + "@sveltejs/vite-plugin-svelte": "^5.0.3", "@testing-library/jest-dom": "^6.4.5", "@testing-library/svelte": "^5.1.0", "@types/eslint": "9.6.1", @@ -85,7 +85,7 @@ "tsm": "^2.3.0", "typescript": "^5.4.5", "typescript-eslint": "^8.0.0", - "vite": "^6.0.0", + "vite": "^6.0.4", "vitest": "^3.0.0" }, "peerDependencies": { diff --git a/packages/vanilla/.gitignore b/packages/vanilla/.gitignore new file mode 100644 index 0000000..53c37a1 --- /dev/null +++ b/packages/vanilla/.gitignore @@ -0,0 +1 @@ +dist \ No newline at end of file diff --git a/packages/vanilla/package.json b/packages/vanilla/package.json new file mode 100644 index 0000000..23318fa --- /dev/null +++ b/packages/vanilla/package.json @@ -0,0 +1,74 @@ +{ + "name": "@sheepdog/vanilla", + "version": "0.0.6", + "repository": { + "type": "git", + "url": "git+https://github.com/mainmatter/sheepdog.git" + }, + "main": "./dist/src/index.js", + "type": "module", + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + }, + "./task": { + "types": "./dist/src/task.d.ts", + "import": "./dist/src/task.js" + }, + "./utils": { + "types": "./dist/src/utils.d.ts", + "import": "./dist/src/utils.js" + }, + "./vite": { + "types": "./dist/src/vite.d.ts", + "import": "./dist/src/vite.js" + } + }, + "types": "./dist/src/index.d.ts", + "files": [ + "dist", + "!dist/tsconfig.tsbuildinfo", + "!dist/**/*.test.*", + "!dist/**/*.spec.*" + ], + "scripts": { + "build": "tsc && publint", + "format": "eslint . --fix && prettier --write .", + "lint": "prettier --check . && eslint .", + "prepare": "pnpm build", + "prepublishOnly": "pnpm build", + "generate-expected": "tsm ./src/lib/tests/expected-transforms/generate-expected.ts", + "generate-expected-force": "tsm ./src/lib/tests/expected-transforms/generate-expected.ts -f", + "test": "pnpm run test:unit && pnpm run test:treeshake", + "test:unit": "vitest", + "test:treeshake": "pnpm build && vitest --config treeshake.vite.config.ts", + "test:unit:ui": "vitest --ui" + }, + "dependencies": { + "@sheepdog/core": "workspace:*" + }, + "devDependencies": { + "@types/eslint": "9.6.1", + "@types/eslint-config-prettier": "^6.11.3", + "@types/eslint__js": "^8.42.3", + "@vitest/coverage-v8": "^2.0.0", + "@vitest/ui": "^2.0.0", + "eslint": "^9.2.0", + "eslint-config-prettier": "^9.1.0", + "execa": "^9.4.0", + "fixturify-project": "^7.1.3", + "globals": "^15.2.0", + "prettier": "^3.2.5", + "publint": "^0.2.7", + "tslib": "^2.6.2", + "tsm": "^2.3.0", + "typescript": "^5.4.5", + "typescript-eslint": "^8.0.0", + "vite": "^6.0.0", + "vitest": "^2.1.2" + }, + "volta": { + "extends": "../../package.json" + } +} diff --git a/packages/vanilla/src/index.ts b/packages/vanilla/src/index.ts new file mode 100644 index 0000000..94ab216 --- /dev/null +++ b/packages/vanilla/src/index.ts @@ -0,0 +1,6 @@ +// Reexport your entry components here +import { didCancel, timeout, transform } from './utils'; +import { task, CancelationError } from './task.js'; +export type { Task, SheepdogUtils, TaskInstance } from './task.js'; + +export { task, CancelationError, didCancel, timeout, transform }; diff --git a/packages/vanilla/src/task.ts b/packages/vanilla/src/task.ts new file mode 100644 index 0000000..00e9ea9 --- /dev/null +++ b/packages/vanilla/src/task.ts @@ -0,0 +1,239 @@ +import type { + HandlerType, + HandlersMap, + SheepdogUtils, + TaskOptions, + TaskFunction, +} from '@sheepdog/core'; +import { CancelationError, createTask, handlers } from '@sheepdog/core'; +export type { SheepdogUtils, TaskOptions }; + +export { CancelationError }; + +export type Task = ReturnType>; + +type InstanceEvents = 'error' | 'finish' | 'cancel' | 'start' | 'success'; +type Events = 'start' | 'finish' | 'instance-create' | `instance-${InstanceEvents}`; + +class SheepdogEvent extends CustomEvent { + constructor(name: Events) { + super(name); + } +} + +class SheepdogInstanceEvent extends CustomEvent { + constructor(name: InstanceEvents) { + super(name); + } +} + +type MappedInstance = { + event_target: EventTarget; + is_running: boolean; + instance: TaskInstance; + offs: Set<() => void>; +}; + +export type TaskInstance = { + error?: unknown; + value?: TReturn; + on: (event: InstanceEvents, cb: () => void, options?: AddEventListenerOptions) => void; +}; + +function define_properties(on: TOn, from: TFrom): asserts on is TOn & Readonly { + for (const key in from) { + Object.defineProperty(on, key, { + enumerable: true, + get() { + return from[key as never]; + }, + }); + } +} + +function _task( + gen_or_fun: TaskFunction, + options?: TaskOptions, +) { + const event_target = new EventTarget(); + + const task_instance = { + isRunning: false, + last: undefined as undefined | TaskInstance, + lastCanceled: undefined as undefined | TaskInstance, + lastErrored: undefined as undefined | TaskInstance, + lastRunning: undefined as undefined | TaskInstance, + lastSuccessful: undefined as undefined | TaskInstance, + performCount: 0, + on(event: Events, cb: () => void, options?: AddEventListenerOptions) { + event_target.addEventListener(event, cb, options); + return () => { + event_target.removeEventListener(event, cb, options); + }; + }, + destroy() {}, + }; + + function update_is_running() { + task_instance.isRunning = [...instances.values()].some((val) => val.is_running); + } + + const instances = new Map>(); + + const actual_task = createTask>( + { + onDestroy(fn) { + task_instance.destroy = fn; + }, + onError(instance_id, error) { + const instance = instances.get(instance_id); + if (instance) { + task_instance.lastErrored = instance.instance; + instance.instance.error = error; + instance.is_running = false; + update_is_running(); + instance.event_target.dispatchEvent(new SheepdogInstanceEvent('error')); + instance.event_target.dispatchEvent(new SheepdogInstanceEvent('finish')); + // we delete after a microtask to avoid returnModifier + // not founding the instance in case of a syncronous + // cancellation (for example with drop) + queueMicrotask(() => { + instances.delete(instance_id); + for (const off of instance.offs) { + off(); + } + }); + } + event_target.dispatchEvent(new SheepdogEvent('instance-error')); + event_target.dispatchEvent(new SheepdogEvent('instance-finish')); + if (![...instances.values()].some((instance) => instance.is_running)) { + event_target.dispatchEvent(new SheepdogEvent('finish')); + } + }, + onInstanceCancel(instance_id) { + const instance = instances.get(instance_id); + if (instance) { + instance.is_running = false; + update_is_running(); + instance.event_target.dispatchEvent(new SheepdogInstanceEvent('cancel')); + instance.event_target.dispatchEvent(new SheepdogInstanceEvent('finish')); + // we delete after a microtask to avoid returnModifier + // not founding the instance in case of a syncronous + // cancellation (for example with drop) + queueMicrotask(() => { + instances.delete(instance_id); + for (const off of instance.offs) { + off(); + } + }); + } + event_target.dispatchEvent(new SheepdogEvent('instance-cancel')); + event_target.dispatchEvent(new SheepdogEvent('instance-finish')); + if (![...instances.values()].some((instance) => instance.is_running)) { + event_target.dispatchEvent(new SheepdogEvent('finish')); + } + }, + onInstanceCreate(instance_id) { + const instance_event_target = new EventTarget(); + const offs = new Set<() => void>(); + const instance: MappedInstance = { + event_target: instance_event_target, + offs, + instance: { + on(event, cb, options) { + instance_event_target.addEventListener(event, cb, options); + function off() { + instance_event_target.removeEventListener(event, cb, options); + } + offs.add(off); + return off; + }, + error: undefined, + value: undefined, + }, + is_running: false, + }; + task_instance.last = instance.instance; + if (instances.size === 0) { + event_target.dispatchEvent(new SheepdogEvent('start')); + } + instances.set(instance_id, instance); + event_target.dispatchEvent(new SheepdogEvent('instance-create')); + }, + onInstanceStart(instance_id) { + const instance = instances.get(instance_id); + if (instance) { + instance.event_target.dispatchEvent(new SheepdogInstanceEvent('start')); + instance.is_running = true; + update_is_running(); + } + task_instance.performCount++; + event_target.dispatchEvent(new SheepdogEvent('instance-start')); + }, + onInstanceComplete(instance_id, last_result) { + const instance = instances.get(instance_id); + if (instance) { + instance.instance.value = last_result; + instance.is_running = false; + update_is_running(); + instance.event_target.dispatchEvent(new SheepdogInstanceEvent('success')); + instance.event_target.dispatchEvent(new SheepdogInstanceEvent('finish')); + // we delete after a microtask to avoid returnModifier + // not founding the instance in case of a synchronous + // cancellation (for example with drop) + queueMicrotask(() => { + instances.delete(instance_id); + for (const off of instance.offs) { + off(); + } + }); + } + event_target.dispatchEvent(new SheepdogEvent('instance-success')); + event_target.dispatchEvent(new SheepdogEvent('instance-finish')); + if (![...instances.values()].some((instance) => instance.is_running)) { + event_target.dispatchEvent(new SheepdogEvent('finish')); + } + }, + returnModifier(instance_id, returned_value) { + const instance = instances.get(instance_id); + if (!instance) + throw new Error('Return modifier has been called before the instance was created'); + define_properties(returned_value, instance.instance); + return returned_value; + }, + }, + gen_or_fun, + options, + ); + define_properties(actual_task, task_instance); + return actual_task; +} + +type HandlersShorthands = { + [K in HandlerType]: ( + gen_or_fun: ( + args: TArgs, + utils: SheepdogUtils, + ) => Promise | AsyncGenerator, + options?: Parameters extends [] ? object : Parameters[0], + ) => ReturnType>; +}; + +const task: typeof _task & HandlersShorthands = _task as typeof _task & HandlersShorthands; + +function is_key(handler: string): handler is HandlerType { + return handler in handlers; +} + +for (const handler in handlers) { + if (is_key(handler)) { + task[handler] = (gen_or_fun, options) => { + if (!is_key(handler)) { + throw new Error('Impossible'); + } + return _task(gen_or_fun, { ...(options ?? {}), kind: handler }); + }; + } +} + +export { task }; diff --git a/packages/vanilla/src/utils.ts b/packages/vanilla/src/utils.ts new file mode 100644 index 0000000..34d6510 --- /dev/null +++ b/packages/vanilla/src/utils.ts @@ -0,0 +1,3 @@ +import { didCancel, timeout, transform } from '@sheepdog/core/utils'; + +export { didCancel, timeout, transform }; diff --git a/packages/vanilla/src/vite.ts b/packages/vanilla/src/vite.ts new file mode 100644 index 0000000..9ee4734 --- /dev/null +++ b/packages/vanilla/src/vite.ts @@ -0,0 +1,3 @@ +import { asyncTransform } from '@sheepdog/core/vite'; + +export { asyncTransform }; diff --git a/packages/vanilla/tests/treeshake/index.test.ts b/packages/vanilla/tests/treeshake/index.test.ts new file mode 100644 index 0000000..f1f961a --- /dev/null +++ b/packages/vanilla/tests/treeshake/index.test.ts @@ -0,0 +1,97 @@ +import { test, describe, expect } from 'vitest'; +import { Project } from 'fixturify-project'; +import { execa } from 'execa'; +import { readdir, readFile } from 'node:fs/promises'; + +async function does_it_shake(file: string) { + const project = new Project({ + files: { + 'index.js': file, + 'index.html': ``, + 'vite.config.ts': ` + export default { + build: { + minify: false, + modulePreload: { polyfill: false } + } + }`, + }, + }); + project.linkDevDependency('vite', { + baseDir: process.cwd(), + }); + project.linkDevDependency('@sheepdog/vanilla', { + baseDir: process.cwd(), + resolveName: '.', + }); + await project.write(); + await execa({ cwd: project.baseDir })`vite build`; + const folder = `${project.baseDir}/dist/assets`; + const dir = await readdir(folder); + return readFile(`${folder}/${dir[0]}`, 'utf-8'); +} + +describe('threeshake', () => { + test('importing `timeout` should treeshake the rest of the library', async () => { + const file = await does_it_shake(`import { timeout } from '@sheepdog/vanilla'; + + timeout();`); + expect(file).toMatchInlineSnapshot(` + "async function timeout(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + timeout(); + " + `); + }); + + test('importing `didCancel` should treeshake the rest of the library', async () => { + const file = await does_it_shake(`import { didCancel } from '@sheepdog/vanilla'; + + console.log(didCancel());`); + expect(file).toMatchInlineSnapshot(` + "class CancelationError extends Error { + constructor() { + super("CancelationError: the task instance was cancelled"); + super.name = "CancelationError"; + } + } + const didCancel = (e) => { + return e instanceof CancelationError; + }; + console.log(didCancel()); + " + `); + }); + + test('importing `CancelationError` should treeshake the rest of the library', async () => { + const file = await does_it_shake(`import { CancelationError } from '@sheepdog/vanilla'; + + console.log(CancelationError);`); + expect(file).toMatchInlineSnapshot(` + "class CancelationError extends Error { + constructor() { + super("CancelationError: the task instance was cancelled"); + super.name = "CancelationError"; + } + } + console.log(CancelationError); + " + `); + }); + + test('importing `transform` should treeshake the rest of the library', async () => { + const file = await does_it_shake(`import { transform } from '@sheepdog/vanilla'; + + console.log(transform);`); + expect(file).toMatchInlineSnapshot(` + "function transform(fn) { + { + throw new Error("You are using the transform function without the vite plugin. Please add the \`asyncTransform\` plugin to your \`vite.config.ts\`"); + } + } + console.log(transform); + " + `); + }); +}); diff --git a/packages/vanilla/tests/tsconfig.json b/packages/vanilla/tests/tsconfig.json new file mode 100644 index 0000000..d2267fb --- /dev/null +++ b/packages/vanilla/tests/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "noEmit": true + }, + "include": ["./**/*"] +} diff --git a/packages/vanilla/treeshake.vite.config.ts b/packages/vanilla/treeshake.vite.config.ts new file mode 100644 index 0000000..03edea5 --- /dev/null +++ b/packages/vanilla/treeshake.vite.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['./tests/treeshake/*.{test,spec}.{js,ts}'], + retry: 1, + }, +}); diff --git a/packages/vanilla/tsconfig.json b/packages/vanilla/tsconfig.json new file mode 100644 index 0000000..0d6dded --- /dev/null +++ b/packages/vanilla/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist/src", + "types": ["vite/client"] + }, + "include": ["./src"] +} diff --git a/packages/vanilla/vite.config.ts b/packages/vanilla/vite.config.ts new file mode 100644 index 0000000..9eae235 --- /dev/null +++ b/packages/vanilla/vite.config.ts @@ -0,0 +1,12 @@ +import { coverageConfigDefaults, defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['tests/**/*.{test,spec}.{js,ts}'], + retry: 1, + exclude: ['./tests/threeshake/*'], + coverage: { + exclude: ['*.[j|t]s', './tests/threeshake/*', ...coverageConfigDefaults.exclude], + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 147a993..7af9ac5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -113,13 +113,13 @@ importers: specifier: ^4.0.0 version: 4.0.0(@sveltejs/kit@2.16.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.2)(vite@6.0.9(@types/node@22.10.10)(yaml@2.5.1)))(svelte@5.19.2)(vite@6.0.9(@types/node@22.10.10)(yaml@2.5.1))) '@sveltejs/kit': - specifier: ^2.5.8 + specifier: ^2.13.0 version: 2.16.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.2)(vite@6.0.9(@types/node@22.10.10)(yaml@2.5.1)))(svelte@5.19.2)(vite@6.0.9(@types/node@22.10.10)(yaml@2.5.1)) '@sveltejs/package': specifier: ^2.3.1 version: 2.3.9(svelte@5.19.2)(typescript@5.7.3) '@sveltejs/vite-plugin-svelte': - specifier: ^5.0.1 + specifier: ^5.0.3 version: 5.0.3(svelte@5.19.2)(vite@6.0.9(@types/node@22.10.10)(yaml@2.5.1)) '@testing-library/jest-dom': specifier: ^6.4.5 @@ -194,12 +194,73 @@ importers: specifier: ^8.0.0 version: 8.21.0(eslint@9.18.0)(typescript@5.7.3) vite: - specifier: ^6.0.0 + specifier: ^6.0.4 version: 6.0.9(@types/node@22.10.10)(yaml@2.5.1) vitest: specifier: ^3.0.0 version: 3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(happy-dom@16.7.2)(yaml@2.5.1) + packages/vanilla: + dependencies: + '@sheepdog/core': + specifier: workspace:* + version: link:../core + devDependencies: + '@types/eslint': + specifier: 9.6.1 + version: 9.6.1 + '@types/eslint-config-prettier': + specifier: ^6.11.3 + version: 6.11.3 + '@types/eslint__js': + specifier: ^8.42.3 + version: 8.42.3 + '@vitest/coverage-v8': + specifier: ^2.0.0 + version: 2.1.8(vitest@2.1.8) + '@vitest/ui': + specifier: ^2.0.0 + version: 2.1.8(vitest@2.1.8) + eslint: + specifier: ^9.2.0 + version: 9.18.0 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@9.18.0) + execa: + specifier: ^9.4.0 + version: 9.5.2 + fixturify-project: + specifier: ^7.1.3 + version: 7.1.3 + globals: + specifier: ^15.2.0 + version: 15.14.0 + prettier: + specifier: ^3.2.5 + version: 3.4.2 + publint: + specifier: ^0.2.7 + version: 0.2.12 + tslib: + specifier: ^2.6.2 + version: 2.8.1 + tsm: + specifier: ^2.3.0 + version: 2.3.0 + typescript: + specifier: ^5.4.5 + version: 5.7.3 + typescript-eslint: + specifier: ^8.0.0 + version: 8.21.0(eslint@9.18.0)(typescript@5.7.3) + vite: + specifier: ^6.0.0 + version: 6.0.9(@types/node@22.10.10)(yaml@2.5.1) + vitest: + specifier: ^2.1.2 + version: 2.1.8(@types/node@22.10.10)(@vitest/ui@2.1.8)(happy-dom@16.7.2) + packages: '@adobe/css-tools@4.4.0': @@ -302,6 +363,9 @@ packages: resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} @@ -338,12 +402,24 @@ packages: '@emnapi/runtime@1.3.0': resolution: {integrity: sha512-XMBySMuNZs3DM96xcJmLW4EfGnf+uGmFNjzpehMjuX5PLB5j87ar2Zc4e3PVeZ3I5g3tYtAqskB28manlF69Zw==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.24.2': resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.24.2': resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} engines: {node: '>=18'} @@ -356,54 +432,108 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.24.2': resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.24.2': resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.24.2': resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.24.2': resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.24.2': resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.24.2': resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.24.2': resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.24.2': resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.24.2': resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} engines: {node: '>=18'} @@ -416,36 +546,72 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.24.2': resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.24.2': resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.24.2': resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.24.2': resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.24.2': resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.24.2': resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} engines: {node: '>=18'} @@ -458,6 +624,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.24.2': resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} engines: {node: '>=18'} @@ -470,30 +642,60 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.24.2': resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.24.2': resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.24.2': resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.24.2': resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.24.2': resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} engines: {node: '>=18'} @@ -1414,6 +1616,15 @@ packages: engines: {node: '>=18'} hasBin: true + '@vitest/coverage-v8@2.1.8': + resolution: {integrity: sha512-2Y7BPlKH18mAZYAW1tYByudlCYrQyl5RGvnnDYJKW5tCiO5qg3KSAy3XAxcxKz900a0ZXxWtKrMuZLe3lKBpJw==} + peerDependencies: + '@vitest/browser': 2.1.8 + vitest: 2.1.8 + peerDependenciesMeta: + '@vitest/browser': + optional: true + '@vitest/coverage-v8@3.0.4': resolution: {integrity: sha512-f0twgRCHgbs24Dp8cLWagzcObXMcuKtAwgxjJV/nnysPAJJk1JiKu/W0gIehZLmkljhJXU/E0/dmuQzsA/4jhA==} peerDependencies: @@ -1423,9 +1634,23 @@ packages: '@vitest/browser': optional: true + '@vitest/expect@2.1.8': + resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} + '@vitest/expect@3.0.4': resolution: {integrity: sha512-Nm5kJmYw6P2BxhJPkO3eKKhGYKRsnqJqf+r0yOGRKpEP+bSCBDsjXgiu1/5QFrnPMEgzfC38ZEjvCFgaNBC0Eg==} + '@vitest/mocker@2.1.8': + resolution: {integrity: sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + '@vitest/mocker@3.0.4': resolution: {integrity: sha512-gEef35vKafJlfQbnyOXZ0Gcr9IBUsMTyTLXsEQwuyYAerpHqvXhzdBnDFuHLpFqth3F7b6BaFr4qV/Cs1ULx5A==} peerDependencies: @@ -1437,23 +1662,43 @@ packages: vite: optional: true + '@vitest/pretty-format@2.1.8': + resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} + '@vitest/pretty-format@3.0.4': resolution: {integrity: sha512-ts0fba+dEhK2aC9PFuZ9LTpULHpY/nd6jhAQ5IMU7Gaj7crPCTdCFfgvXxruRBLFS+MLraicCuFXxISEq8C93g==} + '@vitest/runner@2.1.8': + resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==} + '@vitest/runner@3.0.4': resolution: {integrity: sha512-dKHzTQ7n9sExAcWH/0sh1elVgwc7OJ2lMOBrAm73J7AH6Pf9T12Zh3lNE1TETZaqrWFXtLlx3NVrLRb5hCK+iw==} + '@vitest/snapshot@2.1.8': + resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==} + '@vitest/snapshot@3.0.4': resolution: {integrity: sha512-+p5knMLwIk7lTQkM3NonZ9zBewzVp9EVkVpvNta0/PlFWpiqLaRcF4+33L1it3uRUCh0BGLOaXPPGEjNKfWb4w==} + '@vitest/spy@2.1.8': + resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==} + '@vitest/spy@3.0.4': resolution: {integrity: sha512-sXIMF0oauYyUy2hN49VFTYodzEAu744MmGcPR3ZBsPM20G+1/cSW/n1U+3Yu/zHxX2bIDe1oJASOkml+osTU6Q==} + '@vitest/ui@2.1.8': + resolution: {integrity: sha512-5zPJ1fs0ixSVSs5+5V2XJjXLmNzjugHRyV11RqxYVR+oMcogZ9qTuSfKW+OcTV0JeFNznI83BNylzH6SSNJ1+w==} + peerDependencies: + vitest: 2.1.8 + '@vitest/ui@3.0.4': resolution: {integrity: sha512-e+s2F9e9FUURkZ5aFIe1Fi3Y8M7UF6gEuShcaV/ur7y/Ldri+1tzWQ1TJq9Vas42NXnXvCAIrU39Z4U2RyET6g==} peerDependencies: vitest: 3.0.4 + '@vitest/utils@2.1.8': + resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} + '@vitest/utils@3.0.4': resolution: {integrity: sha512-8BqC1ksYsHtbWH+DfpOAKrFw3jl3Uf9J7yeFh85Pz52IWuh1hBBtyfEbRNNZNjl8H8A5yMLH9/t+k7HIKzQcZQ==} @@ -2190,6 +2435,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.24.2: resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} engines: {node: '>=18'} @@ -2219,6 +2469,12 @@ packages: peerDependencies: eslint: '>=7.0.0' + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + eslint-plugin-playwright@2.2.0: resolution: {integrity: sha512-qSQpAw7RcSzE3zPp8FMGkthaCWovHZ/BsXtpmnGax9vQLIovlh1bsZHEa2+j2lv9DWhnyeLM/qZmp7ffQZfQvg==} engines: {node: '>=16.6.0'} @@ -3791,6 +4047,11 @@ packages: proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + publint@0.2.12: + resolution: {integrity: sha512-YNeUtCVeM4j9nDiTT2OPczmlyzOkIXNtdDZnSuajAxS/nZ6j3t7Vs9SUB4euQNddiltIwu7Tdd3s+hr08fAsMw==} + engines: {node: '>=16'} + hasBin: true + publint@0.3.2: resolution: {integrity: sha512-fPs7QUbUvwixxPYUUTn0Kqp0rbH5rbiAOZwQOXMkIj+4Nopby1AngodSQmzTkJWTJ5R4uVV8oYmgVIjj+tgv1w==} engines: {node: '>=18'} @@ -4295,6 +4556,10 @@ packages: resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + tinyrainbow@2.0.0: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} @@ -4554,11 +4819,47 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@2.1.8: + resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite-node@3.0.4: resolution: {integrity: sha512-7JZKEzcYV2Nx3u6rlvN8qdo3QV7Fxyt6hx+CCKz9fbWxdX5IvUOmTWEAxMrWxaiSf7CKGLJQ5rFu8prb/jBjOA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true + vite@5.4.14: + resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vite@6.0.9: resolution: {integrity: sha512-MSgUxHcaXLtnBPktkbUSoQUANApKYuxZ6DrbVENlIorbhL2dZydTLaZ01tjUoE3szeFzlFk9ANOKk0xurh4MKA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -4607,6 +4908,31 @@ packages: vite: optional: true + vitest@2.1.8: + resolution: {integrity: sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.8 + '@vitest/ui': 2.1.8 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vitest@3.0.4: resolution: {integrity: sha512-6XG8oTKy2gnJIFTHP6LD7ExFeNLxiTkK3CfMvT7IfR8IN+BYICCf0lXUQmX7i7JoxUP8QmeP4mTnWXgflu4yjw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -5133,6 +5459,8 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@bcoe/v8-coverage@0.2.3': {} + '@bcoe/v8-coverage@1.0.2': {} '@ctrl/tinycolor@4.1.0': {} @@ -5182,84 +5510,153 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.24.2': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.24.2': optional: true '@esbuild/android-arm@0.15.18': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.24.2': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.24.2': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.24.2': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.24.2': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.24.2': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.24.2': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.24.2': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.24.2': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.24.2': optional: true '@esbuild/linux-loong64@0.15.18': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.24.2': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.24.2': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.24.2': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.24.2': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.24.2': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.24.2': optional: true '@esbuild/netbsd-arm64@0.24.2': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.24.2': optional: true '@esbuild/openbsd-arm64@0.24.2': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.24.2': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.24.2': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.24.2': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.24.2': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.24.2': optional: true @@ -6365,6 +6762,24 @@ snapshots: - rollup - supports-color + '@vitest/coverage-v8@2.1.8(vitest@2.1.8)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.4.0 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + magicast: 0.3.5 + std-env: 3.8.0 + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 + vitest: 2.1.8(@types/node@22.10.10)(@vitest/ui@2.1.8)(happy-dom@16.7.2) + transitivePeerDependencies: + - supports-color + '@vitest/coverage-v8@3.0.4(vitest@3.0.4)': dependencies: '@ampproject/remapping': 2.3.0 @@ -6383,6 +6798,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/expect@2.1.8': + dependencies: + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + tinyrainbow: 1.2.0 + '@vitest/expect@3.0.4': dependencies: '@vitest/spy': 3.0.4 @@ -6390,6 +6812,14 @@ snapshots: chai: 5.1.2 tinyrainbow: 2.0.0 + '@vitest/mocker@2.1.8(vite@5.4.14(@types/node@22.10.10))': + dependencies: + '@vitest/spy': 2.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 5.4.14(@types/node@22.10.10) + '@vitest/mocker@3.0.4(vite@6.0.9(@types/node@22.10.10)(yaml@2.5.1))': dependencies: '@vitest/spy': 3.0.4 @@ -6398,25 +6828,55 @@ snapshots: optionalDependencies: vite: 6.0.9(@types/node@22.10.10)(yaml@2.5.1) + '@vitest/pretty-format@2.1.8': + dependencies: + tinyrainbow: 1.2.0 + '@vitest/pretty-format@3.0.4': dependencies: tinyrainbow: 2.0.0 + '@vitest/runner@2.1.8': + dependencies: + '@vitest/utils': 2.1.8 + pathe: 1.1.2 + '@vitest/runner@3.0.4': dependencies: '@vitest/utils': 3.0.4 pathe: 2.0.2 + '@vitest/snapshot@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + magic-string: 0.30.17 + pathe: 1.1.2 + '@vitest/snapshot@3.0.4': dependencies: '@vitest/pretty-format': 3.0.4 magic-string: 0.30.17 pathe: 2.0.2 + '@vitest/spy@2.1.8': + dependencies: + tinyspy: 3.0.2 + '@vitest/spy@3.0.4': dependencies: tinyspy: 3.0.2 + '@vitest/ui@2.1.8(vitest@2.1.8)': + dependencies: + '@vitest/utils': 2.1.8 + fflate: 0.8.2 + flatted: 3.3.2 + pathe: 1.1.2 + sirv: 3.0.0 + tinyglobby: 0.2.10 + tinyrainbow: 1.2.0 + vitest: 2.1.8(@types/node@22.10.10)(@vitest/ui@2.1.8)(happy-dom@16.7.2) + '@vitest/ui@3.0.4(vitest@3.0.4)': dependencies: '@vitest/utils': 3.0.4 @@ -6428,6 +6888,12 @@ snapshots: tinyrainbow: 2.0.0 vitest: 3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(happy-dom@16.7.2)(yaml@2.5.1) + '@vitest/utils@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + '@vitest/utils@3.0.4': dependencies: '@vitest/pretty-format': 3.0.4 @@ -7212,6 +7678,32 @@ snapshots: esbuild-windows-64: 0.15.18 esbuild-windows-arm64: 0.15.18 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.24.2: optionalDependencies: '@esbuild/aix-ppc64': 0.24.2 @@ -7255,6 +7747,10 @@ snapshots: dependencies: eslint: 9.18.0 + eslint-config-prettier@9.1.0(eslint@9.18.0): + dependencies: + eslint: 9.18.0 + eslint-plugin-playwright@2.2.0(eslint@9.18.0): dependencies: eslint: 9.18.0 @@ -9270,6 +9766,12 @@ snapshots: proto-list@1.2.4: {} + publint@0.2.12: + dependencies: + npm-packlist: 5.1.3 + picocolors: 1.1.1 + sade: 1.8.1 + publint@0.3.2: dependencies: '@publint/pack': 0.1.1 @@ -9928,6 +10430,8 @@ snapshots: tinypool@1.0.2: {} + tinyrainbow@1.2.0: {} + tinyrainbow@2.0.0: {} tinyspy@3.0.2: {} @@ -10133,6 +10637,24 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 + vite-node@2.1.8(@types/node@22.10.10): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.6.0 + pathe: 1.1.2 + vite: 5.4.14(@types/node@22.10.10) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-node@3.0.4(@types/node@22.10.10)(yaml@2.5.1): dependencies: cac: 6.7.14 @@ -10154,6 +10676,15 @@ snapshots: - tsx - yaml + vite@5.4.14(@types/node@22.10.10): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.1 + rollup: 4.32.0 + optionalDependencies: + '@types/node': 22.10.10 + fsevents: 2.3.3 + vite@6.0.9(@types/node@22.10.10)(yaml@2.5.1): dependencies: esbuild: 0.24.2 @@ -10168,6 +10699,43 @@ snapshots: optionalDependencies: vite: 6.0.9(@types/node@22.10.10)(yaml@2.5.1) + vitest@2.1.8(@types/node@22.10.10)(@vitest/ui@2.1.8)(happy-dom@16.7.2): + dependencies: + '@vitest/expect': 2.1.8 + '@vitest/mocker': 2.1.8(vite@5.4.14(@types/node@22.10.10)) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.8 + '@vitest/snapshot': 2.1.8 + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + debug: 4.4.0 + expect-type: 1.1.0 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.14(@types/node@22.10.10) + vite-node: 2.1.8(@types/node@22.10.10) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.10.10 + '@vitest/ui': 2.1.8(vitest@2.1.8) + happy-dom: 16.7.2 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(happy-dom@16.7.2)(yaml@2.5.1): dependencies: '@vitest/expect': 3.0.4