diff --git a/.gitignore b/.gitignore
index 486eb366..c76a91ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,5 @@ yarn.lock
vite.config.js.timestamp-*
/packages/create-svelte/template/CHANGELOG.md
.test-tmp
+.outputs-e2e
+.outputs-snapshots
diff --git a/.prettierignore b/.prettierignore
index ea3293fe..5880e91c 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,2 +1,3 @@
packages/core/tests/**/input.*
packages/core/tests/**/output.*
+packages/adder-tests/_snapshots
diff --git a/community-adder-template/package.json b/community-adder-template/package.json
index 91f9b34c..44c49d78 100644
--- a/community-adder-template/package.json
+++ b/community-adder-template/package.json
@@ -13,13 +13,17 @@
],
"scripts": {
"start": "sv add -C temp --community file:../",
- "create-temp": "sv create temp --check-types typescript --template skeleton --no-adders --no-install"
+ "create-temp": "sv create temp --check-types typescript --template skeleton --no-adders --no-install",
+ "dev:test": "vitest",
+ "test": "vitest run"
},
"dependencies": {
"@sveltejs/cli-core": "workspace:*"
},
"devDependencies": {
- "sv": "workspace:*"
+ "@sveltejs/adder-testing-library": "workspace:*",
+ "sv": "workspace:*",
+ "vitest": "^2.1.2"
},
"files": [
"src",
diff --git a/community-adder-template/src/index.js b/community-adder-template/src/index.js
index 9e4348aa..826a7261 100644
--- a/community-adder-template/src/index.js
+++ b/community-adder-template/src/index.js
@@ -3,14 +3,14 @@ import { imports } from '@sveltejs/cli-core/js';
import { parseScript } from '@sveltejs/cli-core/parsers';
export const options = defineAdderOptions({
- demo: {
- question: 'Do you want to use a demo?',
- type: 'boolean',
- default: false
- }
+ demo: {
+ question: 'Do you want to use a demo?',
+ type: 'boolean',
+ default: false
+ }
});
-export const adder = defineAdder({
+export default defineAdder({
id: 'community-adder-template',
environments: { kit: true, svelte: true },
options,
diff --git a/community-adder-template/tests/end2end.js b/community-adder-template/tests/end2end.js
new file mode 100644
index 00000000..706ae11d
--- /dev/null
+++ b/community-adder-template/tests/end2end.js
@@ -0,0 +1,13 @@
+import { test, describe, beforeAll, afterAll } from 'vitest';
+import { runEndToEndTests } from '@sveltejs/adder-testing-library';
+import adder from '../src/index.js';
+import { tests } from './tests.js';
+
+runEndToEndTests(
+ '.outputs-e2e',
+ [{ config: adder, tests }],
+ describe,
+ test.concurrent,
+ beforeAll,
+ afterAll
+);
diff --git a/community-adder-template/tests/snapshot.js b/community-adder-template/tests/snapshot.js
new file mode 100644
index 00000000..cadecc66
--- /dev/null
+++ b/community-adder-template/tests/snapshot.js
@@ -0,0 +1,14 @@
+import { test, describe, beforeAll, afterAll } from 'vitest';
+import { runSnapshotTests } from '@sveltejs/adder-testing-library';
+import adder from '../src/index.js';
+import { tests } from './tests.js';
+
+runSnapshotTests(
+ '.outputs-snapshots',
+ '_snapshot',
+ [{ config: adder, tests }],
+ describe,
+ test.concurrent,
+ beforeAll,
+ afterAll
+);
diff --git a/community-adder-template/tests/tests.js b/community-adder-template/tests/tests.js
index 373c556b..7bbefcc2 100644
--- a/community-adder-template/tests/tests.js
+++ b/community-adder-template/tests/tests.js
@@ -2,9 +2,20 @@ import { defineAdderTests } from '@sveltejs/cli-core';
import { options } from '../src/index.js';
export const tests = defineAdderTests({
- files: [],
options,
optionValues: [{ demo: true }],
+ files: [
+ {
+ name: ({ kit }) => `${kit?.routesDirectory}/+page.svelte`,
+ condition: ({ kit }) => Boolean(kit),
+ content: () => '
'
+ },
+ {
+ name: () => 'src/App.svelte',
+ condition: ({ kit }) => !kit,
+ content: () => ''
+ }
+ ],
tests: [
{
name: 'demo test',
diff --git a/community-adder-template/vitest.config.ts b/community-adder-template/vitest.config.ts
new file mode 100644
index 00000000..e8faff1d
--- /dev/null
+++ b/community-adder-template/vitest.config.ts
@@ -0,0 +1,11 @@
+import { defineConfig, type UserConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ include: ['./tests/**/*.js'],
+ exclude: ['./tests/tests.js'],
+ testTimeout: 1000 * 60 * 2, // 2 minutes
+ hookTimeout: 1000 * 60 * 3, // 3 minutes
+ pool: 'threads'
+ }
+}) as UserConfig;
diff --git a/eslint.config.js b/eslint.config.js
index c6f1bbf0..f128499f 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -31,6 +31,8 @@ export default [
'.test-tmp/**/*',
'**/dist/*',
'packages/**/tests/**/{output,input}.ts',
+ 'packages/**/.outputs-*/**/*',
+ 'packages/**/_snapshots/**/*',
'rollup.config.js'
]
}
diff --git a/package.json b/package.json
index 3678c39b..2fce6314 100644
--- a/package.json
+++ b/package.json
@@ -1,17 +1,20 @@
{
"name": "sv-monorepo",
- "version": "0.0.1",
- "description": "monorepo for sv and friends",
"private": true,
+ "version": "0.0.1",
"type": "module",
+ "description": "monorepo for sv and friends",
+ "engines": {
+ "pnpm": "^9.0.0"
+ },
"scripts": {
+ "build": "rollup -c",
+ "changeset:publish": "changeset publish",
"check": "pnpm --parallel check",
- "lint": "pnpm --parallel lint && eslint --cache --cache-location node_modules/.eslintcache",
- "format": "pnpm --parallel format",
"dev": "rollup --config --watch",
- "build": "rollup -c",
- "test": "pnpm --parallel test",
- "changeset:publish": "changeset publish"
+ "format": "pnpm --parallel format",
+ "lint": "pnpm --parallel lint && eslint --cache --cache-location node_modules/.eslintcache",
+ "test": "pnpm --parallel test"
},
"devDependencies": {
"@changesets/cli": "^2.27.9",
@@ -23,7 +26,7 @@
"@sveltejs/eslint-config": "^8.1.0",
"@svitejs/changesets-changelog-github-compact": "^1.1.0",
"@types/node": "^22.3.0",
- "@vitest/ui": "^2.0.5",
+ "@vitest/ui": "^2.1.2",
"eslint": "^9.10.0",
"magic-string": "^0.30.11",
"prettier": "^3.3.3",
@@ -37,10 +40,7 @@
"typescript": "^5.6.2",
"typescript-eslint": "^8.5.0",
"unplugin-isolated-decl": "^0.6.5",
- "vitest": "^2.0.5"
+ "vitest": "^2.1.2"
},
- "packageManager": "pnpm@9.7.0",
- "engines": {
- "pnpm": "^9.0.0"
- }
+ "packageManager": "pnpm@9.7.0"
}
diff --git a/packages/adder-testing-library/browser.ts b/packages/adder-testing-library/browser.ts
new file mode 100644
index 00000000..0d54ca0f
--- /dev/null
+++ b/packages/adder-testing-library/browser.ts
@@ -0,0 +1,27 @@
+import { chromium, type Browser, type Page } from 'playwright';
+
+let browser: Browser;
+const headless = true;
+
+export async function startBrowser(): Promise {
+ browser = await chromium.launch({ headless });
+ console.log('browser started');
+}
+
+export async function openPage(url: string): Promise {
+ const page = await browser.newPage();
+
+ await page.goto(url, { timeout: 60_000 });
+ await page.waitForLoadState('networkidle');
+
+ // always use light mode. Otherwise the tests might depend on the OS setting
+ // of each developer and thus leads to inconsistent test results.
+ await page.emulateMedia({ colorScheme: 'light' });
+
+ return page;
+}
+
+export async function stopBrowser(): Promise {
+ if (!browser) return;
+ await browser.close();
+}
diff --git a/packages/adder-testing-library/index.ts b/packages/adder-testing-library/index.ts
new file mode 100644
index 00000000..f9778fe4
--- /dev/null
+++ b/packages/adder-testing-library/index.ts
@@ -0,0 +1,168 @@
+import type { AdderTestConfig, AdderWithoutExplicitArgs, TestType } from '@sveltejs/cli-core';
+import path from 'node:path';
+import fs from 'node:fs';
+import process from 'node:process';
+import { openPage, stopBrowser } from './browser.ts';
+import {
+ generateTestCases,
+ prepareEndToEndTests,
+ prepareSnapshotTests,
+ runAdder,
+ startDevServer,
+ stopDevServer,
+ type TestCase
+} from './utils.ts';
+import { startTests } from './tests.ts';
+
+const templatesDirectoryName = 'templates';
+const addersDirectoryName = 'adders';
+
+export type AdderWithTests = {
+ config: AdderWithoutExplicitArgs;
+ tests: AdderTestConfig>;
+};
+
+export function runEndToEndTests(
+ outputDirectory: string,
+ adders: AdderWithTests[],
+ describe: (name: string, testFactory: () => void) => void,
+ test: (name: string, testFunction: (args: TestArguments) => Promise | void) => void,
+ beforeAll: (fn: () => void) => void,
+ afterAll: (fn: () => void) => void
+): void {
+ const outputPath = path.join(process.cwd(), outputDirectory);
+ const templatesPath = path.join(outputPath, templatesDirectoryName);
+ const addersOutputPath = path.join(outputPath, addersDirectoryName);
+ const testCases = generateTestCases(adders, addersOutputPath, { ignoreEmptyTests: true });
+
+ runTests(adders, testCases, 'end2end', {
+ describe,
+ test,
+ beforeAll,
+ afterAll,
+ prepare: async () => {
+ await prepareEndToEndTests(outputPath, templatesPath, addersOutputPath, adders, testCases);
+ },
+ run: async (testCase, adder) => {
+ const cmd = adder.tests!.command ?? 'dev';
+ const { url, devServer } = await startDevServer(testCase.cwd, cmd);
+ const page = await openPage(url);
+
+ try {
+ const errorOcurred = await page.$('vite-error-overlay');
+ if (errorOcurred)
+ throw new Error('Dev server failed to start correctly. Vite errors present');
+
+ await startTests(page, adder, testCase.options);
+ } finally {
+ await page.close();
+ await stopDevServer(devServer);
+ }
+ },
+ tearDown: async () => {
+ await stopBrowser();
+ }
+ });
+}
+
+type TestArguments = {
+ expect: (content: string) => {
+ toMatchFileSnapshot: (filePath: string, message?: string) => void;
+ };
+};
+
+export function runSnapshotTests(
+ outputDirectory: string,
+ snapshotDirectory: string,
+ adders: AdderWithTests[],
+ describe: (name: string, testFactory: () => void) => void,
+ test: (name: string, testFunction: (args: TestArguments) => Promise | void) => void,
+ beforeAll: (fn: () => void) => void,
+ afterAll: (fn: () => void) => void
+): void {
+ const outputPath = path.join(process.cwd(), outputDirectory);
+ const templatesPath = path.join(outputPath, templatesDirectoryName);
+ const addersOutputPath = path.join(outputPath, addersDirectoryName);
+ const testCases = generateTestCases(adders, addersOutputPath, { ignoreEmptyTests: false });
+
+ runTests(adders, testCases, 'snapshot', {
+ describe,
+ test,
+ beforeAll,
+ afterAll,
+ prepare: async () => {
+ await prepareSnapshotTests(outputPath, templatesPath, addersOutputPath, testCases);
+ },
+ run: (testCase, _, { expect }) => {
+ const filesToFormat = runAdder(testCase.adder, testCase.cwd, testCase.options, adders);
+
+ for (const changedFile of filesToFormat) {
+ const fullFilePath = path.join(testCase.cwd, changedFile);
+ const content = fs.readFileSync(fullFilePath).toString();
+
+ const relativeTestCasePath = testCase.cwd.replace(addersOutputPath, '');
+ const snapshotPath = path.join(
+ process.cwd(),
+ snapshotDirectory,
+ relativeTestCasePath,
+ changedFile
+ );
+
+ expect(content).toMatchFileSnapshot(snapshotPath, changedFile);
+ }
+ },
+ tearDown: async () => {}
+ });
+}
+
+function runTests(
+ adders: AdderWithTests[],
+ testCases: Map,
+ testType: TestType,
+ options: {
+ describe: (name: string, testFactory: () => void) => void;
+ test: (name: string, testFunction: (args: TestArguments) => Promise | void) => void;
+ beforeAll: (fn: () => void) => void;
+ afterAll: (fn: () => void) => void;
+ prepare: () => Promise;
+ run: (testCase: TestCase, adder: AdderWithTests, args: TestArguments) => Promise | void;
+ tearDown: () => Promise;
+ }
+) {
+ options.beforeAll(async () => {
+ await options.prepare();
+ });
+
+ for (const [adderId, adderTestCases] of testCases) {
+ options.describe(adderId, () => {
+ const adder = adders.find((x) => x.config.id == adderId)!;
+ if (!adder) throw new Error('failed to find ' + adderId);
+ const adderTestDetails = adder.tests!;
+ options.beforeAll(async () => {
+ if (adderTestDetails.beforeAll) await adderTestDetails.beforeAll(testType);
+ });
+
+ for (const testCase of adderTestCases) {
+ options.test(testCase.testName, async (testArgs) => {
+ if (!adder.tests) return;
+
+ if (adder.tests.beforeEach) await adder.tests.beforeEach(testCase.cwd, testType);
+
+ try {
+ await options.run(testCase, adder, testArgs);
+ } finally {
+ if (adder.tests.afterEach) await adder.tests.afterEach(testCase.cwd, testType);
+ }
+ });
+ }
+
+ options.afterAll(async () => {
+ if (adderTestDetails.afterAll) await adderTestDetails.afterAll(testType);
+ });
+ });
+ }
+
+ options.afterAll(async () => {
+ await options.tearDown();
+ });
+}
diff --git a/packages/adder-testing-library/package.json b/packages/adder-testing-library/package.json
new file mode 100644
index 00000000..1bbdb47e
--- /dev/null
+++ b/packages/adder-testing-library/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "@sveltejs/adder-testing-library",
+ "private": true,
+ "version": "1.0.0",
+ "type": "module",
+ "scripts": {
+ "check": "tsc",
+ "format": "pnpm lint --write",
+ "postinstall": "pnpm exec playwright install chromium",
+ "lint": "prettier --check . --config ../../.prettierrc --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore"
+ },
+ "files": [
+ "dist"
+ ],
+ "exports": {
+ ".": {
+ "types": "./dist/index.d.ts",
+ "default": "./dist/index.js"
+ }
+ },
+ "dependencies": {
+ "@sveltejs/cli-core": "workspace:*",
+ "playwright": "^1.44.1",
+ "sv": "workspace:*",
+ "terminate": "^2.8.0",
+ "tiged": "3.0.0-rc.0"
+ }
+}
diff --git a/packages/adder-testing-library/tests.ts b/packages/adder-testing-library/tests.ts
new file mode 100644
index 00000000..4561d4b9
--- /dev/null
+++ b/packages/adder-testing-library/tests.ts
@@ -0,0 +1,98 @@
+import type { OptionValues, Question, Tests } from '@sveltejs/cli-core';
+import type { Page } from 'playwright';
+import type { AdderWithTests } from './index.ts';
+
+export async function startTests(
+ page: Page,
+ adder: AdderWithTests,
+ options: OptionValues>
+): Promise {
+ const tests: Tests = {
+ expectProperty: async (selector, property, expectedValue) => {
+ await expectProperty(page, selector, property, expectedValue);
+ },
+ elementExists: async (selector) => {
+ await elementExists(page, selector);
+ },
+ click: async (selector, path) => {
+ await click(page, selector, path);
+ },
+ expectUrlPath: (path) => {
+ expectUrlPath(page, path);
+ }
+ };
+
+ await executeAdderTests(adder, tests, options);
+}
+
+async function executeAdderTests(
+ adder: AdderWithTests,
+ testMethods: Tests,
+ options: OptionValues>
+) {
+ if (!adder.tests || adder.tests.tests.length == 0)
+ throw new Error('Cannot test adder without tests!');
+
+ for (const test of adder.tests.tests) {
+ if (test.condition && !test.condition(options)) continue;
+
+ await test.run(testMethods);
+ }
+}
+
+async function elementExists(page: Page, selector: string) {
+ const elementToCheck = await page.$(selector);
+ if (!elementToCheck) {
+ throw new Error('No element found for selector ' + selector);
+ }
+
+ return elementToCheck;
+}
+
+/**
+ * @param path If the click action results in a navigation, provide the expected path
+ *
+ * @example
+ * ```js
+ * await click(page, "a.some-link", "/some-path");
+ * ```
+ */
+async function click(page: Page, selector: string, path?: string) {
+ await elementExists(page, selector);
+
+ await page.click(selector);
+
+ if (path) {
+ await page.waitForURL((url) => url.pathname === path);
+ }
+}
+
+function expectUrlPath(page: Page, path: string) {
+ const url = new URL(page.url());
+
+ if (url.pathname !== path) {
+ throw new Error(`Found path ${url.pathname} but expected ${path}!`);
+ }
+}
+
+async function expectProperty(
+ page: Page,
+ selector: string,
+ property: string,
+ expectedValue: string
+) {
+ const elementToCheck = await elementExists(page, selector);
+
+ const computedStyle = await page.evaluate(
+ ([element, pV]) => window.getComputedStyle(element).getPropertyValue(pV),
+ [elementToCheck, property] as const
+ );
+
+ if (computedStyle !== expectedValue) {
+ throw new Error(
+ `Expected '${expectedValue}' but got '${computedStyle}' for selector '${selector}'`
+ );
+ }
+
+ return computedStyle;
+}
diff --git a/packages/adder-testing-library/tsconfig.json b/packages/adder-testing-library/tsconfig.json
new file mode 100644
index 00000000..a1fcf6c9
--- /dev/null
+++ b/packages/adder-testing-library/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "checkJs": false,
+ "isolatedDeclarations": true,
+ "declaration": true
+ }
+}
diff --git a/packages/adder-testing-library/utils.ts b/packages/adder-testing-library/utils.ts
new file mode 100644
index 00000000..fd92a4b8
--- /dev/null
+++ b/packages/adder-testing-library/utils.ts
@@ -0,0 +1,311 @@
+import { execSync, spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';
+import path from 'node:path';
+import fs from 'node:fs';
+import tiged from 'tiged';
+import terminate from 'terminate';
+import { create, createOrUpdateFiles, createWorkspace, installPackages } from 'sv';
+import { type OptionValues, type Question } from '@sveltejs/cli-core';
+import { startBrowser } from './browser.ts';
+import type { AdderWithTests } from './index.ts';
+
+export type TestCase = {
+ testName: string;
+ template: string;
+ adder: AdderWithTests;
+ options: OptionValues>;
+ cwd: string;
+};
+
+export const ProjectTypes = {
+ Svelte_JS: 'svelte-js',
+ Svelte_TS: 'svelte-ts',
+ Kit_JS: 'kit-js',
+ Kit_JS_Comments: 'kit-js-comments',
+ Kit_TS: 'kit-ts'
+};
+export const ProjectTypesList: string[] = Object.values(ProjectTypes);
+
+export async function forceKill(devServer: ChildProcessWithoutNullStreams): Promise {
+ return new Promise((resolve) => {
+ if (!devServer.pid) return;
+
+ // just killing the process was not enough, because the process itself
+ // spawns child process, that also need to be killed!
+ terminate(devServer.pid, () => {
+ resolve();
+ });
+ });
+}
+
+export async function downloadProjectTemplates(outputPath: string): Promise {
+ for (const templateType of ProjectTypesList) {
+ const templateOutputPath = path.join(outputPath, templateType);
+
+ if (templateType.includes('kit')) {
+ create(templateOutputPath, {
+ name: templateType,
+ template: 'minimal',
+ types:
+ templateType == ProjectTypes.Kit_TS
+ ? 'typescript'
+ : templateType == ProjectTypes.Kit_JS_Comments
+ ? 'checkjs'
+ : 'none'
+ });
+ } else {
+ const templateName =
+ templateType == ProjectTypes.Svelte_TS ? 'template-svelte-ts' : 'template-svelte';
+
+ const emitter = tiged(`vitejs/vite/packages/create-vite/${templateName}`, {
+ cache: false,
+ force: true,
+ verbose: false
+ });
+
+ await emitter.clone(templateOutputPath);
+ }
+ }
+}
+
+export async function startDevServer(
+ output: string,
+ command: string
+): Promise<{ url: string; devServer: ChildProcessWithoutNullStreams }> {
+ try {
+ const program = spawn('pnpm', ['run', command], { stdio: 'pipe', shell: true, cwd: output });
+
+ return await new Promise((resolve) => {
+ program.stdout?.on('data', (data: Buffer) => {
+ const value = data.toString();
+
+ // extract dev server url from console output
+ const regexUnicode = /[^\x20-\xaf]+/g;
+ const withoutUnicode = value.replace(regexUnicode, '');
+
+ const regexUnicodeDigits = /\[[0-9]{1,2}m/g;
+ const withoutColors = withoutUnicode.replace(regexUnicodeDigits, '');
+
+ const regexUrl = /http:\/\/[^:\s]+:[0-9]+\//g;
+ const urls = withoutColors.match(regexUrl);
+
+ if (urls && urls.length > 0) {
+ const url = urls[0];
+ resolve({ url, devServer: program });
+ }
+ });
+ });
+ } catch (error) {
+ const typedError = error as Error;
+ throw new Error('Failed to start dev server' + typedError.message);
+ }
+}
+
+export async function stopDevServer(devServer: ChildProcessWithoutNullStreams): Promise {
+ if (!devServer.pid) return;
+
+ await forceKill(devServer);
+}
+
+export function generateTestCases(
+ adders: AdderWithTests[],
+ addersOutputPath: string,
+ options: { ignoreEmptyTests: boolean }
+): Map {
+ const testCases = new Map();
+ for (const adder of adders) {
+ const adderId = adder.config.id;
+ const adderTestCases: TestCase[] = [];
+ const testData = adder.tests;
+ if (!testData || !testData.tests || (options.ignoreEmptyTests && testData.tests.length == 0))
+ continue;
+
+ for (const template of ProjectTypesList) {
+ const environments = adder.config.environments;
+ if (
+ (!environments.kit && template.includes('kit')) ||
+ (!environments.svelte && template.includes('svelte'))
+ ) {
+ continue;
+ }
+
+ const optionsCombinations = testData.optionValues;
+ // if list if empty, add empty options so that one testcase gets run
+ if (optionsCombinations.length == 0) optionsCombinations.push({});
+
+ for (const options of optionsCombinations) {
+ let optionDirectoryName = Object.entries(options)
+ .map(([key, value]) => `${key}=${value}`)
+ .join('+');
+ if (!optionDirectoryName) optionDirectoryName = 'default';
+ const cwd = path.join(addersOutputPath, adderId, template, optionDirectoryName);
+ const testName = `${adder.config.id} / ${template} / ${JSON.stringify(options)}`;
+
+ const testCase: TestCase = {
+ testName,
+ adder,
+ options,
+ template,
+ cwd
+ };
+
+ adderTestCases.push(testCase);
+ }
+ }
+
+ testCases.set(adderId, adderTestCases);
+ }
+ return testCases;
+}
+
+export async function prepareEndToEndTests(
+ outputPath: string,
+ templatesPath: string,
+ addersPath: string,
+ adders: AdderWithTests[],
+ testCases: Map
+): Promise {
+ console.log('deleting old files');
+ // only delete adders and templates directory. Trying to delete `node_modules`
+ // typically fails because some `esbuild` binary is locked
+ fs.rmSync(addersPath, { recursive: true, force: true });
+ fs.rmSync(templatesPath, { recursive: true, force: true });
+
+ fs.mkdirSync(outputPath, { recursive: true });
+
+ console.log('downloading project templates');
+ await downloadProjectTemplates(templatesPath);
+
+ const dirs: string[] = [];
+ for (const type of Object.values(ProjectTypes)) {
+ dirs.push(...adders.map((a) => ` - 'adders/${a.config.id}/${type}/*'`));
+ }
+
+ const pnpmWorkspace = `packages:\n${dirs.join('\n')}\n`;
+ fs.writeFileSync(path.join(outputPath, 'pnpm-workspace.yaml'), pnpmWorkspace, {
+ encoding: 'utf8'
+ });
+
+ const testRootPkgJson = JSON.stringify({ name: 'test-root', version: '0.0.0', type: 'module' });
+ fs.writeFileSync(path.join(outputPath, 'package.json'), testRootPkgJson, {
+ encoding: 'utf8'
+ });
+
+ console.log('executing adders');
+ for (const adderTestCases of testCases.values()) {
+ const applyAdderTasks = [];
+ for (const testCase of adderTestCases) {
+ fs.mkdirSync(testCase.cwd, { recursive: true });
+
+ // copy template into working directory
+ const templatePath = path.join(templatesPath, testCase.template);
+ fs.cpSync(templatePath, testCase.cwd, { recursive: true });
+
+ applyAdderTasks.push(runAdder(testCase.adder, testCase.cwd, testCase.options, adders));
+ }
+
+ await Promise.all(applyAdderTasks);
+ }
+
+ console.log('preparing test files');
+ for (const adderTestCases of testCases.values()) {
+ for (const testCase of adderTestCases) {
+ const workspace = createWorkspace({ cwd: testCase.cwd });
+ workspace.options = testCase.options;
+ createOrUpdateFiles(testCase.adder.tests?.files ?? [], workspace);
+ }
+ }
+
+ console.log('installing dependencies');
+ execSync('pnpm install', { cwd: outputPath, stdio: 'pipe' });
+
+ await startBrowser();
+
+ console.log('start testing');
+}
+
+export async function prepareSnapshotTests(
+ outputPath: string,
+ templatesPath: string,
+ addersPath: string,
+ testCases: Map
+): Promise {
+ console.log('deleting old files');
+ // only delete adders and templates directory. Trying to delete `node_modules`
+ // typically fails because some `esbuild` binary is locked
+ fs.rmSync(addersPath, { recursive: true, force: true });
+ fs.rmSync(templatesPath, { recursive: true, force: true });
+
+ fs.mkdirSync(outputPath, { recursive: true });
+
+ console.log('downloading project templates');
+ await downloadProjectTemplates(templatesPath);
+
+ console.log('preparing adder templates');
+ // create all relevant directories with the templates
+ for (const adderTestCases of testCases.values()) {
+ for (const testCase of adderTestCases) {
+ fs.mkdirSync(testCase.cwd, { recursive: true });
+
+ // copy template into working directory
+ const templatePath = path.join(templatesPath, testCase.template);
+ fs.cpSync(templatePath, testCase.cwd, { recursive: true });
+ }
+ }
+}
+
+export function runAdder(
+ adder: AdderWithTests,
+ cwd: string,
+ options: OptionValues>,
+ adders: AdderWithTests[]
+): Set {
+ const { config } = adder;
+ const workspace = createWorkspace({ cwd });
+
+ workspace.options = options;
+
+ const filesToFormat = new Set();
+
+ // execute adders
+ if (config.dependsOn) {
+ for (const dependencyAdderId of config.dependsOn) {
+ const dependencyAdder = adders.find((x) => x.config.id == dependencyAdderId);
+
+ if (!dependencyAdder)
+ throw new Error(
+ `failed to find required dependency '${dependencyAdderId}' of adder ${adder.config.id}`
+ );
+
+ // apply default adder options
+ const options: Record = {};
+ for (const [key, question] of Object.entries(dependencyAdder.config.options)) {
+ options[key] = question.default;
+ }
+
+ runAdder(dependencyAdder, cwd, options as OptionValues>, adders);
+ }
+ }
+
+ const pkgPath = installPackages(config, workspace);
+ filesToFormat.add(pkgPath);
+ const changedFiles = createOrUpdateFiles(config.files, workspace);
+ changedFiles.forEach((file) => filesToFormat.add(file));
+
+ if (config.scripts && config.scripts.length > 0) {
+ for (const script of config.scripts) {
+ if (script.condition?.(workspace) === false) continue;
+
+ try {
+ execSync('pnpx ' + script.args.join(' '), {
+ cwd: workspace.cwd,
+ stdio: 'pipe'
+ });
+ } catch (error) {
+ const typedError = error as Error;
+ throw new Error(`Failed to execute scripts '${script.description}': ` + typedError.message);
+ }
+ }
+ }
+
+ return filesToFormat;
+}
diff --git a/packages/adder-tests/common.ts b/packages/adder-tests/common.ts
new file mode 100644
index 00000000..0e1cbb94
--- /dev/null
+++ b/packages/adder-tests/common.ts
@@ -0,0 +1,12 @@
+import { getAdderDetails, officialAdders } from '@sveltejs/adders';
+
+export async function getAdderTestDetails() {
+ return Promise.all(
+ officialAdders.map(async (x) => {
+ return {
+ config: getAdderDetails(x.id),
+ tests: (await import(`../adders/${x.id}/tests.ts`)).tests
+ };
+ })
+ );
+}
diff --git a/packages/adder-tests/package.json b/packages/adder-tests/package.json
new file mode 100644
index 00000000..33378254
--- /dev/null
+++ b/packages/adder-tests/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "@sveltejs/adder-tests",
+ "private": true,
+ "version": "1.0.0",
+ "type": "module",
+ "scripts": {
+ "check": "tsc",
+ "format": "pnpm lint --write",
+ "lint": "prettier --check . --config ../../.prettierrc --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore",
+ "test": "vitest run",
+ "test:ui": "vitest --ui"
+ },
+ "dependencies": {
+ "@sveltejs/adder-testing-library": "workspace:*",
+ "@sveltejs/adders": "workspace:*"
+ }
+}
diff --git a/packages/adder-tests/tests/official/end2end.ts b/packages/adder-tests/tests/official/end2end.ts
new file mode 100644
index 00000000..f780235d
--- /dev/null
+++ b/packages/adder-tests/tests/official/end2end.ts
@@ -0,0 +1,7 @@
+import { test, describe, beforeAll, afterAll } from 'vitest';
+import { getAdderTestDetails } from '../../common.ts';
+import { runEndToEndTests } from '@sveltejs/adder-testing-library';
+
+const adders = await getAdderTestDetails();
+
+runEndToEndTests('.outputs-e2e', adders, describe, test.concurrent, beforeAll, afterAll);
diff --git a/packages/adder-tests/tests/official/snapshots.ts b/packages/adder-tests/tests/official/snapshots.ts
new file mode 100644
index 00000000..bf98d8b6
--- /dev/null
+++ b/packages/adder-tests/tests/official/snapshots.ts
@@ -0,0 +1,15 @@
+import { test, describe, beforeAll, afterAll } from 'vitest';
+import { runSnapshotTests } from '@sveltejs/adder-testing-library';
+import { getAdderTestDetails } from '../../common.ts';
+
+const adders = await getAdderTestDetails();
+
+runSnapshotTests(
+ '.outputs-snapshots',
+ '_snapshots',
+ adders,
+ describe,
+ test.concurrent,
+ beforeAll,
+ afterAll
+);
diff --git a/packages/adder-tests/vitest.config.ts b/packages/adder-tests/vitest.config.ts
new file mode 100644
index 00000000..facb0b3d
--- /dev/null
+++ b/packages/adder-tests/vitest.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig, type UserConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ include: ['./tests/**/*.ts'],
+ testTimeout: 1000 * 60 * 2, // 2 minutes
+ hookTimeout: 1000 * 60 * 3, // 3 minutes
+ pool: 'threads'
+ }
+}) as UserConfig;
diff --git a/packages/adders/_config/index.ts b/packages/adders/_config/index.ts
index 80b647a8..fd4d3c16 100644
--- a/packages/adders/_config/index.ts
+++ b/packages/adders/_config/index.ts
@@ -1,2 +1,2 @@
-export { officialAdders, getAdderDetails } from './official.ts';
+export { officialAdders, getAdderDetails, getAdderTestDetails } from './official.ts';
export { getCommunityAdder, communityAdderIds } from './community.ts';
diff --git a/packages/adders/drizzle/docker-compose.yml b/packages/adders/drizzle/docker-compose.yml
new file mode 100644
index 00000000..f6f5e0a7
--- /dev/null
+++ b/packages/adders/drizzle/docker-compose.yml
@@ -0,0 +1,20 @@
+services:
+ db-postgres:
+ image: postgres
+ restart: always
+ shm_size: 128mb
+ ports:
+ - 5432:5432
+ environment:
+ POSTGRES_USER: root
+ POSTGRES_PASSWORD: mysecretpassword
+ POSTGRES_DB: local
+ db-mysql:
+ image: mysql
+ restart: always
+ shm_size: 128mb
+ ports:
+ - 3306:3306
+ environment:
+ MYSQL_ROOT_PASSWORD: mysecretpassword
+ MYSQL_DATABASE: local
diff --git a/packages/adders/drizzle/index.ts b/packages/adders/drizzle/index.ts
index f3174054..5e48fb26 100644
--- a/packages/adders/drizzle/index.ts
+++ b/packages/adders/drizzle/index.ts
@@ -76,45 +76,49 @@ export default defineAdder({
name: 'mysql2',
version: '^3.11.0',
dev: false,
- condition: ({ options }) => options.mysql === 'mysql2'
+ condition: ({ options }) => options.database == 'mysql' && options.mysql === 'mysql2'
},
{
name: '@planetscale/database',
version: '^1.18.0',
dev: false,
- condition: ({ options }) => options.mysql === 'planetscale'
+ condition: ({ options }) => options.database == 'mysql' && options.mysql === 'planetscale'
},
// PostgreSQL
{
name: '@neondatabase/serverless',
version: '^0.9.4',
dev: false,
- condition: ({ options }) => options.postgresql === 'neon'
+ condition: ({ options }) => options.database == 'postgresql' && options.postgresql === 'neon'
},
{
name: 'postgres',
version: '^3.4.4',
dev: false,
- condition: ({ options }) => options.postgresql === 'postgres.js'
+ condition: ({ options }) =>
+ options.database == 'postgresql' && options.postgresql === 'postgres.js'
},
// SQLite
{
name: 'better-sqlite3',
version: '^11.1.2',
dev: false,
- condition: ({ options }) => options.sqlite === 'better-sqlite3'
+ condition: ({ options }) =>
+ options.database == 'sqlite' && options.sqlite === 'better-sqlite3'
},
{
name: '@types/better-sqlite3',
version: '^7.6.11',
dev: true,
- condition: ({ options }) => options.sqlite === 'better-sqlite3'
+ condition: ({ options }) =>
+ options.database == 'sqlite' && options.sqlite === 'better-sqlite3'
},
{
name: '@libsql/client',
version: '^0.9.0',
dev: false,
- condition: ({ options }) => options.sqlite === 'libsql' || options.sqlite === 'turso'
+ condition: ({ options }) =>
+ options.database == 'sqlite' && (options.sqlite === 'libsql' || options.sqlite === 'turso')
}
],
files: [
@@ -129,7 +133,9 @@ export default defineAdder({
{
name: () => 'docker-compose.yml',
condition: ({ options }) =>
- options.docker && (options.mysql === 'mysql2' || options.postgresql === 'postgres.js'),
+ options.docker &&
+ ((options.database == 'mysql' && options.mysql === 'mysql2') ||
+ (options.database == 'postgresql' && options.postgresql === 'postgres.js')),
content: ({ content, options }) => {
// if the file already exists, don't modify it
// (in the future, we could add some tooling for modifying yaml)
@@ -143,13 +149,13 @@ export default defineAdder({
const DB_NAME = 'local';
let dbSpecificContent = '';
- if (options.mysql === 'mysql2') {
+ if (options.database == 'mysql' && options.mysql === 'mysql2') {
dbSpecificContent = `
MYSQL_ROOT_PASSWORD: ${PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
`;
}
- if (options.postgresql === 'postgres.js') {
+ if (options.database == 'postgresql' && options.postgresql === 'postgres.js') {
dbSpecificContent = `
POSTGRES_USER: ${USER}
POSTGRES_PASSWORD: ${PASSWORD}
@@ -215,7 +221,10 @@ export default defineAdder({
const objExpression = exportDefault.arguments?.[0];
if (!objExpression || objExpression.type !== 'ObjectExpression') return content;
- const driver = options.sqlite === 'turso' ? common.createLiteral('turso') : undefined;
+ const driver =
+ options.database == 'sqlite' && options.sqlite === 'turso'
+ ? common.createLiteral('turso')
+ : undefined;
const authToken =
options.sqlite === 'turso'
? common.expressionFromString('process.env.DATABASE_AUTH_TOKEN')
@@ -312,13 +321,16 @@ export default defineAdder({
let clientExpression;
// SQLite
- if (options.sqlite === 'better-sqlite3') {
+ if (options.database == 'sqlite' && options.sqlite === 'better-sqlite3') {
imports.addDefault(ast, 'better-sqlite3', 'Database');
imports.addNamed(ast, 'drizzle-orm/better-sqlite3', { drizzle: 'drizzle' });
clientExpression = common.expressionFromString('new Database(env.DATABASE_URL)');
}
- if (options.sqlite === 'libsql' || options.sqlite === 'turso') {
+ if (
+ options.database == 'sqlite' &&
+ (options.sqlite === 'libsql' || options.sqlite === 'turso')
+ ) {
imports.addNamed(ast, '@libsql/client', { createClient: 'createClient' });
imports.addNamed(ast, 'drizzle-orm/libsql', { drizzle: 'drizzle' });
@@ -340,7 +352,7 @@ export default defineAdder({
}
}
// MySQL
- if (options.mysql === 'mysql2') {
+ if (options.database == 'mysql' && options.mysql === 'mysql2') {
imports.addDefault(ast, 'mysql2/promise', 'mysql');
imports.addNamed(ast, 'drizzle-orm/mysql2', { drizzle: 'drizzle' });
@@ -348,20 +360,20 @@ export default defineAdder({
'await mysql.createConnection(env.DATABASE_URL)'
);
}
- if (options.mysql === 'planetscale') {
+ if (options.database == 'mysql' && options.mysql === 'planetscale') {
imports.addNamed(ast, '@planetscale/database', { Client: 'Client' });
imports.addNamed(ast, 'drizzle-orm/planetscale-serverless', { drizzle: 'drizzle' });
clientExpression = common.expressionFromString('new Client({ url: env.DATABASE_URL })');
}
// PostgreSQL
- if (options.postgresql === 'neon') {
+ if (options.database == 'postgresql' && options.postgresql === 'neon') {
imports.addNamed(ast, '@neondatabase/serverless', { neon: 'neon' });
imports.addNamed(ast, 'drizzle-orm/neon-http', { drizzle: 'drizzle' });
clientExpression = common.expressionFromString('neon(env.DATABASE_URL)');
}
- if (options.postgresql === 'postgres.js') {
+ if (options.database == 'postgresql' && options.postgresql === 'postgres.js') {
imports.addDefault(ast, 'postgres', 'postgres');
imports.addNamed(ast, 'drizzle-orm/postgres-js', { drizzle: 'drizzle' });
diff --git a/packages/adders/drizzle/tests.ts b/packages/adders/drizzle/tests.ts
index 3257b575..8dcabb76 100644
--- a/packages/adders/drizzle/tests.ts
+++ b/packages/adders/drizzle/tests.ts
@@ -1,6 +1,9 @@
-import { options } from './index.ts';
import { defineAdderTests } from '@sveltejs/cli-core';
-import { parseSvelte, parseJson } from '@sveltejs/cli-core/parsers';
+import path from 'node:path';
+import url from 'node:url';
+import { execSync } from 'node:child_process';
+import { options } from './index.ts';
+import { parseSvelte } from '@sveltejs/cli-core/parsers';
const defaultOptionValues = {
sqlite: options.sqlite.default,
@@ -9,6 +12,8 @@ const defaultOptionValues = {
docker: options.docker.default
};
+const dockerComposeCwd = path.resolve(url.fileURLToPath(import.meta.url), '..');
+
export const tests = defineAdderTests({
options,
optionValues: [
@@ -64,17 +69,31 @@ export const tests = defineAdderTests({
content: ({ content }) => {
return content.replace('strict: true,', '');
}
- },
- {
- name: () => 'package.json',
- content: ({ content }) => {
- const { data, generateCode } = parseJson(content);
- // executes after pnpm install
- data.scripts['postinstall'] ??= 'pnpm run db:push';
- return generateCode();
- }
}
],
+ beforeAll: async (testType) => {
+ if (testType == 'snapshot') return;
+
+ console.log('Starting docker containers');
+ execSync('docker compose up --detach', { cwd: dockerComposeCwd, stdio: 'pipe' });
+
+ // the containers take some time to startup and be ready
+ // to accept any connections. As there is no standard / easy
+ // way of doing this for different containers (mysql / postgres)
+ // we are waiting for them to startup
+ await new Promise((x) => setTimeout(x, 15000));
+ },
+ afterAll: (testType) => {
+ if (testType == 'snapshot') return;
+
+ console.log('Stopping docker containers');
+ execSync('docker compose down --volumes', { cwd: dockerComposeCwd, stdio: 'pipe' });
+ },
+ beforeEach: (cwd, testType) => {
+ if (testType == 'snapshot') return;
+
+ execSync('pnpm db:push', { cwd, stdio: 'pipe' });
+ },
tests: [
{
name: 'queries database',
diff --git a/packages/cli/env.ts b/packages/cli/env.ts
index d482918b..4ab46826 100644
--- a/packages/cli/env.ts
+++ b/packages/cli/env.ts
@@ -1,3 +1,3 @@
import process from 'node:process';
-export const TESTING: boolean = process.env.CI?.toLowerCase() === 'true';
+export const TESTING: boolean = process.env.NODE_ENV?.toLowerCase() === 'test';
diff --git a/packages/cli/index.ts b/packages/cli/index.ts
index 50f83ec1..4fb7e779 100644
--- a/packages/cli/index.ts
+++ b/packages/cli/index.ts
@@ -1,3 +1,10 @@
import { create } from '@sveltejs/create';
+import { createWorkspace } from './commands/add/workspace.ts';
+import { installPackages } from './commands/add/utils.ts';
+import { createOrUpdateFiles } from './commands/add/processor.ts';
export { create };
+
+// todo: this should not be exported here, rather in something internal
+// we should avoid duplicating the code thought due to maintance overhead
+export { createWorkspace, installPackages, createOrUpdateFiles };
diff --git a/packages/core/adder/config.ts b/packages/core/adder/config.ts
index f19cb146..8bd3bcc6 100644
--- a/packages/core/adder/config.ts
+++ b/packages/core/adder/config.ts
@@ -72,13 +72,18 @@ export type TestDefinition = {
condition?: (options: OptionValues) => boolean;
};
+export type TestType = 'snapshot' | 'end2end';
+
export type AdderTestConfig = {
files: Array>;
options: Args;
optionValues: Array>;
- runSynchronously?: boolean;
command?: string;
tests: Array>;
+ beforeAll?: (testType: TestType) => MaybePromise;
+ afterAll?: (testType: TestType) => MaybePromise;
+ beforeEach?: (cwd: string, testType: TestType) => MaybePromise;
+ afterEach?: (cwd: string, testType: TestType) => MaybePromise;
};
export function defineAdderTests(
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 31227042..42da4297 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -36,8 +36,8 @@ importers:
specifier: ^22.3.0
version: 22.5.4
'@vitest/ui':
- specifier: ^2.0.5
- version: 2.0.5(vitest@2.0.5)
+ specifier: ^2.1.2
+ version: 2.1.2(vitest@2.1.2)
eslint:
specifier: ^9.10.0
version: 9.10.0
@@ -78,8 +78,8 @@ importers:
specifier: ^0.6.5
version: 0.6.5(rollup@4.21.2)(typescript@5.6.2)(webpack-sources@3.2.3)
vitest:
- specifier: ^2.0.5
- version: 2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5)
+ specifier: ^2.1.2
+ version: 2.1.2(@types/node@22.5.4)(@vitest/ui@2.1.2)
community-adder-template:
dependencies:
@@ -87,9 +87,42 @@ importers:
specifier: workspace:*
version: link:../packages/core
devDependencies:
+ '@sveltejs/adder-testing-library':
+ specifier: workspace:*
+ version: link:../packages/adder-testing-library
sv:
specifier: workspace:*
version: link:../packages/cli
+ vitest:
+ specifier: ^2.1.2
+ version: 2.1.2(@types/node@22.5.4)(@vitest/ui@2.1.2)
+
+ packages/adder-testing-library:
+ dependencies:
+ '@sveltejs/cli-core':
+ specifier: workspace:*
+ version: link:../core
+ playwright:
+ specifier: ^1.44.1
+ version: 1.47.2
+ sv:
+ specifier: workspace:*
+ version: link:../cli
+ terminate:
+ specifier: ^2.8.0
+ version: 2.8.0
+ tiged:
+ specifier: 3.0.0-rc.0
+ version: 3.0.0-rc.0
+
+ packages/adder-tests:
+ dependencies:
+ '@sveltejs/adder-testing-library':
+ specifier: workspace:*
+ version: link:../adder-testing-library
+ '@sveltejs/adders':
+ specifier: workspace:*
+ version: link:../adders
packages/adders:
dependencies:
@@ -498,6 +531,10 @@ packages:
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
+ '@isaacs/fs-minipass@4.0.1':
+ resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
+ engines: {node: '>=18.0.0'}
+
'@jridgewell/gen-mapping@0.3.5':
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
engines: {node: '>=6.0.0'}
@@ -809,28 +846,40 @@ packages:
resolution: {integrity: sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@vitest/expect@2.0.5':
- resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==}
+ '@vitest/expect@2.1.2':
+ resolution: {integrity: sha512-FEgtlN8mIUSEAAnlvn7mP8vzaWhEaAEvhSXCqrsijM7K6QqjB11qoRZYEd4AKSCDz8p0/+yH5LzhZ47qt+EyPg==}
+
+ '@vitest/mocker@2.1.2':
+ resolution: {integrity: sha512-ExElkCGMS13JAJy+812fw1aCv2QO/LBK6CyO4WOPAzLTmve50gydOlWhgdBJPx2ztbADUq3JVI0C5U+bShaeEA==}
+ peerDependencies:
+ '@vitest/spy': 2.1.2
+ msw: ^2.3.5
+ vite: ^5.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
- '@vitest/pretty-format@2.0.5':
- resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==}
+ '@vitest/pretty-format@2.1.2':
+ resolution: {integrity: sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==}
- '@vitest/runner@2.0.5':
- resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==}
+ '@vitest/runner@2.1.2':
+ resolution: {integrity: sha512-UCsPtvluHO3u7jdoONGjOSil+uON5SSvU9buQh3lP7GgUXHp78guN1wRmZDX4wGK6J10f9NUtP6pO+SFquoMlw==}
- '@vitest/snapshot@2.0.5':
- resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==}
+ '@vitest/snapshot@2.1.2':
+ resolution: {integrity: sha512-xtAeNsZ++aRIYIUsek7VHzry/9AcxeULlegBvsdLncLmNCR6tR8SRjn8BbDP4naxtccvzTqZ+L1ltZlRCfBZFA==}
- '@vitest/spy@2.0.5':
- resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==}
+ '@vitest/spy@2.1.2':
+ resolution: {integrity: sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A==}
- '@vitest/ui@2.0.5':
- resolution: {integrity: sha512-m+ZpVt/PVi/nbeRKEjdiYeoh0aOfI9zr3Ria9LO7V2PlMETtAXJS3uETEZkc8Be2oOl8mhd7Ew+5SRBXRYncNw==}
+ '@vitest/ui@2.1.2':
+ resolution: {integrity: sha512-92gcNzkDnmxOxyHzQrQYRsoV9Q0Aay0r4QMLnV+B+lbqlUWa8nDg9ivyLV5mMVTtGirHsYUGGh/zbIA55gBZqA==}
peerDependencies:
- vitest: 2.0.5
+ vitest: 2.1.2
- '@vitest/utils@2.0.5':
- resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==}
+ '@vitest/utils@2.1.2':
+ resolution: {integrity: sha512-zMO2KdYy6mx56btx9JvAqAZ6EyS3g49krMPPrgOp1yxGZiA93HumGk+bZ5jIZtOg5/VBYl5eBmGRQHqq4FG6uQ==}
acorn-jsx@5.3.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
@@ -847,6 +896,10 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
+ agent-base@7.1.1:
+ resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==}
+ engines: {node: '>= 14'}
+
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
@@ -969,6 +1022,10 @@ packages:
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
engines: {node: '>= 16'}
+ chownr@3.0.0:
+ resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
+ engines: {node: '>=18'}
+
ci-info@3.9.0:
resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
engines: {node: '>=8'}
@@ -980,6 +1037,9 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ colorette@2.0.20:
+ resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
+
commander@12.1.0:
resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
engines: {node: '>=18'}
@@ -1074,6 +1134,9 @@ packages:
resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
engines: {node: '>=12'}
+ duplexer@0.1.2:
+ resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
+
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
@@ -1215,9 +1278,8 @@ packages:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
- execa@8.0.1:
- resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
- engines: {node: '>=16.17'}
+ event-stream@3.3.4:
+ resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==}
extendable-error@0.1.7:
resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==}
@@ -1245,6 +1307,14 @@ packages:
fastq@1.17.1:
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+ fdir@6.3.0:
+ resolution: {integrity: sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
fflate@0.8.2:
resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
@@ -1275,6 +1345,13 @@ packages:
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
engines: {node: '>=14'}
+ from@0.1.7:
+ resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==}
+
+ fs-extra@11.2.0:
+ resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
+ engines: {node: '>=14.14'}
+
fs-extra@7.0.1:
resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
engines: {node: '>=6 <7 || >=8'}
@@ -1283,6 +1360,11 @@ packages:
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
engines: {node: '>=6 <7 || >=8'}
+ fsevents@2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -1291,6 +1373,9 @@ packages:
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+ fuzzysearch@1.0.3:
+ resolution: {integrity: sha512-s+kNWQuI3mo9OALw0HJ6YGmMbLqEufCh2nX/zzV5CrICQ/y4AwPxM+6TIiF9ItFCHXFCyM/BfCCmN57NTIJuPg==}
+
get-func-name@2.0.2:
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
@@ -1298,10 +1383,6 @@ packages:
resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==}
engines: {node: '>=12'}
- get-stream@8.0.1:
- resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
- engines: {node: '>=16'}
-
get-tsconfig@4.8.0:
resolution: {integrity: sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==}
@@ -1363,13 +1444,13 @@ packages:
htmlparser2@9.1.0:
resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
+ https-proxy-agent@7.0.4:
+ resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==}
+ engines: {node: '>= 14'}
+
human-id@1.0.2:
resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==}
- human-signals@5.0.0:
- resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
- engines: {node: '>=16.17.0'}
-
iconv-lite@0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
@@ -1427,10 +1508,6 @@ packages:
is-reference@3.0.2:
resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==}
- is-stream@3.0.0:
- resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
-
is-subdir@1.2.0:
resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==}
engines: {node: '>=4'}
@@ -1469,6 +1546,9 @@ packages:
jsonfile@4.0.0:
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
+ jsonfile@6.1.0:
+ resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -1518,8 +1598,8 @@ packages:
magic-string@0.30.12:
resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==}
- merge-stream@2.0.0:
- resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+ map-stream@0.1.0:
+ resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==}
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
@@ -1529,10 +1609,6 @@ packages:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
- mimic-fn@4.0.0:
- resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
- engines: {node: '>=12'}
-
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -1544,6 +1620,15 @@ packages:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
+ minizlib@3.0.1:
+ resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==}
+ engines: {node: '>= 18'}
+
+ mkdirp@3.0.1:
+ resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==}
+ engines: {node: '>=10'}
+ hasBin: true
+
mri@1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'}
@@ -1575,10 +1660,6 @@ packages:
encoding:
optional: true
- npm-run-path@5.3.0:
- resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
-
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
@@ -1586,10 +1667,6 @@ packages:
once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
- onetime@6.0.0:
- resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
- engines: {node: '>=12'}
-
optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
@@ -1650,10 +1727,6 @@ packages:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
- path-key@4.0.0:
- resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
- engines: {node: '>=12'}
-
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
@@ -1672,6 +1745,9 @@ packages:
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
engines: {node: '>= 14.16'}
+ pause-stream@0.0.11:
+ resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==}
+
picocolors@1.1.0:
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
@@ -1679,6 +1755,10 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
+ picomatch@4.0.2:
+ resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
+ engines: {node: '>=12'}
+
pify@4.0.1:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
engines: {node: '>=6'}
@@ -1687,6 +1767,16 @@ packages:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
+ playwright-core@1.47.2:
+ resolution: {integrity: sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ playwright@1.47.2:
+ resolution: {integrity: sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
postcss-load-config@3.1.4:
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
@@ -1747,6 +1837,11 @@ packages:
engines: {node: '>=14'}
hasBin: true
+ ps-tree@1.2.0:
+ resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==}
+ engines: {node: '>= 0.10'}
+ hasBin: true
+
pseudomap@1.0.2:
resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
@@ -1793,6 +1888,11 @@ packages:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ rimraf@5.0.7:
+ resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==}
+ engines: {node: '>=14.18'}
+ hasBin: true
+
rollup-plugin-esbuild@6.1.1:
resolution: {integrity: sha512-CehMY9FAqJD5OUaE/Mi1r5z0kNeYxItmRO2zG4Qnv2qWKF09J2lTy5GUzjJR354ZPrLkCj4fiBN41lo8PzBUhw==}
engines: {node: '>=14.18.0'}
@@ -1887,6 +1987,9 @@ packages:
spawndamnit@2.0.0:
resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==}
+ split@0.3.3:
+ resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==}
+
sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
@@ -1896,6 +1999,9 @@ packages:
std-env@3.7.0:
resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==}
+ stream-combiner@0.0.4:
+ resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==}
+
streamx@2.20.1:
resolution: {integrity: sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==}
@@ -1919,10 +2025,6 @@ packages:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
engines: {node: '>=4'}
- strip-final-newline@3.0.0:
- resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
- engines: {node: '>=12'}
-
strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
@@ -1967,10 +2069,18 @@ packages:
tar-stream@3.1.7:
resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
+ tar@7.4.0:
+ resolution: {integrity: sha512-XQs0S8fuAkQWuqhDeCdMlJXDX80D7EOVLDPVFkna9yQfzS+PHKgfxcei0jf6/+QAWcjqrnC8uM3fSAnrQl+XYg==}
+ engines: {node: '>=18'}
+
term-size@2.2.1:
resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
engines: {node: '>=8'}
+ terminate@2.8.0:
+ resolution: {integrity: sha512-bcbjJEg0wY5nuJXvGxxHfmoEPkyHLCctUKO6suwtxy7jVSgGcgPeGwpbLDLELFhIaxCGRr3dPvyNg1yuz2V0eg==}
+ engines: {node: '>=12'}
+
text-decoder@1.2.0:
resolution: {integrity: sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==}
@@ -1984,6 +2094,14 @@ packages:
thenify@3.3.1:
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+ through@2.3.8:
+ resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
+
+ tiged@3.0.0-rc.0:
+ resolution: {integrity: sha512-BfPQmGvFoh0DaTl45/I+kxo0q8kAy+HgZgpSMn5gJdYVns5pARkvwW/Er2dldDiue+uwnMvSoIPfQBbphVszCw==}
+ engines: {node: '>=8.0.0'}
+ hasBin: true
+
tiny-glob@0.2.9:
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
@@ -1996,6 +2114,10 @@ packages:
tinyexec@0.3.0:
resolution: {integrity: sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==}
+ tinyglobby@0.2.6:
+ resolution: {integrity: sha512-NbBoFBpqfcgd1tCiO8Lkfdk+xrA7mlLR9zgvZcZWQQwU63XAfUePyd6wZBaU93Hqw347lHnwFzttAkemHzzz4g==}
+ engines: {node: '>=12.0.0'}
+
tinypool@1.0.1:
resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -2064,6 +2186,10 @@ packages:
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
engines: {node: '>= 4.0.0'}
+ universalify@2.0.1:
+ resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
+ engines: {node: '>= 10.0.0'}
+
unplugin-isolated-decl@0.6.5:
resolution: {integrity: sha512-bEtUFVSTczPKAXrQiRQRfi55ziDt143G5ZL/jpj2+NoOJIxT5rjWltwHIlHXS6ym/LyuoqoZApTHkmMTFn6YTA==}
engines: {node: '>=18.12.0'}
@@ -2102,8 +2228,8 @@ packages:
typescript:
optional: true
- vite-node@2.0.5:
- resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==}
+ vite-node@2.1.2:
+ resolution: {integrity: sha512-HPcGNN5g/7I2OtPjLqgOtCRu/qhVvBxTUD3qzitmL0SrG1cWFzxzhMDWussxSbrRYWqnKf8P2jiNhPMSN+ymsQ==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
@@ -2138,15 +2264,15 @@ packages:
terser:
optional: true
- vitest@2.0.5:
- resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==}
+ vitest@2.1.2:
+ resolution: {integrity: sha512-veNjLizOMkRrJ6xxb+pvxN6/QAWg95mzcRjtmkepXdN87FNfxAss9RKe2far/G9cQpipfgP2taqg0KiWsquj8A==}
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.0.5
- '@vitest/ui': 2.0.5
+ '@vitest/browser': 2.1.2
+ '@vitest/ui': 2.1.2
happy-dom: '*'
jsdom: '*'
peerDependenciesMeta:
@@ -2208,6 +2334,10 @@ packages:
yallist@2.1.2:
resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
+ yallist@5.0.0:
+ resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
+ engines: {node: '>=18'}
+
yaml@1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'}
@@ -2512,6 +2642,10 @@ snapshots:
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
+ '@isaacs/fs-minipass@4.0.1':
+ dependencies:
+ minipass: 7.1.2
+
'@jridgewell/gen-mapping@0.3.5':
dependencies:
'@jridgewell/set-array': 1.2.1
@@ -2808,47 +2942,54 @@ snapshots:
'@typescript-eslint/types': 8.5.0
eslint-visitor-keys: 3.4.3
- '@vitest/expect@2.0.5':
+ '@vitest/expect@2.1.2':
dependencies:
- '@vitest/spy': 2.0.5
- '@vitest/utils': 2.0.5
+ '@vitest/spy': 2.1.2
+ '@vitest/utils': 2.1.2
chai: 5.1.1
tinyrainbow: 1.2.0
- '@vitest/pretty-format@2.0.5':
+ '@vitest/mocker@2.1.2(@vitest/spy@2.1.2)(vite@5.4.3(@types/node@22.5.4))':
+ dependencies:
+ '@vitest/spy': 2.1.2
+ estree-walker: 3.0.3
+ magic-string: 0.30.12
+ optionalDependencies:
+ vite: 5.4.3(@types/node@22.5.4)
+
+ '@vitest/pretty-format@2.1.2':
dependencies:
tinyrainbow: 1.2.0
- '@vitest/runner@2.0.5':
+ '@vitest/runner@2.1.2':
dependencies:
- '@vitest/utils': 2.0.5
+ '@vitest/utils': 2.1.2
pathe: 1.1.2
- '@vitest/snapshot@2.0.5':
+ '@vitest/snapshot@2.1.2':
dependencies:
- '@vitest/pretty-format': 2.0.5
+ '@vitest/pretty-format': 2.1.2
magic-string: 0.30.12
pathe: 1.1.2
- '@vitest/spy@2.0.5':
+ '@vitest/spy@2.1.2':
dependencies:
tinyspy: 3.0.2
- '@vitest/ui@2.0.5(vitest@2.0.5)':
+ '@vitest/ui@2.1.2(vitest@2.1.2)':
dependencies:
- '@vitest/utils': 2.0.5
- fast-glob: 3.3.2
+ '@vitest/utils': 2.1.2
fflate: 0.8.2
flatted: 3.3.1
pathe: 1.1.2
sirv: 2.0.4
+ tinyglobby: 0.2.6
tinyrainbow: 1.2.0
- vitest: 2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5)
+ vitest: 2.1.2(@types/node@22.5.4)(@vitest/ui@2.1.2)
- '@vitest/utils@2.0.5':
+ '@vitest/utils@2.1.2':
dependencies:
- '@vitest/pretty-format': 2.0.5
- estree-walker: 3.0.3
+ '@vitest/pretty-format': 2.1.2
loupe: 3.1.1
tinyrainbow: 1.2.0
@@ -2862,6 +3003,12 @@ snapshots:
acorn@8.12.1: {}
+ agent-base@7.1.1:
+ dependencies:
+ debug: 4.3.7
+ transitivePeerDependencies:
+ - supports-color
+
ajv@6.12.6:
dependencies:
fast-deep-equal: 3.1.3
@@ -2975,6 +3122,8 @@ snapshots:
check-error@2.1.1: {}
+ chownr@3.0.0: {}
+
ci-info@3.9.0: {}
color-convert@2.0.1:
@@ -2983,6 +3132,8 @@ snapshots:
color-name@1.1.4: {}
+ colorette@2.0.20: {}
+
commander@12.1.0: {}
commander@4.1.1: {}
@@ -3051,6 +3202,8 @@ snapshots:
dotenv@16.4.5: {}
+ duplexer@0.1.2: {}
+
eastasianwidth@0.2.0: {}
emoji-regex@8.0.0: {}
@@ -3244,17 +3397,15 @@ snapshots:
esutils@2.0.3: {}
- execa@8.0.1:
+ event-stream@3.3.4:
dependencies:
- cross-spawn: 7.0.3
- get-stream: 8.0.1
- human-signals: 5.0.0
- is-stream: 3.0.0
- merge-stream: 2.0.0
- npm-run-path: 5.3.0
- onetime: 6.0.0
- signal-exit: 4.1.0
- strip-final-newline: 3.0.0
+ duplexer: 0.1.2
+ from: 0.1.7
+ map-stream: 0.1.0
+ pause-stream: 0.0.11
+ split: 0.3.3
+ stream-combiner: 0.0.4
+ through: 2.3.8
extendable-error@0.1.7: {}
@@ -3284,6 +3435,10 @@ snapshots:
dependencies:
reusify: 1.0.4
+ fdir@6.3.0(picomatch@4.0.2):
+ optionalDependencies:
+ picomatch: 4.0.2
+
fflate@0.8.2: {}
file-entry-cache@8.0.0:
@@ -3316,6 +3471,14 @@ snapshots:
cross-spawn: 7.0.3
signal-exit: 4.1.0
+ from@0.1.7: {}
+
+ fs-extra@11.2.0:
+ dependencies:
+ graceful-fs: 4.2.11
+ jsonfile: 6.1.0
+ universalify: 2.0.1
+
fs-extra@7.0.1:
dependencies:
graceful-fs: 4.2.11
@@ -3328,17 +3491,20 @@ snapshots:
jsonfile: 4.0.0
universalify: 0.1.2
+ fsevents@2.3.2:
+ optional: true
+
fsevents@2.3.3:
optional: true
function-bind@1.1.2: {}
+ fuzzysearch@1.0.3: {}
+
get-func-name@2.0.2: {}
get-stdin@9.0.0: {}
- get-stream@8.0.1: {}
-
get-tsconfig@4.8.0:
dependencies:
resolve-pkg-maps: 1.0.0
@@ -3406,9 +3572,14 @@ snapshots:
domutils: 3.1.0
entities: 4.5.0
- human-id@1.0.2: {}
+ https-proxy-agent@7.0.4:
+ dependencies:
+ agent-base: 7.1.1
+ debug: 4.3.7
+ transitivePeerDependencies:
+ - supports-color
- human-signals@5.0.0: {}
+ human-id@1.0.2: {}
iconv-lite@0.4.24:
dependencies:
@@ -3455,8 +3626,6 @@ snapshots:
dependencies:
'@types/estree': 1.0.5
- is-stream@3.0.0: {}
-
is-subdir@1.2.0:
dependencies:
better-path-resolve: 1.0.0
@@ -3492,6 +3661,12 @@ snapshots:
optionalDependencies:
graceful-fs: 4.2.11
+ jsonfile@6.1.0:
+ dependencies:
+ universalify: 2.0.1
+ optionalDependencies:
+ graceful-fs: 4.2.11
+
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@@ -3540,7 +3715,7 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
- merge-stream@2.0.0: {}
+ map-stream@0.1.0: {}
merge2@1.4.1: {}
@@ -3549,8 +3724,6 @@ snapshots:
braces: 3.0.3
picomatch: 2.3.1
- mimic-fn@4.0.0: {}
-
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
@@ -3561,6 +3734,13 @@ snapshots:
minipass@7.1.2: {}
+ minizlib@3.0.1:
+ dependencies:
+ minipass: 7.1.2
+ rimraf: 5.0.7
+
+ mkdirp@3.0.1: {}
+
mri@1.2.0: {}
mrmime@2.0.0: {}
@@ -3581,20 +3761,12 @@ snapshots:
dependencies:
whatwg-url: 5.0.0
- npm-run-path@5.3.0:
- dependencies:
- path-key: 4.0.0
-
object-assign@4.1.1: {}
once@1.4.0:
dependencies:
wrappy: 1.0.2
- onetime@6.0.0:
- dependencies:
- mimic-fn: 4.0.0
-
optionator@0.9.4:
dependencies:
deep-is: 0.1.4
@@ -3655,8 +3827,6 @@ snapshots:
path-key@3.1.1: {}
- path-key@4.0.0: {}
-
path-parse@1.0.7: {}
path-scurry@1.11.1:
@@ -3670,14 +3840,28 @@ snapshots:
pathval@2.0.0: {}
+ pause-stream@0.0.11:
+ dependencies:
+ through: 2.3.8
+
picocolors@1.1.0: {}
picomatch@2.3.1: {}
+ picomatch@4.0.2: {}
+
pify@4.0.1: {}
pirates@4.0.6: {}
+ playwright-core@1.47.2: {}
+
+ playwright@1.47.2:
+ dependencies:
+ playwright-core: 1.47.2
+ optionalDependencies:
+ fsevents: 2.3.2
+
postcss-load-config@3.1.4(postcss@8.4.45):
dependencies:
lilconfig: 2.1.0
@@ -3722,6 +3906,10 @@ snapshots:
prettier@3.3.3: {}
+ ps-tree@1.2.0:
+ dependencies:
+ event-stream: 3.3.4
+
pseudomap@1.0.2: {}
pump@3.0.2:
@@ -3766,6 +3954,10 @@ snapshots:
reusify@1.0.4: {}
+ rimraf@5.0.7:
+ dependencies:
+ glob: 10.4.5
+
rollup-plugin-esbuild@6.1.1(esbuild@0.21.5)(rollup@4.21.2):
dependencies:
'@rollup/pluginutils': 5.1.2(rollup@4.21.2)
@@ -3868,12 +4060,20 @@ snapshots:
cross-spawn: 5.1.0
signal-exit: 3.0.7
+ split@0.3.3:
+ dependencies:
+ through: 2.3.8
+
sprintf-js@1.0.3: {}
stackback@0.0.2: {}
std-env@3.7.0: {}
+ stream-combiner@0.0.4:
+ dependencies:
+ duplexer: 0.1.2
+
streamx@2.20.1:
dependencies:
fast-fifo: 1.3.2
@@ -3904,8 +4104,6 @@ snapshots:
strip-bom@3.0.0: {}
- strip-final-newline@3.0.0: {}
-
strip-json-comments@3.1.1: {}
sucrase@3.35.0:
@@ -3971,8 +4169,21 @@ snapshots:
fast-fifo: 1.3.2
streamx: 2.20.1
+ tar@7.4.0:
+ dependencies:
+ '@isaacs/fs-minipass': 4.0.1
+ chownr: 3.0.0
+ minipass: 7.1.2
+ minizlib: 3.0.1
+ mkdirp: 3.0.1
+ yallist: 5.0.0
+
term-size@2.2.1: {}
+ terminate@2.8.0:
+ dependencies:
+ ps-tree: 1.2.0
+
text-decoder@1.2.0:
dependencies:
b4a: 1.6.6
@@ -3987,6 +4198,22 @@ snapshots:
dependencies:
any-promise: 1.3.0
+ through@2.3.8: {}
+
+ tiged@3.0.0-rc.0:
+ dependencies:
+ colorette: 2.0.20
+ enquirer: 2.4.1
+ fs-extra: 11.2.0
+ fuzzysearch: 1.0.3
+ https-proxy-agent: 7.0.4
+ mri: 1.2.0
+ rimraf: 5.0.7
+ tar: 7.4.0
+ tiny-glob: 0.2.9
+ transitivePeerDependencies:
+ - supports-color
+
tiny-glob@0.2.9:
dependencies:
globalyzer: 0.1.0
@@ -3998,6 +4225,11 @@ snapshots:
tinyexec@0.3.0: {}
+ tinyglobby@0.2.6:
+ dependencies:
+ fdir: 6.3.0(picomatch@4.0.2)
+ picomatch: 4.0.2
+
tinypool@1.0.1: {}
tinyrainbow@1.2.0: {}
@@ -4047,6 +4279,8 @@ snapshots:
universalify@0.1.2: {}
+ universalify@2.0.1: {}
+
unplugin-isolated-decl@0.6.5(rollup@4.21.2)(typescript@5.6.2)(webpack-sources@3.2.3):
dependencies:
'@rollup/pluginutils': 5.1.2(rollup@4.21.2)
@@ -4076,12 +4310,11 @@ snapshots:
optionalDependencies:
typescript: 5.6.2
- vite-node@2.0.5(@types/node@22.5.4):
+ vite-node@2.1.2(@types/node@22.5.4):
dependencies:
cac: 6.7.14
debug: 4.3.7
pathe: 1.1.2
- tinyrainbow: 1.2.0
vite: 5.4.3(@types/node@22.5.4)
transitivePeerDependencies:
- '@types/node'
@@ -4103,33 +4336,34 @@ snapshots:
'@types/node': 22.5.4
fsevents: 2.3.3
- vitest@2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5):
+ vitest@2.1.2(@types/node@22.5.4)(@vitest/ui@2.1.2):
dependencies:
- '@ampproject/remapping': 2.3.0
- '@vitest/expect': 2.0.5
- '@vitest/pretty-format': 2.0.5
- '@vitest/runner': 2.0.5
- '@vitest/snapshot': 2.0.5
- '@vitest/spy': 2.0.5
- '@vitest/utils': 2.0.5
+ '@vitest/expect': 2.1.2
+ '@vitest/mocker': 2.1.2(@vitest/spy@2.1.2)(vite@5.4.3(@types/node@22.5.4))
+ '@vitest/pretty-format': 2.1.2
+ '@vitest/runner': 2.1.2
+ '@vitest/snapshot': 2.1.2
+ '@vitest/spy': 2.1.2
+ '@vitest/utils': 2.1.2
chai: 5.1.1
debug: 4.3.7
- execa: 8.0.1
magic-string: 0.30.12
pathe: 1.1.2
std-env: 3.7.0
tinybench: 2.9.0
+ tinyexec: 0.3.0
tinypool: 1.0.1
tinyrainbow: 1.2.0
vite: 5.4.3(@types/node@22.5.4)
- vite-node: 2.0.5(@types/node@22.5.4)
+ vite-node: 2.1.2(@types/node@22.5.4)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 22.5.4
- '@vitest/ui': 2.0.5(vitest@2.0.5)
+ '@vitest/ui': 2.1.2(vitest@2.1.2)
transitivePeerDependencies:
- less
- lightningcss
+ - msw
- sass
- sass-embedded
- stylus
@@ -4180,6 +4414,8 @@ snapshots:
yallist@2.1.2: {}
+ yallist@5.0.0: {}
+
yaml@1.10.2: {}
yocto-queue@0.1.0: {}
diff --git a/rollup.config.js b/rollup.config.js
index f66a0e6c..e8bdebf5 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -130,6 +130,7 @@ export default [
getConfig('ast-tooling'),
getConfig('create'),
getConfig('core'),
+ getConfig('adder-testing-library'),
getConfig('cli')
];
diff --git a/tsconfig.json b/tsconfig.json
index 415c0abd..f509789e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,6 +5,7 @@
"**/core/tests/**",
"packages/create/templates/**",
"packages/create/shared/**",
+ "packages/adder-tests/_snapshots/**",
// Ignoring the rollup config so that the imported plugins can resolve their types correctly
// (setting `moduleResolution: Node16` breaks them)
"rollup.config.js"