diff --git a/.changeset/slimy-wombats-peel.md b/.changeset/slimy-wombats-peel.md new file mode 100644 index 00000000..316548be --- /dev/null +++ b/.changeset/slimy-wombats-peel.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix(eslint): generated import order are now sorted alphabetically diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c4714b86 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,122 @@ +# SV Contributing Guide + +## Workflow + +We follow the standard fork-based workflow: + +1. **Fork** this repository to your GitHub account. +2. **Clone** your fork locally. +3. **Create a new branch** for your change: + `git checkout -b your-feature-name` +4. **Commit and push** your changes to your branch. +5. **Open a pull request** from your branch to the `main` branch of this repository. + +Please keep your pull requests focused to feature or issue. Focused smaller changes are easier to review and faster to merge. + +## Preparing +This is a monorepo, meaning the repo holds multiple packages. It requires the use of [pnpm](https://pnpm.io/). You can [install pnpm](https://pnpm.io/installation) with: + +```bash +npm i -g pnpm +``` + +For running certain packages and tests locally you will need to install [docker](https://docs.docker.com/get-started/get-docker). +Linux users, you will have to ensure 'sudo' is not required. See [docker post install](https://docs.docker.com/engine/install/linux-postinstall/) + +`pnpm` commands run in the project's root directory will run on all sub-projects. You can checkout the code and install the dependencies with: + +```bash +cd cli +pnpm install +``` + +## Build and run +To build the project and all packages. Run the 'build' script: + +```bash +# from root of project +pnpm build +``` +This outputs into /packages/PACKAGE/dist/. + +Run the 'cli' package: +```bash +pnpm sv +``` + +Run build with watch mode: +```bash +pnpm dev +``` + +## Testing + +For each add-on we have integration tests setup. These install the deps, build the app, run the dev server and then run a few small snippets against the add-on to see if the changes introduced by the add-on are working as expected. + +Run all tests: +```bash +# from root of project +pnpm test +``` + +Run tests with vitest ui: +```bash +# from root of project +pnpm test:ui +``` + +Run package specific tests by specifying a project flag to the package and running the test command. Eg: +```bash +pnpm test --project core # addons / create / migrate / etc. +``` + +To run a individual test. `cd` into the package. Run the local `test` script to that package, with a path arg to the individual peice you want tested. Eg: +```bash +pnpm test [path-to-test] +``` + +To debug a failing test. A good starting point is to `cd` into the failing tests dir. Proceed to `build` it. Then `preview` it. From here you will have increased information to help in the debug process. Eg: +```bash +# Each test is a standalone app +cd .test-output/addons/[addon-test]/[test-id] +pnpm build +pnpm preview +``` + +## Style Guide + +### Coding style + +There are a few guidelines we follow: + +- Ensure `pnpm lint` and `pnpm check` pass. You can run `pnpm format` to format the code +- linting +```bash +# from root of project +pnpm lint +``` +- formatting +```bash +# from root of project +pnpm format +``` +- type checking +```bash +# from root of project +pnpm check +``` + +## svelte-migrate +To run svelte-migrate locally: +```bash +# from root of project +node ./packages/migrate/bin.js +``` + +## Generating changelogs +Only publish a change set if it is in 'sv' or 'svelte-migrate' as all other packages are bundled. +For changes to be reflected in package changelogs: +```bash +# from root of project +pnpm changeset:publish +``` diff --git a/community-addon-template/package.json b/community-addon-template/package.json index 90d44a8e..c9ba0aa1 100644 --- a/community-addon-template/package.json +++ b/community-addon-template/package.json @@ -18,9 +18,9 @@ "@sveltejs/cli-core": "workspace:*" }, "devDependencies": { - "@playwright/test": "^1.49.1", + "@playwright/test": "^1.51.1", "sv": "workspace:*", - "vitest": "^3.0.5" + "vitest": "^3.0.9" }, "keywords": [ "svelte-add-on", diff --git a/community-addon-template/tests/setup/global.ts b/community-addon-template/tests/setup/global.ts index 872cd690..31b2ed10 100644 --- a/community-addon-template/tests/setup/global.ts +++ b/community-addon-template/tests/setup/global.ts @@ -1,11 +1,11 @@ import { fileURLToPath } from 'node:url'; import { setup, type ProjectVariant } from 'sv/testing'; -import type { GlobalSetupContext } from 'vitest/node'; +import type { TestProject } 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) { +export default async function ({ provide }: TestProject) { // global setup (e.g. spin up docker containers) // downloads different project configurations (sveltekit, js/ts, vite-only, etc) diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index 9b2dc0a5..3b7c0413 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -4,7 +4,7 @@ import { execSync } from 'node:child_process'; import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; import { - addPnpmBuildDependendencies, + addPnpmBuildDependencies, createProject, startPreview, type CreateProject, @@ -78,7 +78,7 @@ export function setupTest(addons: Addons) { options, packageManager: 'pnpm' }); - addPnpmBuildDependendencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); + addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); return cwd; }; diff --git a/documentation/docs/20-commands/10-sv-create.md b/documentation/docs/20-commands/10-sv-create.md index 7425d3f3..ae5d29be 100644 --- a/documentation/docs/20-commands/10-sv-create.md +++ b/documentation/docs/20-commands/10-sv-create.md @@ -35,9 +35,19 @@ Prevent typechecking from being added. Not recommended! Run the command without the interactive add-ons prompt +### `--install ` + +Installs dependencies with a specified package manager: + +- `npm` +- `pnpm` +- `yarn` +- `bun` +- `deno` + ### `--no-install` -Skip dependency installation +Prevents installing dependencies. -- `--no-install` — skip dependency installation +- `--install` — installs dependencies with a specified package manager +- `--no-install` — prevents installing dependencies ## Official add-ons - - -- `drizzle` -- `eslint` -- `sveltekit-adapter` -- `lucia` -- `mdsvex` -- `paraglide` -- `playwright` -- `prettier` -- `storybook` -- `tailwindcss` -- `vitest` + + +- [`drizzle`](drizzle) +- [`eslint`](eslint) +- [`lucia`](lucia) +- [`mdsvex`](mdsvex) +- [`paraglide`](paraglide) +- [`playwright`](playwright) +- [`prettier`](prettier) +- [`storybook`](storybook) +- [`sveltekit-adapter`](sveltekit-adapter) +- [`tailwindcss`](tailwind) +- [`vitest`](vitest) diff --git a/documentation/docs/30-add-ons/05-drizzle.md b/documentation/docs/30-add-ons/05-drizzle.md new file mode 100644 index 00000000..97766fde --- /dev/null +++ b/documentation/docs/30-add-ons/05-drizzle.md @@ -0,0 +1,54 @@ +--- +title: drizzle +--- + +[Drizzle ORM](https://orm.drizzle.team/) is a TypeScript ORM offering both relational and SQL-like query APIs, and which is serverless-ready by design. + +## Usage + +```bash +npx sv add drizzle +``` + +## What you get + +- a setup that keeps your database access in SvelteKit's server files +- an `.env` file to store your credentials +- compatibility with the Lucia auth add-on +- an optional Docker configuration to help with running a local database + +## Options + +### database + +Which database variant to use: + +- `postgresql` — the most popular open source database +- `mysql` — another popular open source database +- `sqlite` — file-based database not requiring a database server + +```bash +npx sv add drizzle=database:postgresql +``` + +### client + +The SQL client to use, depends on `database`: + +- For `postgresql`: `postgres.js`, `neon`, +- For `mysql`: `mysql2`, `planetscale` +- For `sqlite`: `better-sqlite3`, `libsql`, `turso` + +```bash +npx sv add drizzle=database:postgresql+client:postgres.js +``` + +Drizzle is compatible with well over a dozen database drivers. We just offer a few of the most common ones here for simplicity, but if you'd like to use another one you can choose one as a placeholder and swap it out for another after setup by choosing from [Drizzle's full list of compatible drivers](https://orm.drizzle.team/docs/connect-overview#next-steps). + +### docker + +Whether to add Docker Compose configuration. Only available for [`database`](#Options-database) `postgresql` or `mysql` + +```bash +npx sv add drizzle=database:postgresql+client:postgres.js+docker:yes +``` diff --git a/documentation/docs/30-add-ons/10-eslint.md b/documentation/docs/30-add-ons/10-eslint.md new file mode 100644 index 00000000..318bb504 --- /dev/null +++ b/documentation/docs/30-add-ons/10-eslint.md @@ -0,0 +1,18 @@ +--- +title: eslint +--- + +[ESLint](https://eslint.org/) finds and fixes problems in your code. + +## Usage + +```bash +npx sv add eslint +``` + +## What you get + +- the relevant packages installed including `eslint-plugin-svelte` +- an `eslint.config.js` file +- updated `.vscode/settings.json` +- configured to work with TypeScript and `prettier` if you're using those packages diff --git a/documentation/docs/30-add-ons/15-lucia.md b/documentation/docs/30-add-ons/15-lucia.md new file mode 100644 index 00000000..eb7b68e1 --- /dev/null +++ b/documentation/docs/30-add-ons/15-lucia.md @@ -0,0 +1,26 @@ +--- +title: lucia +--- + +An auth setup following [the Lucia auth guide](https://lucia-auth.com/). + +## Usage + +```bash +npx sv add lucia +``` + +## What you get + +- an auth setup for SvelteKit and Drizzle following the best practices from the Lucia auth guide +- optional demo registration and login pages + +## Options + +### demo + +Whether to include demo registration and login pages. + +```bash +npx sv add lucia=demo:yes +``` diff --git a/documentation/docs/30-add-ons/20-mdsvex.md b/documentation/docs/30-add-ons/20-mdsvex.md new file mode 100644 index 00000000..00b95c45 --- /dev/null +++ b/documentation/docs/30-add-ons/20-mdsvex.md @@ -0,0 +1,15 @@ +--- +title: mdsvex +--- + +[mdsvex](https://mdsvex.pngwn.io) is a markdown preprocessor for Svelte components - basically MDX for Svelte. It allows you to use Svelte components in your markdown, or markdown in your Svelte components. + +## Usage + +```bash +npx sv add mdsvex +``` + +## What you get + +- mdsvex installed and configured in your `svelte.config.js` diff --git a/documentation/docs/30-add-ons/25-paraglide.md b/documentation/docs/30-add-ons/25-paraglide.md new file mode 100644 index 00000000..e4658e0f --- /dev/null +++ b/documentation/docs/30-add-ons/25-paraglide.md @@ -0,0 +1,38 @@ +--- +title: paraglide +--- + +[Paraglide from Inlang](https://inlang.com/m/gerre34r/library-inlang-paraglideJs) is a compiler-based i18n library that emits tree-shakable message functions with small bundle sizes, no async waterfalls, full type-safety, and more. + +## Usage + +```bash +npx sv add paraglide +``` + +## What you get + +- Inlang project settings +- paraglide Vite plugin +- SvelteKit `reroute` and `handle` hooks +- `text-direction` and `lang` attributes in `app.html` +- updated `.gitignore` +- an optional demo page showing how to use paraglide + +## Options + +### languageTags + +The languages you'd like to support specified as IETF BCP 47 language tags. + +```bash +npx sv add paraglide="languageTags:en,es" +``` + +### demo + +Whether to generate an optional demo page showing how to use paraglide. + +```bash +npx sv add paraglide="demo:yes" +``` diff --git a/documentation/docs/30-add-ons/30-playwright.md b/documentation/docs/30-add-ons/30-playwright.md new file mode 100644 index 00000000..0c16d86f --- /dev/null +++ b/documentation/docs/30-add-ons/30-playwright.md @@ -0,0 +1,18 @@ +--- +title: playwright +--- + +[Playwright](https://playwright.dev) browser testing. + +## Usage + +```bash +npx sv add playwright +``` + +## What you get + +- scripts added in your `package.json` +- a Playwright config file +- an updated `.gitignore` +- a demo test diff --git a/documentation/docs/30-add-ons/35-prettier.md b/documentation/docs/30-add-ons/35-prettier.md new file mode 100644 index 00000000..68014ae4 --- /dev/null +++ b/documentation/docs/30-add-ons/35-prettier.md @@ -0,0 +1,17 @@ +--- +title: prettier +--- + +[Prettier](https://prettier.io) is an opinionated code formatter. + +## Usage + +```bash +npx sv add prettier +``` + +## What you get + +- scripts in your `package.json` +- `.prettierignore` and `.prettierrc` files +- updates to your eslint config if you're using that package diff --git a/documentation/docs/30-add-ons/40-storybook.md b/documentation/docs/30-add-ons/40-storybook.md new file mode 100644 index 00000000..9ba57adb --- /dev/null +++ b/documentation/docs/30-add-ons/40-storybook.md @@ -0,0 +1,16 @@ +--- +title: storybook +--- + +[Storybook](https://storybook.js.org/) is a frontend component workshop. + +## Usage + +```bash +npx sv add storybook +``` + +## What you get + +- `npx storybook init` run for you from the same convenient `sv` CLI used for all other add-ons +- [Storybook for SvelteKit](https://storybook.js.org/docs/get-started/frameworks/sveltekit) or [Storybook for Svelte & Vite](https://storybook.js.org/docs/get-started/frameworks/svelte-vite) with default config provided, easy mocking of many SvelteKit modules, automatic link handling, and more. diff --git a/documentation/docs/30-add-ons/45-sveltekit-adapter.md b/documentation/docs/30-add-ons/45-sveltekit-adapter.md new file mode 100644 index 00000000..1bc77cc6 --- /dev/null +++ b/documentation/docs/30-add-ons/45-sveltekit-adapter.md @@ -0,0 +1,32 @@ +--- +title: sveltekit-adapter +--- + +[SvelteKit adapters](/docs/kit/adapters) allow you to deploy your site to numerous platforms. This add-on allows you to configure officially provided SvelteKit adapters, but a number of [community-provided adapters](https://www.sveltesociety.dev/packages?category=sveltekit-adapters) are also available. + +## Usage + +```bash +npx sv add sveltekit-adapter +``` + +## What you get + +- the chosen SvelteKit adapter installed and configured in your `svelte.config.js` + +## Options + +### adapter + +Which SvelteKit adapter to use: + +- `auto` — [`@sveltejs/adapter-auto`](/docs/kit/adapter-auto) automatically chooses the proper adapter to use, but is less configurable +- `node` — [`@sveltejs/adapter-node`](/docs/kit/adapter-node) generates a standalone Node server +- `static` — [`@sveltejs/adapter-static`](/docs/kit/adapter-static) allows you to use SvelteKit as a static site generator (SSG) +- `vercel` — [`@sveltejs/adapter-vercel`](/docs/kit/adapter-vercel) allows you to deploy to Vercel +- `cloudflare` — [`@sveltejs/adapter-cloudflare`](/docs/kit/adapter-cloudflare) allows you to deploy to Cloudflare +- `netlify` — [`@sveltejs/adapter-netlify`](/docs/kit/adapter-netlify) allows you to deploy to Netlify + +```bash +npx sv add sveltekit-adapter=adapter:node +``` diff --git a/documentation/docs/30-add-ons/50-tailwind.md b/documentation/docs/30-add-ons/50-tailwind.md new file mode 100644 index 00000000..a0926b51 --- /dev/null +++ b/documentation/docs/30-add-ons/50-tailwind.md @@ -0,0 +1,31 @@ +--- +title: tailwindcss +--- + +[Tailwind CSS](https://tailwindcss.com/) allows you to rapidly build modern websites without ever leaving your HTML. + +## Usage + +```bash +npx sv add tailwindcss +``` + +## What you get + +- Tailwind setup following the [Tailwind for SvelteKit guide](https://tailwindcss.com/docs/installation/framework-guides/sveltekit) +- Tailwind Vite plugin +- updated `app.css` and `+layout.svelte` (for SvelteKit) or `App.svelte` (for non-SvelteKit Vite apps) +- integration with `prettier` if using that package + +## Options + +### plugins + +Which plugin to use: + +- `typography` — [`@tailwindcss/typography`](https://github.com/tailwindlabs/tailwindcss-typography) +- `forms` — [`@tailwindcss/forms`](https://github.com/tailwindlabs/tailwindcss-forms) + +```bash +npx sv add tailwindcss="plugins:typography" +``` diff --git a/documentation/docs/30-add-ons/55-vitest.md b/documentation/docs/30-add-ons/55-vitest.md new file mode 100644 index 00000000..e2ee77c6 --- /dev/null +++ b/documentation/docs/30-add-ons/55-vitest.md @@ -0,0 +1,17 @@ +--- +title: vitest +--- + +[Vitest](https://vitest.dev/) is a Vite-native testing framework. + +## Usage + +```bash +npx sv add vitest +``` + +## What you get + +- the relevant packages installed and scripts added to your `package.json` +- client/server-aware testing setup for Svelte in your Vite config file +- demo tests diff --git a/documentation/docs/30-add-ons/index.md b/documentation/docs/30-add-ons/index.md new file mode 100644 index 00000000..61874f22 --- /dev/null +++ b/documentation/docs/30-add-ons/index.md @@ -0,0 +1,3 @@ +--- +title: Add-ons +--- diff --git a/package.json b/package.json index 433fd18c..059e4299 100644 --- a/package.json +++ b/package.json @@ -19,25 +19,26 @@ "update-addon-deps": "node ./scripts/update-addon-dependencies.js" }, "devDependencies": { - "@changesets/cli": "^2.27.10", - "@playwright/test": "^1.49.1", + "@changesets/cli": "^2.28.1", + "@playwright/test": "^1.51.1", "@sveltejs/create": "workspace:*", - "@sveltejs/eslint-config": "^8.1.0", + "@sveltejs/eslint-config": "^8.2.0", "@svitejs/changesets-changelog-github-compact": "^1.2.0", - "@types/node": "^22.10.2", - "@vitest/ui": "^3.0.5", - "eslint": "^9.17.0", - "magic-string": "^0.30.15", - "prettier": "^3.4.2", - "prettier-plugin-packagejson": "^2.5.6", - "prettier-plugin-svelte": "^3.3.2", + "@types/node": "^22.14.0", + "@vitest/ui": "^3.0.9", + "eslint": "^9.24.0", + "eslint-plugin-svelte": "^3.5.1", + "magic-string": "^0.30.17", + "prettier": "^3.5.3", + "prettier-plugin-packagejson": "^2.5.10", + "prettier-plugin-svelte": "^3.3.3", "rolldown": "1.0.0-beta.1", "sv": "workspace:*", - "svelte": "^5.12.0", - "typescript": "^5.6.2", - "typescript-eslint": "^8.18.0", + "svelte": "^5.25.7", + "typescript": "^5.8.3", + "typescript-eslint": "^8.29.0", "unplugin-isolated-decl": "^0.8.3", - "vitest": "^3.0.5" + "vitest": "^3.0.9" }, "packageManager": "pnpm@10.4.1", "pnpm": { @@ -45,4 +46,4 @@ "esbuild" ] } -} +} \ No newline at end of file diff --git a/packages/addons/_tests/_setup/global.ts b/packages/addons/_tests/_setup/global.ts index 5b99b41d..c078a3c6 100644 --- a/packages/addons/_tests/_setup/global.ts +++ b/packages/addons/_tests/_setup/global.ts @@ -1,11 +1,11 @@ import { fileURLToPath } from 'node:url'; import { setup, type ProjectVariant } from 'sv/testing'; -import type { GlobalSetupContext } from 'vitest/node'; +import type { TestProject } from 'vitest/node'; const TEST_DIR = fileURLToPath(new URL('../../../../.test-output/addons/', import.meta.url)); const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; -export default async function ({ provide }: GlobalSetupContext) { +export default async function ({ provide }: TestProject) { // downloads different project configurations (sveltekit, js/ts, vite-only, etc) const { templatesDir } = await setup({ cwd: TEST_DIR, variants }); diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 5c6e5a1b..65615a8c 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -6,7 +6,7 @@ import { installAddon, type AddonMap, type OptionMap } from 'sv'; import { createProject, startPreview, - addPnpmBuildDependendencies, + addPnpmBuildDependencies, type CreateProject, type ProjectVariant } from 'sv/testing'; @@ -75,7 +75,7 @@ export function setupTest(addons: Addons) { options, packageManager: 'pnpm' }); - addPnpmBuildDependendencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); + addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); return cwd; }; diff --git a/packages/addons/_tests/drizzle/test.ts b/packages/addons/_tests/drizzle/test.ts index 2a6d7230..c1e49076 100644 --- a/packages/addons/_tests/drizzle/test.ts +++ b/packages/addons/_tests/drizzle/test.ts @@ -43,7 +43,7 @@ test.concurrent.for(testCases)( const ts = variant === 'kit-ts'; const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`); - const content = fs.readFileSync(drizzleConfig, 'utf8').replace('strict: true,', ''); + const content = fs.readFileSync(drizzleConfig, 'utf8').replace(/strict: true[,\s]/, ''); fs.writeFileSync(drizzleConfig, content, 'utf8'); const routes = path.resolve(cwd, 'src', 'routes'); diff --git a/packages/addons/_tests/paraglide/test.ts b/packages/addons/_tests/paraglide/test.ts index e2d2ac01..67c68eff 100644 --- a/packages/addons/_tests/paraglide/test.ts +++ b/packages/addons/_tests/paraglide/test.ts @@ -6,7 +6,7 @@ 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 cwd = await ctx.run(variant, { paraglide: { demo: true, languageTags: 'en' } }); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/_tests/storybook/test.ts b/packages/addons/_tests/storybook/test.ts index 5a7e76b8..8e796638 100644 --- a/packages/addons/_tests/storybook/test.ts +++ b/packages/addons/_tests/storybook/test.ts @@ -2,8 +2,10 @@ import process from 'node:process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import storybook from '../../storybook/index.ts'; +import eslint from '../../eslint/index.ts'; -const { test, variants, prepareServer } = setupTest({ storybook }); +// we're including the `eslint` add-on to prevent `storybook` from modifying this repo's `eslint.config.js` +const { test, variants, prepareServer } = setupTest({ storybook, eslint }); let port = 6006; @@ -11,7 +13,7 @@ test.for(variants)( 'storybook loaded - %s', { concurrent: !process.env.CI }, async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { storybook: {} }); + const cwd = await ctx.run(variant, { storybook: {}, eslint: {} }); const { close } = await prepareServer({ cwd, diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index f6a0166d..41646ef8 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -8,9 +8,9 @@ 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 }, () => { - execSync('npm run test', { cwd, stdio: 'pipe' }); - }); + const { close } = await prepareServer({ cwd, page }); + + execSync('pnpm test', { cwd, stdio: 'pipe' }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/addons/common.ts b/packages/addons/common.ts index 5795e133..b03d9d5e 100644 --- a/packages/addons/common.ts +++ b/packages/addons/common.ts @@ -1,5 +1,6 @@ import { imports, exports, common } from '@sveltejs/cli-core/js'; import { parseScript, parseSvelte } from '@sveltejs/cli-core/parsers'; +import process from 'node:process'; export function addEslintConfigPrettier(content: string): string { const { ast, generateCode } = parseScript(content); @@ -75,3 +76,28 @@ export function addToDemoPage(content: string, path: string): string { const src = template.source + `${newLine}${path}`; return generateCode({ template: src }); } + +/** + * Returns the corresponding `@types/node` version for the version of Node.js running in the current process. + * + * If the installed version of Node.js is from a `Current` release, then the major is decremented to + * the nearest `LTS` release version. + */ +export function getNodeTypesVersion(): string { + const nodeVersion = process.versions.node; + const isDenoOrBun = Boolean(process.versions.deno ?? process.versions.bun); + const [major] = nodeVersion.split('.'); + + const majorNum = Number(major); + const isEvenMajor = majorNum % 2 === 0; + const isLTS = !!process.release.lts || (isDenoOrBun && isEvenMajor); + if (isLTS) { + return `^${major}`; + } + + // It's possible for an even major number to _temporarily_ not + // be an `LTS` release (meaning `process.release.lts` is `undefined`) during it's `Current` stage. + // In those cases, we'll decrement the major by 2. + const previousLTSMajor = isEvenMajor ? majorNum - 2 : majorNum - 1; + return `^${previousLTSMajor}`; +} diff --git a/packages/addons/drizzle/index.ts b/packages/addons/drizzle/index.ts index 01fd7234..dc3dfeae 100644 --- a/packages/addons/drizzle/index.ts +++ b/packages/addons/drizzle/index.ts @@ -1,6 +1,9 @@ +import fs from 'node:fs'; +import path from 'node:path'; import { common, exports, functions, imports, object, variables } from '@sveltejs/cli-core/js'; import { defineAddon, defineAddonOptions, dedent, type OptionValues } from '@sveltejs/cli-core'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; +import { getNodeTypesVersion } from '../common.ts'; const PORTS = { mysql: '3306', @@ -68,14 +71,31 @@ export default defineAddon({ shortDescription: 'database orm', homepage: 'https://orm.drizzle.team', options, - setup: ({ kit, unsupported }) => { - if (!kit) unsupported('Requires SvelteKit'); + setup: ({ kit, unsupported, cwd, typescript }) => { + const ext = typescript ? 'ts' : 'js'; + if (!kit) { + return unsupported('Requires SvelteKit'); + } + + const baseDBPath = path.resolve(kit.libDirectory, 'server', 'db'); + const paths = { + 'drizzle config': path.relative(cwd, path.resolve(cwd, `drizzle.config.${ext}`)), + 'database schema': path.relative(cwd, path.resolve(baseDBPath, `schema.${ext}`)), + database: path.relative(cwd, path.resolve(baseDBPath, `index.${ext}`)) + }; + + for (const [fileType, filePath] of Object.entries(paths)) { + if (fs.existsSync(filePath)) { + unsupported(`Preexisting ${fileType} file at '${filePath}'`); + } + } }, run: ({ sv, typescript, options, kit }) => { const ext = typescript ? 'ts' : 'js'; sv.dependency('drizzle-orm', '^0.40.0'); sv.devDependency('drizzle-kit', '^0.30.2'); + sv.devDependency('@types/node', getNodeTypesVersion()); // MySQL if (options.mysql === 'mysql2') sv.dependency('mysql2', '^3.12.0'); @@ -176,41 +196,27 @@ export default defineAddon({ imports.addNamed(ast, 'drizzle-kit', { defineConfig: 'defineConfig' }); - const envCheckStatement = common.statementFromString( - "if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');" + common.addStatement( + ast, + common.statementFromString( + "if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');" + ) ); - common.addStatement(ast, envCheckStatement); - - const fallback = common.expressionFromString('defineConfig({})'); - const { value: exportDefault } = exports.defaultExport(ast, fallback); - if (exportDefault.type !== 'CallExpression') return content; - - const objExpression = exportDefault.arguments?.[0]; - if (!objExpression || objExpression.type !== 'ObjectExpression') return content; - - const authToken = - options.sqlite === 'turso' - ? common.expressionFromString('process.env.DATABASE_AUTH_TOKEN') - : undefined; - - object.properties(objExpression, { - schema: common.createLiteral(`./src/lib/server/db/schema.${typescript ? 'ts' : 'js'}`), - dbCredentials: object.create({ - url: common.expressionFromString('process.env.DATABASE_URL'), - authToken - }), - verbose: { type: 'Literal', value: true }, - strict: { type: 'Literal', value: true } - }); - const dialect = options.sqlite === 'turso' ? 'turso' : options.database; - object.overrideProperties(objExpression, { - dialect: common.createLiteral(dialect) - }); - - // The `driver` property is only required for _some_ sqlite DBs. - // We'll need to remove it if it's anything but sqlite - if (options.database !== 'sqlite') object.removeProperty(objExpression, 'driver'); + exports.defaultExport( + ast, + common.expressionFromString(` + defineConfig({ + schema: "./src/lib/server/db/schema.${typescript ? 'ts' : 'js'}", + dialect: "${options.sqlite === 'turso' ? 'turso' : options.database}", + dbCredentials: { + ${options.sqlite === 'turso' ? 'authToken: process.env.DATABASE_AUTH_TOKEN,' : ''} + url: process.env.DATABASE_URL + }, + verbose: true, + strict: true + })`) + ); return generateCode(); }); @@ -222,7 +228,6 @@ export default defineAddon({ if (options.database === 'sqlite') { imports.addNamed(ast, 'drizzle-orm/sqlite-core', { sqliteTable: 'sqliteTable', - text: 'text', integer: 'integer' }); @@ -235,7 +240,6 @@ export default defineAddon({ imports.addNamed(ast, 'drizzle-orm/mysql-core', { mysqlTable: 'mysqlTable', serial: 'serial', - text: 'text', int: 'int' }); @@ -248,7 +252,6 @@ export default defineAddon({ imports.addNamed(ast, 'drizzle-orm/pg-core', { pgTable: 'pgTable', serial: 'serial', - text: 'text', integer: 'integer' }); @@ -309,9 +312,7 @@ export default defineAddon({ imports.addDefault(ast, 'mysql2/promise', 'mysql'); imports.addNamed(ast, 'drizzle-orm/mysql2', { drizzle: 'drizzle' }); - clientExpression = common.expressionFromString( - 'await mysql.createConnection(env.DATABASE_URL)' - ); + clientExpression = common.expressionFromString('mysql.createPool(env.DATABASE_URL)'); } // PostgreSQL if (options.postgresql === 'neon') { diff --git a/packages/addons/eslint/index.ts b/packages/addons/eslint/index.ts index 786f8810..82492ae3 100644 --- a/packages/addons/eslint/index.ts +++ b/packages/addons/eslint/index.ts @@ -1,4 +1,3 @@ -import { addEslintConfigPrettier } from '../common.ts'; import { defineAddon, log } from '@sveltejs/cli-core'; import { array, @@ -10,6 +9,7 @@ import { type AstTypes } from '@sveltejs/cli-core/js'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; +import { addEslintConfigPrettier } from '../common.ts'; export default defineAddon({ id: 'eslint', @@ -115,7 +115,6 @@ export default defineAddon({ if (typescript) { const svelteTSParserConfig = object.create({ files: common.expressionFromString("['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js']"), - ignores: common.expressionFromString("['eslint.config.js', 'svelte.config.js']"), languageOptions: object.create({ parserOptions: object.create({ projectService: common.expressionFromString('true'), @@ -165,8 +164,8 @@ export default defineAddon({ imports.addNamed(ast, 'node:url', { fileURLToPath: 'fileURLToPath' }); imports.addDefault(ast, 'globals', 'globals'); imports.addDefault(ast, 'eslint-plugin-svelte', 'svelte'); - imports.addNamed(ast, '@eslint/compat', { includeIgnoreFile: 'includeIgnoreFile' }); imports.addDefault(ast, '@eslint/js', 'js'); + imports.addNamed(ast, '@eslint/compat', { includeIgnoreFile: 'includeIgnoreFile' }); return generateCode(); }); diff --git a/packages/addons/lucia/index.ts b/packages/addons/lucia/index.ts index 355cdea2..01677a8b 100644 --- a/packages/addons/lucia/index.ts +++ b/packages/addons/lucia/index.ts @@ -38,9 +38,11 @@ export default defineAddon({ shortDescription: 'auth guide', homepage: 'https://lucia-auth.com', options, - setup: ({ kit, dependencyVersion, unsupported, dependsOn }) => { + setup: ({ kit, dependencyVersion, unsupported, dependsOn, runsAfter }) => { if (!kit) unsupported('Requires SvelteKit'); if (!dependencyVersion('drizzle-orm')) dependsOn('drizzle'); + + runsAfter('tailwindcss'); }, run: ({ sv, typescript, options, kit, dependencyVersion }) => { const ext = typescript ? 'ts' : 'js'; @@ -365,7 +367,7 @@ export default defineAddon({ sv.file(`src/hooks.server.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); - js.imports.addNamespace(ast, '$lib/server/auth.js', 'auth'); + js.imports.addNamespace(ast, '$lib/server/auth', 'auth'); js.kit.addHooksHandle(ast, typescript, 'handleAuth', getAuthHandleContent()); return generateCode(); }); @@ -465,7 +467,7 @@ export default defineAddon({ const sessionToken = auth.generateSessionToken(); const session = await auth.createSession(sessionToken, userId); auth.setSessionTokenCookie(event, sessionToken, session.expiresAt); - } catch (e) { + } catch { return fail(500, { message: 'An error has occurred' }); } return redirect(302, '/demo/lucia'); @@ -505,6 +507,12 @@ export default defineAddon({ return content; } + const tailwind = dependencyVersion('@tailwindcss/vite') !== undefined; + const twInputClasses = + 'class="mt-1 px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"'; + const twBtnClasses = + 'class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition"'; + const svelte5 = !!dependencyVersion('svelte')?.startsWith('5'); const [ts, s5] = utils.createPrinter(typescript, svelte5); return dedent` @@ -515,17 +523,28 @@ export default defineAddon({

