diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e1fe314d..78e64e81 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -39,7 +39,10 @@ jobs:
- run: pnpm build
- run: pnpm check
test:
- runs-on: ubuntu-latest
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
@@ -48,5 +51,6 @@ jobs:
node-version: 18
cache: pnpm
- run: pnpm install --frozen-lockfile
+ - run: pnpm exec playwright install chromium
- run: pnpm build
- run: pnpm test
diff --git a/.gitignore b/.gitignore
index 486eb366..aeb3dc67 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,4 @@ package-lock.json
yarn.lock
vite.config.js.timestamp-*
/packages/create-svelte/template/CHANGELOG.md
-.test-tmp
+.test-output
diff --git a/.prettierignore b/.prettierignore
deleted file mode 100644
index ea3293fe..00000000
--- a/.prettierignore
+++ /dev/null
@@ -1,2 +0,0 @@
-packages/core/tests/**/input.*
-packages/core/tests/**/output.*
diff --git a/community-adder-template/.gitignore b/community-adder-template/.gitignore
index 33738ed9..a9e1699a 100644
--- a/community-adder-template/.gitignore
+++ b/community-adder-template/.gitignore
@@ -1,3 +1,4 @@
node_modules
temp
.outputs
+.test-output
diff --git a/community-adder-template/package.json b/community-adder-template/package.json
index 557b1e55..fedd5d42 100644
--- a/community-adder-template/package.json
+++ b/community-adder-template/package.json
@@ -2,25 +2,28 @@
"name": "community-adder-template",
"private": true,
"version": "0.0.0",
- "license": "MIT",
"type": "module",
- "exports": "./src/index.js",
- "keywords": [
- "svelte-add-on",
- "sv"
- ],
+ "license": "MIT",
"scripts": {
+ "create-temp": "sv create temp --types ts --template minimal --no-add-ons --no-install",
"start": "sv add -C temp --community file:../",
- "create-temp": "sv create temp --check-types typescript --template skeleton --no-adders --no-install"
+ "test": "vitest run"
},
+ "files": [
+ "src",
+ "!src/**/*.test.*"
+ ],
+ "exports": "./src/index.js",
"dependencies": {
"@sveltejs/cli-core": "workspace:*"
},
"devDependencies": {
- "sv": "workspace:*"
+ "@playwright/test": "^1.48.2",
+ "sv": "workspace:*",
+ "vitest": "^2.1.4"
},
- "files": [
- "src",
- "!src/**/*.test.*"
+ "keywords": [
+ "svelte-add-on",
+ "sv"
]
}
diff --git a/community-adder-template/src/index.js b/community-adder-template/src/index.js
index 9e4348aa..c063124b 100644
--- a/community-adder-template/src/index.js
+++ b/community-adder-template/src/index.js
@@ -1,17 +1,17 @@
import { defineAdder, defineAdderOptions } from '@sveltejs/cli-core';
import { imports } from '@sveltejs/cli-core/js';
-import { parseScript } from '@sveltejs/cli-core/parsers';
+import { parseSvelte } 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({
- id: 'community-adder-template',
+export default defineAdder({
+ id: 'community-addon',
environments: { kit: true, svelte: true },
options,
packages: [],
@@ -27,10 +27,11 @@ export const adder = defineAdder({
},
{
name: () => 'src/DemoComponent.svelte',
- content: ({ content }) => {
- const { ast, generateCode } = parseScript(content);
- imports.addDefault(ast, '../adder-template-demo.txt?raw', 'Demo');
- return generateCode();
+ content: ({ content, options, typescript }) => {
+ if (!options.demo) return content;
+ const { script, generateCode } = parseSvelte(content, { typescript });
+ imports.addDefault(script.ast, '../adder-template-demo.txt?raw', 'demo');
+ return generateCode({ script: script.generateCode(), template: '{demo}' });
}
}
]
diff --git a/community-adder-template/tests/custom-addon.test.ts b/community-adder-template/tests/custom-addon.test.ts
new file mode 100644
index 00000000..20a970e3
--- /dev/null
+++ b/community-adder-template/tests/custom-addon.test.ts
@@ -0,0 +1,28 @@
+import path from 'node:path';
+import { expect } from '@playwright/test';
+import { fixture, setupTest } from './setup/suite.js';
+import addon from '../src/index.js';
+
+const id = addon.id;
+const { test, variants, prepareServer } = setupTest({ [id]: addon });
+
+test.concurrent.for(variants)('demo - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { [id]: { demo: true } });
+
+ // ...add files
+ if (variant.startsWith('kit')) {
+ const target = path.resolve(cwd, 'src', 'routes', '+page.svelte');
+ fixture({ name: '+page.svelte', target });
+ } else {
+ const target = path.resolve(cwd, 'src', 'App.svelte');
+ fixture({ name: 'App.svelte', target });
+ }
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ // expectations
+ const textContent = await page.getByTestId('demo').textContent();
+ expect(textContent).toContain('This is a text file made by the Community Adder Template demo!');
+});
diff --git a/community-adder-template/tests/fixtures/+page.svelte b/community-adder-template/tests/fixtures/+page.svelte
new file mode 100644
index 00000000..bd5a70ff
--- /dev/null
+++ b/community-adder-template/tests/fixtures/+page.svelte
@@ -0,0 +1,5 @@
+
+
+{demo}
diff --git a/community-adder-template/tests/fixtures/App.svelte b/community-adder-template/tests/fixtures/App.svelte
new file mode 100644
index 00000000..8694a285
--- /dev/null
+++ b/community-adder-template/tests/fixtures/App.svelte
@@ -0,0 +1,5 @@
+
+
+{demo}
diff --git a/community-adder-template/tests/setup/global.ts b/community-adder-template/tests/setup/global.ts
new file mode 100644
index 00000000..872cd690
--- /dev/null
+++ b/community-adder-template/tests/setup/global.ts
@@ -0,0 +1,29 @@
+import { fileURLToPath } from 'node:url';
+import { setup, type ProjectVariant } from 'sv/testing';
+import type { GlobalSetupContext } from 'vitest/node';
+
+const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts'];
+const TEST_DIR = fileURLToPath(new URL('../../.test-output/', import.meta.url));
+
+export default async function ({ provide }: GlobalSetupContext) {
+ // global setup (e.g. spin up docker containers)
+
+ // downloads different project configurations (sveltekit, js/ts, vite-only, etc)
+ const { templatesDir } = await setup({ cwd: TEST_DIR, variants, clean: true });
+
+ provide('testDir', TEST_DIR);
+ provide('templatesDir', templatesDir);
+ provide('variants', variants);
+
+ return async () => {
+ // tear down... (e.g. cleanup docker containers)
+ };
+}
+
+declare module 'vitest' {
+ export interface ProvidedContext {
+ testDir: string;
+ templatesDir: string;
+ variants: ProjectVariant[];
+ }
+}
diff --git a/community-adder-template/tests/setup/suite.ts b/community-adder-template/tests/setup/suite.ts
new file mode 100644
index 00000000..46f3f8c8
--- /dev/null
+++ b/community-adder-template/tests/setup/suite.ts
@@ -0,0 +1,108 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import { execSync } from 'node:child_process';
+import * as vitest from 'vitest';
+import { installAddon, type AddonMap, type OptionMap } from 'sv';
+import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/testing';
+import { chromium, type Browser, type Page } from '@playwright/test';
+import { fileURLToPath } from 'node:url';
+
+const cwd = vitest.inject('testDir');
+const templatesDir = vitest.inject('templatesDir');
+const variants = vitest.inject('variants');
+
+const SETUP_DIR = fileURLToPath(new URL('.', import.meta.url));
+
+type Fixtures = {
+ page: Page;
+ run(variant: ProjectVariant, options: OptionMap): Promise;
+};
+
+export function setupTest(addons: Addons) {
+ let create: CreateProject;
+ let browser: Browser;
+
+ const test = vitest.test.extend>({} as any);
+
+ vitest.beforeAll(async () => {
+ browser = await chromium.launch();
+ return async () => {
+ await browser.close();
+ };
+ });
+
+ vitest.beforeAll(({ name }) => {
+ const testName = path.parse(name).name.replace('.test', '');
+
+ // constructs a builder for create test projects
+ create = createProject({ cwd, templatesDir, testName });
+
+ // creates a pnpm workspace in each addon dir
+ fs.writeFileSync(
+ path.resolve(cwd, testName, 'pnpm-workspace.yaml'),
+ `packages:\n - '**/*'`,
+ 'utf8'
+ );
+ });
+
+ // runs before each test case
+ vitest.beforeEach>(async (ctx) => {
+ const browserCtx = await browser.newContext();
+ ctx.page = await browserCtx.newPage();
+ ctx.run = async (variant, options) => {
+ const cwd = create({ testId: ctx.task.id, variant });
+
+ // test metadata
+ const metaPath = path.resolve(cwd, 'meta.json');
+ fs.writeFileSync(metaPath, JSON.stringify({ variant, options }, null, '\t'), 'utf8');
+
+ // run addon
+ await installAddon({ cwd, addons, options, packageManager: 'pnpm' });
+
+ return cwd;
+ };
+
+ return async () => {
+ await browserCtx.close();
+ // ...other tear downs
+ };
+ });
+
+ return {
+ test,
+ variants,
+ prepareServer
+ };
+}
+
+/**
+ * Installs dependencies, builds the project, and spins up the preview server
+ */
+async function prepareServer({ cwd, page }: { cwd: string; page: Page }) {
+ // install deps
+ execSync('pnpm install --no-frozen-lockfile', { cwd, stdio: 'pipe' });
+
+ // ...do commands and any other extra stuff
+
+ // build project
+ execSync('npm run build', { cwd, stdio: 'pipe' });
+
+ // start preview server `vite preview`
+ const { url, close } = await startPreview({ cwd });
+
+ // navigate to the page
+ await page.goto(url);
+
+ return { url, close };
+}
+
+/**
+ * Applies a fixture to the target path
+ */
+export function fixture({ name, target }: { name: string; target: string }) {
+ const fixturePath = path.resolve(SETUP_DIR, '..', 'fixtures', name);
+ if (!fs.existsSync(fixturePath)) {
+ throw new Error(`Fixture does not exist at: ${fixturePath}`);
+ }
+ fs.copyFileSync(fixturePath, target);
+}
diff --git a/community-adder-template/tests/tests.js b/community-adder-template/tests/tests.js
deleted file mode 100644
index 373c556b..00000000
--- a/community-adder-template/tests/tests.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { defineAdderTests } from '@sveltejs/cli-core';
-import { options } from '../src/index.js';
-
-export const tests = defineAdderTests({
- files: [],
- options,
- optionValues: [{ demo: true }],
- tests: [
- {
- name: 'demo test',
- run: async ({ elementExists }) => {
- await elementExists('.test');
- }
- }
- ]
-});
diff --git a/community-adder-template/vitest.config.js b/community-adder-template/vitest.config.js
new file mode 100644
index 00000000..0dee885f
--- /dev/null
+++ b/community-adder-template/vitest.config.js
@@ -0,0 +1,14 @@
+import { defineConfig } from 'vitest/config';
+
+const ONE_MINUTE = 1000 * 60;
+
+export default defineConfig({
+ test: {
+ include: ['tests/**/*.test.{js,ts}'],
+ exclude: ['tests/setup/*'],
+ testTimeout: ONE_MINUTE * 3,
+ hookTimeout: ONE_MINUTE * 3,
+ maxConcurrency: 10,
+ globalSetup: ['tests/setup/global.ts']
+ }
+});
diff --git a/eslint.config.js b/eslint.config.js
index c6f1bbf0..62799efb 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -28,10 +28,11 @@ export default [
'packages/create/scripts/**/*',
'packages/create/templates/**/*',
'**/temp/*',
- '.test-tmp/**/*',
+ '**/.test-output/*',
'**/dist/*',
'packages/**/tests/**/{output,input}.ts',
- 'rollup.config.js'
+ 'rollup.config.js',
+ 'community-adder-template/tests/*'
]
}
];
diff --git a/package.json b/package.json
index 3678c39b..abe8d183 100644
--- a/package.json
+++ b/package.json
@@ -1,20 +1,25 @@
{
"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": "vitest run --silent",
+ "test:ui": "vitest --ui"
},
"devDependencies": {
"@changesets/cli": "^2.27.9",
+ "@playwright/test": "^1.48.2",
"@rollup/plugin-commonjs": "^26.0.1",
"@rollup/plugin-dynamic-import-vars": "^2.1.2",
"@rollup/plugin-json": "^6.1.0",
@@ -23,7 +28,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.4",
"eslint": "^9.10.0",
"magic-string": "^0.30.11",
"prettier": "^3.3.3",
@@ -37,10 +42,7 @@
"typescript": "^5.6.2",
"typescript-eslint": "^8.5.0",
"unplugin-isolated-decl": "^0.6.5",
- "vitest": "^2.0.5"
+ "vitest": "^2.1.4"
},
- "packageManager": "pnpm@9.7.0",
- "engines": {
- "pnpm": "^9.0.0"
- }
+ "packageManager": "pnpm@9.7.0"
}
diff --git a/packages/adders/_config/official.ts b/packages/adders/_config/official.ts
index 2afb5764..6beba501 100644
--- a/packages/adders/_config/official.ts
+++ b/packages/adders/_config/official.ts
@@ -9,7 +9,7 @@ import playwright from '../playwright/index.ts';
import prettier from '../prettier/index.ts';
import storybook from '../storybook/index.ts';
import tailwindcss from '../tailwindcss/index.ts';
-import vitest from '../vitest/index.ts';
+import vitest from '../vitest-addon/index.ts';
// The order of adders here determines the order they are displayed inside the CLI
// We generally try to order them by perceived popularity
diff --git a/packages/adders/_tests/_setup/global.ts b/packages/adders/_tests/_setup/global.ts
new file mode 100644
index 00000000..93b6b955
--- /dev/null
+++ b/packages/adders/_tests/_setup/global.ts
@@ -0,0 +1,23 @@
+import { fileURLToPath } from 'node:url';
+import { setup, type ProjectVariant } from 'sv/testing';
+import type { GlobalSetupContext } from 'vitest/node';
+
+const TEST_DIR = fileURLToPath(new URL('../../../../.test-output/adders/', import.meta.url));
+const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts'];
+
+export default async function ({ provide }: GlobalSetupContext) {
+ // downloads different project configurations (sveltekit, js/ts, vite-only, etc)
+ const { templatesDir } = await setup({ cwd: TEST_DIR, variants });
+
+ provide('testDir', TEST_DIR);
+ provide('templatesDir', templatesDir);
+ provide('variants', variants);
+}
+
+declare module 'vitest' {
+ export interface ProvidedContext {
+ testDir: string;
+ templatesDir: string;
+ variants: ProjectVariant[];
+ }
+}
diff --git a/packages/adders/_tests/_setup/suite.ts b/packages/adders/_tests/_setup/suite.ts
new file mode 100644
index 00000000..df151f87
--- /dev/null
+++ b/packages/adders/_tests/_setup/suite.ts
@@ -0,0 +1,114 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import { execSync } from 'node:child_process';
+import * as vitest from 'vitest';
+import { installAddon, type AddonMap, type OptionMap } from 'sv';
+import { createProject, startPreview, type CreateProject, type ProjectVariant } from 'sv/testing';
+import { chromium, type Browser, type Page } from '@playwright/test';
+
+const cwd = vitest.inject('testDir');
+const templatesDir = vitest.inject('templatesDir');
+const variants = vitest.inject('variants');
+
+type Fixtures = {
+ page: Page;
+ run(variant: ProjectVariant, options: OptionMap): Promise;
+};
+
+export function setupTest(addons: Addons) {
+ const test = vitest.test.extend>({} as any);
+
+ let create: CreateProject;
+ let browser: Browser;
+
+ vitest.beforeAll(async () => {
+ browser = await chromium.launch();
+ return async () => {
+ await browser.close();
+ };
+ });
+
+ vitest.beforeAll(({ name }) => {
+ const testName = path.dirname(name).split('/').at(-1)!;
+
+ // constructs a builder for create test projects
+ create = createProject({ cwd, templatesDir, testName });
+
+ // creates a pnpm workspace in each addon dir
+ fs.writeFileSync(
+ path.resolve(cwd, testName, 'pnpm-workspace.yaml'),
+ "packages:\n - '**/*'",
+ 'utf8'
+ );
+ });
+
+ // runs before each test case
+ vitest.beforeEach>(async (ctx) => {
+ const browserCtx = await browser.newContext();
+ ctx.page = await browserCtx.newPage();
+ ctx.run = async (variant, options) => {
+ const cwd = create({ testId: ctx.task.id, variant });
+
+ // test metadata
+ const metaPath = path.resolve(cwd, 'meta.json');
+ fs.writeFileSync(metaPath, JSON.stringify({ variant, options }, null, '\t'), 'utf8');
+
+ // run adder
+ await installAddon({ cwd, addons, options, packageManager: 'pnpm' });
+
+ return cwd;
+ };
+
+ return async () => {
+ await browserCtx.close();
+ // ...other tear downs
+ };
+ });
+
+ return { test, variants, prepareServer };
+}
+
+type PrepareServerOptions = {
+ cwd: string;
+ page: Page;
+ previewCommand?: string;
+ buildCommand?: string;
+ installCommand?: string;
+};
+// installs dependencies, builds the project, and spins up the preview server
+async function prepareServer(
+ {
+ cwd,
+ page,
+ previewCommand = 'npm run preview',
+ buildCommand = 'npm run build',
+ installCommand = 'pnpm install --no-frozen-lockfile'
+ }: PrepareServerOptions,
+ afterInstall?: () => Promise | any
+) {
+ // install deps
+ if (installCommand) execSync(installCommand, { cwd, stdio: 'pipe' });
+
+ // ...do commands and any other extra stuff
+ await afterInstall?.();
+
+ // build project
+ if (buildCommand) execSync(buildCommand, { cwd, stdio: 'pipe' });
+
+ // start preview server
+ const { url, close } = await startPreview({ cwd, command: previewCommand });
+
+ // increases timeout as 30s is not always enough when running the full suite
+ page.setDefaultNavigationTimeout(60_000);
+
+ try {
+ // navigate to the page
+ await page.goto(url);
+ } catch (e) {
+ // cleanup in the instance of a timeout
+ await close();
+ throw e;
+ }
+
+ return { url, close };
+}
diff --git a/packages/adders/_tests/drizzle/docker-compose.yml b/packages/adders/_tests/drizzle/docker-compose.yml
new file mode 100644
index 00000000..f6f5e0a7
--- /dev/null
+++ b/packages/adders/_tests/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/_tests/drizzle/fixtures.ts b/packages/adders/_tests/drizzle/fixtures.ts
new file mode 100644
index 00000000..a6e2f803
--- /dev/null
+++ b/packages/adders/_tests/drizzle/fixtures.ts
@@ -0,0 +1,26 @@
+export const pageServer = `
+import { db } from '$lib/server/db';
+import { user } from '$lib/server/db/schema.js';
+
+export const load = async () => {
+ await insertUser({ name: 'Foobar', id: 0, age: 20 }).catch((err) => console.error(err));
+
+ const users = await db.select().from(user);
+
+ return { users };
+};
+
+function insertUser(value) {
+ return db.insert(user).values(value);
+}
+`;
+
+export const pageComp = `
+
+
+{#each data.users as user}
+ {user.id} {user.name}
+{/each}
+`;
diff --git a/packages/adders/_tests/drizzle/test.ts b/packages/adders/_tests/drizzle/test.ts
new file mode 100644
index 00000000..2a6d7230
--- /dev/null
+++ b/packages/adders/_tests/drizzle/test.ts
@@ -0,0 +1,64 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import process from 'node:process';
+import { fileURLToPath } from 'node:url';
+import { execSync } from 'node:child_process';
+import * as vitest from 'vitest';
+import { expect } from '@playwright/test';
+import { setupTest } from '../_setup/suite.ts';
+import drizzle from '../../drizzle/index.ts';
+import { pageServer, pageComp } from './fixtures.ts';
+
+const { test, variants, prepareServer } = setupTest({ drizzle });
+
+// only linux is supported for running docker containers in github runners
+const noDocker = process.env.CI && process.platform !== 'linux';
+
+vitest.beforeAll(() => {
+ if (noDocker) return;
+ const cwd = path.dirname(fileURLToPath(import.meta.url));
+ execSync('docker compose up --detach', { cwd, stdio: 'pipe' });
+
+ return () => {
+ execSync('docker compose down --volumes', { cwd, stdio: 'pipe' });
+ };
+});
+
+const kitOnly = variants.filter((v) => v.includes('kit'));
+const testCases = [
+ { name: 'better-sqlite3', options: { database: 'sqlite', sqlite: 'better-sqlite3' } },
+ { name: 'libsql', options: { database: 'sqlite', sqlite: 'libsql' } },
+ { name: 'mysql2', options: { database: 'mysql', mysql: 'mysql2', docker: true } },
+ {
+ name: 'postgres.js',
+ options: { database: 'postgresql', postgresql: 'postgres.js', docker: true }
+ }
+].flatMap((opts) => kitOnly.map((variant) => ({ ...opts, variant })));
+
+test.concurrent.for(testCases)(
+ 'queries database - $name - $variant',
+ async ({ options, variant }, { page, ...ctx }) => {
+ if (options.docker && noDocker) ctx.skip();
+ const cwd = await ctx.run(variant, { drizzle: options as any });
+
+ const ts = variant === 'kit-ts';
+ const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`);
+ const content = fs.readFileSync(drizzleConfig, 'utf8').replace('strict: true,', '');
+ fs.writeFileSync(drizzleConfig, content, 'utf8');
+
+ const routes = path.resolve(cwd, 'src', 'routes');
+ const pagePath = path.resolve(routes, '+page.svelte');
+ fs.writeFileSync(pagePath, pageComp, 'utf8');
+
+ const pageServerPath = path.resolve(routes, `+page.server.${ts ? 'ts' : 'js'}`);
+ fs.writeFileSync(pageServerPath, pageServer, 'utf8');
+
+ const { close } = await prepareServer({ cwd, page }, () => {
+ execSync('npm run db:push', { cwd, stdio: 'pipe' });
+ });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ expect(await page.$('[data-testid]')).toBeTruthy();
+ }
+);
diff --git a/packages/adders/_tests/eslint/test.ts b/packages/adders/_tests/eslint/test.ts
new file mode 100644
index 00000000..6a8d3e20
--- /dev/null
+++ b/packages/adders/_tests/eslint/test.ts
@@ -0,0 +1,15 @@
+import { expect } from '@playwright/test';
+import { setupTest } from '../_setup/suite.ts';
+import eslint from '../../eslint/index.ts';
+
+const { test, variants, prepareServer } = setupTest({ eslint });
+
+test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { eslint: {} });
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ expect(true).toBe(true);
+});
diff --git a/packages/adders/_tests/lucia/test.ts b/packages/adders/_tests/lucia/test.ts
new file mode 100644
index 00000000..c95ac959
--- /dev/null
+++ b/packages/adders/_tests/lucia/test.ts
@@ -0,0 +1,20 @@
+import { expect } from '@playwright/test';
+import { setupTest } from '../_setup/suite.ts';
+import lucia from '../../lucia/index.ts';
+import drizzle from '../../drizzle/index.ts';
+
+const { test, variants, prepareServer } = setupTest({ drizzle, lucia });
+
+const kitOnly = variants.filter((v) => v.includes('kit'));
+test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, {
+ drizzle: { database: 'sqlite', sqlite: 'libsql' },
+ lucia: { demo: true }
+ });
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ expect(true).toBe(true);
+});
diff --git a/packages/adders/_tests/mdsvex/fixtures.ts b/packages/adders/_tests/mdsvex/fixtures.ts
new file mode 100644
index 00000000..909f8173
--- /dev/null
+++ b/packages/adders/_tests/mdsvex/fixtures.ts
@@ -0,0 +1,11 @@
+export const svxFile = `
+---
+title: Svex up your markdown
+---
+
+# { title }
+
+## Good stuff in your markdown
+
+Markdown is pretty good but sometimes you just need more.
+`;
diff --git a/packages/adders/_tests/mdsvex/test.ts b/packages/adders/_tests/mdsvex/test.ts
new file mode 100644
index 00000000..13f71ab6
--- /dev/null
+++ b/packages/adders/_tests/mdsvex/test.ts
@@ -0,0 +1,55 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import { expect } from '@playwright/test';
+import { parseSvelte } from '@sveltejs/cli-core/parsers';
+import { imports } from '@sveltejs/cli-core/js';
+import * as html from '@sveltejs/cli-core/html';
+import { setupTest } from '../_setup/suite.ts';
+import { svxFile } from './fixtures.ts';
+import mdsvex from '../../mdsvex/index.ts';
+
+const { test, variants, prepareServer } = setupTest({ mdsvex });
+
+test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { mdsvex: {} });
+
+ // ...add test files
+ addFixture(cwd, variant);
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ expect(await page.$('.mdsvex h1')).toBeTruthy();
+ expect(await page.$('.mdsvex h2')).toBeTruthy();
+ expect(await page.$('.mdsvex p')).toBeTruthy();
+});
+
+function addFixture(cwd: string, variant: string) {
+ let page;
+ let svx;
+ if (variant.startsWith('kit')) {
+ page = path.resolve(cwd, 'src', 'routes', '+page.svelte');
+ svx = path.resolve(cwd, 'src', 'routes', 'Demo.svx');
+ } else {
+ page = path.resolve(cwd, 'src', 'App.svelte');
+ svx = path.resolve(cwd, 'src', 'Demo.svx');
+ }
+
+ const src = fs.readFileSync(page, 'utf8');
+ const { script, template, generateCode } = parseSvelte(src);
+ imports.addDefault(script.ast, './Demo.svx', 'Demo');
+
+ const div = html.div({ class: 'mdsvex' });
+ html.appendElement(template.ast.childNodes, div);
+ const mdsvexNode = html.element('Demo');
+ html.appendElement(div.childNodes, mdsvexNode);
+
+ const content = generateCode({
+ script: script.generateCode(),
+ template: template.generateCode()
+ });
+
+ fs.writeFileSync(page, content, 'utf8');
+ fs.writeFileSync(svx, svxFile, 'utf8');
+}
diff --git a/packages/adders/_tests/paraglide/test.ts b/packages/adders/_tests/paraglide/test.ts
new file mode 100644
index 00000000..e2d2ac01
--- /dev/null
+++ b/packages/adders/_tests/paraglide/test.ts
@@ -0,0 +1,16 @@
+import { expect } from '@playwright/test';
+import { setupTest } from '../_setup/suite.ts';
+import paraglide from '../../paraglide/index.ts';
+
+const { test, variants, prepareServer } = setupTest({ paraglide });
+
+const kitOnly = variants.filter((v) => v.includes('kit'));
+test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { paraglide: { demo: true, availableLanguageTags: 'en' } });
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ expect(true).toBe(true);
+});
diff --git a/packages/adders/_tests/playwright/test.ts b/packages/adders/_tests/playwright/test.ts
new file mode 100644
index 00000000..e8d735f7
--- /dev/null
+++ b/packages/adders/_tests/playwright/test.ts
@@ -0,0 +1,15 @@
+import { expect } from '@playwright/test';
+import { setupTest } from '../_setup/suite.ts';
+import playwright from '../../playwright/index.ts';
+
+const { test, variants, prepareServer } = setupTest({ playwright });
+
+test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { playwright: {} });
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ expect(true).toBe(true);
+});
diff --git a/packages/adders/_tests/prettier/test.ts b/packages/adders/_tests/prettier/test.ts
new file mode 100644
index 00000000..1b3f2992
--- /dev/null
+++ b/packages/adders/_tests/prettier/test.ts
@@ -0,0 +1,15 @@
+import { expect } from '@playwright/test';
+import { setupTest } from '../_setup/suite.ts';
+import prettier from '../../prettier/index.ts';
+
+const { test, variants, prepareServer } = setupTest({ prettier });
+
+test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { prettier: {} });
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ expect(true).toBe(true);
+});
diff --git a/packages/adders/_tests/storybook/test.ts b/packages/adders/_tests/storybook/test.ts
new file mode 100644
index 00000000..4fdc82a4
--- /dev/null
+++ b/packages/adders/_tests/storybook/test.ts
@@ -0,0 +1,28 @@
+import process from 'node:process';
+import { expect } from '@playwright/test';
+import { setupTest } from '../_setup/suite.ts';
+import storybook from '../../storybook/index.ts';
+
+const { test, variants, prepareServer } = setupTest({ storybook });
+
+let port = 6006;
+
+const skip = process.env.CI && process.platform === 'win32';
+test.skipIf(skip).concurrent.for(variants)(
+ 'storybook loaded - %s',
+ async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { storybook: {} });
+
+ const { close } = await prepareServer({
+ cwd,
+ page,
+ previewCommand: `pnpm storybook -p ${++port} --ci`,
+ buildCommand: ''
+ });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ expect(await page.$('main .sb-bar')).toBeTruthy();
+ expect(await page.$('#storybook-preview-wrapper')).toBeTruthy();
+ }
+);
diff --git a/packages/adders/_tests/tailwindcss/fixtures.ts b/packages/adders/_tests/tailwindcss/fixtures.ts
new file mode 100644
index 00000000..737a10fc
--- /dev/null
+++ b/packages/adders/_tests/tailwindcss/fixtures.ts
@@ -0,0 +1,19 @@
+import fs from 'node:fs';
+import path from 'node:path';
+
+const markup = `
+
+`;
+
+export function addFixture(cwd: string, variant: string) {
+ let page;
+ if (variant.startsWith('kit')) {
+ page = path.resolve(cwd, 'src', 'routes', '+page.svelte');
+ } else {
+ page = path.resolve(cwd, 'src', 'App.svelte');
+ }
+ const content = fs.readFileSync(page, 'utf8') + markup;
+ fs.writeFileSync(page, content, 'utf8');
+}
diff --git a/packages/adders/_tests/tailwindcss/test.ts b/packages/adders/_tests/tailwindcss/test.ts
new file mode 100644
index 00000000..1ede1055
--- /dev/null
+++ b/packages/adders/_tests/tailwindcss/test.ts
@@ -0,0 +1,40 @@
+import { expect } from '@playwright/test';
+import { setupTest } from '../_setup/suite.ts';
+import { addFixture } from './fixtures.ts';
+import tailwindcss from '../../tailwindcss/index.ts';
+
+const { test, variants, prepareServer } = setupTest({ tailwindcss });
+
+test.concurrent.for(variants)('none - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { tailwindcss: { plugins: [] } });
+
+ // ...add test files
+ addFixture(cwd, variant);
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ const el = page.getByTestId('base');
+ await expect(el).toHaveCSS('background-color', 'rgb(71, 85, 105)');
+ await expect(el).toHaveCSS('border-color', 'rgb(249, 250, 251)');
+ await expect(el).toHaveCSS('border-width', '4px');
+ await expect(el).toHaveCSS('margin-top', '4px');
+});
+
+test.concurrent.for(variants)('typography - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { tailwindcss: { plugins: ['typography'] } });
+
+ // ...add files
+ addFixture(cwd, variant);
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ const el = page.getByTestId('typography');
+ await expect(el).toHaveCSS('font-size', '18px');
+ await expect(el).toHaveCSS('line-height', '28px');
+ await expect(el).toHaveCSS('text-align', 'right');
+ await expect(el).toHaveCSS('text-decoration-line', 'line-through');
+});
diff --git a/packages/adders/_tests/vitest/test.ts b/packages/adders/_tests/vitest/test.ts
new file mode 100644
index 00000000..ed451996
--- /dev/null
+++ b/packages/adders/_tests/vitest/test.ts
@@ -0,0 +1,15 @@
+import { expect } from '@playwright/test';
+import { setupTest } from '../_setup/suite.ts';
+import vitest from '../../vitest-addon/index.ts';
+
+const { test, variants, prepareServer } = setupTest({ vitest });
+
+test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => {
+ const cwd = await ctx.run(variant, { vitest: {} });
+
+ const { close } = await prepareServer({ cwd, page });
+ // kill server process when we're done
+ ctx.onTestFinished(async () => await close());
+
+ expect(true).toBe(true);
+});
diff --git a/packages/adders/drizzle/index.ts b/packages/adders/drizzle/index.ts
index f3174054..69a15b9c 100644
--- a/packages/adders/drizzle/index.ts
+++ b/packages/adders/drizzle/index.ts
@@ -8,7 +8,7 @@ const PORTS = {
sqlite: ''
} as const;
-export const options = defineAdderOptions({
+const options = defineAdderOptions({
database: {
question: 'Which database would you like to use?',
type: 'select',
@@ -204,7 +204,7 @@ export default defineAdder({
imports.addNamed(ast, 'drizzle-kit', { defineConfig: 'defineConfig' });
const envCheckStatement = common.statementFromString(
- `if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');`
+ "if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');"
);
common.addStatement(ast, envCheckStatement);
@@ -306,7 +306,7 @@ export default defineAdder({
// env var checks
const dbURLCheck = common.statementFromString(
- `if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');`
+ "if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');"
);
common.addStatement(ast, dbURLCheck);
@@ -326,7 +326,7 @@ export default defineAdder({
imports.addNamed(ast, '$app/environment', { dev: 'dev' });
// auth token check in prod
const authTokenCheck = common.statementFromString(
- `if (!dev && !env.DATABASE_AUTH_TOKEN) throw new Error('DATABASE_AUTH_TOKEN is not set');`
+ "if (!dev && !env.DATABASE_AUTH_TOKEN) throw new Error('DATABASE_AUTH_TOKEN is not set');"
);
common.addStatement(ast, authTokenCheck);
diff --git a/packages/adders/drizzle/tests.ts b/packages/adders/drizzle/tests.ts
deleted file mode 100644
index 3257b575..00000000
--- a/packages/adders/drizzle/tests.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { options } from './index.ts';
-import { defineAdderTests } from '@sveltejs/cli-core';
-import { parseSvelte, parseJson } from '@sveltejs/cli-core/parsers';
-
-const defaultOptionValues = {
- sqlite: options.sqlite.default,
- mysql: options.mysql.default,
- postgresql: options.postgresql.default,
- docker: options.docker.default
-};
-
-export const tests = defineAdderTests({
- options,
- optionValues: [
- { ...defaultOptionValues, database: 'sqlite', sqlite: 'better-sqlite3' },
- { ...defaultOptionValues, database: 'sqlite', sqlite: 'libsql' },
- { ...defaultOptionValues, database: 'mysql', mysql: 'mysql2', docker: true },
- { ...defaultOptionValues, database: 'postgresql', postgresql: 'postgres.js', docker: true }
- ],
- files: [
- {
- name: ({ kit }) => `${kit?.routesDirectory}/+page.svelte`,
- condition: ({ kit }) => Boolean(kit),
- content: ({ content }) => {
- const { script, template, generateCode } = parseSvelte(content);
- const dataProp = '\nexport let data;';
- const eachBlock = `
- {#each data.users as user}
- {user.id} {user.name}
- {/each}`;
- return generateCode({
- script: script.source + dataProp,
- template: template.source + eachBlock
- });
- }
- },
- {
- name: ({ kit, typescript }) =>
- `${kit?.routesDirectory}/+page.server.${typescript ? 'ts' : 'js'}`,
- condition: ({ kit }) => Boolean(kit),
- content: ({ typescript }) => {
- return `
- import { db } from '$lib/server/db';
- import { user } from '$lib/server/db/schema.js';
-
- export const load = async () => {
- await insertUser({ name: 'Foobar', id: 0, age: 20 }).catch((err) => console.error(err));
-
- const users = await db.select().from(user);
-
- return { users };
- };
-
- function insertUser(${typescript ? 'value: typeof user.$inferInsert' : 'value'}) {
- return db.insert(user).values(value);
- }
- `;
- }
- },
- {
- // override the config so we can remove strict mode
- name: ({ typescript }) => `drizzle.config.${typescript ? 'ts' : 'js'}`,
- condition: ({ kit }) => Boolean(kit),
- 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();
- }
- }
- ],
- tests: [
- {
- name: 'queries database',
- run: async ({ elementExists }) => {
- await elementExists('[data-test-id]');
- }
- }
- ]
-});
diff --git a/packages/adders/eslint/tests.ts b/packages/adders/eslint/tests.ts
deleted file mode 100644
index 764975ed..00000000
--- a/packages/adders/eslint/tests.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { defineAdderTests } from '@sveltejs/cli-core';
-
-export const tests = defineAdderTests({
- files: [],
- options: {},
- optionValues: [],
- tests: []
-});
diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts
index f66df276..18e9aaa7 100644
--- a/packages/adders/lucia/index.ts
+++ b/packages/adders/lucia/index.ts
@@ -25,7 +25,7 @@ type Dialect = 'mysql' | 'postgresql' | 'sqlite';
let drizzleDialect: Dialect;
let schemaPath: string;
-export const options = defineAdderOptions({
+const options = defineAdderOptions({
demo: {
type: 'boolean',
default: true,
@@ -121,21 +121,21 @@ export default defineAdder({
integer: 'integer'
});
object.overrideProperties(userAttributes, {
- id: common.expressionFromString(`text('id').primaryKey()`)
+ id: common.expressionFromString("text('id').primaryKey()")
});
if (options.demo) {
object.overrideProperties(userAttributes, {
- username: common.expressionFromString(`text('username').notNull().unique()`),
- passwordHash: common.expressionFromString(`text('password_hash').notNull()`)
+ username: common.expressionFromString("text('username').notNull().unique()"),
+ passwordHash: common.expressionFromString("text('password_hash').notNull()")
});
}
object.overrideProperties(sessionAttributes, {
- id: common.expressionFromString(`text('id').primaryKey()`),
+ id: common.expressionFromString("text('id').primaryKey()"),
userId: common.expressionFromString(
- `text('user_id').notNull().references(() => user.id)`
+ "text('user_id').notNull().references(() => user.id)"
),
expiresAt: common.expressionFromString(
- `integer('expires_at', { mode: 'timestamp' }).notNull()`
+ "integer('expires_at', { mode: 'timestamp' }).notNull()"
)
});
}
@@ -146,24 +146,24 @@ export default defineAdder({
datetime: 'datetime'
});
object.overrideProperties(userAttributes, {
- id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`)
+ id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()")
});
if (options.demo) {
object.overrideProperties(userAttributes, {
username: common.expressionFromString(
- `varchar('username', { length: 32 }).notNull().unique()`
+ "varchar('username', { length: 32 }).notNull().unique()"
),
passwordHash: common.expressionFromString(
- `varchar('password_hash', { length: 255 }).notNull()`
+ "varchar('password_hash', { length: 255 }).notNull()"
)
});
}
object.overrideProperties(sessionAttributes, {
- id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`),
+ id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()"),
userId: common.expressionFromString(
- `varchar('user_id', { length: 255 }).notNull().references(() => user.id)`
+ "varchar('user_id', { length: 255 }).notNull().references(() => user.id)"
),
- expiresAt: common.expressionFromString(`datetime('expires_at').notNull()`)
+ expiresAt: common.expressionFromString("datetime('expires_at').notNull()")
});
}
if (drizzleDialect === 'postgresql') {
@@ -173,21 +173,21 @@ export default defineAdder({
timestamp: 'timestamp'
});
object.overrideProperties(userAttributes, {
- id: common.expressionFromString(`text('id').primaryKey()`)
+ id: common.expressionFromString("text('id').primaryKey()")
});
if (options.demo) {
object.overrideProperties(userAttributes, {
- username: common.expressionFromString(`text('username').notNull().unique()`),
- passwordHash: common.expressionFromString(`text('password_hash').notNull()`)
+ username: common.expressionFromString("text('username').notNull().unique()"),
+ passwordHash: common.expressionFromString("text('password_hash').notNull()")
});
}
object.overrideProperties(sessionAttributes, {
- id: common.expressionFromString(`text('id').primaryKey()`),
+ id: common.expressionFromString("text('id').primaryKey()"),
userId: common.expressionFromString(
- `text('user_id').notNull().references(() => user.id)`
+ "text('user_id').notNull().references(() => user.id)"
),
expiresAt: common.expressionFromString(
- `timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()`
+ "timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()"
)
});
}
@@ -396,7 +396,7 @@ export default defineAdder({
import * as auth from '$lib/server/auth';
import { db } from '$lib/server/db';
import * as table from '$lib/server/db/schema';
- ${ts(`import type { Actions, PageServerLoad } from './$types';\n`)}
+ ${ts("import type { Actions, PageServerLoad } from './$types';\n")}
export const load${ts(': PageServerLoad')} = async (event) => {
if (event.locals.user) {
return redirect(302, '/demo/lucia');
@@ -516,9 +516,9 @@ export default defineAdder({
const svelte5 = !!dependencyVersion('svelte')?.startsWith('5');
const [ts, s5] = utils.createPrinter(typescript, svelte5);
return dedent`
-
@@ -555,7 +555,7 @@ export default defineAdder({
return dedent`
import * as auth from '$lib/server/auth';
import { fail, redirect } from '@sveltejs/kit';
- ${ts(`import type { Actions, PageServerLoad } from './$types';\n`)}
+ ${ts("import type { Actions, PageServerLoad } from './$types';\n")}
export const load${ts(': PageServerLoad')} = async (event) => {
if (!event.locals.user) {
return redirect(302, '/demo/lucia/login');
@@ -590,9 +590,9 @@ export default defineAdder({
const svelte5 = !!dependencyVersion('svelte')?.startsWith('5');
const [ts, s5] = utils.createPrinter(typescript, svelte5);
return dedent`
-
diff --git a/packages/adders/lucia/tests.ts b/packages/adders/lucia/tests.ts
deleted file mode 100644
index cf23fa33..00000000
--- a/packages/adders/lucia/tests.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { defineAdderTests } from '@sveltejs/cli-core';
-import { options } from './index.ts';
-
-export const tests = defineAdderTests({
- files: [],
- options,
- optionValues: [],
- tests: []
-});
diff --git a/packages/adders/mdsvex/tests.ts b/packages/adders/mdsvex/tests.ts
deleted file mode 100644
index 503d2a1b..00000000
--- a/packages/adders/mdsvex/tests.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { defineAdderTests, type OptionDefinition, type FileEditor } from '@sveltejs/cli-core';
-import { imports } from '@sveltejs/cli-core/js';
-import * as html from '@sveltejs/cli-core/html';
-import { parseSvelte } from '@sveltejs/cli-core/parsers';
-
-export const tests = defineAdderTests({
- files: [
- {
- name: ({ kit }) => `${kit?.routesDirectory}/+page.svelte`,
- content: useMarkdownFile,
- condition: ({ kit }) => Boolean(kit)
- },
- {
- name: () => 'src/App.svelte',
- content: useMarkdownFile,
- condition: ({ kit }) => !kit
- },
- {
- name: ({ kit }) => `${kit?.routesDirectory}/Demo.svx`,
- content: addMarkdownFile,
- condition: ({ kit }) => Boolean(kit)
- },
- {
- name: () => 'src/Demo.svx',
- content: addMarkdownFile,
- condition: ({ kit }) => !kit
- }
- ],
- options: {},
- optionValues: [],
- tests: [
- {
- name: 'elements exist',
- run: async ({ elementExists }) => {
- await elementExists('.mdsvex h1');
- await elementExists('.mdsvex h2');
- await elementExists('.mdsvex p');
- }
- }
- ]
-});
-
-function addMarkdownFile({ content }: FileEditor) {
- // example taken from website: https://mdsvex.pngwn.io
- return (
- content +
- `
----
-title: Svex up your markdown
----
-
-# { title }
-
-## Good stuff in your markdown
-
-Markdown is pretty good but sometimes you just need more.
-`
- );
-}
-
-function useMarkdownFile({ content }: FileEditor) {
- const { script, template, generateCode } = parseSvelte(content);
- imports.addDefault(script.ast, './Demo.svx', 'Demo');
-
- const div = html.div({ class: 'mdsvex' });
- html.appendElement(template.ast.childNodes, div);
- const mdsvexNode = html.element('Demo');
- html.appendElement(div.childNodes, mdsvexNode);
- return generateCode({ script: script.generateCode(), template: template.generateCode() });
-}
diff --git a/packages/adders/package.json b/packages/adders/package.json
index c580c405..05a0f370 100644
--- a/packages/adders/package.json
+++ b/packages/adders/package.json
@@ -6,14 +6,11 @@
"scripts": {
"check": "tsc",
"format": "pnpm lint --write",
- "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore"
- },
- "exports": {
- ".": {
- "types": "./index.ts",
- "default": "./index.ts"
- }
+ "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore",
+ "test": "vitest run",
+ "test:ui": "vitest --ui"
},
+ "exports": "./index.ts",
"dependencies": {
"@sveltejs/cli-core": "workspace:*"
}
diff --git a/packages/adders/paraglide/index.ts b/packages/adders/paraglide/index.ts
index 459f0295..b2f1b49d 100644
--- a/packages/adders/paraglide/index.ts
+++ b/packages/adders/paraglide/index.ts
@@ -32,7 +32,7 @@ const DEFAULT_INLANG_PROJECT = {
}
};
-export const options = defineAdderOptions({
+const options = defineAdderOptions({
availableLanguageTags: {
question: `Which languages would you like to support? ${colors.gray('(e.g. en,de-ch)')}`,
type: 'string',
diff --git a/packages/adders/paraglide/tests.ts b/packages/adders/paraglide/tests.ts
deleted file mode 100644
index 8941a20b..00000000
--- a/packages/adders/paraglide/tests.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { defineAdderTests } from '@sveltejs/cli-core';
-import { options } from './index.ts';
-// e2e tests make no sense in this context
-
-export const tests = defineAdderTests({
- files: [],
- options,
- optionValues: [],
- tests: []
-});
diff --git a/packages/adders/playwright/tests.ts b/packages/adders/playwright/tests.ts
deleted file mode 100644
index 764975ed..00000000
--- a/packages/adders/playwright/tests.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { defineAdderTests } from '@sveltejs/cli-core';
-
-export const tests = defineAdderTests({
- files: [],
- options: {},
- optionValues: [],
- tests: []
-});
diff --git a/packages/adders/prettier/tests.ts b/packages/adders/prettier/tests.ts
deleted file mode 100644
index 764975ed..00000000
--- a/packages/adders/prettier/tests.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { defineAdderTests } from '@sveltejs/cli-core';
-
-export const tests = defineAdderTests({
- files: [],
- options: {},
- optionValues: [],
- tests: []
-});
diff --git a/packages/adders/storybook/index.ts b/packages/adders/storybook/index.ts
index 9a76cbef..20fdc5e8 100644
--- a/packages/adders/storybook/index.ts
+++ b/packages/adders/storybook/index.ts
@@ -9,7 +9,7 @@ export default defineAdder({
scripts: [
{
description: 'applies storybook',
- args: ['storybook@latest', 'init', '--skip-install', '--no-dev'],
+ args: ['storybook@8.3.6', 'init', '--skip-install', '--no-dev'],
stdio: 'inherit'
}
],
diff --git a/packages/adders/storybook/tests.ts b/packages/adders/storybook/tests.ts
deleted file mode 100644
index 5fb56a32..00000000
--- a/packages/adders/storybook/tests.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { defineAdderTests } from '@sveltejs/cli-core';
-
-let port = 6006;
-
-export const tests = defineAdderTests({
- options: {},
- optionValues: [],
- get command() {
- return `storybook -p ${port++} --ci`;
- },
- files: [],
- tests: [
- {
- name: 'storybook loaded',
- run: async ({ elementExists }) => {
- await elementExists('main .sb-bar');
- await elementExists('#storybook-preview-wrapper');
- }
- }
- ]
-});
diff --git a/packages/adders/tailwindcss/index.ts b/packages/adders/tailwindcss/index.ts
index 4993f9fb..b0f30d33 100644
--- a/packages/adders/tailwindcss/index.ts
+++ b/packages/adders/tailwindcss/index.ts
@@ -45,7 +45,7 @@ const pluginPackages: Array> = plugins.map((x)
condition: ({ options }) => options.plugins.includes(x.id)
}));
-export const options = defineAdderOptions({
+const options = defineAdderOptions({
plugins: {
type: 'multiselect',
question: 'Which plugins would you like to add?',
diff --git a/packages/adders/tailwindcss/tests.ts b/packages/adders/tailwindcss/tests.ts
deleted file mode 100644
index ea28b2af..00000000
--- a/packages/adders/tailwindcss/tests.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { defineAdderTests } from '@sveltejs/cli-core';
-import { options } from './index.ts';
-
-const divId = 'myDiv';
-const typographyDivId = 'myTypographyDiv';
-
-export const tests = defineAdderTests({
- files: [
- {
- name: ({ kit }) => `${kit?.routesDirectory}/+page.svelte`,
- content: ({ content, options }) => {
- content = prepareCoreTest(content);
- if (options.plugins.includes('typography')) content = prepareTypographyTest(content);
- return content;
- },
- condition: ({ kit }) => Boolean(kit)
- },
- {
- name: () => 'src/App.svelte',
- content: ({ content, options }) => {
- content = prepareCoreTest(content);
- if (options.plugins.includes('typography')) content = prepareTypographyTest(content);
- return content;
- },
- condition: ({ kit }) => !kit
- }
- ],
- options,
- optionValues: [{ plugins: [] }, { plugins: ['typography'] }],
- tests: [
- {
- name: 'core properties',
- run: async ({ expectProperty }) => {
- const selector = '#' + divId;
- await expectProperty(selector, 'background-color', 'rgb(71, 85, 105)');
- await expectProperty(selector, 'border-color', 'rgb(249, 250, 251)');
- await expectProperty(selector, 'border-width', '4px');
- await expectProperty(selector, 'margin-top', '4px');
- }
- },
- {
- name: 'typography properties',
- condition: ({ plugins }) => plugins.includes('typography'),
- run: async ({ expectProperty }) => {
- const selector = '#' + typographyDivId;
- await expectProperty(selector, 'font-size', '18px');
- await expectProperty(selector, 'line-height', '28px');
- await expectProperty(selector, 'text-align', 'right');
- await expectProperty(selector, 'text-decoration-line', 'line-through');
- }
- }
- ]
-});
-
-function prepareCoreTest(content: string) {
- const div = ``;
- return content + div;
-}
-
-function prepareTypographyTest(content: string) {
- const p = ``;
- return content + p;
-}
diff --git a/packages/adders/vitest/index.ts b/packages/adders/vitest-addon/index.ts
similarity index 100%
rename from packages/adders/vitest/index.ts
rename to packages/adders/vitest-addon/index.ts
diff --git a/packages/adders/vitest/logo.svg b/packages/adders/vitest-addon/logo.svg
similarity index 100%
rename from packages/adders/vitest/logo.svg
rename to packages/adders/vitest-addon/logo.svg
diff --git a/packages/adders/vitest.config.ts b/packages/adders/vitest.config.ts
new file mode 100644
index 00000000..9f43ca88
--- /dev/null
+++ b/packages/adders/vitest.config.ts
@@ -0,0 +1,15 @@
+import { env } from 'node:process';
+import { defineConfig } from 'vitest/config';
+
+const ONE_MINUTE = 1000 * 60;
+
+export default defineConfig({
+ test: {
+ name: 'adders',
+ include: ['_tests/**/test.{js,ts}'],
+ globalSetup: ['_tests/_setup/global.ts'],
+ testTimeout: ONE_MINUTE * 3,
+ hookTimeout: ONE_MINUTE * 3,
+ retry: env.CI ? 3 : 0
+ }
+});
diff --git a/packages/adders/vitest/tests.ts b/packages/adders/vitest/tests.ts
deleted file mode 100644
index 764975ed..00000000
--- a/packages/adders/vitest/tests.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { defineAdderTests } from '@sveltejs/cli-core';
-
-export const tests = defineAdderTests({
- files: [],
- options: {},
- optionValues: [],
- tests: []
-});
diff --git a/packages/cli/bin.ts b/packages/cli/bin.ts
index 4a4c8924..838dda5d 100644
--- a/packages/cli/bin.ts
+++ b/packages/cli/bin.ts
@@ -6,7 +6,7 @@ import { add } from './commands/add/index.ts';
import { create } from './commands/create.ts';
import { migrate } from './commands/migrate.ts';
import { check } from './commands/check.ts';
-import { helpConfig } from './common.ts';
+import { helpConfig } from './utils/common.ts';
program.name(pkg.name).version(pkg.version, '-v, --version').configureHelp(helpConfig);
program.addCommand(create).addCommand(add).addCommand(migrate).addCommand(check);
diff --git a/packages/cli/utils/fetch-packages.ts b/packages/cli/commands/add/fetch-packages.ts
similarity index 98%
rename from packages/cli/utils/fetch-packages.ts
rename to packages/cli/commands/add/fetch-packages.ts
index 9bb3e8ff..d14be995 100644
--- a/packages/cli/utils/fetch-packages.ts
+++ b/packages/cli/commands/add/fetch-packages.ts
@@ -7,7 +7,7 @@ import { fileURLToPath } from 'node:url';
import type { AdderWithoutExplicitArgs } from '@sveltejs/cli-core';
// path to the `node_modules` directory of `sv`
-const NODE_MODULES = path.join(fileURLToPath(import.meta.url), '..', '..', 'node_modules');
+const NODE_MODULES = fileURLToPath(new URL('../node_modules', import.meta.url));
const REGISTRY = 'https://registry.npmjs.org';
export const Directive = { file: 'file:', npm: 'npm:' };
diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts
index a91ea35c..de05a29b 100644
--- a/packages/cli/commands/add/index.ts
+++ b/packages/cli/commands/add/index.ts
@@ -15,11 +15,13 @@ import {
getCommunityAdder
} from '@sveltejs/adders';
import type { AdderWithoutExplicitArgs, OptionValues } from '@sveltejs/cli-core';
-import * as common from '../../common.ts';
-import { Directive, downloadPackage, getPackageJSON } from '../../utils/fetch-packages.ts';
+import * as common from '../../utils/common.ts';
import { createWorkspace } from './workspace.ts';
-import { getHighlighter, installPackages } from './utils.ts';
import { createOrUpdateFiles } from './processor.ts';
+import { getGlobalPreconditions } from './preconditions.ts';
+import { formatFiles, getHighlighter, installPackages } from './utils.ts';
+import { Directive, downloadPackage, getPackageJSON } from './fetch-packages.ts';
+import { installDependencies, packageManagerPrompt } from '../../utils/package-manager.ts';
const AddersSchema = v.array(v.string());
const AdderOptionFlagsSchema = v.object({
@@ -333,7 +335,7 @@ export async function runAddCommand(
const { kit } = createWorkspace({ cwd: options.cwd });
const projectType = kit ? 'kit' : 'svelte';
const adders = selectedAdders.map(({ adder }) => adder);
- const { preconditions } = common.getGlobalPreconditions(options.cwd, projectType, adders);
+ const { preconditions } = getGlobalPreconditions(options.cwd, projectType, adders);
const fails: Array<{ name: string; message?: string }> = [];
for (const condition of preconditions) {
@@ -425,7 +427,7 @@ export async function runAddCommand(
// prompt for package manager
let packageManager: AgentName | undefined;
if (options.install) {
- packageManager = await common.packageManagerPrompt(options.cwd);
+ packageManager = await packageManagerPrompt(options.cwd);
}
// apply adders
@@ -434,7 +436,7 @@ export async function runAddCommand(
// install dependencies
if (packageManager && options.install) {
- await common.installDependencies(packageManager, options.cwd);
+ await installDependencies(packageManager, options.cwd);
}
// format modified/created files with prettier (if available)
@@ -443,7 +445,7 @@ export async function runAddCommand(
const { start, stop } = p.spinner();
start('Formatting modified files');
try {
- await common.formatFiles({ packageManager, cwd: options.cwd, paths: filesToFormat });
+ await formatFiles({ packageManager, cwd: options.cwd, paths: filesToFormat });
stop('Successfully formatted modified files');
} catch (e) {
stop('Failed to format files');
@@ -545,7 +547,10 @@ async function runAdders({
if (workspace.packageManager === 'npm') args.unshift('--yes');
try {
- await exec(command, args, { nodeOptions: { cwd: workspace.cwd, stdio: script.stdio } });
+ await exec(command, args, {
+ nodeOptions: { cwd: workspace.cwd, stdio: script.stdio },
+ throwOnError: true
+ });
} catch (error) {
const typedError = error as Error;
throw new Error(
diff --git a/packages/cli/commands/add/preconditions.ts b/packages/cli/commands/add/preconditions.ts
new file mode 100644
index 00000000..50f90098
--- /dev/null
+++ b/packages/cli/commands/add/preconditions.ts
@@ -0,0 +1,66 @@
+import { exec } from 'tinyexec';
+import type { AdderWithoutExplicitArgs, Precondition } from '@sveltejs/cli-core';
+
+type PreconditionCheck = { name: string; preconditions: Precondition[] };
+export function getGlobalPreconditions(
+ cwd: string,
+ projectType: 'svelte' | 'kit',
+ adders: AdderWithoutExplicitArgs[]
+): PreconditionCheck {
+ return {
+ name: 'global checks',
+ preconditions: [
+ {
+ name: 'clean working directory',
+ run: async () => {
+ try {
+ // If a user has pending git changes the output of the following command will list
+ // all files that have been added/modified/deleted and thus the output will not be empty.
+ // In case the output of the command below is an empty text, we can safely assume
+ // there are no pending changes. If the below command is run outside of a git repository,
+ // git will exit with a failing exit code, which will trigger the catch statement.
+ // also see https://remarkablemark.org/blog/2017/10/12/check-git-dirty/#git-status
+ const { stdout } = await exec('git', ['status', '--short'], {
+ nodeOptions: { cwd },
+ throwOnError: true
+ });
+
+ if (stdout) {
+ return { success: false, message: 'Found modified files' };
+ }
+
+ return { success: true, message: undefined };
+ } catch {
+ return { success: true, message: 'Not a git repository' };
+ }
+ }
+ },
+ {
+ name: 'supported environments',
+ run: () => {
+ const addersForInvalidEnvironment = adders.filter((a) => {
+ const supportedEnvironments = a.environments;
+ if (projectType === 'kit' && !supportedEnvironments.kit) return true;
+ if (projectType === 'svelte' && !supportedEnvironments.svelte) return true;
+
+ return false;
+ });
+
+ if (addersForInvalidEnvironment.length === 0) {
+ return { success: true, message: undefined };
+ }
+
+ const messages = addersForInvalidEnvironment.map((a) => {
+ if (projectType === 'kit') {
+ return `'${a.id}' does not support SvelteKit`;
+ } else {
+ return `'${a.id}' requires SvelteKit`;
+ }
+ });
+
+ throw new Error(messages.join('\n'));
+ }
+ }
+ ]
+ };
+}
diff --git a/packages/cli/commands/add/processor.ts b/packages/cli/commands/add/processor.ts
index 8f635243..46c3e7c8 100644
--- a/packages/cli/commands/add/processor.ts
+++ b/packages/cli/commands/add/processor.ts
@@ -21,12 +21,14 @@ export function createOrUpdateFiles(
let content = exists ? readFile(workspace.cwd, fileDetails.name(workspace)) : '';
// process file
content = fileDetails.content({ content, ...workspace });
+ if (!content) continue;
writeFile(workspace, fileDetails.name(workspace), content);
changedFiles.push(fileDetails.name(workspace));
} catch (e) {
- if (e instanceof Error)
+ if (e instanceof Error) {
throw new Error(`Unable to process '${fileDetails.name(workspace)}'. Reason: ${e.message}`);
+ }
throw e;
}
}
diff --git a/packages/cli/commands/add/utils.ts b/packages/cli/commands/add/utils.ts
index 0651fadf..55051644 100644
--- a/packages/cli/commands/add/utils.ts
+++ b/packages/cli/commands/add/utils.ts
@@ -1,8 +1,10 @@
import fs from 'node:fs';
import path from 'node:path';
import pc from 'picocolors';
+import { exec } from 'tinyexec';
import { parseJson } from '@sveltejs/cli-core/parsers';
import type { Adder, Highlighter, Workspace } from '@sveltejs/cli-core';
+import { resolveCommand, type AgentName } from 'package-manager-detector';
export type Package = {
name: string;
@@ -15,7 +17,11 @@ export type Package = {
workspaces?: string[];
};
-export function getPackageJson(cwd: string) {
+export function getPackageJson(cwd: string): {
+ source: string;
+ data: Package;
+ generateCode: () => string;
+} {
const packageText = readFile(cwd, commonFilePaths.packageJson);
if (!packageText) {
const pkgPath = path.join(cwd, commonFilePaths.packageJson);
@@ -26,8 +32,21 @@ export function getPackageJson(cwd: string) {
return { source: packageText, data: data as Package, generateCode };
}
+export async function formatFiles(options: {
+ packageManager: AgentName;
+ cwd: string;
+ paths: string[];
+}): Promise {
+ const args = ['prettier', '--write', '--ignore-unknown', ...options.paths];
+ const cmd = resolveCommand(options.packageManager, 'execute-local', args)!;
+ await exec(cmd.command, cmd.args, {
+ nodeOptions: { cwd: options.cwd, stdio: 'pipe' },
+ throwOnError: true
+ });
+}
+
export function readFile(cwd: string, filePath: string): string {
- const fullFilePath = getFilePath(cwd, filePath);
+ const fullFilePath = path.resolve(cwd, filePath);
if (!fileExists(cwd, filePath)) {
return '';
@@ -72,7 +91,7 @@ function alphabetizeProperties(obj: Record) {
}
export function writeFile(workspace: Workspace, filePath: string, content: string): void {
- const fullFilePath = getFilePath(workspace.cwd, filePath);
+ const fullFilePath = path.resolve(workspace.cwd, filePath);
const fullDirectoryPath = path.dirname(fullFilePath);
if (content && !content.endsWith('\n')) content += '\n';
@@ -85,14 +104,10 @@ export function writeFile(workspace: Workspace, filePath: string, content:
}
export function fileExists(cwd: string, filePath: string): boolean {
- const fullFilePath = getFilePath(cwd, filePath);
+ const fullFilePath = path.resolve(cwd, filePath);
return fs.existsSync(fullFilePath);
}
-export function getFilePath(cwd: string, fileName: string): string {
- return path.join(cwd, fileName);
-}
-
export const commonFilePaths = {
packageJson: 'package.json',
svelteConfig: 'svelte.config.js',
diff --git a/packages/cli/commands/add/workspace.ts b/packages/cli/commands/add/workspace.ts
index 6e93d7e5..ac4d396f 100644
--- a/packages/cli/commands/add/workspace.ts
+++ b/packages/cli/commands/add/workspace.ts
@@ -3,11 +3,11 @@ import path from 'node:path';
import * as find from 'empathic/find';
import { common, object, type AstTypes } from '@sveltejs/cli-core/js';
import { parseScript } from '@sveltejs/cli-core/parsers';
-import { TESTING } from '../../env.ts';
-import { getUserAgent } from '../../common.ts';
-import { commonFilePaths, getPackageJson, readFile } from './utils.ts';
import type { Workspace } from '@sveltejs/cli-core';
import type { AgentName } from 'package-manager-detector';
+import { TESTING } from '../../utils/env.ts';
+import { commonFilePaths, getPackageJson, readFile } from './utils.ts';
+import { getUserAgent } from '../../utils/package-manager.ts';
type CreateWorkspaceOptions = { cwd: string; packageManager?: AgentName };
export function createWorkspace({ cwd, packageManager }: CreateWorkspaceOptions): Workspace {
diff --git a/packages/cli/commands/check.ts b/packages/cli/commands/check.ts
index eb925103..23797d20 100644
--- a/packages/cli/commands/check.ts
+++ b/packages/cli/commands/check.ts
@@ -1,10 +1,10 @@
-import { execSync } from 'node:child_process';
import process from 'node:process';
+import { execSync } from 'node:child_process';
import pc from 'picocolors';
-import * as resolve from 'empathic/resolve';
import { Command } from 'commander';
+import * as resolve from 'empathic/resolve';
import { resolveCommand } from 'package-manager-detector/commands';
-import { getUserAgent } from '../common.ts';
+import { getUserAgent } from '../utils/package-manager.ts';
export const check = new Command('check')
.description('a CLI for checking your Svelte code')
diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts
index 8f1f0130..dd93c4f1 100644
--- a/packages/cli/commands/create.ts
+++ b/packages/cli/commands/create.ts
@@ -11,9 +11,14 @@ import {
type LanguageType,
type TemplateType
} from '@sveltejs/create';
-import * as common from '../common.js';
+import * as common from '../utils/common.ts';
import { runAddCommand } from './add/index.ts';
import { detectSync, type AgentName } from 'package-manager-detector';
+import {
+ getUserAgent,
+ installDependencies,
+ packageManagerPrompt
+} from '../utils/package-manager.ts';
const langs = ['ts', 'jsdoc'] as const;
const langMap: Record = {
@@ -59,8 +64,7 @@ export const create = new Command('create')
let i = 1;
const initialSteps: string[] = [];
const relative = path.relative(process.cwd(), directory);
- const pm =
- packageManager ?? detectSync({ cwd: directory })?.name ?? common.getUserAgent() ?? 'npm';
+ const pm = packageManager ?? detectSync({ cwd: directory })?.name ?? getUserAgent() ?? 'npm';
if (relative !== '') {
const pathHasSpaces = relative.includes(' ');
initialSteps.push(
@@ -157,8 +161,8 @@ async function createProject(cwd: ProjectPath, options: Options) {
let packageManager: AgentName | undefined | null;
let addOnNextSteps: string | undefined;
const installDeps = async () => {
- packageManager = await common.packageManagerPrompt(projectPath);
- if (packageManager) await common.installDependencies(packageManager, projectPath);
+ packageManager = await packageManagerPrompt(projectPath);
+ if (packageManager) await installDependencies(packageManager, projectPath);
};
if (options.addOns) {
diff --git a/packages/cli/commands/migrate.ts b/packages/cli/commands/migrate.ts
index 88a5dd7c..b3fecb36 100644
--- a/packages/cli/commands/migrate.ts
+++ b/packages/cli/commands/migrate.ts
@@ -2,7 +2,7 @@ import { execSync } from 'node:child_process';
import process from 'node:process';
import { Command } from 'commander';
import { resolveCommand } from 'package-manager-detector';
-import { getUserAgent } from '../common.ts';
+import { getUserAgent } from '../utils/package-manager.ts';
export const migrate = new Command('migrate')
.description('a CLI for migrating Svelte(Kit) codebases')
diff --git a/packages/cli/common.ts b/packages/cli/common.ts
deleted file mode 100644
index de39f0a2..00000000
--- a/packages/cli/common.ts
+++ /dev/null
@@ -1,200 +0,0 @@
-import process from 'node:process';
-import pc from 'picocolors';
-import pkg from './package.json';
-import { exec } from 'tinyexec';
-import * as p from '@sveltejs/clack-prompts';
-import { AGENTS, type AgentName, detectSync } from 'package-manager-detector';
-import { COMMANDS, constructCommand, resolveCommand } from 'package-manager-detector/commands';
-import type { Argument, HelpConfiguration, Option } from 'commander';
-import type { AdderWithoutExplicitArgs, Precondition } from '@sveltejs/cli-core';
-
-const NO_PREFIX = '--no-';
-let options: readonly Option[] = [];
-
-function getLongFlag(flags: string) {
- return flags
- .split(',')
- .map((f) => f.trim())
- .find((f) => f.startsWith('--'));
-}
-
-export const helpConfig: HelpConfiguration = {
- argumentDescription: formatDescription,
- optionDescription: formatDescription,
- visibleOptions(cmd) {
- // hack so that we can access existing options in `optionTerm`
- options = cmd.options;
-
- const visible = cmd.options.filter((o) => !o.hidden);
- const show: Option[] = [];
- // hide any `--no-` flag variants if there's an existing flag of a similar name
- // e.g. `--types` and `--no-types` will combine into a single `--[no-]types` flag
- for (const option of visible) {
- const flag = getLongFlag(option.flags);
- if (flag?.startsWith(NO_PREFIX)) {
- const stripped = flag.slice(NO_PREFIX.length);
- const isNoVariant = visible.some((o) => getLongFlag(o.flags)?.startsWith(`--${stripped}`));
- if (isNoVariant) continue;
- }
- show.push(option);
- }
- return show;
- },
- optionTerm(option) {
- const longFlag = getLongFlag(option.flags);
- const flag = longFlag?.split(' ').at(0);
- if (!flag || !longFlag) return option.flags;
-
- // check if there's a `--no-{flag}` variant
- const noVariant = `--no-${flag.slice(2)}`;
- const hasVariant = options.some((o) => getLongFlag(o.flags) === noVariant);
- if (hasVariant) {
- return `--[no-]${longFlag.slice(2)}`;
- }
-
- return option.flags;
- }
-};
-
-function formatDescription(arg: Option | Argument): string {
- let output = arg.description;
- if (arg.defaultValue !== undefined && String(arg.defaultValue)) {
- output += pc.dim(` (default: ${JSON.stringify(arg.defaultValue)})`);
- }
- if (arg.argChoices !== undefined && String(arg.argChoices)) {
- output += pc.dim(` (choices: ${arg.argChoices.join(', ')})`);
- }
- return output;
-}
-
-type MaybePromise = () => Promise | void;
-
-export async function runCommand(action: MaybePromise) {
- try {
- p.intro(`Welcome to the Svelte CLI! ${pc.gray(`(v${pkg.version})`)}`);
- await action();
- p.outro("You're all set!");
- } catch (e) {
- p.cancel('Operation failed.');
- if (e instanceof Error) {
- console.error(e.stack ?? e);
- }
- }
-}
-
-export async function formatFiles(options: {
- packageManager: AgentName;
- cwd: string;
- paths: string[];
-}): Promise {
- const args = ['prettier', '--write', '--ignore-unknown', ...options.paths];
- const cmd = resolveCommand(options.packageManager, 'execute-local', args)!;
- await exec(cmd.command, cmd.args, { nodeOptions: { cwd: options.cwd, stdio: 'pipe' } });
-}
-
-const agents = AGENTS.filter((agent): agent is AgentName => !agent.includes('@'));
-const agentOptions: PackageManagerOptions = agents.map((pm) => ({ value: pm, label: pm }));
-agentOptions.unshift({ label: 'None', value: undefined });
-
-type PackageManagerOptions = Array<{ value: AgentName | undefined; label: AgentName | 'None' }>;
-export async function packageManagerPrompt(cwd: string): Promise {
- const detected = detectSync({ cwd });
- const agent = detected?.name ?? getUserAgent();
-
- const pm = await p.select({
- message: 'Which package manager do you want to install dependencies with?',
- options: agentOptions,
- initialValue: agent
- });
- if (p.isCancel(pm)) {
- p.cancel('Operation cancelled.');
- process.exit(1);
- }
-
- return pm;
-}
-
-export async function installDependencies(agent: AgentName, cwd: string) {
- const spinner = p.spinner();
- spinner.start('Installing dependencies...');
- try {
- const { command, args } = constructCommand(COMMANDS[agent].install, [])!;
- await exec(command, args, { nodeOptions: { cwd } });
-
- spinner.stop('Successfully installed dependencies');
- } catch (error) {
- spinner.stop('Failed to install dependencies', 2);
- throw error;
- }
-}
-
-export function getUserAgent(): AgentName | undefined {
- const userAgent = process.env.npm_config_user_agent;
- if (!userAgent) return undefined;
-
- const pmSpec = userAgent.split(' ')[0]!;
- const separatorPos = pmSpec.lastIndexOf('/');
- const name = pmSpec.substring(0, separatorPos) as AgentName;
- return AGENTS.includes(name) ? name : undefined;
-}
-
-type PreconditionCheck = { name: string; preconditions: Precondition[] };
-export function getGlobalPreconditions(
- cwd: string,
- projectType: 'svelte' | 'kit',
- adders: AdderWithoutExplicitArgs[]
-): PreconditionCheck {
- return {
- name: 'global checks',
- preconditions: [
- {
- name: 'clean working directory',
- run: async () => {
- try {
- // If a user has pending git changes the output of the following command will list
- // all files that have been added/modified/deleted and thus the output will not be empty.
- // In case the output of the command below is an empty text, we can safely assume
- // there are no pending changes. If the below command is run outside of a git repository,
- // git will exit with a failing exit code, which will trigger the catch statement.
- // also see https://remarkablemark.org/blog/2017/10/12/check-git-dirty/#git-status
- const { stdout } = await exec('git', ['status', '--short'], { nodeOptions: { cwd } });
-
- if (stdout) {
- return { success: false, message: 'Found modified files' };
- }
-
- return { success: true, message: undefined };
- } catch {
- return { success: true, message: 'Not a git repository' };
- }
- }
- },
- {
- name: 'supported environments',
- run: () => {
- const addersForInvalidEnvironment = adders.filter((a) => {
- const supportedEnvironments = a.environments;
- if (projectType === 'kit' && !supportedEnvironments.kit) return true;
- if (projectType === 'svelte' && !supportedEnvironments.svelte) return true;
-
- return false;
- });
-
- if (addersForInvalidEnvironment.length === 0) {
- return { success: true, message: undefined };
- }
-
- const messages = addersForInvalidEnvironment.map((a) => {
- if (projectType === 'kit') {
- return `'${a.id}' does not support SvelteKit`;
- } else {
- return `'${a.id}' requires SvelteKit`;
- }
- });
-
- throw new Error(messages.join('\n'));
- }
- }
- ]
- };
-}
diff --git a/packages/cli/env.ts b/packages/cli/env.ts
deleted file mode 100644
index d482918b..00000000
--- a/packages/cli/env.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import process from 'node:process';
-
-export const TESTING: boolean = process.env.CI?.toLowerCase() === 'true';
diff --git a/packages/cli/index.ts b/packages/cli/index.ts
deleted file mode 100644
index 50f83ec1..00000000
--- a/packages/cli/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { create } from '@sveltejs/create';
-
-export { create };
diff --git a/packages/cli/lib/index.ts b/packages/cli/lib/index.ts
new file mode 100644
index 00000000..13aa9292
--- /dev/null
+++ b/packages/cli/lib/index.ts
@@ -0,0 +1,3 @@
+export { create } from '@sveltejs/create';
+export { installAddon } from './install.ts';
+export type { AddonMap, InstallOptions, OptionMap } from './install.ts';
diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts
new file mode 100644
index 00000000..555da7e8
--- /dev/null
+++ b/packages/cli/lib/install.ts
@@ -0,0 +1,95 @@
+import { exec } from 'tinyexec';
+import { resolveCommand } from 'package-manager-detector';
+import type { Adder, Workspace, PackageManager, OptionValues, Question } from '@sveltejs/cli-core';
+import { installPackages } from '../commands/add/utils.ts';
+import { createWorkspace } from '../commands/add/workspace.ts';
+import { createOrUpdateFiles } from '../commands/add/processor.ts';
+
+type Addon = Adder;
+export type InstallOptions = {
+ cwd: string;
+ addons: Addons;
+ options: OptionMap;
+ packageManager: PackageManager;
+};
+
+export type AddonMap = Record;
+export type OptionMap = {
+ [K in keyof Addons]: Partial>;
+};
+
+export async function installAddon({
+ addons,
+ cwd,
+ options,
+ packageManager = 'npm'
+}: InstallOptions): Promise {
+ const filesToFormat = new Set();
+
+ const mapped = Object.entries(addons).map(([, addon]) => addon);
+ const ordered = orderAddons(mapped);
+
+ for (const addon of ordered) {
+ const workspace = createWorkspace({ cwd, packageManager });
+ workspace.options = options[addon.id];
+
+ const files = await runAddon(workspace, addon);
+ files.forEach((f) => filesToFormat.add(f));
+ }
+
+ return Array.from(filesToFormat);
+}
+
+async function runAddon(
+ workspace: Workspace,
+ addon: Adder>
+): Promise {
+ const files = new Set();
+
+ // apply default adder options
+ for (const [, question] of Object.entries(addon.options)) {
+ // we'll only apply defaults to options that don't explicitly fail their conditions
+ if (question.condition?.(workspace.options) !== false) {
+ workspace.options ??= question.default;
+ }
+ }
+
+ await addon.preInstall?.(workspace);
+ const pkgPath = installPackages(addon, workspace);
+ files.add(pkgPath);
+ const changedFiles = createOrUpdateFiles(addon.files, workspace);
+ changedFiles.forEach((file) => files.add(file));
+ await addon.postInstall?.(workspace);
+
+ for (const script of addon.scripts ?? []) {
+ if (script.condition?.(workspace) === false) continue;
+
+ try {
+ const { args, command } = resolveCommand(workspace.packageManager, 'execute', script.args)!;
+ if (workspace.packageManager === 'npm') args.unshift('--yes');
+ await exec(command, args, {
+ nodeOptions: { cwd: workspace.cwd, stdio: 'pipe' },
+ throwOnError: true
+ });
+ } catch (error) {
+ const typedError = error as Error;
+ throw new Error(`Failed to execute scripts '${script.description}': ` + typedError.message);
+ }
+ }
+
+ return Array.from(files);
+}
+
+// sorts them to their execution order
+function orderAddons(addons: Addon[]) {
+ return Array.from(addons).sort((a, b) => {
+ if (!a.dependsOn && !b.dependsOn) return 0;
+ if (!a.dependsOn) return -1;
+ if (!b.dependsOn) return 1;
+
+ if (a.dependsOn.includes(b.id)) return 1;
+ if (b.dependsOn.includes(a.id)) return -1;
+
+ return 0;
+ });
+}
diff --git a/packages/cli/lib/testing.ts b/packages/cli/lib/testing.ts
new file mode 100644
index 00000000..62857525
--- /dev/null
+++ b/packages/cli/lib/testing.ts
@@ -0,0 +1,151 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import process from 'node:process';
+import degit from 'degit';
+import { exec } from 'tinyexec';
+import { create } from '@sveltejs/create';
+import pstree, { type PS } from 'ps-tree';
+
+export type ProjectVariant = 'kit-js' | 'kit-ts' | 'vite-js' | 'vite-ts';
+
+const TEMPLATES_DIR = '.templates';
+
+export type CreateProject = (options: {
+ testId: string;
+ variant: ProjectVariant;
+ /** @default true */
+ clean?: boolean;
+}) => string;
+
+type SetupOptions = {
+ cwd: string;
+ variants: readonly ProjectVariant[];
+ /** @default false */
+ clean?: boolean;
+};
+export async function setup({
+ cwd,
+ clean = false,
+ variants
+}: SetupOptions): Promise<{ templatesDir: string }> {
+ const workingDir = path.resolve(cwd);
+ if (clean && fs.existsSync(workingDir)) {
+ fs.rmSync(workingDir, { force: true, recursive: true });
+ }
+
+ // fetch the project types
+ const templatesDir = path.resolve(workingDir, TEMPLATES_DIR);
+ fs.mkdirSync(templatesDir, { recursive: true });
+ for (const variant of variants) {
+ const templatePath = path.resolve(templatesDir, variant);
+ if (fs.existsSync(templatePath)) continue;
+
+ if (variant === 'kit-js') {
+ create(templatePath, { name: variant, template: 'minimal', types: 'checkjs' });
+ } else if (variant === 'kit-ts') {
+ create(templatePath, { name: variant, template: 'minimal', types: 'typescript' });
+ } else if (variant === 'vite-js' || variant === 'vite-ts') {
+ const name = `template-svelte${variant === 'vite-ts' ? '-ts' : ''}`;
+ // TODO: should probably point this to a specific commit hash (ex: `#1234abcd`)
+ const template = degit(`vitejs/vite/packages/create-vite/${name}`, { force: true });
+ await template.clone(templatePath);
+
+ // vite templates have their gitignore file named as `_gitignore`
+ const gitignorePath = path.resolve(templatePath, '_gitignore');
+ if (fs.existsSync(gitignorePath)) {
+ const fixedPath = path.resolve(templatePath, '.gitignore');
+ fs.renameSync(gitignorePath, fixedPath);
+ }
+ } else {
+ throw new Error(`Unknown project variant: ${variant}`);
+ }
+ }
+
+ return { templatesDir };
+}
+
+type CreateOptions = { cwd: string; testName: string; templatesDir: string };
+export function createProject({ cwd, testName, templatesDir }: CreateOptions): CreateProject {
+ // create the reference dir
+ const testDir = path.resolve(cwd, testName);
+ fs.mkdirSync(testDir, { recursive: true });
+ return ({ testId, variant, clean = true }) => {
+ const targetDir = path.resolve(testDir, testId);
+ if (clean && fs.existsSync(targetDir)) {
+ fs.rmSync(targetDir, { force: true, recursive: true });
+ }
+ const templatePath = path.resolve(templatesDir, variant);
+ fs.cpSync(templatePath, targetDir, { recursive: true, force: true });
+ return targetDir;
+ };
+}
+
+type PreviewOptions = { cwd: string; command?: string };
+export async function startPreview({
+ cwd,
+ command = 'npm run preview'
+}: PreviewOptions): Promise<{ url: string; close: () => Promise }> {
+ const [cmd, ...args] = command.split(' ');
+ const proc = exec(cmd, args, {
+ nodeOptions: { cwd, stdio: 'pipe' },
+ throwOnError: true,
+ timeout: 60_000
+ });
+
+ const close = async () => {
+ if (!proc.pid) return;
+ await terminate(proc.pid);
+ };
+
+ return await new Promise((resolve, reject) => {
+ if (!proc.process?.stdout) return reject('impossible state');
+
+ proc.process.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, close });
+ }
+ });
+ });
+}
+
+async function getProcessTree(pid: number) {
+ return new Promise((res, rej) => {
+ pstree(pid, (err, children) => {
+ if (err) rej(err);
+ res(children);
+ });
+ });
+}
+
+async function terminate(pid: number) {
+ const children = await getProcessTree(pid);
+ // the process tree is ordered from parents -> children,
+ // so we'll iterate in the reverse order to terminate the children first
+ for (let i = children.length - 1; i >= 0; i--) {
+ const child = children[i];
+ const pid = Number(child.PID);
+ kill(pid);
+ }
+ kill(pid);
+}
+
+function kill(pid: number) {
+ try {
+ process.kill(pid);
+ } catch {
+ // this can happen if a process has been automatically terminated.
+ }
+}
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 4628db83..291f8afc 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -21,8 +21,12 @@
"bin": "./dist/bin.js",
"exports": {
".": {
- "types": "./dist/index.d.ts",
+ "types": "./dist/lib/index.d.ts",
"default": "./dist/index.js"
+ },
+ "./testing": {
+ "types": "./dist/lib/testing.d.ts",
+ "default": "./dist/testing.js"
}
},
"devDependencies": {
@@ -30,13 +34,17 @@
"@sveltejs/clack-prompts": "workspace:*",
"@sveltejs/cli-core": "workspace:*",
"@sveltejs/create": "workspace:*",
+ "@types/degit": "^2.8.6",
+ "@types/ps-tree": "^1.1.6",
"@types/tar-fs": "^2.0.4",
"commander": "^12.1.0",
+ "degit": "^2.8.4",
"empathic": "^1.0.0",
"package-manager-detector": "^0.2.2",
"picocolors": "^1.1.0",
+ "ps-tree": "^1.2.0",
"tar-fs": "^3.0.6",
- "tinyexec": "^0.3.0",
+ "tinyexec": "^0.3.1",
"valibot": "^0.41.0"
},
"keywords": [
diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json
index 6f800349..54c4c150 100644
--- a/packages/cli/tsconfig.json
+++ b/packages/cli/tsconfig.json
@@ -6,5 +6,5 @@
"declaration": true
},
// we'll only want to enforce `isolatedDeclarations` on the library portion of the CLI
- "include": ["index.ts"]
+ "include": ["lib/index.ts", "lib/testing.ts"]
}
diff --git a/packages/cli/utils/common.ts b/packages/cli/utils/common.ts
new file mode 100644
index 00000000..bfcbfd16
--- /dev/null
+++ b/packages/cli/utils/common.ts
@@ -0,0 +1,78 @@
+import pc from 'picocolors';
+import pkg from '../package.json';
+import * as p from '@sveltejs/clack-prompts';
+import type { Argument, HelpConfiguration, Option } from 'commander';
+
+const NO_PREFIX = '--no-';
+let options: readonly Option[] = [];
+
+function getLongFlag(flags: string) {
+ return flags
+ .split(',')
+ .map((f) => f.trim())
+ .find((f) => f.startsWith('--'));
+}
+
+export const helpConfig: HelpConfiguration = {
+ argumentDescription: formatDescription,
+ optionDescription: formatDescription,
+ visibleOptions(cmd) {
+ // hack so that we can access existing options in `optionTerm`
+ options = cmd.options;
+
+ const visible = cmd.options.filter((o) => !o.hidden);
+ const show: Option[] = [];
+ // hide any `--no-` flag variants if there's an existing flag of a similar name
+ // e.g. `--types` and `--no-types` will combine into a single `--[no-]types` flag
+ for (const option of visible) {
+ const flag = getLongFlag(option.flags);
+ if (flag?.startsWith(NO_PREFIX)) {
+ const stripped = flag.slice(NO_PREFIX.length);
+ const isNoVariant = visible.some((o) => getLongFlag(o.flags)?.startsWith(`--${stripped}`));
+ if (isNoVariant) continue;
+ }
+ show.push(option);
+ }
+ return show;
+ },
+ optionTerm(option) {
+ const longFlag = getLongFlag(option.flags);
+ const flag = longFlag?.split(' ').at(0);
+ if (!flag || !longFlag) return option.flags;
+
+ // check if there's a `--no-{flag}` variant
+ const noVariant = `--no-${flag.slice(2)}`;
+ const hasVariant = options.some((o) => getLongFlag(o.flags) === noVariant);
+ if (hasVariant) {
+ return `--[no-]${longFlag.slice(2)}`;
+ }
+
+ return option.flags;
+ }
+};
+
+function formatDescription(arg: Option | Argument): string {
+ let output = arg.description;
+ if (arg.defaultValue !== undefined && String(arg.defaultValue)) {
+ output += pc.dim(` (default: ${JSON.stringify(arg.defaultValue)})`);
+ }
+ if (arg.argChoices !== undefined && String(arg.argChoices)) {
+ output += pc.dim(` (choices: ${arg.argChoices.join(', ')})`);
+ }
+ return output;
+}
+
+type MaybePromise = () => Promise | void;
+
+export async function runCommand(action: MaybePromise): Promise {
+ try {
+ p.intro(`Welcome to the Svelte CLI! ${pc.gray(`(v${pkg.version})`)}`);
+ await action();
+ p.outro("You're all set!");
+ } catch (e) {
+ p.cancel('Operation failed.');
+ if (e instanceof Error) {
+ console.error(e.stack ?? e);
+ }
+ }
+}
diff --git a/packages/cli/utils/env.ts b/packages/cli/utils/env.ts
new file mode 100644
index 00000000..4ab46826
--- /dev/null
+++ b/packages/cli/utils/env.ts
@@ -0,0 +1,3 @@
+import process from 'node:process';
+
+export const TESTING: boolean = process.env.NODE_ENV?.toLowerCase() === 'test';
diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts
new file mode 100644
index 00000000..c0226505
--- /dev/null
+++ b/packages/cli/utils/package-manager.ts
@@ -0,0 +1,56 @@
+import process from 'node:process';
+import { exec } from 'tinyexec';
+import * as p from '@sveltejs/clack-prompts';
+import {
+ AGENTS,
+ COMMANDS,
+ constructCommand,
+ detectSync,
+ type AgentName
+} from 'package-manager-detector';
+
+const agents = AGENTS.filter((agent): agent is AgentName => !agent.includes('@'));
+const agentOptions: PackageManagerOptions = agents.map((pm) => ({ value: pm, label: pm }));
+agentOptions.unshift({ label: 'None', value: undefined });
+
+type PackageManagerOptions = Array<{ value: AgentName | undefined; label: AgentName | 'None' }>;
+export async function packageManagerPrompt(cwd: string): Promise {
+ const detected = detectSync({ cwd });
+ const agent = detected?.name ?? getUserAgent();
+
+ const pm = await p.select({
+ message: 'Which package manager do you want to install dependencies with?',
+ options: agentOptions,
+ initialValue: agent
+ });
+ if (p.isCancel(pm)) {
+ p.cancel('Operation cancelled.');
+ process.exit(1);
+ }
+
+ return pm;
+}
+
+export async function installDependencies(agent: AgentName, cwd: string): Promise {
+ const spinner = p.spinner();
+ spinner.start('Installing dependencies...');
+ try {
+ const { command, args } = constructCommand(COMMANDS[agent].install, [])!;
+ await exec(command, args, { nodeOptions: { cwd }, throwOnError: true });
+
+ spinner.stop('Successfully installed dependencies');
+ } catch (error) {
+ spinner.stop('Failed to install dependencies', 2);
+ throw error;
+ }
+}
+
+export function getUserAgent(): AgentName | undefined {
+ const userAgent = process.env.npm_config_user_agent;
+ if (!userAgent) return undefined;
+
+ const pmSpec = userAgent.split(' ')[0]!;
+ const separatorPos = pmSpec.lastIndexOf('/');
+ const name = pmSpec.substring(0, separatorPos) as AgentName;
+ return AGENTS.includes(name) ? name : undefined;
+}
diff --git a/packages/core/adder/workspace.ts b/packages/core/adder/workspace.ts
index a03f2877..85bb4fcd 100644
--- a/packages/core/adder/workspace.ts
+++ b/packages/core/adder/workspace.ts
@@ -14,5 +14,7 @@ export type Workspace = {
dependencyVersion: (pkg: string) => string | undefined;
typescript: boolean;
kit: { libDirectory: string; routesDirectory: string } | undefined;
- packageManager: 'npm' | 'yarn' | 'pnpm' | 'bun';
+ packageManager: PackageManager;
};
+
+export type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';
diff --git a/packages/core/tests/css/common/add-at-rule/input.css b/packages/core/tests/css/common/add-at-rule/input.css
index faa4215a..cedf0a6d 100644
--- a/packages/core/tests/css/common/add-at-rule/input.css
+++ b/packages/core/tests/css/common/add-at-rule/input.css
@@ -1,3 +1,3 @@
.foo {
- color: red;
+ color: red;
}
diff --git a/packages/core/tests/css/common/add-at-rule/output.css b/packages/core/tests/css/common/add-at-rule/output.css
index ae662e2b..e2a2d26f 100644
--- a/packages/core/tests/css/common/add-at-rule/output.css
+++ b/packages/core/tests/css/common/add-at-rule/output.css
@@ -1,5 +1,5 @@
@tailwind 'lib/path/file.ext';
.foo {
- color: red;
+ color: red;
}
-@tailwind 'lib/path/file1.ext'
+@tailwind 'lib/path/file1.ext';
diff --git a/packages/core/tests/css/common/add-comment/input.css b/packages/core/tests/css/common/add-comment/input.css
index faa4215a..cedf0a6d 100644
--- a/packages/core/tests/css/common/add-comment/input.css
+++ b/packages/core/tests/css/common/add-comment/input.css
@@ -1,3 +1,3 @@
.foo {
- color: red;
+ color: red;
}
diff --git a/packages/core/tests/css/common/add-comment/output.css b/packages/core/tests/css/common/add-comment/output.css
index cc8bc00f..fbb03f63 100644
--- a/packages/core/tests/css/common/add-comment/output.css
+++ b/packages/core/tests/css/common/add-comment/output.css
@@ -1,4 +1,4 @@
.foo {
- color: red;
+ color: red;
}
/* foo comment */
diff --git a/packages/core/tests/css/common/add-imports/input.css b/packages/core/tests/css/common/add-imports/input.css
index faa4215a..cedf0a6d 100644
--- a/packages/core/tests/css/common/add-imports/input.css
+++ b/packages/core/tests/css/common/add-imports/input.css
@@ -1,3 +1,3 @@
.foo {
- color: red;
+ color: red;
}
diff --git a/packages/core/tests/css/common/add-imports/output.css b/packages/core/tests/css/common/add-imports/output.css
index e5b67d82..4f96db19 100644
--- a/packages/core/tests/css/common/add-imports/output.css
+++ b/packages/core/tests/css/common/add-imports/output.css
@@ -1,4 +1,4 @@
@import 'lib/path/file.css';
.foo {
- color: red;
+ color: red;
}
diff --git a/packages/core/tests/css/common/add-rule/input.css b/packages/core/tests/css/common/add-rule/input.css
index faa4215a..cedf0a6d 100644
--- a/packages/core/tests/css/common/add-rule/input.css
+++ b/packages/core/tests/css/common/add-rule/input.css
@@ -1,3 +1,3 @@
.foo {
- color: red;
+ color: red;
}
diff --git a/packages/core/tests/css/common/add-rule/output.css b/packages/core/tests/css/common/add-rule/output.css
index 5c63305b..c99b655a 100644
--- a/packages/core/tests/css/common/add-rule/output.css
+++ b/packages/core/tests/css/common/add-rule/output.css
@@ -1,5 +1,6 @@
.foo {
- color: red;
-}.bar {
- color: blue
+ color: red;
+}
+.bar {
+ color: blue;
}
diff --git a/packages/core/tests/css/index.ts b/packages/core/tests/css/index.ts
index 738e1cb8..77a89d83 100644
--- a/packages/core/tests/css/index.ts
+++ b/packages/core/tests/css/index.ts
@@ -1,12 +1,17 @@
-import { describe, expect, test } from 'vitest';
-import { parseCss, serializeCss } from '@sveltejs/ast-tooling';
import fs from 'node:fs';
import { join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
+import prettier from 'prettier';
+import { describe, expect, test } from 'vitest';
+import { parseCss, serializeCss } from '@sveltejs/ast-tooling';
const baseDir = resolve(fileURLToPath(import.meta.url), '..');
const categoryDirectories = getDirectoryNames(baseDir);
+const prettierConfig = await prettier.resolveConfig(import.meta.url);
+if (!prettierConfig) throw new Error('Failed to resolve prettier config');
+prettierConfig.filepath = 'output.css';
+
for (const categoryDirectory of categoryDirectories) {
describe(categoryDirectory, () => {
const testNames = getDirectoryNames(join(baseDir, categoryDirectory));
@@ -23,7 +28,8 @@ for (const categoryDirectory of categoryDirectories) {
module.run({ ast });
const output = serializeCss(ast);
- await expect(output).toMatchFileSnapshot(`${testDirectoryPath}/output.css`);
+ const formattedOutput = await prettier.format(output, prettierConfig);
+ await expect(formattedOutput).toMatchFileSnapshot(`${testDirectoryPath}/output.css`);
});
}
});
diff --git a/packages/core/tests/html/common/create-div/output.html b/packages/core/tests/html/common/create-div/output.html
index f9cce455..d68abe73 100644
--- a/packages/core/tests/html/common/create-div/output.html
+++ b/packages/core/tests/html/common/create-div/output.html
@@ -1,2 +1,3 @@
-
+
+
diff --git a/packages/core/tests/html/common/create-element/output.html b/packages/core/tests/html/common/create-element/output.html
index 351470bd..6a6aa0de 100644
--- a/packages/core/tests/html/common/create-element/output.html
+++ b/packages/core/tests/html/common/create-element/output.html
@@ -1,2 +1,3 @@
-
+
+
diff --git a/packages/core/tests/html/index.ts b/packages/core/tests/html/index.ts
index 6719acd4..dfad1d0d 100644
--- a/packages/core/tests/html/index.ts
+++ b/packages/core/tests/html/index.ts
@@ -1,12 +1,17 @@
-import { describe, expect, test } from 'vitest';
-import { parseHtml, serializeHtml } from '@sveltejs/ast-tooling';
import fs from 'node:fs';
import { join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
+import prettier from 'prettier';
+import { describe, expect, test } from 'vitest';
+import { parseHtml, serializeHtml } from '@sveltejs/ast-tooling';
const baseDir = resolve(fileURLToPath(import.meta.url), '..');
const categoryDirectories = getDirectoryNames(baseDir);
+const prettierConfig = await prettier.resolveConfig(import.meta.url);
+if (!prettierConfig) throw new Error('Failed to resolve prettier config');
+prettierConfig.filepath = 'output.html';
+
for (const categoryDirectory of categoryDirectories) {
describe(categoryDirectory, () => {
const testNames = getDirectoryNames(join(baseDir, categoryDirectory));
@@ -23,7 +28,8 @@ for (const categoryDirectory of categoryDirectories) {
module.run({ ast });
const output = serializeHtml(ast);
- await expect(output).toMatchFileSnapshot(`${testDirectoryPath}/output.html`);
+ const formattedOutput = await prettier.format(output, prettierConfig);
+ await expect(formattedOutput).toMatchFileSnapshot(`${testDirectoryPath}/output.html`);
});
}
});
diff --git a/packages/core/tests/js/arrays/object-array/output.ts b/packages/core/tests/js/arrays/object-array/output.ts
index c47de750..1fa08802 100644
--- a/packages/core/tests/js/arrays/object-array/output.ts
+++ b/packages/core/tests/js/arrays/object-array/output.ts
@@ -1,5 +1,8 @@
-const array = [{
- test: true
-}, {
- test2: 'string'
-}];
\ No newline at end of file
+const array = [
+ {
+ test: true
+ },
+ {
+ test2: 'string'
+ }
+];
diff --git a/packages/core/tests/js/arrays/string-array/output.ts b/packages/core/tests/js/arrays/string-array/output.ts
index 7d00f941..e7618b3e 100644
--- a/packages/core/tests/js/arrays/string-array/output.ts
+++ b/packages/core/tests/js/arrays/string-array/output.ts
@@ -1 +1 @@
-const array = ['test', 'test2'];
\ No newline at end of file
+const array = ['test', 'test2'];
diff --git a/packages/core/tests/js/common/jsdoc-comment/input.ts b/packages/core/tests/js/common/jsdoc-comment/input.ts
index c4a1447a..a3423c81 100644
--- a/packages/core/tests/js/common/jsdoc-comment/input.ts
+++ b/packages/core/tests/js/common/jsdoc-comment/input.ts
@@ -1,5 +1,5 @@
function switchToLanguage(newLanguage) {
- const canonicalPath = i18n.route($page.url.pathname);
- const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage);
- goto(localisedPath);
+ const canonicalPath = i18n.route($page.url.pathname);
+ const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage);
+ goto(localisedPath);
}
diff --git a/packages/core/tests/js/common/jsdoc-comment/output.ts b/packages/core/tests/js/common/jsdoc-comment/output.ts
index d97338ba..2394044f 100644
--- a/packages/core/tests/js/common/jsdoc-comment/output.ts
+++ b/packages/core/tests/js/common/jsdoc-comment/output.ts
@@ -2,7 +2,7 @@
* @param {import("$lib/paraglide/runtime").AvailableLanguageTag} newLanguage
*/
function switchToLanguage(newLanguage) {
- const canonicalPath = i18n.route($page.url.pathname);
- const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage);
- goto(localisedPath);
+ const canonicalPath = i18n.route($page.url.pathname);
+ const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage);
+ goto(localisedPath);
}
diff --git a/packages/core/tests/js/exports/default-export-with-variable/output.ts b/packages/core/tests/js/exports/default-export-with-variable/output.ts
index e3eafc9d..920afac1 100644
--- a/packages/core/tests/js/exports/default-export-with-variable/output.ts
+++ b/packages/core/tests/js/exports/default-export-with-variable/output.ts
@@ -1,5 +1,5 @@
const object = {
- test: 'string'
+ test: 'string'
};
-export default object;
\ No newline at end of file
+export default object;
diff --git a/packages/core/tests/js/exports/default-export/output.ts b/packages/core/tests/js/exports/default-export/output.ts
index 76088cc4..d2516b3e 100644
--- a/packages/core/tests/js/exports/default-export/output.ts
+++ b/packages/core/tests/js/exports/default-export/output.ts
@@ -1,3 +1,3 @@
export default {
- test: 'string'
-};
\ No newline at end of file
+ test: 'string'
+};
diff --git a/packages/core/tests/js/exports/named-export-with-existing/output.ts b/packages/core/tests/js/exports/named-export-with-existing/output.ts
index 9bcf50f5..3cc72fee 100644
--- a/packages/core/tests/js/exports/named-export-with-existing/output.ts
+++ b/packages/core/tests/js/exports/named-export-with-existing/output.ts
@@ -1,4 +1,4 @@
export const named = {
- test: 'string',
- test2: "string2"
-};
\ No newline at end of file
+ test: 'string',
+ test2: 'string2'
+};
diff --git a/packages/core/tests/js/exports/named-export/output.ts b/packages/core/tests/js/exports/named-export/output.ts
index c8a12a18..fec3056c 100644
--- a/packages/core/tests/js/exports/named-export/output.ts
+++ b/packages/core/tests/js/exports/named-export/output.ts
@@ -1,7 +1,7 @@
export const variable = {
- test: 'string'
+ test: 'string'
};
export const variable2 = {
- test2: 'string2'
-};
\ No newline at end of file
+ test2: 'string2'
+};
diff --git a/packages/core/tests/js/functions/arrow-function/output.ts b/packages/core/tests/js/functions/arrow-function/output.ts
index c74b611e..1dc5293f 100644
--- a/packages/core/tests/js/functions/arrow-function/output.ts
+++ b/packages/core/tests/js/functions/arrow-function/output.ts
@@ -1,6 +1,6 @@
() => console.log('foo');
() => {
- console.log('foo');
- console.log('bar');
-};
\ No newline at end of file
+ console.log('foo');
+ console.log('bar');
+};
diff --git a/packages/core/tests/js/functions/function-call/output.ts b/packages/core/tests/js/functions/function-call/output.ts
index 6a886f44..69b852d5 100644
--- a/packages/core/tests/js/functions/function-call/output.ts
+++ b/packages/core/tests/js/functions/function-call/output.ts
@@ -1,4 +1,4 @@
function foo(bar: string) {
console.log(bar);
}
-foo("bar");
\ No newline at end of file
+foo('bar');
diff --git a/packages/core/tests/js/imports/default-import/output.ts b/packages/core/tests/js/imports/default-import/output.ts
index 9203d582..0f58f59e 100644
--- a/packages/core/tests/js/imports/default-import/output.ts
+++ b/packages/core/tests/js/imports/default-import/output.ts
@@ -1 +1 @@
-import MyPackage from 'package';
\ No newline at end of file
+import MyPackage from 'package';
diff --git a/packages/core/tests/js/imports/empty-import/output.ts b/packages/core/tests/js/imports/empty-import/output.ts
index 47f21090..bf92fd96 100644
--- a/packages/core/tests/js/imports/empty-import/output.ts
+++ b/packages/core/tests/js/imports/empty-import/output.ts
@@ -1,2 +1,2 @@
import 'package/file.css';
-import './relativ/file.css';
\ No newline at end of file
+import './relativ/file.css';
diff --git a/packages/core/tests/js/imports/named-import-merging/input.ts b/packages/core/tests/js/imports/named-import-merging/input.ts
index 67f0c3d9..f4d71375 100644
--- a/packages/core/tests/js/imports/named-import-merging/input.ts
+++ b/packages/core/tests/js/imports/named-import-merging/input.ts
@@ -1 +1 @@
-import { namedOne } from "package";
+import { namedOne } from 'package';
diff --git a/packages/core/tests/js/imports/named-import-merging/output.ts b/packages/core/tests/js/imports/named-import-merging/output.ts
index 772a0f86..7e5affa6 100644
--- a/packages/core/tests/js/imports/named-import-merging/output.ts
+++ b/packages/core/tests/js/imports/named-import-merging/output.ts
@@ -1 +1 @@
-import { namedOne, namedTwo } from "package";
\ No newline at end of file
+import { namedOne, namedTwo } from 'package';
diff --git a/packages/core/tests/js/imports/named-import/output.ts b/packages/core/tests/js/imports/named-import/output.ts
index 1a3abd90..640312d9 100644
--- a/packages/core/tests/js/imports/named-import/output.ts
+++ b/packages/core/tests/js/imports/named-import/output.ts
@@ -1,2 +1,2 @@
import { Handle } from '@sveltejs/kit';
-import { namedOne } from 'package';
\ No newline at end of file
+import { namedOne } from 'package';
diff --git a/packages/core/tests/js/imports/namespaced-import/output.ts b/packages/core/tests/js/imports/namespaced-import/output.ts
index 56eda1b3..89dc72a7 100644
--- a/packages/core/tests/js/imports/namespaced-import/output.ts
+++ b/packages/core/tests/js/imports/namespaced-import/output.ts
@@ -1,2 +1,2 @@
import * as bar from './some-file';
-import * as foo from 'package';
\ No newline at end of file
+import * as foo from 'package';
diff --git a/packages/core/tests/js/index.ts b/packages/core/tests/js/index.ts
index fc93e163..8cf489a4 100644
--- a/packages/core/tests/js/index.ts
+++ b/packages/core/tests/js/index.ts
@@ -1,12 +1,17 @@
-import { describe, expect, test } from 'vitest';
-import { parseScript, serializeScript } from '@sveltejs/ast-tooling';
import fs from 'node:fs';
import { join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
+import prettier from 'prettier';
+import { describe, expect, test } from 'vitest';
+import { parseScript, serializeScript } from '@sveltejs/ast-tooling';
const baseDir = resolve(fileURLToPath(import.meta.url), '..');
const categoryDirectories = getDirectoryNames(baseDir);
+const prettierConfig = await prettier.resolveConfig(import.meta.url);
+if (!prettierConfig) throw new Error('Failed to resolve prettier config');
+prettierConfig.filepath = 'output.ts';
+
for (const categoryDirectory of categoryDirectories) {
describe(categoryDirectory, () => {
const testNames = getDirectoryNames(join(baseDir, categoryDirectory));
@@ -23,7 +28,8 @@ for (const categoryDirectory of categoryDirectories) {
module.run({ ast });
const output = serializeScript(ast, input);
- await expect(output).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`);
+ const formattedOutput = await prettier.format(output, prettierConfig);
+ await expect(formattedOutput).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`);
});
}
});
diff --git a/packages/core/tests/js/object/create/output.ts b/packages/core/tests/js/object/create/output.ts
index a31bc6cf..b8a403ca 100644
--- a/packages/core/tests/js/object/create/output.ts
+++ b/packages/core/tests/js/object/create/output.ts
@@ -1,6 +1,6 @@
const empty = {};
const created = {
- foo: 1,
- bar: 'string'
-};
\ No newline at end of file
+ foo: 1,
+ bar: 'string'
+};
diff --git a/packages/core/tests/js/object/override-property/input.ts b/packages/core/tests/js/object/override-property/input.ts
index 42413f9b..72b9d208 100644
--- a/packages/core/tests/js/object/override-property/input.ts
+++ b/packages/core/tests/js/object/override-property/input.ts
@@ -1,5 +1,5 @@
const test = {
- foo: 1,
- bar: 'string',
- lorem: true
-}
+ foo: 1,
+ bar: 'string',
+ lorem: true
+};
diff --git a/packages/core/tests/js/object/override-property/output.ts b/packages/core/tests/js/object/override-property/output.ts
index d759f951..0069e775 100644
--- a/packages/core/tests/js/object/override-property/output.ts
+++ b/packages/core/tests/js/object/override-property/output.ts
@@ -1,5 +1,5 @@
const test = {
- foo: 2,
- bar: "string2",
- lorem: false
-}
\ No newline at end of file
+ foo: 2,
+ bar: 'string2',
+ lorem: false
+};
diff --git a/packages/core/tests/js/object/property/input.ts b/packages/core/tests/js/object/property/input.ts
index 2e7612f4..8d0b560b 100644
--- a/packages/core/tests/js/object/property/input.ts
+++ b/packages/core/tests/js/object/property/input.ts
@@ -1,3 +1,3 @@
const test = {
- foo: 1
-}
+ foo: 1
+};
diff --git a/packages/core/tests/js/object/property/output.ts b/packages/core/tests/js/object/property/output.ts
index 022a2a8b..3967f063 100644
--- a/packages/core/tests/js/object/property/output.ts
+++ b/packages/core/tests/js/object/property/output.ts
@@ -1,4 +1,4 @@
const test = {
- foo: 1,
- bar: "string"
-}
\ No newline at end of file
+ foo: 1,
+ bar: 'string'
+};
diff --git a/packages/core/tests/js/object/remove-property/input.ts b/packages/core/tests/js/object/remove-property/input.ts
index 2ff5dd43..3967f063 100644
--- a/packages/core/tests/js/object/remove-property/input.ts
+++ b/packages/core/tests/js/object/remove-property/input.ts
@@ -1,4 +1,4 @@
const test = {
- foo: 1,
- bar: 'string'
-}
+ foo: 1,
+ bar: 'string'
+};
diff --git a/packages/core/tests/js/object/remove-property/output.ts b/packages/core/tests/js/object/remove-property/output.ts
index e51fe4a1..f3129ed1 100644
--- a/packages/core/tests/js/object/remove-property/output.ts
+++ b/packages/core/tests/js/object/remove-property/output.ts
@@ -1 +1 @@
-const test = {}
+const test = {};
diff --git a/packages/core/tests/js/variables/declaration/output.ts b/packages/core/tests/js/variables/declaration/output.ts
index 2863841c..e96c602e 100644
--- a/packages/core/tests/js/variables/declaration/output.ts
+++ b/packages/core/tests/js/variables/declaration/output.ts
@@ -1,5 +1,5 @@
const testNumber = 2;
const testObject = {
- foo: 'bar'
-};
\ No newline at end of file
+ foo: 'bar'
+};
diff --git a/packages/core/tests/js/variables/type-annotate-declarator/input.ts b/packages/core/tests/js/variables/type-annotate-declarator/input.ts
index c064160a..9726ffde 100644
--- a/packages/core/tests/js/variables/type-annotate-declarator/input.ts
+++ b/packages/core/tests/js/variables/type-annotate-declarator/input.ts
@@ -1 +1 @@
-const str = "123";
+const str = '123';
diff --git a/packages/core/tests/js/variables/type-annotate-declarator/output.ts b/packages/core/tests/js/variables/type-annotate-declarator/output.ts
index 82e25885..99232ae3 100644
--- a/packages/core/tests/js/variables/type-annotate-declarator/output.ts
+++ b/packages/core/tests/js/variables/type-annotate-declarator/output.ts
@@ -1 +1 @@
-const str: string = "123";
+const str: string = '123';
diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json
index a1fcf6c9..9f06a6bc 100644
--- a/packages/core/tsconfig.json
+++ b/packages/core/tsconfig.json
@@ -4,5 +4,6 @@
"checkJs": false,
"isolatedDeclarations": true,
"declaration": true
- }
+ },
+ "include": ["index.ts"]
}
diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts
index 5387a327..5940c172 100644
--- a/packages/core/vitest.config.ts
+++ b/packages/core/vitest.config.ts
@@ -1,5 +1,8 @@
-import { defineConfig, type UserConfig } from 'vitest/config';
+import { defineConfig } from 'vitest/config';
export default defineConfig({
- test: { dir: './tests', include: ['./**/index.ts'] }
-}) as UserConfig;
+ test: {
+ name: 'core',
+ include: ['./tests/**/index.ts']
+ }
+});
diff --git a/packages/create/.gitignore b/packages/create/.gitignore
index 14b63618..e7e5bfa8 100644
--- a/packages/create/.gitignore
+++ b/packages/create/.gitignore
@@ -1,5 +1,4 @@
/dist
-/.test-tmp
# re-enable this once we're out of prerelease
/cli/versions.js
diff --git a/packages/create/package.json b/packages/create/package.json
index c0560933..762372ba 100644
--- a/packages/create/package.json
+++ b/packages/create/package.json
@@ -16,7 +16,7 @@
"check": "tsc",
"format": "pnpm lint --write",
"lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore",
- "test": "pnpm build:dist && vitest run",
+ "test": "vitest run",
"update-template-repo": "pnpm build:dist && echo \"Updating template repo\" && bash ./scripts/update-template-repo.sh"
},
"files": [
diff --git a/packages/create/test/check.ts b/packages/create/test/check.ts
index 8beb3dba..ba807aa3 100644
--- a/packages/create/test/check.ts
+++ b/packages/create/test/check.ts
@@ -1,9 +1,8 @@
-import { exec } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
-import { fileURLToPath } from 'node:url';
import { promisify } from 'node:util';
-import glob from 'tiny-glob/sync.js';
+import { fileURLToPath } from 'node:url';
+import { exec, type PromiseWithChild } from 'node:child_process';
import { beforeAll, describe, test } from 'vitest';
import { create, type LanguageType, type TemplateType } from '../index.ts';
@@ -11,38 +10,11 @@ import { create, type LanguageType, type TemplateType } from '../index.ts';
const resolve_path = (path: string) => fileURLToPath(new URL(path, import.meta.url));
// use a directory outside of packages to ensure it isn't added to the pnpm workspace
-const test_workspace_dir = resolve_path('../../../.test-tmp/create-svelte/');
-
-const existing_workspace_overrides = JSON.parse(
- fs.readFileSync(resolve_path('../../../package.json'), 'utf-8')
-).pnpm?.overrides;
-
-const overrides = { ...existing_workspace_overrides };
-
-for (const pkg_path of glob(resolve_path('../../../packages/*/package.json'))) {
- const name = JSON.parse(fs.readFileSync(pkg_path, 'utf-8')).name;
- // use `file:` protocol for opting into stricter resolve logic which catches more bugs
- overrides[name] = `file:${path.dirname(path.resolve(pkg_path))}`;
-}
+const test_workspace_dir = resolve_path('../../../.test-output/create/');
// prepare test pnpm workspace
fs.rmSync(test_workspace_dir, { recursive: true, force: true });
fs.mkdirSync(test_workspace_dir, { recursive: true });
-const workspace = {
- name: 'svelte-check-test-fake-pnpm-workspace',
- private: true,
- version: '0.0.0',
- pnpm: { overrides },
- // convert override query "@foo/bar@>x [query.replace(/(@?[^@]+)@.*$/, '$1'), range])
- )
-};
-
-fs.writeFileSync(
- path.join(test_workspace_dir, 'package.json'),
- JSON.stringify(workspace, null, '\t')
-);
fs.writeFileSync(path.join(test_workspace_dir, 'pnpm-workspace.yaml'), 'packages:\n - ./*\n');
@@ -54,37 +26,13 @@ beforeAll(async () => {
});
}, 60000);
-function patch_package_json(pkg: any) {
- Object.entries(overrides).forEach(([key, value]) => {
- if (pkg.devDependencies?.[key]) {
- pkg.devDependencies[key] = value;
- }
-
- if (pkg.dependencies?.[key]) {
- pkg.dependencies[key] = value;
- }
-
- if (!pkg.pnpm) {
- pkg.pnpm = {};
- }
-
- if (!pkg.pnpm.overrides) {
- pkg.pnpm.overrides = {};
- }
-
- pkg.pnpm.overrides = { ...pkg.pnpm.overrides, ...overrides };
- });
- pkg.private = true;
-}
-
/**
* Tests in different templates can be run concurrently for a nice speedup locally, but tests within a template must be run sequentially.
* It'd be better to group tests by template, but vitest doesn't support that yet.
- * @type {Map import('node:child_process').PromiseWithChild][]>}
*/
-const script_test_map = new Map();
+const script_test_map = new Map PromiseWithChild]>>();
-const templates = fs.readdirSync('templates') as TemplateType[];
+const templates = fs.readdirSync(resolve_path('../templates/')) as TemplateType[];
for (const template of templates) {
if (template[0] === '.') continue;
@@ -93,16 +41,9 @@ for (const template of templates) {
const cwd = path.join(test_workspace_dir, `${template}-${types}`);
fs.rmSync(cwd, { recursive: true, force: true });
- create(cwd, {
- name: `create-svelte-test-${template}-${types}`,
- template,
- types
- });
+ create(cwd, { name: `create-svelte-test-${template}-${types}`, template, types });
const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'));
- patch_package_json(pkg);
-
- fs.writeFileSync(path.join(cwd, 'package.json'), JSON.stringify(pkg, null, '\t') + '\n');
// run provided scripts that are non-blocking. All of them should exit with 0
// package script requires lib dir
@@ -120,13 +61,9 @@ for (const template of templates) {
}
for (const [script, tests] of script_test_map) {
- describe.concurrent(
- script,
- () => {
- for (const [name, task] of tests) {
- test(name, task);
- }
- },
- { timeout: 60000 }
- );
+ describe.concurrent(script, { timeout: 60000 }, () => {
+ for (const [name, task] of tests) {
+ test(name, task);
+ }
+ });
}
diff --git a/packages/create/tsconfig.json b/packages/create/tsconfig.json
index 770dd836..c7f6b862 100644
--- a/packages/create/tsconfig.json
+++ b/packages/create/tsconfig.json
@@ -6,5 +6,5 @@
"declaration": true
},
// overrides the root tsconfig `exclude` field so we're not ignoring the `test` dir
- "exclude": ["templates/**", "shared/**", "dist/**"]
+ "exclude": ["templates/**", "shared/**", "dist/**", "vitest.config.ts"]
}
diff --git a/packages/create/vitest.config.ts b/packages/create/vitest.config.ts
index 78e3ca4a..f29b5427 100644
--- a/packages/create/vitest.config.ts
+++ b/packages/create/vitest.config.ts
@@ -1,7 +1,10 @@
-import { defineConfig, type UserConfig } from 'vitest/config';
+import { env } from 'node:process';
+import { defineConfig } from 'vitest/config';
-const config: UserConfig = defineConfig({
- test: { dir: './test', include: ['*.ts'] }
+export default defineConfig({
+ test: {
+ name: 'create',
+ include: ['test/*.ts'],
+ retry: env.CI ? 3 : 0
+ }
});
-
-export default config;
diff --git a/packages/migrate/package.json b/packages/migrate/package.json
index 1301f58c..c856a64b 100644
--- a/packages/migrate/package.json
+++ b/packages/migrate/package.json
@@ -14,7 +14,7 @@
"check": "tsc",
"format": "pnpm lint --write",
"lint": "prettier --check .",
- "test": "vitest run --silent"
+ "test": "vitest run"
},
"files": [
"bin.js",
@@ -41,8 +41,7 @@
"@types/node": "^18.19.48",
"@types/prompts": "^2.4.9",
"@types/semver": "^7.5.6",
- "svelte": "^4.2.10",
- "vitest": "^2.0.1"
+ "svelte": "^4.2.10"
},
"keywords": [
"migration",
diff --git a/packages/migrate/vitest.config.ts b/packages/migrate/vitest.config.ts
new file mode 100644
index 00000000..22afa1cf
--- /dev/null
+++ b/packages/migrate/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ name: 'migrate'
+ }
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index bf920c59..bb9ceae1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,9 @@ importers:
'@changesets/cli':
specifier: ^2.27.9
version: 2.27.9
+ '@playwright/test':
+ specifier: ^1.48.2
+ version: 1.48.2
'@rollup/plugin-commonjs':
specifier: ^26.0.1
version: 26.0.1(rollup@4.21.2)
@@ -28,16 +31,16 @@ importers:
version: link:packages/create
'@sveltejs/eslint-config':
specifier: ^8.1.0
- version: 8.1.0(@stylistic/eslint-plugin-js@2.8.0(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.10.2(eslint@9.10.0))(eslint-plugin-svelte@2.43.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.2))(typescript@5.6.2)
+ version: 8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.13.1(eslint@9.10.0))(eslint-plugin-svelte@2.46.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.3))(typescript@5.6.3)
'@svitejs/changesets-changelog-github-compact':
specifier: ^1.1.0
version: 1.1.0
'@types/node':
specifier: ^22.3.0
- version: 22.5.4
+ version: 22.9.0
'@vitest/ui':
- specifier: ^2.0.5
- version: 2.0.5(vitest@2.0.5)
+ specifier: ^2.1.4
+ version: 2.1.4(vitest@2.1.4)
eslint:
specifier: ^9.10.0
version: 9.10.0
@@ -58,7 +61,7 @@ importers:
version: 4.21.2
rollup-plugin-esbuild:
specifier: ^6.1.1
- version: 6.1.1(esbuild@0.21.5)(rollup@4.21.2)
+ version: 6.1.1(esbuild@0.24.0)(rollup@4.21.2)
rollup-plugin-preserve-shebangs:
specifier: ^0.2.0
version: 0.2.0(rollup@4.21.2)
@@ -70,16 +73,16 @@ importers:
version: 5.0.0
typescript:
specifier: ^5.6.2
- version: 5.6.2
+ version: 5.6.3
typescript-eslint:
specifier: ^8.5.0
- version: 8.5.0(eslint@9.10.0)(typescript@5.6.2)
+ version: 8.5.0(eslint@9.10.0)(typescript@5.6.3)
unplugin-isolated-decl:
specifier: ^0.6.5
- version: 0.6.5(rollup@4.21.2)(typescript@5.6.2)(webpack-sources@3.2.3)
+ version: 0.6.5(rollup@4.21.2)(typescript@5.6.3)(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.4
+ version: 2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4)
community-adder-template:
dependencies:
@@ -87,9 +90,15 @@ importers:
specifier: workspace:*
version: link:../packages/core
devDependencies:
+ '@playwright/test':
+ specifier: ^1.48.2
+ version: 1.48.2
sv:
specifier: workspace:*
version: link:../packages/cli
+ vitest:
+ specifier: ^2.1.4
+ version: 2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4)
packages/adders:
dependencies:
@@ -119,7 +128,7 @@ importers:
version: 9.1.0
postcss:
specifier: ^8.4.38
- version: 8.4.45
+ version: 8.4.47
recast:
specifier: ^0.23.7
version: 0.23.9
@@ -134,7 +143,7 @@ importers:
devDependencies:
picocolors:
specifier: ^1.1.0
- version: 1.1.0
+ version: 1.1.1
sisteransi:
specifier: ^1.0.5
version: 1.0.5
@@ -152,7 +161,7 @@ importers:
version: 1.3.0
picocolors:
specifier: ^1.1.0
- version: 1.1.0
+ version: 1.1.1
sisteransi:
specifier: ^1.0.5
version: 1.0.5
@@ -171,12 +180,21 @@ importers:
'@sveltejs/create':
specifier: workspace:*
version: link:../create
+ '@types/degit':
+ specifier: ^2.8.6
+ version: 2.8.6
+ '@types/ps-tree':
+ specifier: ^1.1.6
+ version: 1.1.6
'@types/tar-fs':
specifier: ^2.0.4
version: 2.0.4
commander:
specifier: ^12.1.0
version: 12.1.0
+ degit:
+ specifier: ^2.8.4
+ version: 2.8.4
empathic:
specifier: ^1.0.0
version: 1.0.0
@@ -185,16 +203,19 @@ importers:
version: 0.2.2
picocolors:
specifier: ^1.1.0
- version: 1.1.0
+ version: 1.1.1
+ ps-tree:
+ specifier: ^1.2.0
+ version: 1.2.0
tar-fs:
specifier: ^3.0.6
version: 3.0.6
tinyexec:
- specifier: ^0.3.0
- version: 0.3.0
+ specifier: ^0.3.1
+ version: 0.3.1
valibot:
specifier: ^0.41.0
- version: 0.41.0(typescript@5.6.2)
+ version: 0.41.0(typescript@5.6.3)
packages/core:
dependencies:
@@ -216,7 +237,7 @@ importers:
version: 0.30.12
picocolors:
specifier: ^1.1.0
- version: 1.1.0
+ version: 1.1.1
packages/create:
devDependencies:
@@ -258,7 +279,7 @@ importers:
version: 24.0.0
typescript:
specifier: ^5.3.3
- version: 5.6.2
+ version: 5.6.3
zimmerframe:
specifier: ^1.1.2
version: 1.1.2
@@ -275,9 +296,6 @@ importers:
svelte:
specifier: ^4.2.10
version: 4.2.19
- vitest:
- specifier: ^2.0.1
- version: 2.0.5(@types/node@18.19.64)(@vitest/ui@2.0.5)
packages:
@@ -370,146 +388,290 @@ packages:
cpu: [ppc64]
os: [aix]
+ '@esbuild/aix-ppc64@0.24.0':
+ resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
'@esbuild/android-arm64@0.21.5':
resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
+ '@esbuild/android-arm64@0.24.0':
+ resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
'@esbuild/android-arm@0.21.5':
resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
engines: {node: '>=12'}
cpu: [arm]
os: [android]
+ '@esbuild/android-arm@0.24.0':
+ resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
'@esbuild/android-x64@0.21.5':
resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
engines: {node: '>=12'}
cpu: [x64]
os: [android]
+ '@esbuild/android-x64@0.24.0':
+ resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
'@esbuild/darwin-arm64@0.21.5':
resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
+ '@esbuild/darwin-arm64@0.24.0':
+ resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
'@esbuild/darwin-x64@0.21.5':
resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
+ '@esbuild/darwin-x64@0.24.0':
+ resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
'@esbuild/freebsd-arm64@0.21.5':
resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
+ '@esbuild/freebsd-arm64@0.24.0':
+ resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
'@esbuild/freebsd-x64@0.21.5':
resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
+ '@esbuild/freebsd-x64@0.24.0':
+ resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
'@esbuild/linux-arm64@0.21.5':
resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
+ '@esbuild/linux-arm64@0.24.0':
+ resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
'@esbuild/linux-arm@0.21.5':
resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
+ '@esbuild/linux-arm@0.24.0':
+ resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
'@esbuild/linux-ia32@0.21.5':
resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
+ '@esbuild/linux-ia32@0.24.0':
+ resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
'@esbuild/linux-loong64@0.21.5':
resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
engines: {node: '>=12'}
cpu: [loong64]
os: [linux]
+ '@esbuild/linux-loong64@0.24.0':
+ resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
'@esbuild/linux-mips64el@0.21.5':
resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
+ '@esbuild/linux-mips64el@0.24.0':
+ resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
'@esbuild/linux-ppc64@0.21.5':
resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
+ '@esbuild/linux-ppc64@0.24.0':
+ resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
'@esbuild/linux-riscv64@0.21.5':
resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
+ '@esbuild/linux-riscv64@0.24.0':
+ resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
'@esbuild/linux-s390x@0.21.5':
resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
+ '@esbuild/linux-s390x@0.24.0':
+ resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
'@esbuild/linux-x64@0.21.5':
resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [linux]
+ '@esbuild/linux-x64@0.24.0':
+ resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
'@esbuild/netbsd-x64@0.21.5':
resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
+ '@esbuild/netbsd-x64@0.24.0':
+ resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.24.0':
+ resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
'@esbuild/openbsd-x64@0.21.5':
resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
+ '@esbuild/openbsd-x64@0.24.0':
+ resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
'@esbuild/sunos-x64@0.21.5':
resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
+ '@esbuild/sunos-x64@0.24.0':
+ resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
'@esbuild/win32-arm64@0.21.5':
resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
+ '@esbuild/win32-arm64@0.24.0':
+ resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
'@esbuild/win32-ia32@0.21.5':
resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
+ '@esbuild/win32-ia32@0.24.0':
+ resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
'@esbuild/win32-x64@0.21.5':
resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
- '@eslint-community/eslint-utils@4.4.0':
- resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
+ '@esbuild/win32-x64@0.24.0':
+ resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@eslint-community/eslint-utils@4.4.1':
+ resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
- '@eslint-community/regexpp@4.11.0':
- resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==}
+ '@eslint-community/regexpp@4.12.1':
+ resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
'@eslint/config-array@0.18.0':
@@ -628,6 +790,11 @@ packages:
resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ '@playwright/test@1.48.2':
+ resolution: {integrity: sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
'@polka/url@1.0.0-next.25':
resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==}
@@ -756,8 +923,8 @@ packages:
cpu: [x64]
os: [win32]
- '@stylistic/eslint-plugin-js@2.8.0':
- resolution: {integrity: sha512-/e7pSzVMrwBd6yzSDsKHwax3TS96+pd/xSKzELaTkOuYqUhYfj/becWdfDbFSBGQD7BBBCiiE4L8L2cUfu5h+A==}
+ '@stylistic/eslint-plugin-js@2.10.1':
+ resolution: {integrity: sha512-IikL/RKy9Sk2UMDUUpqrEcwDeYzUEt6SaL2/UVCFuVQxKACHSgStT0NxXkxZmBOUforaU52FPf2Su07FYH5s5g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: '>=8.40.0'
@@ -780,6 +947,9 @@ packages:
'@ts-morph/common@0.25.0':
resolution: {integrity: sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg==}
+ '@types/degit@2.8.6':
+ resolution: {integrity: sha512-y0M7sqzsnHB6cvAeTCBPrCQNQiZe8U4qdzf8uBVmOWYap5MMTN/gB2iEqrIqFiYcsyvP74GnGD5tgsHttielFw==}
+
'@types/estree@1.0.5':
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
@@ -792,12 +962,15 @@ packages:
'@types/node@18.19.64':
resolution: {integrity: sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==}
- '@types/node@22.5.4':
- resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==}
+ '@types/node@22.9.0':
+ resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==}
'@types/prompts@2.4.9':
resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==}
+ '@types/ps-tree@1.1.6':
+ resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==}
+
'@types/resolve@1.20.2':
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
@@ -867,28 +1040,39 @@ 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.4':
+ resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==}
- '@vitest/pretty-format@2.0.5':
- resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==}
+ '@vitest/mocker@2.1.4':
+ resolution: {integrity: sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^5.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
- '@vitest/runner@2.0.5':
- resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==}
+ '@vitest/pretty-format@2.1.4':
+ resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==}
- '@vitest/snapshot@2.0.5':
- resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==}
+ '@vitest/runner@2.1.4':
+ resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==}
- '@vitest/spy@2.0.5':
- resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==}
+ '@vitest/snapshot@2.1.4':
+ resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==}
- '@vitest/ui@2.0.5':
- resolution: {integrity: sha512-m+ZpVt/PVi/nbeRKEjdiYeoh0aOfI9zr3Ria9LO7V2PlMETtAXJS3uETEZkc8Be2oOl8mhd7Ew+5SRBXRYncNw==}
+ '@vitest/spy@2.1.4':
+ resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==}
+
+ '@vitest/ui@2.1.4':
+ resolution: {integrity: sha512-Zd9e5oU063c+j9N9XzGJagCLNvG71x/2tOme3Js4JEZKX55zsgxhJwUgLI8hkN6NjMLpdJO8d7nVUUuPGAA58Q==}
peerDependencies:
- vitest: 2.0.5
+ vitest: 2.1.4
- '@vitest/utils@2.0.5':
- resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==}
+ '@vitest/utils@2.1.4':
+ resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==}
acorn-jsx@5.3.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
@@ -900,8 +1084,8 @@ packages:
peerDependencies:
acorn: '>=8.9.0'
- acorn@8.12.1:
- resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
+ acorn@8.14.0:
+ resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
engines: {node: '>=0.4.0'}
hasBin: true
@@ -1008,8 +1192,8 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
- chai@5.1.1:
- resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==}
+ chai@5.1.2:
+ resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==}
engines: {node: '>=12'}
chalk@4.1.2:
@@ -1052,7 +1236,7 @@ packages:
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
concat-map@0.0.1:
- resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
cross-spawn@5.1.0:
resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
@@ -1105,6 +1289,11 @@ packages:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
+ degit@2.8.4:
+ resolution: {integrity: sha512-vqYuzmSA5I50J882jd+AbAhQtgK6bdKUJIex1JNfEUPENCgYsxugzKVZlFyMwV4i06MmnV47/Iqi5Io86zf3Ng==}
+ engines: {node: '>=8.0.0'}
+ hasBin: true
+
detect-indent@6.1.0:
resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
engines: {node: '>=8'}
@@ -1138,6 +1327,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==}
@@ -1174,6 +1366,11 @@ packages:
engines: {node: '>=12'}
hasBin: true
+ esbuild@0.24.0:
+ resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
@@ -1196,18 +1393,18 @@ packages:
peerDependencies:
eslint: '>=8'
- eslint-plugin-n@17.10.2:
- resolution: {integrity: sha512-e+s4eAf5NtJaxPhTNu3qMO0Iz40WANS93w9LQgYcvuljgvDmWi/a3rh+OrNyMHeng6aOWGJO0rCg5lH4zi8yTw==}
+ eslint-plugin-n@17.13.1:
+ resolution: {integrity: sha512-97qzhk1z3DdSJNCqT45EslwCu5+LB9GDadSyBItgKUfGsXAmN/aa7LRQ0ZxHffUxUzvgbTPJL27/pE9ZQWHy7A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: '>=8.23.0'
- eslint-plugin-svelte@2.43.0:
- resolution: {integrity: sha512-REkxQWvg2pp7QVLxQNa+dJ97xUqRe7Y2JJbSWkHSuszu0VcblZtXkPBPckkivk99y5CdLw4slqfPylL2d/X4jQ==}
+ eslint-plugin-svelte@2.46.0:
+ resolution: {integrity: sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==}
engines: {node: ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0-0 || ^9.0.0-0
- svelte: ^3.37.0 || ^4.0.0 || ^5.0.0-next.191
+ svelte: ^3.37.0 || ^4.0.0 || ^5.0.0
peerDependenciesMeta:
svelte:
optional: true
@@ -1224,8 +1421,8 @@ packages:
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- eslint-visitor-keys@4.0.0:
- resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==}
+ eslint-visitor-keys@4.2.0:
+ resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
eslint@9.10.0:
@@ -1241,8 +1438,8 @@ packages:
esm-env@1.0.0:
resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==}
- espree@10.1.0:
- resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==}
+ espree@10.3.0:
+ resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
espree@9.6.1:
@@ -1279,9 +1476,12 @@ 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==}
+
+ expect-type@1.1.0:
+ resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==}
+ engines: {node: '>=12.0.0'}
extendable-error@0.1.7:
resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==}
@@ -1347,6 +1547,9 @@ 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@7.0.1:
resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
engines: {node: '>=6 <7 || >=8'}
@@ -1355,6 +1558,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}
@@ -1363,19 +1571,12 @@ packages:
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
- get-func-name@2.0.2:
- resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
-
get-stdin@9.0.0:
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==}
+ get-tsconfig@4.8.1:
+ resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
git-hooks-list@3.1.0:
resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==}
@@ -1400,8 +1601,8 @@ packages:
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
engines: {node: '>=18'}
- globals@15.9.0:
- resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==}
+ globals@15.12.0:
+ resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==}
engines: {node: '>=18'}
globalyzer@0.1.0:
@@ -1438,10 +1639,6 @@ packages:
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'}
@@ -1502,10 +1699,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'}
@@ -1555,8 +1748,8 @@ packages:
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
engines: {node: '>=6'}
- known-css-properties@0.34.0:
- resolution: {integrity: sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==}
+ known-css-properties@0.35.0:
+ resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==}
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
@@ -1586,8 +1779,8 @@ packages:
lodash.startcase@4.4.0:
resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
- loupe@3.1.1:
- resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==}
+ loupe@3.1.2:
+ resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==}
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@@ -1601,12 +1794,12 @@ packages:
magic-string@0.30.12:
resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==}
+ map-stream@0.1.0:
+ resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==}
+
mdn-data@2.0.30:
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
- merge-stream@2.0.0:
- resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
-
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@@ -1615,10 +1808,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==}
@@ -1661,10 +1850,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'}
@@ -1672,10 +1857,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'}
@@ -1739,10 +1920,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==}
@@ -1761,11 +1938,14 @@ packages:
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
engines: {node: '>= 14.16'}
+ pause-stream@0.0.11:
+ resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==}
+
periscopic@3.1.0:
resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
- picocolors@1.1.0:
- resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
@@ -1783,6 +1963,16 @@ packages:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
+ playwright-core@1.48.2:
+ resolution: {integrity: sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ playwright@1.48.2:
+ resolution: {integrity: sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
postcss-load-config@3.1.4:
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
@@ -1811,8 +2001,8 @@ packages:
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
engines: {node: '>=4'}
- postcss@8.4.45:
- resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==}
+ postcss@8.4.47:
+ resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==}
engines: {node: ^10 || ^12 || >=14}
prelude-ls@1.2.1:
@@ -1847,6 +2037,11 @@ packages:
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
engines: {node: '>= 6'}
+ 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==}
@@ -1950,9 +2145,9 @@ packages:
silver-fleece@1.2.1:
resolution: {integrity: sha512-GwiBh7LzX4aKWb3LH1tPu8et2zZqe1cwXn+/uwIUK+H1Y2k119qpvPelVdRKG/6+RQvtUdRep4mBOOVf80VYDA==}
- sirv@2.0.4:
- resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==}
- engines: {node: '>= 10'}
+ sirv@3.0.0:
+ resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==}
+ engines: {node: '>=18'}
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
@@ -1987,6 +2182,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==}
@@ -1996,6 +2194,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==}
@@ -2019,10 +2220,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'}
@@ -2040,11 +2237,11 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
- svelte-eslint-parser@0.41.0:
- resolution: {integrity: sha512-L6f4hOL+AbgfBIB52Z310pg1d2QjRqm7wy3kI1W6hhdhX5bvu7+f0R6w4ykp5HoDdzq+vGhIJmsisaiJDGmVfA==}
+ svelte-eslint-parser@0.43.0:
+ resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
- svelte: ^3.37.0 || ^4.0.0 || ^5.0.0-next.191
+ svelte: ^3.37.0 || ^4.0.0 || ^5.0.0
peerDependenciesMeta:
svelte:
optional: true
@@ -2088,6 +2285,9 @@ packages:
thenify@3.3.1:
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+ through@2.3.8:
+ resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
+
tiny-glob@0.2.9:
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
@@ -2097,8 +2297,8 @@ packages:
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
- tinyexec@0.3.0:
- resolution: {integrity: sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==}
+ tinyexec@0.3.1:
+ resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==}
tinyglobby@0.2.10:
resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==}
@@ -2163,8 +2363,8 @@ packages:
typescript:
optional: true
- typescript@5.6.2:
- resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==}
+ typescript@5.6.3:
+ resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
engines: {node: '>=14.17'}
hasBin: true
@@ -2216,13 +2416,13 @@ packages:
typescript:
optional: true
- vite-node@2.0.5:
- resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==}
+ vite-node@2.1.4:
+ resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
- vite@5.4.3:
- resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==}
+ vite@5.4.10:
+ resolution: {integrity: sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
@@ -2252,15 +2452,15 @@ packages:
terser:
optional: true
- vitest@2.0.5:
- resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==}
+ vitest@2.1.4:
+ resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==}
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.4
+ '@vitest/ui': 2.1.4
happy-dom: '*'
jsdom: '*'
peerDependenciesMeta:
@@ -2412,7 +2612,7 @@ snapshots:
mri: 1.2.0
p-limit: 2.3.0
package-manager-detector: 0.2.2
- picocolors: 1.1.0
+ picocolors: 1.1.1
resolve-from: 5.0.0
semver: 7.6.3
spawndamnit: 2.0.0
@@ -2436,7 +2636,7 @@ snapshots:
dependencies:
'@changesets/types': 6.0.0
'@manypkg/get-packages': 1.1.3
- picocolors: 1.1.0
+ picocolors: 1.1.1
semver: 7.6.3
'@changesets/get-github-info@0.5.2':
@@ -2467,7 +2667,7 @@ snapshots:
'@changesets/logger@0.1.1':
dependencies:
- picocolors: 1.1.0
+ picocolors: 1.1.1
'@changesets/parse@0.4.0':
dependencies:
@@ -2489,7 +2689,7 @@ snapshots:
'@changesets/types': 6.0.0
fs-extra: 7.0.1
p-filter: 2.1.0
- picocolors: 1.1.0
+ picocolors: 1.1.1
'@changesets/should-skip-package@0.1.1':
dependencies:
@@ -2510,78 +2710,150 @@ snapshots:
'@esbuild/aix-ppc64@0.21.5':
optional: true
+ '@esbuild/aix-ppc64@0.24.0':
+ optional: true
+
'@esbuild/android-arm64@0.21.5':
optional: true
+ '@esbuild/android-arm64@0.24.0':
+ optional: true
+
'@esbuild/android-arm@0.21.5':
optional: true
+ '@esbuild/android-arm@0.24.0':
+ optional: true
+
'@esbuild/android-x64@0.21.5':
optional: true
+ '@esbuild/android-x64@0.24.0':
+ optional: true
+
'@esbuild/darwin-arm64@0.21.5':
optional: true
+ '@esbuild/darwin-arm64@0.24.0':
+ optional: true
+
'@esbuild/darwin-x64@0.21.5':
optional: true
+ '@esbuild/darwin-x64@0.24.0':
+ optional: true
+
'@esbuild/freebsd-arm64@0.21.5':
optional: true
+ '@esbuild/freebsd-arm64@0.24.0':
+ optional: true
+
'@esbuild/freebsd-x64@0.21.5':
optional: true
+ '@esbuild/freebsd-x64@0.24.0':
+ optional: true
+
'@esbuild/linux-arm64@0.21.5':
optional: true
+ '@esbuild/linux-arm64@0.24.0':
+ optional: true
+
'@esbuild/linux-arm@0.21.5':
optional: true
+ '@esbuild/linux-arm@0.24.0':
+ optional: true
+
'@esbuild/linux-ia32@0.21.5':
optional: true
+ '@esbuild/linux-ia32@0.24.0':
+ optional: true
+
'@esbuild/linux-loong64@0.21.5':
optional: true
+ '@esbuild/linux-loong64@0.24.0':
+ optional: true
+
'@esbuild/linux-mips64el@0.21.5':
optional: true
+ '@esbuild/linux-mips64el@0.24.0':
+ optional: true
+
'@esbuild/linux-ppc64@0.21.5':
optional: true
+ '@esbuild/linux-ppc64@0.24.0':
+ optional: true
+
'@esbuild/linux-riscv64@0.21.5':
optional: true
+ '@esbuild/linux-riscv64@0.24.0':
+ optional: true
+
'@esbuild/linux-s390x@0.21.5':
optional: true
+ '@esbuild/linux-s390x@0.24.0':
+ optional: true
+
'@esbuild/linux-x64@0.21.5':
optional: true
+ '@esbuild/linux-x64@0.24.0':
+ optional: true
+
'@esbuild/netbsd-x64@0.21.5':
optional: true
+ '@esbuild/netbsd-x64@0.24.0':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.24.0':
+ optional: true
+
'@esbuild/openbsd-x64@0.21.5':
optional: true
+ '@esbuild/openbsd-x64@0.24.0':
+ optional: true
+
'@esbuild/sunos-x64@0.21.5':
optional: true
+ '@esbuild/sunos-x64@0.24.0':
+ optional: true
+
'@esbuild/win32-arm64@0.21.5':
optional: true
+ '@esbuild/win32-arm64@0.24.0':
+ optional: true
+
'@esbuild/win32-ia32@0.21.5':
optional: true
+ '@esbuild/win32-ia32@0.24.0':
+ optional: true
+
'@esbuild/win32-x64@0.21.5':
optional: true
- '@eslint-community/eslint-utils@4.4.0(eslint@9.10.0)':
+ '@esbuild/win32-x64@0.24.0':
+ optional: true
+
+ '@eslint-community/eslint-utils@4.4.1(eslint@9.10.0)':
dependencies:
eslint: 9.10.0
eslint-visitor-keys: 3.4.3
- '@eslint-community/regexpp@4.11.0': {}
+ '@eslint-community/regexpp@4.12.1': {}
'@eslint/config-array@0.18.0':
dependencies:
@@ -2595,7 +2867,7 @@ snapshots:
dependencies:
ajv: 6.12.6
debug: 4.3.7
- espree: 10.1.0
+ espree: 10.3.0
globals: 14.0.0
ignore: 5.3.2
import-fresh: 3.3.0
@@ -2700,6 +2972,10 @@ snapshots:
'@pkgr/core@0.1.1': {}
+ '@playwright/test@1.48.2':
+ dependencies:
+ playwright: 1.48.2
+
'@polka/url@1.0.0-next.25': {}
'@rollup/plugin-commonjs@26.0.1(rollup@4.21.2)':
@@ -2796,22 +3072,22 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.21.2':
optional: true
- '@stylistic/eslint-plugin-js@2.8.0(eslint@9.10.0)':
+ '@stylistic/eslint-plugin-js@2.10.1(eslint@9.10.0)':
dependencies:
eslint: 9.10.0
- eslint-visitor-keys: 4.0.0
- espree: 10.1.0
+ eslint-visitor-keys: 4.2.0
+ espree: 10.3.0
- '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.8.0(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.10.2(eslint@9.10.0))(eslint-plugin-svelte@2.43.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.2))(typescript@5.6.2)':
+ '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.10.0))(eslint-config-prettier@9.1.0(eslint@9.10.0))(eslint-plugin-n@17.13.1(eslint@9.10.0))(eslint-plugin-svelte@2.46.0(eslint@9.10.0)(svelte@5.0.0))(eslint@9.10.0)(typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.3))(typescript@5.6.3)':
dependencies:
- '@stylistic/eslint-plugin-js': 2.8.0(eslint@9.10.0)
+ '@stylistic/eslint-plugin-js': 2.10.1(eslint@9.10.0)
eslint: 9.10.0
eslint-config-prettier: 9.1.0(eslint@9.10.0)
- eslint-plugin-n: 17.10.2(eslint@9.10.0)
- eslint-plugin-svelte: 2.43.0(eslint@9.10.0)(svelte@5.0.0)
- globals: 15.9.0
- typescript: 5.6.2
- typescript-eslint: 8.5.0(eslint@9.10.0)(typescript@5.6.2)
+ eslint-plugin-n: 17.13.1(eslint@9.10.0)
+ eslint-plugin-svelte: 2.46.0(eslint@9.10.0)(svelte@5.0.0)
+ globals: 15.12.0
+ typescript: 5.6.3
+ typescript-eslint: 8.5.0(eslint@9.10.0)(typescript@5.6.3)
'@svitejs/changesets-changelog-github-compact@1.1.0':
dependencies:
@@ -2826,6 +3102,8 @@ snapshots:
path-browserify: 1.0.1
tinyglobby: 0.2.10
+ '@types/degit@2.8.6': {}
+
'@types/estree@1.0.5': {}
'@types/gitignore-parser@0.0.3': {}
@@ -2836,56 +3114,58 @@ snapshots:
dependencies:
undici-types: 5.26.5
- '@types/node@22.5.4':
+ '@types/node@22.9.0':
dependencies:
undici-types: 6.19.8
'@types/prompts@2.4.9':
dependencies:
- '@types/node': 18.19.64
+ '@types/node': 22.9.0
kleur: 3.0.3
+ '@types/ps-tree@1.1.6': {}
+
'@types/resolve@1.20.2': {}
'@types/semver@7.5.8': {}
'@types/tar-fs@2.0.4':
dependencies:
- '@types/node': 22.5.4
+ '@types/node': 22.9.0
'@types/tar-stream': 3.1.3
'@types/tar-stream@3.1.3':
dependencies:
- '@types/node': 22.5.4
+ '@types/node': 22.9.0
- '@typescript-eslint/eslint-plugin@8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.2))(eslint@9.10.0)(typescript@5.6.2)':
+ '@typescript-eslint/eslint-plugin@8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.3))(eslint@9.10.0)(typescript@5.6.3)':
dependencies:
- '@eslint-community/regexpp': 4.11.0
- '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.2)
+ '@eslint-community/regexpp': 4.12.1
+ '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.3)
'@typescript-eslint/scope-manager': 8.5.0
- '@typescript-eslint/type-utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2)
- '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2)
+ '@typescript-eslint/type-utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3)
+ '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3)
'@typescript-eslint/visitor-keys': 8.5.0
eslint: 9.10.0
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
- ts-api-utils: 1.3.0(typescript@5.6.2)
+ ts-api-utils: 1.3.0(typescript@5.6.3)
optionalDependencies:
- typescript: 5.6.2
+ typescript: 5.6.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.2)':
+ '@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.3)':
dependencies:
'@typescript-eslint/scope-manager': 8.5.0
'@typescript-eslint/types': 8.5.0
- '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2)
+ '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.3)
'@typescript-eslint/visitor-keys': 8.5.0
debug: 4.3.7
eslint: 9.10.0
optionalDependencies:
- typescript: 5.6.2
+ typescript: 5.6.3
transitivePeerDependencies:
- supports-color
@@ -2894,21 +3174,21 @@ snapshots:
'@typescript-eslint/types': 8.5.0
'@typescript-eslint/visitor-keys': 8.5.0
- '@typescript-eslint/type-utils@8.5.0(eslint@9.10.0)(typescript@5.6.2)':
+ '@typescript-eslint/type-utils@8.5.0(eslint@9.10.0)(typescript@5.6.3)':
dependencies:
- '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2)
- '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2)
+ '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.3)
+ '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3)
debug: 4.3.7
- ts-api-utils: 1.3.0(typescript@5.6.2)
+ ts-api-utils: 1.3.0(typescript@5.6.3)
optionalDependencies:
- typescript: 5.6.2
+ typescript: 5.6.3
transitivePeerDependencies:
- eslint
- supports-color
'@typescript-eslint/types@8.5.0': {}
- '@typescript-eslint/typescript-estree@8.5.0(typescript@5.6.2)':
+ '@typescript-eslint/typescript-estree@8.5.0(typescript@5.6.3)':
dependencies:
'@typescript-eslint/types': 8.5.0
'@typescript-eslint/visitor-keys': 8.5.0
@@ -2917,18 +3197,18 @@ snapshots:
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.6.3
- ts-api-utils: 1.3.0(typescript@5.6.2)
+ ts-api-utils: 1.3.0(typescript@5.6.3)
optionalDependencies:
- typescript: 5.6.2
+ typescript: 5.6.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.5.0(eslint@9.10.0)(typescript@5.6.2)':
+ '@typescript-eslint/utils@8.5.0(eslint@9.10.0)(typescript@5.6.3)':
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0)
+ '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0)
'@typescript-eslint/scope-manager': 8.5.0
'@typescript-eslint/types': 8.5.0
- '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2)
+ '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.3)
eslint: 9.10.0
transitivePeerDependencies:
- supports-color
@@ -2939,59 +3219,66 @@ snapshots:
'@typescript-eslint/types': 8.5.0
eslint-visitor-keys: 3.4.3
- '@vitest/expect@2.0.5':
+ '@vitest/expect@2.1.4':
dependencies:
- '@vitest/spy': 2.0.5
- '@vitest/utils': 2.0.5
- chai: 5.1.1
+ '@vitest/spy': 2.1.4
+ '@vitest/utils': 2.1.4
+ chai: 5.1.2
tinyrainbow: 1.2.0
- '@vitest/pretty-format@2.0.5':
+ '@vitest/mocker@2.1.4(vite@5.4.10(@types/node@22.9.0))':
+ dependencies:
+ '@vitest/spy': 2.1.4
+ estree-walker: 3.0.3
+ magic-string: 0.30.12
+ optionalDependencies:
+ vite: 5.4.10(@types/node@22.9.0)
+
+ '@vitest/pretty-format@2.1.4':
dependencies:
tinyrainbow: 1.2.0
- '@vitest/runner@2.0.5':
+ '@vitest/runner@2.1.4':
dependencies:
- '@vitest/utils': 2.0.5
+ '@vitest/utils': 2.1.4
pathe: 1.1.2
- '@vitest/snapshot@2.0.5':
+ '@vitest/snapshot@2.1.4':
dependencies:
- '@vitest/pretty-format': 2.0.5
+ '@vitest/pretty-format': 2.1.4
magic-string: 0.30.12
pathe: 1.1.2
- '@vitest/spy@2.0.5':
+ '@vitest/spy@2.1.4':
dependencies:
tinyspy: 3.0.2
- '@vitest/ui@2.0.5(vitest@2.0.5)':
+ '@vitest/ui@2.1.4(vitest@2.1.4)':
dependencies:
- '@vitest/utils': 2.0.5
- fast-glob: 3.3.2
+ '@vitest/utils': 2.1.4
fflate: 0.8.2
flatted: 3.3.1
pathe: 1.1.2
- sirv: 2.0.4
+ sirv: 3.0.0
+ tinyglobby: 0.2.10
tinyrainbow: 1.2.0
- vitest: 2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5)
+ vitest: 2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4)
- '@vitest/utils@2.0.5':
+ '@vitest/utils@2.1.4':
dependencies:
- '@vitest/pretty-format': 2.0.5
- estree-walker: 3.0.3
- loupe: 3.1.1
+ '@vitest/pretty-format': 2.1.4
+ loupe: 3.1.2
tinyrainbow: 1.2.0
- acorn-jsx@5.3.2(acorn@8.12.1):
+ acorn-jsx@5.3.2(acorn@8.14.0):
dependencies:
- acorn: 8.12.1
+ acorn: 8.14.0
- acorn-typescript@1.4.13(acorn@8.12.1):
+ acorn-typescript@1.4.13(acorn@8.14.0):
dependencies:
- acorn: 8.12.1
+ acorn: 8.14.0
- acorn@8.12.1: {}
+ acorn@8.14.0: {}
ajv@6.12.6:
dependencies:
@@ -3085,12 +3372,12 @@ snapshots:
callsites@3.1.0: {}
- chai@5.1.1:
+ chai@5.1.2:
dependencies:
assertion-error: 2.0.1
check-error: 2.1.1
deep-eql: 5.0.2
- loupe: 3.1.1
+ loupe: 3.1.2
pathval: 2.0.0
chalk@4.1.2:
@@ -3110,7 +3397,7 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
'@types/estree': 1.0.5
- acorn: 8.12.1
+ acorn: 8.14.0
estree-walker: 3.0.3
periscopic: 3.1.0
@@ -3163,6 +3450,8 @@ snapshots:
deepmerge@4.3.1: {}
+ degit@2.8.4: {}
+
detect-indent@6.1.0: {}
detect-indent@7.0.1: {}
@@ -3193,6 +3482,8 @@ snapshots:
dotenv@16.4.5: {}
+ duplexer@0.1.2: {}
+
eastasianwidth@0.2.0: {}
emoji-regex@8.0.0: {}
@@ -3245,6 +3536,33 @@ snapshots:
'@esbuild/win32-ia32': 0.21.5
'@esbuild/win32-x64': 0.21.5
+ esbuild@0.24.0:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.24.0
+ '@esbuild/android-arm': 0.24.0
+ '@esbuild/android-arm64': 0.24.0
+ '@esbuild/android-x64': 0.24.0
+ '@esbuild/darwin-arm64': 0.24.0
+ '@esbuild/darwin-x64': 0.24.0
+ '@esbuild/freebsd-arm64': 0.24.0
+ '@esbuild/freebsd-x64': 0.24.0
+ '@esbuild/linux-arm': 0.24.0
+ '@esbuild/linux-arm64': 0.24.0
+ '@esbuild/linux-ia32': 0.24.0
+ '@esbuild/linux-loong64': 0.24.0
+ '@esbuild/linux-mips64el': 0.24.0
+ '@esbuild/linux-ppc64': 0.24.0
+ '@esbuild/linux-riscv64': 0.24.0
+ '@esbuild/linux-s390x': 0.24.0
+ '@esbuild/linux-x64': 0.24.0
+ '@esbuild/netbsd-x64': 0.24.0
+ '@esbuild/openbsd-arm64': 0.24.0
+ '@esbuild/openbsd-x64': 0.24.0
+ '@esbuild/sunos-x64': 0.24.0
+ '@esbuild/win32-arm64': 0.24.0
+ '@esbuild/win32-ia32': 0.24.0
+ '@esbuild/win32-x64': 0.24.0
+
escape-string-regexp@4.0.0: {}
eslint-compat-utils@0.5.1(eslint@9.10.0):
@@ -3258,37 +3576,37 @@ snapshots:
eslint-plugin-es-x@7.8.0(eslint@9.10.0):
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0)
- '@eslint-community/regexpp': 4.11.0
+ '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0)
+ '@eslint-community/regexpp': 4.12.1
eslint: 9.10.0
eslint-compat-utils: 0.5.1(eslint@9.10.0)
- eslint-plugin-n@17.10.2(eslint@9.10.0):
+ eslint-plugin-n@17.13.1(eslint@9.10.0):
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0)
+ '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0)
enhanced-resolve: 5.17.1
eslint: 9.10.0
eslint-plugin-es-x: 7.8.0(eslint@9.10.0)
- get-tsconfig: 4.8.0
- globals: 15.9.0
+ get-tsconfig: 4.8.1
+ globals: 15.12.0
ignore: 5.3.2
minimatch: 9.0.5
semver: 7.6.3
- eslint-plugin-svelte@2.43.0(eslint@9.10.0)(svelte@5.0.0):
+ eslint-plugin-svelte@2.46.0(eslint@9.10.0)(svelte@5.0.0):
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0)
+ '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0)
'@jridgewell/sourcemap-codec': 1.5.0
eslint: 9.10.0
eslint-compat-utils: 0.5.1(eslint@9.10.0)
esutils: 2.0.3
- known-css-properties: 0.34.0
- postcss: 8.4.45
- postcss-load-config: 3.1.4(postcss@8.4.45)
- postcss-safe-parser: 6.0.0(postcss@8.4.45)
+ known-css-properties: 0.35.0
+ postcss: 8.4.47
+ postcss-load-config: 3.1.4(postcss@8.4.47)
+ postcss-safe-parser: 6.0.0(postcss@8.4.47)
postcss-selector-parser: 6.1.2
semver: 7.6.3
- svelte-eslint-parser: 0.41.0(svelte@5.0.0)
+ svelte-eslint-parser: 0.43.0(svelte@5.0.0)
optionalDependencies:
svelte: 5.0.0
transitivePeerDependencies:
@@ -3306,12 +3624,12 @@ snapshots:
eslint-visitor-keys@3.4.3: {}
- eslint-visitor-keys@4.0.0: {}
+ eslint-visitor-keys@4.2.0: {}
eslint@9.10.0:
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0)
- '@eslint-community/regexpp': 4.11.0
+ '@eslint-community/eslint-utils': 4.4.1(eslint@9.10.0)
+ '@eslint-community/regexpp': 4.12.1
'@eslint/config-array': 0.18.0
'@eslint/eslintrc': 3.1.0
'@eslint/js': 9.10.0
@@ -3325,8 +3643,8 @@ snapshots:
debug: 4.3.7
escape-string-regexp: 4.0.0
eslint-scope: 8.0.2
- eslint-visitor-keys: 4.0.0
- espree: 10.1.0
+ eslint-visitor-keys: 4.2.0
+ espree: 10.3.0
esquery: 1.6.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
@@ -3349,16 +3667,16 @@ snapshots:
esm-env@1.0.0: {}
- espree@10.1.0:
+ espree@10.3.0:
dependencies:
- acorn: 8.12.1
- acorn-jsx: 5.3.2(acorn@8.12.1)
- eslint-visitor-keys: 4.0.0
+ acorn: 8.14.0
+ acorn-jsx: 5.3.2(acorn@8.14.0)
+ eslint-visitor-keys: 4.2.0
espree@9.6.1:
dependencies:
- acorn: 8.12.1
- acorn-jsx: 5.3.2(acorn@8.12.1)
+ acorn: 8.14.0
+ acorn-jsx: 5.3.2(acorn@8.14.0)
eslint-visitor-keys: 3.4.3
esprima@4.0.1: {}
@@ -3386,17 +3704,17 @@ 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
+
+ expect-type@1.1.0: {}
extendable-error@0.1.7: {}
@@ -3462,6 +3780,8 @@ snapshots:
cross-spawn: 7.0.3
signal-exit: 4.1.0
+ from@0.1.7: {}
+
fs-extra@7.0.1:
dependencies:
graceful-fs: 4.2.11
@@ -3474,18 +3794,17 @@ 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: {}
- get-func-name@2.0.2: {}
-
get-stdin@9.0.0: {}
- get-stream@8.0.1: {}
-
- get-tsconfig@4.8.0:
+ get-tsconfig@4.8.1:
dependencies:
resolve-pkg-maps: 1.0.0
@@ -3512,7 +3831,7 @@ snapshots:
globals@14.0.0: {}
- globals@15.9.0: {}
+ globals@15.12.0: {}
globalyzer@0.1.0: {}
@@ -3554,8 +3873,6 @@ snapshots:
human-id@1.0.2: {}
- human-signals@5.0.0: {}
-
iconv-lite@0.4.24:
dependencies:
safer-buffer: 2.1.2
@@ -3603,8 +3920,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
@@ -3648,7 +3963,7 @@ snapshots:
kleur@4.1.5: {}
- known-css-properties@0.34.0: {}
+ known-css-properties@0.35.0: {}
levn@0.4.1:
dependencies:
@@ -3673,9 +3988,7 @@ snapshots:
lodash.startcase@4.4.0: {}
- loupe@3.1.1:
- dependencies:
- get-func-name: 2.0.2
+ loupe@3.1.2: {}
lru-cache@10.4.3: {}
@@ -3692,9 +4005,9 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
- mdn-data@2.0.30: {}
+ map-stream@0.1.0: {}
- merge-stream@2.0.0: {}
+ mdn-data@2.0.30: {}
merge2@1.4.1: {}
@@ -3703,8 +4016,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
@@ -3735,20 +4046,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
@@ -3811,8 +4114,6 @@ snapshots:
path-key@3.1.1: {}
- path-key@4.0.0: {}
-
path-parse@1.0.7: {}
path-scurry@1.11.1:
@@ -3826,13 +4127,17 @@ snapshots:
pathval@2.0.0: {}
+ pause-stream@0.0.11:
+ dependencies:
+ through: 2.3.8
+
periscopic@3.1.0:
dependencies:
'@types/estree': 1.0.5
estree-walker: 3.0.3
is-reference: 3.0.2
- picocolors@1.1.0: {}
+ picocolors@1.1.1: {}
picomatch@2.3.1: {}
@@ -3842,30 +4147,38 @@ snapshots:
pirates@4.0.6: {}
- postcss-load-config@3.1.4(postcss@8.4.45):
+ playwright-core@1.48.2: {}
+
+ playwright@1.48.2:
+ dependencies:
+ playwright-core: 1.48.2
+ optionalDependencies:
+ fsevents: 2.3.2
+
+ postcss-load-config@3.1.4(postcss@8.4.47):
dependencies:
lilconfig: 2.1.0
yaml: 1.10.2
optionalDependencies:
- postcss: 8.4.45
+ postcss: 8.4.47
- postcss-safe-parser@6.0.0(postcss@8.4.45):
+ postcss-safe-parser@6.0.0(postcss@8.4.47):
dependencies:
- postcss: 8.4.45
+ postcss: 8.4.47
- postcss-scss@4.0.9(postcss@8.4.45):
+ postcss-scss@4.0.9(postcss@8.4.47):
dependencies:
- postcss: 8.4.45
+ postcss: 8.4.47
postcss-selector-parser@6.1.2:
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
- postcss@8.4.45:
+ postcss@8.4.47:
dependencies:
nanoid: 3.3.7
- picocolors: 1.1.0
+ picocolors: 1.1.1
source-map-js: 1.2.1
prelude-ls@1.2.1: {}
@@ -3891,6 +4204,10 @@ snapshots:
kleur: 3.0.3
sisteransi: 1.0.5
+ ps-tree@1.2.0:
+ dependencies:
+ event-stream: 3.3.4
+
pseudomap@1.0.2: {}
pump@3.0.2:
@@ -3935,13 +4252,13 @@ snapshots:
reusify@1.0.4: {}
- rollup-plugin-esbuild@6.1.1(esbuild@0.21.5)(rollup@4.21.2):
+ rollup-plugin-esbuild@6.1.1(esbuild@0.24.0)(rollup@4.21.2):
dependencies:
'@rollup/pluginutils': 5.1.2(rollup@4.21.2)
debug: 4.3.7
es-module-lexer: 1.5.4
- esbuild: 0.21.5
- get-tsconfig: 4.8.0
+ esbuild: 0.24.0
+ get-tsconfig: 4.8.1
rollup: 4.21.2
transitivePeerDependencies:
- supports-color
@@ -4001,7 +4318,7 @@ snapshots:
silver-fleece@1.2.1: {}
- sirv@2.0.4:
+ sirv@3.0.0:
dependencies:
'@polka/url': 1.0.0-next.25
mrmime: 2.0.0
@@ -4037,12 +4354,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
@@ -4073,8 +4398,6 @@ snapshots:
strip-bom@3.0.0: {}
- strip-final-newline@3.0.0: {}
-
strip-json-comments@3.1.1: {}
sucrase@3.35.0:
@@ -4093,13 +4416,13 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
- svelte-eslint-parser@0.41.0(svelte@5.0.0):
+ svelte-eslint-parser@0.43.0(svelte@5.0.0):
dependencies:
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3
espree: 9.6.1
- postcss: 8.4.45
- postcss-scss: 4.0.9(postcss@8.4.45)
+ postcss: 8.4.47
+ postcss-scss: 4.0.9(postcss@8.4.47)
optionalDependencies:
svelte: 5.0.0
@@ -4109,7 +4432,7 @@ snapshots:
'@jridgewell/sourcemap-codec': 1.5.0
'@jridgewell/trace-mapping': 0.3.25
'@types/estree': 1.0.5
- acorn: 8.12.1
+ acorn: 8.14.0
aria-query: 5.3.2
axobject-query: 4.1.0
code-red: 1.0.4
@@ -4125,8 +4448,8 @@ snapshots:
'@ampproject/remapping': 2.3.0
'@jridgewell/sourcemap-codec': 1.5.0
'@types/estree': 1.0.5
- acorn: 8.12.1
- acorn-typescript: 1.4.13(acorn@8.12.1)
+ acorn: 8.14.0
+ acorn-typescript: 1.4.13(acorn@8.14.0)
aria-query: 5.3.2
axobject-query: 4.1.0
esm-env: 1.0.0
@@ -4173,6 +4496,8 @@ snapshots:
dependencies:
any-promise: 1.3.0
+ through@2.3.8: {}
+
tiny-glob@0.2.9:
dependencies:
globalyzer: 0.1.0
@@ -4182,7 +4507,7 @@ snapshots:
tinybench@2.9.0: {}
- tinyexec@0.3.0: {}
+ tinyexec@0.3.1: {}
tinyglobby@0.2.10:
dependencies:
@@ -4209,9 +4534,9 @@ snapshots:
tr46@0.0.3: {}
- ts-api-utils@1.3.0(typescript@5.6.2):
+ ts-api-utils@1.3.0(typescript@5.6.3):
dependencies:
- typescript: 5.6.2
+ typescript: 5.6.3
ts-interface-checker@0.1.13: {}
@@ -4226,18 +4551,18 @@ snapshots:
dependencies:
prelude-ls: 1.2.1
- typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.2):
+ typescript-eslint@8.5.0(eslint@9.10.0)(typescript@5.6.3):
dependencies:
- '@typescript-eslint/eslint-plugin': 8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.2))(eslint@9.10.0)(typescript@5.6.2)
- '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.2)
- '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.2)
+ '@typescript-eslint/eslint-plugin': 8.5.0(@typescript-eslint/parser@8.5.0(eslint@9.10.0)(typescript@5.6.3))(eslint@9.10.0)(typescript@5.6.3)
+ '@typescript-eslint/parser': 8.5.0(eslint@9.10.0)(typescript@5.6.3)
+ '@typescript-eslint/utils': 8.5.0(eslint@9.10.0)(typescript@5.6.3)
optionalDependencies:
- typescript: 5.6.2
+ typescript: 5.6.3
transitivePeerDependencies:
- eslint
- supports-color
- typescript@5.6.2: {}
+ typescript@5.6.3: {}
undici-types@5.26.5: {}
@@ -4245,21 +4570,21 @@ snapshots:
universalify@0.1.2: {}
- unplugin-isolated-decl@0.6.5(rollup@4.21.2)(typescript@5.6.2)(webpack-sources@3.2.3):
+ unplugin-isolated-decl@0.6.5(rollup@4.21.2)(typescript@5.6.3)(webpack-sources@3.2.3):
dependencies:
'@rollup/pluginutils': 5.1.2(rollup@4.21.2)
magic-string: 0.30.12
oxc-parser: 0.30.3
unplugin: 1.14.1(webpack-sources@3.2.3)
optionalDependencies:
- typescript: 5.6.2
+ typescript: 5.6.3
transitivePeerDependencies:
- rollup
- webpack-sources
unplugin@1.14.1(webpack-sources@3.2.3):
dependencies:
- acorn: 8.12.1
+ acorn: 8.14.0
webpack-virtual-modules: 0.6.2
optionalDependencies:
webpack-sources: 3.2.3
@@ -4270,35 +4595,16 @@ snapshots:
util-deprecate@1.0.2: {}
- valibot@0.41.0(typescript@5.6.2):
+ valibot@0.41.0(typescript@5.6.3):
optionalDependencies:
- typescript: 5.6.2
-
- vite-node@2.0.5(@types/node@18.19.64):
- dependencies:
- cac: 6.7.14
- debug: 4.3.7
- pathe: 1.1.2
- tinyrainbow: 1.2.0
- vite: 5.4.3(@types/node@18.19.64)
- transitivePeerDependencies:
- - '@types/node'
- - less
- - lightningcss
- - sass
- - sass-embedded
- - stylus
- - sugarss
- - supports-color
- - terser
+ typescript: 5.6.3
- vite-node@2.0.5(@types/node@22.5.4):
+ vite-node@2.1.4(@types/node@22.9.0):
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)
+ vite: 5.4.10(@types/node@22.9.0)
transitivePeerDependencies:
- '@types/node'
- less
@@ -4310,85 +4616,44 @@ snapshots:
- supports-color
- terser
- vite@5.4.3(@types/node@18.19.64):
+ vite@5.4.10(@types/node@22.9.0):
dependencies:
esbuild: 0.21.5
- postcss: 8.4.45
+ postcss: 8.4.47
rollup: 4.21.2
optionalDependencies:
- '@types/node': 18.19.64
+ '@types/node': 22.9.0
fsevents: 2.3.3
- vite@5.4.3(@types/node@22.5.4):
+ vitest@2.1.4(@types/node@22.9.0)(@vitest/ui@2.1.4):
dependencies:
- esbuild: 0.21.5
- postcss: 8.4.45
- rollup: 4.21.2
- optionalDependencies:
- '@types/node': 22.5.4
- fsevents: 2.3.3
-
- vitest@2.0.5(@types/node@18.19.64)(@vitest/ui@2.0.5):
- 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
- 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
- tinypool: 1.0.1
- tinyrainbow: 1.2.0
- vite: 5.4.3(@types/node@18.19.64)
- vite-node: 2.0.5(@types/node@18.19.64)
- why-is-node-running: 2.3.0
- optionalDependencies:
- '@types/node': 18.19.64
- '@vitest/ui': 2.0.5(vitest@2.0.5)
- transitivePeerDependencies:
- - less
- - lightningcss
- - sass
- - sass-embedded
- - stylus
- - sugarss
- - supports-color
- - terser
-
- vitest@2.0.5(@types/node@22.5.4)(@vitest/ui@2.0.5):
- 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
- chai: 5.1.1
+ '@vitest/expect': 2.1.4
+ '@vitest/mocker': 2.1.4(vite@5.4.10(@types/node@22.9.0))
+ '@vitest/pretty-format': 2.1.4
+ '@vitest/runner': 2.1.4
+ '@vitest/snapshot': 2.1.4
+ '@vitest/spy': 2.1.4
+ '@vitest/utils': 2.1.4
+ chai: 5.1.2
debug: 4.3.7
- execa: 8.0.1
+ expect-type: 1.1.0
magic-string: 0.30.12
pathe: 1.1.2
std-env: 3.7.0
tinybench: 2.9.0
+ tinyexec: 0.3.1
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: 5.4.10(@types/node@22.9.0)
+ vite-node: 2.1.4(@types/node@22.9.0)
why-is-node-running: 2.3.0
optionalDependencies:
- '@types/node': 22.5.4
- '@vitest/ui': 2.0.5(vitest@2.0.5)
+ '@types/node': 22.9.0
+ '@vitest/ui': 2.1.4(vitest@2.1.4)
transitivePeerDependencies:
- less
- lightningcss
+ - msw
- sass
- sass-embedded
- stylus
diff --git a/prettier.config.js b/prettier.config.js
index 1a3d9c70..e44ee21e 100644
--- a/prettier.config.js
+++ b/prettier.config.js
@@ -44,11 +44,13 @@ const packageSortOrder = [
'keywords'
];
+/** @type {import("prettier").Config} */
export default {
useTabs: true,
singleQuote: true,
trailingComma: 'none',
printWidth: 100,
+ endOfLine: 'lf',
plugins: ['prettier-plugin-packagejson', 'prettier-plugin-svelte'],
overrides: [
{
@@ -65,10 +67,7 @@ export default {
}
},
{
- files: [
- '**/CHANGELOG.md',
- 'packages/migrate/migrations/routes/*/samples.md'
- ],
+ files: ['**/CHANGELOG.md', 'packages/migrate/migrations/routes/*/samples.md'],
options: {
requirePragma: true
}
@@ -80,4 +79,4 @@ export default {
}
}
]
-}
+};
diff --git a/rollup.config.js b/rollup.config.js
index f66a0e6c..6ec4e049 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -35,7 +35,11 @@ function getConfig(project) {
parsers: `${projectRoot}/tooling/parsers.ts`
};
} else if (project === 'cli') {
- inputs = [`${projectRoot}/index.ts`, `${projectRoot}/bin.ts`];
+ inputs = [
+ `${projectRoot}/lib/index.ts`,
+ `${projectRoot}/lib/testing.ts`,
+ `${projectRoot}/bin.ts`
+ ];
} else {
inputs = [`${projectRoot}/index.ts`];
}
@@ -68,6 +72,7 @@ function getConfig(project) {
console.log('building templates');
const start = performance.now();
await buildTemplates(path.resolve('packages', 'cli', 'dist'));
+ await buildTemplates(path.resolve('packages', 'create', 'dist'));
const end = performance.now();
console.log(`finished building templates: ${Math.round(end - start)}ms`);
}
@@ -107,7 +112,8 @@ function getConfig(project) {
external,
plugins: [
preserveShebangs(),
- 'exports' in pkg && dts({ include: project === 'cli' ? [inputs[0]] : undefined }),
+ 'exports' in pkg &&
+ dts({ include: project === 'cli' ? [`${projectRoot}/lib/*`] : undefined }),
esbuild(),
nodeResolve({ preferBuiltins: true, rootDir: projectRoot }),
commonjs(),
@@ -115,7 +121,7 @@ function getConfig(project) {
dynamicImportVars({
// since we're relying on the usage of standard dynamic imports for community adders, we need to
// prevent this plugin from transforming these cases
- exclude: ['packages/cli/utils/fetch-packages.ts']
+ exclude: ['packages/cli/commands/add/fetch-packages.ts']
}),
buildCliTemplatesPlugin,
communityAdderIdsPlugin
diff --git a/vitest.workspace.ts b/vitest.workspace.ts
new file mode 100644
index 00000000..2a7e8f5f
--- /dev/null
+++ b/vitest.workspace.ts
@@ -0,0 +1,3 @@
+import { defineWorkspace } from 'vitest/config';
+
+export default defineWorkspace(['packages/*', 'community-adder-template']);