diff --git a/.vscode/settings.json b/.vscode/settings.json index 3e90e64819c5..45f0436107f0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -38,4 +38,13 @@ "volar.takeOverMode.enabled": "auto", "editor.tabSize": 2, + "coverage-gutters.coverageFileNames": [ + "coverage-final.json", + "lcov.info", + "cov.xml", + "coverage.xml", + "cobertura.xml", + "jacoco.xml", + "coverage.cobertura.xml" + ], } diff --git a/.yarnclean b/.yarnclean index 410da765e3aa..4f16bf4b4f2f 100644 --- a/.yarnclean +++ b/.yarnclean @@ -44,4 +44,6 @@ wercker.yml .flowconfig .documentup.json .yarn-metadata.json -.travis.yml \ No newline at end of file +.travis.yml + +!node_modules/istanbul-reports/lib/html/assets \ No newline at end of file diff --git a/packages/data-context/src/util/config-file-updater.ts b/packages/data-context/src/util/config-file-updater.ts index 421136c73385..1bcc0a579204 100644 --- a/packages/data-context/src/util/config-file-updater.ts +++ b/packages/data-context/src/util/config-file-updater.ts @@ -34,6 +34,7 @@ export async function insertValueInJSString (fileContents: string, obj: Record { + // The force no rewrite file follows a convention where we try + // and match all possible node_modules paths if the force no + // rewrite entry starts with "*/". If it does not + // start with "*" then it is an exact match. + return (forceNorewrite.startsWith('*/') && dependency.endsWith(forceNorewrite.slice(2))) || dependency === forceNorewrite +} diff --git a/tooling/v8-snapshot/src/doctor/determine-deferred.ts b/tooling/v8-snapshot/src/doctor/determine-deferred.ts index 4850738dab54..2489d36af4b0 100644 --- a/tooling/v8-snapshot/src/doctor/determine-deferred.ts +++ b/tooling/v8-snapshot/src/doctor/determine-deferred.ts @@ -1,9 +1,10 @@ import debug from 'debug' import fs from 'fs' import path from 'path' -import { doesDependencyMatchForceNorewriteEntry, SnapshotDoctor } from './snapshot-doctor' +import { SnapshotDoctor } from './snapshot-doctor' import { canAccess, createHashForFile, matchFileHash } from '../utils' - +import { doesDependencyMatchForceNorewriteEntry } from './dependency-match' +import { forceDeferred } from '../setup/force-deferred' const logInfo = debug('cypress:snapgen:info') interface ErrorOnInvalidForceNorewriteOpts { @@ -49,6 +50,20 @@ function errorOnInvalidForceNorewrite (opts: ErrorOnInvalidForceNorewriteOpts) { } } +export interface SnapshotMetadata { + deferredHash: string + norewrite: string[] + deferred: string[] + healthy: string[] +} + +async function importCachedSnapshotMetadata (cacheDir: string): Promise { + const jsonPath = path.join(cacheDir, 'snapshot-meta.json') + const contents = await fs.promises.readFile(jsonPath, 'utf8') + + return JSON.parse(contents) satisfies SnapshotMetadata +} + export async function determineDeferred ( bundlerPath: string, projectBaseDir: string, @@ -63,11 +78,12 @@ export async function determineDeferred ( }, ) { const jsonPath = path.join(cacheDir, 'snapshot-meta.json') + const usePreviousSnapshotMetadata = (!process.env.V8_SNAPSHOT_FROM_SCRATCH || !['1', 'true'].includes(process.env.V8_SNAPSHOT_FROM_SCRATCH)) && await canAccess(jsonPath) - const { deferredHash, norewrite, deferred, healthy } = usePreviousSnapshotMetadata ? require(jsonPath) : { deferredHash: '', norewrite: [], deferred: [], healthy: [] } + const { deferredHash, norewrite, deferred, healthy } = usePreviousSnapshotMetadata ? await importCachedSnapshotMetadata(cacheDir) : await Promise.resolve({ deferredHash: '', norewrite: [], deferred: [], healthy: [] }) + const hashFilePath = await findHashFile(projectBaseDir) const currentHash = await createHashForFile(hashFilePath) - const res = await matchFileHash(hashFilePath, deferredHash) let nodeModulesHealthy: string[] = [] let projectHealthy: string[] = [] @@ -105,7 +121,10 @@ export async function determineDeferred ( } }) - if (res.match && opts.nodeModulesOnly) { + const res = await matchFileHash(hashFilePath, deferredHash) + const fileHashMatchesDeferredHash = res.match + + if (fileHashMatchesDeferredHash && opts.nodeModulesOnly) { const combined: Set = new Set([ ...currentNorewrite, ...opts.forceNorewrite, @@ -127,9 +146,9 @@ export async function determineDeferred ( entryFilePath: snapshotEntryFile, baseDirPath: projectBaseDir, nodeModulesOnly: opts.nodeModulesOnly, - previousDeferred: currentDeferred, - previousHealthy: currentHealthy, - previousNorewrite: currentNorewrite, + previousDeferred: new Set([...currentDeferred, ...forceDeferred()]), + previousHealthy: new Set(currentHealthy), + previousNorewrite: new Set(currentNorewrite), forceNorewrite: opts.forceNorewrite, nodeEnv: opts.nodeEnv, cypressInternalEnv: opts.cypressInternalEnv, diff --git a/tooling/v8-snapshot/src/doctor/snapshot-doctor.ts b/tooling/v8-snapshot/src/doctor/snapshot-doctor.ts index 2791628e2fa2..4c0e2acd41b4 100644 --- a/tooling/v8-snapshot/src/doctor/snapshot-doctor.ts +++ b/tooling/v8-snapshot/src/doctor/snapshot-doctor.ts @@ -19,6 +19,7 @@ import { WarningConsequence, WarningsProcessor, } from './warnings-processor' +import { doesDependencyMatchForceNorewriteEntry } from './dependency-match' const logInfo = debug('cypress:snapgen:info') const logDebug = debug('cypress:snapgen:debug') @@ -48,20 +49,6 @@ export type SnapshotDoctorOpts = Omit< forceNorewrite: Set } -/** - * Checks if a dependency matches a force no rewrite entry - * @param dependency - The dependency to check - * @param forceNorewrite - The force no rewrite entry - * @returns true if the dependency matches the force no rewrite entry, false otherwise - */ -export const doesDependencyMatchForceNorewriteEntry = (dependency: string, forceNorewrite: string) => { - // The force no rewrite file follows a convention where we try - // and match all possible node_modules paths if the force no - // rewrite entry starts with "*/". If it does not - // start with "*" then it is an exact match. - return (forceNorewrite.startsWith('*/') && dependency.endsWith(forceNorewrite.slice(2))) || dependency === forceNorewrite -} - /** * Tracks which modules have been deferred, need to be deferred and so on * during the doctor process diff --git a/tooling/v8-snapshot/src/generator/snapshot-generator.ts b/tooling/v8-snapshot/src/generator/snapshot-generator.ts index c059f6b30432..b869acb186bc 100644 --- a/tooling/v8-snapshot/src/generator/snapshot-generator.ts +++ b/tooling/v8-snapshot/src/generator/snapshot-generator.ts @@ -263,10 +263,12 @@ export class SnapshotGenerator { if (this.useExistingSnapshotScript) { let contents = await fs.promises.readFile(this.snapshotScriptPath, 'utf8') + console.log('??', contents, this.updateSnapshotScriptContents) if (this.updateSnapshotScriptContents) { contents = this.updateSnapshotScriptContents(contents) } + console.log('??', contents) this.snapshotScript = Buffer.from(contents) await fs.promises.writeFile(this.snapshotScriptPath, this.snapshotScript) @@ -339,7 +341,8 @@ export class SnapshotGenerator { // errors we verify that the generated script is snapshot-able. logInfo('Verifying snapshot script') try { - this._verifyScript() + assert(this.snapshotScript != null, 'need snapshotScript to be set') + this._snapshotVerifier.verify(this.snapshotScript, this.snapshotScriptPath) } catch (err) { logInfo(`Script failed verification, writing to ${this.snapshotScriptPath}`) @@ -604,9 +607,4 @@ export class SnapshotGenerator { throw new Error('make snapshot failed') } - - private _verifyScript () { - assert(this.snapshotScript != null, 'need snapshotScript to be set') - this._snapshotVerifier.verify(this.snapshotScript, this.snapshotScriptPath) - } } diff --git a/tooling/v8-snapshot/src/setup/force-deferred.ts b/tooling/v8-snapshot/src/setup/force-deferred.ts new file mode 100644 index 000000000000..c95152edd81a --- /dev/null +++ b/tooling/v8-snapshot/src/setup/force-deferred.ts @@ -0,0 +1,3 @@ +export function forceDeferred (): string[] { + return [] +} diff --git a/tooling/v8-snapshot/test/fixtures/force-deferred.json b/tooling/v8-snapshot/test/fixtures/force-deferred.json new file mode 100644 index 000000000000..a3fe9d829f6c --- /dev/null +++ b/tooling/v8-snapshot/test/fixtures/force-deferred.json @@ -0,0 +1,6 @@ +{ + "empty": [], + "withValues": [ + "node_modules/some-package/src/index.js" + ] +} \ No newline at end of file diff --git a/tooling/v8-snapshot/test/unit/determine-deferred.vspec.ts b/tooling/v8-snapshot/test/unit/determine-deferred.vspec.ts new file mode 100644 index 000000000000..b78276c37828 --- /dev/null +++ b/tooling/v8-snapshot/test/unit/determine-deferred.vspec.ts @@ -0,0 +1,478 @@ +import { describe, it, expect, vi, beforeEach, afterEach, Mock } from 'vitest' + +import { determineDeferred, SnapshotMetadata } from '../../src/doctor/determine-deferred' + +import fs from 'fs' +import * as doctor from '../../src/doctor/snapshot-doctor' +import * as utils from '../../src/utils' +import type { Metadata } from '../../src/types' +import forceDeferredFixtures from '../../test/fixtures/force-deferred.json' +import { forceDeferred } from '../../src/setup/force-deferred' +const { createHashForFile, matchFileHash } = utils +const { SnapshotDoctor } = doctor + +expect.extend({ + setContaining | Array | U, U> (received: Set, expected: T) { + if (!(received instanceof Set)) { + return { message: () => `expected ${received} to be a Set`, pass: false } + } + + const notFound: U[] = [] + const coercedExpected: U[] = expected instanceof Set ? Array.from(expected) : expected instanceof Array ? expected : [expected] + + for (const val of coercedExpected) { + if (!received.has(val)) { + notFound.push(val) + } + } + + return { message: () => `expected ${received} to contain ${expected}`, pass: notFound.length === 0 } + }, +}) + +declare module 'vitest' { + interface Assertion { + setContaining (expected: Set | Array | U): void + } + + interface AsymmetricMatchers { + setContaining (expected: Set | Array | U): void + } + + interface ExpectStatic { + setContaining (expected: Set | Array | U): void + } +} + +vi.mock('../../src/setup/force-deferred', () => { + return { + forceDeferred: vi.fn(), + } +}) + +vi.mock('fs', async () => { + const actual = await vi.importActual('fs') + + return { + ...actual, + promises: { + ...actual.promises, + writeFile: vi.fn(), + }, + } +}) + +vi.mock('../../src/utils', async () => { + const actual = await vi.importActual('../../src/utils') + + return { + ...actual, + createHashForFile: vi.fn(), + canAccess: vi.fn(), + matchFileHash: vi.fn(), + } +}) + +vi.mock('../../src/doctor/snapshot-doctor') + +describe('determineDeferred', () => { + let bundlerPath: string + let projectBaseDir: string + let snapshotEntryFile: string + let cacheDir: string + let opts: { + nodeModulesOnly: boolean + forceNorewrite: Set + nodeEnv: string + cypressInternalEnv: string + integrityCheckSource: string | undefined + } + + let matchFileHashResult: Awaited> + + let meta: Metadata + + const projectYarnLockHash = 'projectYarnLockHash' + + beforeEach(() => { + bundlerPath = 'bundlerPath' + projectBaseDir = 'projectBaseDir' + snapshotEntryFile = 'snapshotEntryFile' + cacheDir = 'cacheDir' + + opts = { + nodeModulesOnly: true, + forceNorewrite: new Set(), + nodeEnv: 'nodeEnv', + cypressInternalEnv: 'cypressInternalEnv', + integrityCheckSource: 'integrityCheckSource', + } + + meta = { + inputs: {}, + resolverMap: {}, + outputs: {}, + } + + matchFileHashResult = { + hash: 'hash', + match: true, + } + + ;(matchFileHash as Mock).mockImplementation(() => { + return Promise.resolve(matchFileHashResult) + }) + + vi.spyOn(fs.promises, 'writeFile').mockResolvedValue(void 0) + + vi.mocked(forceDeferred).mockReturnValue(forceDeferredFixtures.empty) + }) + + afterEach(() => { + vi.resetAllMocks() + }) + + describe('when using previous snapshot metadata', () => { + let previousSnapshotMetadata: SnapshotMetadata + + let prevEnv: string | undefined + + beforeEach(() => { + previousSnapshotMetadata = { + deferredHash: 'deferredHash', + norewrite: ['norewrite'], + deferred: ['deferred'], + healthy: ['healthy'], + } + + prevEnv = process.env.V8_SNAPSHOT_FROM_SCRATCH + + process.env.V8_SNAPSHOT_FROM_SCRATCH = 'false' + + vi.spyOn(utils, 'canAccess').mockResolvedValue(true) + vi.spyOn(fs.promises, 'readFile').mockImplementation(() => { + return Promise.resolve(JSON.stringify(previousSnapshotMetadata)) + }) + + ;(createHashForFile as Mock).mockImplementation(() => { + return Promise.resolve(projectYarnLockHash) + }) + }) + + afterEach(() => { + process.env.V8_SNAPSHOT_FROM_SCRATCH = prevEnv + }) + + describe('when using nodeModulesOnly', () => { + const moduleHealthy: string = 'node_modules/healthy' + const moduleDeferred: string = 'node_modules/deferred' + const moduleNorewrite: string = 'node_modules/norewrite' + + beforeEach(() => { + opts.nodeModulesOnly = true + previousSnapshotMetadata.healthy.push(moduleHealthy) + previousSnapshotMetadata.norewrite.push(moduleNorewrite) + previousSnapshotMetadata.deferred.push(moduleDeferred) + }) + + describe('when deferred hash matches the project yarn.lock hash', () => { + beforeEach(() => { + matchFileHashResult.match = true + }) + + it('returns only the node_modules dependencies from the previous snapshot metadata, and does not call doctor.heal()', async () => { + await expect( + determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts), + ).resolves.toEqual({ + deferred: expect.arrayContaining([moduleDeferred]), + norewrite: expect.arrayContaining([moduleNorewrite]), + healthy: expect.arrayContaining([moduleHealthy]), + }) + + expect(SnapshotDoctor.prototype.heal).not.toHaveBeenCalled() + }) + }) + + describe('and hash does not match', () => { + beforeEach(() => { + (matchFileHash as Mock).mockImplementation(() => { + return Promise.resolve({ + hash: 'differentHash', + match: false, + }) + }) + }) + + describe('when doctor.heal() returns meta inputs for each forceNoRewrite entry', () => { + beforeEach(() => { + opts.forceNorewrite.add('node_modules/included') + + ;(SnapshotDoctor.prototype.heal as Mock).mockImplementation(() => { + const ret = { + healthy: [...previousSnapshotMetadata.healthy, 'newHealthy'], + deferred: [...previousSnapshotMetadata.deferred, 'newDeferred'], + norewrite: [...previousSnapshotMetadata.norewrite, 'newNorewrite'], + bundle: Buffer.from(''), + meta: { + ...meta, + inputs: Array.from(opts.forceNorewrite).reduce((prev, dependency) => { + return { + ...prev, + [dependency]: { fileInfo: { fullPath: dependency } }, + } + }, {}), + }, + } + + return Promise.resolve(ret) + }) + }) + + it('returns the previous snapshot merged with the new changes, without the hash', async () => { + const { deferredHash, ...previousMetadata } = previousSnapshotMetadata + + const res = await determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts) + + expect( + res, + ).toEqual({ + deferred: expect.arrayContaining(['newDeferred']), + norewrite: expect.arrayContaining(['newNorewrite']), + healthy: expect.arrayContaining(['newHealthy']), + }) + + expect(res).toEqual({ + deferred: expect.arrayContaining(previousMetadata.deferred), + norewrite: expect.arrayContaining(previousMetadata.norewrite), + healthy: expect.arrayContaining(previousMetadata.healthy), + }) + }) + }) + + describe('when doctor.heal() returns inputs that do not include all forceNoRewrite entries', () => { + beforeEach(() => { + meta.inputs = {} + opts.forceNorewrite.add('node_modules/missing-force-norewrite') + vi.mocked(SnapshotDoctor.prototype.heal).mockResolvedValue({ + healthy: previousSnapshotMetadata.healthy, + deferred: previousSnapshotMetadata.deferred, + norewrite: previousSnapshotMetadata.norewrite, + bundle: Buffer.from(''), + meta, + }) + }) + + it('throws an error', async () => { + await expect( + determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts), + ).rejects.toThrow() + }) + + describe('and there are non-node_modules entries in forceNorewrite', () => { + beforeEach(() => { + opts.forceNorewrite.add('/non-npm') + }) + + it('throws an error', async () => { + await expect( + determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts), + ).rejects.toThrow() + }) + }) + }) + }) + }) + + describe('when not using nodeModulesOnly', () => { + beforeEach(() => { + opts.nodeModulesOnly = false + }) + + describe('when doctor.heal() returns no changes', () => { + beforeEach(() => { + (SnapshotDoctor.prototype.heal as Mock).mockResolvedValue({ + healthy: previousSnapshotMetadata.healthy, + deferred: previousSnapshotMetadata.deferred, + norewrite: previousSnapshotMetadata.norewrite, + bundle: Buffer.from(''), + meta, + }) + }) + + it('returns the previous snapshot metadata, without the hash', async () => { + const { deferredHash, ...previousMetadata } = previousSnapshotMetadata + + await expect( + determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts), + ).resolves.toEqual(previousMetadata) + }) + + describe('and updateMetaFile env is true', () => { + let prevEnv + + beforeEach(() => { + prevEnv = { ...process.env } + process.env.V8_UPDATE_METAFILE = 'true' + }) + + afterEach(() => { + process.env = prevEnv + }) + + describe('and generateFromScratch is true', () => { + beforeEach(() => { + process.env.V8_SNAPSHOT_FROM_SCRATCH = 'true' + }) + + it('writes updated meta to file', async () => { + await determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts) + const [[snapshotPath, writtenMeta, encoding]] = (fs.promises.writeFile as Mock).mock.calls + + expect(snapshotPath).to.eq('cacheDir/snapshot-meta.json') + expect(JSON.parse(writtenMeta as string)).toMatchObject({ + ...previousSnapshotMetadata, + deferredHashFile: 'yarn.lock', + deferredHash: projectYarnLockHash, + }) + + expect(encoding).to.eq('utf8') + }) + }) + + describe('and generateFromScratch is falsey', () => { + beforeEach(() => { + process.env.V8_SNAPSHOT_FROM_SCRATCH = undefined + }) + + it('writes updated meta to file', async () => { + await determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts) + + const [[snapshotPath, writtenMeta, encoding]] = (fs.promises.writeFile as Mock).mock.calls + + expect(snapshotPath).to.eq('cacheDir/snapshot-meta.json') + expect(JSON.parse(writtenMeta as string)).toMatchObject({ + ...previousSnapshotMetadata, + deferredHashFile: 'yarn.lock', + deferredHash: projectYarnLockHash, + }) + + expect(encoding).to.eq('utf8') + }) + }) + }) + + describe('and updateMetaFile env is false', () => { + let prevEnv + + beforeEach(() => { + prevEnv = { ...process.env } + process.env.V8_UPDATE_METAFAILE = undefined + }) + + afterEach(() => { + process.env = prevEnv + }) + + describe('and generateFromScratch is true', () => { + beforeEach(() => { + process.env.V8_SNAPSHOT_FROM_SCRATCH = 'true' + }) + + it('writes updated meta to file', async () => { + await determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts) + const [[snapshotPath, writtenMeta, encoding]] = (fs.promises.writeFile as Mock).mock.calls + + expect(snapshotPath).to.eq('cacheDir/snapshot-meta.json') + expect(JSON.parse(writtenMeta as string)).toMatchObject({ + ...previousSnapshotMetadata, + deferredHashFile: 'yarn.lock', + deferredHash: projectYarnLockHash, + }) + + expect(encoding).to.eq('utf8') + }) + }) + + describe('and generateFromScratch is falsey', () => { + beforeEach(() => { + process.env.V8_SNAPSHOT_FROM_SCRATCH = undefined + }) + + it('does not write updated meta to file', async () => { + await determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts) + + expect(fs.promises.writeFile).not.toHaveBeenCalled() + }) + }) + }) + }) + + describe('when doctor.heal() returns invalid forceNorewrite', () => { + const meta: Metadata = { + inputs: {}, + resolverMap: {}, + outputs: {}, + } + + beforeEach(() => { + vi.mocked(SnapshotDoctor.prototype.heal).mockResolvedValue({ + healthy: previousSnapshotMetadata.healthy, + deferred: previousSnapshotMetadata.deferred, + norewrite: previousSnapshotMetadata.norewrite, + bundle: Buffer.from(''), + meta, + }) + + opts.forceNorewrite.add('node_modules/missing-deferred') + }) + + it('throws an error', async () => { + await expect( + determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts), + ).rejects.toThrow() + }) + }) + }) + }) + + describe('when not using previous snapshot metadata', () => { + let prevEnv + + beforeEach(() => { + prevEnv = process.env.V8_SNAPSHOT_FROM_SCRATCH + + process.env.V8_SNAPSHOT_FROM_SCRATCH = '1' + + vi.spyOn(utils, 'canAccess').mockResolvedValue(false) + + matchFileHashResult.match = false + opts.nodeModulesOnly = false + + vi.mocked(SnapshotDoctor.prototype.heal).mockResolvedValue({ + healthy: [], + deferred: [], + norewrite: [], + bundle: Buffer.from(''), + meta, + }) + }) + + afterEach(() => { + process.env.V8_SNAPSHOT_FROM_SCRATCH = prevEnv + }) + + describe('when there are files that are force-deferred', () => { + beforeEach(() => { + vi.mocked(forceDeferred).mockReturnValue(forceDeferredFixtures.withValues) + }) + + it('initializes the doctor with the force-deferred entries in the previousDeferred param', async () => { + await determineDeferred(bundlerPath, projectBaseDir, snapshotEntryFile, cacheDir, opts) + + expect(SnapshotDoctor).toHaveBeenCalledWith(expect.objectContaining({ + previousDeferred: expect.setContaining(forceDeferredFixtures.withValues), + })) + }) + }) + }) +}) diff --git a/tooling/v8-snapshot/vite.config.mjs b/tooling/v8-snapshot/vite.config.mjs new file mode 100644 index 000000000000..93a828e86ff2 --- /dev/null +++ b/tooling/v8-snapshot/vite.config.mjs @@ -0,0 +1,17 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + include: ['test/unit/**/*.vspec.ts'], + exclude: ['**/__snapshots__/**/*', '**/dist/**/*', '**/node_modules/**/*'], + reporters: [ + 'default', + ['junit', { suiteName: 'v8-snapshot tooling Unit Tests', outputFile: '/tmp/cypress/junit/v8-snapshot-test-results.xml' }], + ], + coverage: { + provider: 'v8', + reporter: ['lcovonly'], + exclude: ['**/__snapshots__/**/*', '**/dist/**/*', '**/node_modules/**/*', 'test/**/*', 'vite.config.mjs', 'cache/**/*'], + }, + }, +}) diff --git a/yarn.lock b/yarn.lock index 15593d552d4a..8f0c89d05078 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1402,7 +1402,7 @@ "@babel/highlight" "^7.24.7" picocolors "^1.0.0" -"@babel/code-frame@7.26.2", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.7": +"@babel/code-frame@7.26.2": version "7.26.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== @@ -1411,12 +1411,21 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.2.tgz#e41928bd33475305c586f6acbbb7e3ade7a6f7f5" - integrity sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.7", "@babel/code-frame@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" + integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== + dependencies: + "@babel/helper-validator-identifier" "^7.27.1" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.2", "@babel/compat-data@^7.27.2": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.27.3.tgz#cc49c2ac222d69b889bf34c795f537c0c6311111" + integrity sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw== -"@babel/core@7.25.2", "@babel/core@^7.0.0", "@babel/core@^7.18.9", "@babel/core@^7.21.3", "@babel/core@^7.23.3", "@babel/core@^7.24.5", "@babel/core@^7.25.2": +"@babel/core@7.25.2": version "7.25.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.2.tgz#ed8eec275118d7613e77a352894cd12ded8eba77" integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA== @@ -1437,6 +1446,27 @@ json5 "^2.2.3" semver "^6.3.1" +"@babel/core@^7.0.0", "@babel/core@^7.18.9", "@babel/core@^7.21.3", "@babel/core@^7.23.3", "@babel/core@^7.24.5", "@babel/core@^7.25.2": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.27.3.tgz#d7d05502bccede3cab36373ed142e6a1df554c2f" + integrity sha512-hyrN8ivxfvJ4i0fIJuV4EOlV0WDMz5Ui4StRTgVaAvWeiRCilXgwVvxJKtFQ3TKtHgJscB2YiXKGNJuVwhQMtA== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.27.3" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-module-transforms" "^7.27.3" + "@babel/helpers" "^7.27.3" + "@babel/parser" "^7.27.3" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.27.3" + "@babel/types" "^7.27.3" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/eslint-parser@7.25.1": version "7.25.1" resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.1.tgz#469cee4bd18a88ff3edbdfbd227bd20e82aa9b82" @@ -1446,7 +1476,7 @@ eslint-visitor-keys "^2.1.0" semver "^6.3.1" -"@babel/generator@7.25.0", "@babel/generator@^7.15.4", "@babel/generator@^7.15.8", "@babel/generator@^7.25.0", "@babel/generator@^7.5.0": +"@babel/generator@7.25.0": version "7.25.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.0.tgz#f858ddfa984350bc3d3b7f125073c9af6988f18e" integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw== @@ -1456,6 +1486,17 @@ "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" +"@babel/generator@^7.15.4", "@babel/generator@^7.15.8", "@babel/generator@^7.25.0", "@babel/generator@^7.27.3", "@babel/generator@^7.5.0": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.27.3.tgz#ef1c0f7cfe3b5fc8cbb9f6cc69f93441a68edefc" + integrity sha512-xnlJYj5zepml8NXtjkG0WquFUv8RskFqyFcVgTBp5k+NaA/8uw/K+OSVf8AMGw5e9HKP2ETd5xpK5MLZQD6b4Q== + dependencies: + "@babel/parser" "^7.27.3" + "@babel/types" "^7.27.3" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^3.0.2" + "@babel/helper-annotate-as-pure@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" @@ -1471,14 +1512,14 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.24.8", "@babel/helper-compilation-targets@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c" - integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.24.8", "@babel/helper-compilation-targets@^7.25.2", "@babel/helper-compilation-targets@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" + integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== dependencies: - "@babel/compat-data" "^7.25.2" - "@babel/helper-validator-option" "^7.24.8" - browserslist "^4.23.1" + "@babel/compat-data" "^7.27.2" + "@babel/helper-validator-option" "^7.27.1" + browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" @@ -1546,13 +1587,13 @@ "@babel/traverse" "^7.24.8" "@babel/types" "^7.24.8" -"@babel/helper-module-imports@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" - integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== +"@babel/helper-module-imports@^7.24.7", "@babel/helper-module-imports@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" + integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" "@babel/helper-module-imports@~7.22.15": version "7.22.15" @@ -1561,15 +1602,14 @@ dependencies: "@babel/types" "^7.22.15" -"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.25.0", "@babel/helper-module-transforms@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz#ee713c29768100f2776edf04d4eb23b8d27a66e6" - integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== +"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.25.0", "@babel/helper-module-transforms@^7.25.2", "@babel/helper-module-transforms@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz#db0bbcfba5802f9ef7870705a7ef8788508ede02" + integrity sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg== dependencies: - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-simple-access" "^7.24.7" - "@babel/helper-validator-identifier" "^7.24.7" - "@babel/traverse" "^7.25.2" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/traverse" "^7.27.3" "@babel/helper-optimise-call-expression@^7.24.7": version "7.24.7" @@ -1624,20 +1664,20 @@ dependencies: "@babel/types" "^7.24.7" -"@babel/helper-string-parser@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" - integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== +"@babel/helper-string-parser@^7.24.8", "@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== -"@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.24.7", "@babel/helper-validator-identifier@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" - integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== +"@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.24.7", "@babel/helper-validator-identifier@^7.25.9", "@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== -"@babel/helper-validator-option@^7.24.7", "@babel/helper-validator-option@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" - integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== +"@babel/helper-validator-option@^7.24.7", "@babel/helper-validator-option@^7.24.8", "@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== "@babel/helper-wrap-function@^7.25.0": version "7.25.0" @@ -1648,13 +1688,13 @@ "@babel/traverse" "^7.25.0" "@babel/types" "^7.25.0" -"@babel/helpers@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.0.tgz#e69beb7841cb93a6505531ede34f34e6a073650a" - integrity sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw== +"@babel/helpers@^7.25.0", "@babel/helpers@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.27.3.tgz#387d65d279290e22fe7a47a8ffcd2d0c0184edd0" + integrity sha512-h/eKy9agOya1IGuLaZ9tEUgz+uIRXcbtOhRtUyyMf8JFmn1iT13vnl/IGVWSkdOCG/pC57U4S1jnAabAavTMwg== dependencies: - "@babel/template" "^7.25.0" - "@babel/types" "^7.25.0" + "@babel/template" "^7.27.2" + "@babel/types" "^7.27.3" "@babel/highlight@^7.24.7": version "7.24.7" @@ -1671,13 +1711,20 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.6.tgz#043b9aa3c303c0722e5377fef9197f4cf1796549" integrity sha512-S/TSCcsRuCkmpUuoWijua0Snt+f3ewU/8spLo+4AXJCZfT0bVCzLD5MuOKdrx0mlAptbKzn5AdgEIIKXxXkz9Q== -"@babel/parser@7.25.3", "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.15.4", "@babel/parser@^7.15.8", "@babel/parser@^7.16.4", "@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.9", "@babel/parser@^7.24.4", "@babel/parser@^7.25.0", "@babel/parser@^7.25.3": +"@babel/parser@7.25.3": version "7.25.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.3.tgz#91fb126768d944966263f0657ab222a642b82065" integrity sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw== dependencies: "@babel/types" "^7.25.2" +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.15.4", "@babel/parser@^7.15.8", "@babel/parser@^7.16.4", "@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.9", "@babel/parser@^7.24.4", "@babel/parser@^7.25.0", "@babel/parser@^7.25.3", "@babel/parser@^7.25.4", "@babel/parser@^7.27.2", "@babel/parser@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.3.tgz#1b7533f0d908ad2ac545c4d05cbe2fb6dc8cfaaf" + integrity sha512-xyYxRj6+tLNDTWi0KCBcZ9V7yg3/lwL9DWh9Uwh/RIVlIfFidggcgxKX3GCXwCiswwcGRawBKbEg2LG/Y8eJhw== + dependencies: + "@babel/types" "^7.27.3" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.3": version "7.25.3" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz#dca427b45a6c0f5c095a1c639dfe2476a3daba7f" @@ -2527,14 +2574,14 @@ dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.23.9", "@babel/template@^7.24.7", "@babel/template@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" - integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== +"@babel/template@^7.23.9", "@babel/template@^7.24.7", "@babel/template@^7.25.0", "@babel/template@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" + integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/parser" "^7.25.0" - "@babel/types" "^7.25.0" + "@babel/code-frame" "^7.27.1" + "@babel/parser" "^7.27.2" + "@babel/types" "^7.27.1" "@babel/traverse@7.15.4": version "7.15.4" @@ -2551,16 +2598,16 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.18.9", "@babel/traverse@^7.23.9", "@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3": - version "7.25.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.3.tgz#f1b901951c83eda2f3e29450ce92743783373490" - integrity sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.18.9", "@babel/traverse@^7.23.9", "@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3", "@babel/traverse@^7.27.1", "@babel/traverse@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.3.tgz#8b62a6c2d10f9d921ba7339c90074708509cffae" + integrity sha512-lId/IfN/Ye1CIu8xG7oKBHXd2iNb2aW1ilPszzGcJug6M8RCKfVNcYhpI5+bMvFYjK7lXIM0R+a+6r8xhHp2FQ== dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.25.0" - "@babel/parser" "^7.25.3" - "@babel/template" "^7.25.0" - "@babel/types" "^7.25.2" + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.27.3" + "@babel/parser" "^7.27.3" + "@babel/template" "^7.27.2" + "@babel/types" "^7.27.3" debug "^4.3.1" globals "^11.1.0" @@ -2572,7 +2619,7 @@ "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" -"@babel/types@7.25.2", "@babel/types@^7.0.0", "@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.22.15", "@babel/types@^7.23.9", "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.4.4": +"@babel/types@7.25.2": version "7.25.2" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.2.tgz#55fb231f7dc958cd69ea141a4c2997e819646125" integrity sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q== @@ -2581,6 +2628,14 @@ "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" +"@babel/types@^7.0.0", "@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.22.15", "@babel/types@^7.23.9", "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.25.4", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.4.4": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.3.tgz#c0257bedf33aad6aad1f406d35c44758321eb3ec" + integrity sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@bahmutov/all-paths@1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@bahmutov/all-paths/-/all-paths-1.0.2.tgz#9ae0dcdf9022dd6e5e14d7fda3479e6a330d035b" @@ -2597,6 +2652,11 @@ check-more-types "2.24.0" lazy-ass "1.6.0" +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -4630,6 +4690,11 @@ resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b" integrity sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ== +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + "@jest/types@^26.3.0": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -4938,7 +5003,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.9": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -8819,6 +8884,24 @@ resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37" integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ== +"@vitest/coverage-v8@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-2.1.8.tgz#738527e6e79cef5004248452527e272e0df12284" + integrity sha512-2Y7BPlKH18mAZYAW1tYByudlCYrQyl5RGvnnDYJKW5tCiO5qg3KSAy3XAxcxKz900a0ZXxWtKrMuZLe3lKBpJw== + dependencies: + "@ampproject/remapping" "^2.3.0" + "@bcoe/v8-coverage" "^0.2.3" + debug "^4.3.7" + 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.12" + magicast "^0.3.5" + std-env "^3.8.0" + test-exclude "^7.0.1" + tinyrainbow "^1.2.0" + "@vitest/expect@2.1.4": version "2.1.4" resolved "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.4.tgz#48f4f53a01092a3bdc118cff245f79ef388bdd8e" @@ -11257,7 +11340,7 @@ browserslist-to-esbuild@^2.1.1: dependencies: meow "^13.0.0" -browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.23.0, browserslist@^4.23.1, browserslist@^4.23.3, browserslist@^4.24.0: +browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.23.0, browserslist@^4.23.3, browserslist@^4.24.0: version "4.24.4" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b" integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A== @@ -17521,7 +17604,7 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^10.2.2, glob@^10.3.10, glob@^10.3.12, glob@^10.3.3, glob@^10.3.7, glob@^10.4.2: +glob@^10.2.2, glob@^10.3.10, glob@^10.3.12, glob@^10.3.3, glob@^10.3.7, glob@^10.4.1, glob@^10.4.2: version "10.4.5" resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== @@ -18367,7 +18450,7 @@ html-entities@^2.4.0: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.5.2.tgz#201a3cf95d3a15be7099521620d19dfb4f65359f" integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA== -html-escaper@^2.0.2: +html-escaper@^2.0.0, html-escaper@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== @@ -19827,6 +19910,37 @@ issue-parser@^6.0.0: lodash.isstring "^4.0.1" lodash.uniqby "^4.7.0" +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-report@^3.0.0, istanbul-lib-report@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz#acaef948df7747c8eb5fbf1265cb980f6353a441" + integrity sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A== + dependencies: + "@jridgewell/trace-mapping" "^0.3.23" + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + +istanbul-reports@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" + integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + istextorbinary@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-6.0.0.tgz#bc6e7541006bc203feffe16628d0a72893b2ad54" @@ -20068,6 +20182,11 @@ jsesc@2.5.2, jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" @@ -21533,7 +21652,16 @@ magic-string@^0.30.10, magic-string@^0.30.11, magic-string@^0.30.12: dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" -make-dir@4.0.0: +magicast@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.5.tgz#8301c3c7d66704a0771eb1bad74274f0ec036739" + integrity sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ== + dependencies: + "@babel/parser" "^7.25.4" + "@babel/types" "^7.25.4" + source-map-js "^1.2.0" + +make-dir@4.0.0, make-dir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== @@ -29632,6 +29760,15 @@ terser@5.39.0, terser@^5.10.0, terser@^5.31.1: commander "^2.20.0" source-map-support "~0.5.20" +test-exclude@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-7.0.1.tgz#20b3ba4906ac20994e275bbcafd68d510264c2a2" + integrity sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^10.4.1" + minimatch "^9.0.4" + text-decoder@^1.1.0: version "1.1.1" resolved "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz#5df9c224cebac4a7977720b9f083f9efa1aefde8" @@ -31364,7 +31501,7 @@ vitest@2.1.4: vite-node "2.1.4" why-is-node-running "^2.3.0" -vitest@^2.1.8: +vitest@2.1.8, vitest@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.8.tgz#2e6a00bc24833574d535c96d6602fb64163092fa" integrity sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==