Login/Register

-
+ - - + +

{form?.message ?? ''}

`; @@ -542,12 +561,11 @@ export default defineAddon({ return dedent` import * as auth from '$lib/server/auth'; import { fail, redirect } from '@sveltejs/kit'; + import { getRequestEvent } from '$app/server'; ${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'); - } - return { user: event.locals.user }; + export const load${ts(': PageServerLoad')} = async () => { + const user = requireLogin() + return { user }; }; export const actions${ts(': Actions')} = { @@ -561,6 +579,16 @@ export default defineAddon({ return redirect(302, '/demo/lucia/login'); }, }; + + function requireLogin() { + const { locals } = getRequestEvent(); + + if (!locals.user) { + return redirect(302, "/demo/lucia/login"); + } + + return locals.user; + } `; }); diff --git a/packages/addons/paraglide/index.ts b/packages/addons/paraglide/index.ts index 822b30a7..d2b5bf9e 100644 --- a/packages/addons/paraglide/index.ts +++ b/packages/addons/paraglide/index.ts @@ -26,11 +26,13 @@ const DEFAULT_INLANG_PROJECT = { }; const options = defineAddonOptions({ - availableLanguageTags: { + languageTags: { question: `Which languages would you like to support? ${colors.gray('(e.g. en,de-ch)')}`, type: 'string', default: 'en, es', validate(input) { + if (!input) return; + const { invalidLanguageTags, validLanguageTags } = parseLanguageTagInput(input); if (invalidLanguageTags.length > 0) { @@ -78,7 +80,7 @@ export default defineAddon({ for (const key in DEFAULT_INLANG_PROJECT) { data[key] = DEFAULT_INLANG_PROJECT[key as keyof typeof DEFAULT_INLANG_PROJECT]; } - const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); + const { validLanguageTags } = parseLanguageTagInput(options.languageTags); const baseLocale = validLanguageTags[0]; data.baseLocale = baseLocale; @@ -205,7 +207,7 @@ export default defineAddon({ // add links to other localized pages, the first one is the default // language, thus it does not require any localized route - const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); + const { validLanguageTags } = parseLanguageTagInput(options.languageTags); const links = validLanguageTags .map( (x) => @@ -222,7 +224,7 @@ export default defineAddon({ }); } - const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); + const { validLanguageTags } = parseLanguageTagInput(options.languageTags); for (const languageTag of validLanguageTags) { sv.file(`messages/${languageTag}.json`, (content) => { const { data, generateCode } = parseJson(content); diff --git a/packages/addons/prettier/index.ts b/packages/addons/prettier/index.ts index 873ffd51..4c3f1117 100644 --- a/packages/addons/prettier/index.ts +++ b/packages/addons/prettier/index.ts @@ -24,7 +24,15 @@ export default defineAddon({ }); sv.file('.prettierrc', (content) => { - const { data, generateCode } = parseJson(content); + let data, generateCode; + try { + ({ data, generateCode } = parseJson(content)); + } catch { + log.warn( + `A ${colors.yellow('.prettierrc')} config already exists and cannot be parsed as JSON. Skipping initialization.` + ); + return content; + } if (Object.keys(data).length === 0) { // we'll only set these defaults if there is no pre-existing config data.useTabs = true; diff --git a/packages/addons/storybook/index.ts b/packages/addons/storybook/index.ts index 82edb41f..dd9a782f 100644 --- a/packages/addons/storybook/index.ts +++ b/packages/addons/storybook/index.ts @@ -1,11 +1,23 @@ +import process from 'node:process'; import { defineAddon } from '@sveltejs/cli-core'; +import { getNodeTypesVersion } from '../common.ts'; export default defineAddon({ id: 'storybook', shortDescription: 'frontend workshop', homepage: 'https://storybook.js.org', options: {}, + setup: ({ runsAfter }) => { + runsAfter('vitest'); + runsAfter('eslint'); + }, run: async ({ sv }) => { - await sv.execute(['storybook@latest', 'init', '--skip-install', '--no-dev'], 'inherit'); + const args = ['storybook@latest', 'init', '--skip-install', '--no-dev']; + + // skips the onboarding prompt during tests + if (process.env.NODE_ENV?.toLowerCase() === 'test') args.push('--yes'); + + await sv.execute(args, 'inherit'); + sv.devDependency(`@types/node`, getNodeTypesVersion()); } }); diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 59de5120..7bbdef6d 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -9,13 +9,12 @@ type Adapter = { }; const adapters: Adapter[] = [ - { id: 'auto', package: '@sveltejs/adapter-auto', version: '^4.0.0' }, - { id: 'node', package: '@sveltejs/adapter-node', version: '^5.2.11' }, + { id: 'auto', package: '@sveltejs/adapter-auto', version: '^6.0.0' }, + { id: 'node', package: '@sveltejs/adapter-node', version: '^5.2.12' }, { id: 'static', package: '@sveltejs/adapter-static', version: '^3.0.8' }, - { id: 'vercel', package: '@sveltejs/adapter-vercel', version: '^5.5.2' }, - { id: 'cloudflare-pages', package: '@sveltejs/adapter-cloudflare', version: '^5.0.1' }, - { id: 'cloudflare-workers', package: '@sveltejs/adapter-cloudflare-workers', version: '^2.7.0' }, - { id: 'netlify', package: '@sveltejs/adapter-netlify', version: '^4.4.0' } + { id: 'vercel', package: '@sveltejs/adapter-vercel', version: '^5.6.3' }, + { id: 'cloudflare', package: '@sveltejs/adapter-cloudflare', version: '^7.0.0' }, + { id: 'netlify', package: '@sveltejs/adapter-netlify', version: '^5.0.0' } ]; const options = defineAddonOptions({ diff --git a/packages/addons/vitest-addon/index.ts b/packages/addons/vitest-addon/index.ts index 59819bb3..11df9cf2 100644 --- a/packages/addons/vitest-addon/index.ts +++ b/packages/addons/vitest-addon/index.ts @@ -10,7 +10,7 @@ export default defineAddon({ run: ({ sv, typescript, kit }) => { const ext = typescript ? 'ts' : 'js'; - sv.devDependency('vitest', '^3.0.0'); + sv.devDependency('vitest', '^3.2.3'); sv.devDependency('@testing-library/svelte', '^5.2.4'); sv.devDependency('@testing-library/jest-dom', '^6.6.3'); sv.devDependency('jsdom', '^26.0.0'); @@ -141,7 +141,7 @@ export default defineAddon({ const vitestConfig = functions.argumentByIndex(defineWorkspaceCall, 0, object.createEmpty()); const testObject = object.property(vitestConfig, 'test', object.createEmpty()); - const workspaceArray = object.property(testObject, 'workspace', array.createEmpty()); + const workspaceArray = object.property(testObject, 'projects', array.createEmpty()); array.push(workspaceArray, clientObjectExpression); array.push(workspaceArray, serverObjectExpression); diff --git a/packages/ast-tooling/README.md b/packages/ast-tooling/README.md deleted file mode 100644 index 7f3a2c38..00000000 --- a/packages/ast-tooling/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# @sveltejs/ast-tooling - -This package provides tools and methods for parsing and serializing CSS, HTML and JS AST's. As the main [sv](https://svelte-add.com) project requires all of these tools they have been extracted into this separate project. - -Additionally this separate package allows us to bundle all (currently 8) required dependencies into on single package. diff --git a/packages/ast-tooling/package.json b/packages/ast-tooling/package.json deleted file mode 100644 index ee7629ce..00000000 --- a/packages/ast-tooling/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@sveltejs/ast-tooling", - "private": true, - "version": "0.0.0", - "type": "module", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/sveltejs/cli/tree/main/packages/ast-tooling" - }, - "bugs": "https://github.com/sveltejs/cli/issues", - "scripts": { - "check": "tsc", - "format": "pnpm lint --write", - "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" - }, - "files": [ - "dist" - ], - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } - }, - "devDependencies": { - "@sveltejs/acorn-typescript": "^1.0.1", - "@types/estree": "^1.0.6", - "acorn": "^8.14.0", - "dedent": "^1.5.3", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "esrap": "^1.4.5", - "htmlparser2": "^9.1.0", - "postcss": "^8.4.49", - "silver-fleece": "^1.2.1", - "zimmerframe": "^1.1.2" - } -} diff --git a/packages/ast-tooling/tsconfig.json b/packages/ast-tooling/tsconfig.json deleted file mode 100644 index c98d2852..00000000 --- a/packages/ast-tooling/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "checkJs": false, - "isolatedDeclarations": true, - "declaration": true - }, - "exclude": ["vitest.config.ts"] -} diff --git a/packages/ast-tooling/utils.ts b/packages/ast-tooling/utils.ts deleted file mode 100644 index b101faab..00000000 --- a/packages/ast-tooling/utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as Walker from 'zimmerframe'; -import type { TsEstree } from './ts-estree.ts'; - -// Sourced from `golden-fleece` -// https://github.com/Rich-Harris/golden-fleece/blob/f2446f331640f325e13609ed99b74b6a45e755c2/src/patch.ts#L302 -export function guessIndentString(str: string | undefined): string { - if (!str) return '\t'; - - const lines = str.split('\n'); - - let tabs = 0; - let spaces = 0; - let minSpaces = 8; - - lines.forEach((line) => { - const match = /^(?: +|\t+)/.exec(line); - if (!match) return; - - const whitespace = match[0]; - if (whitespace.length === line.length) return; - - if (whitespace[0] === '\t') { - tabs += 1; - } else { - spaces += 1; - if (whitespace.length > 1 && whitespace.length < minSpaces) { - minSpaces = whitespace.length; - } - } - }); - - if (spaces > tabs) { - let result = ''; - while (minSpaces--) result += ' '; - return result; - } else { - return '\t'; - } -} - -export function guessQuoteStyle(ast: TsEstree.Node): 'single' | 'double' | undefined { - let singleCount = 0; - let doubleCount = 0; - - Walker.walk(ast, null, { - Literal(node) { - if (node.raw && node.raw.length >= 2) { - // we have at least two characters in the raw string that could represent both quotes - const quotes = [node.raw[0], node.raw[node.raw.length - 1]]; - for (const quote of quotes) { - switch (quote) { - case "'": - singleCount++; - break; - case '"': - doubleCount++; - break; - default: - break; - } - } - } - } - }); - - if (singleCount === 0 && doubleCount === 0) { - // new file or file without any quotes - return undefined; - } - - return singleCount > doubleCount ? 'single' : 'double'; -} diff --git a/packages/ast-tooling/vitest.config.ts b/packages/ast-tooling/vitest.config.ts deleted file mode 100644 index 01f7288b..00000000 --- a/packages/ast-tooling/vitest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineProject } from 'vitest/config'; - -export default defineProject({ - test: { - name: 'ast-tooling', - include: ['./tests/*.ts'] - } -}); diff --git a/packages/clack-core/LICENSE b/packages/clack-core/LICENSE deleted file mode 100644 index a95d8e47..00000000 --- a/packages/clack-core/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -MIT License - -Copyright (c) Nate Moore - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---- - -`ansi-regex` is adapted from https://github.com/chalk/ansi-regex - -MIT License - -Copyright (c) Sindre Sorhus (https://sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/clack-core/README.md b/packages/clack-core/README.md deleted file mode 100644 index 57ac05f2..00000000 --- a/packages/clack-core/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# `@clack/core` - -Clack contains low-level primitives for implementing your own command-line applications. - -Currently, `TextPrompt`, `SelectPrompt`, and `ConfirmPrompt` are exposed as well as the base `Prompt` class. - -Each `Prompt` accepts a `render` function. - -```js -import { TextPrompt, isCancel } from '@clack/core'; - -const p = new TextPrompt({ - render() { - return `What's your name?\n${this.valueWithCursor}`; - } -}); - -const name = await p.prompt(); -if (isCancel(name)) { - process.exit(0); -} -``` diff --git a/packages/clack-core/index.ts b/packages/clack-core/index.ts deleted file mode 100644 index 37313080..00000000 --- a/packages/clack-core/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export { default as ConfirmPrompt } from './src/prompts/confirm.ts'; -export { default as GroupMultiSelectPrompt } from './src/prompts/group-multiselect.ts'; -export { default as MultiSelectPrompt } from './src/prompts/multi-select.ts'; -export { default as PasswordPrompt } from './src/prompts/password.ts'; -export { default as Prompt, isCancel } from './src/prompts/prompt.ts'; -export type { State } from './src/prompts/prompt.ts'; -export { default as SelectPrompt } from './src/prompts/select.ts'; -export { default as SelectKeyPrompt } from './src/prompts/select-key.ts'; -export { default as TextPrompt } from './src/prompts/text.ts'; -export { block } from './src/utils.ts'; diff --git a/packages/clack-core/package.json b/packages/clack-core/package.json deleted file mode 100644 index 4727de98..00000000 --- a/packages/clack-core/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "@sveltejs/clack-core", - "private": true, - "version": "0.4.2", - "type": "module", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/sveltejs/cli/tree/main/packages/clack-prompts" - }, - "bugs": "https://github.com/sveltejs/cli/issues", - "scripts": { - "check": "tsc", - "format": "pnpm lint --write", - "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" - }, - "files": [ - "dist" - ], - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "./package.json": "./package.json" - }, - "devDependencies": { - "picocolors": "^1.1.1", - "sisteransi": "^1.0.5", - "wrap-ansi": "^8.1.0" - } -} diff --git a/packages/clack-core/src/prompts/confirm.ts b/packages/clack-core/src/prompts/confirm.ts deleted file mode 100644 index 50e2a8a9..00000000 --- a/packages/clack-core/src/prompts/confirm.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { cursor } from 'sisteransi'; -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface ConfirmOptions extends PromptOptions { - active: string; - inactive: string; - initialValue?: boolean; -} -export default class ConfirmPrompt extends Prompt { - get cursor(): 0 | 1 { - return this.value ? 0 : 1; - } - - private get _value() { - return this.cursor === 0; - } - - constructor(opts: ConfirmOptions) { - super(opts, false); - this.value = opts.initialValue ? true : false; - - this.on('value', () => { - this.value = this._value; - }); - - this.on('confirm', (confirm) => { - this.output.write(cursor.move(0, -1)); - this.value = confirm; - this.state = 'submit'; - this.close(); - }); - - this.on('cursor', () => { - this.value = !this.value; - }); - } -} diff --git a/packages/clack-core/src/prompts/group-multiselect.ts b/packages/clack-core/src/prompts/group-multiselect.ts deleted file mode 100644 index e0601f44..00000000 --- a/packages/clack-core/src/prompts/group-multiselect.ts +++ /dev/null @@ -1,82 +0,0 @@ -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface GroupMultiSelectOptions - extends PromptOptions> { - options: Record; - initialValues?: Array; - required?: boolean; - cursorAt?: T['value']; - selectableGroups?: boolean; -} -export default class GroupMultiSelectPrompt extends Prompt { - options: Array; - cursor: number = 0; - #selectableGroups: boolean; - - getGroupItems(group: string): T[] { - return this.options.filter((o) => o.group === group); - } - - isGroupSelected(group: string): boolean { - const items = this.getGroupItems(group); - return this.#selectableGroups && items.every((i) => this.value.includes(i.value)); - } - - private toggleValue() { - const item = this.options[this.cursor]!; - if (item.group === true) { - const group = item.value; - const groupedItems = this.getGroupItems(group); - if (this.isGroupSelected(group)) { - this.value = this.value.filter( - (v: string) => groupedItems.findIndex((i) => i.value === v) === -1 - ); - } else { - this.value = [...this.value, ...groupedItems.map((i) => i.value)]; - } - this.value = Array.from(new Set(this.value)); - } else { - const selected = this.value.includes(item.value); - this.value = selected - ? this.value.filter((v: T['value']) => v !== item.value) - : [...this.value, item.value]; - } - } - - constructor(opts: GroupMultiSelectOptions) { - super(opts, false); - const { options } = opts; - this.#selectableGroups = opts.selectableGroups ?? true; - this.options = Object.entries(options).flatMap(([key, option]) => [ - { value: key, group: true, label: key }, - ...option.map((opt) => ({ ...opt, group: key })) - ]) as any; - this.value = [...(opts.initialValues ?? [])]; - this.cursor = Math.max( - this.options.findIndex(({ value }) => value === opts.cursorAt), - this.#selectableGroups ? 0 : 1 - ); - - this.on('cursor', (key) => { - switch (key) { - case 'left': - case 'up': - this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; - if (!this.#selectableGroups && this.options[this.cursor]!.group === true) { - this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; - } - break; - case 'down': - case 'right': - this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; - if (!this.#selectableGroups && this.options[this.cursor]!.group === true) { - this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; - } - break; - case 'space': - this.toggleValue(); - break; - } - }); - } -} diff --git a/packages/clack-core/src/prompts/multi-select.ts b/packages/clack-core/src/prompts/multi-select.ts deleted file mode 100644 index d708d50e..00000000 --- a/packages/clack-core/src/prompts/multi-select.ts +++ /dev/null @@ -1,60 +0,0 @@ -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface MultiSelectOptions extends PromptOptions> { - options: T[]; - initialValues?: Array; - required?: boolean; - cursorAt?: T['value']; -} -export default class MultiSelectPrompt extends Prompt { - options: T[]; - cursor: number = 0; - - private get _value() { - return this.options[this.cursor]!.value; - } - - private toggleAll() { - const allSelected = this.value.length === this.options.length; - this.value = allSelected ? [] : this.options.map((v) => v.value); - } - - private toggleValue() { - const selected = this.value.includes(this._value); - this.value = selected - ? this.value.filter((value: T['value']) => value !== this._value) - : [...this.value, this._value]; - } - - constructor(opts: MultiSelectOptions) { - super(opts, false); - - this.options = opts.options; - this.value = [...(opts.initialValues ?? [])]; - this.cursor = Math.max( - this.options.findIndex(({ value }) => value === opts.cursorAt), - 0 - ); - this.on('key', (char) => { - if (char === 'a') { - this.toggleAll(); - } - }); - - this.on('cursor', (key) => { - switch (key) { - case 'left': - case 'up': - this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; - break; - case 'down': - case 'right': - this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; - break; - case 'space': - this.toggleValue(); - break; - } - }); - } -} diff --git a/packages/clack-core/src/prompts/password.ts b/packages/clack-core/src/prompts/password.ts deleted file mode 100644 index fa2c55ce..00000000 --- a/packages/clack-core/src/prompts/password.ts +++ /dev/null @@ -1,33 +0,0 @@ -import color from 'picocolors'; -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface PasswordOptions extends PromptOptions { - mask?: string; -} -export default class PasswordPrompt extends Prompt { - valueWithCursor = ''; - private _mask = '•'; - get cursor(): number { - return this._cursor; - } - get masked(): string { - return this.value.replaceAll(/./g, this._mask); - } - constructor({ mask, ...opts }: PasswordOptions) { - super(opts); - this._mask = mask ?? '•'; - - this.on('finalize', () => { - this.valueWithCursor = this.masked; - }); - this.on('value', () => { - if (this.cursor >= this.value.length) { - this.valueWithCursor = `${this.masked}${color.inverse(color.hidden('_'))}`; - } else { - const s1 = this.masked.slice(0, this.cursor); - const s2 = this.masked.slice(this.cursor); - this.valueWithCursor = `${s1}${color.inverse(s2[0])}${s2.slice(1)}`; - } - }); - } -} diff --git a/packages/clack-core/src/prompts/prompt.ts b/packages/clack-core/src/prompts/prompt.ts deleted file mode 100644 index 40a2a057..00000000 --- a/packages/clack-core/src/prompts/prompt.ts +++ /dev/null @@ -1,273 +0,0 @@ -import readline, { type Key, type ReadLine } from 'node:readline'; -import process, { stdin, stdout } from 'node:process'; -import { WriteStream } from 'node:tty'; -import type { Readable, Writable } from 'node:stream'; -import { cursor, erase } from 'sisteransi'; -import wrap from 'wrap-ansi'; - -function diffLines(a: string, b: string) { - if (a === b) return; - - const aLines = a.split('\n'); - const bLines = b.split('\n'); - const diff: number[] = []; - - for (let i = 0; i < Math.max(aLines.length, bLines.length); i++) { - if (aLines[i] !== bLines[i]) diff.push(i); - } - - return diff; -} - -const cancel = Symbol('clack:cancel'); -export function isCancel(value: unknown): value is symbol { - return value === cancel; -} - -function setRawMode(input: Readable, value: boolean) { - if ((input as typeof stdin).isTTY) (input as typeof stdin).setRawMode(value); -} - -const aliases = new Map([ - ['k', 'up'], - ['j', 'down'], - ['h', 'left'], - ['l', 'right'] -]); -const keys = new Set(['up', 'down', 'left', 'right', 'space', 'enter']); - -export interface PromptOptions { - render(this: Omit): string | void; - placeholder?: string; - initialValue?: any; - validate?: ((value: any) => string | void) | undefined; - input?: Readable; - output?: Writable; - debug?: boolean; -} - -export type State = 'initial' | 'active' | 'cancel' | 'submit' | 'error'; - -export default class Prompt { - protected input: Readable; - protected output: Writable; - private rl!: ReadLine; - private opts: Omit, 'render' | 'input' | 'output'>; - private _track: boolean = false; - private _render: (context: Omit) => string | void; - protected _cursor: number = 0; - - public state: State = 'initial'; - public value: any; - public error: string = ''; - - constructor( - { render, input = stdin, output = stdout, ...opts }: PromptOptions, - trackValue: boolean = true - ) { - this.opts = opts; - this.onKeypress = this.onKeypress.bind(this); - this.close = this.close.bind(this); - this.render = this.render.bind(this); - this._render = render.bind(this); - this._track = trackValue; - - this.input = input; - this.output = output; - } - - public prompt(): Promise { - const sink = new WriteStream(0); - sink._write = (chunk, encoding, done) => { - if (this._track) { - this.value = this.rl.line.replace(/\t/g, ''); - this._cursor = this.rl.cursor; - this.emit('value', this.value); - } - done(); - }; - this.input.pipe(sink); - - this.rl = readline.createInterface({ - input: this.input, - output: sink, - tabSize: 2, - prompt: '', - escapeCodeTimeout: 50 - }); - readline.emitKeypressEvents(this.input, this.rl); - this.rl.prompt(); - if (this.opts.initialValue !== undefined && this._track) { - this.rl.write(this.opts.initialValue); - } - - this.input.on('keypress', this.onKeypress); - setRawMode(this.input, true); - this.output.on('resize', this.render); - - this.render(); - - return new Promise((resolve) => { - this.once('submit', () => { - this.output.write(cursor.show); - this.output.off('resize', this.render); - setRawMode(this.input, false); - resolve(this.value); - }); - this.once('cancel', () => { - this.output.write(cursor.show); - this.output.off('resize', this.render); - setRawMode(this.input, false); - resolve(cancel); - }); - }); - } - - private subscribers = new Map any; once?: boolean }>>(); - public on(event: string, cb: (...args: any) => any): void { - const arr = this.subscribers.get(event) ?? []; - arr.push({ cb }); - this.subscribers.set(event, arr); - } - public once(event: string, cb: (...args: any) => any): void { - const arr = this.subscribers.get(event) ?? []; - arr.push({ cb, once: true }); - this.subscribers.set(event, arr); - } - public emit(event: string, ...data: any[]): void { - const cbs = this.subscribers.get(event) ?? []; - const cleanup: Array<() => void> = []; - for (const subscriber of cbs) { - subscriber.cb(...data); - if (subscriber.once) { - cleanup.push(() => cbs.splice(cbs.indexOf(subscriber), 1)); - } - } - for (const cb of cleanup) { - cb(); - } - } - private unsubscribe() { - this.subscribers.clear(); - } - - private onKeypress(char: string, key?: Key) { - if (this.state === 'error') { - this.state = 'active'; - } - if (key?.name && !this._track && aliases.has(key.name)) { - this.emit('cursor', aliases.get(key.name)); - } - if (key?.name && keys.has(key.name)) { - this.emit('cursor', key.name); - } - if (char && (char.toLowerCase() === 'y' || char.toLowerCase() === 'n')) { - this.emit('confirm', char.toLowerCase() === 'y'); - } - if (char === '\t' && this.opts.placeholder) { - if (!this.value) { - this.rl.write(this.opts.placeholder); - this.emit('value', this.opts.placeholder); - } - } - if (char) { - this.emit('key', char.toLowerCase()); - } - - if (key?.name === 'return') { - if (this.opts.validate) { - const problem = this.opts.validate(this.value); - if (problem) { - this.error = problem; - this.state = 'error'; - this.rl.write(this.value); - } - } - if (this.state !== 'error') { - this.state = 'submit'; - } - } - if (char === '\x03') { - this.state = 'cancel'; - } - if (this.state === 'submit' || this.state === 'cancel') { - this.emit('finalize'); - } - this.render(); - if (this.state === 'submit' || this.state === 'cancel') { - this.close(); - } - } - - protected close(): void { - this.input.unpipe(); - this.input.removeListener('keypress', this.onKeypress); - this.output.write('\n'); - setRawMode(this.input, false); - this.rl.close(); - this.emit(this.state, this.value); - this.unsubscribe(); - } - - private restoreCursor() { - const lines = - wrap(this._prevFrame, process.stdout.columns, { hard: true }).split('\n').length - 1; - this.output.write(cursor.move(-999, lines * -1)); - } - - private _prevFrame = ''; - private render() { - const frame = wrap(this._render(this) ?? '', process.stdout.columns, { hard: true }); - if (frame === this._prevFrame) return; - - if (this.state === 'initial') { - this.output.write(cursor.hide); - } - - const diff = diffLines(this._prevFrame, frame); - this.restoreCursor(); - if (diff) { - const diffLine = diff[0]!; - const lines = frame.split('\n'); - let newLines: string[] = []; - - // If we don't have enough vertical space to print all of the lines simultaneously, - // then we'll sticky the prompt message (first 3 lines) to the top so it's always shown. - // We'll then take the remaining space and render a snippet of the list that's relative - // to the currently selected option - if (lines.length > process.stdout.rows) { - const OFFSET = 3; - const PAGE_SIZE = process.stdout.rows - OFFSET; - - // @ts-expect-error `cursor` is a property that's implemented by prompts extending this class. - const pos: number = this.cursor; - - // page positions - const start = pos <= OFFSET ? OFFSET : pos; - const end = start + PAGE_SIZE; - - this.output.write(erase.down()); - - // stickied headers - const header = lines.slice(0, OFFSET); - const content = lines.slice(start, end); - newLines = newLines.concat(header, content); - } else { - this.output.write(cursor.move(0, diffLine)); - this.output.write(erase.down()); - - newLines = lines.slice(diffLine); - } - - this.output.write(newLines.join('\n')); - this._prevFrame = frame; - return; - } - - this.output.write(frame); - if (this.state === 'initial') { - this.state = 'active'; - } - this._prevFrame = frame; - } -} diff --git a/packages/clack-core/src/prompts/select-key.ts b/packages/clack-core/src/prompts/select-key.ts deleted file mode 100644 index b0c703e6..00000000 --- a/packages/clack-core/src/prompts/select-key.ts +++ /dev/null @@ -1,27 +0,0 @@ -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface SelectKeyOptions extends PromptOptions> { - options: T[]; -} -export default class SelectKeyPrompt extends Prompt { - options: T[]; - cursor: number = 0; - - constructor(opts: SelectKeyOptions) { - super(opts, false); - - this.options = opts.options; - const keys = this.options.map(({ value: [initial] }) => initial?.toLowerCase()); - this.cursor = Math.max(keys.indexOf(opts.initialValue), 0); - - this.on('key', (key) => { - if (!keys.includes(key)) return; - const value = this.options.find(({ value: [initial] }) => initial?.toLowerCase() === key); - if (value) { - this.value = value.value; - this.state = 'submit'; - this.emit('submit'); - } - }); - } -} diff --git a/packages/clack-core/src/prompts/select.ts b/packages/clack-core/src/prompts/select.ts deleted file mode 100644 index ee5f2627..00000000 --- a/packages/clack-core/src/prompts/select.ts +++ /dev/null @@ -1,41 +0,0 @@ -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface SelectOptions extends PromptOptions> { - options: T[]; - initialValue?: T['value']; -} -export default class SelectPrompt extends Prompt { - options: T[]; - cursor: number = 0; - - private get _value() { - return this.options[this.cursor]; - } - - private changeValue() { - this.value = this._value!.value; - } - - constructor(opts: SelectOptions) { - super(opts, false); - - this.options = opts.options; - this.cursor = this.options.findIndex(({ value }) => value === opts.initialValue); - if (this.cursor === -1) this.cursor = 0; - this.changeValue(); - - this.on('cursor', (key) => { - switch (key) { - case 'left': - case 'up': - this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; - break; - case 'down': - case 'right': - this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; - break; - } - this.changeValue(); - }); - } -} diff --git a/packages/clack-core/src/prompts/text.ts b/packages/clack-core/src/prompts/text.ts deleted file mode 100644 index b2a89a71..00000000 --- a/packages/clack-core/src/prompts/text.ts +++ /dev/null @@ -1,33 +0,0 @@ -import color from 'picocolors'; -import Prompt, { type PromptOptions } from './prompt.ts'; - -export interface TextOptions extends PromptOptions { - placeholder?: string; - defaultValue?: string; -} - -export default class TextPrompt extends Prompt { - valueWithCursor = ''; - get cursor(): number { - return this._cursor; - } - constructor(opts: TextOptions) { - super(opts); - - this.on('finalize', () => { - if (!this.value) { - this.value = opts.defaultValue; - } - this.valueWithCursor = this.value; - }); - this.on('value', () => { - if (this.cursor >= this.value.length) { - this.valueWithCursor = `${this.value}${color.inverse(color.hidden('_'))}`; - } else { - const s1 = this.value.slice(0, this.cursor); - const s2 = this.value.slice(this.cursor); - this.valueWithCursor = `${s1}${color.inverse(s2[0])}${s2.slice(1)}`; - } - }); - } -} diff --git a/packages/clack-core/src/utils.ts b/packages/clack-core/src/utils.ts deleted file mode 100644 index b4a101e0..00000000 --- a/packages/clack-core/src/utils.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type { Key } from 'node:readline'; - -import process, { stdin, stdout } from 'node:process'; -import * as readline from 'node:readline'; -import { cursor } from 'sisteransi'; - -const isWindows = process.platform.startsWith('win'); - -export type BlockOptions = { - input?: NodeJS.ReadStream | undefined; - output?: NodeJS.WriteStream | undefined; - overwrite?: boolean | undefined; - hideCursor?: boolean | undefined; -}; - -export function block({ - input = stdin, - output = stdout, - overwrite = true, - hideCursor = true -}: BlockOptions = {}) { - const rl = readline.createInterface({ - input, - output, - prompt: '', - tabSize: 1 - }); - readline.emitKeypressEvents(input, rl); - if (input.isTTY) input.setRawMode(true); - - const clear = (data: Buffer, { name }: Key) => { - const str = String(data); - if (str === '\x03') { - process.exit(0); - } - if (!overwrite) return; - const dx = name === 'return' ? 0 : -1; - const dy = name === 'return' ? -1 : 0; - - readline.moveCursor(output, dx, dy, () => { - readline.clearLine(output, 1, () => { - input.once('keypress', clear); - }); - }); - }; - if (hideCursor) process.stdout.write(cursor.hide); - input.once('keypress', clear); - - return (): void => { - input.off('keypress', clear); - if (hideCursor) process.stdout.write(cursor.show); - - // Prevent Windows specific issues: https://github.com/natemoo-re/clack/issues/176 - if (input.isTTY && !isWindows) input.setRawMode(false); - - // @ts-expect-error fix for https://github.com/nodejs/node/issues/31762#issuecomment-1441223907 - rl.terminal = false; - rl.close(); - }; -} diff --git a/packages/clack-core/tsconfig.json b/packages/clack-core/tsconfig.json deleted file mode 100644 index a1fcf6c9..00000000 --- a/packages/clack-core/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "checkJs": false, - "isolatedDeclarations": true, - "declaration": true - } -} diff --git a/packages/clack-prompts/LICENSE b/packages/clack-prompts/LICENSE deleted file mode 100644 index a95d8e47..00000000 --- a/packages/clack-prompts/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -MIT License - -Copyright (c) Nate Moore - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---- - -`ansi-regex` is adapted from https://github.com/chalk/ansi-regex - -MIT License - -Copyright (c) Sindre Sorhus (https://sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/clack-prompts/README.md b/packages/clack-prompts/README.md deleted file mode 100644 index e5837fd6..00000000 --- a/packages/clack-prompts/README.md +++ /dev/null @@ -1,174 +0,0 @@ -# `@clack/prompts` - -Effortlessly build beautiful command-line apps 🪄 [Try the demo](https://stackblitz.com/edit/clack-prompts?file=index.js) - -![clack-prompt](https://github.com/natemoo-re/clack/blob/main/.github/assets/clack-demo.gif) - ---- - -`@clack/prompts` is an opinionated, pre-styled wrapper around [`@clack/core`](https://www.npmjs.com/package/@clack/core). - -- 🤏 80% smaller than other options -- 💎 Beautiful, minimal UI -- ✅ Simple API -- 🧱 Comes with `text`, `confirm`, `select`, `multiselect`, and `spinner` components - -## Basics - -### Setup - -The `intro` and `outro` functions will print a message to begin or end a prompt session, respectively. - -```js -import { intro, outro } from '@clack/prompts'; - -intro(`create-my-app`); -// Do stuff -outro(`You're all set!`); -``` - -### Cancellation - -The `isCancel` function is a guard that detects when a user cancels a question with `CTRL + C`. You should handle this situation for each prompt, optionally providing a nice cancellation message with the `cancel` utility. - -```js -import { isCancel, cancel, text } from '@clack/prompts'; - -const value = await text(/* TODO */); - -if (isCancel(value)) { - cancel('Operation cancelled.'); - process.exit(0); -} -``` - -## Components - -### Text - -The text component accepts a single line of text. - -```js -import { text } from '@clack/prompts'; - -const meaning = await text({ - message: 'What is the meaning of life?', - placeholder: 'Not sure', - initialValue: '42', - validate(value) { - if (value.length === 0) return `Value is required!`; - } -}); -``` - -### Confirm - -The confirm component accepts a yes or no answer. The result is a boolean value of `true` or `false`. - -```js -import { confirm } from '@clack/prompts'; - -const shouldContinue = await confirm({ - message: 'Do you want to continue?' -}); -``` - -### Select - -The select component allows a user to choose one value from a list of options. The result is the `value` prop of a given option. - -```js -import { select } from '@clack/prompts'; - -const projectType = await select({ - message: 'Pick a project type.', - options: [ - { value: 'ts', label: 'TypeScript' }, - { value: 'js', label: 'JavaScript' }, - { value: 'coffee', label: 'CoffeeScript', hint: 'oh no' } - ] -}); -``` - -### Multi-Select - -The `multiselect` component allows a user to choose many values from a list of options. The result is an array with all selected `value` props. - -```js -import { multiselect } from '@clack/prompts'; - -const additionalTools = await multiselect({ - message: 'Select additional tools.', - options: [ - { value: 'eslint', label: 'ESLint', hint: 'recommended' }, - { value: 'prettier', label: 'Prettier' }, - { value: 'gh-action', label: 'GitHub Action' } - ], - required: false -}); -``` - -### Spinner - -The spinner component surfaces a pending action, such as a long-running download or dependency installation. - -```js -import { spinner } from '@clack/prompts'; - -const s = spinner(); -s.start('Installing via npm'); -// Do installation here -s.stop('Installed via npm'); -``` - -## Utilities - -### Grouping - -Grouping prompts together is a great way to keep your code organized. This accepts a JSON object with a name that can be used to reference the group later. The second argument is an optional but has a `onCancel` callback that will be called if the user cancels one of the prompts in the group. - -```js -import * as p from '@clack/prompts'; - -const group = await p.group( - { - name: () => p.text({ message: 'What is your name?' }), - age: () => p.text({ message: 'What is your age?' }), - color: ({ results }) => - p.multiselect({ - message: `What is your favorite color ${results.name}?`, - options: [ - { value: 'red', label: 'Red' }, - { value: 'green', label: 'Green' }, - { value: 'blue', label: 'Blue' } - ] - }) - }, - { - // On Cancel callback that wraps the group - // So if the user cancels one of the prompts in the group this function will be called - onCancel: ({ results }) => { - p.cancel('Operation cancelled.'); - process.exit(0); - } - } -); - -console.log(group.name, group.age, group.color); -``` - -### Tasks - -Execute multiple tasks in spinners. - -```js -await p.tasks([ - { - title: 'Installing via npm', - task: async (message) => { - // Do installation here - return 'Installed via npm'; - } - } -]); -``` diff --git a/packages/clack-prompts/index.ts b/packages/clack-prompts/index.ts deleted file mode 100644 index d93f8c0f..00000000 --- a/packages/clack-prompts/index.ts +++ /dev/null @@ -1,894 +0,0 @@ -import process from 'node:process'; -import { - block, - ConfirmPrompt, - GroupMultiSelectPrompt, - isCancel, - MultiSelectPrompt, - PasswordPrompt, - SelectKeyPrompt, - SelectPrompt, - type State, - TextPrompt -} from '@sveltejs/clack-core'; -import isUnicodeSupported from 'is-unicode-supported'; -import color from 'picocolors'; -import { cursor, erase } from 'sisteransi'; - -export { isCancel } from '@sveltejs/clack-core'; - -const unicode = isUnicodeSupported(); -const s = (c: string, fallback: string) => (unicode ? c : fallback); -const S_STEP_ACTIVE = s('◆', '*'); -const S_STEP_CANCEL = s('■', 'x'); -const S_STEP_ERROR = s('▲', 'x'); -const S_STEP_SUBMIT = s('◇', 'o'); - -const S_BAR_START = s('┌', 'T'); -const S_BAR = s('│', '|'); -const S_BAR_END = s('└', '—'); - -const S_RADIO_ACTIVE = s('●', '>'); -const S_RADIO_INACTIVE = s('○', ' '); -const S_CHECKBOX_ACTIVE = s('◻', '[•]'); -const S_CHECKBOX_SELECTED = s('◼', '[+]'); -const S_CHECKBOX_INACTIVE = s('◻', '[ ]'); -const S_PASSWORD_MASK = s('▪', '•'); - -const S_BAR_H = s('─', '-'); -const S_CORNER_TOP_RIGHT = s('╮', '+'); -const S_CONNECT_LEFT = s('├', '+'); -const S_CORNER_BOTTOM_RIGHT = s('╯', '+'); - -const S_INFO = s('●', '•'); -const S_SUCCESS = s('◆', '*'); -const S_WARN = s('▲', '!'); -const S_ERROR = s('■', 'x'); - -const symbol = (state: State) => { - switch (state) { - case 'initial': - case 'active': - return color.cyan(S_STEP_ACTIVE); - case 'cancel': - return color.red(S_STEP_CANCEL); - case 'error': - return color.yellow(S_STEP_ERROR); - case 'submit': - return color.green(S_STEP_SUBMIT); - } -}; - -interface LimitOptionsParams { - options: TOption[]; - maxItems: number | undefined; - cursor: number; - style: (option: TOption, active: boolean) => string; -} - -const limitOptions = (params: LimitOptionsParams): string[] => { - const { cursor, options, style } = params; - - const paramMaxItems = params.maxItems ?? Infinity; - const outputMaxItems = Math.max(process.stdout.rows - 4, 0); - // We clamp to minimum 5 because anything less doesn't make sense UX wise - const maxItems = Math.min(outputMaxItems, Math.max(paramMaxItems, 5)); - let slidingWindowLocation = 0; - - if (cursor >= slidingWindowLocation + maxItems - 3) { - slidingWindowLocation = Math.max(Math.min(cursor - maxItems + 3, options.length - maxItems), 0); - } else if (cursor < slidingWindowLocation + 2) { - slidingWindowLocation = Math.max(cursor - 2, 0); - } - - const shouldRenderTopEllipsis = maxItems < options.length && slidingWindowLocation > 0; - const shouldRenderBottomEllipsis = - maxItems < options.length && slidingWindowLocation + maxItems < options.length; - - return options - .slice(slidingWindowLocation, slidingWindowLocation + maxItems) - .map((option, i, arr) => { - const isTopLimit = i === 0 && shouldRenderTopEllipsis; - const isBottomLimit = i === arr.length - 1 && shouldRenderBottomEllipsis; - return isTopLimit || isBottomLimit - ? color.dim('...') - : style(option, i + slidingWindowLocation === cursor); - }); -}; - -export interface TextOptions { - message: string; - placeholder?: string; - defaultValue?: string; - initialValue?: string; - validate?: (value: string) => string | void; -} -export const text = (opts: TextOptions): Promise => { - return new TextPrompt({ - validate: opts.validate, - placeholder: opts.placeholder, - defaultValue: opts.defaultValue, - initialValue: opts.initialValue, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - const placeholder = opts.placeholder - ? color.inverse(opts.placeholder[0]) + color.dim(opts.placeholder.slice(1)) - : color.inverse(color.hidden('_')); - const value = !this.value ? placeholder : this.valueWithCursor; - - switch (this.state) { - case 'error': - return `${title.trim()}\n${color.yellow(S_BAR)} ${value}\n${color.yellow( - S_BAR_END - )} ${color.yellow(this.error)}\n`; - case 'submit': - return `${title}${color.gray(S_BAR)} ${color.dim(this.value || opts.placeholder)}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${color.strikethrough( - color.dim(this.value ?? '') - )}${this.value?.trim() ? '\n' + color.gray(S_BAR) : ''}`; - default: - return `${title}${color.cyan(S_BAR)} ${value}\n${color.cyan(S_BAR_END)}\n`; - } - } - }).prompt(); -}; - -export interface PasswordOptions { - message: string; - mask?: string; - validate?: (value: string) => string | void; -} -export const password = (opts: PasswordOptions): Promise => { - return new PasswordPrompt({ - validate: opts.validate, - mask: opts.mask ?? S_PASSWORD_MASK, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - const value = this.valueWithCursor; - const masked = this.masked; - - switch (this.state) { - case 'error': - return `${title.trim()}\n${color.yellow(S_BAR)} ${masked}\n${color.yellow( - S_BAR_END - )} ${color.yellow(this.error)}\n`; - case 'submit': - return `${title}${color.gray(S_BAR)} ${color.dim(masked)}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${color.strikethrough(color.dim(masked ?? ''))}${ - masked ? '\n' + color.gray(S_BAR) : '' - }`; - default: - return `${title}${color.cyan(S_BAR)} ${value}\n${color.cyan(S_BAR_END)}\n`; - } - } - }).prompt(); -}; - -export interface ConfirmOptions { - message: string; - active?: string; - inactive?: string; - initialValue?: boolean; -} -export const confirm = (opts: ConfirmOptions) => { - const active = opts.active ?? 'Yes'; - const inactive = opts.inactive ?? 'No'; - return new ConfirmPrompt({ - active, - inactive, - initialValue: opts.initialValue ?? true, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - const value = this.value ? active : inactive; - - switch (this.state) { - case 'submit': - return `${title}${color.gray(S_BAR)} ${color.dim(value)}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${color.strikethrough( - color.dim(value) - )}\n${color.gray(S_BAR)}`; - default: { - return `${title}${color.cyan(S_BAR)} ${ - this.value - ? `${color.green(S_RADIO_ACTIVE)} ${active}` - : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(active)}` - } ${color.dim('/')} ${ - !this.value - ? `${color.green(S_RADIO_ACTIVE)} ${inactive}` - : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(inactive)}` - }\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -type Primitive = Readonly; - -type Option = Value extends Primitive - ? { value: Value; label?: string; hint?: string } - : { value: Value; label: string; hint?: string }; - -export interface SelectOptions { - message: string; - options: Array>; - initialValue?: Value; - maxItems?: number; -} - -export const select = (opts: SelectOptions) => { - const opt = (option: Option, state: 'inactive' | 'active' | 'selected' | 'cancelled') => { - const label = option.label ?? String(option.value); - switch (state) { - case 'selected': - return color.dim(label); - case 'active': - return `${color.green(S_RADIO_ACTIVE)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - case 'cancelled': - return color.strikethrough(color.dim(label)); - default: - return `${color.dim(S_RADIO_INACTIVE)} ${color.dim(label)}`; - } - }; - - return new SelectPrompt({ - options: opts.options, - initialValue: opts.initialValue, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - - switch (this.state) { - case 'submit': - return `${title}${color.gray(S_BAR)} ${opt(this.options[this.cursor]!, 'selected')}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${opt( - this.options[this.cursor]!, - 'cancelled' - )}\n${color.gray(S_BAR)}`; - default: { - return `${title}${color.cyan(S_BAR)} ${limitOptions({ - cursor: this.cursor, - options: this.options, - maxItems: opts.maxItems, - style: (item, active) => opt(item, active ? 'active' : 'inactive') - }).join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -export const selectKey = (opts: SelectOptions) => { - const opt = ( - option: Option, - state: 'inactive' | 'active' | 'selected' | 'cancelled' = 'inactive' - ) => { - const label = option.label ?? String(option.value); - if (state === 'selected') { - return color.dim(label); - } else if (state === 'cancelled') { - return color.strikethrough(color.dim(label)); - } else if (state === 'active') { - return `${color.bgCyan(color.gray(` ${option.value} `))} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } - return `${color.gray(color.bgWhite(color.inverse(` ${option.value} `)))} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - }; - - return new SelectKeyPrompt({ - options: opts.options, - initialValue: opts.initialValue, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - - switch (this.state) { - case 'submit': - return `${title}${color.gray(S_BAR)} ${opt( - this.options.find((opt) => opt.value === this.value)!, - 'selected' - )}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${opt(this.options[0]!, 'cancelled')}\n${color.gray( - S_BAR - )}`; - default: { - return `${title}${color.cyan(S_BAR)} ${this.options - .map((option, i) => opt(option, i === this.cursor ? 'active' : 'inactive')) - .join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -export interface MultiSelectOptions { - message: string; - options: Array>; - initialValues?: Value[]; - maxItems?: number; - required?: boolean; - cursorAt?: Value; -} -export const multiselect = (opts: MultiSelectOptions) => { - const opt = ( - option: Option, - state: 'inactive' | 'active' | 'selected' | 'active-selected' | 'submitted' | 'cancelled' - ) => { - const label = option.label ?? String(option.value); - if (state === 'active') { - return `${color.cyan(S_CHECKBOX_ACTIVE)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } else if (state === 'selected') { - return `${color.green(S_CHECKBOX_SELECTED)} ${color.dim(label)}`; - } else if (state === 'cancelled') { - return color.strikethrough(color.dim(label)); - } else if (state === 'active-selected') { - return `${color.green(S_CHECKBOX_SELECTED)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } else if (state === 'submitted') { - return color.dim(label); - } - return `${color.dim(S_CHECKBOX_INACTIVE)} ${color.dim(label)}`; - }; - - return new MultiSelectPrompt({ - options: opts.options, - initialValues: opts.initialValues, - required: opts.required ?? true, - cursorAt: opts.cursorAt, - validate(selected: Value[]) { - if (this.required && selected.length === 0) - return `Please select at least one option.\n${color.reset( - color.dim( - `Press ${color.gray(color.bgWhite(color.inverse(' space ')))} to select, ${color.gray( - color.bgWhite(color.inverse(' enter ')) - )} to submit` - ) - )}`; - }, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - - const styleOption = (option: Option, active: boolean) => { - const selected = this.value.includes(option.value); - if (active && selected) { - return opt(option, 'active-selected'); - } - if (selected) { - return opt(option, 'selected'); - } - return opt(option, active ? 'active' : 'inactive'); - }; - - switch (this.state) { - case 'submit': { - return `${title}${color.gray(S_BAR)} ${ - this.options - .filter(({ value }) => this.value.includes(value)) - .map((option) => opt(option, 'submitted')) - .join(color.dim(', ')) || color.dim('none') - }`; - } - case 'cancel': { - const label = this.options - .filter(({ value }) => this.value.includes(value)) - .map((option) => opt(option, 'cancelled')) - .join(color.dim(', ')); - return `${title}${color.gray(S_BAR)} ${ - label.trim() ? `${label}\n${color.gray(S_BAR)}` : '' - }`; - } - case 'error': { - const footer = this.error - .split('\n') - .map((ln, i) => - i === 0 ? `${color.yellow(S_BAR_END)} ${color.yellow(ln)}` : ` ${ln}` - ) - .join('\n'); - return ( - title + - color.yellow(S_BAR) + - ' ' + - limitOptions({ - options: this.options, - cursor: this.cursor, - maxItems: opts.maxItems, - style: styleOption - }).join(`\n${color.yellow(S_BAR)} `) + - '\n' + - footer + - '\n' - ); - } - default: { - return `${title}${color.cyan(S_BAR)} ${limitOptions({ - options: this.options, - cursor: this.cursor, - maxItems: opts.maxItems, - style: styleOption - }).join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -export interface GroupMultiSelectOptions { - message: string; - options: Record>>; - initialValues?: Value[]; - required?: boolean; - cursorAt?: Value; - selectableGroups?: boolean; - spacedGroups?: boolean; -} - -export const groupMultiselect = (opts: GroupMultiSelectOptions) => { - const { selectableGroups = false, spacedGroups = false } = opts; - const opt = ( - option: Option, - state: - | 'inactive' - | 'active' - | 'selected' - | 'active-selected' - | 'group-active' - | 'group-active-selected' - | 'submitted' - | 'cancelled', - options: Array> = [] - ) => { - const label = option.label ?? String(option.value); - const isItem = typeof (option as any).group === 'string'; - const next = isItem && (options[options.indexOf(option) + 1] ?? { group: true }); - // @ts-ignore - const isLast = isItem && next.group === true; - const prefix = isItem ? (selectableGroups ? `${isLast ? S_BAR_END : S_BAR} ` : ' ') : ''; - const spacingPrefix = spacedGroups && !isItem ? `\n${color.cyan(S_BAR)} ` : ''; - - if (state === 'active') { - return `${spacingPrefix}${color.dim(prefix)}${color.cyan(S_CHECKBOX_ACTIVE)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } else if (state === 'group-active') { - return `${spacingPrefix}${prefix}${color.cyan(S_CHECKBOX_ACTIVE)} ${color.dim(label)}`; - } else if (state === 'group-active-selected') { - return `${spacingPrefix}${prefix}${color.green(S_CHECKBOX_SELECTED)} ${color.dim(label)}`; - } else if (state === 'selected') { - return `${spacingPrefix}${color.dim(prefix)}${color.green(S_CHECKBOX_SELECTED)} ${color.dim( - label - )}`; - } else if (state === 'cancelled') { - return color.strikethrough(color.dim(label)); - } else if (state === 'active-selected') { - return `${spacingPrefix}${color.dim(prefix)}${color.green(S_CHECKBOX_SELECTED)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } else if (state === 'submitted') { - return color.dim(label); - } - return `${spacingPrefix}${color.dim(prefix)}${ - isItem || selectableGroups ? `${color.dim(S_CHECKBOX_INACTIVE)} ` : '' - }${color.dim(label)}`; - }; - - return new GroupMultiSelectPrompt({ - options: opts.options, - initialValues: opts.initialValues, - required: opts.required ?? true, - cursorAt: opts.cursorAt, - selectableGroups, - validate(selected: Value[]) { - if (this.required && selected.length === 0) - return `Please select at least one option.\n${color.reset( - color.dim( - `Press ${color.gray(color.bgWhite(color.inverse(' space ')))} to select, ${color.gray( - color.bgWhite(color.inverse(' enter ')) - )} to submit` - ) - )}`; - }, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - - switch (this.state) { - case 'submit': { - return `${title}${color.gray(S_BAR)} ${this.options - .filter(({ value }) => this.value.includes(value)) - .map((option) => opt(option, 'submitted')) - .join(color.dim(', '))}`; - } - case 'cancel': { - const label = this.options - .filter(({ value }) => this.value.includes(value)) - .map((option) => opt(option, 'cancelled')) - .join(color.dim(', ')); - return `${title}${color.gray(S_BAR)} ${ - label.trim() ? `${label}\n${color.gray(S_BAR)}` : '' - }`; - } - case 'error': { - const footer = this.error - .split('\n') - .map((ln, i) => - i === 0 ? `${color.yellow(S_BAR_END)} ${color.yellow(ln)}` : ` ${ln}` - ) - .join('\n'); - return `${title}${color.yellow(S_BAR)} ${this.options - .map((option, i, options) => { - const selected = - this.value.includes(option.value) || - (option.group === true && this.isGroupSelected(`${option.value}`)); - const active = i === this.cursor; - const groupActive = - !active && - typeof option.group === 'string' && - this.options[this.cursor]!.value === option.group; - if (groupActive) { - return opt(option, selected ? 'group-active-selected' : 'group-active', options); - } - if (active && selected) { - return opt(option, 'active-selected', options); - } - if (selected) { - return opt(option, 'selected', options); - } - return opt(option, active ? 'active' : 'inactive', options); - }) - .join(`\n${color.yellow(S_BAR)} `)}\n${footer}\n`; - } - default: { - return `${title}${color.cyan(S_BAR)} ${this.options - .map((option, i, options) => { - const selected = - this.value.includes(option.value) || - (option.group === true && this.isGroupSelected(`${option.value}`)); - const active = i === this.cursor; - const groupActive = - !active && - typeof option.group === 'string' && - this.options[this.cursor]!.value === option.group; - if (groupActive) { - return opt(option, selected ? 'group-active-selected' : 'group-active', options); - } - if (active && selected) { - return opt(option, 'active-selected', options); - } - if (selected) { - return opt(option, 'selected', options); - } - return opt(option, active ? 'active' : 'inactive', options); - }) - .join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -const strip = (str: string) => str.replace(ansiRegex(), ''); -function buildBox(message = '', title = '', dimmed = true) { - const lines = `\n${message}\n`.split('\n'); - const titleLen = strip(title).length; - const len = - Math.max( - lines.reduce((sum, ln) => { - ln = strip(ln); - return ln.length > sum ? ln.length : sum; - }, 0), - titleLen - ) + 2; - const msg = lines - .map( - (ln) => - `${color.gray(S_BAR)} ${dimmed ? color.dim(ln) : ln}${' '.repeat(len - strip(ln).length)}${color.gray(S_BAR)}` - ) - .join('\n'); - process.stdout.write( - `${color.gray(S_BAR)}\n${color.green(S_STEP_SUBMIT)} ${color.reset(title)} ${color.gray( - S_BAR_H.repeat(Math.max(len - titleLen - 1, 1)) + S_CORNER_TOP_RIGHT - )}\n${msg}\n${color.gray(S_CONNECT_LEFT + S_BAR_H.repeat(len + 2) + S_CORNER_BOTTOM_RIGHT)}\n` - ); -} - -export const note = (message = '', title = ''): void => buildBox(message, title, true); -export const box = (message = '', title = ''): void => buildBox(message, title, false); -export const taskLog = (title: string) => { - const BAR = color.dim(S_BAR); - const ACTIVE = color.green(S_STEP_SUBMIT); - const SUCCESS = color.green(S_SUCCESS); - const ERROR = color.red(S_ERROR); - - // heading - process.stdout.write(`${BAR}\n`); - process.stdout.write(`${ACTIVE} ${title}\n`); - - let output = ''; - let frame = ''; - - // clears previous output - const clear = (eraseTitle = false): void => { - if (!frame) return; - const terminalWidth = process.stdout.columns; - const frameHeight = frame.split('\n').reduce((height, line) => { - // accounts for line wraps - height += Math.ceil(line.length / terminalWidth); - return height; - }, 0); - const lines = frameHeight + (eraseTitle ? 1 : 0); - - process.stdout.write(cursor.up(lines)); - process.stdout.write(erase.down()); - }; - - // logs the output - const print = (limit = 0): void => { - const lines = output.split('\n').slice(-limit); - // reset frame - frame = ''; - for (const line of lines) { - frame += `${BAR} ${line}\n`; - } - process.stdout.write(color.dim(frame)); - }; - - return { - set text(data: string) { - clear(); - output += data; - // half the height of the terminal - const frameHeight = Math.ceil(process.stdout.rows / 2); - print(frameHeight); - }, - fail(message: string): void { - clear(true); - process.stdout.write(`${ERROR} ${message}\n`); - print(); // log the output on failure - }, - success(message: string): void { - clear(true); - process.stdout.write(`${SUCCESS} ${message}\n`); - } - }; -}; - -export const cancel = (message = ''): void => { - process.stdout.write(`${color.gray(S_BAR_END)} ${color.red(message)}\n\n`); -}; - -export const intro = (title = ''): void => { - process.stdout.write(`${color.gray(S_BAR_START)} ${title}\n`); -}; - -export const outro = (message = ''): void => { - process.stdout.write(`${color.gray(S_BAR)}\n${color.gray(S_BAR_END)} ${message}\n\n`); -}; - -export type LogMessageOptions = { - symbol?: string; -}; -export const log = { - message: (message = '', { symbol = color.gray(S_BAR) }: LogMessageOptions = {}): void => { - const parts = [color.gray(S_BAR)]; - if (message) { - const [firstLine, ...lines] = message.split('\n'); - parts.push(`${symbol} ${firstLine}`, ...lines.map((ln) => `${color.gray(S_BAR)} ${ln}`)); - } - process.stdout.write(`${parts.join('\n')}\n`); - }, - info: (message: string): void => { - log.message(message, { symbol: color.blue(S_INFO) }); - }, - success: (message: string): void => { - log.message(message, { symbol: color.green(S_SUCCESS) }); - }, - step: (message: string): void => { - log.message(message, { symbol: color.green(S_STEP_SUBMIT) }); - }, - warn: (message: string): void => { - log.message(message, { symbol: color.yellow(S_WARN) }); - }, - /** alias for `log.warn()`. */ - warning: (message: string): void => { - log.warn(message); - }, - error: (message: string): void => { - log.message(message, { symbol: color.red(S_ERROR) }); - } -}; - -export const spinner = (): { - start: (msg?: string) => void; - stop: (msg?: string, code?: number) => void; - message: (msg?: string) => void; -} => { - const frames = unicode ? ['◒', '◐', '◓', '◑'] : ['•', 'o', 'O', '0']; - const delay = unicode ? 80 : 120; - - let unblock: () => void; - let loop: NodeJS.Timeout; - let isSpinnerActive: boolean = false; - let _message: string = ''; - - const handleExit = (code: number) => { - const msg = code > 1 ? 'Something went wrong' : 'Canceled'; - if (isSpinnerActive) stop(msg, code); - }; - - const errorEventHandler = () => { - handleExit(2); - }; - const signalEventHandler = () => { - handleExit(1); - }; - - const registerHooks = () => { - // Reference: https://nodejs.org/api/process.html#event-uncaughtexception - process.on('uncaughtExceptionMonitor', errorEventHandler); - // Reference: https://nodejs.org/api/process.html#event-unhandledrejection - process.on('unhandledRejection', errorEventHandler); - // Reference Signal Events: https://nodejs.org/api/process.html#signal-events - process.on('SIGINT', signalEventHandler); - process.on('SIGTERM', signalEventHandler); - process.on('exit', handleExit); - }; - - const clearHooks = () => { - process.removeListener('uncaughtExceptionMonitor', errorEventHandler); - process.removeListener('unhandledRejection', errorEventHandler); - process.removeListener('SIGINT', signalEventHandler); - process.removeListener('SIGTERM', signalEventHandler); - process.removeListener('exit', handleExit); - }; - - const start = (msg: string = ''): void => { - isSpinnerActive = true; - unblock = block(); - _message = msg.replace(/\.+$/, ''); - process.stdout.write(`${color.gray(S_BAR)}\n`); - let frameIndex = 0; - let dotsTimer = 0; - registerHooks(); - loop = setInterval(() => { - const frame = color.magenta(frames[frameIndex]); - const loadingDots = '.'.repeat(Math.floor(dotsTimer)).slice(0, 3); - process.stdout.write(cursor.move(-999, 0)); - process.stdout.write(erase.down(1)); - process.stdout.write(`${frame} ${_message}${loadingDots}`); - frameIndex = frameIndex + 1 < frames.length ? frameIndex + 1 : 0; - dotsTimer = dotsTimer < frames.length ? dotsTimer + 0.125 : 0; - }, delay); - }; - - const stop = (msg: string = '', code: number = 0): void => { - _message = msg ?? _message; - isSpinnerActive = false; - clearInterval(loop); - const step = - code === 0 - ? color.green(S_STEP_SUBMIT) - : code === 1 - ? color.red(S_STEP_CANCEL) - : color.red(S_STEP_ERROR); - process.stdout.write(cursor.move(-999, 0)); - process.stdout.write(erase.down(1)); - process.stdout.write(`${step} ${_message}\n`); - clearHooks(); - unblock(); - }; - - const message = (msg: string = ''): void => { - _message = msg ?? _message; - }; - - return { - start, - stop, - message - }; -}; - -// Adapted from https://github.com/chalk/ansi-regex -// @see LICENSE -function ansiRegex() { - const pattern = [ - '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', - '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))' - ].join('|'); - - return new RegExp(pattern, 'g'); -} - -export type PromptGroupAwaitedReturn = { - [P in keyof T]: Exclude, symbol>; -}; - -export interface PromptGroupOptions { - /** - * Control how the group can be canceled - * if one of the prompts is canceled. - */ - onCancel?: (opts: { results: Prettify>> }) => void; -} - -type Prettify = { - [P in keyof T]: T[P]; -} & {}; - -export type PromptGroup = { - [P in keyof T]: (opts: { - results: Prettify>>>; - }) => void | Promise; -}; - -/** - * Define a group of prompts to be displayed - * and return a results of objects within the group - */ -export const group = async ( - prompts: PromptGroup, - opts?: PromptGroupOptions -): Promise>> => { - const results = {} as any; - const promptNames = Object.keys(prompts); - - for (const name of promptNames) { - const prompt = prompts[name as keyof T]; - const result = await prompt({ results })?.catch((e) => { - throw e; - }); - - // Pass the results to the onCancel function - // so the user can decide what to do with the results - // TODO: Switch to callback within core to avoid isCancel Fn - if (typeof opts?.onCancel === 'function' && isCancel(result)) { - results[name] = 'canceled'; - opts.onCancel({ results }); - continue; - } - - results[name] = result; - } - - return results; -}; - -export type Task = { - /** - * Task title - */ - title: string; - /** - * Task function - */ - task: (message: (string: string) => void) => string | Promise | void | Promise; - - /** - * If enabled === false the task will be skipped - */ - enabled?: boolean; -}; - -/** - * Define a group of tasks to be executed - */ -export const tasks = async (tasks: Task[]): Promise => { - for (const task of tasks) { - if (task.enabled === false) continue; - - const s = spinner(); - s.start(task.title); - const result = await task.task(s.message); - s.stop(result || task.title); - } -}; diff --git a/packages/clack-prompts/package.json b/packages/clack-prompts/package.json deleted file mode 100644 index 733d8445..00000000 --- a/packages/clack-prompts/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "@sveltejs/clack-prompts", - "private": true, - "version": "0.9.1", - "type": "module", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/sveltejs/cli/tree/main/packages/clack-prompts" - }, - "bugs": "https://github.com/sveltejs/cli/issues", - "scripts": { - "check": "tsc", - "format": "pnpm lint --write", - "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" - }, - "files": [ - "dist" - ], - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "./package.json": "./package.json" - }, - "devDependencies": { - "@sveltejs/clack-core": "workspace:*", - "is-unicode-supported": "^1.3.0", - "picocolors": "^1.1.1", - "sisteransi": "^1.0.5" - } -} diff --git a/packages/clack-prompts/tsconfig.json b/packages/clack-prompts/tsconfig.json deleted file mode 100644 index a1fcf6c9..00000000 --- a/packages/clack-prompts/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "checkJs": false, - "isolatedDeclarations": true, - "declaration": true - } -} diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index a4c71bc5..56c32df8 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,104 @@ # sv +## 0.8.10 +### Patch Changes + + +- chore: update lucia template ([#586](https://github.com/sveltejs/cli/pull/586)) + +## 0.8.9 +### Patch Changes + + +- fix(vitest): unpin vitest to ^3.2.3 after it fixed a regression ([#587](https://github.com/sveltejs/cli/pull/587)) + +## 0.8.8 +### Patch Changes + + +- fix(vitest): `mount(...)` not available ([#584](https://github.com/sveltejs/cli/pull/584)) + +## 0.8.7 +### Patch Changes + + +- fix: removed unused import in `drizzle` schema to fix lint ([#571](https://github.com/sveltejs/cli/pull/571)) + + +- fix: add null check for `kit` in the `drizzle` add-on's setup ([#574](https://github.com/sveltejs/cli/pull/574)) + +## 0.8.6 +### Patch Changes + + +- fix: account for Node `current` releases with even majors when resolving `@types/node` version ([#565](https://github.com/sveltejs/cli/pull/565)) + +## 0.8.5 +### Patch Changes + + +- fix: directory selection placeholder value was taken as folder path ([#564](https://github.com/sveltejs/cli/pull/564)) + +## 0.8.4 +### Patch Changes + + +- fix: lucia require user redirect moved to auth guard function ([#558](https://github.com/sveltejs/cli/pull/558)) + + +- feat: expose `runsAfter` to add-ons ([#554](https://github.com/sveltejs/cli/pull/554)) + +## 0.8.3 +### Patch Changes + + +- fix: always add `storybook` after all other add-ons ([#547](https://github.com/sveltejs/cli/pull/547)) + + +- security: upgrade vite to avoid CVE-2025-32395 ([#548](https://github.com/sveltejs/cli/pull/548)) + +## 0.8.2 +### Patch Changes + + +- fix: rename Cloudflare adapter option from `cloudflare-pages` to `cloudflare` ([#545](https://github.com/sveltejs/cli/pull/545)) + + +- chore: update `adapter-auto` ([#542](https://github.com/sveltejs/cli/pull/542)) + + +- fix: add `@types/node` as a dev dependency to the `drizzle` and `storybook` add-ons ([#541](https://github.com/sveltejs/cli/pull/541)) + + +- fix: use connection pool when using mysql2 with `drizzle` ([#537](https://github.com/sveltejs/cli/pull/537)) + +## 0.8.1 +### Patch Changes + + +- feat: adds `--install ` flag to `create` and `add` ([#531](https://github.com/sveltejs/cli/pull/531)) + + +- fix: warn on an unparsable `.prettierrc` config file ([#527](https://github.com/sveltejs/cli/pull/527)) + + +- chore: remove redundant `ignores` property in `eslint` config ([#533](https://github.com/sveltejs/cli/pull/533)) + +## 0.8.0 +### Minor Changes + + +- feat: remove `adapter-cloudflare-workers` and upgrade other adapters ([#520](https://github.com/sveltejs/cli/pull/520)) + + +### Patch Changes + + +- security: Upgrade Vite to avoid CVE-2025-31125 ([#517](https://github.com/sveltejs/cli/pull/517)) + + +- security: upgrade vite to avoid CVE-2025-31486 ([#522](https://github.com/sveltejs/cli/pull/522)) + ## 0.7.2 ### Patch Changes diff --git a/packages/cli/commands/add/fetch-packages.ts b/packages/cli/commands/add/fetch-packages.ts index 5bc86bb5..35e8144a 100644 --- a/packages/cli/commands/add/fetch-packages.ts +++ b/packages/cli/commands/add/fetch-packages.ts @@ -3,7 +3,8 @@ import path from 'node:path'; import { createGunzip } from 'node:zlib'; import { fileURLToPath } from 'node:url'; import { pipeline } from 'node:stream/promises'; -import { extract } from 'tar-fs'; +// TODO: replace tar-fs +// import { extract } from 'tar-fs'; import type { AddonWithoutExplicitArgs } from '@sveltejs/cli-core'; // path to the `node_modules` directory of `sv` @@ -65,15 +66,15 @@ export async function downloadPackage(options: DownloadOptions): Promise { - // file paths from the tarball will always have a `package/` prefix, - // so we'll need to replace it with the name of the package - header.name = header.name.replace('package', pkg.name); - return header; - } - }) + createGunzip() + // extract(NODE_MODULES, { + // map: (header) => { + // // file paths from the tarball will always have a `package/` prefix, + // // so we'll need to replace it with the name of the package + // header.name = header.name.replace('package', pkg.name); + // return header; + // } + // }) ); const { default: details } = await import(pkg.name); diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index bd11bf73..cc2d85b4 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -4,8 +4,8 @@ import process from 'node:process'; import pc from 'picocolors'; import * as v from 'valibot'; import * as pkg from 'empathic/package'; -import * as p from '@sveltejs/clack-prompts'; -import { Command, Option } from 'commander'; +import * as p from '@clack/prompts'; +import { Command } from 'commander'; import { officialAddons, getAddonDetails, @@ -19,48 +19,159 @@ import { createWorkspace } from './workspace.ts'; import { formatFiles, getHighlighter } from './utils.ts'; import { Directive, downloadPackage, getPackageJSON } from './fetch-packages.ts'; import { - addPnpmBuildDependendencies, + addPnpmBuildDependencies, + AGENT_NAMES, installDependencies, + installOption, packageManagerPrompt } from '../../utils/package-manager.ts'; import { getGlobalPreconditions } from './preconditions.ts'; import { type AddonMap, applyAddons, setupAddons } from '../../lib/install.ts'; const aliases = officialAddons.map((c) => c.alias).filter((v) => v !== undefined); -const addonsOptions = getAddonOptionFlags(); +const addonOptions = getAddonOptionFlags(); const communityDetails: AddonWithoutExplicitArgs[] = []; -const OptionFlagSchema = v.optional(v.array(v.string())); - -const addonOptionFlags = addonsOptions.reduce( - (flags, opt) => Object.assign(flags, { [opt.attributeName()]: OptionFlagSchema }), - {} -); - const AddonsSchema = v.array(v.string()); -const AddonOptionFlagsSchema = v.object(addonOptionFlags); const OptionsSchema = v.strictObject({ cwd: v.string(), - install: v.boolean(), + install: v.union([v.boolean(), v.picklist(AGENT_NAMES)]), preconditions: v.boolean(), community: v.optional(v.union([AddonsSchema, v.boolean()])), - ...AddonOptionFlagsSchema.entries + addons: v.record(v.string(), v.optional(v.array(v.string()))) }); type Options = v.InferOutput; +type AddonArgs = { id: string; options: string[] | undefined }; + // infers the workspace cwd if a `package.json` resides in a parent directory const defaultPkgPath = pkg.up(); const defaultCwd = defaultPkgPath ? path.dirname(defaultPkgPath) : undefined; - export const add = new Command('add') .description('applies specified add-ons into a project') - .argument('[add-on...]', 'add-ons to install') + .argument('[add-on...]', `add-ons to install`, (value, prev: AddonArgs[] = []) => { + const [addonId, optionFlags] = value.split('=', 2); + + // validates that there are no repeated add-ons (e.g. `sv add foo=demo:yes foo=demo:no`) + const repeatedAddons = prev.find(({ id }) => id === addonId); + if (repeatedAddons) { + console.error(`Malformed arguments: Add-on '${addonId}' is repeated multiple times.`); + process.exit(1); + } + + // occurs when an `=` isn't present (e.g. `sv add foo`) + if (optionFlags === undefined) { + prev.push({ id: addonId, options: undefined }); + return prev; + } + + // validates that the options are relatively well-formed. + // occurs when no or is specified (e.g. `sv add foo=demo`). + if (optionFlags.length > 0 && !/.+:.*/.test(optionFlags)) { + console.error( + `Malformed arguments: An add-on's option in '${value}' is missing it's option name or value (e.g. 'addon=option:value').` + ); + process.exit(1); + } + + // parses the option flags into a array of `:` strings + const options: string[] = optionFlags.match(/[^+]*:[^:]*(?=\+|$)/g) ?? []; + + prev.push({ id: addonId, options }); + return prev; + }) .option('-C, --cwd ', 'path to working directory', defaultCwd) - .option('--no-install', 'skip installing dependencies') .option('--no-preconditions', 'skip validating preconditions') + .option('--no-install', 'skip installing dependencies') + .addOption(installOption) //.option('--community [add-on...]', 'community addons to install') - .configureHelp(common.helpConfig) - .action((addonArgs, opts) => { + .configureHelp({ + ...common.helpConfig, + formatHelp(cmd, helper) { + const termWidth = helper.padWidth(cmd, helper); + const helpWidth = helper.helpWidth ?? 80; // in case prepareContext() was not called + + function callFormatItem(term: string, description: string) { + return helper.formatItem(term, termWidth, description, helper); + } + + // Usage + let output = [ + `${helper.styleTitle('Usage:')} ${helper.styleUsage(helper.commandUsage(cmd))}`, + '' + ]; + + // Description + const commandDescription = helper.commandDescription(cmd); + if (commandDescription.length > 0) { + output = output.concat([ + helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth), + '' + ]); + } + + // Arguments + const argumentList = helper.visibleArguments(cmd).map((argument) => { + return callFormatItem( + helper.styleArgumentTerm(helper.argumentTerm(argument)), + helper.styleArgumentDescription(helper.argumentDescription(argument)) + ); + }); + if (argumentList.length > 0) { + output = output.concat([helper.styleTitle('Arguments:'), ...argumentList, '']); + } + + // Addon Options + const addonList = addonOptions.map((option) => { + // const description = `${pc.dim(`(preset: ${option.preset})`)}\n${option.choices}`; + const description = option.choices; + return callFormatItem( + helper.styleArgumentTerm(option.id), + helper.styleArgumentDescription(description) + ); + }); + if (addonList.length > 0) { + output = output.concat([helper.styleTitle('Add-On Options:'), ...addonList, '']); + } + + // Options + const optionList = helper.visibleOptions(cmd).map((option) => { + return callFormatItem( + helper.styleOptionTerm(helper.optionTerm(option)), + helper.styleOptionDescription(helper.optionDescription(option)) + ); + }); + if (optionList.length > 0) { + output = output.concat([helper.styleTitle('Options:'), ...optionList, '']); + } + + if (helper.showGlobalOptions) { + const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => { + return callFormatItem( + helper.styleOptionTerm(helper.optionTerm(option)), + helper.styleOptionDescription(helper.optionDescription(option)) + ); + }); + if (globalOptionList.length > 0) { + output = output.concat([helper.styleTitle('Global Options:'), ...globalOptionList, '']); + } + } + + // Commands + const commandList = helper.visibleCommands(cmd).map((cmd) => { + return callFormatItem( + helper.styleSubcommandTerm(helper.subcommandTerm(cmd)), + helper.styleSubcommandDescription(helper.subcommandDescription(cmd)) + ); + }); + if (commandList.length > 0) { + output = output.concat([helper.styleTitle('Commands:'), ...commandList, '']); + } + + return output.join('\n'); + } + }) + .action((addonArgs: AddonArgs[], opts) => { // validate workspace if (opts.cwd === undefined) { console.error( @@ -75,29 +186,26 @@ export const add = new Command('add') process.exit(1); } - const specifiedAddons = v.parse(AddonsSchema, addonArgs); - const options = v.parse(OptionsSchema, opts); const addonIds = officialAddons.map((addon) => addon.id); - const invalidAddons = specifiedAddons.filter( - (a) => !addonIds.includes(a) && !aliases.includes(a) - ); + const invalidAddons = addonArgs + .filter(({ id }) => !addonIds.includes(id) && !aliases.includes(id)) + .map(({ id }) => id); if (invalidAddons.length > 0) { console.error(`Invalid add-ons specified: ${invalidAddons.join(', ')}`); process.exit(1); } - const selectedAddons = transformAliases(specifiedAddons); + const options = v.parse(OptionsSchema, { ...opts, addons: {} }); + const selectedAddons = transformAliases(addonArgs); + selectedAddons.forEach((addon) => (options.addons[addon.id] = addon.options)); + common.runCommand(async () => { - const { nextSteps } = await runAddCommand(options, selectedAddons); - if (nextSteps) p.box(nextSteps, 'Next steps'); + const selectedAddonIds = selectedAddons.map(({ id }) => id); + const { nextSteps } = await runAddCommand(options, selectedAddonIds); + if (nextSteps) p.note(nextSteps, 'Next steps', { format: (line) => line }); }); }); -// adds addon specific option flags to the `add` command -for (const option of addonsOptions) { - add.addOption(option); -} - type SelectedAddon = { type: 'official' | 'community'; addon: AddonWithoutExplicitArgs }; export async function runAddCommand( options: Options, @@ -116,11 +224,9 @@ export async function runAddCommand( const community: AddonOption = {}; // apply specified options from flags - for (const addonOption of addonsOptions) { - const addonId = addonOption.name() as keyof Options; - // if the add-on flag contains a `-`, it'll be camelcased (e.g. `sveltekit-adapter` is `sveltekitAdapter`) - const aliased = addonOption.attributeName() as keyof Options; - const specifiedOptions = (options[addonId] || options[aliased]) as string[] | undefined; + for (const addonOption of addonOptions) { + const addonId = addonOption.id; + const specifiedOptions = options.addons[addonId]; if (!specifiedOptions) continue; const details = getAddonDetails(addonId); @@ -131,42 +237,44 @@ export async function runAddCommand( official[addonId] ??= {}; const optionEntries = Object.entries(details.options); - for (const specifiedOption of specifiedOptions) { - // we'll skip empty string and `none` options so that default values can be applied later - if (!specifiedOption || specifiedOption === 'none') continue; - - // figure out which option it belongs to - const optionEntry = optionEntries.find(([id, question]) => { - if (question.type === 'boolean') { - return id === specifiedOption || `no-${id}` === specifiedOption; - } - if (question.type === 'select' || question.type === 'multiselect') { - return question.options.some((o) => o.value === specifiedOption); - } - }); + for (const option of specifiedOptions) { + let [optionId, optionValue] = option.split(':', 2); + + // validates that the option exists + const optionEntry = optionEntries.find( + ([id, question]) => id === optionId || question.group === optionId + ); if (!optionEntry) { const { choices } = getOptionChoices(details); throw new Error( - `Invalid '--${addonId}' option: '${specifiedOption}'\nAvailable options: ${choices.join(', ')}` + `Invalid '${addonId}' option: '${option}'\nAvailable options: ${choices.join(', ')}` ); } const [questionId, question] = optionEntry; + // multiselect options can be specified with a `none` option, which equates to an empty string + if (question.type === 'multiselect' && optionValue === 'none') optionValue = ''; + // validate that there are no conflicts let existingOption = official[addonId][questionId]; if (existingOption !== undefined) { if (typeof existingOption === 'boolean') { - // need to transform the boolean back to `no-{id}` or `{id}` - existingOption = existingOption ? questionId : `no-${questionId}`; + // need to transform the boolean back to `yes` or `no` + existingOption = existingOption ? 'yes' : 'no'; } throw new Error( - `Conflicting '--${addonId}' option: '${specifiedOption}' conflicts with '${existingOption}'` + `Conflicting '${addonId}' option: '${option}' conflicts with '${questionId}:${existingOption}'` ); } - official[addonId][questionId] = - question.type === 'boolean' ? !specifiedOption.startsWith('no-') : specifiedOption; + if (question.type === 'boolean') { + official[addonId][questionId] = optionValue === 'yes'; + } else if (question.type === 'number') { + official[addonId][questionId] = Number(optionValue); + } else { + official[addonId][questionId] = optionValue; + } } // apply defaults to unspecified options @@ -175,12 +283,10 @@ export async function runAddCommand( if (question.condition?.(official[addonId]) !== false) { official[addonId][id] ??= question.default; } else { - // we'll also error out if they specified an option that is incompatible with other options. - // (e.g. the client isn't available for a given database `--drizzle sqlite mysql2`) + // we'll also error out if a specified option is incompatible with other options. + // (e.g. `libsql` isn't a valid client for a `mysql` database: `sv add drizzle=database:mysql2,client:libsql`) if (official[addonId][id] !== undefined) { - throw new Error( - `Incompatible '--${addonId}' option specified: '${official[addonId][id]}'` - ); + throw new Error(`Incompatible '${addonId}' option specified: '${official[addonId][id]}'`); } } } @@ -281,7 +387,8 @@ export async function runAddCommand( // prepare official addons let workspace = await createWorkspace({ cwd: options.cwd }); - const addonSetupResults = setupAddons(officialAddons, workspace); + const setups = selectedAddons.length ? selectedAddons.map(({ addon }) => addon) : officialAddons; + const addonSetupResults = setupAddons(setups, workspace); // prompt which addons to apply if (selectedAddons.length === 0) { @@ -353,7 +460,7 @@ export async function runAddCommand( .map(({ name, message }) => pc.yellow(`${name} (${message})`)) .join('\n- '); - p.note(`- ${message}`, 'Preconditions not met'); + p.note(`- ${message}`, 'Preconditions not met', { format: (line) => line }); const force = await p.confirm({ message: 'Preconditions failed. Do you wish to continue?', @@ -449,12 +556,13 @@ export async function runAddCommand( // prompt for package manager and install dependencies let packageManager: PackageManager | undefined; if (options.install) { - packageManager = await packageManagerPrompt(options.cwd); + packageManager = + options.install === true ? await packageManagerPrompt(options.cwd) : options.install; if (packageManager) { workspace.packageManager = packageManager; - addPnpmBuildDependendencies(workspace.cwd, packageManager, [ + addPnpmBuildDependencies(workspace.cwd, packageManager, [ 'esbuild', ...addonPnpmBuildDependencies ]); @@ -506,21 +614,22 @@ export async function runAddCommand( /** * Dedupes and transforms aliases into their respective addon id */ -function transformAliases(ids: string[]): string[] { - const set = new Set(); - for (const id of ids) { - if (aliases.includes(id)) { - const addon = officialAddons.find((a) => a.alias === id)!; - set.add(addon.id); +function transformAliases(addons: AddonArgs[]): AddonArgs[] { + const set = new Map(); + + for (const addon of addons) { + if (aliases.includes(addon.id)) { + const officialAddon = officialAddons.find((a) => a.alias === addon.id)!; + set.set(officialAddon.id, { id: officialAddon.id, options: addon.options }); } else { - set.add(id); + set.set(addon.id, addon); } } - return Array.from(set); + return Array.from(set.values()); } -function getAddonOptionFlags(): Option[] { - const options: Option[] = []; +function getAddonOptionFlags() { + const options: Array<{ id: string; choices: string; preset: string }> = []; for (const addon of officialAddons) { const id = addon.id; const details = getAddonDetails(id); @@ -531,19 +640,7 @@ function getAddonOptionFlags(): Option[] { .map(([group, choices]) => `${pc.dim(`${group}:`)} ${choices.join(', ')}`) .join('\n'); const preset = defaults.join(', ') || 'none'; - const option = new Option( - `--${id} [options...]`, - `${id} add-on options ${pc.dim(`(preset: ${preset})`)}\n${choices}` - ) - // presets are applied when `--{addonName}` is specified with no options - .preset(preset) - .argParser((value, prev: string[]) => { - prev ??= []; - prev = prev.concat(value.split(/\s|,/)); - return prev; - }); - - options.push(option); + options.push({ id, choices, preset }); } return options; } @@ -557,7 +654,7 @@ function getOptionChoices(details: AddonWithoutExplicitArgs) { let values: string[] = []; const applyDefault = question.condition?.(options) !== false; if (question.type === 'boolean') { - values = [id, `no-${id}`]; + values = ['yes', `no`]; if (applyDefault) { options[id] = question.default; defaults.push((question.default ? values[0] : values[1])!); @@ -577,9 +674,15 @@ function getOptionChoices(details: AddonWithoutExplicitArgs) { defaults.push(...question.default); } } + if (question.type === 'string' || question.type === 'number') { + values = ['']; + if (applyDefault) { + options[id] = question.default; + defaults.push(question.default.toString()); + } + } choices.push(...values); - // we'll fallback to the question's id const groupId = question.group ?? id; groups[groupId] ??= []; diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts index a42b1893..5d259c31 100644 --- a/packages/cli/commands/create.ts +++ b/packages/cli/commands/create.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import process from 'node:process'; import * as v from 'valibot'; import { Command, Option } from 'commander'; -import * as p from '@sveltejs/clack-prompts'; +import * as p from '@clack/prompts'; import pc from 'picocolors'; import { create as createKit, @@ -15,9 +15,11 @@ import * as common from '../utils/common.ts'; import { runAddCommand } from './add/index.ts'; import { detect, resolveCommand, type AgentName } from 'package-manager-detector'; import { - addPnpmBuildDependendencies, + addPnpmBuildDependencies, + AGENT_NAMES, getUserAgent, installDependencies, + installOption, packageManagerPrompt } from '../utils/package-manager.ts'; @@ -40,7 +42,7 @@ const OptionsSchema = v.strictObject({ v.transform((lang) => langMap[String(lang)]) ), addOns: v.boolean(), - install: v.boolean(), + install: v.union([v.boolean(), v.picklist(AGENT_NAMES)]), template: v.optional(v.picklist(templateChoices)) }); type Options = v.InferOutput; @@ -54,6 +56,7 @@ export const create = new Command('create') .option('--no-types') .option('--no-add-ons', 'skips interactive add-on installer') .option('--no-install', 'skip installing dependencies') + .addOption(installOption) .configureHelp(common.helpConfig) .action((projectPath, opts) => { const cwd = v.parse(ProjectPathSchema, projectPath); @@ -90,8 +93,8 @@ export const create = new Command('create') `Stuck? Visit us at ${pc.cyan('https://svelte.dev/chat')}` ]; - p.box(steps.join('\n'), 'Project next steps'); - if (addOnNextSteps) p.box(addOnNextSteps, 'Add-on next steps'); + p.note(steps.join('\n'), 'Project next steps', { format: (line) => line }); + if (addOnNextSteps) p.note(addOnNextSteps, 'Add-on next steps', { format: (line) => line }); }); }); @@ -164,29 +167,36 @@ async function createProject(cwd: ProjectPath, options: Options) { let packageManager: AgentName | undefined | null; let addOnNextSteps: string | undefined; - const installDeps = async () => { - packageManager = await packageManagerPrompt(projectPath); - addPnpmBuildDependendencies(projectPath, packageManager, ['esbuild']); + + const installDeps = async (install: true | AgentName) => { + packageManager = install === true ? await packageManagerPrompt(projectPath) : install; + addPnpmBuildDependencies(projectPath, packageManager, ['esbuild']); if (packageManager) await installDependencies(packageManager, projectPath); }; if (options.addOns) { // `runAddCommand` includes installing dependencies const { nextSteps, packageManager: pm } = await runAddCommand( - { cwd: projectPath, install: options.install, preconditions: false, community: [] }, + { + cwd: projectPath, + install: options.install, + preconditions: false, + community: [], + addons: {} + }, [] ); packageManager = pm; addOnNextSteps = nextSteps; } else if (options.install) { // `--no-add-ons` was set, so we'll prompt to install deps manually - await installDeps(); + await installDeps(options.install); } // no add-ons were selected (which means the install prompt was skipped in `runAddCommand`), // so we'll prompt to install if (packageManager === null && options.install) { - await installDeps(); + await installDeps(options.install); } return { directory: projectPath, addOnNextSteps, packageManager }; diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 03932917..958a8ee4 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -9,7 +9,7 @@ import type { AddonWithoutExplicitArgs } from '@sveltejs/cli-core'; import pc from 'picocolors'; -import * as p from '@sveltejs/clack-prompts'; +import * as p from '@clack/prompts'; import { exec, NonZeroExitError } from 'tinyexec'; import { resolveCommand } from 'package-manager-detector'; import { TESTING } from '../utils/env.ts'; @@ -87,11 +87,15 @@ export function setupAddons( const addonSetupResults: Record = {}; for (const addon of addons) { - const setupResult: AddonSetupResult = { unsupported: [], dependsOn: [] }; + const setupResult: AddonSetupResult = { unsupported: [], dependsOn: [], runsAfter: [] }; addon.setup?.({ ...workspace, - dependsOn: (name) => setupResult.dependsOn.push(name), - unsupported: (reason) => setupResult.unsupported.push(reason) + dependsOn: (name) => { + setupResult.dependsOn.push(name); + setupResult.runsAfter.push(name); + }, + unsupported: (reason) => setupResult.unsupported.push(reason), + runsAfter: (name) => setupResult.runsAfter.push(name) }); addonSetupResults[addon.id] = setupResult; } @@ -181,10 +185,10 @@ async function runAddon({ addon, multiple, workspace }: RunAddon) { } // orders addons by putting addons that don't require any other addon in the front. -// This is a drastic simplification, as this could still cause some inconvenient cituations, -// but works for now in contrary to the previouse implementation +// This is a drastic simplification, as this could still cause some inconvenient circumstances, +// but works for now in contrary to the previous implementation function orderAddons(addons: Array>, setupResults: Record) { - return addons.sort( - (a, b) => setupResults[a.id]?.dependsOn?.length - setupResults[b.id]?.dependsOn?.length - ); + return addons.sort((a, b) => { + return setupResults[a.id]?.runsAfter?.length - setupResults[b.id]?.runsAfter?.length; + }); } diff --git a/packages/cli/lib/testing.ts b/packages/cli/lib/testing.ts index 101214bf..98f5cdae 100644 --- a/packages/cli/lib/testing.ts +++ b/packages/cli/lib/testing.ts @@ -6,7 +6,7 @@ import { exec } from 'tinyexec'; import { create } from '@sveltejs/create'; import pstree, { type PS } from 'ps-tree'; -export { addPnpmBuildDependendencies } from '../utils/package-manager.ts'; +export { addPnpmBuildDependencies } from '../utils/package-manager.ts'; export type ProjectVariant = 'kit-js' | 'kit-ts' | 'vite-js' | 'vite-ts'; const TEMPLATES_DIR = '.templates'; diff --git a/packages/cli/package.json b/packages/cli/package.json index 71ab8a52..15a4aa53 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.7.2", + "version": "0.8.10", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT", @@ -30,21 +30,19 @@ } }, "devDependencies": { + "@clack/prompts": "^1.0.0-alpha.1", "@sveltejs/addons": "workspace:*", - "@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": "^13.0.0", + "commander": "^13.1.0", "degit": "^2.8.4", "empathic": "^1.0.0", - "package-manager-detector": "^0.2.7", + "package-manager-detector": "^0.2.11", "picocolors": "^1.1.1", "ps-tree": "^1.2.0", - "tar-fs": "^3.0.6", - "tinyexec": "^0.3.1", + "tinyexec": "^0.3.2", "valibot": "^0.41.0" }, "keywords": [ diff --git a/packages/cli/utils/common.ts b/packages/cli/utils/common.ts index 935024bf..b2282f97 100644 --- a/packages/cli/utils/common.ts +++ b/packages/cli/utils/common.ts @@ -1,6 +1,6 @@ import pc from 'picocolors'; import pkg from '../package.json' with { type: 'json' }; -import * as p from '@sveltejs/clack-prompts'; +import * as p from '@clack/prompts'; import type { Argument, HelpConfiguration, Option } from 'commander'; import { UnsupportedError } from './errors.ts'; import process from 'node:process'; diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index f747dedd..f53e4878 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -3,7 +3,8 @@ import path from 'node:path'; import process from 'node:process'; import * as find from 'empathic/find'; import { exec } from 'tinyexec'; -import * as p from '@sveltejs/clack-prompts'; +import { Option } from 'commander'; +import * as p from '@clack/prompts'; import { AGENTS, COMMANDS, @@ -13,10 +14,15 @@ import { } from 'package-manager-detector'; import { parseJson } from '@sveltejs/cli-core/parsers'; -const agents = AGENTS.filter((agent): agent is AgentName => !agent.includes('@')); -const agentOptions: PackageManagerOptions = agents.map((pm) => ({ value: pm, label: pm })); +export const AGENT_NAMES = AGENTS.filter((agent): agent is AgentName => !agent.includes('@')); +const agentOptions: PackageManagerOptions = AGENT_NAMES.map((pm) => ({ value: pm, label: pm })); agentOptions.unshift({ label: 'None', value: undefined }); +export const installOption = new Option( + '--install ', + 'installs dependencies with a specified package manager' +).choices(AGENT_NAMES); + type PackageManagerOptions = Array<{ value: AgentName | undefined; label: AgentName | 'None' }>; export async function packageManagerPrompt(cwd: string): Promise { const detected = await detect({ cwd }); @@ -40,7 +46,12 @@ export async function packageManagerPrompt(cwd: string): Promise { - const task = p.taskLog(`Installing dependencies with ${agent}...`); + const task = p.taskLog({ + title: `Installing dependencies with ${agent}...`, + limit: Math.ceil(process.stdout.rows / 2), + spacing: 0, + retainLog: true + }); try { const { command, args } = constructCommand(COMMANDS[agent].install, [])!; @@ -50,17 +61,17 @@ export async function installDependencies(agent: AgentName, cwd: string): Promis }); proc.process?.stdout?.on('data', (data) => { - task.text = data; + task.message(data.toString(), { raw: true }); }); proc.process?.stderr?.on('data', (data) => { - task.text = data; + task.message(data.toString(), { raw: true }); }); await proc; task.success('Successfully installed dependencies'); } catch { - task.fail('Failed to install dependencies'); + task.error('Failed to install dependencies'); p.cancel('Operation failed.'); process.exit(2); } @@ -76,7 +87,7 @@ export function getUserAgent(): AgentName | undefined { return AGENTS.includes(name) ? name : undefined; } -export function addPnpmBuildDependendencies( +export function addPnpmBuildDependencies( cwd: string, packageManager: AgentName | null | undefined, allowedPackages: string[] diff --git a/packages/core/addon/config.ts b/packages/core/addon/config.ts index be36f777..fbce3775 100644 --- a/packages/core/addon/config.ts +++ b/packages/core/addon/config.ts @@ -37,6 +37,7 @@ export type Addon = { workspace: Workspace & { dependsOn: (name: string) => void; unsupported: (reason: string) => void; + runsAfter: (addonName: string) => void; } ) => MaybePromise; run: (workspace: Workspace & { sv: SvApi }) => MaybePromise; @@ -59,7 +60,7 @@ export function defineAddon(config: Addon): return config; } -export type AddonSetupResult = { dependsOn: string[]; unsupported: string[] }; +export type AddonSetupResult = { dependsOn: string[]; unsupported: string[]; runsAfter: string[] }; export type AddonWithoutExplicitArgs = Addon>; export type AddonConfigWithoutExplicitArgs = Addon>; diff --git a/packages/core/addon/options.ts b/packages/core/addon/options.ts index b9f3a262..94c25233 100644 --- a/packages/core/addon/options.ts +++ b/packages/core/addon/options.ts @@ -6,14 +6,14 @@ export type BooleanQuestion = { export type StringQuestion = { type: 'string'; default: string; - validate?: (value: string) => string | undefined; + validate?: (value: string | undefined) => string | Error | undefined; placeholder?: string; }; export type NumberQuestion = { type: 'number'; default: number; - validate?: (value: string) => string | undefined; + validate?: (value: string | undefined) => string | Error | undefined; placeholder?: string; }; diff --git a/packages/core/index.ts b/packages/core/index.ts index 9ba5b086..e22448cb 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -1,5 +1,5 @@ export { defineAddon, defineAddonOptions } from './addon/config.ts'; -export { log } from '@sveltejs/clack-prompts'; +export { log } from '@clack/prompts'; export { default as colors } from 'picocolors'; export { default as dedent } from 'dedent'; export * as utils from './utils.ts'; @@ -9,4 +9,4 @@ export type * from './addon/options.ts'; export type * from './addon/config.ts'; export type * from './addon/workspace.ts'; -export { Walker } from '@sveltejs/ast-tooling'; +export { Walker } from './tooling/index.ts'; diff --git a/packages/core/package.json b/packages/core/package.json index 4de33a4b..c60e78e9 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -41,15 +41,23 @@ "default": "./dist/parsers.js" } }, - "dependencies": { - "@sveltejs/ast-tooling": "workspace:*" - }, "devDependencies": { - "@sveltejs/clack-prompts": "workspace:*", + "@clack/prompts": "^1.0.0-alpha.1", + "@sveltejs/acorn-typescript": "^1.0.1", + "@types/estree": "^1.0.6", + "acorn": "^8.14.0", "decircular": "^1.0.0", "dedent": "^1.5.3", - "magic-string": "^0.30.15", - "picocolors": "^1.1.1" + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "esrap": "^1.4.5", + "htmlparser2": "^9.1.0", + "magic-string": "^0.30.17", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "silver-fleece": "^1.2.1", + "zimmerframe": "^1.1.2" }, "keywords": [ "create", diff --git a/packages/core/tests/css/index.ts b/packages/core/tests/css/index.ts index d9d20386..6548abf7 100644 --- a/packages/core/tests/css/index.ts +++ b/packages/core/tests/css/index.ts @@ -3,7 +3,7 @@ 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'; +import { parseCss, serializeCss } from '../../tooling/index.ts'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); diff --git a/packages/core/tests/html/index.ts b/packages/core/tests/html/index.ts index b5e33cd3..d327848b 100644 --- a/packages/core/tests/html/index.ts +++ b/packages/core/tests/html/index.ts @@ -3,7 +3,7 @@ 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'; +import { parseHtml, serializeHtml } from '../../tooling/index.ts'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); diff --git a/packages/core/tests/js/common/expression-from-string/output.ts b/packages/core/tests/js/common/expression-from-string/output.ts new file mode 100644 index 00000000..a5aea556 --- /dev/null +++ b/packages/core/tests/js/common/expression-from-string/output.ts @@ -0,0 +1 @@ +export default defineConfig({ path: 'some/string/as/path.js', valid: true }); diff --git a/packages/core/tests/js/common/expression-from-string/run.ts b/packages/core/tests/js/common/expression-from-string/run.ts new file mode 100644 index 00000000..f831db6c --- /dev/null +++ b/packages/core/tests/js/common/expression-from-string/run.ts @@ -0,0 +1,13 @@ +import { common, exports, type AstTypes } from '@sveltejs/cli-core/js'; + +export function run(ast: AstTypes.Program): void { + exports.defaultExport( + ast, + common.expressionFromString(` + defineConfig({ + path: "some/string/as/path.js", + valid: true + }) + `) + ); +} diff --git a/packages/core/tests/js/imports/reverse-order/output.ts b/packages/core/tests/js/imports/reverse-order/output.ts new file mode 100644 index 00000000..8f1966b8 --- /dev/null +++ b/packages/core/tests/js/imports/reverse-order/output.ts @@ -0,0 +1,5 @@ +import * as foo from 'p1'; +import * as bar from './p2'; +import { namedTwo } from 'p3'; +import 'p4'; +import MyPackage from 'p5'; diff --git a/packages/core/tests/js/imports/reverse-order/run.ts b/packages/core/tests/js/imports/reverse-order/run.ts new file mode 100644 index 00000000..d786161b --- /dev/null +++ b/packages/core/tests/js/imports/reverse-order/run.ts @@ -0,0 +1,16 @@ +import { imports, type AstTypes } from '@sveltejs/cli-core/js'; + +export function run(ast: AstTypes.Program): void { + // imports should be added HERE in the reverse order + // so that the imports are added from the top (unshift) + imports.addDefault(ast, 'p5', 'MyPackage'); + imports.addEmpty(ast, 'p4'); + imports.addNamed(ast, 'p3', { namedTwo: 'namedTwo' }, false); + imports.addNamespace(ast, './p2', 'bar'); + imports.addNamespace(ast, 'p1', 'foo'); + + // adding the same import twice should not produce two imports + imports.addNamespace(ast, './p2', 'bar'); + // adding the same import for the 3rd time. Only the first one should be kept. + imports.addNamespace(ast, './p2', 'bar'); +} diff --git a/packages/core/tests/js/index.ts b/packages/core/tests/js/index.ts index 6bcfda9f..c7f2021e 100644 --- a/packages/core/tests/js/index.ts +++ b/packages/core/tests/js/index.ts @@ -1,17 +1,12 @@ 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'; +import { parseScript, serializeScript } from '../../tooling/index.ts'; 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)); @@ -27,9 +22,9 @@ for (const categoryDirectory of categoryDirectories) { const module = await import(`./${categoryDirectory}/${testName}/run.ts`); module.run(ast); - const output = serializeScript(ast, input); - const formattedOutput = await prettier.format(output, prettierConfig); - await expect(formattedOutput).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`); + let output = serializeScript(ast, input); + if (!output.endsWith('\n')) output += '\n'; + await expect(output).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`); }); } }); diff --git a/packages/ast-tooling/tests/utils.ts b/packages/core/tests/utils.ts similarity index 95% rename from packages/ast-tooling/tests/utils.ts rename to packages/core/tests/utils.ts index fd65346d..a2a4405b 100644 --- a/packages/ast-tooling/tests/utils.ts +++ b/packages/core/tests/utils.ts @@ -1,7 +1,12 @@ import { expect, test } from 'vitest'; import dedent from 'dedent'; -import { guessIndentString, guessQuoteStyle } from '../utils.ts'; -import { parseScript, serializeScript, type AstTypes } from '../index.ts'; +import { + parseScript, + serializeScript, + guessIndentString, + guessQuoteStyle, + type AstTypes +} from '../tooling/index.ts'; test('guessIndentString - one tab', () => { const code = dedent` diff --git a/packages/core/tooling/css/index.ts b/packages/core/tooling/css/index.ts index f3a460ca..ab69813e 100644 --- a/packages/core/tooling/css/index.ts +++ b/packages/core/tooling/css/index.ts @@ -1,11 +1,4 @@ -import { - Declaration, - Rule, - AtRule, - Comment, - type CssAst, - type CssChildNode -} from '@sveltejs/ast-tooling'; +import { Declaration, Rule, AtRule, Comment, type CssAst, type CssChildNode } from '../index.ts'; export type { CssAst }; diff --git a/packages/core/tooling/html/index.ts b/packages/core/tooling/html/index.ts index a02e689a..94dcd881 100644 --- a/packages/core/tooling/html/index.ts +++ b/packages/core/tooling/html/index.ts @@ -5,7 +5,7 @@ import { HtmlElement, HtmlElementType, parseHtml -} from '@sveltejs/ast-tooling'; +} from '../index.ts'; import { addFromString } from '../js/common.ts'; export { HtmlElement, HtmlElementType }; diff --git a/packages/ast-tooling/index.ts b/packages/core/tooling/index.ts similarity index 71% rename from packages/ast-tooling/index.ts rename to packages/core/tooling/index.ts index 27cc72cd..27e41cbe 100644 --- a/packages/ast-tooling/index.ts +++ b/packages/core/tooling/index.ts @@ -1,3 +1,5 @@ +import * as Walker from 'zimmerframe'; +import type { TsEstree } from './js/ts-estree.ts'; import { Document, Element, type ChildNode } from 'domhandler'; import { ElementType, parseDocument } from 'htmlparser2'; import serializeDom from 'dom-serializer'; @@ -11,21 +13,10 @@ import { type ChildNode as CssChildNode } from 'postcss'; import * as fleece from 'silver-fleece'; -import * as Walker from 'zimmerframe'; -import type { TsEstree } from './ts-estree.ts'; -import { guessIndentString, guessQuoteStyle } from './utils.ts'; import { print as esrapPrint } from 'esrap'; import * as acorn from 'acorn'; import { tsPlugin } from '@sveltejs/acorn-typescript'; -/** - * Most of the AST tooling is pretty big in bundle size and bundling takes forever. - * Nevertheless bundling of these tools seems smart, as they add many dependencies to each install. - * In order to avoid long bundling during development, all of the AST tools have been extracted - * into this separate package and are bundled only here. This package has been marked as external - * and will not be bundled into all other projects / bundles. - */ - export { // html Document as HtmlDocument, @@ -61,7 +52,7 @@ export type { export function parseScript(content: string): TsEstree.Program { const comments: TsEstree.Comment[] = []; - const acornTs = acorn.Parser.extend(tsPlugin({ allowSatisfies: true })); + const acornTs = acorn.Parser.extend(tsPlugin()); // Acorn doesn't add comments to the AST by itself. This factory returns the capabilities to add them after the fact. const ast = acornTs.parse(content, { @@ -179,3 +170,73 @@ export function serializeJson(originalInput: string, data: unknown): string { return fleece.stringify(data, { spaces }); } + +// Sourced from `golden-fleece` +// https://github.com/Rich-Harris/golden-fleece/blob/f2446f331640f325e13609ed99b74b6a45e755c2/src/patch.ts#L302 +export function guessIndentString(str: string | undefined): string { + if (!str) return '\t'; + + const lines = str.split('\n'); + + let tabs = 0; + let spaces = 0; + let minSpaces = 8; + + lines.forEach((line) => { + const match = /^(?: +|\t+)/.exec(line); + if (!match) return; + + const whitespace = match[0]; + if (whitespace.length === line.length) return; + + if (whitespace[0] === '\t') { + tabs += 1; + } else { + spaces += 1; + if (whitespace.length > 1 && whitespace.length < minSpaces) { + minSpaces = whitespace.length; + } + } + }); + + if (spaces > tabs) { + let result = ''; + while (minSpaces--) result += ' '; + return result; + } else { + return '\t'; + } +} + +export function guessQuoteStyle(ast: TsEstree.Node): 'single' | 'double' | undefined { + let singleCount = 0; + let doubleCount = 0; + + Walker.walk(ast, null, { + Literal(node) { + if (node.raw && node.raw.length >= 2) { + // we have at least two characters in the raw string that could represent both quotes + const quotes = [node.raw[0], node.raw[node.raw.length - 1]]; + for (const quote of quotes) { + switch (quote) { + case "'": + singleCount++; + break; + case '"': + doubleCount++; + break; + default: + break; + } + } + } + } + }); + + if (singleCount === 0 && doubleCount === 0) { + // new file or file without any quotes + return undefined; + } + + return singleCount > doubleCount ? 'single' : 'double'; +} diff --git a/packages/core/tooling/js/array.ts b/packages/core/tooling/js/array.ts index 1565d10a..46da53ee 100644 --- a/packages/core/tooling/js/array.ts +++ b/packages/core/tooling/js/array.ts @@ -1,5 +1,5 @@ import { areNodesEqual } from './common.ts'; -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function createEmpty(): AstTypes.ArrayExpression { const arrayExpression: AstTypes.ArrayExpression = { diff --git a/packages/core/tooling/js/common.ts b/packages/core/tooling/js/common.ts index c50900f1..c6b328ca 100644 --- a/packages/core/tooling/js/common.ts +++ b/packages/core/tooling/js/common.ts @@ -1,10 +1,4 @@ -import { - type AstTypes, - Walker, - parseScript, - serializeScript, - stripAst -} from '@sveltejs/ast-tooling'; +import { type AstTypes, Walker, parseScript, serializeScript, stripAst } from '../index.ts'; import decircular from 'decircular'; import dedent from 'dedent'; @@ -121,6 +115,7 @@ export function addFromString( export function expressionFromString(value: string): AstTypes.Expression { const program = parseScript(dedent(value)); + stripAst(program, ['raw']); const statement = program.body[0]!; if (statement.type !== 'ExpressionStatement') { throw new Error('value passed was not an expression'); diff --git a/packages/core/tooling/js/exports.ts b/packages/core/tooling/js/exports.ts index d09f198d..ea12e764 100644 --- a/packages/core/tooling/js/exports.ts +++ b/packages/core/tooling/js/exports.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export type ExportDefaultReturn = { astNode: AstTypes.ExportDefaultDeclaration; @@ -71,7 +71,8 @@ export function namedExport( namedExport = { type: 'ExportNamedDeclaration', declaration: fallback, - specifiers: [] + specifiers: [], + attributes: [] }; ast.body.push(namedExport); return namedExport; diff --git a/packages/core/tooling/js/function.ts b/packages/core/tooling/js/function.ts index 672394e5..f6701982 100644 --- a/packages/core/tooling/js/function.ts +++ b/packages/core/tooling/js/function.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function call(name: string, args: string[]): AstTypes.CallExpression { const callExpression: AstTypes.CallExpression = { diff --git a/packages/core/tooling/js/imports.ts b/packages/core/tooling/js/imports.ts index 61746676..81ce9a35 100644 --- a/packages/core/tooling/js/imports.ts +++ b/packages/core/tooling/js/imports.ts @@ -1,4 +1,4 @@ -import { Walker, type AstTypes } from '@sveltejs/ast-tooling'; +import { Walker, type AstTypes } from '../index.ts'; import { areNodesEqual } from './common.ts'; export function addEmpty(ast: AstTypes.Program, importFrom: string): void { @@ -9,6 +9,7 @@ export function addEmpty(ast: AstTypes.Program, importFrom: string): void { value: importFrom }, specifiers: [], + attributes: [], importKind: 'value' }; @@ -25,7 +26,8 @@ export function addNamespace(ast: AstTypes.Program, importFrom: string, importAs type: 'ImportNamespaceSpecifier', local: { type: 'Identifier', name: importAs } } - ] + ], + attributes: [] }; addImportIfNecessary(ast, expectedImportDeclaration); @@ -47,6 +49,7 @@ export function addDefault(ast: AstTypes.Program, importFrom: string, importAs: } } ], + attributes: [], importKind: 'value' }; @@ -109,6 +112,7 @@ export function addNamed( value: importFrom }, specifiers, + attributes: [], importKind: isType ? 'type' : 'value' }; diff --git a/packages/core/tooling/js/index.ts b/packages/core/tooling/js/index.ts index 7e556569..08482f14 100644 --- a/packages/core/tooling/js/index.ts +++ b/packages/core/tooling/js/index.ts @@ -6,4 +6,4 @@ export * as imports from './imports.ts'; export * as variables from './variables.ts'; export * as exports from './exports.ts'; export * as kit from './kit.ts'; -export type { AstTypes } from '@sveltejs/ast-tooling'; +export type { AstTypes } from '../index.ts'; diff --git a/packages/core/tooling/js/kit.ts b/packages/core/tooling/js/kit.ts index 9f4f25c9..d9a38a4a 100644 --- a/packages/core/tooling/js/kit.ts +++ b/packages/core/tooling/js/kit.ts @@ -1,4 +1,4 @@ -import { Walker, type AstTypes } from '@sveltejs/ast-tooling'; +import { Walker, type AstTypes } from '../index.ts'; import { common, functions, imports, variables, exports } from '../js/index.ts'; export function addGlobalAppInterface( diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 22ffb19c..a909aa72 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function property( ast: AstTypes.ObjectExpression, diff --git a/packages/ast-tooling/ts-estree.ts b/packages/core/tooling/js/ts-estree.ts similarity index 100% rename from packages/ast-tooling/ts-estree.ts rename to packages/core/tooling/js/ts-estree.ts diff --git a/packages/core/tooling/js/variables.ts b/packages/core/tooling/js/variables.ts index 1390343c..bd652dfd 100644 --- a/packages/core/tooling/js/variables.ts +++ b/packages/core/tooling/js/variables.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function declaration( ast: AstTypes.Program | AstTypes.Declaration, diff --git a/packages/core/tooling/parsers.ts b/packages/core/tooling/parsers.ts index 846cb8ea..f7764d34 100644 --- a/packages/core/tooling/parsers.ts +++ b/packages/core/tooling/parsers.ts @@ -1,4 +1,4 @@ -import * as tools from '@sveltejs/ast-tooling'; +import * as utils from './index.ts'; import MagicString from 'magic-string'; type ParseBase = { @@ -6,31 +6,31 @@ type ParseBase = { generateCode(): string; }; -export function parseScript(source: string): { ast: tools.AstTypes.Program } & ParseBase { - const ast = tools.parseScript(source); - const generateCode = () => tools.serializeScript(ast, source); +export function parseScript(source: string): { ast: utils.AstTypes.Program } & ParseBase { + const ast = utils.parseScript(source); + const generateCode = () => utils.serializeScript(ast, source); return { ast, source, generateCode }; } -export function parseCss(source: string): { ast: tools.CssAst } & ParseBase { - const ast = tools.parseCss(source); +export function parseCss(source: string): { ast: utils.CssAst } & ParseBase { + const ast = utils.parseCss(source); const generateCode = () => ast.toString(); return { ast, source, generateCode }; } -export function parseHtml(source: string): { ast: tools.HtmlDocument } & ParseBase { - const ast = tools.parseHtml(source); - const generateCode = () => tools.serializeHtml(ast); +export function parseHtml(source: string): { ast: utils.HtmlDocument } & ParseBase { + const ast = utils.parseHtml(source); + const generateCode = () => utils.serializeHtml(ast); return { ast, source, generateCode }; } export function parseJson(source: string): { data: any } & ParseBase { if (!source) source = '{}'; - const data = tools.parseJson(source); - const generateCode = () => tools.serializeJson(source, data); + const data = utils.parseJson(source); + const generateCode = () => utils.serializeJson(source, data); return { data, source, generateCode }; } diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts index 8b52c7a6..6aa2d6af 100644 --- a/packages/core/vitest.config.ts +++ b/packages/core/vitest.config.ts @@ -3,6 +3,6 @@ import { defineProject } from 'vitest/config'; export default defineProject({ test: { name: 'core', - include: ['./tests/**/index.ts'] + include: ['./tests/**/index.ts', './tests/*.ts'] } }); diff --git a/packages/create/templates/demo/package.json b/packages/create/templates/demo/package.json index 91c81909..0dbee191 100644 --- a/packages/create/templates/demo/package.json +++ b/packages/create/templates/demo/package.json @@ -16,6 +16,6 @@ "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.25.0", "typescript": "^5.3.3", - "vite": "^6.0.0" + "vite": "^6.2.4" } } diff --git a/packages/create/templates/demo/package.template.json b/packages/create/templates/demo/package.template.json index a3ceb4eb..07362f14 100644 --- a/packages/create/templates/demo/package.template.json +++ b/packages/create/templates/demo/package.template.json @@ -12,10 +12,10 @@ "devDependencies": { "@fontsource/fira-mono": "^5.0.0", "@neoconfetti/svelte": "^2.0.0", - "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.25.0", - "vite": "^6.0.0" + "vite": "^6.2.6" } } diff --git a/packages/create/templates/demo/src/app.css b/packages/create/templates/demo/src/app.css index 1441d940..f62c2c7a 100644 --- a/packages/create/templates/demo/src/app.css +++ b/packages/create/templates/demo/src/app.css @@ -1,8 +1,9 @@ @import '@fontsource/fira-mono'; :root { - --font-body: Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, - Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --font-body: + Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, + 'Open Sans', 'Helvetica Neue', sans-serif; --font-mono: 'Fira Mono', monospace; --color-bg-0: rgb(202, 216, 228); --color-bg-1: hsl(209, 36%, 86%); @@ -22,11 +23,8 @@ body { background-attachment: fixed; background-color: var(--color-bg-1); background-size: 100vw 100vh; - background-image: radial-gradient( - 50% 50% at 50% 50%, - rgba(255, 255, 255, 0.75) 0%, - rgba(255, 255, 255, 0) 100% - ), + background-image: + radial-gradient(50% 50% at 50% 50%, rgba(255, 255, 255, 0.75) 0%, rgba(255, 255, 255, 0) 100%), linear-gradient(180deg, var(--color-bg-0) 0%, var(--color-bg-1) 15%, var(--color-bg-2) 50%); } diff --git a/packages/create/templates/library/package.template.json b/packages/create/templates/library/package.template.json index 082f3804..d4c30ccd 100644 --- a/packages/create/templates/library/package.template.json +++ b/packages/create/templates/library/package.template.json @@ -23,14 +23,14 @@ "svelte": "^5.0.0" }, "devDependencies": { - "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/kit": "^2.16.0", "@sveltejs/package": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "publint": "^0.3.2", "svelte": "^5.0.0", "typescript": "^5.3.2", - "vite": "^6.0.0" + "vite": "^6.2.6" }, "keywords": ["svelte"] } diff --git a/packages/create/templates/minimal/package.template.json b/packages/create/templates/minimal/package.template.json index afcc928f..96f3f0d2 100644 --- a/packages/create/templates/minimal/package.template.json +++ b/packages/create/templates/minimal/package.template.json @@ -10,10 +10,10 @@ "prepare": "svelte-kit sync || echo ''" }, "devDependencies": { - "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", - "vite": "^6.0.0" + "vite": "^6.2.6" } } diff --git a/packages/migrate/package.json b/packages/migrate/package.json index 6188b954..3a4c1ee9 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -27,21 +27,21 @@ "svelte-migrate": "./bin.js" }, "dependencies": { - "@clack/prompts": "^0.9.0", + "@clack/prompts": "^1.0.0-alpha.0", "import-meta-resolve": "^4.1.0", - "magic-string": "^0.30.15", - "package-manager-detector": "^0.2.7", + "magic-string": "^0.30.17", + "package-manager-detector": "^0.2.11", "picocolors": "^1.1.1", - "semver": "^7.6.3", + "semver": "^7.7.1", "tiny-glob": "^0.2.9", "ts-morph": "^24.0.0", - "typescript": "^5.7.2", + "typescript": "^5.8.3", "zimmerframe": "^1.1.2" }, "devDependencies": { - "@types/node": "^18.19.68", + "@types/node": "^18.19.86", "@types/prompts": "^2.4.9", - "@types/semver": "^7.5.8", + "@types/semver": "^7.7.0", "svelte": "^4.2.19" }, "keywords": [ diff --git a/packages/migrate/utils.js b/packages/migrate/utils.js index 4fd00665..cd401068 100644 --- a/packages/migrate/utils.js +++ b/packages/migrate/utils.js @@ -440,5 +440,7 @@ export function migration_succeeded(next_steps) { messages.push(`${i + 1}: ${step}`); }); - p.note(messages.join('\n'), 'Recommended next steps:'); + p.note(messages.join('\n'), 'Recommended next steps:', { + format: (line) => pc.white(line) + }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 992314a5..99567e50 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,62 +9,65 @@ importers: .: devDependencies: '@changesets/cli': - specifier: ^2.27.10 - version: 2.27.11 + specifier: ^2.28.1 + version: 2.28.1 '@playwright/test': - specifier: ^1.49.1 - version: 1.49.1 + specifier: ^1.51.1 + version: 1.51.1 '@sveltejs/create': specifier: workspace:* version: link:packages/create '@sveltejs/eslint-config': - specifier: ^8.1.0 - version: 8.1.0(@stylistic/eslint-plugin-js@2.12.1(eslint@9.17.0))(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint-plugin-n@17.15.1(eslint@9.17.0))(eslint-plugin-svelte@2.46.1(eslint@9.17.0)(svelte@5.16.0))(eslint@9.17.0)(typescript-eslint@8.18.2(eslint@9.17.0)(typescript@5.7.2))(typescript@5.7.2) + specifier: ^8.2.0 + version: 8.2.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.24.0))(eslint-config-prettier@9.1.0(eslint@9.24.0))(eslint-plugin-n@17.13.1(eslint@9.24.0))(eslint-plugin-svelte@3.5.1(eslint@9.24.0)(svelte@5.25.7))(eslint@9.24.0)(typescript-eslint@8.29.0(eslint@9.24.0)(typescript@5.8.3))(typescript@5.8.3) '@svitejs/changesets-changelog-github-compact': specifier: ^1.2.0 version: 1.2.0 '@types/node': - specifier: ^22.10.2 - version: 22.10.2 + specifier: ^22.14.0 + version: 22.14.0 '@vitest/ui': - specifier: ^3.0.5 - version: 3.0.9(vitest@3.0.5) + specifier: ^3.0.9 + version: 3.0.9(vitest@3.0.9) eslint: - specifier: ^9.17.0 - version: 9.17.0 + specifier: ^9.24.0 + version: 9.24.0 + eslint-plugin-svelte: + specifier: ^3.5.1 + version: 3.5.1(eslint@9.24.0)(svelte@5.25.7) magic-string: - specifier: ^0.30.15 + specifier: ^0.30.17 version: 0.30.17 prettier: - specifier: ^3.4.2 - version: 3.4.2 + specifier: ^3.5.3 + version: 3.5.3 prettier-plugin-packagejson: - specifier: ^2.5.6 - version: 2.5.6(prettier@3.4.2) + specifier: ^2.5.10 + version: 2.5.10(prettier@3.5.3) prettier-plugin-svelte: - specifier: ^3.3.2 - version: 3.3.2(prettier@3.4.2)(svelte@5.16.0) + specifier: ^3.3.3 + version: 3.3.3(prettier@3.5.3)(svelte@5.25.7) rolldown: specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(@babel/runtime@7.26.0) + version: 1.0.0-beta.1(@babel/runtime@7.27.0) sv: specifier: workspace:* version: link:packages/cli svelte: - specifier: ^5.12.0 - version: 5.16.0 + specifier: ^5.25.7 + version: 5.25.7 typescript: - specifier: ^5.6.2 - version: 5.7.2 + specifier: ^5.8.3 + version: 5.8.3 typescript-eslint: - specifier: ^8.18.0 - version: 8.18.2(eslint@9.17.0)(typescript@5.7.2) + specifier: ^8.29.0 + version: 8.29.0(eslint@9.24.0)(typescript@5.8.3) unplugin-isolated-decl: specifier: ^0.8.3 - version: 0.8.3(rollup@4.34.5)(typescript@5.7.2) + version: 0.8.3(rollup@4.39.0)(typescript@5.8.3) vitest: - specifier: ^3.0.5 - version: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.9) + specifier: ^3.0.9 + version: 3.0.9(@types/node@22.14.0)(@vitest/ui@3.0.9) community-addon-template: dependencies: @@ -73,14 +76,14 @@ importers: version: link:../packages/core devDependencies: '@playwright/test': - specifier: ^1.49.1 - version: 1.49.1 + specifier: ^1.51.1 + version: 1.51.1 sv: specifier: workspace:* version: link:../packages/cli vitest: - specifier: ^3.0.5 - version: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.5) + specifier: ^3.0.9 + version: 3.0.9(@types/node@22.14.0)(@vitest/ui@3.0.9) packages/addons: dependencies: @@ -88,80 +91,14 @@ importers: specifier: workspace:* version: link:../core - packages/ast-tooling: - devDependencies: - '@sveltejs/acorn-typescript': - specifier: ^1.0.1 - version: 1.0.1(acorn@8.14.0) - '@types/estree': - specifier: ^1.0.6 - version: 1.0.6 - acorn: - specifier: ^8.14.0 - version: 8.14.0 - dedent: - specifier: ^1.5.3 - version: 1.5.3 - dom-serializer: - specifier: ^2.0.0 - version: 2.0.0 - domhandler: - specifier: ^5.0.3 - version: 5.0.3 - domutils: - specifier: ^3.1.0 - version: 3.2.1 - esrap: - specifier: ^1.4.5 - version: 1.4.5 - htmlparser2: - specifier: ^9.1.0 - version: 9.1.0 - postcss: - specifier: ^8.4.49 - version: 8.5.3 - silver-fleece: - specifier: ^1.2.1 - version: 1.2.1 - zimmerframe: - specifier: ^1.1.2 - version: 1.1.2 - - packages/clack-core: - devDependencies: - picocolors: - specifier: ^1.1.1 - version: 1.1.1 - sisteransi: - specifier: ^1.0.5 - version: 1.0.5 - wrap-ansi: - specifier: ^8.1.0 - version: 8.1.0 - - packages/clack-prompts: - devDependencies: - '@sveltejs/clack-core': - specifier: workspace:* - version: link:../clack-core - is-unicode-supported: - specifier: ^1.3.0 - version: 1.3.0 - picocolors: - specifier: ^1.1.1 - version: 1.1.1 - sisteransi: - specifier: ^1.0.5 - version: 1.0.5 - packages/cli: devDependencies: + '@clack/prompts': + specifier: ^1.0.0-alpha.1 + version: 1.0.0-alpha.1 '@sveltejs/addons': specifier: workspace:* version: link:../addons - '@sveltejs/clack-prompts': - specifier: workspace:* - version: link:../clack-prompts '@sveltejs/cli-core': specifier: workspace:* version: link:../core @@ -174,12 +111,9 @@ importers: '@types/ps-tree': specifier: ^1.1.6 version: 1.1.6 - '@types/tar-fs': - specifier: ^2.0.4 - version: 2.0.4 commander: - specifier: ^13.0.0 - version: 13.0.0 + specifier: ^13.1.0 + version: 13.1.0 degit: specifier: ^2.8.4 version: 2.8.4 @@ -187,45 +121,71 @@ importers: specifier: ^1.0.0 version: 1.0.0 package-manager-detector: - specifier: ^0.2.7 - version: 0.2.8 + specifier: ^0.2.11 + version: 0.2.11 picocolors: specifier: ^1.1.1 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.1 + specifier: ^0.3.2 version: 0.3.2 valibot: specifier: ^0.41.0 - version: 0.41.0(typescript@5.7.2) + version: 0.41.0(typescript@5.8.3) packages/core: - dependencies: - '@sveltejs/ast-tooling': - specifier: workspace:* - version: link:../ast-tooling devDependencies: - '@sveltejs/clack-prompts': - specifier: workspace:* - version: link:../clack-prompts + '@clack/prompts': + specifier: ^1.0.0-alpha.1 + version: 1.0.0-alpha.1 + '@sveltejs/acorn-typescript': + specifier: ^1.0.1 + version: 1.0.5(acorn@8.14.1) + '@types/estree': + specifier: ^1.0.6 + version: 1.0.7 + acorn: + specifier: ^8.14.0 + version: 8.14.1 decircular: specifier: ^1.0.0 version: 1.0.0 dedent: specifier: ^1.5.3 version: 1.5.3 + dom-serializer: + specifier: ^2.0.0 + version: 2.0.0 + domhandler: + specifier: ^5.0.3 + version: 5.0.3 + domutils: + specifier: ^3.1.0 + version: 3.2.2 + esrap: + specifier: ^1.4.5 + version: 1.4.6 + htmlparser2: + specifier: ^9.1.0 + version: 9.1.0 magic-string: - specifier: ^0.30.15 + specifier: ^0.30.17 version: 0.30.17 picocolors: specifier: ^1.1.1 version: 1.1.1 + postcss: + specifier: ^8.4.49 + version: 8.5.3 + silver-fleece: + specifier: ^1.2.1 + version: 1.2.1 + zimmerframe: + specifier: ^1.1.2 + version: 1.1.2 packages/create: devDependencies: @@ -245,22 +205,22 @@ importers: packages/migrate: dependencies: '@clack/prompts': - specifier: ^0.9.0 - version: 0.9.0 + specifier: ^1.0.0-alpha.0 + version: 1.0.0-alpha.0 import-meta-resolve: specifier: ^4.1.0 version: 4.1.0 magic-string: - specifier: ^0.30.15 + specifier: ^0.30.17 version: 0.30.17 package-manager-detector: - specifier: ^0.2.7 - version: 0.2.8 + specifier: ^0.2.11 + version: 0.2.11 picocolors: specifier: ^1.1.1 version: 1.1.1 semver: - specifier: ^7.6.3 + specifier: ^7.7.1 version: 7.7.1 tiny-glob: specifier: ^0.2.9 @@ -269,21 +229,21 @@ importers: specifier: ^24.0.0 version: 24.0.0 typescript: - specifier: ^5.7.2 - version: 5.7.2 + specifier: ^5.8.3 + version: 5.8.3 zimmerframe: specifier: ^1.1.2 version: 1.1.2 devDependencies: '@types/node': - specifier: ^18.19.68 - version: 18.19.68 + specifier: ^18.19.86 + version: 18.19.86 '@types/prompts': specifier: ^2.4.9 version: 2.4.9 '@types/semver': - specifier: ^7.5.8 - version: 7.5.8 + specifier: ^7.7.0 + version: 7.7.0 svelte: specifier: ^4.2.19 version: 4.2.19 @@ -294,37 +254,37 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@babel/runtime@7.26.0': - resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + '@babel/runtime@7.27.0': + resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} - '@changesets/apply-release-plan@7.0.7': - resolution: {integrity: sha512-qnPOcmmmnD0MfMg9DjU1/onORFyRpDXkMMl2IJg9mECY6RnxL3wN0TCCc92b2sXt1jt8DgjAUUsZYGUGTdYIXA==} + '@changesets/apply-release-plan@7.0.10': + resolution: {integrity: sha512-wNyeIJ3yDsVspYvHnEz1xQDq18D9ifed3lI+wxRQRK4pArUcuHgCTrHv0QRnnwjhVCQACxZ+CBih3wgOct6UXw==} - '@changesets/assemble-release-plan@6.0.5': - resolution: {integrity: sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==} + '@changesets/assemble-release-plan@6.0.6': + resolution: {integrity: sha512-Frkj8hWJ1FRZiY3kzVCKzS0N5mMwWKwmv9vpam7vt8rZjLL1JMthdh6pSDVSPumHPshTTkKZ0VtNbE0cJHZZUg==} - '@changesets/changelog-git@0.2.0': - resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - '@changesets/cli@2.27.11': - resolution: {integrity: sha512-1QislpE+nvJgSZZo9+Lj3Lno5pKBgN46dAV8IVxKJy9wX8AOrs9nn5pYVZuDpoxWJJCALmbfOsHkyxujgetQSg==} + '@changesets/cli@2.28.1': + resolution: {integrity: sha512-PiIyGRmSc6JddQJe/W1hRPjiN4VrMvb2VfQ6Uydy2punBioQrsxppyG5WafinKcW1mT0jOe/wU4k9Zy5ff21AA==} hasBin: true - '@changesets/config@3.0.5': - resolution: {integrity: sha512-QyXLSSd10GquX7hY0Mt4yQFMEeqnO5z/XLpbIr4PAkNNoQNKwDyiSrx4yd749WddusH1v3OSiA0NRAYmH/APpQ==} + '@changesets/config@3.1.1': + resolution: {integrity: sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} - '@changesets/get-dependents-graph@2.1.2': - resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} + '@changesets/get-dependents-graph@2.1.3': + resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} '@changesets/get-github-info@0.6.0': resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} - '@changesets/get-release-plan@4.0.6': - resolution: {integrity: sha512-FHRwBkY7Eili04Y5YMOZb0ezQzKikTka4wL753vfUA5COSebt7KThqiuCN9BewE4/qFGgF/5t3AuzXx1/UAY4w==} + '@changesets/get-release-plan@4.0.8': + resolution: {integrity: sha512-MM4mq2+DQU1ZT7nqxnpveDMTkMBLnwNX44cX7NSxlXmr7f8hO6/S2MXNiXG54uf/0nYnefv0cfy4Czf/ZL/EKQ==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} @@ -335,194 +295,200 @@ packages: '@changesets/logger@0.1.1': resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} - '@changesets/parse@0.4.0': - resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} + '@changesets/parse@0.4.1': + resolution: {integrity: sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==} - '@changesets/pre@2.0.1': - resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} - '@changesets/read@0.6.2': - resolution: {integrity: sha512-wjfQpJvryY3zD61p8jR87mJdyx2FIhEcdXhKUqkja87toMrP/3jtg/Yg29upN+N4Ckf525/uvV7a4tzBlpk6gg==} + '@changesets/read@0.6.3': + resolution: {integrity: sha512-9H4p/OuJ3jXEUTjaVGdQEhBdqoT2cO5Ts95JTFsQyawmKzpL8FnIeJSyhTDPW1MBRDnwZlHFEM9SpPwJDY5wIg==} - '@changesets/should-skip-package@0.1.1': - resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} '@changesets/types@4.1.0': resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} - '@changesets/types@6.0.0': - resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - '@changesets/write@0.3.2': - resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + '@clack/core@1.0.0-alpha.0': + resolution: {integrity: sha512-Cp/bPW/pMUCkJ7Lr8VFixvFrlnJ4tQPDHqfTNQ51z50qwX1fSIAstQLfel2NquVHqbfjyrUkBsal8OJRBPJVjw==} - '@clack/core@0.4.0': - resolution: {integrity: sha512-YJCYBsyJfNDaTbvDUVSJ3SgSuPrcujarRgkJ5NLjexDZKvaOiVVJvAQYx8lIgG0qRT8ff0fPgqyBCVivanIZ+A==} + '@clack/core@1.0.0-alpha.1': + resolution: {integrity: sha512-rFbCU83JnN7l3W1nfgCqqme4ZZvTTgsiKQ6FM0l+r0P+o2eJpExcocBUWUIwnDzL76Aca9VhUdWmB2MbUv+Qyg==} - '@clack/prompts@0.9.0': - resolution: {integrity: sha512-nGsytiExgUr4FL0pR/LeqxA28nz3E0cW7eLTSh3Iod9TGrbBt8Y7BHbV3mmkNC4G0evdYyQ3ZsbiBkk7ektArA==} + '@clack/prompts@1.0.0-alpha.0': + resolution: {integrity: sha512-Aem7r4U2A4jdOh0PIv51Ugi+4vDgzJjGVMnuPUNVVHDGhFHEO//u6F/JY6NsZQFtXrd7ZmfePSiipikr/e5wWg==} - '@emnapi/core@1.3.1': - resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==} + '@clack/prompts@1.0.0-alpha.1': + resolution: {integrity: sha512-07MNT0OsxjKOcyVfX8KhXBhJiyUbDP1vuIAcHc+nx5v93MJO23pX3X/k3bWz6T3rpM9dgWPq90i4Jq7gZAyMbw==} - '@emnapi/runtime@1.3.1': - resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + '@emnapi/core@1.4.0': + resolution: {integrity: sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==} + + '@emnapi/runtime@1.4.0': + resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} '@emnapi/wasi-threads@1.0.1': resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} - '@esbuild/aix-ppc64@0.24.2': - resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + '@esbuild/aix-ppc64@0.25.2': + resolution: {integrity: sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.24.2': - resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + '@esbuild/android-arm64@0.25.2': + resolution: {integrity: sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.24.2': - resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + '@esbuild/android-arm@0.25.2': + resolution: {integrity: sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.24.2': - resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + '@esbuild/android-x64@0.25.2': + resolution: {integrity: sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.24.2': - resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + '@esbuild/darwin-arm64@0.25.2': + resolution: {integrity: sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.24.2': - resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + '@esbuild/darwin-x64@0.25.2': + resolution: {integrity: sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.24.2': - resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + '@esbuild/freebsd-arm64@0.25.2': + resolution: {integrity: sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.24.2': - resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + '@esbuild/freebsd-x64@0.25.2': + resolution: {integrity: sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.24.2': - resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + '@esbuild/linux-arm64@0.25.2': + resolution: {integrity: sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.24.2': - resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + '@esbuild/linux-arm@0.25.2': + resolution: {integrity: sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.24.2': - resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + '@esbuild/linux-ia32@0.25.2': + resolution: {integrity: sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.24.2': - resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + '@esbuild/linux-loong64@0.25.2': + resolution: {integrity: sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.24.2': - resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + '@esbuild/linux-mips64el@0.25.2': + resolution: {integrity: sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.24.2': - resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + '@esbuild/linux-ppc64@0.25.2': + resolution: {integrity: sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.24.2': - resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + '@esbuild/linux-riscv64@0.25.2': + resolution: {integrity: sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.24.2': - resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + '@esbuild/linux-s390x@0.25.2': + resolution: {integrity: sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.24.2': - resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + '@esbuild/linux-x64@0.25.2': + resolution: {integrity: sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.24.2': - resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + '@esbuild/netbsd-arm64@0.25.2': + resolution: {integrity: sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.24.2': - resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + '@esbuild/netbsd-x64@0.25.2': + resolution: {integrity: sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.24.2': - resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + '@esbuild/openbsd-arm64@0.25.2': + resolution: {integrity: sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.24.2': - resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + '@esbuild/openbsd-x64@0.25.2': + resolution: {integrity: sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.24.2': - resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + '@esbuild/sunos-x64@0.25.2': + resolution: {integrity: sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.24.2': - resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + '@esbuild/win32-arm64@0.25.2': + resolution: {integrity: sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.24.2': - resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + '@esbuild/win32-ia32@0.25.2': + resolution: {integrity: sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.24.2': - resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + '@esbuild/win32-x64@0.25.2': + resolution: {integrity: sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.4.1': - resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + '@eslint-community/eslint-utils@4.5.1': + resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -531,28 +497,36 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.19.1': - resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==} + '@eslint/config-array@0.20.0': + resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.2.1': + resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.12.0': + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.9.1': - resolution: {integrity: sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==} + '@eslint/core@0.13.0': + resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/eslintrc@3.2.0': - resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.17.0': - resolution: {integrity: sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==} + '@eslint/js@9.24.0': + resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.5': - resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==} + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.4': - resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} + '@eslint/plugin-kit@0.2.8': + resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@humanfs/core@0.19.1': @@ -571,8 +545,8 @@ packages: resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.1': - resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} '@isaacs/cliui@8.0.2': @@ -603,8 +577,8 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - '@napi-rs/wasm-runtime@0.2.6': - resolution: {integrity: sha512-z8YVS3XszxFTO73iwvFDNpQIzdMmSDTP/mB3E/ucR37V3Sx57hSExcXyMoNwaucWxnsWf4xfbZv0iZ30jr0M4Q==} + '@napi-rs/wasm-runtime@0.2.8': + resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -665,12 +639,12 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + '@pkgr/core@0.1.2': + resolution: {integrity: sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.49.1': - resolution: {integrity: sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==} + '@playwright/test@1.51.1': + resolution: {integrity: sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q==} engines: {node: '>=18'} hasBin: true @@ -737,8 +711,8 @@ packages: cpu: [x64] os: [win32] - '@rollup/pluginutils@5.1.3': - resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -746,122 +720,127 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.34.5': - resolution: {integrity: sha512-JXmmQcKQtpf3Z6lvA8akkrHDZ5AEfgc2hLMix1/X5BhQbezBQ0AP5GYLdU8jsQRme8qr2sscCe3wizp7UT0L9g==} + '@rollup/rollup-android-arm-eabi@4.39.0': + resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.34.5': - resolution: {integrity: sha512-9/A8/ZBOprUjkrJoP9BBEq2vdSud6BPd3LChw09bJQiEZH5oN4kWIkHu90cA0Cj0cSF5cIaD76+0lA+d5KHmpQ==} + '@rollup/rollup-android-arm64@4.39.0': + resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.34.5': - resolution: {integrity: sha512-b9oCfgHKfc1AJEQ5sEpE8Kf6s7aeygj5bZAsl1hTpZc1V9cfZASFSXzzNj7o/BQNPbjmVkVxpCCLRhBfLXhJ5g==} + '@rollup/rollup-darwin-arm64@4.39.0': + resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.34.5': - resolution: {integrity: sha512-Gz42gKBQPoFdMYdsVqkcpttYOO/0aP7f+1CgMaeZEz0gss7dop1TsO3hT77Iroz/TV7PdPUG/RYlj9EA39L4dw==} + '@rollup/rollup-darwin-x64@4.39.0': + resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.34.5': - resolution: {integrity: sha512-JPkafjkOFaupd8VQYsXfGFKC2pfMr7hwSYGkVGNwhbW0k0lHHyIdhCSNBendJ4O7YlT4yRyKXoms1TL7saO7SQ==} + '@rollup/rollup-freebsd-arm64@4.39.0': + resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.34.5': - resolution: {integrity: sha512-j6Q8VFqyI8hZM33h1JC6DZK2w8ejkXqEMozTrtIEGfRVMpVZL3GrLOOYEUkAgUSpJ9sb2w+FEpjGj7IHRcQfdw==} + '@rollup/rollup-freebsd-x64@4.39.0': + resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.34.5': - resolution: {integrity: sha512-6jyiXKF9Xq6x9yQjct5xrRT0VghJk5VzAfed3o0hgncwacZkzOdR0TXLRNjexsEXWN8tG7jWWwsVk7WeFi//gw==} + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': + resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.34.5': - resolution: {integrity: sha512-cOTYe5tLcGAvGztRLIqx87LE7j/qjaAqFrrHsPFlnuhhhFO5LSr2AzvdQYuxomJMzMBrXkMRNl9bQEpDZ5bjLQ==} + '@rollup/rollup-linux-arm-musleabihf@4.39.0': + resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.34.5': - resolution: {integrity: sha512-KHlrd+YqmS7rriW+LBb1kQNYmd5w1sAIG3z7HEpnQOrg/skeYYv9DAcclGL9gpFdpnzmiAEkzsTT74kZWUtChQ==} + '@rollup/rollup-linux-arm64-gnu@4.39.0': + resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.34.5': - resolution: {integrity: sha512-uOb6hzDqym4Sw+qw3+svS3SmwQGVUhyTdPKyHDdlYg1Z0aHjdNmjwRY7zw/90/UfBe/yD7Mv2mYKhQpOfy4RYA==} + '@rollup/rollup-linux-arm64-musl@4.39.0': + resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.34.5': - resolution: {integrity: sha512-pARu8ZKANZH4wINLdHLKG69EPwJswM6A+Ox1a9LpiclRQoyjacFFTtXN3akKQ2ufJXDasO/pWvxKN9ZfCgEoFA==} + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': + resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.34.5': - resolution: {integrity: sha512-crUWn12NRmCdao2YwS1GvlPCVypMBMJlexTaantaP2+dAMd2eZBErFcKG8hZYEHjSbbk2UoH1aTlyeA4iKLqSA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': + resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.34.5': - resolution: {integrity: sha512-XtD/oMhCdixi3x8rCNyDRMUsLo1Z+1UQcK+oR7AsjglGov9ETiT3TNFhUPzaGC1jH+uaMtPhxrVRUub+pnAKTg==} + '@rollup/rollup-linux-riscv64-gnu@4.39.0': + resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.39.0': + resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.34.5': - resolution: {integrity: sha512-V3+BvgyHb21aF7lw0sc78Tv0+xLp4lm2OM7CKFVrBuppsMvtl/9O5y2OX4tdDT0EhIsDP/ObJPqDuEg1ZoTwSQ==} + '@rollup/rollup-linux-s390x-gnu@4.39.0': + resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.34.5': - resolution: {integrity: sha512-SkCIXLGk42yldTcH8UXh++m0snVxp9DLf4meb1mWm0lC8jzxjFBwSLGtUSeLgQDsC05iBaIhyjNX46DlByrApQ==} + '@rollup/rollup-linux-x64-gnu@4.39.0': + resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.34.5': - resolution: {integrity: sha512-iUcH3FBtBN2/Ce0rI84suRhD0+bB5BVEffqOwsGaX5py5TuYLOQa7S7oVBP0NKtB5rub3i9IvZtMXiD96l5v0A==} + '@rollup/rollup-linux-x64-musl@4.39.0': + resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.34.5': - resolution: {integrity: sha512-PUbWd+h/h6rUowalDYIdc9S9LJXbQDMcJe0BjABl3oT3efYRgZ8aUe8ZZDSie7y+fz6Z+rueNfdorIbkWv5Eqg==} + '@rollup/rollup-win32-arm64-msvc@4.39.0': + resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.34.5': - resolution: {integrity: sha512-3vncGhOJiAUR85fnAXJyvSp2GaDWYByIQmW68ZAr+e8kIxgvJ1VaZbfHD5BO5X6hwRQdY6Um/XfA3l5c2lV+OQ==} + '@rollup/rollup-win32-ia32-msvc@4.39.0': + resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.34.5': - resolution: {integrity: sha512-Mi8yVUlQOoeBpY72n75VLATptPGvj2lHa47rQdK9kZ4MoG5Ve86aVIU+PO3tBklTCBtILtdRfXS0EvIbXgmCAg==} + '@rollup/rollup-win32-x64-msvc@4.39.0': + resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} cpu: [x64] os: [win32] - '@stylistic/eslint-plugin-js@2.12.1': - resolution: {integrity: sha512-5ybogtEgWIGCR6dMnaabztbWyVdAPDsf/5XOk6jBonWug875Q9/a6gm9QxnU3rhdyDEnckWKX7dduwYJMOWrVA==} + '@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' - '@sveltejs/acorn-typescript@1.0.1': - resolution: {integrity: sha512-MPvOVpdeRE5pA7hNPmPJwbVxoMC7dQWsIsn0PBJsfXlWyJJtwas4qSMNyArbLkpiNsMzlkyNU1k5Asckp57Srg==} + '@sveltejs/acorn-typescript@1.0.5': + resolution: {integrity: sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==} peerDependencies: - acorn: '>=8.9.0' + acorn: ^8.9.0 - '@sveltejs/eslint-config@8.1.0': - resolution: {integrity: sha512-cfgp4lPREYBjNd4ZzaP/jA85ufm7vfXiaV7h9vILXNogne80IbZRNhRCQ8XoOqTAOY/pChIzWTBuR8aDNMbAEA==} + '@sveltejs/eslint-config@8.2.0': + resolution: {integrity: sha512-5ab8AXjLoY+H0dsYTGB+9L8AnOvOzd9NZkECj40VAk6Uh9u7+5d8jVk+YYW6NGsEQ+HwHBUi19yij+q+5Pm+aQ==} peerDependencies: '@stylistic/eslint-plugin-js': '>= 1' eslint: '>= 9' eslint-config-prettier: '>= 9' eslint-plugin-n: '>= 17' - eslint-plugin-svelte: '>= 2.36' + eslint-plugin-svelte: '>= 3' typescript: '>= 5' - typescript-eslint: '>= 7.5' + typescript-eslint: '>= 8' '@svitejs/changesets-changelog-github-compact@1.2.0': resolution: {integrity: sha512-08eKiDAjj4zLug1taXSIJ0kGL5cawjVCyJkBb6EWSg5fEPX6L+Wtr0CH2If4j5KYylz85iaZiFlUItvgJvll5g==} @@ -876,8 +855,8 @@ packages: '@types/degit@2.8.6': resolution: {integrity: sha512-y0M7sqzsnHB6cvAeTCBPrCQNQiZe8U4qdzf8uBVmOWYap5MMTN/gB2iEqrIqFiYcsyvP74GnGD5tgsHttielFw==} - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} '@types/gitignore-parser@0.0.3': resolution: {integrity: sha512-sbdu1sG2pQcwjEYWTsX78OqJo5pKnonwC4FV3m2JeQRE2xYb3q0icHHopCHEvpn4uIBuvWBTpJUCJ76ISK24CA==} @@ -888,11 +867,11 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@18.19.68': - resolution: {integrity: sha512-QGtpFH1vB99ZmTa63K4/FU8twThj4fuVSBkGddTp7uIL/cuoLWIUSL2RcOaigBhfR+hg5pgGkBnkoOxrTVBMKw==} + '@types/node@18.19.86': + resolution: {integrity: sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ==} - '@types/node@22.10.2': - resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} + '@types/node@22.14.0': + resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} '@types/prompts@2.4.9': resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} @@ -900,67 +879,61 @@ packages: '@types/ps-tree@1.1.6': resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==} - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + '@types/semver@7.7.0': + resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} - '@types/tar-fs@2.0.4': - resolution: {integrity: sha512-ipPec0CjTmVDWE+QKr9cTmIIoTl7dFG/yARCM5MqK8i6CNLIG1P8x4kwDsOQY1ChZOZjH0wO9nvfgBvWl4R3kA==} - - '@types/tar-stream@3.1.3': - resolution: {integrity: sha512-Zbnx4wpkWBMBSu5CytMbrT5ZpMiF55qgM+EpHzR4yIDu7mv52cej8hTkOc6K+LzpkOAbxwn/m7j3iO+/l42YkQ==} - - '@typescript-eslint/eslint-plugin@8.18.2': - resolution: {integrity: sha512-adig4SzPLjeQ0Tm+jvsozSGiCliI2ajeURDGHjZ2llnA+A67HihCQ+a3amtPhUakd1GlwHxSRvzOZktbEvhPPg==} + '@typescript-eslint/eslint-plugin@8.29.0': + resolution: {integrity: sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.18.2': - resolution: {integrity: sha512-y7tcq4StgxQD4mDr9+Jb26dZ+HTZ/SkfqpXSiqeUXZHxOUyjWDKsmwKhJ0/tApR08DgOhrFAoAhyB80/p3ViuA==} + '@typescript-eslint/parser@8.29.0': + resolution: {integrity: sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/scope-manager@8.18.2': - resolution: {integrity: sha512-YJFSfbd0CJjy14r/EvWapYgV4R5CHzptssoag2M7y3Ra7XNta6GPAJPPP5KGB9j14viYXyrzRO5GkX7CRfo8/g==} + '@typescript-eslint/scope-manager@8.29.0': + resolution: {integrity: sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.18.2': - resolution: {integrity: sha512-AB/Wr1Lz31bzHfGm/jgbFR0VB0SML/hd2P1yxzKDM48YmP7vbyJNHRExUE/wZsQj2wUCvbWH8poNHFuxLqCTnA==} + '@typescript-eslint/type-utils@8.29.0': + resolution: {integrity: sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/types@8.18.2': - resolution: {integrity: sha512-Z/zblEPp8cIvmEn6+tPDIHUbRu/0z5lqZ+NvolL5SvXWT5rQy7+Nch83M0++XzO0XrWRFWECgOAyE8bsJTl1GQ==} + '@typescript-eslint/types@8.29.0': + resolution: {integrity: sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.18.2': - resolution: {integrity: sha512-WXAVt595HjpmlfH4crSdM/1bcsqh+1weFRWIa9XMTx/XHZ9TCKMcr725tLYqWOgzKdeDrqVHxFotrvWcEsk2Tg==} + '@typescript-eslint/typescript-estree@8.29.0': + resolution: {integrity: sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.18.2': - resolution: {integrity: sha512-Cr4A0H7DtVIPkauj4sTSXVl+VBWewE9/o40KcF3TV9aqDEOWoXF3/+oRXNby3DYzZeCATvbdksYsGZzplwnK/Q==} + '@typescript-eslint/utils@8.29.0': + resolution: {integrity: sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/visitor-keys@8.18.2': - resolution: {integrity: sha512-zORcwn4C3trOWiCqFQP1x6G3xTRyZ1LYydnj51cRnJ6hxBlr/cKPckk+PKPUw/fXmvfKTcw7bwY3w9izgx5jZw==} + '@typescript-eslint/visitor-keys@8.29.0': + resolution: {integrity: sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/expect@3.0.5': - resolution: {integrity: sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==} + '@vitest/expect@3.0.9': + resolution: {integrity: sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==} - '@vitest/mocker@3.0.5': - resolution: {integrity: sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==} + '@vitest/mocker@3.0.9': + resolution: {integrity: sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==} peerDependencies: msw: ^2.4.9 vite: ^5.0.0 || ^6.0.0 @@ -970,34 +943,26 @@ packages: vite: optional: true - '@vitest/pretty-format@3.0.5': - resolution: {integrity: sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==} - '@vitest/pretty-format@3.0.9': resolution: {integrity: sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==} - '@vitest/runner@3.0.5': - resolution: {integrity: sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==} + '@vitest/pretty-format@3.1.1': + resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==} - '@vitest/snapshot@3.0.5': - resolution: {integrity: sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==} + '@vitest/runner@3.0.9': + resolution: {integrity: sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==} - '@vitest/spy@3.0.5': - resolution: {integrity: sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==} + '@vitest/snapshot@3.0.9': + resolution: {integrity: sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==} - '@vitest/ui@3.0.5': - resolution: {integrity: sha512-gw2noso6WI+2PeMVCZFntdATS6xl9qhQcbhkPQ9sOmx/Xn0f4Bx4KDSbD90jpJPF0l5wOzSoGCmKyVR3W612mg==} - peerDependencies: - vitest: 3.0.5 + '@vitest/spy@3.0.9': + resolution: {integrity: sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==} '@vitest/ui@3.0.9': resolution: {integrity: sha512-FpZD4aIv/qNpwkV3XbLV6xldWFHMgoNWAJEgg5GmpObmAOLAErpYjew9dDwXdYdKOS3iZRKdwI+P3JOJcYeUBg==} peerDependencies: vitest: 3.0.9 - '@vitest/utils@3.0.5': - resolution: {integrity: sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==} - '@vitest/utils@3.0.9': resolution: {integrity: sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==} @@ -1006,13 +971,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-typescript@1.4.13: - resolution: {integrity: sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==} - peerDependencies: - acorn: '>=8.9.0' - - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} engines: {node: '>=0.4.0'} hasBin: true @@ -1064,27 +1024,9 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - b4a@1.6.7: - resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bare-events@2.5.0: - resolution: {integrity: sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==} - - bare-fs@2.3.5: - resolution: {integrity: sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==} - - bare-os@2.4.4: - resolution: {integrity: sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==} - - bare-path@2.1.3: - resolution: {integrity: sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==} - - bare-stream@2.6.1: - resolution: {integrity: sha512-eVZbtKM+4uehzrsj49KtCy3Pbg7kO1pJ3SKZ1SFrIH/0pnj9scuGGgUlNDf/7qS8WKtGdiJY5Kyhs/ivYPTB/g==} - better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -1107,8 +1049,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - chai@5.1.2: - resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} engines: {node: '>=12'} chalk@4.1.2: @@ -1143,8 +1085,8 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - commander@13.0.0: - resolution: {integrity: sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} commander@4.1.1: @@ -1229,8 +1171,8 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - domutils@3.2.1: - resolution: {integrity: sha512-xWXmuRnN9OMP6ptPd2+H0cCbcYBULa5YDTbMm/2lvkWvNA3O4wcW+GvzooqBuNM8yy6pl3VIAeJTUUWUbfI5Fw==} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} @@ -1252,9 +1194,6 @@ packages: resolution: {integrity: sha512-qtKgI1Mv8rTacvpaTkh28HM2Lbf+IOjXb7rhpt/42kZxRm8TBb/IVlo5iL2ztT19kc/EHAFN0fZ641avlXAgdg==} engines: {node: '>=16'} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enhanced-resolve@5.18.1: resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} engines: {node: '>=10.13.0'} @@ -1270,8 +1209,8 @@ packages: es-module-lexer@1.6.0: resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} - esbuild@0.24.2: - resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + esbuild@0.25.2: + resolution: {integrity: sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==} engines: {node: '>=18'} hasBin: true @@ -1297,28 +1236,24 @@ packages: peerDependencies: eslint: '>=8' - eslint-plugin-n@17.15.1: - resolution: {integrity: sha512-KFw7x02hZZkBdbZEFQduRGH4VkIH4MW97ClsbAM4Y4E6KguBJWGfWG1P4HEIpZk2bkoWf0bojpnjNAhYQP8beA==} + 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.46.1: - resolution: {integrity: sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw==} - engines: {node: ^14.17.0 || >=16.0.0} + eslint-plugin-svelte@3.5.1: + resolution: {integrity: sha512-Qn1slddZHfqYiDO6IN8/iN3YL+VuHlgYjm30FT+hh0Jf/TX0jeZMTJXQMajFm5f6f6hURi+XO8P+NPYD+T4jkg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^7.0.0 || ^8.0.0-0 || ^9.0.0-0 + eslint: ^8.57.1 || ^9.0.0 svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: svelte: optional: true - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-scope@8.2.0: - resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: @@ -1329,8 +1264,8 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.17.0: - resolution: {integrity: sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==} + eslint@9.24.0: + resolution: {integrity: sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -1339,17 +1274,13 @@ packages: jiti: optional: true - esm-env@1.2.1: - resolution: {integrity: sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==} + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} 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: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} @@ -1359,8 +1290,8 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} - esrap@1.4.5: - resolution: {integrity: sha512-CjNMjkBWWZeHn+VX+gS8YvFwJ5+NDhg8aWZBSFJPR8qQduDNjbJodA2WcwCm7uQa5Rjqj+nZvVmceg1RbHFB9g==} + esrap@1.4.6: + resolution: {integrity: sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw==} esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -1383,8 +1314,8 @@ packages: event-stream@3.3.4: resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} - expect-type@1.1.0: - resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} engines: {node: '>=12.0.0'} extendable-error@0.1.7: @@ -1397,11 +1328,8 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: @@ -1410,8 +1338,8 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fastq@1.18.0: - resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} fdir@6.4.3: resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} @@ -1444,14 +1372,11 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatted@3.3.2: - resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} - flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} from@0.1.7: @@ -1482,8 +1407,8 @@ packages: get-tsconfig@4.10.0: resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} - git-hooks-list@3.1.0: - resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==} + git-hooks-list@3.2.0: + resolution: {integrity: sha512-ZHG9a1gEhUMX1TvGrLdyWb9kDopCBbTnI8z4JgRMYxsijWipgjSEYoPWqBuIB0DnRnvqlQSEeVmzpeuPm7NdFQ==} gitignore-parser@0.0.2: resolution: {integrity: sha512-X6mpqUv59uWLGD4n3hZ8Cu8KbF2PMWPSFYmxZjdkpm3yOU7hSUYnzTkZI1mcWqchphvqyuz3/BhgBR4E/JtkCg==} @@ -1532,8 +1457,9 @@ packages: htmlparser2@9.1.0: resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} - human-id@1.0.2: - resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + human-id@4.1.1: + resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} + hasBin: true iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} @@ -1543,8 +1469,8 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} import-meta-resolve@4.1.0: @@ -1581,10 +1507,6 @@ packages: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} - is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -1691,8 +1613,8 @@ packages: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} - mrmime@2.0.0: - resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} ms@2.1.3: @@ -1701,8 +1623,8 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -1722,9 +1644,6 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1770,8 +1689,8 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@0.2.8: - resolution: {integrity: sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==} + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -1796,9 +1715,6 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - pathe@2.0.2: - resolution: {integrity: sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -1827,17 +1743,17 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} - playwright-core@1.49.1: - resolution: {integrity: sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==} + playwright-core@1.51.1: + resolution: {integrity: sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==} engines: {node: '>=18'} hasBin: true - playwright@1.49.1: - resolution: {integrity: sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==} + playwright@1.51.1: + resolution: {integrity: sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==} engines: {node: '>=18'} hasBin: true @@ -1853,11 +1769,11 @@ packages: ts-node: optional: true - postcss-safe-parser@6.0.0: - resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} - engines: {node: '>=12.0'} + postcss-safe-parser@7.0.1: + resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} + engines: {node: '>=18.0'} peerDependencies: - postcss: ^8.3.3 + postcss: ^8.4.31 postcss-scss@4.0.9: resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} @@ -1865,8 +1781,8 @@ packages: peerDependencies: postcss: ^8.4.29 - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} postcss@8.5.3: @@ -1877,16 +1793,16 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-plugin-packagejson@2.5.6: - resolution: {integrity: sha512-TY7KiLtyt6Tlf53BEbXUWkN0+TRdHKgIMmtXtDCyHH6yWnZ50Lwq6Vb6lyjapZrhDTXooC4EtlY5iLe1sCgi5w==} + prettier-plugin-packagejson@2.5.10: + resolution: {integrity: sha512-LUxATI5YsImIVSaaLJlJ3aE6wTD+nvots18U3GuQMJpUyClChaZlQrqx3dBnbhF20OnKWZyx8EgyZypQtBDtgQ==} peerDependencies: prettier: '>= 1.16.0' peerDependenciesMeta: prettier: optional: true - prettier-plugin-svelte@3.3.2: - resolution: {integrity: sha512-kRPjH8wSj2iu+dO+XaUv4vD8qr5mdDmlak3IT/7AOgGIMRG86z/EHOLauFcClKEnOUf4A4nOA7sre5KrJD4Raw==} + prettier-plugin-svelte@3.3.3: + resolution: {integrity: sha512-yViK9zqQ+H2qZD1w/bH7W8i+bVfKrD8GIFjkFe4Thl6kCT9SlAsXVNmt3jCvQOCsnOhcvYgsoVlRV/Eu6x5nNw==} peerDependencies: prettier: ^3.0.0 svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 @@ -1896,8 +1812,8 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.4.2: - resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} engines: {node: '>=14'} hasBin: true @@ -1906,19 +1822,16 @@ packages: engines: {node: '>= 0.10'} hasBin: true - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - queue-tick@1.0.1: - resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} - read-yaml-file@1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} @@ -1937,8 +1850,8 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} rolldown@1.0.0-beta.1: @@ -1950,8 +1863,8 @@ packages: '@babel/runtime': optional: true - rollup@4.34.5: - resolution: {integrity: sha512-GyVCmpo9z/HYqFD8QWoBUnz1Q9xC22t8tPAZm/AvAcUg2U2/+DkboEvSioMwv042zE4I9N3FEhx7fiCT2YHzKQ==} + rollup@4.39.0: + resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1998,8 +1911,8 @@ packages: sort-object-keys@1.1.3: resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} - sort-package-json@2.12.0: - resolution: {integrity: sha512-/HrPQAeeLaa+vbAH/znjuhwUluuiM/zL5XX9kop8UpDgjtyWKt43hGDk2vd/TBdDpzIyzIHVUgmYofzYrAQjew==} + sort-package-json@2.15.1: + resolution: {integrity: sha512-9x9+o8krTT2saA9liI4BljNjwAbvUnWf11Wq+i/iZt8nl2UGYnf3TH5uBydE7VALmP7AGwlfszuEeL8BDyb0YA==} hasBin: true source-map-js@1.2.1: @@ -2018,15 +1931,12 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - std-env@3.8.0: - resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} stream-combiner@0.0.4: resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} - streamx@2.21.1: - resolution: {integrity: sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2060,9 +1970,9 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - svelte-eslint-parser@0.43.0: - resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + svelte-eslint-parser@1.1.2: + resolution: {integrity: sha512-vqFBRamDKo1l70KMfxxXj1/0Cco5TfMDnqaAjgz6D8PyoMhfMcDOLRkAwPg8WkMyZjMtQL3wW66TZ0x59iqO2w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: @@ -2073,8 +1983,8 @@ packages: resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==} engines: {node: '>=16'} - svelte@5.16.0: - resolution: {integrity: sha512-Ygqsiac6UogVED2ruKclU+pOeMThxWtp9LG+li7BXeDKC2paVIsRTMkNmcON4Zejerd1s5sZHWx6ZtU85xklVg==} + svelte@5.25.7: + resolution: {integrity: sha512-0fzXbXaKfSvFUs6Wxev2h4CoEhexZotbTF9EJ4+Cg7MHW64ZnZ9+xUedZyEpgj0Tt9HrYGv9aASHkqjn9b/cPw==} engines: {node: '>=18'} synckit@0.9.2: @@ -2085,19 +1995,10 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tar-fs@3.0.6: - resolution: {integrity: sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==} - - tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} - term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} - text-decoder@1.2.3: - resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} - thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -2117,10 +2018,6 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.10: - resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.12: resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} engines: {node: '>=12.0.0'} @@ -2152,11 +2049,11 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - ts-api-utils@1.4.3: - resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} - engines: {node: '>=16'} + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} peerDependencies: - typescript: '>=4.2.0' + typescript: '>=4.8.4' ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -2171,23 +2068,23 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.18.2: - resolution: {integrity: sha512-KuXezG6jHkvC3MvizeXgupZzaG5wjhU3yE8E7e6viOvAvD9xAWYp8/vy0WULTGe9DYDWcQu7aW03YIV3mSitrQ==} + typescript-eslint@8.29.0: + resolution: {integrity: sha512-ep9rVd9B4kQsZ7ZnWCVxUE/xDLUUUsRzE0poAeNu+4CkFErLfuvPt/qtm2EpnSyfvsR0S6QzDFSrPCFBwf64fg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - typescript@5.7.2: - resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} @@ -2208,8 +2105,8 @@ packages: typescript: optional: true - unplugin@1.16.0: - resolution: {integrity: sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==} + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} engines: {node: '>=14.0.0'} uri-js@4.4.1: @@ -2226,13 +2123,13 @@ packages: typescript: optional: true - vite-node@3.0.5: - resolution: {integrity: sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==} + vite-node@3.0.9: + resolution: {integrity: sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@6.1.0: - resolution: {integrity: sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==} + vite@6.2.5: + resolution: {integrity: sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -2271,16 +2168,16 @@ packages: yaml: optional: true - vitest@3.0.5: - resolution: {integrity: sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==} + vitest@3.0.9: + resolution: {integrity: sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.0.5 - '@vitest/ui': 3.0.5 + '@vitest/browser': 3.0.9 + '@vitest/ui': 3.0.9 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -2330,9 +2227,6 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} @@ -2344,8 +2238,8 @@ packages: zimmerframe@1.1.2: resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} - zod@3.24.1: - resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} + zod@3.24.2: + resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} snapshots: @@ -2354,17 +2248,17 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - '@babel/runtime@7.26.0': + '@babel/runtime@7.27.0': dependencies: regenerator-runtime: 0.14.1 - '@changesets/apply-release-plan@7.0.7': + '@changesets/apply-release-plan@7.0.10': dependencies: - '@changesets/config': 3.0.5 + '@changesets/config': 3.1.1 '@changesets/get-version-range-type': 0.4.0 '@changesets/git': 3.0.2 - '@changesets/should-skip-package': 0.1.1 - '@changesets/types': 6.0.0 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 fs-extra: 7.0.1 @@ -2374,35 +2268,35 @@ snapshots: resolve-from: 5.0.0 semver: 7.7.1 - '@changesets/assemble-release-plan@6.0.5': + '@changesets/assemble-release-plan@6.0.6': dependencies: '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.2 - '@changesets/should-skip-package': 0.1.1 - '@changesets/types': 6.0.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 semver: 7.7.1 - '@changesets/changelog-git@0.2.0': + '@changesets/changelog-git@0.2.1': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 - '@changesets/cli@2.27.11': + '@changesets/cli@2.28.1': dependencies: - '@changesets/apply-release-plan': 7.0.7 - '@changesets/assemble-release-plan': 6.0.5 - '@changesets/changelog-git': 0.2.0 - '@changesets/config': 3.0.5 + '@changesets/apply-release-plan': 7.0.10 + '@changesets/assemble-release-plan': 6.0.6 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.1 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.2 - '@changesets/get-release-plan': 4.0.6 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/get-release-plan': 4.0.8 '@changesets/git': 3.0.2 '@changesets/logger': 0.1.1 - '@changesets/pre': 2.0.1 - '@changesets/read': 0.6.2 - '@changesets/should-skip-package': 0.1.1 - '@changesets/types': 6.0.0 - '@changesets/write': 0.3.2 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 ci-info: 3.9.0 @@ -2411,19 +2305,19 @@ snapshots: fs-extra: 7.0.1 mri: 1.2.0 p-limit: 2.3.0 - package-manager-detector: 0.2.8 + package-manager-detector: 0.2.11 picocolors: 1.1.1 resolve-from: 5.0.0 semver: 7.7.1 spawndamnit: 3.0.1 term-size: 2.2.1 - '@changesets/config@3.0.5': + '@changesets/config@3.1.1': dependencies: '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-dependents-graph': 2.1.3 '@changesets/logger': 0.1.1 - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 micromatch: 4.0.8 @@ -2432,9 +2326,9 @@ snapshots: dependencies: extendable-error: 0.1.7 - '@changesets/get-dependents-graph@2.1.2': + '@changesets/get-dependents-graph@2.1.3': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 picocolors: 1.1.1 semver: 7.7.1 @@ -2446,13 +2340,13 @@ snapshots: transitivePeerDependencies: - encoding - '@changesets/get-release-plan@4.0.6': + '@changesets/get-release-plan@4.0.8': dependencies: - '@changesets/assemble-release-plan': 6.0.5 - '@changesets/config': 3.0.5 - '@changesets/pre': 2.0.1 - '@changesets/read': 0.6.2 - '@changesets/types': 6.0.0 + '@changesets/assemble-release-plan': 6.0.6 + '@changesets/config': 3.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.3 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 '@changesets/get-version-range-type@0.4.0': {} @@ -2469,62 +2363,73 @@ snapshots: dependencies: picocolors: 1.1.1 - '@changesets/parse@0.4.0': + '@changesets/parse@0.4.1': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 js-yaml: 3.14.1 - '@changesets/pre@2.0.1': + '@changesets/pre@2.0.2': dependencies: '@changesets/errors': 0.2.0 - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.2': + '@changesets/read@0.6.3': dependencies: '@changesets/git': 3.0.2 '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.0 - '@changesets/types': 6.0.0 + '@changesets/parse': 0.4.1 + '@changesets/types': 6.1.0 fs-extra: 7.0.1 p-filter: 2.1.0 picocolors: 1.1.1 - '@changesets/should-skip-package@0.1.1': + '@changesets/should-skip-package@0.1.2': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 '@changesets/types@4.1.0': {} - '@changesets/types@6.0.0': {} + '@changesets/types@6.1.0': {} - '@changesets/write@0.3.2': + '@changesets/write@0.4.0': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 fs-extra: 7.0.1 - human-id: 1.0.2 + human-id: 4.1.1 prettier: 2.8.8 - '@clack/core@0.4.0': + '@clack/core@1.0.0-alpha.0': + dependencies: + picocolors: 1.1.1 + sisteransi: 1.0.5 + + '@clack/core@1.0.0-alpha.1': + dependencies: + picocolors: 1.1.1 + sisteransi: 1.0.5 + + '@clack/prompts@1.0.0-alpha.0': dependencies: + '@clack/core': 1.0.0-alpha.0 picocolors: 1.1.1 sisteransi: 1.0.5 - '@clack/prompts@0.9.0': + '@clack/prompts@1.0.0-alpha.1': dependencies: - '@clack/core': 0.4.0 + '@clack/core': 1.0.0-alpha.1 picocolors: 1.1.1 sisteransi: 1.0.5 - '@emnapi/core@1.3.1': + '@emnapi/core@1.4.0': dependencies: '@emnapi/wasi-threads': 1.0.1 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.3.1': + '@emnapi/runtime@1.4.0': dependencies: tslib: 2.8.1 optional: true @@ -2534,120 +2439,127 @@ snapshots: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.24.2': + '@esbuild/aix-ppc64@0.25.2': optional: true - '@esbuild/android-arm64@0.24.2': + '@esbuild/android-arm64@0.25.2': optional: true - '@esbuild/android-arm@0.24.2': + '@esbuild/android-arm@0.25.2': optional: true - '@esbuild/android-x64@0.24.2': + '@esbuild/android-x64@0.25.2': optional: true - '@esbuild/darwin-arm64@0.24.2': + '@esbuild/darwin-arm64@0.25.2': optional: true - '@esbuild/darwin-x64@0.24.2': + '@esbuild/darwin-x64@0.25.2': optional: true - '@esbuild/freebsd-arm64@0.24.2': + '@esbuild/freebsd-arm64@0.25.2': optional: true - '@esbuild/freebsd-x64@0.24.2': + '@esbuild/freebsd-x64@0.25.2': optional: true - '@esbuild/linux-arm64@0.24.2': + '@esbuild/linux-arm64@0.25.2': optional: true - '@esbuild/linux-arm@0.24.2': + '@esbuild/linux-arm@0.25.2': optional: true - '@esbuild/linux-ia32@0.24.2': + '@esbuild/linux-ia32@0.25.2': optional: true - '@esbuild/linux-loong64@0.24.2': + '@esbuild/linux-loong64@0.25.2': optional: true - '@esbuild/linux-mips64el@0.24.2': + '@esbuild/linux-mips64el@0.25.2': optional: true - '@esbuild/linux-ppc64@0.24.2': + '@esbuild/linux-ppc64@0.25.2': optional: true - '@esbuild/linux-riscv64@0.24.2': + '@esbuild/linux-riscv64@0.25.2': optional: true - '@esbuild/linux-s390x@0.24.2': + '@esbuild/linux-s390x@0.25.2': optional: true - '@esbuild/linux-x64@0.24.2': + '@esbuild/linux-x64@0.25.2': optional: true - '@esbuild/netbsd-arm64@0.24.2': + '@esbuild/netbsd-arm64@0.25.2': optional: true - '@esbuild/netbsd-x64@0.24.2': + '@esbuild/netbsd-x64@0.25.2': optional: true - '@esbuild/openbsd-arm64@0.24.2': + '@esbuild/openbsd-arm64@0.25.2': optional: true - '@esbuild/openbsd-x64@0.24.2': + '@esbuild/openbsd-x64@0.25.2': optional: true - '@esbuild/sunos-x64@0.24.2': + '@esbuild/sunos-x64@0.25.2': optional: true - '@esbuild/win32-arm64@0.24.2': + '@esbuild/win32-arm64@0.25.2': optional: true - '@esbuild/win32-ia32@0.24.2': + '@esbuild/win32-ia32@0.25.2': optional: true - '@esbuild/win32-x64@0.24.2': + '@esbuild/win32-x64@0.25.2': optional: true - '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0)': + '@eslint-community/eslint-utils@4.5.1(eslint@9.24.0)': dependencies: - eslint: 9.17.0 + eslint: 9.24.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.19.1': + '@eslint/config-array@0.20.0': dependencies: - '@eslint/object-schema': 2.1.5 + '@eslint/object-schema': 2.1.6 debug: 4.4.0 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/core@0.9.1': + '@eslint/config-helpers@0.2.1': {} + + '@eslint/core@0.12.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/core@0.13.0': dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.2.0': + '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 debug: 4.4.0 espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 - import-fresh: 3.3.0 + import-fresh: 3.3.1 js-yaml: 4.1.0 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.17.0': {} + '@eslint/js@9.24.0': {} - '@eslint/object-schema@2.1.5': {} + '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.2.4': + '@eslint/plugin-kit@0.2.8': dependencies: + '@eslint/core': 0.13.0 levn: 0.4.1 '@humanfs/core@0.19.1': {} @@ -2661,7 +2573,7 @@ snapshots: '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.1': {} + '@humanwhocodes/retry@0.4.2': {} '@isaacs/cliui@8.0.2': dependencies: @@ -2691,24 +2603,24 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.26.0 + '@babel/runtime': 7.27.0 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.26.0 + '@babel/runtime': 7.27.0 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 globby: 11.1.0 read-yaml-file: 1.1.0 - '@napi-rs/wasm-runtime@0.2.6': + '@napi-rs/wasm-runtime@0.2.8': dependencies: - '@emnapi/core': 1.3.1 - '@emnapi/runtime': 1.3.1 + '@emnapi/core': 1.4.0 + '@emnapi/runtime': 1.4.0 '@tybys/wasm-util': 0.9.0 optional: true @@ -2722,7 +2634,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.18.0 + fastq: 1.19.1 '@oxc-parser/binding-darwin-arm64@0.37.0': optional: true @@ -2753,11 +2665,11 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pkgr/core@0.1.1': {} + '@pkgr/core@0.1.2': {} - '@playwright/test@1.49.1': + '@playwright/test@1.51.1': dependencies: - playwright: 1.49.1 + playwright: 1.51.1 '@polka/url@1.0.0-next.28': {} @@ -2787,7 +2699,7 @@ snapshots: '@rolldown/binding-wasm32-wasi@1.0.0-beta.1': dependencies: - '@napi-rs/wasm-runtime': 0.2.6 + '@napi-rs/wasm-runtime': 0.2.8 optional: true '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.1': @@ -2799,91 +2711,94 @@ snapshots: '@rolldown/binding-win32-x64-msvc@1.0.0-beta.1': optional: true - '@rollup/pluginutils@5.1.3(rollup@4.34.5)': + '@rollup/pluginutils@5.1.4(rollup@4.39.0)': dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 estree-walker: 2.0.2 picomatch: 4.0.2 optionalDependencies: - rollup: 4.34.5 + rollup: 4.39.0 + + '@rollup/rollup-android-arm-eabi@4.39.0': + optional: true - '@rollup/rollup-android-arm-eabi@4.34.5': + '@rollup/rollup-android-arm64@4.39.0': optional: true - '@rollup/rollup-android-arm64@4.34.5': + '@rollup/rollup-darwin-arm64@4.39.0': optional: true - '@rollup/rollup-darwin-arm64@4.34.5': + '@rollup/rollup-darwin-x64@4.39.0': optional: true - '@rollup/rollup-darwin-x64@4.34.5': + '@rollup/rollup-freebsd-arm64@4.39.0': optional: true - '@rollup/rollup-freebsd-arm64@4.34.5': + '@rollup/rollup-freebsd-x64@4.39.0': optional: true - '@rollup/rollup-freebsd-x64@4.34.5': + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.34.5': + '@rollup/rollup-linux-arm-musleabihf@4.39.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.34.5': + '@rollup/rollup-linux-arm64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.34.5': + '@rollup/rollup-linux-arm64-musl@4.39.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.34.5': + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.34.5': + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.34.5': + '@rollup/rollup-linux-riscv64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.34.5': + '@rollup/rollup-linux-riscv64-musl@4.39.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.34.5': + '@rollup/rollup-linux-s390x-gnu@4.39.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.34.5': + '@rollup/rollup-linux-x64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-x64-musl@4.34.5': + '@rollup/rollup-linux-x64-musl@4.39.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.34.5': + '@rollup/rollup-win32-arm64-msvc@4.39.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.34.5': + '@rollup/rollup-win32-ia32-msvc@4.39.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.34.5': + '@rollup/rollup-win32-x64-msvc@4.39.0': optional: true - '@stylistic/eslint-plugin-js@2.12.1(eslint@9.17.0)': + '@stylistic/eslint-plugin-js@2.10.1(eslint@9.24.0)': dependencies: - eslint: 9.17.0 + eslint: 9.24.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 - '@sveltejs/acorn-typescript@1.0.1(acorn@8.14.0)': + '@sveltejs/acorn-typescript@1.0.5(acorn@8.14.1)': dependencies: - acorn: 8.14.0 + acorn: 8.14.1 - '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.12.1(eslint@9.17.0))(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint-plugin-n@17.15.1(eslint@9.17.0))(eslint-plugin-svelte@2.46.1(eslint@9.17.0)(svelte@5.16.0))(eslint@9.17.0)(typescript-eslint@8.18.2(eslint@9.17.0)(typescript@5.7.2))(typescript@5.7.2)': + '@sveltejs/eslint-config@8.2.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.24.0))(eslint-config-prettier@9.1.0(eslint@9.24.0))(eslint-plugin-n@17.13.1(eslint@9.24.0))(eslint-plugin-svelte@3.5.1(eslint@9.24.0)(svelte@5.25.7))(eslint@9.24.0)(typescript-eslint@8.29.0(eslint@9.24.0)(typescript@5.8.3))(typescript@5.8.3)': dependencies: - '@stylistic/eslint-plugin-js': 2.12.1(eslint@9.17.0) - eslint: 9.17.0 - eslint-config-prettier: 9.1.0(eslint@9.17.0) - eslint-plugin-n: 17.15.1(eslint@9.17.0) - eslint-plugin-svelte: 2.46.1(eslint@9.17.0)(svelte@5.16.0) + '@stylistic/eslint-plugin-js': 2.10.1(eslint@9.24.0) + eslint: 9.24.0 + eslint-config-prettier: 9.1.0(eslint@9.24.0) + eslint-plugin-n: 17.13.1(eslint@9.24.0) + eslint-plugin-svelte: 3.5.1(eslint@9.24.0)(svelte@5.25.7) globals: 15.15.0 - typescript: 5.7.2 - typescript-eslint: 8.18.2(eslint@9.17.0)(typescript@5.7.2) + typescript: 5.8.3 + typescript-eslint: 8.29.0(eslint@9.24.0)(typescript@5.8.3) '@svitejs/changesets-changelog-github-compact@1.2.0': dependencies: @@ -2896,7 +2811,7 @@ snapshots: dependencies: minimatch: 9.0.5 path-browserify: 1.0.1 - tinyglobby: 0.2.10 + tinyglobby: 0.2.12 '@tybys/wasm-util@0.9.0': dependencies: @@ -2905,7 +2820,7 @@ snapshots: '@types/degit@2.8.6': {} - '@types/estree@1.0.6': {} + '@types/estree@1.0.7': {} '@types/gitignore-parser@0.0.3': {} @@ -2913,160 +2828,139 @@ snapshots: '@types/node@12.20.55': {} - '@types/node@18.19.68': + '@types/node@18.19.86': dependencies: undici-types: 5.26.5 - '@types/node@22.10.2': + '@types/node@22.14.0': dependencies: - undici-types: 6.20.0 + undici-types: 6.21.0 '@types/prompts@2.4.9': dependencies: - '@types/node': 22.10.2 + '@types/node': 22.14.0 kleur: 3.0.3 '@types/ps-tree@1.1.6': {} - '@types/semver@7.5.8': {} - - '@types/tar-fs@2.0.4': - dependencies: - '@types/node': 22.10.2 - '@types/tar-stream': 3.1.3 - - '@types/tar-stream@3.1.3': - dependencies: - '@types/node': 22.10.2 + '@types/semver@7.7.0': {} - '@typescript-eslint/eslint-plugin@8.18.2(@typescript-eslint/parser@8.18.2(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.18.2(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/scope-manager': 8.18.2 - '@typescript-eslint/type-utils': 8.18.2(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.18.2(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/visitor-keys': 8.18.2 - eslint: 9.17.0 + '@typescript-eslint/parser': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/type-utils': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/utils': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.29.0 + eslint: 9.24.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.4.3(typescript@5.7.2) - typescript: 5.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.18.2(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/parser@8.29.0(eslint@9.24.0)(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.18.2 - '@typescript-eslint/types': 8.18.2 - '@typescript-eslint/typescript-estree': 8.18.2(typescript@5.7.2) - '@typescript-eslint/visitor-keys': 8.18.2 + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.29.0 debug: 4.4.0 - eslint: 9.17.0 - typescript: 5.7.2 + eslint: 9.24.0 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.18.2': + '@typescript-eslint/scope-manager@8.29.0': dependencies: - '@typescript-eslint/types': 8.18.2 - '@typescript-eslint/visitor-keys': 8.18.2 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/visitor-keys': 8.29.0 - '@typescript-eslint/type-utils@8.18.2(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/type-utils@8.29.0(eslint@9.24.0)(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.18.2(typescript@5.7.2) - '@typescript-eslint/utils': 8.18.2(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.29.0(eslint@9.24.0)(typescript@5.8.3) debug: 4.4.0 - eslint: 9.17.0 - ts-api-utils: 1.4.3(typescript@5.7.2) - typescript: 5.7.2 + eslint: 9.24.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.18.2': {} + '@typescript-eslint/types@8.29.0': {} - '@typescript-eslint/typescript-estree@8.18.2(typescript@5.7.2)': + '@typescript-eslint/typescript-estree@8.29.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.18.2 - '@typescript-eslint/visitor-keys': 8.18.2 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/visitor-keys': 8.29.0 debug: 4.4.0 - fast-glob: 3.3.2 + fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.1 - ts-api-utils: 1.4.3(typescript@5.7.2) - typescript: 5.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.18.2(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/utils@8.29.0(eslint@9.24.0)(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) - '@typescript-eslint/scope-manager': 8.18.2 - '@typescript-eslint/types': 8.18.2 - '@typescript-eslint/typescript-estree': 8.18.2(typescript@5.7.2) - eslint: 9.17.0 - typescript: 5.7.2 + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.3) + eslint: 9.24.0 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.18.2': + '@typescript-eslint/visitor-keys@8.29.0': dependencies: - '@typescript-eslint/types': 8.18.2 + '@typescript-eslint/types': 8.29.0 eslint-visitor-keys: 4.2.0 - '@vitest/expect@3.0.5': + '@vitest/expect@3.0.9': dependencies: - '@vitest/spy': 3.0.5 - '@vitest/utils': 3.0.5 - chai: 5.1.2 + '@vitest/spy': 3.0.9 + '@vitest/utils': 3.0.9 + chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.5(vite@6.1.0(@types/node@22.10.2))': + '@vitest/mocker@3.0.9(vite@6.2.5(@types/node@22.14.0))': dependencies: - '@vitest/spy': 3.0.5 + '@vitest/spy': 3.0.9 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.1.0(@types/node@22.10.2) + vite: 6.2.5(@types/node@22.14.0) - '@vitest/pretty-format@3.0.5': + '@vitest/pretty-format@3.0.9': dependencies: tinyrainbow: 2.0.0 - '@vitest/pretty-format@3.0.9': + '@vitest/pretty-format@3.1.1': dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@3.0.5': + '@vitest/runner@3.0.9': dependencies: - '@vitest/utils': 3.0.5 - pathe: 2.0.2 + '@vitest/utils': 3.0.9 + pathe: 2.0.3 - '@vitest/snapshot@3.0.5': + '@vitest/snapshot@3.0.9': dependencies: - '@vitest/pretty-format': 3.0.5 + '@vitest/pretty-format': 3.0.9 magic-string: 0.30.17 - pathe: 2.0.2 + pathe: 2.0.3 - '@vitest/spy@3.0.5': + '@vitest/spy@3.0.9': dependencies: tinyspy: 3.0.2 - '@vitest/ui@3.0.5(vitest@3.0.5)': - dependencies: - '@vitest/utils': 3.0.5 - fflate: 0.8.2 - flatted: 3.3.3 - pathe: 2.0.3 - sirv: 3.0.1 - tinyglobby: 0.2.12 - tinyrainbow: 2.0.0 - vitest: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.5) - optional: true - - '@vitest/ui@3.0.9(vitest@3.0.5)': + '@vitest/ui@3.0.9(vitest@3.0.9)': dependencies: '@vitest/utils': 3.0.9 fflate: 0.8.2 @@ -3075,13 +2969,7 @@ snapshots: sirv: 3.0.1 tinyglobby: 0.2.12 tinyrainbow: 2.0.0 - vitest: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.9) - - '@vitest/utils@3.0.5': - dependencies: - '@vitest/pretty-format': 3.0.5 - loupe: 3.1.3 - tinyrainbow: 2.0.0 + vitest: 3.0.9(@types/node@22.14.0)(@vitest/ui@3.0.9) '@vitest/utils@3.0.9': dependencies: @@ -3089,15 +2977,11 @@ snapshots: loupe: 3.1.3 tinyrainbow: 2.0.0 - acorn-jsx@5.3.2(acorn@8.14.0): - dependencies: - acorn: 8.14.0 - - acorn-typescript@1.4.13(acorn@8.14.0): + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: - acorn: 8.14.0 + acorn: 8.14.1 - acorn@8.14.0: {} + acorn@8.14.1: {} ajv@6.12.6: dependencies: @@ -3134,33 +3018,8 @@ snapshots: axobject-query@4.1.0: {} - b4a@1.6.7: {} - balanced-match@1.0.2: {} - bare-events@2.5.0: - optional: true - - bare-fs@2.3.5: - dependencies: - bare-events: 2.5.0 - bare-path: 2.1.3 - bare-stream: 2.6.1 - optional: true - - bare-os@2.4.4: - optional: true - - bare-path@2.1.3: - dependencies: - bare-os: 2.4.4 - optional: true - - bare-stream@2.6.1: - dependencies: - streamx: 2.21.1 - optional: true - better-path-resolve@1.0.0: dependencies: is-windows: 1.0.2 @@ -3182,7 +3041,7 @@ snapshots: callsites@3.1.0: {} - chai@5.1.2: + chai@5.2.0: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 @@ -3208,8 +3067,8 @@ snapshots: code-red@1.0.4: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 - '@types/estree': 1.0.6 - acorn: 8.14.0 + '@types/estree': 1.0.7 + acorn: 8.14.1 estree-walker: 3.0.3 periscopic: 3.1.0 @@ -3219,7 +3078,7 @@ snapshots: color-name@1.1.4: {} - commander@13.0.0: {} + commander@13.1.0: {} commander@4.1.1: {} @@ -3276,7 +3135,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - domutils@3.2.1: + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 domelementtype: 2.3.0 @@ -3294,10 +3153,6 @@ snapshots: empathic@1.0.0: {} - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - enhanced-resolve@5.18.1: dependencies: graceful-fs: 4.2.11 @@ -3312,89 +3167,82 @@ snapshots: es-module-lexer@1.6.0: {} - esbuild@0.24.2: + esbuild@0.25.2: optionalDependencies: - '@esbuild/aix-ppc64': 0.24.2 - '@esbuild/android-arm': 0.24.2 - '@esbuild/android-arm64': 0.24.2 - '@esbuild/android-x64': 0.24.2 - '@esbuild/darwin-arm64': 0.24.2 - '@esbuild/darwin-x64': 0.24.2 - '@esbuild/freebsd-arm64': 0.24.2 - '@esbuild/freebsd-x64': 0.24.2 - '@esbuild/linux-arm': 0.24.2 - '@esbuild/linux-arm64': 0.24.2 - '@esbuild/linux-ia32': 0.24.2 - '@esbuild/linux-loong64': 0.24.2 - '@esbuild/linux-mips64el': 0.24.2 - '@esbuild/linux-ppc64': 0.24.2 - '@esbuild/linux-riscv64': 0.24.2 - '@esbuild/linux-s390x': 0.24.2 - '@esbuild/linux-x64': 0.24.2 - '@esbuild/netbsd-arm64': 0.24.2 - '@esbuild/netbsd-x64': 0.24.2 - '@esbuild/openbsd-arm64': 0.24.2 - '@esbuild/openbsd-x64': 0.24.2 - '@esbuild/sunos-x64': 0.24.2 - '@esbuild/win32-arm64': 0.24.2 - '@esbuild/win32-ia32': 0.24.2 - '@esbuild/win32-x64': 0.24.2 + '@esbuild/aix-ppc64': 0.25.2 + '@esbuild/android-arm': 0.25.2 + '@esbuild/android-arm64': 0.25.2 + '@esbuild/android-x64': 0.25.2 + '@esbuild/darwin-arm64': 0.25.2 + '@esbuild/darwin-x64': 0.25.2 + '@esbuild/freebsd-arm64': 0.25.2 + '@esbuild/freebsd-x64': 0.25.2 + '@esbuild/linux-arm': 0.25.2 + '@esbuild/linux-arm64': 0.25.2 + '@esbuild/linux-ia32': 0.25.2 + '@esbuild/linux-loong64': 0.25.2 + '@esbuild/linux-mips64el': 0.25.2 + '@esbuild/linux-ppc64': 0.25.2 + '@esbuild/linux-riscv64': 0.25.2 + '@esbuild/linux-s390x': 0.25.2 + '@esbuild/linux-x64': 0.25.2 + '@esbuild/netbsd-arm64': 0.25.2 + '@esbuild/netbsd-x64': 0.25.2 + '@esbuild/openbsd-arm64': 0.25.2 + '@esbuild/openbsd-x64': 0.25.2 + '@esbuild/sunos-x64': 0.25.2 + '@esbuild/win32-arm64': 0.25.2 + '@esbuild/win32-ia32': 0.25.2 + '@esbuild/win32-x64': 0.25.2 escape-string-regexp@4.0.0: {} - eslint-compat-utils@0.5.1(eslint@9.17.0): + eslint-compat-utils@0.5.1(eslint@9.24.0): dependencies: - eslint: 9.17.0 + eslint: 9.24.0 semver: 7.7.1 - eslint-config-prettier@9.1.0(eslint@9.17.0): + eslint-config-prettier@9.1.0(eslint@9.24.0): dependencies: - eslint: 9.17.0 + eslint: 9.24.0 - eslint-plugin-es-x@7.8.0(eslint@9.17.0): + eslint-plugin-es-x@7.8.0(eslint@9.24.0): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) '@eslint-community/regexpp': 4.12.1 - eslint: 9.17.0 - eslint-compat-utils: 0.5.1(eslint@9.17.0) + eslint: 9.24.0 + eslint-compat-utils: 0.5.1(eslint@9.24.0) - eslint-plugin-n@17.15.1(eslint@9.17.0): + eslint-plugin-n@17.13.1(eslint@9.24.0): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) enhanced-resolve: 5.18.1 - eslint: 9.17.0 - eslint-plugin-es-x: 7.8.0(eslint@9.17.0) + eslint: 9.24.0 + eslint-plugin-es-x: 7.8.0(eslint@9.24.0) get-tsconfig: 4.10.0 globals: 15.15.0 ignore: 5.3.2 minimatch: 9.0.5 semver: 7.7.1 - eslint-plugin-svelte@2.46.1(eslint@9.17.0)(svelte@5.16.0): + eslint-plugin-svelte@3.5.1(eslint@9.24.0)(svelte@5.25.7): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) '@jridgewell/sourcemap-codec': 1.5.0 - eslint: 9.17.0 - eslint-compat-utils: 0.5.1(eslint@9.17.0) + eslint: 9.24.0 esutils: 2.0.3 known-css-properties: 0.35.0 postcss: 8.5.3 postcss-load-config: 3.1.4(postcss@8.5.3) - postcss-safe-parser: 6.0.0(postcss@8.5.3) - postcss-selector-parser: 6.1.2 + postcss-safe-parser: 7.0.1(postcss@8.5.3) semver: 7.7.1 - svelte-eslint-parser: 0.43.0(svelte@5.16.0) + svelte-eslint-parser: 1.1.2(svelte@5.25.7) optionalDependencies: - svelte: 5.16.0 + svelte: 5.25.7 transitivePeerDependencies: - ts-node - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-scope@8.2.0: + eslint-scope@8.3.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 @@ -3403,26 +3251,27 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.17.0: + eslint@9.24.0: dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.19.1 - '@eslint/core': 0.9.1 - '@eslint/eslintrc': 3.2.0 - '@eslint/js': 9.17.0 - '@eslint/plugin-kit': 0.2.4 + '@eslint/config-array': 0.20.0 + '@eslint/config-helpers': 0.2.1 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.24.0 + '@eslint/plugin-kit': 0.2.8 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.1 - '@types/estree': 1.0.6 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.7 '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.0 escape-string-regexp: 4.0.0 - eslint-scope: 8.2.0 + eslint-scope: 8.3.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 esquery: 1.6.0 @@ -3442,27 +3291,21 @@ snapshots: transitivePeerDependencies: - supports-color - esm-env@1.2.1: {} + esm-env@1.2.2: {} espree@10.3.0: dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 4.2.0 - espree@9.6.1: - dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) - eslint-visitor-keys: 3.4.3 - esprima@4.0.1: {} esquery@1.6.0: dependencies: estraverse: 5.3.0 - esrap@1.4.5: + esrap@1.4.6: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -3476,7 +3319,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 esutils@2.0.3: {} @@ -3490,7 +3333,7 @@ snapshots: stream-combiner: 0.0.4 through: 2.3.8 - expect-type@1.1.0: {} + expect-type@1.2.1: {} extendable-error@0.1.7: {} @@ -3502,9 +3345,7 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-fifo@1.3.2: {} - - fast-glob@3.3.2: + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 @@ -3516,9 +3357,9 @@ snapshots: fast-levenshtein@2.0.6: {} - fastq@1.18.0: + fastq@1.19.1: dependencies: - reusify: 1.0.4 + reusify: 1.1.0 fdir@6.4.3(picomatch@4.0.2): optionalDependencies: @@ -3546,14 +3387,12 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.3.2 + flatted: 3.3.3 keyv: 4.5.4 - flatted@3.3.2: {} - flatted@3.3.3: {} - foreground-child@3.3.0: + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 signal-exit: 4.1.0 @@ -3584,7 +3423,7 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - git-hooks-list@3.1.0: {} + git-hooks-list@3.2.0: {} gitignore-parser@0.0.2: {} @@ -3598,7 +3437,7 @@ snapshots: glob@10.4.5: dependencies: - foreground-child: 3.3.0 + foreground-child: 3.3.1 jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 @@ -3615,7 +3454,7 @@ snapshots: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.2 + fast-glob: 3.3.3 ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 @@ -3632,10 +3471,10 @@ snapshots: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.2.1 + domutils: 3.2.2 entities: 4.5.0 - human-id@1.0.2: {} + human-id@4.1.1: {} iconv-lite@0.4.24: dependencies: @@ -3643,7 +3482,7 @@ snapshots: ignore@5.3.2: {} - import-fresh@3.3.0: + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 @@ -3666,14 +3505,12 @@ snapshots: is-reference@3.0.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 is-subdir@1.2.0: dependencies: better-path-resolve: 1.0.0 - is-unicode-supported@1.3.0: {} - is-windows@1.0.2: {} isexe@2.0.0: {} @@ -3765,7 +3602,7 @@ snapshots: mri@1.2.0: {} - mrmime@2.0.0: {} + mrmime@2.0.1: {} ms@2.1.3: {} @@ -3775,7 +3612,7 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nanoid@3.3.8: {} + nanoid@3.3.11: {} natural-compare@1.4.0: {} @@ -3785,10 +3622,6 @@ snapshots: object-assign@4.1.1: {} - once@1.4.0: - dependencies: - wrappy: 1.0.2 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -3841,7 +3674,9 @@ snapshots: package-json-from-dist@1.0.1: {} - package-manager-detector@0.2.8: {} + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.10 parent-module@1.0.1: dependencies: @@ -3860,8 +3695,6 @@ snapshots: path-type@4.0.0: {} - pathe@2.0.2: {} - pathe@2.0.3: {} pathval@2.0.0: {} @@ -3872,7 +3705,7 @@ snapshots: periscopic@3.1.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 estree-walker: 3.0.3 is-reference: 3.0.3 @@ -3884,13 +3717,13 @@ snapshots: pify@4.0.1: {} - pirates@4.0.6: {} + pirates@4.0.7: {} - playwright-core@1.49.1: {} + playwright-core@1.51.1: {} - playwright@1.49.1: + playwright@1.51.1: dependencies: - playwright-core: 1.49.1 + playwright-core: 1.51.1 optionalDependencies: fsevents: 2.3.2 @@ -3901,7 +3734,7 @@ snapshots: optionalDependencies: postcss: 8.5.3 - postcss-safe-parser@6.0.0(postcss@8.5.3): + postcss-safe-parser@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -3909,49 +3742,44 @@ snapshots: dependencies: postcss: 8.5.3 - postcss-selector-parser@6.1.2: + postcss-selector-parser@7.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 postcss@8.5.3: dependencies: - nanoid: 3.3.8 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 prelude-ls@1.2.1: {} - prettier-plugin-packagejson@2.5.6(prettier@3.4.2): + prettier-plugin-packagejson@2.5.10(prettier@3.5.3): dependencies: - sort-package-json: 2.12.0 + sort-package-json: 2.15.1 synckit: 0.9.2 optionalDependencies: - prettier: 3.4.2 + prettier: 3.5.3 - prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.16.0): + prettier-plugin-svelte@3.3.3(prettier@3.5.3)(svelte@5.25.7): dependencies: - prettier: 3.4.2 - svelte: 5.16.0 + prettier: 3.5.3 + svelte: 5.25.7 prettier@2.8.8: {} - prettier@3.4.2: {} + prettier@3.5.3: {} ps-tree@1.2.0: dependencies: event-stream: 3.3.4 - pump@3.0.2: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - punycode@2.3.1: {} - queue-microtask@1.2.3: {} + quansync@0.2.10: {} - queue-tick@1.0.1: {} + queue-microtask@1.2.3: {} read-yaml-file@1.1.0: dependencies: @@ -3968,13 +3796,13 @@ snapshots: resolve-pkg-maps@1.0.0: {} - reusify@1.0.4: {} + reusify@1.1.0: {} - rolldown@1.0.0-beta.1(@babel/runtime@7.26.0): + rolldown@1.0.0-beta.1(@babel/runtime@7.27.0): dependencies: - zod: 3.24.1 + zod: 3.24.2 optionalDependencies: - '@babel/runtime': 7.26.0 + '@babel/runtime': 7.27.0 '@rolldown/binding-darwin-arm64': 1.0.0-beta.1 '@rolldown/binding-darwin-x64': 1.0.0-beta.1 '@rolldown/binding-freebsd-x64': 1.0.0-beta.1 @@ -3988,29 +3816,30 @@ snapshots: '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.1 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.1 - rollup@4.34.5: + rollup@4.39.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.34.5 - '@rollup/rollup-android-arm64': 4.34.5 - '@rollup/rollup-darwin-arm64': 4.34.5 - '@rollup/rollup-darwin-x64': 4.34.5 - '@rollup/rollup-freebsd-arm64': 4.34.5 - '@rollup/rollup-freebsd-x64': 4.34.5 - '@rollup/rollup-linux-arm-gnueabihf': 4.34.5 - '@rollup/rollup-linux-arm-musleabihf': 4.34.5 - '@rollup/rollup-linux-arm64-gnu': 4.34.5 - '@rollup/rollup-linux-arm64-musl': 4.34.5 - '@rollup/rollup-linux-loongarch64-gnu': 4.34.5 - '@rollup/rollup-linux-powerpc64le-gnu': 4.34.5 - '@rollup/rollup-linux-riscv64-gnu': 4.34.5 - '@rollup/rollup-linux-s390x-gnu': 4.34.5 - '@rollup/rollup-linux-x64-gnu': 4.34.5 - '@rollup/rollup-linux-x64-musl': 4.34.5 - '@rollup/rollup-win32-arm64-msvc': 4.34.5 - '@rollup/rollup-win32-ia32-msvc': 4.34.5 - '@rollup/rollup-win32-x64-msvc': 4.34.5 + '@rollup/rollup-android-arm-eabi': 4.39.0 + '@rollup/rollup-android-arm64': 4.39.0 + '@rollup/rollup-darwin-arm64': 4.39.0 + '@rollup/rollup-darwin-x64': 4.39.0 + '@rollup/rollup-freebsd-arm64': 4.39.0 + '@rollup/rollup-freebsd-x64': 4.39.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.39.0 + '@rollup/rollup-linux-arm-musleabihf': 4.39.0 + '@rollup/rollup-linux-arm64-gnu': 4.39.0 + '@rollup/rollup-linux-arm64-musl': 4.39.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.39.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-musl': 4.39.0 + '@rollup/rollup-linux-s390x-gnu': 4.39.0 + '@rollup/rollup-linux-x64-gnu': 4.39.0 + '@rollup/rollup-linux-x64-musl': 4.39.0 + '@rollup/rollup-win32-arm64-msvc': 4.39.0 + '@rollup/rollup-win32-ia32-msvc': 4.39.0 + '@rollup/rollup-win32-x64-msvc': 4.39.0 fsevents: 2.3.3 run-parallel@1.2.0: @@ -4036,7 +3865,7 @@ snapshots: sirv@3.0.1: dependencies: '@polka/url': 1.0.0-next.28 - mrmime: 2.0.0 + mrmime: 2.0.1 totalist: 3.0.1 sisteransi@1.0.5: {} @@ -4045,16 +3874,16 @@ snapshots: sort-object-keys@1.1.3: {} - sort-package-json@2.12.0: + sort-package-json@2.15.1: dependencies: detect-indent: 7.0.1 detect-newline: 4.0.1 get-stdin: 9.0.0 - git-hooks-list: 3.1.0 + git-hooks-list: 3.2.0 is-plain-obj: 4.1.0 semver: 7.7.1 sort-object-keys: 1.1.3 - tinyglobby: 0.2.10 + tinyglobby: 0.2.12 source-map-js@1.2.1: {} @@ -4071,20 +3900,12 @@ snapshots: stackback@0.0.2: {} - std-env@3.8.0: {} + std-env@3.9.0: {} stream-combiner@0.0.4: dependencies: duplexer: 0.1.2 - streamx@2.21.1: - dependencies: - fast-fifo: 1.3.2 - queue-tick: 1.0.1 - text-decoder: 1.2.3 - optionalDependencies: - bare-events: 2.5.0 - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -4116,30 +3937,31 @@ snapshots: glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 - pirates: 4.0.6 + pirates: 4.0.7 ts-interface-checker: 0.1.13 supports-color@7.2.0: dependencies: has-flag: 4.0.0 - svelte-eslint-parser@0.43.0(svelte@5.16.0): + svelte-eslint-parser@1.1.2(svelte@5.25.7): dependencies: - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 postcss: 8.5.3 postcss-scss: 4.0.9(postcss@8.5.3) + postcss-selector-parser: 7.1.0 optionalDependencies: - svelte: 5.16.0 + svelte: 5.25.7 svelte@4.2.19: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 - '@types/estree': 1.0.6 - acorn: 8.14.0 + '@types/estree': 1.0.7 + acorn: 8.14.1 aria-query: 5.3.2 axobject-query: 4.1.0 code-red: 1.0.4 @@ -4150,18 +3972,18 @@ snapshots: magic-string: 0.30.17 periscopic: 3.1.0 - svelte@5.16.0: + svelte@5.25.7: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 - '@types/estree': 1.0.6 - acorn: 8.14.0 - acorn-typescript: 1.4.13(acorn@8.14.0) + '@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.1) + '@types/estree': 1.0.7 + acorn: 8.14.1 aria-query: 5.3.2 axobject-query: 4.1.0 clsx: 2.1.1 - esm-env: 1.2.1 - esrap: 1.4.5 + esm-env: 1.2.2 + esrap: 1.4.6 is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.17 @@ -4169,31 +3991,13 @@ snapshots: synckit@0.9.2: dependencies: - '@pkgr/core': 0.1.1 + '@pkgr/core': 0.1.2 tslib: 2.8.1 tapable@2.2.1: {} - tar-fs@3.0.6: - dependencies: - pump: 3.0.2 - tar-stream: 3.1.7 - optionalDependencies: - bare-fs: 2.3.5 - bare-path: 2.1.3 - - tar-stream@3.1.7: - dependencies: - b4a: 1.6.7 - fast-fifo: 1.3.2 - streamx: 2.21.1 - term-size@2.2.1: {} - text-decoder@1.2.3: - dependencies: - b4a: 1.6.7 - thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -4213,11 +4017,6 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.10: - dependencies: - fdir: 6.4.3(picomatch@4.0.2) - picomatch: 4.0.2 - tinyglobby@0.2.12: dependencies: fdir: 6.4.3(picomatch@4.0.2) @@ -4241,9 +4040,9 @@ snapshots: tr46@0.0.3: {} - ts-api-utils@1.4.3(typescript@5.7.2): + ts-api-utils@2.1.0(typescript@5.8.3): dependencies: - typescript: 5.7.2 + typescript: 5.8.3 ts-interface-checker@0.1.13: {} @@ -4258,40 +4057,40 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.18.2(eslint@9.17.0)(typescript@5.7.2): + typescript-eslint@8.29.0(eslint@9.24.0)(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.18.2(@typescript-eslint/parser@8.18.2(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/parser': 8.18.2(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.18.2(eslint@9.17.0)(typescript@5.7.2) - eslint: 9.17.0 - typescript: 5.7.2 + '@typescript-eslint/eslint-plugin': 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/parser': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/utils': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + eslint: 9.24.0 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - typescript@5.7.2: {} + typescript@5.8.3: {} undici-types@5.26.5: {} - undici-types@6.20.0: {} + undici-types@6.21.0: {} universalify@0.1.2: {} - unplugin-isolated-decl@0.8.3(rollup@4.34.5)(typescript@5.7.2): + unplugin-isolated-decl@0.8.3(rollup@4.39.0)(typescript@5.8.3): dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.34.5) + '@rollup/pluginutils': 5.1.4(rollup@4.39.0) debug: 4.4.0 magic-string: 0.30.17 oxc-parser: 0.37.0 - unplugin: 1.16.0 + unplugin: 1.16.1 optionalDependencies: - typescript: 5.7.2 + typescript: 5.8.3 transitivePeerDependencies: - rollup - supports-color - unplugin@1.16.0: + unplugin@1.16.1: dependencies: - acorn: 8.14.0 + acorn: 8.14.1 webpack-virtual-modules: 0.6.2 uri-js@4.4.1: @@ -4300,17 +4099,17 @@ snapshots: util-deprecate@1.0.2: {} - valibot@0.41.0(typescript@5.7.2): + valibot@0.41.0(typescript@5.8.3): optionalDependencies: - typescript: 5.7.2 + typescript: 5.8.3 - vite-node@3.0.5(@types/node@22.10.2): + vite-node@3.0.9(@types/node@22.14.0): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 - pathe: 2.0.2 - vite: 6.1.0(@types/node@22.10.2) + pathe: 2.0.3 + vite: 6.2.5(@types/node@22.14.0) transitivePeerDependencies: - '@types/node' - jiti @@ -4325,79 +4124,40 @@ snapshots: - tsx - yaml - vite@6.1.0(@types/node@22.10.2): + vite@6.2.5(@types/node@22.14.0): dependencies: - esbuild: 0.24.2 + esbuild: 0.25.2 postcss: 8.5.3 - rollup: 4.34.5 + rollup: 4.39.0 optionalDependencies: - '@types/node': 22.10.2 + '@types/node': 22.14.0 fsevents: 2.3.3 - vitest@3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.5): - dependencies: - '@vitest/expect': 3.0.5 - '@vitest/mocker': 3.0.5(vite@6.1.0(@types/node@22.10.2)) - '@vitest/pretty-format': 3.0.5 - '@vitest/runner': 3.0.5 - '@vitest/snapshot': 3.0.5 - '@vitest/spy': 3.0.5 - '@vitest/utils': 3.0.5 - chai: 5.1.2 - debug: 4.4.0 - expect-type: 1.1.0 - magic-string: 0.30.17 - pathe: 2.0.2 - std-env: 3.8.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinypool: 1.0.2 - tinyrainbow: 2.0.0 - vite: 6.1.0(@types/node@22.10.2) - vite-node: 3.0.5(@types/node@22.10.2) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 22.10.2 - '@vitest/ui': 3.0.5(vitest@3.0.5) - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vitest@3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.9): + vitest@3.0.9(@types/node@22.14.0)(@vitest/ui@3.0.9): dependencies: - '@vitest/expect': 3.0.5 - '@vitest/mocker': 3.0.5(vite@6.1.0(@types/node@22.10.2)) - '@vitest/pretty-format': 3.0.5 - '@vitest/runner': 3.0.5 - '@vitest/snapshot': 3.0.5 - '@vitest/spy': 3.0.5 - '@vitest/utils': 3.0.5 - chai: 5.1.2 + '@vitest/expect': 3.0.9 + '@vitest/mocker': 3.0.9(vite@6.2.5(@types/node@22.14.0)) + '@vitest/pretty-format': 3.1.1 + '@vitest/runner': 3.0.9 + '@vitest/snapshot': 3.0.9 + '@vitest/spy': 3.0.9 + '@vitest/utils': 3.0.9 + chai: 5.2.0 debug: 4.4.0 - expect-type: 1.1.0 + expect-type: 1.2.1 magic-string: 0.30.17 - pathe: 2.0.2 - std-env: 3.8.0 + pathe: 2.0.3 + std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.1.0(@types/node@22.10.2) - vite-node: 3.0.5(@types/node@22.10.2) + vite: 6.2.5(@types/node@22.14.0) + vite-node: 3.0.9(@types/node@22.14.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.10.2 - '@vitest/ui': 3.0.9(vitest@3.0.5) + '@types/node': 22.14.0 + '@vitest/ui': 3.0.9(vitest@3.0.9) transitivePeerDependencies: - jiti - less @@ -4444,12 +4204,10 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 - wrappy@1.0.2: {} - yaml@1.10.2: {} yocto-queue@0.1.0: {} zimmerframe@1.1.2: {} - zod@3.24.1: {} + zod@3.24.2: {} diff --git a/rolldown.config.js b/rolldown.config.js index 5d193af7..a9eb3aa7 100644 --- a/rolldown.config.js +++ b/rolldown.config.js @@ -118,14 +118,7 @@ function getConfig(project) { } /** @type {RolldownOptions[]} */ -export default [ - getConfig('clack-core'), - getConfig('clack-prompts'), - getConfig('ast-tooling'), - getConfig('create'), - getConfig('core'), - getConfig('cli') -]; +export default [getConfig('create'), getConfig('core'), getConfig('cli')]; /** * @param {PackageJson} pkg