diff --git a/.changeset/calm-brooms-burn.md b/.changeset/calm-brooms-burn.md new file mode 100644 index 000000000000..d9ce3a8c8373 --- /dev/null +++ b/.changeset/calm-brooms-burn.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: remove top-level promise awaiting diff --git a/.changeset/calm-pugs-applaud.md b/.changeset/calm-pugs-applaud.md new file mode 100644 index 000000000000..556047ed1e63 --- /dev/null +++ b/.changeset/calm-pugs-applaud.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: prevent use of dynamic env vars during prerendering, serve env vars dynamically diff --git a/.changeset/chilled-fireants-learn.md b/.changeset/chilled-fireants-learn.md new file mode 100644 index 000000000000..3796f57910ba --- /dev/null +++ b/.changeset/chilled-fireants-learn.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: remove deprecated `use:enhance` callback values diff --git a/.changeset/clean-cars-kiss.md b/.changeset/clean-cars-kiss.md new file mode 100644 index 000000000000..6ce1b9e8db30 --- /dev/null +++ b/.changeset/clean-cars-kiss.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: turn `error` and `redirect` into commands diff --git a/.changeset/dirty-phones-report.md b/.changeset/dirty-phones-report.md new file mode 100644 index 000000000000..40b13d4c0e5c --- /dev/null +++ b/.changeset/dirty-phones-report.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: the type for `depends` now requires a `:` as part of the string diff --git a/.changeset/dull-eyes-check.md b/.changeset/dull-eyes-check.md new file mode 100644 index 000000000000..16b4a181f123 --- /dev/null +++ b/.changeset/dull-eyes-check.md @@ -0,0 +1,5 @@ +--- +"@sveltejs/kit": major +--- + +breaking: remove baseUrl fallback from generated tsconfig diff --git a/.changeset/eight-pens-help.md b/.changeset/eight-pens-help.md new file mode 100644 index 000000000000..be20211b5210 --- /dev/null +++ b/.changeset/eight-pens-help.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: fail if route with +page and +server is marked prerenderable diff --git a/.changeset/eighty-scissors-kick.md b/.changeset/eighty-scissors-kick.md new file mode 100644 index 000000000000..4f82777eddd2 --- /dev/null +++ b/.changeset/eighty-scissors-kick.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: remove `resolvePath` in favour of `resolveRoute` from `$app/paths` diff --git a/.changeset/fast-dolls-clean.md b/.changeset/fast-dolls-clean.md new file mode 100644 index 000000000000..824824b64d61 --- /dev/null +++ b/.changeset/fast-dolls-clean.md @@ -0,0 +1,6 @@ +--- +'@sveltejs/adapter-vercel': major +'@sveltejs/adapter-node': major +--- + +breaking: require SvelteKit 2 peer dependency diff --git a/.changeset/fast-eyes-deny.md b/.changeset/fast-eyes-deny.md new file mode 100644 index 000000000000..bfc7e2051d0e --- /dev/null +++ b/.changeset/fast-eyes-deny.md @@ -0,0 +1,5 @@ +--- +"@sveltejs/kit": minor +--- + +feat: add untrack to load diff --git a/.changeset/flat-clocks-listen.md b/.changeset/flat-clocks-listen.md new file mode 100644 index 000000000000..c7fe30360fa7 --- /dev/null +++ b/.changeset/flat-clocks-listen.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-vercel': minor +--- + +feat: expose vercel image optimization config in adapter config diff --git a/.changeset/gentle-guests-clean.md b/.changeset/gentle-guests-clean.md new file mode 100644 index 000000000000..d103f1d81e2b --- /dev/null +++ b/.changeset/gentle-guests-clean.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: drop support for Svelte 3 diff --git a/.changeset/good-jars-relax.md b/.changeset/good-jars-relax.md new file mode 100644 index 000000000000..ea6baeab4b7b --- /dev/null +++ b/.changeset/good-jars-relax.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: prerender optional parameters as empty when `entries` contains `'*'` diff --git a/.changeset/grumpy-sheep-fix.md b/.changeset/grumpy-sheep-fix.md new file mode 100644 index 000000000000..4264d51be24e --- /dev/null +++ b/.changeset/grumpy-sheep-fix.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: require Vite 5.0.3+ diff --git a/.changeset/happy-beds-run.md b/.changeset/happy-beds-run.md new file mode 100644 index 000000000000..132a06443a5f --- /dev/null +++ b/.changeset/happy-beds-run.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: generate `__data.json` files as sibling to `.html` files diff --git a/.changeset/hot-pumas-pump.md b/.changeset/hot-pumas-pump.md new file mode 100644 index 000000000000..8bd1f22e250d --- /dev/null +++ b/.changeset/hot-pumas-pump.md @@ -0,0 +1,5 @@ +--- +'create-svelte': minor +--- + +feat: update vitest to 1.0 diff --git a/.changeset/hungry-kings-collect.md b/.changeset/hungry-kings-collect.md new file mode 100644 index 000000000000..7289023b7bc5 --- /dev/null +++ b/.changeset/hungry-kings-collect.md @@ -0,0 +1,12 @@ +--- +'@sveltejs/adapter-cloudflare-workers': minor +'@sveltejs/adapter-cloudflare': minor +'@sveltejs/adapter-netlify': minor +'@sveltejs/adapter-static': minor +'@sveltejs/adapter-vercel': minor +'@sveltejs/adapter-auto': minor +'@sveltejs/adapter-node': minor +'@sveltejs/amp': minor +--- + +feat: allow SvelteKit 2 as peer dependency diff --git a/.changeset/hungry-moles-turn.md b/.changeset/hungry-moles-turn.md new file mode 100644 index 000000000000..7f537b5501d8 --- /dev/null +++ b/.changeset/hungry-moles-turn.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-cloudflare-workers': patch +--- + +fix: declare the adapter plugin options as optional diff --git a/.changeset/light-moons-dress.md b/.changeset/light-moons-dress.md new file mode 100644 index 000000000000..85afe61bcaaa --- /dev/null +++ b/.changeset/light-moons-dress.md @@ -0,0 +1,5 @@ +--- +"@sveltejs/kit": minor +--- + +feat: implement shallow routing diff --git a/.changeset/loud-parrots-flow.md b/.changeset/loud-parrots-flow.md new file mode 100644 index 000000000000..fca577998c6e --- /dev/null +++ b/.changeset/loud-parrots-flow.md @@ -0,0 +1,5 @@ +--- +"svelte-migrate": minor +--- + +feat: add sveltekit v2 migration diff --git a/.changeset/loud-plants-move.md b/.changeset/loud-plants-move.md new file mode 100644 index 000000000000..c148e4086394 --- /dev/null +++ b/.changeset/loud-plants-move.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: fail if +page and +server have mismatched config diff --git a/.changeset/mean-moose-smell.md b/.changeset/mean-moose-smell.md new file mode 100644 index 000000000000..17d98b2cdbae --- /dev/null +++ b/.changeset/mean-moose-smell.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: error if form without multipart/form-data enctype contains a file input diff --git a/.changeset/mean-trees-notice.md b/.changeset/mean-trees-notice.md new file mode 100644 index 000000000000..397ef057eae6 --- /dev/null +++ b/.changeset/mean-trees-notice.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: resolve route config correctly diff --git a/.changeset/neat-hats-shop.md b/.changeset/neat-hats-shop.md new file mode 100644 index 000000000000..251c39101243 --- /dev/null +++ b/.changeset/neat-hats-shop.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: import Svelte types from svelte/compiler diff --git a/.changeset/nervous-bananas-search.md b/.changeset/nervous-bananas-search.md new file mode 100644 index 000000000000..badfdec6e142 --- /dev/null +++ b/.changeset/nervous-bananas-search.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: require paths pass to preloadCode to be prefixed with basepath diff --git a/.changeset/nervous-cups-argue.md b/.changeset/nervous-cups-argue.md new file mode 100644 index 000000000000..8c5d30d77af4 --- /dev/null +++ b/.changeset/nervous-cups-argue.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-node': minor +--- + +chore: upgrade rollup diff --git a/.changeset/nervous-snails-chew.md b/.changeset/nervous-snails-chew.md new file mode 100644 index 000000000000..8822f934a577 --- /dev/null +++ b/.changeset/nervous-snails-chew.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: `@sveltejs/vite-plugin-svelte` is now a peer dependency and will need to be installed in each project using SvelteKit diff --git a/.changeset/nine-moles-buy.md b/.changeset/nine-moles-buy.md new file mode 100644 index 000000000000..73cc6d40b821 --- /dev/null +++ b/.changeset/nine-moles-buy.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: stop re-exporting vitePreprocess diff --git a/.changeset/old-rockets-film.md b/.changeset/old-rockets-film.md new file mode 100644 index 000000000000..7f6d7e4f9a95 --- /dev/null +++ b/.changeset/old-rockets-film.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: reset invalid resources after a successful invalidation diff --git a/.changeset/pink-lobsters-protect.md b/.changeset/pink-lobsters-protect.md new file mode 100644 index 000000000000..2a92abb5b038 --- /dev/null +++ b/.changeset/pink-lobsters-protect.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-static': major +--- + +breaking: update SvelteKit peer dependency to version 2 diff --git a/.changeset/poor-parrots-own.md b/.changeset/poor-parrots-own.md new file mode 100644 index 000000000000..5e9116e27fd2 --- /dev/null +++ b/.changeset/poor-parrots-own.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: require path option when setting/deleting/serializing cookies diff --git a/.changeset/real-pets-fix.md b/.changeset/real-pets-fix.md new file mode 100644 index 000000000000..336da95529b1 --- /dev/null +++ b/.changeset/real-pets-fix.md @@ -0,0 +1,5 @@ +--- +"@sveltejs/kit": major +--- + +breaking: tighten up error handling diff --git a/.changeset/rotten-penguins-hope.md b/.changeset/rotten-penguins-hope.md new file mode 100644 index 000000000000..e350d1710d38 --- /dev/null +++ b/.changeset/rotten-penguins-hope.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-node': major +--- + +breaking: remove polyfill option. fetch APIs will now always come from the platform being used. File and crypto APIs will be polyfilled if not available diff --git a/.changeset/serious-months-happen.md b/.changeset/serious-months-happen.md new file mode 100644 index 000000000000..861d42d2959f --- /dev/null +++ b/.changeset/serious-months-happen.md @@ -0,0 +1,5 @@ +--- +"@sveltejs/kit": major +--- + +breaking: remove state option from goto in favor of shallow routing diff --git a/.changeset/shy-trees-carry.md b/.changeset/shy-trees-carry.md new file mode 100644 index 000000000000..c00143651e4b --- /dev/null +++ b/.changeset/shy-trees-carry.md @@ -0,0 +1,5 @@ +--- +'create-svelte': major +--- + +feat: create projects with SvelteKit 2 diff --git a/.changeset/silent-donuts-push.md b/.changeset/silent-donuts-push.md new file mode 100644 index 000000000000..a10b047c9bbb --- /dev/null +++ b/.changeset/silent-donuts-push.md @@ -0,0 +1,8 @@ +--- +'@sveltejs/adapter-cloudflare-workers': minor +'@sveltejs/adapter-cloudflare': minor +'@sveltejs/adapter-netlify': minor +'@sveltejs/adapter-vercel': minor +--- + +chore: upgrade esbuild diff --git a/.changeset/silent-games-taste.md b/.changeset/silent-games-taste.md new file mode 100644 index 000000000000..fcd66101a965 --- /dev/null +++ b/.changeset/silent-games-taste.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: disallow external navigation with `goto` diff --git a/.changeset/silent-mayflies-burn.md b/.changeset/silent-mayflies-burn.md new file mode 100644 index 000000000000..7bd6f712f5ed --- /dev/null +++ b/.changeset/silent-mayflies-burn.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: upgrade to TypeScript 5. Default `moduleResolution` to `bundler` in user projects to be permissive in consuming and `NodeNext` when running `package` to be strict in distributing diff --git a/.changeset/smart-buttons-return.md b/.changeset/smart-buttons-return.md new file mode 100644 index 000000000000..fb4bfc1dd054 --- /dev/null +++ b/.changeset/smart-buttons-return.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': minor +--- + +feat: provide SvelteKit html typings diff --git a/.changeset/smart-crabs-lick.md b/.changeset/smart-crabs-lick.md new file mode 100644 index 000000000000..05f603cfc359 --- /dev/null +++ b/.changeset/smart-crabs-lick.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': minor +--- + +feat: redact internal stack trace when reporting config errors diff --git a/.changeset/strange-eyes-sort.md b/.changeset/strange-eyes-sort.md new file mode 100644 index 000000000000..70de048ab975 --- /dev/null +++ b/.changeset/strange-eyes-sort.md @@ -0,0 +1,5 @@ +--- +"@sveltejs/kit": minor +--- + +feat: allow for fine grained invalidation of search params diff --git a/.changeset/swift-clocks-kneel.md b/.changeset/swift-clocks-kneel.md new file mode 100644 index 000000000000..493107153a90 --- /dev/null +++ b/.changeset/swift-clocks-kneel.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: Adjust fail method and ActionFailure type diff --git a/.changeset/tall-suns-protect.md b/.changeset/tall-suns-protect.md new file mode 100644 index 000000000000..21f8fa055fa0 --- /dev/null +++ b/.changeset/tall-suns-protect.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: undefined is no longer a valid value for paths.relative diff --git a/.changeset/thick-suits-help.md b/.changeset/thick-suits-help.md new file mode 100644 index 000000000000..acb67c634a71 --- /dev/null +++ b/.changeset/thick-suits-help.md @@ -0,0 +1,6 @@ +--- +'@sveltejs/kit': major +'create-svelte': major +--- + +breaking: require Node 18.13 or newer diff --git a/.changeset/twelve-paws-remember.md b/.changeset/twelve-paws-remember.md new file mode 100644 index 000000000000..1d484047af0c --- /dev/null +++ b/.changeset/twelve-paws-remember.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: fix path resolution diff --git a/.changeset/twenty-birds-eat.md b/.changeset/twenty-birds-eat.md new file mode 100644 index 000000000000..c999f7c49845 --- /dev/null +++ b/.changeset/twenty-birds-eat.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: remove `dangerZone.trackServerFetches` diff --git a/.changeset/twenty-ducks-reply.md b/.changeset/twenty-ducks-reply.md new file mode 100644 index 000000000000..9ddd4abb78a0 --- /dev/null +++ b/.changeset/twenty-ducks-reply.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +chore(deps): upgrade cookies dependency diff --git a/.changeset/unlucky-crabs-wonder.md b/.changeset/unlucky-crabs-wonder.md new file mode 100644 index 000000000000..1ac22c413258 --- /dev/null +++ b/.changeset/unlucky-crabs-wonder.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/enhanced-img': patch +--- + +chore: upgrade vite-imagetools diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7cd2ca41db19..c38ce191773a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,11 +26,11 @@ jobs: - uses: pnpm/action-setup@v2.4.0 - uses: actions/setup-node@v4 with: - node-version: '16.x' + node-version: '18.x' cache: pnpm - run: pnpm install --frozen-lockfile - run: pnpm run lint - - run: cd packages/kit && pnpm prepublishOnly && { [ "`git status --porcelain=v1`" == "" ] || (echo "Generated types have changed — please run prepublishOnly locally and commit the changes after you have reviewed them" && exit 1); } + - run: cd packages/kit && pnpm prepublishOnly && { [ "`git status --porcelain=v1`" == "" ] || (echo "Generated types have changed — please run prepublishOnly locally and commit the changes after you have reviewed them"; git diff; exit 1); } - run: pnpm run check Tests: runs-on: ${{ matrix.os }} @@ -39,9 +39,6 @@ jobs: fail-fast: false matrix: include: - - node-version: 16 - os: ubuntu-latest - e2e-browser: 'chromium' - node-version: 18 os: ubuntu-latest e2e-browser: 'chromium' @@ -79,27 +76,27 @@ jobs: fail-fast: false matrix: include: - - node-version: 16 + - node-version: 18 os: windows-2019 # slowness reported on newer versions https://github.com/actions/runner-images/issues/5166 e2e-browser: 'chromium' mode: 'dev' - - node-version: 16 + - node-version: 18 os: ubuntu-latest e2e-browser: 'firefox' mode: 'dev' - - node-version: 16 + - node-version: 18 os: macOS-latest e2e-browser: 'webkit' mode: 'dev' - - node-version: 16 + - node-version: 18 os: windows-2019 # slowness reported on newer versions https://github.com/actions/runner-images/issues/5166 e2e-browser: 'chromium' mode: 'build' - - node-version: 16 + - node-version: 18 os: ubuntu-latest e2e-browser: 'firefox' mode: 'build' - - node-version: 16 + - node-version: 18 os: macOS-latest e2e-browser: 'webkit' mode: 'build' @@ -134,7 +131,7 @@ jobs: - uses: pnpm/action-setup@v2.4.0 - uses: actions/setup-node@v4 with: - node-version: 16 + node-version: 18 cache: pnpm - run: pnpm install --frozen-lockfile - run: cd packages/kit && pnpm prepublishOnly diff --git a/documentation/docs/10-getting-started/10-introduction.md b/documentation/docs/10-getting-started/10-introduction.md index 189fcb3bcc7d..fb113d7578fb 100644 --- a/documentation/docs/10-getting-started/10-introduction.md +++ b/documentation/docs/10-getting-started/10-introduction.md @@ -22,6 +22,6 @@ In short, Svelte is a way of writing user interface components — like a naviga Svelte renders UI components. You can compose these components and render an entire page with just Svelte, but you need more than just Svelte to write an entire app. -SvelteKit helps you build web apps while following modern best practices and providing solutions to common development challenges. It offers everything from basic functionalities — like a [router](glossary#routing) that updates your UI when a link is clicked — to more advanced capabilities. Its extensive list of features includes [build optimizations](https://vitejs.dev/guide/features.html#build-optimizations) to load only the minimal required code; [offline support](service-workers); [preloading](link-options#data-sveltekit-preload-data) pages before user navigation; [configurable rendering](page-options) to handle different parts of your app on the server via [SSR](glossary#ssr), in the browser through [client-side rendering](glossary#csr), or at build-time with [prerendering](glossary#prerendering); and much more. Building an app with all the modern best practices is fiendishly complicated, but SvelteKit does all the boring stuff for you so that you can get on with the creative part. +SvelteKit helps you build web apps while following modern best practices and providing solutions to common development challenges. It offers everything from basic functionalities — like a [router](glossary#routing) that updates your UI when a link is clicked — to more advanced capabilities. Its extensive list of features includes [build optimizations](https://vitejs.dev/guide/features.html#build-optimizations) to load only the minimal required code; [offline support](service-workers); [preloading](link-options#data-sveltekit-preload-data) pages before user navigation; [configurable rendering](page-options) to handle different parts of your app on the server via [SSR](glossary#ssr), in the browser through [client-side rendering](glossary#csr), or at build-time with [prerendering](glossary#prerendering); [image optimization](images); and much more. Building an app with all the modern best practices is fiendishly complicated, but SvelteKit does all the boring stuff for you so that you can get on with the creative part. It reflects changes to your code in the browser instantly to provide a lightning-fast and feature-rich development experience by leveraging [Vite](https://vitejs.dev/) with a [Svelte plugin](https://github.com/sveltejs/vite-plugin-svelte) to do [Hot Module Replacement (HMR)](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#hot). diff --git a/documentation/docs/20-core-concepts/10-routing.md b/documentation/docs/20-core-concepts/10-routing.md index 125b1d5282e2..d21be05291af 100644 --- a/documentation/docs/20-core-concepts/10-routing.md +++ b/documentation/docs/20-core-concepts/10-routing.md @@ -61,7 +61,7 @@ export function load({ params }) { }; } - throw error(404, 'Not found'); + error(404, 'Not found'); } ``` @@ -104,7 +104,7 @@ export async function load({ params }) { return post; } - throw error(404, 'Not found'); + error(404, 'Not found'); } ``` @@ -264,7 +264,7 @@ export function GET({ url }) { const d = max - min; if (isNaN(d) || d < 0) { - throw error(400, 'min and max must be numbers, and min must be less than max'); + error(400, 'min and max must be numbers, and min must be less than max'); } const random = min + Math.random() * d; @@ -277,7 +277,7 @@ The first argument to `Response` can be a [`ReadableStream`](https://developer.m You can use the [`error`](modules#sveltejs-kit-error), [`redirect`](modules#sveltejs-kit-redirect) and [`json`](modules#sveltejs-kit-json) methods from `@sveltejs/kit` for convenience (but you don't have to). -If an error is thrown (either `throw error(...)` or an unexpected error), the response will be a JSON representation of the error or a fallback error page — which can be customised via `src/error.html` — depending on the `Accept` header. The [`+error.svelte`](#error) component will _not_ be rendered in this case. You can read more about error handling [here](errors). +If an error is thrown (either `error(...)` or an unexpected error), the response will be a JSON representation of the error or a fallback error page — which can be customised via `src/error.html` — depending on the `Accept` header. The [`+error.svelte`](#error) component will _not_ be rendered in this case. You can read more about error handling [here](errors). > When creating an `OPTIONS` handler, note that Vite will inject `Access-Control-Allow-Origin` and `Access-Control-Allow-Methods` headers — these will not be present in production unless you add them. diff --git a/documentation/docs/20-core-concepts/20-load.md b/documentation/docs/20-core-concepts/20-load.md index f867fe6d9787..7448cf521c5f 100644 --- a/documentation/docs/20-core-concepts/20-load.md +++ b/documentation/docs/20-core-concepts/20-load.md @@ -172,7 +172,7 @@ A `load` function is invoked at runtime, unless you [prerender](page-options#pre ### Input -Both universal and server `load` functions have access to properties describing the request (`params`, `route` and `url`) and various functions (`fetch`, `setHeaders`, `parent` and `depends`). These are described in the following sections. +Both universal and server `load` functions have access to properties describing the request (`params`, `route` and `url`) and various functions (`fetch`, `setHeaders`, `parent`, `depends` and `untrack`). These are described in the following sections. Server `load` functions are called with a `ServerLoadEvent`, which inherits `clientAddress`, `cookies`, `locals`, `platform` and `request` from `RequestEvent`. @@ -283,8 +283,6 @@ For example, if SvelteKit is serving my.domain.com: Other cookies will not be passed when `credentials: 'include'` is set, because SvelteKit does not know which domain which cookie belongs to (the browser does not pass this information along), so it's not safe to forward any of them. Use the [handleFetch hook](hooks#server-hooks-handlefetch) to work around it. -> When setting cookies, be aware of the `path` property. By default, the `path` of a cookie is the current pathname. If you for example set a cookie at page `admin/user`, the cookie will only be available within the `admin` pages by default. In most cases you likely want to set `path` to `'/'` to make the cookie available throughout your app. - ## Headers Both server and universal `load` functions have access to a `setHeaders` function that, when running on the server, can set headers for the response. (When running in the browser, `setHeaders` has no effect.) This is useful if you want the page to be cached, for example: @@ -376,7 +374,7 @@ export async function load({ params, parent }) { ## Errors -If an error is thrown during `load`, the nearest [`+error.svelte`](routing#error) will be rendered. For _expected_ errors, use the `error` helper from `@sveltejs/kit` to specify the HTTP status code and an optional message: +If an error is thrown during `load`, the nearest [`+error.svelte`](routing#error) will be rendered. For [_expected_](/docs/errors#expected-errors) errors, use the `error` helper from `@sveltejs/kit` to specify the HTTP status code and an optional message: ```js /// file: src/routes/admin/+layout.server.js @@ -397,20 +395,24 @@ import { error } from '@sveltejs/kit'; /** @type {import('./$types').LayoutServerLoad} */ export function load({ locals }) { if (!locals.user) { - throw error(401, 'not logged in'); + error(401, 'not logged in'); } if (!locals.user.isAdmin) { - throw error(403, 'not an admin'); + error(403, 'not an admin'); } } ``` -If an _unexpected_ error is thrown, SvelteKit will invoke [`handleError`](hooks#shared-hooks-handleerror) and treat it as a 500 Internal Error. +Calling `error(...)` will throw an exception, making it easy to stop execution from inside helper functions. + +If an [_unexpected_](/docs/errors#unexpected-errors) error is thrown, SvelteKit will invoke [`handleError`](hooks#shared-hooks-handleerror) and treat it as a 500 Internal Error. + +> [In SvelteKit 1.x](migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you) you had to `throw` the error yourself ## Redirects -To redirect users, use the `redirect` helper from `@sveltejs/kit` to specify the location to which they should be redirected alongside a `3xx` status code. +To redirect users, use the `redirect` helper from `@sveltejs/kit` to specify the location to which they should be redirected alongside a `3xx` status code. Like `error(...)`, calling `redirect(...)` will throw an exception, making it easy to stop execution from inside helper functions. ```js /// file: src/routes/user/+layout.server.js @@ -430,33 +432,40 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('./$types').LayoutServerLoad} */ export function load({ locals }) { if (!locals.user) { - throw redirect(307, '/login'); + redirect(307, '/login'); } } ``` -> Don't use `throw redirect()` from within a try-catch block, as the redirect will immediately trigger the catch statement. +> Don't use `redirect()` inside a `try {...}` block, as the redirect will immediately trigger the catch statement. In the browser, you can also navigate programmatically outside of a `load` function using [`goto`](modules#$app-navigation-goto) from [`$app.navigation`](modules#$app-navigation). +> [In SvelteKit 1.x](migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you) you had to `throw` the `redirect` yourself + ## Streaming with promises -Promises at the _top level_ of the returned object will be awaited, making it easy to return multiple promises without creating a waterfall. When using a server `load`, _nested_ promises will be streamed to the browser as they resolve. This is useful if you have slow, non-essential data, since you can start rendering the page before all the data is available: +When using a server `load`, promises will be streamed to the browser as they resolve. This is useful if you have slow, non-essential data, since you can start rendering the page before all the data is available: ```js -/// file: src/routes/+page.server.js +/// file: src/routes/blog/[slug]/+page.server.js +// @filename: ambient.d.ts +declare global { + const loadPost: (slug: string) => Promise<{ title: string, content: string }>; + const loadComments: (slug: string) => Promise<{ content: string }>; +} + +export {}; + +// @filename: index.js +// ---cut--- /** @type {import('./$types').PageServerLoad} */ -export function load() { +export async function load({ params }) { return { - one: Promise.resolve(1), - two: Promise.resolve(2), - streamed: { - three: new Promise((fulfil) => { - setTimeout(() => { - fulfil(3) - }, 1000); - }) - } + // make sure the `await` happens at the end, otherwise we + // can't start loading comments until we've loaded the post + comments: loadComments(params.slug), + post: await loadPost(params.slug) }; } ``` @@ -464,28 +473,24 @@ export function load() { This is useful for creating skeleton loading states, for example: ```svelte - + -

- one: {data.one} -

-

- two: {data.two} -

-

- three: - {#await data.streamed.three} - Loading... - {:then value} - {value} - {:catch error} - {error.message} - {/await} -

+

{data.post.title}

+
{@html data.post.content}
+ +{#await data.comments} + Loading comments... +{:then comments} + {#each comments as comment} +

{comment.content}

+ {/each} +{:catch error} +

error loading comments: {error.message}

+{/await} ``` When streaming data, be careful to handle promise rejections correctly. More specifically, the server could crash with an "unhandled promise rejection" error if a lazy-loaded promise fails before rendering starts (at which point it's caught) and isn't handling the error in some way. When using SvelteKit's `fetch` directly in the `load` function, SvelteKit will handle this case for you. For other promises, it is enough to attach a noop-`catch` to the promise to mark it as handled. @@ -498,21 +503,21 @@ export function load({ fetch }) { ok_manual.catch(() => {}); return { - streamed: { - ok_manual, - ok_fetch: fetch('/fetch/that/could/fail'), - dangerous_unhandled: Promise.reject() - } + ok_manual, + ok_fetch: fetch('/fetch/that/could/fail'), + dangerous_unhandled: Promise.reject() }; } ``` > On platforms that do not support streaming, such as AWS Lambda, responses will be buffered. This means the page will only render once all promises resolve. If you are using a proxy (e.g. NGINX), make sure it does not buffer responses from the proxied server. -> Streaming data will only work when JavaScript is enabled. You should avoid returning nested promises from a universal `load` function if the page is server rendered, as these are _not_ streamed — instead, the promise is recreated when the function reruns in the browser. +> Streaming data will only work when JavaScript is enabled. You should avoid returning promises from a universal `load` function if the page is server rendered, as these are _not_ streamed — instead, the promise is recreated when the function reruns in the browser. > The headers and status code of a response cannot be changed once the response has started streaming, therefore you cannot `setHeaders` or throw redirects inside a streamed promise. +> [In SvelteKit 1.x](migrating-to-sveltekit-2#top-level-promises-are-no-longer-awaited) top-level promises were automatically awaited, only nested promises were streamed. + ## Parallel loading When rendering (or navigating to) a page, SvelteKit runs all `load` functions concurrently, avoiding a waterfall of requests. During client-side navigation, the result of calling multiple server `load` functions are grouped into a single response. Once all `load` functions have returned, the page is rendered. @@ -567,6 +572,23 @@ A `load` function that calls `await parent()` will also rerun if a parent `load` Dependency tracking does not apply _after_ the `load` function has returned — for example, accessing `params.x` inside a nested [promise](#streaming-with-promises) will not cause the function to rerun when `params.x` changes. (Don't worry, you'll get a warning in development if you accidentally do this.) Instead, access the parameter in the main body of your `load` function. +Search parameters are tracked independently from the rest of the url. For example, accessing `event.url.searchParams.get("x")` inside a `load` function will make that `load` function re-run when navigating from `?x=1` to `?x=2`, but not when navigating from `?x=1&y=1` to `?x=1&y=2`. + +### Untracking dependencies + +In rare cases, you may wish to exclude something from the dependency tracking mechanism. You can do this with the provided `untrack` function: + +```js +/// file: src/routes/+page.js +/** @type {import('./$types').PageLoad} */ +export async function load({ untrack, url }) { + // Untrack url.pathname so that path changes don't trigger a rerun + if (untrack(() => url.pathname === '/')) { + return { message: 'Welcome!' }; + } +} +``` + ### Manual invalidation You can also rerun `load` functions that apply to the current page using [`invalidate(url)`](modules#$app-navigation-invalidate), which reruns all `load` functions that depend on `url`, and [`invalidateAll()`](modules#$app-navigation-invalidateall), which reruns every `load` function. Server load functions will never automatically depend on a fetched `url` to avoid leaking secrets to the client. @@ -616,6 +638,7 @@ To summarize, a `load` function will rerun in the following situations: - It references a property of `params` whose value has changed - It references a property of `url` (such as `url.pathname` or `url.search`) whose value has changed. Properties in `request.url` are _not_ tracked +- It calls `url.searchParams.get(...)`, `url.searchParams.getAll(...)` or `url.searchParams.has(...)` and the parameter in question changes. Accessing other properties of `url.searchParams` will have the same effect as accessing `url.search`. - It calls `await parent()` and a parent `load` function reran - It declared a dependency on a specific URL via [`fetch`](#making-fetch-requests) (universal load only) or [`depends`](types#public-types-loadevent), and that URL was marked invalid with [`invalidate(url)`](modules#$app-navigation-invalidate) - All active `load` functions were forcibly rerun with [`invalidateAll()`](modules#$app-navigation-invalidateall) diff --git a/documentation/docs/20-core-concepts/30-form-actions.md b/documentation/docs/20-core-concepts/30-form-actions.md index d25e141eadc7..470d7318412b 100644 --- a/documentation/docs/20-core-concepts/30-form-actions.md +++ b/documentation/docs/20-core-concepts/30-form-actions.md @@ -234,7 +234,7 @@ export const actions = { cookies.set('sessionid', await db.createSession(user)); + if (url.searchParams.has('redirectTo')) { -+ throw redirect(303, url.searchParams.get('redirectTo')); ++ redirect(303, url.searchParams.get('redirectTo')); + } return { success: true }; diff --git a/documentation/docs/25-build-and-deploy/40-adapter-node.md b/documentation/docs/25-build-and-deploy/40-adapter-node.md index f3c04bfa85c3..8736968e1a31 100644 --- a/documentation/docs/25-build-and-deploy/40-adapter-node.md +++ b/documentation/docs/25-build-and-deploy/40-adapter-node.md @@ -131,8 +131,7 @@ export default { // default options are shown out: 'build', precompress: false, - envPrefix: '', - polyfill: true + envPrefix: '' }) } }; @@ -161,12 +160,6 @@ MY_CUSTOM_ORIGIN=https://my.site \ node build ``` -### polyfill - -Controls whether your build will load polyfills for missing modules. It defaults to `true`, and should only be disabled when using Node 18.11 or greater. - -Note: to use Node's built-in `crypto` global with Node 18 you will need to use the `--experimental-global-webcrypto` flag. This flag is not required with Node 20. - ## Custom server The adapter creates two files in your build directory — `index.js` and `handler.js`. Running `index.js` — e.g. `node build`, if you use the default build directory — will start a server on the configured port. diff --git a/documentation/docs/25-build-and-deploy/90-adapter-vercel.md b/documentation/docs/25-build-and-deploy/90-adapter-vercel.md index 6f72025b9565..2e0f92ff77d7 100644 --- a/documentation/docs/25-build-and-deploy/90-adapter-vercel.md +++ b/documentation/docs/25-build-and-deploy/90-adapter-vercel.md @@ -18,7 +18,7 @@ import adapter from '@sveltejs/adapter-vercel'; export default { kit: { adapter: adapter({ - // see the 'Deployment configuration' section below + // see below for options that can be set here }) } }; @@ -64,6 +64,18 @@ And the following option apply to serverless functions: If your functions need to access data in a specific region, it's recommended that they be deployed in the same region (or close to it) for optimal performance. +## Image Optimization + +You may set the `images` config to control how Vercel builds your images. See the [image configuration reference](https://vercel.com/docs/build-output-api/v3/configuration#images) for full details. As an example, you may set: + +``` +{ + sizes: [640, 828, 1200, 1920, 3840], + formats: ['image/avif', 'image/webp'], + minimumCacheTTL: 300 +} +``` + ## Incremental Static Regeneration Vercel supports [Incremental Static Regeneration](https://vercel.com/docs/concepts/incremental-static-regeneration/overview) (ISR), which provides the performance and cost advantages of prerendered content with the flexibility of dynamically rendered content. diff --git a/documentation/docs/30-advanced/10-advanced-routing.md b/documentation/docs/30-advanced/10-advanced-routing.md index ca84a27df22b..524cb698287d 100644 --- a/documentation/docs/30-advanced/10-advanced-routing.md +++ b/documentation/docs/30-advanced/10-advanced-routing.md @@ -57,7 +57,7 @@ import { error } from '@sveltejs/kit'; /** @type {import('./$types').PageLoad} */ export function load(event) { - throw error(404, 'Not Found'); + error(404, 'Not Found'); } ``` diff --git a/documentation/docs/30-advanced/20-hooks.md b/documentation/docs/30-advanced/20-hooks.md index 48a9a9388d61..d979ec88b1b1 100644 --- a/documentation/docs/30-advanced/20-hooks.md +++ b/documentation/docs/30-advanced/20-hooks.md @@ -139,12 +139,14 @@ The following can be added to `src/hooks.server.js` _and_ `src/hooks.client.js`: ### handleError -If an unexpected error is thrown during loading or rendering, this function will be called with the `error` and the `event`. This allows for two things: +If an [unexpected error](/docs/errors#unexpected-errors) is thrown during loading or rendering, this function will be called with the `error`, `event`, `status` code and `message`. This allows for two things: - you can log the error -- you can generate a custom representation of the error that is safe to show to users, omitting sensitive details like messages and stack traces. The returned value becomes the value of `$page.error`. It defaults to `{ message: 'Not Found' }` in case of a 404 (you can detect them through `event.route.id` being `null`) and to `{ message: 'Internal Error' }` for everything else. To make this type-safe, you can customize the expected shape by declaring an `App.Error` interface (which must include `message: string`, to guarantee sensible fallback behavior). +- you can generate a custom representation of the error that is safe to show to users, omitting sensitive details like messages and stack traces. The returned value, which defaults to `{ message }`, becomes the value of `$page.error`. -The following code shows an example of typing the error shape as `{ message: string; errorId: string }` and returning it accordingly from the `handleError` functions: +For errors thrown from your code (or library code called by your code) the status will be 500 and the message will be "Internal Error". While `error.message` may contain sensitive information that should not be exposed to users, `message` is safe (albeit meaningless to the average user). + +To add more information to the `$page.error` object in a type-safe way, you can customize the expected shape by declaring an `App.Error` interface (which must include `message: string`, to guarantee sensible fallback behavior). This allows you to — for example — append a tracking ID for users to quote in correspondence with your technical support staff: ```ts /// file: src/app.d.ts @@ -162,7 +164,7 @@ export {}; ```js /// file: src/hooks.server.js -// @errors: 2322 +// @errors: 2322 2353 // @filename: ambient.d.ts declare module '@sentry/sveltekit' { export const init: (opts: any) => void; @@ -172,15 +174,17 @@ declare module '@sentry/sveltekit' { // @filename: index.js // ---cut--- import * as Sentry from '@sentry/sveltekit'; -import crypto from 'crypto'; Sentry.init({/*...*/}) /** @type {import('@sveltejs/kit').HandleServerError} */ -export async function handleError({ error, event }) { +export async function handleError({ error, event, status, message }) { const errorId = crypto.randomUUID(); + // example integration with https://sentry.io/ - Sentry.captureException(error, { extra: { event, errorId } }); + Sentry.captureException(error, { + extra: { event, errorId, status } + }); return { message: 'Whoops!', @@ -191,7 +195,7 @@ export async function handleError({ error, event }) { ```js /// file: src/hooks.client.js -// @errors: 2322 +// @errors: 2322 2353 // @filename: ambient.d.ts declare module '@sentry/sveltekit' { export const init: (opts: any) => void; @@ -205,10 +209,13 @@ import * as Sentry from '@sentry/sveltekit'; Sentry.init({/*...*/}) /** @type {import('@sveltejs/kit').HandleClientError} */ -export async function handleError({ error, event }) { +export async function handleError({ error, event, status, message }) { const errorId = crypto.randomUUID(); + // example integration with https://sentry.io/ - Sentry.captureException(error, { extra: { event, errorId } }); + Sentry.captureException(error, { + extra: { event, errorId, status } + }); return { message: 'Whoops!', diff --git a/documentation/docs/30-advanced/25-errors.md b/documentation/docs/30-advanced/25-errors.md index 4918db08b697..b594c6dd31d8 100644 --- a/documentation/docs/30-advanced/25-errors.md +++ b/documentation/docs/30-advanced/25-errors.md @@ -31,7 +31,7 @@ export async function load({ params }) { const post = await db.getPost(params.slug); if (!post) { - throw error(404, { + error(404, { message: 'Not found' }); } @@ -40,7 +40,7 @@ export async function load({ params }) { } ``` -This tells SvelteKit to set the response status code to 404 and render an [`+error.svelte`](routing#error) component, where `$page.error` is the object provided as the second argument to `error(...)`. +This throws an exception that SvelteKit catches, causing it to set the response status code to 404 and render an [`+error.svelte`](routing#error) component, where `$page.error` is the object provided as the second argument to `error(...)`. ```svelte @@ -54,7 +54,7 @@ This tells SvelteKit to set the response status code to 404 and render an [`+err You can add extra properties to the error object if needed... ```diff -throw error(404, { +error(404, { message: 'Not found', + code: 'NOT_FOUND' }); @@ -63,10 +63,12 @@ throw error(404, { ...otherwise, for convenience, you can pass a string as the second argument: ```diff --throw error(404, { message: 'Not found' }); -+throw error(404, 'Not found'); +-error(404, { message: 'Not found' }); ++error(404, 'Not found'); ``` +> [In SvelteKit 1.x](migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you) you had to `throw` the `error` yourself + ## Unexpected errors An _unexpected_ error is any other exception that occurs while handling a request. Since these can contain sensitive information, unexpected error messages and stack traces are not exposed to users. @@ -77,36 +79,7 @@ By default, unexpected errors are printed to the console (or, in production, you { "message": "Internal Error" } ``` -Unexpected errors will go through the [`handleError`](hooks#shared-hooks-handleerror) hook, where you can add your own error handling — for example, sending errors to a reporting service, or returning a custom error object. - -```js -/// file: src/hooks.server.js -// @errors: 2322 1360 2571 2339 -// @filename: ambient.d.ts -declare module '@sentry/sveltekit' { - export const init: (opts: any) => void; - export const captureException: (error: any, opts: any) => void; -} - -// @filename: index.js -// ---cut--- -import * as Sentry from '@sentry/sveltekit'; - -Sentry.init({/*...*/}) - -/** @type {import('@sveltejs/kit').HandleServerError} */ -export function handleError({ error, event }) { - // example integration with https://sentry.io/ - Sentry.captureException(error, { extra: { event } }); - - return { - message: 'Whoops!', - code: error?.code ?? 'UNKNOWN' - }; -} -``` - -> Make sure that `handleError` _never_ throws an error +Unexpected errors will go through the [`handleError`](hooks#shared-hooks-handleerror) hook, where you can add your own error handling — for example, sending errors to a reporting service, or returning a custom error object which becomes `$page.error`. ## Responses diff --git a/documentation/docs/30-advanced/67-shallow-routing.md b/documentation/docs/30-advanced/67-shallow-routing.md new file mode 100644 index 000000000000..466f9ee2049e --- /dev/null +++ b/documentation/docs/30-advanced/67-shallow-routing.md @@ -0,0 +1,97 @@ +--- +title: Shallow routing +--- + +As you navigate around a SvelteKit app, you create _history entries_. Clicking the back and forward buttons traverses through this list of entries, re-running any `load` functions and replacing page components as necessary. + +Sometimes, it's useful to create history entries _without_ navigating. For example, you might want to show a modal dialog that the user can dismiss by navigating back. This is particularly valuable on mobile devices, where swipe gestures are often more natural than interacting directly with the UI. In these cases, a modal that is _not_ associated with a history entry can be a source of frustration, as a user may swipe backwards in an attempt to dismiss it and find themselves on the wrong page. + +SvelteKit makes this possible with the [`pushState`](/docs/modules#$app-navigation-pushstate) and [`replaceState`](/docs/modules#$app-navigation-replacestate) functions, which allow you to associate state with a history entry without navigating. For example, to implement a history-driven modal: + +```svelte + + + +{#if $page.state.showModal} + history.back()} /> +{/if} +``` + +The modal can be dismissed by navigating back (unsetting `$page.state.showModal`) or by interacting with it in a way that causes the `close` callback to run, which will navigate back programmatically. + +## API + +The first argument to `pushState` is the URL, relative to the current URL. To stay on the current URL, use `''`. + +The second argument is the new page state, which can be accessed via the [page store](/docs/modules#$app-stores-page) as `$page.state`. You can make page state type-safe by declaring an [`App.PageState`](/docs/types#app) interface (usually in `src/app.d.ts`). + +To set page state without creating a new history entry, use `replaceState` instead of `pushState`. + +## Loading data for a route + +When shallow routing, you may want to render another `+page.svelte` inside the current page. For example, clicking on a photo thumbnail could pop up the detail view without navigating to the photo page. + +For this to work, you need to load the data that the `+page.svelte` expects. A convenient way to do this is to use [`preloadData`](/docs/modules#$app-navigation-preloaddata) inside the `click` handler of an `` element. If the element (or a parent) uses [`data-sveltekit-preload-data`](/docs/link-options#data-sveltekit-preload-data), the data will have already been requested, and `preloadData` will reuse that request. + +```svelte + + + +{#each data.thumbnails as thumbnail} + { + // bail if opening a new tab, or we're on too small a screen + if (e.metaKey || innerWidth < 640) return; + + // prevent navigation + e.preventDefault(); + + const { href } = e.currentTarget; + + // run `load` functions (or rather, get the result of the `load` functions + // that are already running because of `data-sveltekit-preload-data`) + const result = await preloadData(href); + + if (result.type === 'loaded' && result.status === 200) { + pushState(href, { selected: result.data }); + } else { + // something bad happened! try navigating + goto(href); + } + }} + > + {thumbnail.alt} + +{/each} + +{#if $page.state.selected} + history.goBack()}> + + + +{/if} +``` + +## Caveats + +During server-side rendering, `$page.state` is always an empty object. The same is true for the first page the user lands on — if the user reloads the page, state will _not_ be applied until they navigate. + +Shallow routing is a feature that requires JavaScript to work. Be mindful when using it and try to think of sensible fallback behavior in case JavaScript isn't available. diff --git a/documentation/docs/60-appendix/01-faq.md b/documentation/docs/60-appendix/10-faq.md similarity index 100% rename from documentation/docs/60-appendix/01-faq.md rename to documentation/docs/60-appendix/10-faq.md diff --git a/documentation/docs/60-appendix/05-integrations.md b/documentation/docs/60-appendix/20-integrations.md similarity index 91% rename from documentation/docs/60-appendix/05-integrations.md rename to documentation/docs/60-appendix/20-integrations.md index 4bf23ff97c51..9ebd5fd330e6 100644 --- a/documentation/docs/60-appendix/05-integrations.md +++ b/documentation/docs/60-appendix/20-integrations.md @@ -8,11 +8,11 @@ Preprocessors transform your `.svelte` files before passing them to the compiler ### `vitePreprocess` -`vite-plugin-svelte` offers a [`vitePreprocess`](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/preprocess.md) feature which utilizes Vite for preprocessing. It is capable of handling the language flavors Vite handles: TypeScript, PostCSS, SCSS, Less, Stylus, and SugarSS. For convenience, it is re-exported from the `@sveltejs/kit/vite` package. If you set your project up with TypeScript it will be included by default: +`vite-plugin-svelte` offers a [`vitePreprocess`](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/preprocess.md) feature which utilizes Vite for preprocessing. It is capable of handling the language flavors Vite handles: TypeScript, PostCSS, SCSS, Less, Stylus, and SugarSS. If you set your project up with TypeScript it will be included by default: ```js // svelte.config.js -import { vitePreprocess } from '@sveltejs/kit/vite'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; export default { preprocess: [vitePreprocess()] diff --git a/documentation/docs/60-appendix/30-migrating-to-sveltekit-2.md b/documentation/docs/60-appendix/30-migrating-to-sveltekit-2.md new file mode 100644 index 000000000000..0fc01031ce78 --- /dev/null +++ b/documentation/docs/60-appendix/30-migrating-to-sveltekit-2.md @@ -0,0 +1,160 @@ +--- +title: Migrating to SvelteKit v2 +--- + +Upgrading from SvelteKit version 1 to version 2 should be mostly seamless. There are a few breaking changes to note, which are listed here. You can use `npx svelte-migrate sveltekit-2` to migrate some of these changes automatically. + +We highly recommend upgrading to the most recent 1.x version before upgrading to 2.0, so that you can take advantage of targeted deprecation warnings. We also recommend [updating to Svelte 4](https://svelte.dev/docs/v4-migration-guide) first: Later versions of SvelteKit 1.x support it, and SvelteKit 2.0 requires it. + +## `redirect` and `error` are no longer thrown by you + +Previously, you had to `throw` the values returned from `error(...)` and `redirect(...)` yourself. In SvelteKit 2 this is no longer the case — calling the functions is sufficient. + +```diff +import { error } from '@sveltejs/kit' + +... +- throw error(500, 'something went wrong'); ++ error(500, 'something went wrong'); +``` + +`svelte-migrate` will do these changes automatically for you. + +If the error or redirect is thrown inside a `try {...}` block (hint: don't do this!), you can distinguish them from unexpected errors using [`isHttpError`](/docs/modules#sveltejs-kit-ishttperror) and [`isRedirect`](/docs/modules#sveltejs-kit-isredirect) imported from `@sveltejs/kit`. + +## path is required when setting cookies + +When receiving a `Set-Cookie` header that doesn't specify a `path`, browsers will [set the cookie path](https://www.rfc-editor.org/rfc/rfc6265#section-5.1.4) to the parent of the resource in question. This behaviour isn't particularly helpful or intuitive, and frequently results in bugs because the developer expected the cookie to apply to the domain as a whole. + +As of SvelteKit 2.0, you need to set a `path` when calling `cookies.set(...)`, `cookies.delete(...)` or `cookies.serialize(...)` so that there's no ambiguity. Most of the time, you probably want to use `path: '/'`, but you can set it to whatever you like, including relative paths — `''` means 'the current path', `'.'` means 'the current directory'. + +```diff +export function load({ cookies }) { +- cookies.set(name, value); ++ cookies.set(name, value, { path: '/' }); + return { response } +} +``` + +`svelte-migrate` will add comments highlighting the locations that need to be adjusted. + +## Top-level promises are no longer awaited + +In SvelteKit version 1, if the top-level properties of the object returned from a `load` function were promises, they were automatically awaited. With the introduction of [streaming](https://svelte.dev/blog/streaming-snapshots-sveltekit) this behavior became a bit awkward as it forces you to nest your streamed data one level deep. + +As of version 2, SvelteKit no longer differentiates between top-level and non-top-level promises. To get back the blocking behavior, use `await` (with `Promise.all` to prevent waterfalls, where appropriate): + +```diff +// If you have a single promise +export function load({ fetch }) { +- const response = fetch(...).then(r => r.json()); ++ const response = await fetch(...).then(r => r.json()); + return { response } +} +``` + +```diff +// If you have multiple promises +export function load({ fetch }) { +- const a = fetch(...).then(r => r.json()); +- const b = fetch(...).then(r => r.json()); ++ const [a, b] = await Promise.all([ ++ fetch(...).then(r => r.json()), ++ fetch(...).then(r => r.json()), ++ ]); + return { a, b }; +} +``` + +## goto(...) changes + +`goto(...)` no longer accepts external URLs. To navigate to an external URL, use `window.location = url`. The `state` option was removed in favor of [shallow routing](shallow-routing). + +## paths are now relative by default + +In SvelteKit 1, `%sveltekit.assets%` in your `app.html` was replaced with a relative path by default (i.e. `.` or `..` or `../..` etc, depending on the path being rendered) during server-side rendering unless the [`paths.relative`](/docs/configuration#paths) config option was explicitly set to `false`. The same was true for `base` and `assets` imported from `$app/paths`, but only if the `paths.relative` option was explicitly set to `true`. + +This inconsistency is fixed in version 2. Paths are either always relative or always absolute, depending on the value of [`paths.relative`](/docs/configuration#paths). It defaults to `true` as this results in more portable apps: if the `base` is something other than the app expected (as is the case when viewed on the [Internet Archive](https://archive.org/), for example) or unknown at build time (as is the case when deploying to [IPFS](https://ipfs.tech/) and so on), fewer things are likely to break. + +## Server fetches are not trackable anymore + +Previously it was possible to track URLs from `fetch`es on the server in order to rerun load functions. This poses a possible security risk (private URLs leaking), and as such it was behind the `dangerZone.trackServerFetches` setting, which is now removed. + +## `preloadCode` arguments must be prefixed with `base` + +SvelteKit exposes two functions, [`preloadCode`](/docs/modules#$app-navigation-preloadcode) and [`preloadData`](/docs/modules#$app-navigation-preloaddata), for programmatically loading the code and data associated with a particular path. In version 1, there was a subtle inconsistency — the path passed to `preloadCode` did not need to be prefixed with the `base` path (if set), while the path passed to `preloadData` did. + +This is fixed in SvelteKit 2 — in both cases, the path should be prefixed with `base` if it is set. + +Additionally, `preloadCode` now takes a single argument rather than _n_ arguments. + +## `resolvePath` has been removed + +SvelteKit 1 included a function called `resolvePath` which allows you to resolve a route ID (like `/blog/[slug]`) and a set of parameters (like `{ slug: 'hello' }`) to a pathname. Unfortunately the return value didn't include the `base` path, limiting its usefulness in cases where `base` was set. + +As such, SvelteKit 2 replaces `resolvePath` with a (slightly better named) function called `resolveRoute`, which is imported from `$app/paths` and which takes `base` into account. + +```diff +-import { resolvePath } from '@sveltejs/kit'; +-import { base } from '$app/paths'; ++import { resolveRoute } from '$app/paths'; + +-const path = base + resolvePath('/blog/[slug]', { slug }); ++const path = resolveRoute('/blog/[slug]', { slug }); +``` + +`svelte-migrate` will do the method replacement for you, though if you later prepend the result with `base`, you need to remove that yourself. + +## Improved error handling + +Errors are handled inconsistently in SvelteKit 1. Some errors trigger the `handleError` hook but there is no good way to discern their status (for example, the only way to tell a 404 from a 500 is by seeing if `event.route.id` is `null`), while others (such as 405 errors for `POST` requests to pages without actions) don't trigger `handleError` at all, but should. In the latter case, the resulting `$page.error` will deviate from the [`App.Error`](/docs/types#app-error) type, if it is specified. + +SvelteKit 2 cleans this up by calling `handleError` hooks with two new properties: `status` and `message`. For errors thrown from your code (or library code called by your code) the status will be `500` and the message will be `Internal Error`. While `error.message` may contain sensitive information that should not be exposed to users, `message` is safe. + +## Dynamic environment variables cannot be used during prerendering + +The `$env/dynamic/public` and `$env/dynamic/private` modules provide access to _run time_ environment variables, as opposed to the _build time_ environment variables exposed by `$env/static/public` and `$env/static/private`. + +During prerendering in SvelteKit 1, they are one and the same. As such, prerendered pages that make use of 'dynamic' environment variables are really 'baking in' build time values, which is incorrect. Worse, `$env/dynamic/public` is populated in the browser with these stale values if the user happens to land on a prerendered page before navigating to dynamically-rendered pages. + +Because of this, dynamic environment variables can no longer be read during prerendering in SvelteKit 2 — you should use the `static` modules instead. If the user lands on a prerendered page, SvelteKit will request up-to-date values for `$env/dynamic/public` from the server (by default from a module called `_env.js` — this can be configured with `config.kit.env.publicModule`) instead of reading them from the server-rendered HTML. + +## `form` and `data` have been removed from `use:enhance` callbacks + +If you provide a callback to [`use:enhance`](/docs/form-actions#progressive-enhancement-use-enhance), it will be called with an object containing various useful properties. + +In SvelteKit 1, those properties included `form` and `data`. These were deprecated some time ago in favour of `formElement` and `formData`, and have been removed altogether in SvelteKit 2. + +## Forms containing file inputs must use `multipart/form-data` + +If a form contains an `` but does not have an `enctype="multipart/form-data"` attribute, non-JS submissions will omit the file. SvelteKit 2 will throw an error if it encounters a form like this during a `use:enhance` submission to ensure that your forms work correctly when JavaScript is not present. + +## Generated `tsconfig.json` is more strict + +Previously, the generated `tsconfig.json` was trying its best to still produce a somewhat valid config when your `tsconfig.json` included `paths` or `baseUrl`. In SvelteKit 2, the validation is more strict and will warn when you use either `paths` or `baseUrl` in your `tsconfig.json`. These settings are used to generate path aliases and you should use [the `alias` config](configuration#alias) option in your `svelte.config.js` instead, to also create a corresponding alias for the bundler. + +## `getRequest` no longer throws errors + +The `@sveltejs/kit/node` module exports helper functions for use in Node environments, including `getRequest` which turns a Node [`ClientRequest`](https://nodejs.org/api/http.html#class-httpclientrequest) into a standard [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. + +In SvelteKit 1, `getRequest` could throw if the `Content-Length` header exceeded the specified size limit. In SvelteKit 2, the error will not be thrown until later, when the request body (if any) is being read. This enables better diagnostics and simpler code. + +## `vitePreprocess` is no longer exported from `@sveltejs/kit/vite` + +Since `@sveltejs/vite-plugin-svelte` is now a peer dependency, SvelteKit 2 no longer re-exports `vitePreprocess`. You should import it directly from `@sveltejs/vite-plugin-svelte`. + +## Updated dependency requirements + +SvelteKit 2 requires Node `18.13` or higher, and the following minimum dependency versions: + +- `svelte@4` +- `vite@5` +- `typescript@5` +- `@sveltejs/adapter-static@3` (if you're using it) +- `@sveltejs/vite-plugin-svelte@3` (this is now required as a `peerDependency` of SvelteKit — previously it was directly depended upon) + +`svelte-migrate` will update your `package.json` for you. + +As part of the TypeScript upgrade, the generated `tsconfig.json` (the one your `tsconfig.json` extends from) now uses `"moduleResolution": "bundler"` (which is recommended by the TypeScript team, as it properly resolves types from packages with an `exports` map in package.json) and `verbatimModuleSyntax` (which replaces the existing `importsNotUsedAsValues ` and `preserveValueImports` flags — if you have those in your `tsconfig.json`, remove them. `svelte-migrate` will do this for you). + +SvelteKit 2 uses ES2022 features, which are supported in all modern browsers. diff --git a/documentation/docs/60-appendix/10-migrating.md b/documentation/docs/60-appendix/40-migrating.md similarity index 100% rename from documentation/docs/60-appendix/10-migrating.md rename to documentation/docs/60-appendix/40-migrating.md diff --git a/documentation/docs/60-appendix/20-additional-resources.md b/documentation/docs/60-appendix/50-additional-resources.md similarity index 100% rename from documentation/docs/60-appendix/20-additional-resources.md rename to documentation/docs/60-appendix/50-additional-resources.md diff --git a/documentation/docs/60-appendix/30-glossary.md b/documentation/docs/60-appendix/60-glossary.md similarity index 100% rename from documentation/docs/60-appendix/30-glossary.md rename to documentation/docs/60-appendix/60-glossary.md diff --git a/package.json b/package.json index 25b2fa0143cd..a64f82d7623f 100644 --- a/package.json +++ b/package.json @@ -19,24 +19,21 @@ "start": "cd sites/kit.svelte.dev && npm run dev" }, "devDependencies": { - "@changesets/cli": "^2.26.2", - "@rollup/plugin-commonjs": "^25.0.0", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.1", + "@changesets/cli": "^2.27.1", "@sveltejs/eslint-config": "^6.0.4", "@svitejs/changesets-changelog-github-compact": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "eslint": "^8.52.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-svelte": "^2.31.0", + "@typescript-eslint/eslint-plugin": "^6.14.0", + "eslint": "^8.55.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-svelte": "^2.35.1", "eslint-plugin-unicorn": "^49.0.0", "playwright": "1.30.0", "prettier": "^3.1.1", "rollup": "^3.29.4", - "svelte": "^4.2.7", - "typescript": "^4.9.4" + "svelte": "^4.2.8", + "typescript": "^5.3.3" }, - "packageManager": "pnpm@8.10.2", + "packageManager": "pnpm@8.11.0", "engines": { "pnpm": "^8.0.0" } diff --git a/packages/adapter-auto/package.json b/packages/adapter-auto/package.json index 037ba5fd38ab..ba1ff78660e7 100644 --- a/packages/adapter-auto/package.json +++ b/packages/adapter-auto/package.json @@ -31,13 +31,14 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "@types/node": "^16.18.6", - "typescript": "^4.9.4" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@types/node": "^18.19.3", + "typescript": "^5.3.3" }, "dependencies": { "import-meta-resolve": "^4.0.0" }, "peerDependencies": { - "@sveltejs/kit": "^1.0.0" + "@sveltejs/kit": "^1.0.0 || ^2.0.0" } } diff --git a/packages/adapter-cloudflare-workers/index.d.ts b/packages/adapter-cloudflare-workers/index.d.ts index 8b90611b73c3..d5ef5b24e7b5 100644 --- a/packages/adapter-cloudflare-workers/index.d.ts +++ b/packages/adapter-cloudflare-workers/index.d.ts @@ -1,4 +1,4 @@ import { Adapter } from '@sveltejs/kit'; import './ambient.js'; -export default function plugin(options: { config?: string }): Adapter; +export default function plugin(options?: { config?: string }): Adapter; diff --git a/packages/adapter-cloudflare-workers/package.json b/packages/adapter-cloudflare-workers/package.json index 8913f8885e73..86a31cd1270a 100644 --- a/packages/adapter-cloudflare-workers/package.json +++ b/packages/adapter-cloudflare-workers/package.json @@ -30,16 +30,16 @@ "check": "tsc" }, "dependencies": { - "@cloudflare/workers-types": "^4.20230404.0", + "@cloudflare/workers-types": "^4.20231121.0", "@iarna/toml": "^2.2.5", - "esbuild": "^0.18.11" + "esbuild": "^0.19.9" }, "devDependencies": { "@cloudflare/kv-asset-handler": "^0.3.0", - "@types/node": "^16.18.6", - "typescript": "^4.9.4" + "@types/node": "^18.19.3", + "typescript": "^5.3.3" }, "peerDependencies": { - "@sveltejs/kit": "^1.0.0" + "@sveltejs/kit": "^1.0.0 || ^2.0.0" } } diff --git a/packages/adapter-cloudflare/package.json b/packages/adapter-cloudflare/package.json index 6b2f5d274568..19c6f42cad95 100644 --- a/packages/adapter-cloudflare/package.json +++ b/packages/adapter-cloudflare/package.json @@ -32,17 +32,17 @@ "prepublishOnly": "pnpm build" }, "dependencies": { - "@cloudflare/workers-types": "^4.20230404.0", - "esbuild": "^0.18.11", + "@cloudflare/workers-types": "^4.20231121.0", + "esbuild": "^0.19.9", "worktop": "0.8.0-next.15" }, "devDependencies": { - "@types/node": "^16.18.6", - "@types/ws": "^8.5.3", - "typescript": "^4.9.4" + "@types/node": "^18.19.3", + "@types/ws": "^8.5.10", + "typescript": "^5.3.3" }, "peerDependencies": { - "@sveltejs/kit": "^1.0.0" + "@sveltejs/kit": "^1.0.0 || ^2.0.0" }, "publishConfig": { "access": "public" diff --git a/packages/adapter-netlify/package.json b/packages/adapter-netlify/package.json index b417461d9b8f..2a921d2529b1 100644 --- a/packages/adapter-netlify/package.json +++ b/packages/adapter-netlify/package.json @@ -34,22 +34,23 @@ }, "dependencies": { "@iarna/toml": "^2.2.5", - "esbuild": "^0.18.11", + "esbuild": "^0.19.9", "set-cookie-parser": "^2.6.0" }, "devDependencies": { - "@netlify/functions": "^2.0.1", - "@rollup/plugin-commonjs": "^25.0.0", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.1", + "@netlify/functions": "^2.4.1", + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", "@sveltejs/kit": "workspace:^", - "@types/node": "^16.18.6", - "@types/set-cookie-parser": "^2.4.2", - "rollup": "^3.29.4", - "typescript": "^4.9.4", - "vitest": "^0.34.5" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@types/node": "^18.19.3", + "@types/set-cookie-parser": "^2.4.7", + "rollup": "^4.8.0", + "typescript": "^5.3.3", + "vitest": "^1.0.4" }, "peerDependencies": { - "@sveltejs/kit": "^1.5.0" + "@sveltejs/kit": "^1.5.0 || ^2.0.0" } } diff --git a/packages/adapter-netlify/rollup.config.js b/packages/adapter-netlify/rollup.config.js index 7eca711c728c..b69d62886502 100644 --- a/packages/adapter-netlify/rollup.config.js +++ b/packages/adapter-netlify/rollup.config.js @@ -12,6 +12,7 @@ const config = { dir: 'files/esm', format: 'esm' }, + // @ts-ignore https://github.com/rollup/plugins/issues/1329 plugins: [nodeResolve({ preferBuiltins: true }), commonjs(), json()], external: (id) => id === '0SERVER' || id.startsWith('node:'), preserveEntrySignatures: 'exports-only' diff --git a/packages/adapter-netlify/tsconfig.json b/packages/adapter-netlify/tsconfig.json index 050c14d467ea..1eeee8b0847d 100644 --- a/packages/adapter-netlify/tsconfig.json +++ b/packages/adapter-netlify/tsconfig.json @@ -5,10 +5,10 @@ "noEmit": true, "noImplicitAny": true, "target": "es2022", - "module": "es2022", - // `@netlify/function` > `@netlify/serverless-functions-api` types are not compatible, - // so using this moduleResolution for now - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", + // https://github.com/netlify/functions/issues/447 + "skipLibCheck": true, "allowSyntheticDefaultImports": true, "baseUrl": ".", "paths": { diff --git a/packages/adapter-node/index.d.ts b/packages/adapter-node/index.d.ts index 12ea6273dd66..d32510e25186 100644 --- a/packages/adapter-node/index.d.ts +++ b/packages/adapter-node/index.d.ts @@ -9,7 +9,6 @@ interface AdapterOptions { out?: string; precompress?: boolean; envPrefix?: string; - polyfill?: boolean; } export default function plugin(options?: AdapterOptions): Adapter; diff --git a/packages/adapter-node/index.js b/packages/adapter-node/index.js index 2d34cfb22d29..4cd8d42cbe29 100644 --- a/packages/adapter-node/index.js +++ b/packages/adapter-node/index.js @@ -9,7 +9,7 @@ const files = fileURLToPath(new URL('./files', import.meta.url).href); /** @type {import('./index.js').default} */ export default function (opts = {}) { - const { out = 'build', precompress, envPrefix = '', polyfill = true } = opts; + const { out = 'build', precompress, envPrefix = '' } = opts; return { name: '@sveltejs/adapter-node', @@ -62,7 +62,9 @@ export default function (opts = {}) { preferBuiltins: true, exportConditions: ['node'] }), + // @ts-ignore https://github.com/rollup/plugins/issues/1329 commonjs({ strictRequires: true }), + // @ts-ignore https://github.com/rollup/plugins/issues/1329 json() ] }); @@ -84,11 +86,6 @@ export default function (opts = {}) { ENV_PREFIX: JSON.stringify(envPrefix) } }); - - // If polyfills aren't wanted then clear the file - if (!polyfill) { - writeFileSync(`${out}/shims.js`, '', 'utf-8'); - } } }; } diff --git a/packages/adapter-node/package.json b/packages/adapter-node/package.json index d18a3f1c46f1..d3b5c1c7ce58 100644 --- a/packages/adapter-node/package.json +++ b/packages/adapter-node/package.json @@ -33,22 +33,23 @@ "prepublishOnly": "pnpm build" }, "devDependencies": { - "@polka/url": "^1.0.0-next.23", + "@polka/url": "1.0.0-next.24", "@sveltejs/kit": "workspace:^", - "@types/node": "^16.18.6", - "c8": "^8.0.0", - "polka": "^1.0.0-next.23", + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@types/node": "^18.19.3", + "c8": "^8.0.1", + "polka": "1.0.0-next.24", "sirv": "^2.0.3", - "typescript": "^4.9.4", - "vitest": "^0.34.5" + "typescript": "^5.3.3", + "vitest": "^1.0.4" }, "dependencies": { - "@rollup/plugin-commonjs": "^25.0.0", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.1", - "rollup": "^3.7.0" + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "rollup": "^4.8.0" }, "peerDependencies": { - "@sveltejs/kit": "^1.0.0" + "@sveltejs/kit": "^2.0.0" } } diff --git a/packages/adapter-node/src/handler.js b/packages/adapter-node/src/handler.js index bae1854bdd7e..09bf98f63a11 100644 --- a/packages/adapter-node/src/handler.js +++ b/packages/adapter-node/src/handler.js @@ -76,20 +76,11 @@ function serve_prerendered() { /** @type {import('polka').Middleware} */ const ssr = async (req, res) => { - /** @type {Request | undefined} */ - let request; - - try { - request = await getRequest({ - base: origin || get_origin(req.headers), - request: req, - bodySizeLimit: body_size_limit - }); - } catch (err) { - res.statusCode = err.status || 400; - res.end('Invalid request body'); - return; - } + const request = await getRequest({ + base: origin || get_origin(req.headers), + request: req, + bodySizeLimit: body_size_limit + }); setResponse( res, diff --git a/packages/adapter-node/tsconfig.json b/packages/adapter-node/tsconfig.json index 7d320c09f70c..17a612157ece 100644 --- a/packages/adapter-node/tsconfig.json +++ b/packages/adapter-node/tsconfig.json @@ -6,11 +6,8 @@ "noImplicitAny": true, "allowSyntheticDefaultImports": true, "target": "es2022", - "module": "es2022", - // Can't use moduleResolution: node16 because of these issues: - // https://github.com/rollup/plugins/issues/1329 - // https://github.com/lukeed/polka/issues/199 - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "baseUrl": ".", "paths": { "@sveltejs/kit": ["../kit/types/index"] diff --git a/packages/adapter-static/index.js b/packages/adapter-static/index.js index 2fe366a5231e..32d7e5319df7 100644 --- a/packages/adapter-static/index.js +++ b/packages/adapter-static/index.js @@ -52,6 +52,7 @@ See https://kit.svelte.dev/docs/page-options#prerender for more details` } const { + // @ts-ignore pages = 'build', assets = pages, fallback, @@ -61,6 +62,7 @@ See https://kit.svelte.dev/docs/page-options#prerender for more details` builder.rimraf(assets); builder.rimraf(pages); + builder.generateEnvModule(); builder.writeClient(assets); builder.writePrerendered(pages); diff --git a/packages/adapter-static/package.json b/packages/adapter-static/package.json index 1a1ab9478510..878e652767f9 100644 --- a/packages/adapter-static/package.json +++ b/packages/adapter-static/package.json @@ -32,13 +32,14 @@ "devDependencies": { "@playwright/test": "1.30.0", "@sveltejs/kit": "workspace:^", - "@types/node": "^16.18.6", + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@types/node": "^18.19.3", "sirv": "^2.0.3", - "svelte": "^4.2.7", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "peerDependencies": { - "@sveltejs/kit": "^1.5.0" + "@sveltejs/kit": "^2.0.0" } } diff --git a/packages/adapter-static/test/apps/prerendered/package.json b/packages/adapter-static/test/apps/prerendered/package.json index 782b53e3c746..98b381193dbe 100644 --- a/packages/adapter-static/test/apps/prerendered/package.json +++ b/packages/adapter-static/test/apps/prerendered/package.json @@ -10,9 +10,10 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "sirv-cli": "^2.0.2", - "svelte": "^4.2.7", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/adapter-static/test/apps/prerendered/src/routes/public-env/+page.svelte b/packages/adapter-static/test/apps/prerendered/src/routes/public-env/+page.svelte index 1c06b45b43e4..a36f01afaa54 100644 --- a/packages/adapter-static/test/apps/prerendered/src/routes/public-env/+page.svelte +++ b/packages/adapter-static/test/apps/prerendered/src/routes/public-env/+page.svelte @@ -1,5 +1,11 @@ -

The answer is {env.PUBLIC_ANSWER}

+

The answer is {PUBLIC_ANSWER}

+ +{#if browser} +

The dynamic answer is {env.PUBLIC_ANSWER}

+{/if} diff --git a/packages/adapter-static/test/apps/prerendered/test/test.js b/packages/adapter-static/test/apps/prerendered/test/test.js index 6a5ea0c2ee8b..2e187f8effd5 100644 --- a/packages/adapter-static/test/apps/prerendered/test/test.js +++ b/packages/adapter-static/test/apps/prerendered/test/test.js @@ -24,4 +24,5 @@ test('prerenders a referenced endpoint with implicit `prerender` setting', async test('exposes public env vars to the client', async ({ page }) => { await page.goto('/public-env'); expect(await page.textContent('h1')).toEqual('The answer is 42'); + expect(await page.textContent('h2')).toEqual('The dynamic answer is 42'); }); diff --git a/packages/adapter-static/test/apps/spa/package.json b/packages/adapter-static/test/apps/spa/package.json index d166f5828292..03971e030a2e 100644 --- a/packages/adapter-static/test/apps/spa/package.json +++ b/packages/adapter-static/test/apps/spa/package.json @@ -11,9 +11,10 @@ "devDependencies": { "@sveltejs/adapter-node": "workspace:^", "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "sirv-cli": "^2.0.2", - "svelte": "^4.2.7", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/adapter-static/test/apps/spa/src/routes/fallback/[...rest]/+page.svelte b/packages/adapter-static/test/apps/spa/src/routes/fallback/[...rest]/+page.svelte index 8950feed162a..55b4798e99c5 100644 --- a/packages/adapter-static/test/apps/spa/src/routes/fallback/[...rest]/+page.svelte +++ b/packages/adapter-static/test/apps/spa/src/routes/fallback/[...rest]/+page.svelte @@ -1,7 +1,7 @@

the fallback page was rendered

-{env.PUBLIC_VALUE} +{PUBLIC_VALUE} diff --git a/packages/adapter-vercel/files/serverless.js b/packages/adapter-vercel/files/serverless.js index 5a6c2f64e2fd..d732371568c8 100644 --- a/packages/adapter-vercel/files/serverless.js +++ b/packages/adapter-vercel/files/serverless.js @@ -32,15 +32,7 @@ export default async (req, res) => { } } - /** @type {Request} */ - let request; - - try { - request = await getRequest({ base: `https://${req.headers.host}`, request: req }); - } catch (err) { - res.statusCode = /** @type {any} */ (err).status || 400; - return res.end('Invalid request body'); - } + const request = await getRequest({ base: `https://${req.headers.host}`, request: req }); setResponse( res, diff --git a/packages/adapter-vercel/index.d.ts b/packages/adapter-vercel/index.d.ts index 8e3a96bec132..6d9f8d359891 100644 --- a/packages/adapter-vercel/index.d.ts +++ b/packages/adapter-vercel/index.d.ts @@ -28,6 +28,12 @@ export interface ServerlessConfig { * If `true`, this route will always be deployed as its own separate function */ split?: boolean; + + /** + * https://vercel.com/docs/build-output-api/v3/configuration#images + */ + images?: ImagesConfig; + /** * [Incremental Static Regeneration](https://vercel.com/docs/concepts/incremental-static-regeneration/overview) configuration. * Serverless only. @@ -53,6 +59,26 @@ export interface ServerlessConfig { | false; } +type ImageFormat = 'image/avif' | 'image/webp'; + +type RemotePattern = { + protocol?: 'http' | 'https'; + hostname: string; + port?: string; + pathname?: string; +}; + +type ImagesConfig = { + sizes: number[]; + domains: string[]; + remotePatterns?: RemotePattern[]; + minimumCacheTTL?: number; // seconds + formats?: ImageFormat[]; + dangerouslyAllowSVG?: boolean; + contentSecurityPolicy?: string; + contentDispositionType?: string; +}; + export interface EdgeConfig { /** * Whether to use [Edge Functions](https://vercel.com/docs/concepts/functions/edge-functions) (`'edge'`) or [Serverless Functions](https://vercel.com/docs/concepts/functions/serverless-functions) (`'nodejs18.x'`, `'nodejs20.x'` etc). diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index 40fe02c2b0d9..3a6ebec5240f 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -54,7 +54,7 @@ const plugin = function (defaults = {}) { functions: `${dir}/functions` }; - const static_config = static_vercel_config(builder); + const static_config = static_vercel_config(builder, defaults); builder.log.minor('Generating serverless function...'); @@ -367,14 +367,20 @@ function write(file, data) { } // This function is duplicated in adapter-static -/** @param {import('@sveltejs/kit').Builder} builder */ -function static_vercel_config(builder) { +/** + * @param {import('@sveltejs/kit').Builder} builder + * @param {import('.').Config} config + */ +function static_vercel_config(builder, config) { /** @type {any[]} */ const prerendered_redirects = []; /** @type {Record} */ const overrides = {}; + /** @type {import('./index').ImagesConfig} */ + const images = config.images; + for (const [src, redirect] of builder.prerendered.redirects) { prerendered_redirects.push({ src, @@ -420,7 +426,8 @@ function static_vercel_config(builder) { handle: 'filesystem' } ], - overrides + overrides, + images }; } diff --git a/packages/adapter-vercel/package.json b/packages/adapter-vercel/package.json index e8b8b139a7f7..7da9c6843e32 100644 --- a/packages/adapter-vercel/package.json +++ b/packages/adapter-vercel/package.json @@ -31,16 +31,17 @@ "test": "vitest run" }, "dependencies": { - "@vercel/nft": "^0.24.0", - "esbuild": "^0.18.11" + "@vercel/nft": "^0.24.4", + "esbuild": "^0.19.9" }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "@types/node": "^16.18.6", - "typescript": "^4.9.4", - "vitest": "^0.34.5" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@types/node": "^18.19.3", + "typescript": "^5.3.3", + "vitest": "^1.0.4" }, "peerDependencies": { - "@sveltejs/kit": "^1.5.0" + "@sveltejs/kit": "^2.0.0" } } diff --git a/packages/amp/package.json b/packages/amp/package.json index d8740cc5aeb1..b93383234560 100644 --- a/packages/amp/package.json +++ b/packages/amp/package.json @@ -27,6 +27,6 @@ "format": "pnpm lint --write" }, "peerDependencies": { - "@sveltejs/kit": "^1.0.0" + "@sveltejs/kit": "^1.0.0 || ^2.0.0" } } diff --git a/packages/create-svelte/package.json b/packages/create-svelte/package.json index 909ada69e12e..26981aa1d375 100644 --- a/packages/create-svelte/package.json +++ b/packages/create-svelte/package.json @@ -17,14 +17,14 @@ }, "devDependencies": { "@playwright/test": "1.30.0", - "@types/gitignore-parser": "^0.0.2", + "@types/gitignore-parser": "^0.0.3", "gitignore-parser": "^0.0.2", "prettier": "^3.1.1", - "prettier-plugin-svelte": "^3.0.0", - "sucrase": "^3.29.0", - "svelte": "^4.2.7", + "prettier-plugin-svelte": "^3.1.2", + "sucrase": "^3.34.0", + "svelte": "^4.2.8", "tiny-glob": "^0.2.9", - "vitest": "^0.34.5" + "vitest": "^1.0.4" }, "scripts": { "build": "node scripts/build-templates", diff --git a/packages/create-svelte/shared/+default+checkjs/svelte.config.js b/packages/create-svelte/shared/+default+checkjs/svelte.config.js index 1cf26a00dfea..2b35fe1befd3 100644 --- a/packages/create-svelte/shared/+default+checkjs/svelte.config.js +++ b/packages/create-svelte/shared/+default+checkjs/svelte.config.js @@ -1,5 +1,5 @@ import adapter from '@sveltejs/adapter-auto'; -import { vitePreprocess } from '@sveltejs/kit/vite'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { diff --git a/packages/create-svelte/shared/+default+typescript/svelte.config.js b/packages/create-svelte/shared/+default+typescript/svelte.config.js index 1cf26a00dfea..2b35fe1befd3 100644 --- a/packages/create-svelte/shared/+default+typescript/svelte.config.js +++ b/packages/create-svelte/shared/+default+typescript/svelte.config.js @@ -1,5 +1,5 @@ import adapter from '@sveltejs/adapter-auto'; -import { vitePreprocess } from '@sveltejs/kit/vite'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { diff --git a/packages/create-svelte/shared/+typescript/svelte.config.js b/packages/create-svelte/shared/+typescript/svelte.config.js index 1cf26a00dfea..2b35fe1befd3 100644 --- a/packages/create-svelte/shared/+typescript/svelte.config.js +++ b/packages/create-svelte/shared/+typescript/svelte.config.js @@ -1,5 +1,5 @@ import adapter from '@sveltejs/adapter-auto'; -import { vitePreprocess } from '@sveltejs/kit/vite'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { diff --git a/packages/create-svelte/shared/+vitest/package.json b/packages/create-svelte/shared/+vitest/package.json index 58c77018dcf5..94385f64f0df 100644 --- a/packages/create-svelte/shared/+vitest/package.json +++ b/packages/create-svelte/shared/+vitest/package.json @@ -1,6 +1,6 @@ { "devDependencies": { - "vitest": "^0.34.0" + "vitest": "^1.0.0" }, "scripts": { "test": "vitest" diff --git a/packages/create-svelte/templates/default/package.json b/packages/create-svelte/templates/default/package.json index 48b47d940eb1..6983ef883100 100644 --- a/packages/create-svelte/templates/default/package.json +++ b/packages/create-svelte/templates/default/package.json @@ -11,12 +11,13 @@ "@neoconfetti/svelte": "^1.0.0", "@sveltejs/adapter-auto": "workspace:*", "@sveltejs/kit": "workspace:*", - "svelte": "^4.2.7", - "typescript": "^5.0.0", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.8", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module", "dependencies": { - "@fontsource/fira-mono": "^5.0.5" + "@fontsource/fira-mono": "^5.0.8" } } diff --git a/packages/create-svelte/templates/default/package.template.json b/packages/create-svelte/templates/default/package.template.json index 02b891efa8c2..586d0f7e863b 100644 --- a/packages/create-svelte/templates/default/package.template.json +++ b/packages/create-svelte/templates/default/package.template.json @@ -10,9 +10,10 @@ "@fontsource/fira-mono": "^4.5.10", "@neoconfetti/svelte": "^1.0.0", "@sveltejs/adapter-auto": "^2.0.0", - "@sveltejs/kit": "^1.27.4", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", "svelte": "^4.2.7", - "vite": "^4.4.2" + "vite": "^5.0.3" }, "type": "module" } diff --git a/packages/create-svelte/templates/default/src/app.d.ts b/packages/create-svelte/templates/default/src/app.d.ts index f59b884c51ed..743f07b2e50a 100644 --- a/packages/create-svelte/templates/default/src/app.d.ts +++ b/packages/create-svelte/templates/default/src/app.d.ts @@ -5,6 +5,7 @@ declare global { // interface Error {} // interface Locals {} // interface PageData {} + // interface PageState {} // interface Platform {} } } diff --git a/packages/create-svelte/templates/default/src/routes/sverdle/+page.server.ts b/packages/create-svelte/templates/default/src/routes/sverdle/+page.server.ts index 0bd1db1f264f..cc77d8d43913 100644 --- a/packages/create-svelte/templates/default/src/routes/sverdle/+page.server.ts +++ b/packages/create-svelte/templates/default/src/routes/sverdle/+page.server.ts @@ -45,7 +45,7 @@ export const actions = { game.guesses[i] += key; } - cookies.set('sverdle', game.toString()); + cookies.set('sverdle', game.toString(), { path: '' }); }, /** @@ -62,10 +62,10 @@ export const actions = { return fail(400, { badGuess: true }); } - cookies.set('sverdle', game.toString()); + cookies.set('sverdle', game.toString(), { path: '' }); }, restart: async ({ cookies }) => { - cookies.delete('sverdle'); + cookies.delete('sverdle', { path: '' }); } } satisfies Actions; diff --git a/packages/create-svelte/templates/default/svelte.config.js b/packages/create-svelte/templates/default/svelte.config.js index e4597b125653..67ce801eb041 100644 --- a/packages/create-svelte/templates/default/svelte.config.js +++ b/packages/create-svelte/templates/default/svelte.config.js @@ -1,5 +1,5 @@ import adapter from '@sveltejs/adapter-auto'; -import { vitePreprocess } from '@sveltejs/kit/vite'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; // This config is ignored and replaced with one of the configs in the shared folder when a project is created. diff --git a/packages/create-svelte/templates/skeleton/package.template.json b/packages/create-svelte/templates/skeleton/package.template.json index e37b4bff6665..fada20157b4a 100644 --- a/packages/create-svelte/templates/skeleton/package.template.json +++ b/packages/create-svelte/templates/skeleton/package.template.json @@ -9,9 +9,10 @@ }, "devDependencies": { "@sveltejs/adapter-auto": "^2.0.0", - "@sveltejs/kit": "^1.27.4", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", "svelte": "^4.2.7", - "vite": "^4.4.2" + "vite": "^5.0.3" }, "type": "module" } diff --git a/packages/create-svelte/templates/skeleton/src/app.d.ts b/packages/create-svelte/templates/skeleton/src/app.d.ts index f59b884c51ed..743f07b2e50a 100644 --- a/packages/create-svelte/templates/skeleton/src/app.d.ts +++ b/packages/create-svelte/templates/skeleton/src/app.d.ts @@ -5,6 +5,7 @@ declare global { // interface Error {} // interface Locals {} // interface PageData {} + // interface PageState {} // interface Platform {} } } diff --git a/packages/create-svelte/templates/skeletonlib/package.template.json b/packages/create-svelte/templates/skeletonlib/package.template.json index 0b6cda74d2e1..b5af7d05f186 100644 --- a/packages/create-svelte/templates/skeletonlib/package.template.json +++ b/packages/create-svelte/templates/skeletonlib/package.template.json @@ -20,13 +20,14 @@ }, "devDependencies": { "@sveltejs/adapter-auto": "^2.0.0", - "@sveltejs/kit": "^1.27.4", + "@sveltejs/kit": "^2.0.0", "@sveltejs/package": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", "publint": "^0.1.9", "svelte": "^4.2.7", "tslib": "^2.4.1", - "typescript": "^5.0.0", - "vite": "^4.4.2" + "typescript": "^5.3.2", + "vite": "^5.0.3" }, "svelte": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/packages/create-svelte/templates/skeletonlib/src/app.d.ts b/packages/create-svelte/templates/skeletonlib/src/app.d.ts index f59b884c51ed..743f07b2e50a 100644 --- a/packages/create-svelte/templates/skeletonlib/src/app.d.ts +++ b/packages/create-svelte/templates/skeletonlib/src/app.d.ts @@ -5,6 +5,7 @@ declare global { // interface Error {} // interface Locals {} // interface PageData {} + // interface PageState {} // interface Platform {} } } diff --git a/packages/enhanced-img/package.json b/packages/enhanced-img/package.json index f8cbe3180c32..5cbb1d4f2599 100644 --- a/packages/enhanced-img/package.json +++ b/packages/enhanced-img/package.json @@ -26,17 +26,18 @@ }, "types": "types/index.d.ts", "dependencies": { - "magic-string": "^0.30.0", - "svelte-parse-markup": "^0.1.1", - "vite-imagetools": "^6.2.4" + "magic-string": "^0.30.5", + "svelte-parse-markup": "^0.1.2", + "vite-imagetools": "^6.2.7" }, "devDependencies": { - "@types/estree": "^1.0.2", - "@types/node": "^16.18.6", + "@types/estree": "^1.0.5", + "@types/node": "^18.19.3", "estree-walker": "^3.0.3", - "svelte": "^4.2.7", - "typescript": "^4.9.4", - "vite": "^4.4.2", - "vitest": "^0.34.0" + "rollup": "^4.8.0", + "svelte": "^4.2.8", + "typescript": "^5.3.3", + "vite": "^5.0.8", + "vitest": "^1.0.4" } } diff --git a/packages/enhanced-img/src/index.js b/packages/enhanced-img/src/index.js index 438b1ced6260..48347ee6ae97 100644 --- a/packages/enhanced-img/src/index.js +++ b/packages/enhanced-img/src/index.js @@ -24,7 +24,7 @@ export async function enhancedImages() { function image_plugin(imagetools_plugin) { /** * @type {{ - * plugin_context: import('rollup').PluginContext + * plugin_context: import('vite').Rollup.PluginContext * imagetools_plugin: import('vite').Plugin * }} */ diff --git a/packages/enhanced-img/src/preprocessor.js b/packages/enhanced-img/src/preprocessor.js index bf1289a25878..e67adfe8b5bb 100644 --- a/packages/enhanced-img/src/preprocessor.js +++ b/packages/enhanced-img/src/preprocessor.js @@ -9,7 +9,7 @@ const OPTIMIZABLE = /^[^?]+\.(avif|heif|gif|jpeg|jpg|png|tiff|webp)(\?.*)?$/; /** * @param {{ - * plugin_context: import('rollup').PluginContext + * plugin_context: import('vite').Rollup.PluginContext * imagetools_plugin: import('vite').Plugin * }} opts * @returns {import('svelte/types/compiler/preprocess').PreprocessorGroup} @@ -144,7 +144,7 @@ function is_quote(content, index) { /** * @param {{ - * plugin_context: import('rollup').PluginContext + * plugin_context: import('vite').Rollup.PluginContext * imagetools_plugin: import('vite').Plugin * }} opts * @param {string} url diff --git a/packages/enhanced-img/tsconfig.json b/packages/enhanced-img/tsconfig.json index 638484204f12..0ff94d9e3f38 100644 --- a/packages/enhanced-img/tsconfig.json +++ b/packages/enhanced-img/tsconfig.json @@ -5,8 +5,8 @@ "noEmit": true, "strict": true, "target": "es2022", - "module": "es2022", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "allowSyntheticDefaultImports": true, "paths": { "types": ["./types/index"], diff --git a/packages/kit/package.json b/packages/kit/package.json index ba46dd8c0ba2..ff775f1e8364 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -11,37 +11,37 @@ "homepage": "https://kit.svelte.dev", "type": "module", "dependencies": { - "@sveltejs/vite-plugin-svelte": "^2.5.0", - "@types/cookie": "^0.5.1", - "cookie": "^0.5.0", - "devalue": "^4.3.1", + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0", + "devalue": "^4.3.2", "esm-env": "^1.0.0", "kleur": "^4.1.5", - "magic-string": "^0.30.0", + "magic-string": "^0.30.5", "mrmime": "^1.0.1", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", - "sirv": "^2.0.2", - "tiny-glob": "^0.2.9", - "undici": "~5.26.2" + "sirv": "^2.0.3", + "tiny-glob": "^0.2.9" }, "devDependencies": { "@playwright/test": "1.30.0", - "@types/connect": "^3.4.35", - "@types/node": "^16.18.6", - "@types/sade": "^1.7.4", - "@types/set-cookie-parser": "^2.4.2", - "dts-buddy": "^0.2.4", - "rollup": "^3.29.4", - "svelte": "^4.2.7", - "svelte-preprocess": "^5.1.1", - "typescript": "^4.9.4", - "vite": "^4.4.9", - "vitest": "^0.34.5" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@types/connect": "^3.4.38", + "@types/node": "^18.19.3", + "@types/sade": "^1.7.8", + "@types/set-cookie-parser": "^2.4.7", + "dts-buddy": "^0.4.3", + "rollup": "^4.8.0", + "svelte": "^4.2.8", + "svelte-preprocess": "^5.1.2", + "typescript": "^5.3.3", + "vite": "^5.0.8", + "vitest": "^1.0.4" }, "peerDependencies": { - "svelte": "^3.54.0 || ^4.0.0-next.0 || ^5.0.0-next.0", - "vite": "^4.0.0" + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3" }, "bin": { "svelte-kit": "svelte-kit.js" @@ -57,7 +57,7 @@ ], "scripts": { "lint": "prettier --config ../../.prettierrc --check .", - "check": "tsc", + "check": "tsc && cd ./test/types && tsc", "check:all": "tsc && pnpm -r --filter=\"./**\" check", "format": "prettier --config ../../.prettierrc --write .", "test": "pnpm test:unit && pnpm test:integration", @@ -95,6 +95,6 @@ }, "types": "types/index.d.ts", "engines": { - "node": "^16.14 || >=18" + "node": ">=18.13" } } diff --git a/packages/kit/src/core/adapt/builder.js b/packages/kit/src/core/adapt/builder.js index 11fd9cbc1fd6..2c55f5027485 100644 --- a/packages/kit/src/core/adapt/builder.js +++ b/packages/kit/src/core/adapt/builder.js @@ -156,6 +156,13 @@ export function create_builder({ write(dest, fallback); }, + generateEnvModule() { + const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}/env.js`; + const env = get_env(config.kit.env, vite_config.mode); + + write(dest, `export const env=${JSON.stringify(env.public)}`); + }, + generateManifest({ relativePath, routes: subset }) { return generate_manifest({ build_data, diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js index a6e37d794277..cb2a44670bfd 100644 --- a/packages/kit/src/core/config/index.js +++ b/packages/kit/src/core/config/index.js @@ -69,7 +69,15 @@ export async function load_config({ cwd = process.cwd() } = {}) { const config = await import(`${url.pathToFileURL(config_file).href}?ts=${Date.now()}`); - return process_config(config.default, { cwd }); + try { + return process_config(config.default, { cwd }); + } catch (e) { + const error = /** @type {Error} */ (e); + + // redact the stack trace — it's not helpful to users + error.stack = `Could not load svelte.config.js: ${error.message}\n`; + throw error; + } } /** diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index faaf138aebb3..673515c60802 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -69,9 +69,6 @@ const get_defaults = (prefix = '') => ({ csrf: { checkOrigin: true }, - dangerZone: { - trackServerFetches: false - }, embedded: false, env: { dir: process.cwd(), @@ -102,7 +99,7 @@ const get_defaults = (prefix = '') => ({ paths: { base: '', assets: '', - relative: undefined + relative: true }, prerender: { concurrency: 1, @@ -321,7 +318,7 @@ validate_paths( { base: '/path/to/base', assets: '', - relative: undefined + relative: true } ); @@ -333,7 +330,7 @@ validate_paths( { base: '', assets: 'https://cdn.example.com', - relative: undefined + relative: true } ); @@ -346,7 +343,7 @@ validate_paths( { base: '/path/to/base', assets: 'https://cdn.example.com', - relative: undefined + relative: true } ); diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index 2d0c928d9290..dbbb19d97cce 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -111,11 +111,6 @@ const options = object( checkOrigin: boolean(true) }), - dangerZone: object({ - // TODO 2.0: Remove this - trackServerFetches: boolean(false) - }), - embedded: boolean(false), env: object({ @@ -179,13 +174,7 @@ const options = object( return input; }), - relative: validate(undefined, (input, keypath) => { - if (typeof input !== 'boolean') { - throw new Error(`${keypath} option must be a boolean or undefined`); - } - - return input; - }) + relative: boolean(true) }), prerender: object({ diff --git a/packages/kit/src/core/postbuild/analyse.js b/packages/kit/src/core/postbuild/analyse.js index 6cfd975969c7..9dcb0c432c82 100644 --- a/packages/kit/src/core/postbuild/analyse.js +++ b/packages/kit/src/core/postbuild/analyse.js @@ -10,11 +10,10 @@ import { } from '../../utils/exports.js'; import { load_config } from '../config/index.js'; import { forked } from '../../utils/fork.js'; -import { should_polyfill } from '../../utils/platform.js'; import { installPolyfills } from '../../exports/node/polyfills.js'; -import { resolvePath } from '../../exports/index.js'; import { ENDPOINT_METHODS } from '../../constants.js'; import { filter_private_env, filter_public_env } from '../../utils/env.js'; +import { resolve_route } from '../../utils/routing.js'; export default forked(import.meta.url, analyse); @@ -36,9 +35,7 @@ async function analyse({ manifest_path, env }) { /** @type {import('types').ServerInternalModule} */ const internal = await import(pathToFileURL(`${server_root}/server/internal.js`).href); - if (should_polyfill) { - installPolyfills(); - } + installPolyfills(); // configure `import { building } from '$app/environment'` — // essential we do this before analysing the code @@ -46,8 +43,11 @@ async function analyse({ manifest_path, env }) { // set env, in case it's used in initialisation const { publicPrefix: public_prefix, privatePrefix: private_prefix } = config.env; - internal.set_private_env(filter_private_env(env, { public_prefix, private_prefix })); - internal.set_public_env(filter_public_env(env, { public_prefix, private_prefix })); + const private_env = filter_private_env(env, { public_prefix, private_prefix }); + const public_env = filter_public_env(env, { public_prefix, private_prefix }); + internal.set_private_env(private_env); + internal.set_public_env(public_env); + internal.set_safe_public_env(public_env); /** @type {import('types').ServerMetadata} */ const metadata = { @@ -55,10 +55,10 @@ async function analyse({ manifest_path, env }) { routes: new Map() }; - // analyse nodes - for (const loader of manifest._.nodes) { - const node = await loader(); + const nodes = await Promise.all(manifest._.nodes.map((loader) => loader())); + // analyse nodes + for (const node of nodes) { metadata.nodes[node.index] = { has_server_load: node.server?.load !== undefined || node.server?.trailingSlash !== undefined }; @@ -66,78 +66,35 @@ async function analyse({ manifest_path, env }) { // analyse routes for (const route of manifest._.routes) { - /** @type {Array<'GET' | 'POST'>} */ - const page_methods = []; - - /** @type {(import('types').HttpMethod | '*')[]} */ - const api_methods = []; + const page = + route.page && + analyse_page( + route.page.layouts.map((n) => (n === undefined ? n : nodes[n])), + nodes[route.page.leaf] + ); - /** @type {import('types').PrerenderOption | undefined} */ - let prerender = undefined; - /** @type {any} */ - let config = undefined; - /** @type {import('types').PrerenderEntryGenerator | undefined} */ - let entries = undefined; + const endpoint = route.endpoint && analyse_endpoint(route, await route.endpoint()); - if (route.endpoint) { - const mod = await route.endpoint(); - if (mod.prerender !== undefined) { - validate_server_exports(mod, route.id); + if (page?.prerender && endpoint?.prerender) { + throw new Error(`Cannot prerender a route with both +page and +server files (${route.id})`); + } - if (mod.prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) { + if (page?.config && endpoint?.config) { + for (const key in { ...page.config, ...endpoint.config }) { + if (JSON.stringify(page.config[key]) !== JSON.stringify(endpoint.config[key])) { throw new Error( - `Cannot prerender a +server file with POST, PATCH, PUT, or DELETE (${route.id})` + `Mismatched route config for ${route.id} — the +page and +server files must export the same config, if any` ); } - - prerender = mod.prerender; - } - - for (const method of /** @type {import('types').HttpMethod[]} */ (ENDPOINT_METHODS)) { - if (mod[method]) api_methods.push(method); } - - if (mod.fallback) { - api_methods.push('*'); - } - - config = mod.config; - entries = mod.entries; } - if (route.page) { - const nodes = await Promise.all( - [...route.page.layouts, route.page.leaf].map((n) => { - if (n !== undefined) return manifest._.nodes[n](); - }) - ); - - const layouts = nodes.slice(0, -1); - const page = nodes.at(-1); - - for (const layout of layouts) { - if (layout) { - validate_layout_server_exports(layout.server, layout.server_id); - validate_layout_exports(layout.universal, layout.universal_id); - } - } - - if (page) { - page_methods.push('GET'); - if (page.server?.actions) page_methods.push('POST'); - - validate_page_server_exports(page.server, page.server_id); - validate_page_exports(page.universal, page.universal_id); - } - - prerender = get_option(nodes, 'prerender') ?? false; - - config = get_config(nodes); - entries ??= get_option(nodes, 'entries'); - } + const page_methods = page?.methods ?? []; + const api_methods = endpoint?.methods ?? []; + const entries = page?.entries ?? endpoint?.entries; metadata.routes.set(route.id, { - config, + config: page?.config ?? endpoint?.config, methods: Array.from(new Set([...page_methods, ...api_methods])), page: { methods: page_methods @@ -145,29 +102,90 @@ async function analyse({ manifest_path, env }) { api: { methods: api_methods }, - prerender, + prerender: page?.prerender ?? endpoint?.prerender, entries: - entries && (await entries()).map((entry_object) => resolvePath(route.id, entry_object)) + entries && (await entries()).map((entry_object) => resolve_route(route.id, entry_object)) }); } return metadata; } +/** + * @param {import('types').SSRRoute} route + * @param {import('types').SSREndpoint} mod + */ +function analyse_endpoint(route, mod) { + validate_server_exports(mod, route.id); + + if (mod.prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) { + throw new Error( + `Cannot prerender a +server file with POST, PATCH, PUT, or DELETE (${route.id})` + ); + } + + /** @type {Array} */ + const methods = []; + + for (const method of /** @type {import('types').HttpMethod[]} */ (ENDPOINT_METHODS)) { + if (mod[method]) methods.push(method); + } + + if (mod.fallback) { + methods.push('*'); + } + + return { + config: mod.config, + entries: mod.entries, + methods, + prerender: mod.prerender ?? false + }; +} + +/** + * @param {Array} layouts + * @param {import('types').SSRNode} leaf + */ +function analyse_page(layouts, leaf) { + for (const layout of layouts) { + if (layout) { + validate_layout_server_exports(layout.server, layout.server_id); + validate_layout_exports(layout.universal, layout.universal_id); + } + } + + /** @type {Array<'GET' | 'POST'>} */ + const methods = ['GET']; + if (leaf.server?.actions) methods.push('POST'); + + validate_page_server_exports(leaf.server, leaf.server_id); + validate_page_exports(leaf.universal, leaf.universal_id); + + return { + config: get_config([...layouts, leaf]), + entries: leaf.universal?.entries ?? leaf.server?.entries, + methods, + prerender: get_option([...layouts, leaf], 'prerender') ?? false + }; +} + /** * Do a shallow merge (first level) of the config object * @param {Array} nodes */ function get_config(nodes) { + /** @type {any} */ let current = {}; + for (const node of nodes) { - const config = node?.universal?.config ?? node?.server?.config; - if (config) { - current = { - ...current, - ...config - }; - } + if (!node?.universal?.config && !node?.server?.config) continue; + + current = { + ...current, + ...node?.universal?.config, + ...node?.server?.config + }; } return Object.keys(current).length ? current : undefined; diff --git a/packages/kit/src/core/postbuild/fixtures/base/output.json b/packages/kit/src/core/postbuild/fixtures/base/output.json index af7a9e70a93c..203973f65687 100644 --- a/packages/kit/src/core/postbuild/fixtures/base/output.json +++ b/packages/kit/src/core/postbuild/fixtures/base/output.json @@ -2,7 +2,7 @@ "hrefs": [ "/base-path/styles.css", "/base-path/favicon.png", - "https://external.com", + "https://external.com/", "/base-path/wheee", "/base-path/wheee2", "/base-path/wheee3", diff --git a/packages/kit/src/core/postbuild/fixtures/basic-href/output.json b/packages/kit/src/core/postbuild/fixtures/basic-href/output.json index 415f7b38671f..48b9db674814 100644 --- a/packages/kit/src/core/postbuild/fixtures/basic-href/output.json +++ b/packages/kit/src/core/postbuild/fixtures/basic-href/output.json @@ -2,7 +2,7 @@ "hrefs": [ "/styles.css", "/favicon.png", - "https://external.com", + "https://external.com/", "/wheee", "/wheee2", "/wheee3", diff --git a/packages/kit/src/core/postbuild/fixtures/href-with-character-reference/output.json b/packages/kit/src/core/postbuild/fixtures/href-with-character-reference/output.json index eb649d122431..0ac291842779 100644 --- a/packages/kit/src/core/postbuild/fixtures/href-with-character-reference/output.json +++ b/packages/kit/src/core/postbuild/fixtures/href-with-character-reference/output.json @@ -3,9 +3,9 @@ "/styles.css", "/favicon.png", "/test&ersand", - "/test\"quotation", - "/test♡decimal", - "/test♥hex" + "/test%22quotation", + "/test%E2%99%A1decimal", + "/test%E2%99%A5hex" ], "ids": [] } diff --git a/packages/kit/src/core/postbuild/fixtures/ids/output.json b/packages/kit/src/core/postbuild/fixtures/ids/output.json index e749d3128d7e..750406f0dbcc 100644 --- a/packages/kit/src/core/postbuild/fixtures/ids/output.json +++ b/packages/kit/src/core/postbuild/fixtures/ids/output.json @@ -1,4 +1,4 @@ { - "hrefs": ["/#encöded"], + "hrefs": ["/#enc%C3%B6ded"], "ids": ["before", "after", "encöded"] } diff --git a/packages/kit/src/core/postbuild/fixtures/include-rel-external/output.json b/packages/kit/src/core/postbuild/fixtures/include-rel-external/output.json index 1d2f9337af06..b389f1b5a3e7 100644 --- a/packages/kit/src/core/postbuild/fixtures/include-rel-external/output.json +++ b/packages/kit/src/core/postbuild/fixtures/include-rel-external/output.json @@ -1,4 +1,4 @@ { - "hrefs": ["/styles.css", "/favicon.png", "https://external.com"], + "hrefs": ["/styles.css", "/favicon.png", "https://external.com/"], "ids": [] } diff --git a/packages/kit/src/core/postbuild/fixtures/meta/output.json b/packages/kit/src/core/postbuild/fixtures/meta/output.json index 76cfe72ada91..2e5881e7521d 100644 --- a/packages/kit/src/core/postbuild/fixtures/meta/output.json +++ b/packages/kit/src/core/postbuild/fixtures/meta/output.json @@ -1,4 +1,9 @@ { - "hrefs": ["https://external.com", "/og-image.jpg", "https://example.com/audio.mp3", "/video.mp4"], + "hrefs": [ + "https://external.com/", + "/og-image.jpg", + "https://example.com/audio.mp3", + "/video.mp4" + ], "ids": [] } diff --git a/packages/kit/src/core/postbuild/fixtures/unquoted-attributes/output.json b/packages/kit/src/core/postbuild/fixtures/unquoted-attributes/output.json index 2f95abb62dd4..d2d68c5d41e0 100644 --- a/packages/kit/src/core/postbuild/fixtures/unquoted-attributes/output.json +++ b/packages/kit/src/core/postbuild/fixtures/unquoted-attributes/output.json @@ -1,4 +1,4 @@ { - "hrefs": ["/styles.css", "/favicon.png", "https://external.com", "/wheee"], + "hrefs": ["/styles.css", "/favicon.png", "https://external.com/", "/wheee"], "ids": [] } diff --git a/packages/kit/src/core/postbuild/prerender.js b/packages/kit/src/core/postbuild/prerender.js index e64b7f852364..f6e3e2315f37 100644 --- a/packages/kit/src/core/postbuild/prerender.js +++ b/packages/kit/src/core/postbuild/prerender.js @@ -3,7 +3,6 @@ import { dirname, join } from 'node:path'; import { pathToFileURL } from 'node:url'; import { installPolyfills } from '../../exports/node/polyfills.js'; import { mkdirp, posixify, walk } from '../../utils/filesystem.js'; -import { should_polyfill } from '../../utils/platform.js'; import { decode_uri, is_root_relative, resolve } from '../../utils/url.js'; import { escape_html_attr } from '../../utils/escape.js'; import { logger } from '../utils.js'; @@ -94,9 +93,7 @@ async function prerender({ out, manifest_path, metadata, verbose, env }) { /** @type {import('types').Logger} */ const log = logger({ verbose }); - if (should_polyfill) { - installPolyfills(); - } + installPolyfills(); /** @type {Map} */ const saved = new Map(); @@ -153,6 +150,7 @@ async function prerender({ out, manifest_path, metadata, verbose, env }) { } const files = new Set(walk(`${out}/client`).map(posixify)); + files.add(`${config.appDir}/env.js`); const immutable = `${config.appDir}/immutable`; if (existsSync(`${out}/server/${immutable}`)) { @@ -429,8 +427,12 @@ async function prerender({ out, manifest_path, metadata, verbose, env }) { if (entry === '*') { for (const [id, prerender] of prerender_map) { if (prerender) { - if (id.includes('[')) continue; - const path = `/${get_route_segments(id).join('/')}`; + // remove optional parameters from the route + const segments = get_route_segments(id).filter((segment) => !segment.startsWith('[[')); + const processed_id = '/' + segments.join('/'); + + if (processed_id.includes('[')) continue; + const path = `/${get_route_segments(processed_id).join('/')}`; enqueue(null, config.paths.base + path); } } @@ -472,10 +474,10 @@ async function prerender({ out, manifest_path, metadata, verbose, env }) { } if (not_prerendered.length > 0) { + const list = not_prerendered.map((id) => ` - ${id}`).join('\n'); + throw new Error( - `The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${not_prerendered.map( - (id) => ` - ${id}` - )}\n\nSee https://kit.svelte.dev/docs/page-options#prerender-troubleshooting for info on how to solve this` + `The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${list}\n\nSee https://kit.svelte.dev/docs/page-options#prerender-troubleshooting for info on how to solve this` ); } diff --git a/packages/kit/src/core/sync/sync.js b/packages/kit/src/core/sync/sync.js index 3d1f0f9e57e9..d16466818f40 100644 --- a/packages/kit/src/core/sync/sync.js +++ b/packages/kit/src/core/sync/sync.js @@ -5,6 +5,7 @@ import { write_root } from './write_root.js'; import { write_tsconfig } from './write_tsconfig.js'; import { write_types, write_all_types } from './write_types/index.js'; import { write_ambient } from './write_ambient.js'; +import { write_non_ambient } from './write_non_ambient.js'; import { write_server } from './write_server.js'; /** @@ -15,6 +16,7 @@ import { write_server } from './write_server.js'; export function init(config, mode) { write_tsconfig(config.kit); write_ambient(config.kit, mode); + write_non_ambient(config.kit); } /** diff --git a/packages/kit/src/core/sync/write_non_ambient.js b/packages/kit/src/core/sync/write_non_ambient.js new file mode 100644 index 000000000000..a191495ac6f2 --- /dev/null +++ b/packages/kit/src/core/sync/write_non_ambient.js @@ -0,0 +1,42 @@ +import path from 'node:path'; +import { GENERATED_COMMENT } from '../../constants.js'; +import { write_if_changed } from './utils.js'; + +// `declare module "svelte/elements"` needs to happen in a non-ambient module, and dts-buddy generates one big ambient module, +// so we can't add it there - therefore generate the typings ourselves here. +// We're not using the `declare namespace svelteHTML` variant because that one doesn't augment the HTMLAttributes interface +// people could use to type their own components. +// The T generic is needed or else there's a "all declarations must have identical type parameters" error. +const template = ` +${GENERATED_COMMENT} + +declare module "svelte/elements" { + export interface HTMLAttributes { + 'data-sveltekit-keepfocus'?: true | '' | 'off' | undefined | null; + 'data-sveltekit-noscroll'?: true | '' | 'off' | undefined | null; + 'data-sveltekit-preload-code'?: + | true + | '' + | 'eager' + | 'viewport' + | 'hover' + | 'tap' + | 'off' + | undefined + | null; + 'data-sveltekit-preload-data'?: true | '' | 'hover' | 'tap' | 'off' | undefined | null; + 'data-sveltekit-reload'?: true | '' | 'off' | undefined | null; + 'data-sveltekit-replacestate'?: true | '' | 'off' | undefined | null; + } +} + +export {}; +`; + +/** + * Writes non-ambient declarations to the output directory + * @param {import('types').ValidatedKitConfig} config + */ +export function write_non_ambient(config) { + write_if_changed(path.join(config.outDir, 'non-ambient.d.ts'), template); +} diff --git a/packages/kit/src/core/sync/write_server.js b/packages/kit/src/core/sync/write_server.js index f3d29dfbb20b..8971f82aa871 100644 --- a/packages/kit/src/core/sync/write_server.js +++ b/packages/kit/src/core/sync/write_server.js @@ -28,13 +28,13 @@ const server_template = ({ import root from '../root.${isSvelte5Plus() ? 'js' : 'svelte'}'; import { set_building } from '__sveltekit/environment'; import { set_assets } from '__sveltekit/paths'; -import { set_private_env, set_public_env } from '${runtime_directory}/shared-server.js'; +import { set_private_env, set_public_env, set_safe_public_env } from '${runtime_directory}/shared-server.js'; export const options = { + app_dir: ${s(config.kit.appDir)}, app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')}, csp: ${s(config.kit.csp)}, csrf_check_origin: ${s(config.kit.csrf.checkOrigin)}, - track_server_fetches: ${s(config.kit.dangerZone.trackServerFetches)}, embedded: ${config.kit.embedded}, env_public_prefix: '${config.kit.env.publicPrefix}', env_private_prefix: '${config.kit.env.privatePrefix}', @@ -63,7 +63,7 @@ export function get_hooks() { return ${hooks ? `import(${s(hooks)})` : '{}'}; } -export { set_assets, set_building, set_private_env, set_public_env }; +export { set_assets, set_building, set_private_env, set_public_env, set_safe_public_env }; `; // TODO need to re-run this whenever src/app.html or src/error.html are diff --git a/packages/kit/src/core/sync/write_tsconfig.js b/packages/kit/src/core/sync/write_tsconfig.js index 92e7daf53cc5..8e2747436f42 100644 --- a/packages/kit/src/core/sync/write_tsconfig.js +++ b/packages/kit/src/core/sync/write_tsconfig.js @@ -3,7 +3,6 @@ import path from 'node:path'; import colors from 'kleur'; import { posixify } from '../../utils/filesystem.js'; import { write_if_changed } from './utils.js'; -import { ts } from './ts.js'; /** * @param {string} cwd @@ -42,51 +41,22 @@ export function write_tsconfig(kit, cwd = process.cwd()) { const out = path.join(kit.outDir, 'tsconfig.json'); const user_config = load_user_tsconfig(cwd); - if (user_config) validate_user_config(kit, cwd, out, user_config); - - // only specify baseUrl if a) the user doesn't specify their own baseUrl - // and b) they have non-relative paths. this causes problems with auto-imports, - // so we print a suggestion that they use relative paths instead - // TODO(v2): never include base URL, and skip the check below - let include_base_url = false; - - if (user_config && !user_config.options.compilerOptions?.baseUrl) { - const non_relative_paths = new Set(); - for (const paths of Object.values(user_config?.options.compilerOptions?.paths || {})) { - for (const path of paths) { - if (!path.startsWith('.')) non_relative_paths.add(path); - } - } - - if (non_relative_paths.size) { - include_base_url = true; - - console.log(colors.bold().yellow('Please replace non-relative compilerOptions.paths:\n')); + if (user_config) validate_user_config(cwd, out, user_config); - for (const path of non_relative_paths) { - console.log(` - "${path}" -> "./${path}"`); - } - - console.log( - '\nDoing so allows us to omit "baseUrl" — which causes problems with imports — from the generated tsconfig.json. See https://github.com/sveltejs/kit/pull/8437 for more information.' - ); - } - } - - write_if_changed(out, JSON.stringify(get_tsconfig(kit, include_base_url), null, '\t')); + write_if_changed(out, JSON.stringify(get_tsconfig(kit), null, '\t')); } /** * Generates the tsconfig that the user's tsconfig inherits from. * @param {import('types').ValidatedKitConfig} kit - * @param {boolean} include_base_url */ -export function get_tsconfig(kit, include_base_url) { +export function get_tsconfig(kit) { /** @param {string} file */ const config_relative = (file) => posixify(path.relative(kit.outDir, file)); const include = new Set([ 'ambient.d.ts', + 'non-ambient.d.ts', './types/**/$types.d.ts', config_relative('vite.config.js'), config_relative('vite.config.ts') @@ -110,7 +80,7 @@ export function get_tsconfig(kit, include_base_url) { include.add(config_relative(`${test_folder}/**/*.ts`)); include.add(config_relative(`${test_folder}/**/*.svelte`)); - const exclude = [config_relative('node_modules/**'), './[!ambient.d.ts]**']; + const exclude = [config_relative('node_modules/**')]; if (path.extname(kit.files.serviceWorker)) { exclude.push(config_relative(kit.files.serviceWorker)); } else { @@ -122,30 +92,25 @@ export function get_tsconfig(kit, include_base_url) { const config = { compilerOptions: { // generated options - baseUrl: include_base_url ? config_relative('.') : undefined, - paths: get_tsconfig_paths(kit, include_base_url), + paths: get_tsconfig_paths(kit), rootDirs: [config_relative('.'), './types'], // essential options // svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript // to enforce using \`import type\` instead of \`import\` for Types. - importsNotUsedAsValues: 'error', + // Also, TypeScript doesn't know about import usages in the template because it only sees the + // script of a Svelte file. Therefore preserve all value imports. + verbatimModuleSyntax: true, // Vite compiles modules one at a time isolatedModules: true, - // TypeScript doesn't know about import usages in the template because it only sees the - // script of a Svelte file. Therefore preserve all value imports. Requires TS 4.5 or higher. - preserveValueImports: true, // This is required for svelte-package to work as expected // Can be overwritten lib: ['esnext', 'DOM', 'DOM.Iterable'], - moduleResolution: 'node', // TODO change to "bundler" in SvelteKit v2 + moduleResolution: 'bundler', module: 'esnext', noEmit: true, // prevent tsconfig error "overwriting input files" - Vite handles the build and ignores this - target: 'esnext', - - // TODO(v2): use the new flag verbatimModuleSyntax instead (requires support by Vite/Esbuild) - ignoreDeprecations: ts && Number(ts.version.split('.')[0]) >= 5 ? '5.0' : undefined + target: 'esnext' }, include: [...include], exclude @@ -170,12 +135,11 @@ function load_user_tsconfig(cwd) { } /** - * @param {import('types').ValidatedKitConfig} kit * @param {string} cwd * @param {string} out * @param {{ kind: string, options: any }} config */ -function validate_user_config(kit, cwd, out, config) { +function validate_user_config(cwd, out, config) { // we need to check that the user's tsconfig extends the framework config const extend = config.options.extends; const extends_framework_config = @@ -188,29 +152,17 @@ function validate_user_config(kit, cwd, out, config) { const options = config.options.compilerOptions || {}; if (extends_framework_config) { - const { paths: user_paths } = options; - - if (user_paths && fs.existsSync(kit.files.lib)) { - /** @type {string[]} */ - const lib = user_paths['$lib'] || []; - /** @type {string[]} */ - const lib_ = user_paths['$lib/*'] || []; - - // TODO(v2): check needs to be adjusted when we remove the base path - const missing_lib_paths = - !lib.some((relative) => path.resolve(cwd, relative) === kit.files.lib) || - !lib_.some((relative) => path.resolve(cwd, relative) === path.join(kit.files.lib, '/*')); - - if (missing_lib_paths) { - console.warn( - colors - .bold() - .yellow(`Your compilerOptions.paths in ${config.kind} should include the following:`) - ); - let relative = posixify(path.relative('.', kit.files.lib)); - if (!relative.startsWith('.')) relative = `./${relative}`; - console.warn(`{\n "$lib":["${relative}"],\n "$lib/*":["${relative}/*"]\n}`); - } + const { paths, baseUrl } = options; + + if (baseUrl || paths) { + console.warn( + colors + .bold() + .yellow( + `You have specified a baseUrl and/or paths in your ${config.kind} which interferes with SvelteKit's auto-generated tsconfig.json. ` + + 'Remove it to avoid problems with intellisense. For path aliases, use `kit.alias` instead: https://kit.svelte.dev/docs/configuration#alias' + ) + ); } } else { let relative = posixify(path.relative('.', out)); @@ -235,9 +187,8 @@ const value_regex = /^(.*?)((\/\*)|(\.\w+))?$/; * Related to vite alias creation. * * @param {import('types').ValidatedKitConfig} config - * @param {boolean} include_base_url */ -function get_tsconfig_paths(config, include_base_url) { +function get_tsconfig_paths(config) { /** @param {string} file */ const config_relative = (file) => posixify(path.relative(config.outDir, file)); @@ -256,9 +207,7 @@ function get_tsconfig_paths(config, include_base_url) { const value_match = value_regex.exec(value); if (!value_match) throw new Error(`Invalid alias value: ${value}`); - const rel_path = (include_base_url ? project_relative : config_relative)( - remove_trailing_slashstar(value) - ); + const rel_path = config_relative(remove_trailing_slashstar(value)); const slashstar = key_match[2]; if (slashstar) { diff --git a/packages/kit/src/core/sync/write_tsconfig.spec.js b/packages/kit/src/core/sync/write_tsconfig.spec.js index 6efa9368791e..fbfa18cc97b9 100644 --- a/packages/kit/src/core/sync/write_tsconfig.spec.js +++ b/packages/kit/src/core/sync/write_tsconfig.spec.js @@ -14,7 +14,7 @@ test('Creates tsconfig path aliases from kit.alias', () => { } }); - const { compilerOptions } = get_tsconfig(kit, false); + const { compilerOptions } = get_tsconfig(kit); // $lib isn't part of the outcome because there's a "path exists" // check in the implementation @@ -27,31 +27,6 @@ test('Creates tsconfig path aliases from kit.alias', () => { }); }); -test('Creates tsconfig path aliases from kit.alias with existing baseUrl', () => { - const { kit } = validate_config({ - kit: { - alias: { - simpleKey: 'simple/value', - key: 'value', - 'key/*': 'some/other/value/*', - keyToFile: 'path/to/file.ts' - } - } - }); - - const { compilerOptions } = get_tsconfig(kit, true); - - // $lib isn't part of the outcome because there's a "path exists" - // check in the implementation - expect(compilerOptions.paths).toEqual({ - simpleKey: ['simple/value'], - 'simpleKey/*': ['simple/value/*'], - key: ['value'], - 'key/*': ['some/other/value/*'], - keyToFile: ['path/to/file.ts'] - }); -}); - test('Allows generated tsconfig to be mutated', () => { const { kit } = validate_config({ kit: { @@ -63,8 +38,9 @@ test('Allows generated tsconfig to be mutated', () => { } }); - const config = get_tsconfig(kit, false); + const config = get_tsconfig(kit); + // @ts-expect-error assert.equal(config.extends, 'some/other/tsconfig.json'); }); @@ -80,8 +56,9 @@ test('Allows generated tsconfig to be replaced', () => { } }); - const config = get_tsconfig(kit, false); + const config = get_tsconfig(kit); + // @ts-expect-error assert.equal(config.extends, 'some/other/tsconfig.json'); }); @@ -94,10 +71,11 @@ test('Creates tsconfig include from kit.files', () => { } }); - const { include } = get_tsconfig(kit, false); + const { include } = get_tsconfig(kit); expect(include).toEqual([ 'ambient.d.ts', + 'non-ambient.d.ts', './types/**/$types.d.ts', '../vite.config.js', '../vite.config.ts', diff --git a/packages/kit/src/core/sync/write_types/index.js b/packages/kit/src/core/sync/write_types/index.js index d21030e01109..2c2f0fa0b5b3 100644 --- a/packages/kit/src/core/sync/write_types/index.js +++ b/packages/kit/src/core/sync/write_types/index.js @@ -480,7 +480,7 @@ function process_node(node, outdir, is_page, proxies, all_pages_have_load = true const from = proxy.modified ? `./proxy${replace_ext_with_js(path.basename(file_path))}` : path_to_original(outdir, file_path); - const type = `Kit.AwaitedProperties>>`; + const type = `Kit.LoadProperties>>`; return expand ? `Expand>>` : type; } else { return fallback; diff --git a/packages/kit/src/core/sync/write_types/test/package.json b/packages/kit/src/core/sync/write_types/test/package.json index 47d157b4a13a..9ccb30aba068 100644 --- a/packages/kit/src/core/sync/write_types/test/package.json +++ b/packages/kit/src/core/sync/write_types/test/package.json @@ -1,5 +1,6 @@ { "private": true, + "type": "module", "scripts": { "testtypes": "tsc" } diff --git a/packages/kit/src/core/sync/write_types/test/tsconfig.json b/packages/kit/src/core/sync/write_types/test/tsconfig.json index fc3cf322453b..39ea59584873 100644 --- a/packages/kit/src/core/sync/write_types/test/tsconfig.json +++ b/packages/kit/src/core/sync/write_types/test/tsconfig.json @@ -4,9 +4,9 @@ "checkJs": true, "noEmit": true, "strict": true, - "target": "es2020", + "target": "es2022", "module": "es2022", - "moduleResolution": "node", + "moduleResolution": "bundler", "allowSyntheticDefaultImports": true, "baseUrl": ".", "paths": { diff --git a/packages/kit/src/exports/index.js b/packages/kit/src/exports/index.js index 07737d6aa6f9..283ba840c2ef 100644 --- a/packages/kit/src/exports/index.js +++ b/packages/kit/src/exports/index.js @@ -1,51 +1,106 @@ import { HttpError, Redirect, ActionFailure } from '../runtime/control.js'; import { BROWSER, DEV } from 'esm-env'; -import { get_route_segments } from '../utils/routing.js'; export { VERSION } from '../version.js'; /** + * @template {number} TNumber + * @template {any[]} [TArray=[]] + * @typedef {TNumber extends TArray['length'] ? TArray[number] : LessThan} LessThan + */ + +/** + * @template {number} TStart + * @template {number} TEnd + * @typedef {Exclude, LessThan>} NumericRange + */ + +// we have to repeat the JSDoc because the display for function overloads is broken +// see https://github.com/microsoft/TypeScript/issues/55056 + +/** + * Throws an error with a HTTP status code and an optional message. + * When called during request handling, this will cause SvelteKit to + * return an error response without invoking `handleError`. + * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it. + * @param {NumericRange<400, 599>} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. + * @param {App.Error} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property. * @overload - * @param {number} status + * @param {NumericRange<400, 599>} status * @param {App.Error} body - * @return {HttpError} + * @return {never} + * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. + * @throws {Error} If the provided status is invalid (not between 400 and 599). */ - /** + * Throws an error with a HTTP status code and an optional message. + * When called during request handling, this will cause SvelteKit to + * return an error response without invoking `handleError`. + * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it. + * @param {NumericRange<400, 599>} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. + * @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} [body] An object that conforms to the App.Error type. If a string is passed, it will be used as the message property. * @overload - * @param {number} status + * @param {NumericRange<400, 599>} status * @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} [body] - * @return {HttpError} + * @return {never} + * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. + * @throws {Error} If the provided status is invalid (not between 400 and 599). */ - /** - * Creates an `HttpError` object with an HTTP status code and an optional message. - * This object, if thrown during request handling, will cause SvelteKit to + * Throws an error with a HTTP status code and an optional message. + * When called during request handling, this will cause SvelteKit to * return an error response without invoking `handleError`. * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it. - * @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. + * @param {NumericRange<400, 599>} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. * @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property. + * @return {never} + * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. + * @throws {Error} If the provided status is invalid (not between 400 and 599). */ export function error(status, body) { if ((!BROWSER || DEV) && (isNaN(status) || status < 400 || status > 599)) { throw new Error(`HTTP error status codes must be between 400 and 599 — ${status} is invalid`); } - return new HttpError(status, body); + throw new HttpError(status, body); } /** - * Create a `Redirect` object. If thrown during request handling, SvelteKit will return a redirect response. + * Checks whether this is an error thrown by {@link error}. + * @template {number} T + * @param {unknown} e + * @param {T} [status] The status to filter for. + * @return {e is (HttpError & { status: T extends undefined ? never : T })} + */ +export function isHttpError(e, status) { + if (!(e instanceof HttpError)) return false; + return !status || e.status === status; +} + +/** + * Redirect a request. When called during request handling, SvelteKit will return a redirect response. * Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it. - * @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308. + * @param {NumericRange<300, 308>} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308. * @param {string | URL} location The location to redirect to. + * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location. + * @throws {Error} If the provided status is invalid. + * @return {never} */ export function redirect(status, location) { if ((!BROWSER || DEV) && (isNaN(status) || status < 300 || status > 308)) { throw new Error('Invalid status code'); } - return new Redirect(status, location.toString()); + throw new Redirect(status, location.toString()); +} + +/** + * Checks whether this is a redirect thrown by {@link redirect}. + * @param {unknown} e The object to check. + * @return {e is Redirect} + */ +export function isRedirect(e) { + return e instanceof Redirect; } /** @@ -100,68 +155,30 @@ export function text(body, init) { }); } +/** + * Create an `ActionFailure` object. + * @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. + * @overload + * @param {number} status + * @returns {import('./public.js').ActionFailure} + */ /** * Create an `ActionFailure` object. * @template {Record | undefined} [T=undefined] * @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. - * @param {T} [data] Data associated with the failure (e.g. validation errors) - * @returns {ActionFailure} + * @param {T} data Data associated with the failure (e.g. validation errors) + * @overload + * @param {number} status + * @param {T} data + * @returns {import('./public.js').ActionFailure} */ -export function fail(status, data) { - return new ActionFailure(status, data); -} - -const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g; - -let warned = false; - /** - * @deprecated Use `resolveRoute` from `$app/paths` instead. - * - * Populate a route ID with params to resolve a pathname. - * @example - * ```js - * resolvePath( - * `/blog/[slug]/[...somethingElse]`, - * { - * slug: 'hello-world', - * somethingElse: 'something/else' - * } - * ); // `/blog/hello-world/something/else` - * ``` - * @param {string} id - * @param {Record} params - * @returns {string} + * Create an `ActionFailure` object. + * @param {number} status + * @param {any} [data] + * @returns {import('./public.js').ActionFailure} */ -export function resolvePath(id, params) { - if (!warned) { - console.warn('`resolvePath` is deprecated. Use `resolveRoute` from `$app/paths` instead.'); - warned = true; - } - - const segments = get_route_segments(id); - return ( - '/' + - segments - .map((segment) => - segment.replace(basic_param_pattern, (_, optional, rest, name) => { - const param_value = params[name]; - - // This is nested so TS correctly narrows the type - if (!param_value) { - if (optional) return ''; - if (rest && param_value !== undefined) return ''; - throw new Error(`Missing parameter '${name}' in route ${id}`); - } - - if (param_value.startsWith('/') || param_value.endsWith('/')) - throw new Error( - `Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar` - ); - return param_value; - }) - ) - .filter(Boolean) - .join('/') - ); +export function fail(status, data) { + // @ts-expect-error unique symbol missing + return new ActionFailure(status, data); } diff --git a/packages/kit/src/exports/index.spec.js b/packages/kit/src/exports/index.spec.js deleted file mode 100644 index 22fbf9784cef..000000000000 --- a/packages/kit/src/exports/index.spec.js +++ /dev/null @@ -1,59 +0,0 @@ -import { assert, expect, test } from 'vitest'; -import { resolvePath } from './index.js'; - -const from_params_tests = [ - { - route: '/blog/[one]/[two]', - params: { one: 'one', two: 'two' }, - expected: '/blog/one/two' - }, - { - route: '/blog/[one=matcher]/[...two]', - params: { one: 'one', two: 'two/three' }, - expected: '/blog/one/two/three' - }, - { - route: '/blog/[one=matcher]/[[two]]', - params: { one: 'one' }, - expected: '/blog/one' - }, - { - route: '/blog/[one]/[two]-and-[three]', - params: { one: 'one', two: '2', three: '3' }, - expected: '/blog/one/2-and-3' - }, - { - route: '/blog/[...one]', - params: { one: '' }, - expected: '/blog' - }, - { - route: '/blog/[one]/[...two]-not-three', - params: { one: 'one', two: 'two/2' }, - expected: '/blog/one/two/2-not-three' - } -]; - -for (const { route, params, expected } of from_params_tests) { - test(`resolvePath generates correct path for ${route}`, () => { - const result = resolvePath(route, params); - assert.equal(result, expected); - }); -} - -test('resolvePath errors on missing params for required param', () => { - expect(() => resolvePath('/blog/[one]/[two]', { one: 'one' })).toThrow( - "Missing parameter 'two' in route /blog/[one]/[two]" - ); -}); - -test('resolvePath errors on params values starting or ending with slashes', () => { - assert.throws( - () => resolvePath('/blog/[one]/[two]', { one: 'one', two: '/two' }), - "Parameter 'two' in route /blog/[one]/[two] cannot start or end with a slash -- this would cause an invalid route like foo//bar" - ); - assert.throws( - () => resolvePath('/blog/[one]/[two]', { one: 'one', two: 'two/' }), - "Parameter 'two' in route /blog/[one]/[two] cannot start or end with a slash -- this would cause an invalid route like foo//bar" - ); -}); diff --git a/packages/kit/src/exports/node/index.js b/packages/kit/src/exports/node/index.js index ced8310907ce..ae3d57afc9cc 100644 --- a/packages/kit/src/exports/node/index.js +++ b/packages/kit/src/exports/node/index.js @@ -1,5 +1,5 @@ import * as set_cookie_parser from 'set-cookie-parser'; -import { error } from '../index.js'; +import { SvelteKitError } from '../../runtime/control.js'; /** * @param {import('http').IncomingMessage} req @@ -22,19 +22,6 @@ function get_raw_body(req, body_size_limit) { return null; } - let length = content_length; - - if (body_size_limit) { - if (!length) { - length = body_size_limit; - } else if (length > body_size_limit) { - throw error( - 413, - `Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.` - ); - } - } - if (req.destroyed) { const readable = new ReadableStream(); readable.cancel(); @@ -46,6 +33,17 @@ function get_raw_body(req, body_size_limit) { return new ReadableStream({ start(controller) { + if (body_size_limit !== undefined && content_length > body_size_limit) { + const error = new SvelteKitError( + 413, + 'Payload Too Large', + `Content-length of ${content_length} exceeds limit of ${body_size_limit} bytes.` + ); + + controller.error(error); + return; + } + req.on('error', (error) => { cancelled = true; controller.error(error); @@ -60,16 +58,15 @@ function get_raw_body(req, body_size_limit) { if (cancelled) return; size += chunk.length; - if (size > length) { + if (size > content_length) { cancelled = true; - controller.error( - error( - 413, - `request body size exceeded ${ - content_length ? "'content-length'" : 'BODY_SIZE_LIMIT' - } of ${length}` - ) - ); + + const constraint = content_length ? 'content-length' : 'BODY_SIZE_LIMIT'; + const message = `request body size exceeded ${constraint} of ${content_length}`; + + const error = new SvelteKitError(413, 'Payload Too Large', message); + controller.error(error); + return; } diff --git a/packages/kit/src/exports/node/polyfills.js b/packages/kit/src/exports/node/polyfills.js index 46d5e71bce02..347c68cea2e9 100644 --- a/packages/kit/src/exports/node/polyfills.js +++ b/packages/kit/src/exports/node/polyfills.js @@ -1,54 +1,25 @@ -import { ReadableStream, TransformStream, WritableStream } from 'node:stream/web'; import buffer from 'node:buffer'; import { webcrypto as crypto } from 'node:crypto'; -import { fetch, Response, Request, Headers, FormData, File as UndiciFile } from 'undici'; // `buffer.File` was added in Node 18.13.0 while the `File` global was added in Node 20.0.0 -const File = /** @type {import('node:buffer') & { File?: File}} */ (buffer).File ?? UndiciFile; +const File = /** @type {import('node:buffer') & { File?: File}} */ (buffer).File; /** @type {Record} */ -const globals_post_node_18_11 = { +const globals = { crypto, File }; -/** @type {Record} */ -// TODO: remove this once we only support Node 18.11+ (the version multipart/form-data was added) -const globals_pre_node_18_11 = { - crypto, - fetch, - Response, - Request, - Headers, - ReadableStream, - TransformStream, - WritableStream, - FormData, - File -}; - // exported for dev/preview and node environments /** * Make various web APIs available as globals: * - `crypto` - * - `fetch` (only in node < 18.11) - * - `Headers` (only in node < 18.11) - * - `Request` (only in node < 18.11) - * - `Response` (only in node < 18.11) + * - `File` */ export function installPolyfills() { - // Be defensive (we don't know in which environments this is called) and always apply if something goes wrong - let globals = globals_pre_node_18_11; - try { - const version = process.versions.node.split('.').map((n) => parseInt(n, 10)); - if ((version[0] === 18 && version[1] >= 11) || version[0] > 18) { - globals = globals_post_node_18_11; - } - } catch (e) { - // ignore - } - for (const name in globals) { + if (name in globalThis) continue; + Object.defineProperty(globalThis, name, { enumerable: true, configurable: true, diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 088605713797..7caa0c4bf038 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -2,7 +2,7 @@ import 'svelte'; // pick up `declare module "*.svelte"` import 'vite/client'; // pick up `declare module "*.jpg"`, etc. import '../types/ambient.js'; -import { CompileOptions } from 'svelte/types/compiler/interfaces'; +import { CompileOptions } from 'svelte/compiler'; import { AdapterEntry, CspDirectives, @@ -17,12 +17,10 @@ import { RequestOptions, RouteSegment } from '../types/private.js'; -import { ActionFailure } from '../runtime/control.js'; import { BuildData, SSRNodeLoader, SSRRoute, ValidatedConfig } from 'types'; import type { PluginOptions } from '@sveltejs/vite-plugin-svelte'; export { PrerenderOption } from '../types/private.js'; -export { ActionFailure }; /** * [Adapters](https://kit.svelte.dev/docs/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -39,20 +37,11 @@ export interface Adapter { adapt(builder: Builder): MaybePromise; } -type AwaitedPropertiesUnion | void> = input extends void +export type LoadProperties | void> = input extends void ? undefined // needs to be undefined, because void will break intellisense : input extends Record - ? { - [key in keyof input]: Awaited; - } - : {} extends input // handles the any case - ? input - : unknown; - -export type AwaitedProperties | void> = - AwaitedPropertiesUnion extends Record - ? OptionalUnion> - : AwaitedPropertiesUnion; + ? input + : unknown; export type AwaitedActions any>> = OptionalUnion< { @@ -67,6 +56,14 @@ type OptionalUnion< A extends keyof U = U extends U ? keyof U : never > = U extends unknown ? { [P in Exclude]?: never } & U : never; +declare const uniqueSymbol: unique symbol; + +export interface ActionFailure | undefined = undefined> { + status: number; + data: T; + [uniqueSymbol]: true; // necessary or else UnpackValidationError could wrongly unpack objects with the same shape as ActionFailure +} + type UnpackValidationError = T extends ActionFailure ? X : T extends void @@ -104,6 +101,11 @@ export interface Builder { */ generateFallback(dest: string): Promise; + /** + * Generate a module exposing build-time environment variables as `$env/dynamic/public`. + */ + generateEnvModule(): void; + /** * Generate a server-side manifest to initialise the SvelteKit [server](https://kit.svelte.dev/docs/types#public-types-server) with. * @param opts a relative path to the base directory of the app and optionally in which format (esm or cjs) the manifest should be generated @@ -212,34 +214,42 @@ export interface Cookies { * * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. * - * By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. + * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children * @param name the name of the cookie * @param value the cookie value * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - set(name: string, value: string, opts?: import('cookie').CookieSerializeOptions): void; + set( + name: string, + value: string, + opts: import('cookie').CookieSerializeOptions & { path: string } + ): void; /** * Deletes a cookie by setting its value to an empty string and setting the expiry date in the past. * - * By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. + * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children * @param name the name of the cookie * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - delete(name: string, opts?: import('cookie').CookieSerializeOptions): void; + delete(name: string, opts: import('cookie').CookieSerializeOptions & { path: string }): void; /** * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. * * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. * - * By default, the `path` of a cookie is the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. + * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children * * @param name the name of the cookie * @param value the cookie value * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - serialize(name: string, value: string, opts?: import('cookie').CookieSerializeOptions): string; + serialize( + name: string, + value: string, + opts: import('cookie').CookieSerializeOptions & { path: string } + ): string; } export interface KitConfig { @@ -279,7 +289,9 @@ export interface KitConfig { */ alias?: Record; /** - * The directory relative to `paths.assets` where the built JS and CSS (and imported assets) are served from. (The filenames therein contain content-based hashes, meaning they can be cached indefinitely). Must not start or end with `/`. + * The directory where SvelteKit keeps its stuff, including static assets (such as JS and CSS) and internally-used routes. + * + * If `paths.assets` is specified, there will be two app directories — `${paths.assets}/${appDir}` and `${paths.base}/${appDir}`. * @default "_app" */ appDir?: string; @@ -343,16 +355,6 @@ export interface KitConfig { */ checkOrigin?: boolean; }; - /** - * Here be dragons. Enable at your peril. - */ - dangerZone?: { - /** - * Automatically add server-side `fetch`ed URLs to the `dependencies` map of `load` functions. This will expose secrets - * to the client if your URL contains them. - */ - trackServerFetches?: boolean; - }; /** * Whether or not the app is embedded inside a larger app. If `true`, SvelteKit will add its event listeners related to navigation etc on the parent of `%sveltekit.body%` instead of `window`, and will pass `params` from the server rather than inferring them from `location.pathname`. * @default false @@ -473,17 +475,20 @@ export interface KitConfig { */ base?: '' | `/${string}`; /** - * Whether to use relative asset paths. By default, if `paths.assets` is not external, SvelteKit will replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` will be as specified in your config. + * Whether to use relative asset paths. * - * If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in portable HTML. + * If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in more portable HTML. * If `false`, `%sveltekit.assets%` and references to build artifacts will always be root-relative paths, unless `paths.assets` is an external URL * * [Single-page app](https://kit.svelte.dev/docs/single-page-apps) fallback pages will always use absolute paths, regardless of this setting. * * If your app uses a `` element, you should set this to `false`, otherwise asset URLs will incorrectly be resolved against the `` URL rather than the current page. - * @default undefined + * + * In 1.0, `undefined` was a valid value, which was set by default. In that case, if `paths.assets` was not external, SvelteKit would replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` would be as specified in your config. + * + * @default true */ - relative?: boolean | undefined; + relative?: boolean; }; /** * See [Prerendering](https://kit.svelte.dev/docs/page-options#prerender). @@ -500,7 +505,7 @@ export interface KitConfig { */ crawl?: boolean; /** - * An array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all non-dynamic routes (i.e. pages with no `[parameters]`, because SvelteKit doesn't know what value the parameters should have). + * An array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all routes containing no required `[parameters]` with optional parameters included as being empty (since SvelteKit doesn't know what value any parameters should have). * @default ["*"] */ entries?: Array<'*' | `/${string}`>; @@ -652,6 +657,8 @@ export type Handle = (input: { export type HandleServerError = (input: { error: unknown; event: RequestEvent; + status: number; + message: string; }) => MaybePromise; /** @@ -663,6 +670,8 @@ export type HandleServerError = (input: { export type HandleClientError = (input: { error: unknown; event: NavigationEvent; + status: number; + message: string; }) => MaybePromise; /** @@ -781,7 +790,21 @@ export interface LoadEvent< * * ``` */ - depends(...deps: string[]): void; + depends(...deps: Array<`${string}:${string}`>): void; + /** + * Use this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example: + * + * ```js + * /// file: src/routes/+page.server.js + * export async function load({ untrack, url }) { + * // Untrack url.pathname so that path changes don't trigger a rerun + * if (untrack(() => url.pathname === '/')) { + * return { message: 'Welcome!' }; + * } + * } + * ``` + */ + untrack(fn: () => T): T; } export interface NavigationEvent< @@ -848,7 +871,7 @@ export interface Navigation { /** * The type of navigation: * - `form`: The user submitted a `
` - * - `leave`: The user is leaving the app by closing the tab or using the back/forward buttons to go to a different document + * - `leave`: The app is being left either because the tab is being closed or a navigation to a different document is occurring * - `link`: Navigation was triggered by a link click * - `goto`: Navigation was triggered by a `goto(...)` call or a redirect * - `popstate`: Navigation was triggered by back/forward navigation @@ -952,6 +975,10 @@ export interface Page< * The merged result of all data from all `load` functions on the current page. You can type a common denominator through `App.PageData`. */ data: App.PageData & Record; + /** + * The page state, which can be manipulated using the [`pushState`](https://kit.svelte.dev/docs/modules#$app-navigation-pushstate) and [`replaceState`](https://kit.svelte.dev/docs/modules#$app-navigation-replacestate) functions from `$app/navigation`. + */ + state: App.PageState; /** * Filled only after a form submission. See [form actions](https://kit.svelte.dev/docs/form-actions) for more info. */ @@ -1183,6 +1210,20 @@ export interface ServerLoadEvent< * ``` */ depends(...deps: string[]): void; + /** + * Use this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example: + * + * ```js + * /// file: src/routes/+page.js + * export async function load({ untrack, url }) { + * // Untrack url.pathname so that path changes don't trigger a rerun + * if (untrack(() => url.pathname === '/')) { + * return { message: 'Welcome!' }; + * } + * } + * ``` + */ + untrack(fn: () => T): T; } /** @@ -1249,17 +1290,7 @@ export type SubmitFunction< Failure extends Record | undefined = Record > = (input: { action: URL; - /** - * use `formData` instead of `data` - * @deprecated - */ - data: FormData; formData: FormData; - /** - * use `formElement` instead of `form` - * @deprecated - */ - form: HTMLFormElement; formElement: HTMLFormElement; controller: AbortController; submitter: HTMLElement | null; @@ -1267,17 +1298,7 @@ export type SubmitFunction< }) => MaybePromise< | void | ((opts: { - /** - * use `formData` instead of `data` - * @deprecated - */ - data: FormData; formData: FormData; - /** - * use `formElement` instead of `form` - * @deprecated - */ - form: HTMLFormElement; formElement: HTMLFormElement; action: URL; result: ActionResult; diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 517f63dbbd28..a80b34447213 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -8,7 +8,6 @@ import { getRequest, setResponse } from '../../../exports/node/index.js'; import { installPolyfills } from '../../../exports/node/polyfills.js'; import { coalesce_to_error } from '../../../utils/error.js'; import { posixify, resolve_entry, to_fs } from '../../../utils/filesystem.js'; -import { should_polyfill } from '../../../utils/platform.js'; import { load_error_page } from '../../../core/config/index.js'; import { SVELTE_KIT_ASSETS } from '../../../constants.js'; import * as sync from '../../../core/sync/sync.js'; @@ -26,9 +25,7 @@ const cwd = process.cwd(); * @return {Promise void>>} */ export async function dev(vite, vite_config, svelte_config) { - if (should_polyfill) { - installPolyfills(); - } + installPolyfills(); const fetch = globalThis.fetch; globalThis.fetch = (info, init) => { @@ -123,7 +120,8 @@ export async function dev(vite, vite_config, svelte_config) { app: `${to_fs(svelte_config.kit.outDir)}/generated/client/app.js`, imports: [], stylesheets: [], - fonts: [] + fonts: [], + uses_env_dynamic_public: true }, nodes: manifest_data.nodes.map((node, index) => { return async () => { @@ -357,7 +355,8 @@ export async function dev(vite, vite_config, svelte_config) { control_module_node.replace_implementations({ ActionFailure: control_module_vite.ActionFailure, HttpError: control_module_vite.HttpError, - Redirect: control_module_vite.Redirect + Redirect: control_module_vite.Redirect, + SvelteKitError: control_module_vite.SvelteKitError }); } align_exports(); @@ -473,17 +472,10 @@ export async function dev(vite, vite_config, svelte_config) { await server.init({ env }); - let request; - - try { - request = await getRequest({ - base, - request: req - }); - } catch (/** @type {any} */ err) { - res.statusCode = err.status || 400; - return res.end('Invalid request body'); - } + const request = await getRequest({ + base, + request: req + }); if (manifest_error) { console.error(colors.bold().red(manifest_error.message)); @@ -537,7 +529,7 @@ export async function dev(vite, vite_config, svelte_config) { * @param {import('connect').Server} server */ function remove_static_middlewares(server) { - const static_middlewares = ['viteServeStaticMiddleware']; + const static_middlewares = ['viteServeStaticMiddleware', 'viteServePublicMiddleware']; for (let i = server.stack.length - 1; i > 0; i--) { // @ts-expect-error using internals if (static_middlewares.includes(server.stack[i].handle.name)) { diff --git a/packages/kit/src/exports/vite/graph_analysis/index.js b/packages/kit/src/exports/vite/graph_analysis/index.js index 6dc6860a0a3c..7ab7cd3cdfa2 100644 --- a/packages/kit/src/exports/vite/graph_analysis/index.js +++ b/packages/kit/src/exports/vite/graph_analysis/index.js @@ -1,11 +1,9 @@ import path from 'node:path'; import { posixify } from '../../../utils/filesystem.js'; import { strip_virtual_prefix } from '../utils.js'; +import { env_dynamic_private, env_static_private } from '../module_ids.js'; -const ILLEGAL_IMPORTS = new Set([ - '\0virtual:$env/dynamic/private', - '\0virtual:$env/static/private' -]); +const ILLEGAL_IMPORTS = new Set([env_dynamic_private, env_static_private]); const ILLEGAL_MODULE_NAME_PATTERN = /.*\.server\..+/; /** diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index a7a886d6d745..dbd9c6c1c17a 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -1,5 +1,5 @@ import fs from 'node:fs'; -import path from 'node:path'; +import path, { join } from 'node:path'; import { svelte } from '@sveltejs/vite-plugin-svelte'; import colors from 'kleur'; @@ -19,14 +19,23 @@ import { dev } from './dev/index.js'; import { is_illegal, module_guard, normalize_id } from './graph_analysis/index.js'; import { preview } from './preview/index.js'; import { get_config_aliases, get_env, strip_virtual_prefix } from './utils.js'; +import { SVELTE_KIT_ASSETS } from '../../constants.js'; import { write_client_manifest } from '../../core/sync/write_client_manifest.js'; import prerender from '../../core/postbuild/prerender.js'; import analyse from '../../core/postbuild/analyse.js'; import { s } from '../../utils/misc.js'; import { hash } from '../../runtime/hash.js'; import { dedent, isSvelte5Plus } from '../../core/sync/utils.js'; - -export { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +import sirv from 'sirv'; +import { + env_dynamic_private, + env_dynamic_public, + env_static_private, + env_static_public, + service_worker, + sveltekit_environment, + sveltekit_paths +} from './module_ids.js'; const cwd = process.cwd(); @@ -72,7 +81,7 @@ const options_regex = /(export\s+const\s+(prerender|csr|ssr|trailingSlash))\s*=/ /** @type {Set} */ const warned = new Set(); -/** @type {import('@sveltejs/vite-plugin-svelte').PreprocessorGroup} */ +/** @type {import('svelte/compiler').PreprocessorGroup} */ const warning_preprocessor = { script: ({ content, filename }) => { if (!filename) return; @@ -363,22 +372,22 @@ function kit({ svelte_config }) { } switch (id) { - case '\0virtual:$env/static/private': + case env_static_private: return create_static_module('$env/static/private', env.private); - case '\0virtual:$env/static/public': + case env_static_public: return create_static_module('$env/static/public', env.public); - case '\0virtual:$env/dynamic/private': + case env_dynamic_private: return create_dynamic_module( 'private', vite_config_env.command === 'serve' ? env.private : undefined ); - case '\0virtual:$env/dynamic/public': + case env_dynamic_public: // populate `$env/dynamic/public` from `window` if (browser) { - return `export const env = ${global}.env;`; + return `export const env = ${global}.env ?? (await import(/* @vite-ignore */ ${global}.base + '/' + '${kit.appDir}/env.js')).env;`; } return create_dynamic_module( @@ -386,12 +395,12 @@ function kit({ svelte_config }) { vite_config_env.command === 'serve' ? env.public : undefined ); - case '\0virtual:$service-worker': + case service_worker: return create_service_worker_module(svelte_config); // for internal use only. it's published as $app/paths externally // we use this alias so that we won't collide with user aliases - case '\0virtual:__sveltekit/paths': { + case sveltekit_paths: { const { assets, base } = svelte_config.kit.paths; // use the values defined in `global`, but fall back to hard-coded values @@ -429,7 +438,7 @@ function kit({ svelte_config }) { `; } - case '\0virtual:__sveltekit/environment': { + case sveltekit_environment: { const { version } = svelte_config.kit; return dedent` @@ -570,7 +579,7 @@ function kit({ svelte_config }) { preserveEntrySignatures: 'strict' }, ssrEmitAssets: true, - target: ssr ? 'node16.14' : undefined + target: ssr ? 'node18.13' : 'es2022' }, publicDir: kit.files.assets, worker: { @@ -617,6 +626,31 @@ function kit({ svelte_config }) { * @see https://vitejs.dev/guide/api-plugin.html#configurepreviewserver */ configurePreviewServer(vite) { + // generated client assets and the contents of `static` + // should we use Vite's built-in asset server for this? + // we would need to set the outDir to do so + const { paths } = svelte_config.kit; + const assets = paths.assets ? SVELTE_KIT_ASSETS : paths.base; + vite.middlewares.use( + scoped( + assets, + sirv(join(svelte_config.kit.outDir, 'output/client'), { + setHeaders: (res, pathname) => { + if (pathname.startsWith(`/${svelte_config.kit.appDir}/immutable`)) { + res.setHeader('cache-control', 'public,max-age=31536000,immutable'); + } + if (vite_config.preview.cors) { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader( + 'Access-Control-Allow-Headers', + 'Origin, Content-Type, Accept, Range' + ); + } + } + }) + ) + ); + return preview(vite, vite_config, svelte_config); }, @@ -738,7 +772,10 @@ function kit({ svelte_config }) { app: app.file, imports: [...start.imports, ...app.imports], stylesheets: [...start.stylesheets, ...app.stylesheets], - fonts: [...start.fonts, ...app.fonts] + fonts: [...start.fonts, ...app.fonts], + uses_env_dynamic_public: output.some( + (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public] + ) }; const css = output.filter( @@ -906,3 +943,25 @@ const create_service_worker_module = (config) => dedent` export const prerendered = []; export const version = ${s(config.kit.version.name)}; `; + +/** + * @param {string} scope + * @param {(req: import('http').IncomingMessage, res: import('http').ServerResponse, next: () => void) => void} handler + * @returns {(req: import('http').IncomingMessage, res: import('http').ServerResponse, next: () => void) => void} + */ +function scoped(scope, handler) { + if (scope === '') return handler; + + return (req, res, next) => { + if (req.url?.startsWith(scope)) { + const original_url = req.url; + req.url = req.url.slice(scope.length); + handler(req, res, () => { + req.url = original_url; + next(); + }); + } else { + next(); + } + }; +} diff --git a/packages/kit/src/exports/vite/module_ids.js b/packages/kit/src/exports/vite/module_ids.js new file mode 100644 index 000000000000..a6097f5b6f44 --- /dev/null +++ b/packages/kit/src/exports/vite/module_ids.js @@ -0,0 +1,7 @@ +export const env_static_private = '\0virtual:$env/static/private'; +export const env_static_public = '\0virtual:$env/static/public'; +export const env_dynamic_private = '\0virtual:$env/dynamic/private'; +export const env_dynamic_public = '\0virtual:$env/dynamic/public'; +export const service_worker = '\0virtual:$service-worker'; +export const sveltekit_paths = '\0virtual:__sveltekit/paths'; +export const sveltekit_environment = '\0virtual:__sveltekit/environment'; diff --git a/packages/kit/src/exports/vite/preview/index.js b/packages/kit/src/exports/vite/preview/index.js index 5bb2d9a972b8..fe44e4524deb 100644 --- a/packages/kit/src/exports/vite/preview/index.js +++ b/packages/kit/src/exports/vite/preview/index.js @@ -7,8 +7,6 @@ import { loadEnv, normalizePath } from 'vite'; import { getRequest, setResponse } from '../../../exports/node/index.js'; import { installPolyfills } from '../../../exports/node/polyfills.js'; import { SVELTE_KIT_ASSETS } from '../../../constants.js'; -import { should_polyfill } from '../../../utils/platform.js'; -import { not_found } from '../utils.js'; /** @typedef {import('http').IncomingMessage} Req */ /** @typedef {import('http').ServerResponse} Res */ @@ -20,12 +18,9 @@ import { not_found } from '../utils.js'; * @param {import('types').ValidatedConfig} svelte_config */ export async function preview(vite, vite_config, svelte_config) { - if (should_polyfill) { - installPolyfills(); - } + installPolyfills(); const { paths } = svelte_config.kit; - const base = paths.base; const assets = paths.assets ? SVELTE_KIT_ASSETS : paths.base; const protocol = vite_config.preview.https ? 'https' : 'http'; @@ -54,131 +49,84 @@ export async function preview(vite, vite_config, svelte_config) { }); return () => { - // generated client assets and the contents of `static` + // prerendered dependencies vite.middlewares.use( - scoped( - assets, - sirv(join(svelte_config.kit.outDir, 'output/client'), { - setHeaders: (res, pathname) => { - // only apply to immutable directory, not e.g. version.json - if (pathname.startsWith(`/${svelte_config.kit.appDir}/immutable`)) { - res.setHeader('cache-control', 'public,max-age=31536000,immutable'); - } - } - }) - ) + mutable(join(svelte_config.kit.outDir, 'output/prerendered/dependencies')) ); + // prerendered pages (we can't just use sirv because we need to + // preserve the correct trailingSlash behaviour) vite.middlewares.use((req, res, next) => { - const original_url = /** @type {string} */ (req.url); - const { pathname, search } = new URL(original_url, 'http://dummy'); - - // if `paths.base === '/a/b/c`, then the root route is `/a/b/c/`, - // regardless of the `trailingSlash` route option - if (base.length > 1 && pathname === base) { - let location = base + '/'; - if (search) location += search; - res.writeHead(307, { - location - }); + let if_none_match_value = req.headers['if-none-match']; + + if (if_none_match_value?.startsWith('W/"')) { + if_none_match_value = if_none_match_value.substring(2); + } + + if (if_none_match_value === etag) { + res.statusCode = 304; res.end(); return; } - if (pathname.startsWith(base)) { - next(); - } else { - res.statusCode = 404; - not_found(req, res, base); - } - }); + const { pathname, search } = new URL(/** @type {string} */ (req.url), 'http://dummy'); - // prerendered dependencies - vite.middlewares.use( - scoped(base, mutable(join(svelte_config.kit.outDir, 'output/prerendered/dependencies'))) - ); - - // prerendered pages (we can't just use sirv because we need to - // preserve the correct trailingSlash behaviour) - vite.middlewares.use( - scoped(base, (req, res, next) => { - let if_none_match_value = req.headers['if-none-match']; + let filename = normalizePath( + join(svelte_config.kit.outDir, 'output/prerendered/pages' + pathname) + ); + let prerendered = is_file(filename); - if (if_none_match_value?.startsWith('W/"')) { - if_none_match_value = if_none_match_value.substring(2); - } + if (!prerendered) { + const has_trailing_slash = pathname.endsWith('/'); + const html_filename = `${filename}${has_trailing_slash ? 'index.html' : '.html'}`; - if (if_none_match_value === etag) { - res.statusCode = 304; - res.end(); - return; - } + /** @type {string | undefined} */ + let redirect; - const { pathname, search } = new URL(/** @type {string} */ (req.url), 'http://dummy'); - - let filename = normalizePath( - join(svelte_config.kit.outDir, 'output/prerendered/pages' + pathname) - ); - let prerendered = is_file(filename); - - if (!prerendered) { - const has_trailing_slash = pathname.endsWith('/'); - const html_filename = `${filename}${has_trailing_slash ? 'index.html' : '.html'}`; - - /** @type {string | undefined} */ - let redirect; - - if (is_file(html_filename)) { - filename = html_filename; - prerendered = true; - } else if (has_trailing_slash) { - if (is_file(filename.slice(0, -1) + '.html')) { - redirect = pathname.slice(0, -1); - } - } else if (is_file(filename + '/index.html')) { - redirect = pathname + '/'; + if (is_file(html_filename)) { + filename = html_filename; + prerendered = true; + } else if (has_trailing_slash) { + if (is_file(filename.slice(0, -1) + '.html')) { + redirect = pathname.slice(0, -1); } + } else if (is_file(filename + '/index.html')) { + redirect = pathname + '/'; + } - if (redirect) { - if (search) redirect += search; - res.writeHead(307, { - location: redirect - }); + if (redirect) { + if (search) redirect += search; + res.writeHead(307, { + location: redirect + }); - res.end(); + res.end(); - return; - } + return; } + } - if (prerendered) { - res.writeHead(200, { - 'content-type': lookup(pathname) || 'text/html', - etag - }); + if (prerendered) { + res.writeHead(200, { + 'content-type': lookup(pathname) || 'text/html', + etag + }); - fs.createReadStream(filename).pipe(res); - } else { - next(); - } - }) - ); + fs.createReadStream(filename).pipe(res); + } else { + next(); + } + }); // SSR vite.middlewares.use(async (req, res) => { const host = req.headers['host']; + req.url = req.originalUrl; - let request; - - try { - request = await getRequest({ - base: `${protocol}://${host}`, - request: req - }); - } catch (/** @type {any} */ err) { - res.statusCode = err.status || 400; - return res.end('Invalid request body'); - } + const request = await getRequest({ + base: `${protocol}://${host}`, + request: req + }); setResponse( res, @@ -207,28 +155,6 @@ const mutable = (dir) => }) : (_req, _res, next) => next(); -/** - * @param {string} scope - * @param {Handler} handler - * @returns {Handler} - */ -function scoped(scope, handler) { - if (scope === '') return handler; - - return (req, res, next) => { - if (req.url?.startsWith(scope)) { - const original_url = req.url; - req.url = req.url.slice(scope.length); - handler(req, res, () => { - req.url = original_url; - next(); - }); - } else { - next(); - } - }; -} - /** @param {string} path */ function is_file(path) { return fs.existsSync(path) && !fs.statSync(path).isDirectory(); diff --git a/packages/kit/src/runtime/app/forms.js b/packages/kit/src/runtime/app/forms.js index d1f6d70323e4..bd2a81fc8656 100644 --- a/packages/kit/src/runtime/app/forms.js +++ b/packages/kit/src/runtime/app/forms.js @@ -49,20 +49,6 @@ export function deserialize(result) { return parsed; } -/** - * @param {string} old_name - * @param {string} new_name - * @param {string} call_location - * @returns void - */ -function warn_on_access(old_name, new_name, call_location) { - if (!DEV) return; - // TODO 2.0: Remove this code - console.warn( - `\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})` - ); -} - /** * Shallow clone an element, so that we can access e.g. `form.action` without worrying * that someone has added an `` (https://github.com/sveltejs/kit/issues/7593) @@ -157,11 +143,9 @@ export function enhance(form_element, submit = () => {}) { if (DEV && clone(form_element).enctype !== 'multipart/form-data') { for (const value of form_data.values()) { if (value instanceof File) { - // TODO 2.0: Upgrade to `throw Error` - console.warn( - 'Your form contains fields, but is missing the `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819. This will be upgraded to an error in v2.0.' + throw new Error( + 'Your form contains fields, but is missing the necessary `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819.' ); - break; } } } @@ -176,21 +160,12 @@ export function enhance(form_element, submit = () => {}) { let cancelled = false; const cancel = () => (cancelled = true); - // TODO 2.0: Remove `data` and `form` const callback = (await submit({ action, cancel, controller, - get data() { - warn_on_access('data', 'formData', 'use:enhance submit function'); - return form_data; - }, formData: form_data, - get form() { - warn_on_access('form', 'formElement', 'use:enhance submit function'); - return form_element; - }, formElement: form_element, submitter: event.submitter })) ?? fallback_callback; @@ -220,15 +195,7 @@ export function enhance(form_element, submit = () => {}) { callback({ action, - get data() { - warn_on_access('data', 'formData', 'callback returned from use:enhance submit function'); - return form_data; - }, formData: form_data, - get form() { - warn_on_access('form', 'formElement', 'callback returned from use:enhance submit function'); - return form_element; - }, formElement: form_element, update: (opts) => fallback_callback({ diff --git a/packages/kit/src/runtime/app/navigation.js b/packages/kit/src/runtime/app/navigation.js index 683dcd1fde11..4bbfae215f9c 100644 --- a/packages/kit/src/runtime/app/navigation.js +++ b/packages/kit/src/runtime/app/navigation.js @@ -11,20 +11,13 @@ export const disableScrollHandling = /* @__PURE__ */ client_method('disable_scro * Returns a Promise that resolves when SvelteKit navigates (or fails to navigate, in which case the promise rejects) to the specified `url`. * For external URLs, use `window.location = url` instead of calling `goto(url)`. * - * @type {(url: string | URL, opts?: { - * replaceState?: boolean; - * noScroll?: boolean; - * keepFocus?: boolean; - * invalidateAll?: boolean; - * state?: any - * }) => Promise} + * @type {(url: string | URL, opts?: { replaceState?: boolean; noScroll?: boolean; keepFocus?: boolean; invalidateAll?: boolean; }) => Promise} * @param {string | URL} url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://kit.svelte.dev/docs/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app. * @param {Object} [opts] Options related to the navigation * @param {boolean} [opts.replaceState] If `true`, will replace the current `history` entry rather than creating a new one with `pushState` * @param {boolean} [opts.noScroll] If `true`, the browser will maintain its scroll position rather than scrolling to the top of the page after navigation * @param {boolean} [opts.keepFocus] If `true`, the currently focused element will retain focus after navigation. Otherwise, focus will be reset to the body - * @param {boolean} [invalidateAll] If `true`, all `load` functions of the page will be rerun. See https://kit.svelte.dev/docs/load#rerunning-load-functions for more info on invalidation. - * @param {any} [opts.state] The state of the new/updated history entry + * @param {boolean} [opts.invalidateAll] If `true`, all `load` functions of the page will be rerun. See https://kit.svelte.dev/docs/load#rerunning-load-functions for more info on invalidation. * @returns {Promise} */ export const goto = /* @__PURE__ */ client_method('goto'); @@ -64,11 +57,11 @@ export const invalidateAll = /* @__PURE__ */ client_method('invalidate_all'); * * This is the same behaviour that SvelteKit triggers when the user taps or mouses over an `` element with `data-sveltekit-preload-data`. * If the next navigation is to `href`, the values returned from load will be used, making navigation instantaneous. - * Returns a Promise that resolves when the preload is complete. + * Returns a Promise that resolves with the result of running the new route's `load` functions once the preload is complete. * - * @type {(href: string) => Promise} + * @type {(href: string) => Promise>} * @param {string} href Page to preload - * @returns {Promise} + * @returns {Promise<{ type: 'loaded'; status: number; data: Record } | { type: 'redirect'; location: string }>} */ export const preloadData = /* @__PURE__ */ client_method('preload_data'); @@ -81,8 +74,8 @@ export const preloadData = /* @__PURE__ */ client_method('preload_data'); * Unlike `preloadData`, this won't call `load` functions. * Returns a Promise that resolves when the modules have been imported. * - * @type {(...urls: string[]) => Promise} - * @param {...string[]} urls + * @type {(url: string) => Promise} + * @param {string} url * @returns {Promise} */ export const preloadCode = /* @__PURE__ */ client_method('preload_code'); @@ -111,7 +104,7 @@ export const beforeNavigate = /* @__PURE__ */ client_method('before_navigate'); * If a function (or a `Promise` that resolves to a function) is returned from the callback, it will be called once the DOM has updated. * * `onNavigate` must be called during a component initialization. It remains active as long as the component is mounted. - * @type {(callback: (navigation: import('@sveltejs/kit').OnNavigate) => import('../../types/internal.js').MaybePromise<(() => void) | void>) => void} + * @type {(callback: (navigation: import('@sveltejs/kit').OnNavigate) => import('types').MaybePromise<(() => void) | void>) => void} * @param {(navigation: import('@sveltejs/kit').OnNavigate) => void} callback * @returns {void} */ @@ -126,3 +119,23 @@ export const onNavigate = /* @__PURE__ */ client_method('on_navigate'); * @returns {void} */ export const afterNavigate = /* @__PURE__ */ client_method('after_navigate'); + +/** + * Programmatically create a new history entry with the given `$page.state`. To use the current URL, you can pass `''` as the first argument. Used for [shallow routing](https://kit.svelte.dev/docs/shallow-routing). + * + * @type {(url: string | URL, state: App.PageState) => void} + * @param {string | URL} url + * @param {App.PageState} state + * @returns {void} + */ +export const pushState = /* @__PURE__ */ client_method('push_state'); + +/** + * Programmatically replace the current history entry with the given `$page.state`. To use the current URL, you can pass `''` as the first argument. Used for [shallow routing](https://kit.svelte.dev/docs/shallow-routing). + * + * @type {(url: string | URL, state: App.PageState) => void} + * @param {string | URL} url + * @param {App.PageState} state + * @returns {void} + */ +export const replaceState = /* @__PURE__ */ client_method('replace_state'); diff --git a/packages/kit/src/runtime/app/paths.js b/packages/kit/src/runtime/app/paths.js index 0a55bcfc33c5..32df2e1b3eda 100644 --- a/packages/kit/src/runtime/app/paths.js +++ b/packages/kit/src/runtime/app/paths.js @@ -1,8 +1,6 @@ export { base, assets } from '__sveltekit/paths'; import { base } from '__sveltekit/paths'; -import { get_route_segments } from '../../utils/routing.js'; - -const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g; +import { resolve_route } from '../../utils/routing.js'; /** * Populate a route ID with params to resolve a pathname. @@ -21,30 +19,5 @@ const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g; * @returns {string} */ export function resolveRoute(id, params) { - const segments = get_route_segments(id); - return ( - base + - '/' + - segments - .map((segment) => - segment.replace(basic_param_pattern, (_, optional, rest, name) => { - const param_value = params[name]; - - // This is nested so TS correctly narrows the type - if (!param_value) { - if (optional) return ''; - if (rest && param_value !== undefined) return ''; - throw new Error(`Missing parameter '${name}' in route ${id}`); - } - - if (param_value.startsWith('/') || param_value.endsWith('/')) - throw new Error( - `Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar` - ); - return param_value; - }) - ) - .filter(Boolean) - .join('/') - ); + return base + resolve_route(id, params); } diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index af41be1dca87..6db0ec702efc 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -4,6 +4,7 @@ import { add_data_suffix, decode_params, decode_pathname, + strip_hash, make_trackable, normalize_path } from '../../utils/url.js'; @@ -18,43 +19,109 @@ import { parse } from './parse.js'; import * as storage from './session-storage.js'; import { find_anchor, - get_base_uri, + resolve_url, get_link_info, get_router_options, is_external_url, - scroll_state, - origin + origin, + scroll_state } from './utils.js'; import { base } from '__sveltekit/paths'; import * as devalue from 'devalue'; -import { compact } from '../../utils/array.js'; +import { + HISTORY_INDEX, + NAVIGATION_INDEX, + PRELOAD_PRIORITIES, + SCROLL_KEY, + STATES_KEY, + SNAPSHOT_KEY, + PAGE_URL_KEY +} from './constants.js'; import { validate_page_exports } from '../../utils/exports.js'; -import { unwrap_promises } from '../../utils/promises.js'; -import { HttpError, Redirect, NotFound } from '../control.js'; +import { compact } from '../../utils/array.js'; +import { HttpError, Redirect, SvelteKitError } from '../control.js'; import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM, validate_depends } from '../shared.js'; -import { INDEX_KEY, PRELOAD_PRIORITIES, SCROLL_KEY, SNAPSHOT_KEY } from './constants.js'; import { stores } from './singletons.js'; +import { get_message, get_status } from '../../utils/error.js'; let errored = false; +/** @typedef {{ x: number; y: number }} ScrollPosition */ + // We track the scroll position associated with each history entry in sessionStorage, // rather than on history.state itself, because when navigation is driven by // popstate it's too late to update the scroll position associated with the // state we're navigating from - -/** @typedef {{ x: number, y: number }} ScrollPosition */ -/** @type {Record} */ +/** + * history index -> { x, y } + * @type {Record} + */ const scroll_positions = storage.get(SCROLL_KEY) ?? {}; -/** @type {Record} */ +/** + * history index -> any + * @type {Record>} + */ +const states = storage.get(STATES_KEY, devalue.parse) ?? {}; + +/** + * navigation index -> any + * @type {Record} + */ const snapshots = storage.get(SNAPSHOT_KEY) ?? {}; +const original_push_state = history.pushState; +const original_replace_state = history.replaceState; + +if (DEV) { + let warned = false; + + const warn = () => { + if (warned) return; + warned = true; + + console.warn( + "Avoid using `history.pushState(...)` and `history.replaceState(...)` as these will conflict with SvelteKit's router. Use the `pushState` and `replaceState` imports from `$app/navigation` instead." + ); + }; + + history.pushState = (...args) => { + warn(); + return original_push_state.apply(history, args); + }; + + history.replaceState = (...args) => { + warn(); + return original_replace_state.apply(history, args); + }; +} + /** @param {number} index */ function update_scroll_positions(index) { scroll_positions[index] = scroll_state(); } +/** + * @param {number} current_history_index + * @param {number} current_navigation_index + */ +function clear_onward_history(current_history_index, current_navigation_index) { + // if we navigated back, then pushed a new state, we can + // release memory by pruning the scroll/snapshot lookup + let i = current_history_index + 1; + while (scroll_positions[i]) { + delete scroll_positions[i]; + i += 1; + } + + i = current_navigation_index + 1; + while (snapshots[i]) { + delete snapshots[i]; + i += 1; + } +} + /** * Loads `href` the old-fashioned way, with a full page reload. * Returns a `Promise` that never resolves (to prevent any @@ -66,6 +133,8 @@ function native_navigation(url) { return new Promise(() => {}); } +function noop() {} + /** * @param {import('./types.js').SvelteKitApp} app * @param {HTMLElement} target @@ -83,6 +152,7 @@ export function create_client(app, target) { default_error_loader(); const container = __SVELTEKIT_EMBEDDED__ ? target : document.documentElement; + /** @type {Array<((url: URL) => boolean)>} */ const invalidated = []; @@ -123,6 +193,8 @@ export function create_client(app, target) { let updating = false; let navigating = false; let hash_navigating = false; + /** True as soon as there happened one client-side navigation (excluding the SvelteKit-initialized initial one when in SPA mode) */ + let has_navigated = false; let force_invalidation = false; @@ -130,16 +202,25 @@ export function create_client(app, target) { let root; // keeping track of the history index in order to prevent popstate navigation events if needed - let current_history_index = history.state?.[INDEX_KEY]; + /** @type {number} */ + let current_history_index = history.state?.[HISTORY_INDEX]; + + /** @type {number} */ + let current_navigation_index = history.state?.[NAVIGATION_INDEX]; if (!current_history_index) { // we use Date.now() as an offset so that cross-document navigations // within the app don't result in data loss - current_history_index = Date.now(); + current_history_index = current_navigation_index = Date.now(); // create initial history entry, so we can return here - history.replaceState( - { ...history.state, [INDEX_KEY]: current_history_index }, + original_replace_state.call( + history, + { + ...history.state, + [HISTORY_INDEX]: current_history_index, + [NAVIGATION_INDEX]: current_navigation_index + }, '', location.href ); @@ -166,13 +247,12 @@ export function create_client(app, target) { // Accept all invalidations as they come, don't swallow any while another invalidation // is running because subsequent invalidations may make earlier ones outdated, // but batch multiple synchronous invalidations. - pending_invalidate = pending_invalidate || Promise.resolve(); - await pending_invalidate; + await (pending_invalidate ||= Promise.resolve()); if (!pending_invalidate) return; pending_invalidate = null; - const url = new URL(location.href); - const intent = get_navigation_intent(url, true); + const intent = get_navigation_intent(current.url, true); + // Clear preload, it might be affected by the invalidation. // Also solves an edge case where a preload is triggered, the navigation for it // was then triggered and is still running while the invalidation kicks in, @@ -185,7 +265,7 @@ export function create_client(app, target) { if (navigation_result) { if (navigation_result.type === 'redirect') { - return goto(new URL(navigation_result.location, url).href, {}, 1, nav_token); + await goto(new URL(navigation_result.location, current.url).href, {}, 1, nav_token); } else { if (navigation_result.props.page !== undefined) { page = navigation_result.props.page; @@ -193,6 +273,8 @@ export function create_client(app, target) { root.$set(navigation_result.props); } } + + invalidated.length = 0; } /** @param {number} index */ @@ -213,49 +295,31 @@ export function create_client(app, target) { update_scroll_positions(current_history_index); storage.set(SCROLL_KEY, scroll_positions); - capture_snapshot(current_history_index); + capture_snapshot(current_navigation_index); storage.set(SNAPSHOT_KEY, snapshots); + storage.set(STATES_KEY, states, devalue.stringify); } /** * @param {string | URL} url - * @param {{ noScroll?: boolean; replaceState?: boolean; keepFocus?: boolean; state?: any; invalidateAll?: boolean }} opts + * @param {{ replaceState?: boolean; noScroll?: boolean; keepFocus?: boolean; invalidateAll?: boolean; }} options * @param {number} redirect_count * @param {{}} [nav_token] */ - async function goto( - url, - { - noScroll = false, - replaceState = false, - keepFocus = false, - state = {}, - invalidateAll = false - }, - redirect_count, - nav_token - ) { - if (typeof url === 'string') { - url = new URL(url, get_base_uri(document)); - } - + async function goto(url, options, redirect_count, nav_token) { return navigate({ - url, - scroll: noScroll ? scroll_state() : null, - keepfocus: keepFocus, + type: 'goto', + url: resolve_url(url), + keepfocus: options.keepFocus, + noscroll: options.noScroll, + replace_state: options.replaceState, redirect_count, - details: { - state, - replaceState - }, nav_token, - accepted: () => { - if (invalidateAll) { + accept: () => { + if (options.invalidateAll) { force_invalidation = true; } - }, - blocked: () => {}, - type: 'goto' + } }); } @@ -275,19 +339,13 @@ export function create_client(app, target) { return load_cache.promise; } - /** @param {...string} pathnames */ - async function preload_code(...pathnames) { - if (DEV && pathnames.length > 1) { - console.warn('Calling `preloadCode` with multiple arguments is deprecated'); - } - - const matching = routes.filter((route) => pathnames.some((pathname) => route.exec(pathname))); - - const promises = matching.map((r) => { - return Promise.all([...r.layouts, r.leaf].map((load) => load?.[1]())); - }); + /** @param {string} pathname */ + async function preload_code(pathname) { + const route = routes.find((route) => route.exec(get_url_path(pathname))); - await Promise.all(promises); + if (route) { + await Promise.all([...route.layouts, route.leaf].map((load) => load?.[1]())); + } } /** @param {import('./types.js').NavigationFinished} result */ @@ -307,7 +365,7 @@ export function create_client(app, target) { hydrate: true }); - restore_snapshot(current_history_index); + restore_snapshot(current_navigation_index); /** @type {import('@sveltejs/kit').AfterNavigate} */ const navigation = { @@ -368,7 +426,8 @@ export function create_client(app, target) { }, props: { // @ts-ignore Somehow it's getting SvelteComponent and SvelteComponentDev mixed up - constructors: compact(branch).map((branch_node) => branch_node.node.component) + constructors: compact(branch).map((branch_node) => branch_node.node.component), + page } }; @@ -412,6 +471,7 @@ export function create_client(app, target) { route: { id: route?.id ?? null }, + state: {}, status, url: new URL(url), form: form ?? null, @@ -441,13 +501,16 @@ export function create_client(app, target) { /** @type {Record | null} */ let data = null; + let is_tracking = true; + /** @type {import('types').Uses} */ const uses = { dependencies: new Set(), params: new Set(), parent: false, route: false, - url: false + url: false, + search_params: new Set() }; const node = await loader(); @@ -471,20 +534,34 @@ export function create_client(app, target) { const load_input = { route: new Proxy(route, { get: (target, key) => { - uses.route = true; + if (is_tracking) { + uses.route = true; + } return target[/** @type {'id'} */ (key)]; } }), params: new Proxy(params, { get: (target, key) => { - uses.params.add(/** @type {string} */ (key)); + if (is_tracking) { + uses.params.add(/** @type {string} */ (key)); + } return target[/** @type {string} */ (key)]; } }), data: server_data_node?.data ?? null, - url: make_trackable(url, () => { - uses.url = true; - }), + url: make_trackable( + url, + () => { + if (is_tracking) { + uses.url = true; + } + }, + (param) => { + if (is_tracking) { + uses.search_params.add(param); + } + } + ), async fetch(resource, init) { /** @type {URL | string} */ let requested; @@ -520,7 +597,9 @@ export function create_client(app, target) { // we must fixup relative urls so they are resolved from the target page const resolved = new URL(requested, url); - depends(resolved.href); + if (is_tracking) { + depends(resolved.href); + } // match ssr serialized data url, which is important to find cached responses if (resolved.origin === url.origin) { @@ -535,8 +614,18 @@ export function create_client(app, target) { setHeaders: () => {}, // noop depends, parent() { - uses.parent = true; + if (is_tracking) { + uses.parent = true; + } return parent(); + }, + untrack(fn) { + is_tracking = false; + try { + return fn(); + } finally { + is_tracking = true; + } } }; @@ -563,7 +652,6 @@ export function create_client(app, target) { } else { data = (await node.universal.load.call(null, load_input)) ?? null; } - data = data ? await unwrap_promises(data, route.id) : null; } return { @@ -585,10 +673,18 @@ export function create_client(app, target) { * @param {boolean} parent_changed * @param {boolean} route_changed * @param {boolean} url_changed + * @param {Set} search_params_changed * @param {import('types').Uses | undefined} uses * @param {Record} params */ - function has_changed(parent_changed, route_changed, url_changed, uses, params) { + function has_changed( + parent_changed, + route_changed, + url_changed, + search_params_changed, + uses, + params + ) { if (force_invalidation) return true; if (!uses) return false; @@ -597,6 +693,10 @@ export function create_client(app, target) { if (uses.route && route_changed) return true; if (uses.url && url_changed) return true; + for (const tracked_params of uses.search_params) { + if (search_params_changed.has(tracked_params)) return true; + } + for (const param of uses.params) { if (params[param] !== current.params[param]) return true; } @@ -619,6 +719,31 @@ export function create_client(app, target) { return null; } + /** + * + * @param {URL | null} old_url + * @param {URL} new_url + */ + function diff_search_params(old_url, new_url) { + if (!old_url) return new Set(new_url.searchParams.keys()); + + const changed = new Set([...old_url.searchParams.keys(), ...new_url.searchParams.keys()]); + + for (const key of changed) { + const old_values = old_url.searchParams.getAll(key); + const new_values = new_url.searchParams.getAll(key); + + if ( + old_values.every((value) => new_values.includes(value)) && + new_values.every((value) => old_values.includes(value)) + ) { + changed.delete(key); + } + } + + return changed; + } + /** * @param {import('./types.js').NavigationIntent} intent * @returns {Promise} @@ -640,9 +765,9 @@ export function create_client(app, target) { /** @type {import('types').ServerNodesResponse | import('types').ServerRedirectNode | null} */ let server_data = null; - const url_changed = current.url ? id !== current.url.pathname + current.url.search : false; const route_changed = current.route ? route.id !== current.route.id : false; + const search_params_changed = diff_search_params(current.url, url); let parent_invalid = false; const invalid_server_nodes = loaders.map((loader, i) => { @@ -651,7 +776,14 @@ export function create_client(app, target) { const invalid = !!loader?.[0] && (previous?.loader !== loader[1] || - has_changed(parent_invalid, route_changed, url_changed, previous.server?.uses, params)); + has_changed( + parent_invalid, + route_changed, + url_changed, + search_params_changed, + previous.server?.uses, + params + )); if (invalid) { // For the next one @@ -666,7 +798,7 @@ export function create_client(app, target) { server_data = await load_data(url, invalid_server_nodes); } catch (error) { return load_root_error_page({ - status: error instanceof HttpError ? error.status : 500, + status: get_status(error), error: await handle_error(error, { url, params, route: { id: route.id } }), url, route @@ -694,7 +826,14 @@ export function create_client(app, target) { const valid = (!server_data_node || server_data_node.type === 'skip') && loader[1] === previous?.loader && - !has_changed(parent_changed, route_changed, url_changed, previous.universal?.uses, params); + !has_changed( + parent_changed, + route_changed, + url_changed, + search_params_changed, + previous.universal?.uses, + params + ); if (valid) return previous; parent_changed = true; @@ -743,7 +882,7 @@ export function create_client(app, target) { }; } - let status = 500; + let status = get_status(err); /** @type {App.Error} */ let error; @@ -753,7 +892,6 @@ export function create_client(app, target) { status = /** @type {import('types').ServerErrorNode} */ (err).status ?? status; error = /** @type {import('types').ServerErrorNode} */ (err).error; } else if (err instanceof HttpError) { - status = err.status; error = err.body; } else { // Referenced node could have been removed due to redeploy, check @@ -905,7 +1043,7 @@ export function create_client(app, target) { function get_navigation_intent(url, invalidating) { if (is_external_url(url, base)) return; - const path = get_url_path(url); + const path = get_url_path(url.pathname); for (const route of routes) { const params = route.exec(path); @@ -919,9 +1057,9 @@ export function create_client(app, target) { } } - /** @param {URL} url */ - function get_url_path(url) { - return decode_pathname(url.pathname.slice(base.length) || '/'); + /** @param {string} pathname */ + function get_url_path(pathname) { + return decode_pathname(pathname.slice(base.length) || '/'); } /** @@ -959,45 +1097,47 @@ export function create_client(app, target) { /** * @param {{ - * url: URL; - * scroll: { x: number, y: number } | null; - * keepfocus: boolean; - * redirect_count: number; - * details: { - * replaceState: boolean; - * state: any; - * } | null; * type: import('@sveltejs/kit').Navigation["type"]; - * delta?: number; + * url: URL; + * popped?: { + * state: Record; + * scroll: { x: number, y: number }; + * delta: number; + * }; + * keepfocus?: boolean; + * noscroll?: boolean; + * replace_state?: boolean; + * redirect_count?: number; * nav_token?: {}; - * accepted: () => void; - * blocked: () => void; + * accept?: () => void; + * block?: () => void; * }} opts */ async function navigate({ + type, url, - scroll, + popped, keepfocus, - redirect_count, - details, - type, - delta, + noscroll, + replace_state, + redirect_count = 0, nav_token = {}, - accepted, - blocked + accept = noop, + block = noop }) { const intent = get_navigation_intent(url, false); - const nav = before_navigate({ url, type, delta, intent }); + const nav = before_navigate({ url, type, delta: popped?.delta, intent }); if (!nav) { - blocked(); + block(); return; } - // store this before calling `accepted()`, which may change the index + // store this before calling `accept()`, which may change the index const previous_history_index = current_history_index; + const previous_navigation_index = current_navigation_index; - accepted(); + accept(); navigating = true; @@ -1015,7 +1155,7 @@ export function create_client(app, target) { navigation_result = await server_fallback( url, { id: null }, - await handle_error(new Error(`Not found: ${url.pathname}`), { + await handle_error(new SvelteKitError(404, 'Not Found', `Not found: ${url.pathname}`), { url, params: {}, route: { id: null } @@ -1051,7 +1191,7 @@ export function create_client(app, target) { goto(new URL(navigation_result.location, url).href, {}, redirect_count + 1, nav_token); return false; } - } else if (/** @type {number} */ (navigation_result.props.page?.status) >= 400) { + } else if (/** @type {number} */ (navigation_result.props.page.status) >= 400) { const updated = await stores.updated.check(); if (updated) { await native_navigation(url); @@ -1066,36 +1206,39 @@ export function create_client(app, target) { updating = true; update_scroll_positions(previous_history_index); - capture_snapshot(previous_history_index); + capture_snapshot(previous_navigation_index); // ensure the url pathname matches the page's trailing slash option - if ( - navigation_result.props.page?.url && - navigation_result.props.page.url.pathname !== url.pathname - ) { - url.pathname = navigation_result.props.page?.url.pathname; + if (navigation_result.props.page.url.pathname !== url.pathname) { + url.pathname = navigation_result.props.page.url.pathname; } - if (details) { - const change = details.replaceState ? 0 : 1; - details.state[INDEX_KEY] = current_history_index += change; - history[details.replaceState ? 'replaceState' : 'pushState'](details.state, '', url); - - if (!details.replaceState) { - // if we navigated back, then pushed a new state, we can - // release memory by pruning the scroll/snapshot lookup - let i = current_history_index + 1; - while (snapshots[i] || scroll_positions[i]) { - delete snapshots[i]; - delete scroll_positions[i]; - i += 1; - } + const state = popped ? popped.state : {}; + + if (!popped) { + // this is a new navigation, rather than a popstate + const change = replace_state ? 0 : 1; + + const entry = { + [HISTORY_INDEX]: (current_history_index += change), + [NAVIGATION_INDEX]: (current_navigation_index += change) + }; + + const fn = replace_state ? original_replace_state : original_push_state; + fn.call(history, entry, '', url); + + if (!replace_state) { + clear_onward_history(current_history_index, current_navigation_index); } } + states[current_history_index] = state; + // reset preload synchronously after the history state has been set to avoid race conditions load_cache = null; + navigation_result.props.page.state = state; + if (started) { current = navigation_result.state; @@ -1127,6 +1270,7 @@ export function create_client(app, target) { } root.$set(navigation_result.props); + has_navigated = true; } else { initialize(navigation_result); } @@ -1137,6 +1281,8 @@ export function create_client(app, target) { await tick(); // we reset scroll before dealing with focus, to avoid a flash of unscrolled content + const scroll = popped ? popped.scroll : noscroll ? scroll_state() : null; + if (autoscroll) { const deep_linked = url.hash && document.getElementById(decodeURIComponent(url.hash.slice(1))); @@ -1172,7 +1318,7 @@ export function create_client(app, target) { navigating = false; if (type === 'popstate') { - restore_snapshot(current_history_index); + restore_snapshot(current_navigation_index); } nav.fulfil(undefined); @@ -1247,9 +1393,7 @@ export function create_client(app, target) { (entries) => { for (const entry of entries) { if (entry.isIntersecting) { - preload_code( - get_url_path(new URL(/** @type {HTMLAnchorElement} */ (entry.target).href)) - ); + preload_code(/** @type {HTMLAnchorElement} */ (entry.target).href); observer.unobserve(entry.target); } } @@ -1290,7 +1434,7 @@ export function create_client(app, target) { } } } else if (priority <= options.preload_code) { - preload_code(get_url_path(/** @type {URL} */ (url))); + preload_code(/** @type {URL} */ (url).pathname); } } } @@ -1310,7 +1454,7 @@ export function create_client(app, target) { } if (options.preload_code === PRELOAD_PRIORITIES.eager) { - preload_code(get_url_path(/** @type {URL} */ (url))); + preload_code(/** @type {URL} */ (url).pathname); } } } @@ -1334,12 +1478,11 @@ export function create_client(app, target) { console.warn('The next HMR update will cause the page to reload'); } + const status = get_status(error); + const message = get_message(error); + return ( - app.hooks.handleError({ error, event }) ?? - /** @type {any} */ ({ - message: - event.route.id === null && error instanceof NotFound ? 'Not Found' : 'Internal Error' - }) + app.hooks.handleError({ error, event, status, message }) ?? /** @type {any} */ ({ message }) ); } @@ -1387,8 +1530,28 @@ export function create_client(app, target) { } }, - goto: (href, opts = {}) => { - return goto(href, opts, 0); + goto: (url, opts = {}) => { + url = resolve_url(url); + + // @ts-expect-error + if (DEV && opts.state) { + // TOOD 3.0 remove + throw new Error( + 'Passing `state` to `goto` is no longer supported. Use `pushState` and `replaceState` from `$app/navigation` instead.' + ); + } + + if (url.origin !== origin) { + return Promise.reject( + new Error( + DEV + ? `Cannot use \`goto\` with an external URL. Use \`window.location = "${url}"\` instead` + : 'goto: invalid URL' + ) + ); + } + + return goto(url, opts, 0); }, invalidate: (resource) => { @@ -1408,17 +1571,89 @@ export function create_client(app, target) { }, preload_data: async (href) => { - const url = new URL(href, get_base_uri(document)); + const url = resolve_url(href); const intent = get_navigation_intent(url, false); if (!intent) { throw new Error(`Attempted to preload a URL that does not belong to this app: ${url}`); } - await preload_data(intent); + const result = await preload_data(intent); + if (result.type === 'redirect') { + return { + type: result.type, + location: result.location + }; + } + + const { status, data } = result.props.page ?? page; + return { type: result.type, status, data }; }, - preload_code, + preload_code: (pathname) => { + if (DEV) { + if (!pathname.startsWith(base)) { + throw new Error( + `pathnames passed to preloadCode must start with \`paths.base\` (i.e. "${base}${pathname}" rather than "${pathname}")` + ); + } + + if (!routes.find((route) => route.exec(get_url_path(pathname)))) { + throw new Error(`'${pathname}' did not match any routes`); + } + } + + return preload_code(pathname); + }, + + push_state: (url, state) => { + if (DEV) { + try { + devalue.stringify(state); + } catch (error) { + // @ts-expect-error + throw new Error(`Could not serialize state${error.path}`); + } + } + + const opts = { + [HISTORY_INDEX]: (current_history_index += 1), + [NAVIGATION_INDEX]: current_navigation_index, + [PAGE_URL_KEY]: page.url.href + }; + + original_push_state.call(history, opts, '', resolve_url(url)); + + page = { ...page, state }; + root.$set({ page }); + + states[current_history_index] = state; + clear_onward_history(current_history_index, current_navigation_index); + }, + + replace_state: (url, state) => { + if (DEV) { + try { + devalue.stringify(state); + } catch (error) { + // @ts-expect-error + throw new Error(`Could not serialize state${error.path}`); + } + } + + const opts = { + [HISTORY_INDEX]: current_history_index, + [NAVIGATION_INDEX]: current_navigation_index, + [PAGE_URL_KEY]: page.url.href + }; + + original_replace_state.call(history, opts, '', resolve_url(url)); + + page = { ...page, state }; + root.$set({ page }); + + states[current_history_index] = state; + }, apply_action: async (result) => { if (result.type === 'error') { @@ -1575,7 +1810,7 @@ export function create_client(app, target) { // This will ensure the `hashchange` event is fired // Removing the hash does a full page navigation in the browser, so make sure a hash is present const [nonhash, hash] = url.href.split('#'); - if (hash !== undefined && nonhash === location.href.split('#')[0]) { + if (hash !== undefined && nonhash === strip_hash(location)) { // If we are trying to navigate to the same hash, we should only // attempt to scroll to that element and avoid any history changes. // Otherwise, this can cause Firefox to incorrectly assign a null @@ -1597,21 +1832,16 @@ export function create_client(app, target) { // hashchange event shouldn't occur if the router is replacing state. hash_navigating = false; - event.preventDefault(); } + event.preventDefault(); + navigate({ + type: 'link', url, - scroll: options.noscroll ? scroll_state() : null, - keepfocus: options.keep_focus ?? false, - redirect_count: 0, - details: { - state: {}, - replaceState: options.replace_state ?? url.href === location.href - }, - accepted: () => event.preventDefault(), - blocked: () => event.preventDefault(), - type: 'link' + keepfocus: options.keepfocus, + noscroll: options.noscroll, + replace_state: options.replace_state ?? url.href === location.href }); }); @@ -1638,8 +1868,8 @@ export function create_client(app, target) { const event_form = /** @type {HTMLFormElement} */ (event.target); - const { keep_focus, noscroll, reload, replace_state } = get_router_options(event_form); - if (reload) return; + const options = get_router_options(event_form); + if (options.reload) return; event.preventDefault(); event.stopPropagation(); @@ -1655,57 +1885,67 @@ export function create_client(app, target) { url.search = new URLSearchParams(data).toString(); navigate({ + type: 'form', url, - scroll: noscroll ? scroll_state() : null, - keepfocus: keep_focus ?? false, - redirect_count: 0, - details: { - state: {}, - replaceState: replace_state ?? url.href === location.href - }, - nav_token: {}, - accepted: () => {}, - blocked: () => {}, - type: 'form' + keepfocus: options.keepfocus, + noscroll: options.noscroll, + replace_state: options.replace_state ?? url.href === location.href }); }); addEventListener('popstate', async (event) => { - token = {}; - if (event.state?.[INDEX_KEY]) { + if (event.state?.[HISTORY_INDEX]) { + const history_index = event.state[HISTORY_INDEX]; + token = {}; + // if a popstate-driven navigation is cancelled, we need to counteract it // with history.go, which means we end up back here, hence this check - if (event.state[INDEX_KEY] === current_history_index) return; - - const scroll = scroll_positions[event.state[INDEX_KEY]]; - const url = new URL(location.href); - - // if the only change is the hash, we don't need to do anything (see https://github.com/sveltejs/kit/pull/10636 for why we need to do `url?.`)... - if (current.url?.href.split('#')[0] === location.href.split('#')[0]) { - // ...except update our internal URL tracking and handle scroll + if (history_index === current_history_index) return; + + const scroll = scroll_positions[history_index]; + const state = states[history_index] ?? {}; + const url = new URL(event.state[PAGE_URL_KEY] ?? location.href); + const navigation_index = event.state[NAVIGATION_INDEX]; + const is_hash_change = strip_hash(location) === strip_hash(current.url); + const shallow = + navigation_index === current_navigation_index && (has_navigated || is_hash_change); + + if (shallow) { + // We don't need to navigate, we just need to update scroll and/or state. + // This happens with hash links and `pushState`/`replaceState`. The + // exception is if we haven't navigated yet, since we could have + // got here after a modal navigation then a reload update_url(url); + scroll_positions[current_history_index] = scroll_state(); - current_history_index = event.state[INDEX_KEY]; - scrollTo(scroll.x, scroll.y); + if (scroll) scrollTo(scroll.x, scroll.y); + + if (state !== page.state) { + page = { ...page, state }; + root.$set({ page }); + } + + current_history_index = history_index; return; } - const delta = event.state[INDEX_KEY] - current_history_index; + const delta = history_index - current_history_index; await navigate({ + type: 'popstate', url, - scroll, - keepfocus: false, - redirect_count: 0, - details: null, - accepted: () => { - current_history_index = event.state[INDEX_KEY]; + popped: { + state, + scroll, + delta + }, + accept: () => { + current_history_index = history_index; + current_navigation_index = navigation_index; }, - blocked: () => { + block: () => { history.go(-delta); }, - type: 'popstate', - delta, nav_token: token }); } else { @@ -1724,8 +1964,13 @@ export function create_client(app, target) { // we need to update history, otherwise we have to leave it alone if (hash_navigating) { hash_navigating = false; - history.replaceState( - { ...history.state, [INDEX_KEY]: ++current_history_index }, + original_replace_state.call( + history, + { + ...history.state, + [HISTORY_INDEX]: ++current_history_index, + [NAVIGATION_INDEX]: current_navigation_index + }, '', location.href ); @@ -1839,13 +2084,17 @@ export function create_client(app, target) { } result = await load_root_error_page({ - status: error instanceof HttpError ? error.status : 500, + status: get_status(error), error: await handle_error(error, { url, params, route }), url, route }); } + if (result.props.page) { + result.props.page.state = {}; + } + initialize(result); } }; @@ -1966,7 +2215,8 @@ function deserialize_uses(uses) { params: new Set(uses?.params ?? []), parent: !!uses?.parent, route: !!uses?.route, - url: !!uses?.url + url: !!uses?.url, + search_params: new Set(uses?.search_params ?? []) }; } diff --git a/packages/kit/src/runtime/client/constants.js b/packages/kit/src/runtime/client/constants.js index e6b515332801..982c25d7debe 100644 --- a/packages/kit/src/runtime/client/constants.js +++ b/packages/kit/src/runtime/client/constants.js @@ -1,6 +1,10 @@ export const SNAPSHOT_KEY = 'sveltekit:snapshot'; export const SCROLL_KEY = 'sveltekit:scroll'; -export const INDEX_KEY = 'sveltekit:index'; +export const STATES_KEY = 'sveltekit:states'; +export const PAGE_URL_KEY = 'sveltekit:pageurl'; + +export const HISTORY_INDEX = 'sveltekit:history'; +export const NAVIGATION_INDEX = 'sveltekit:navigation'; export const PRELOAD_PRIORITIES = /** @type {const} */ ({ tap: 1, diff --git a/packages/kit/src/runtime/client/session-storage.js b/packages/kit/src/runtime/client/session-storage.js index dc2639ef1b5e..e49543bc8b82 100644 --- a/packages/kit/src/runtime/client/session-storage.js +++ b/packages/kit/src/runtime/client/session-storage.js @@ -1,10 +1,11 @@ /** * Read a value from `sessionStorage` * @param {string} key + * @param {(value: string) => any} parse */ -export function get(key) { +export function get(key, parse = JSON.parse) { try { - return JSON.parse(sessionStorage[key]); + return parse(sessionStorage[key]); } catch { // do nothing } @@ -14,11 +15,12 @@ export function get(key) { * Write a value to `sessionStorage` * @param {string} key * @param {any} value + * @param {(value: any) => string} stringify */ -export function set(key, value) { - const json = JSON.stringify(value); +export function set(key, value, stringify = JSON.stringify) { + const data = stringify(value); try { - sessionStorage[key] = json; + sessionStorage[key] = data; } catch { // do nothing } diff --git a/packages/kit/src/runtime/client/singletons.js b/packages/kit/src/runtime/client/singletons.js index e6bf5808eef9..aacaa04907ec 100644 --- a/packages/kit/src/runtime/client/singletons.js +++ b/packages/kit/src/runtime/client/singletons.js @@ -21,7 +21,13 @@ export function init(opts) { */ export function client_method(key) { if (!BROWSER) { - if (key === 'before_navigate' || key === 'after_navigate' || key === 'on_navigate') { + if ( + key === 'before_navigate' || + key === 'after_navigate' || + key === 'on_navigate' || + key === 'push_state' || + key === 'replace_state' + ) { // @ts-expect-error doesn't recognize that both keys here return void so expects a async function return () => {}; } else { diff --git a/packages/kit/src/runtime/client/types.d.ts b/packages/kit/src/runtime/client/types.d.ts index 6466bd916447..458c36ddddae 100644 --- a/packages/kit/src/runtime/client/types.d.ts +++ b/packages/kit/src/runtime/client/types.d.ts @@ -7,7 +7,9 @@ import { invalidate, invalidateAll, preloadCode, - preloadData + preloadData, + pushState, + replaceState } from '../app/navigation.js'; import { SvelteComponent } from 'svelte'; import { ClientHooks, CSRPageNode, CSRPageNodeLoader, CSRRoute, TrailingSlash, Uses } from 'types'; @@ -51,6 +53,8 @@ export interface Client { invalidate_all: typeof invalidateAll; preload_code: typeof preloadCode; preload_data: typeof preloadData; + push_state: typeof pushState; + replace_state: typeof replaceState; apply_action: typeof applyAction; // private API @@ -92,7 +96,7 @@ export type NavigationFinished = { props: { constructors: Array; components?: Array; - page?: Page; + page: Page; form?: Record | null; [key: `data_${number}`]: Record; }; diff --git a/packages/kit/src/runtime/client/utils.js b/packages/kit/src/runtime/client/utils.js index c0a8fcbea05c..d205f48cdc42 100644 --- a/packages/kit/src/runtime/client/utils.js +++ b/packages/kit/src/runtime/client/utils.js @@ -8,16 +8,18 @@ import { PRELOAD_PRIORITIES } from './constants.js'; export const origin = BROWSER ? location.origin : ''; -/** @param {HTMLDocument} doc */ -export function get_base_uri(doc) { - let baseURI = doc.baseURI; +/** @param {string | URL} url */ +export function resolve_url(url) { + if (url instanceof URL) return url; + + let baseURI = document.baseURI; if (!baseURI) { - const baseTags = doc.getElementsByTagName('base'); - baseURI = baseTags.length ? baseTags[0].href : doc.URL; + const baseTags = document.getElementsByTagName('base'); + baseURI = baseTags.length ? baseTags[0].href : document.URL; } - return baseURI; + return new URL(url, baseURI); } export function scroll_state() { @@ -147,7 +149,7 @@ export function get_link_info(a, base) { */ export function get_router_options(element) { /** @type {ValidLinkOptions<'keepfocus'> | null} */ - let keep_focus = null; + let keepfocus = null; /** @type {ValidLinkOptions<'noscroll'> | null} */ let noscroll = null; @@ -170,7 +172,7 @@ export function get_router_options(element) { while (el && el !== document.documentElement) { if (preload_code === null) preload_code = link_option(el, 'preload-code'); if (preload_data === null) preload_data = link_option(el, 'preload-data'); - if (keep_focus === null) keep_focus = link_option(el, 'keepfocus'); + if (keepfocus === null) keepfocus = link_option(el, 'keepfocus'); if (noscroll === null) noscroll = link_option(el, 'noscroll'); if (reload === null) reload = link_option(el, 'reload'); if (replace_state === null) replace_state = link_option(el, 'replacestate'); @@ -188,14 +190,14 @@ export function get_router_options(element) { case 'false': return false; default: - return null; + return undefined; } } return { preload_code: levels[preload_code ?? 'off'], preload_data: levels[preload_data ?? 'off'], - keep_focus: get_option_state(keep_focus), + keepfocus: get_option_state(keepfocus), noscroll: get_option_state(noscroll), reload: get_option_state(reload), replace_state: get_option_state(replace_state) diff --git a/packages/kit/src/runtime/control.js b/packages/kit/src/runtime/control.js index 6bacb73f9273..b55430e88820 100644 --- a/packages/kit/src/runtime/control.js +++ b/packages/kit/src/runtime/control.js @@ -30,15 +30,20 @@ export class Redirect { } } -export class NotFound extends Error { +/** + * An error that was thrown from within the SvelteKit runtime that is not fatal and doesn't result in a 500, such as a 404. + * `SvelteKitError` goes through `handleError`. + */ +export class SvelteKitError extends Error { /** - * @param {string} pathname + * @param {number} status + * @param {string} text + * @param {string} message */ - constructor(pathname) { - super(); - - this.status = 404; - this.message = `Not found: ${pathname}`; + constructor(status, text, message) { + super(message); + this.status = status; + this.text = text; } } @@ -48,7 +53,7 @@ export class NotFound extends Error { export class ActionFailure { /** * @param {number} status - * @param {T} [data] + * @param {T} data */ constructor(status, data) { this.status = status; @@ -66,6 +71,7 @@ export class ActionFailure { * ActionFailure: typeof ActionFailure; * HttpError: typeof HttpError; * Redirect: typeof Redirect; + * SvelteKitError: typeof SvelteKitError; * }} implementations */ export function replace_implementations(implementations) { @@ -75,4 +81,6 @@ export function replace_implementations(implementations) { HttpError = implementations.HttpError; // eslint-disable-line no-class-assign // @ts-expect-error Redirect = implementations.Redirect; // eslint-disable-line no-class-assign + // @ts-expect-error + SvelteKitError = implementations.SvelteKitError; // eslint-disable-line no-class-assign } diff --git a/packages/kit/src/runtime/server/cookie.js b/packages/kit/src/runtime/server/cookie.js index a52e52972075..7acd24417848 100644 --- a/packages/kit/src/runtime/server/cookie.js +++ b/packages/kit/src/runtime/server/cookie.js @@ -1,6 +1,5 @@ import { parse, serialize } from 'cookie'; -import { normalize_path, resolve } from '../../utils/url.js'; -import { warn_with_callsite } from './utils.js'; +import { add_data_suffix, normalize_path, resolve } from '../../utils/url.js'; /** * Tracks all cookies set during dev mode so we can emit warnings @@ -15,24 +14,11 @@ const cookie_paths = {}; */ const MAX_COOKIE_SIZE = 4129; -/** - * - * @param {import('cookie').CookieSerializeOptions} opts - * @param {'set' | 'delete' | 'serialize'} method - */ -function deprecate_missing_path(opts, method) { - if (opts.path === undefined) { - warn_with_callsite( - `Calling \`cookies.${method}(...)\` without specifying a \`path\` is deprecated, and will be disallowed in SvelteKit 2.0. Relative paths can be used`, - 1 - ); - } - - if (opts.path === '') { - warn_with_callsite( - `Calling \`cookies.${method}(...)\` with \`path: ''\` will behave differently in SvelteKit 2.0. Instead of using the browser default behaviour, it will set the cookie path to the current pathname`, - 1 - ); +// TODO 3.0 remove this check +/** @param {import('./page/types.js').Cookie['options']} options */ +function validate_options(options) { + if (options?.path === undefined) { + throw new Error('You must specify a `path` when setting, deleting or serializing cookies'); } } @@ -46,8 +32,6 @@ export function get_cookies(request, url, trailing_slash) { const initial_cookies = parse(header, { decode: (value) => value }); const normalized_url = normalize_path(url.pathname, trailing_slash); - // Emulate browser-behavior: if the cookie is set at '/foo/bar', its path is '/foo' - const default_path = normalized_url.split('/').slice(0, -1).join('/') || '/'; /** @type {Record} */ const new_cookies = {}; @@ -126,39 +110,37 @@ export function get_cookies(request, url, trailing_slash) { /** * @param {string} name * @param {string} value - * @param {import('cookie').CookieSerializeOptions} opts + * @param {import('./page/types.js').Cookie['options']} options */ - set(name, value, opts = {}) { - deprecate_missing_path(opts, 'set'); - set_internal(name, value, { ...defaults, ...opts }); + set(name, value, options) { + validate_options(options); + set_internal(name, value, { ...defaults, ...options }); }, /** * @param {string} name - * @param {import('cookie').CookieSerializeOptions} opts + * @param {import('./page/types.js').Cookie['options']} options */ - delete(name, opts = {}) { - deprecate_missing_path(opts, 'delete'); - - cookies.set(name, '', { - path: default_path, // TODO 2.0 remove this - ...opts, - maxAge: 0 - }); + delete(name, options) { + validate_options(options); + cookies.set(name, '', { ...options, maxAge: 0 }); }, /** * @param {string} name * @param {string} value - * @param {import('cookie').CookieSerializeOptions} opts + * @param {import('./page/types.js').Cookie['options']} options */ - serialize(name, value, opts = {}) { - deprecate_missing_path(opts, 'serialize'); + serialize(name, value, options) { + validate_options(options); + + let path = options.path; + + if (!options.domain || options.domain === url.hostname) { + path = resolve(normalized_url, path); + } - return serialize(name, value, { - ...defaults, - ...opts - }); + return serialize(name, value, { ...defaults, ...options, path }); } }; @@ -199,27 +181,16 @@ export function get_cookies(request, url, trailing_slash) { /** * @param {string} name * @param {string} value - * @param {import('cookie').CookieSerializeOptions} opts + * @param {import('./page/types.js').Cookie['options']} options */ - function set_internal(name, value, opts) { - let path = opts.path; + function set_internal(name, value, options) { + let path = options.path; - if (!opts.domain || opts.domain === url.hostname) { - if (path) { - if (path[0] === '.') path = resolve(url.pathname, path); - } else { - path = default_path; - } + if (!options.domain || options.domain === url.hostname) { + path = resolve(normalized_url, path); } - new_cookies[name] = { - name, - value, - options: { - ...opts, - path - } - }; + new_cookies[name] = { name, value, options: { ...options, path } }; if (__SVELTEKIT_DEV__) { const serialized = serialize(name, value, new_cookies[name].options); @@ -230,10 +201,8 @@ export function get_cookies(request, url, trailing_slash) { cookie_paths[name] ??= new Set(); if (!value) { - // @ts-expect-error temporary cookie_paths[name].delete(path); } else { - // @ts-expect-error temporary cookie_paths[name].add(path); } } @@ -276,6 +245,14 @@ export function add_cookies_to_headers(headers, cookies) { for (const new_cookie of cookies) { const { name, value, options } = new_cookie; headers.append('set-cookie', serialize(name, value, options)); + + // special case — for routes ending with .html, the route data lives in a sibling + // `.html__data.json` file rather than a child `/__data.json` file, which means + // we need to duplicate the cookie + if (options.path.endsWith('.html')) { + const path = add_data_suffix(options.path); + headers.append('set-cookie', serialize(name, value, { ...options, path })); + } } } diff --git a/packages/kit/src/runtime/server/cookie.spec.js b/packages/kit/src/runtime/server/cookie.spec.js index 52f3052c281c..c8f04b1e9cdb 100644 --- a/packages/kit/src/runtime/server/cookie.spec.js +++ b/packages/kit/src/runtime/server/cookie.spec.js @@ -76,11 +76,11 @@ test('default values when set is called', () => { test('default values when set is called on sub path', () => { const { cookies, new_cookies } = cookies_setup({ href: 'https://example.com/foo/bar' }); - cookies.set('a', 'b'); + cookies.set('a', 'b', { path: '' }); const opts = new_cookies['a']?.options; assert.equal(opts?.secure, true); assert.equal(opts?.httpOnly, true); - assert.equal(opts?.path, '/foo'); + assert.equal(opts?.path, '/foo/bar'); assert.equal(opts?.sameSite, 'lax'); }); @@ -199,12 +199,12 @@ test("set_internal isn't affected by defaults", () => { href: 'https://example.com/a/b/c' }); - const options = /** @type {const} */ ({ + const options = { secure: false, httpOnly: false, - sameSite: 'none', + sameSite: /** @type {const} */ ('none'), path: '/a/b/c' - }); + }; set_internal('test', 'foo', options); diff --git a/packages/kit/src/runtime/server/data/index.js b/packages/kit/src/runtime/server/data/index.js index 472c2c10c479..c0316d278e8d 100644 --- a/packages/kit/src/runtime/server/data/index.js +++ b/packages/kit/src/runtime/server/data/index.js @@ -1,4 +1,4 @@ -import { HttpError, Redirect } from '../../control.js'; +import { HttpError, SvelteKitError, Redirect } from '../../control.js'; import { normalize_error } from '../../../utils/error.js'; import { once } from '../../../utils/functions.js'; import { load_server_data } from '../page/load_data.js'; @@ -76,8 +76,7 @@ export async function render_data( } } return data; - }, - track_server_fetches: options.track_server_fetches + } }); } catch (e) { aborted = true; @@ -110,7 +109,10 @@ export async function render_data( return /** @type {import('types').ServerErrorNode} */ ({ type: 'error', error: await handle_error_and_jsonify(event, options, error), - status: error instanceof HttpError ? error.status : undefined + status: + error instanceof HttpError || error instanceof SvelteKitError + ? error.status + : undefined }); }) ) diff --git a/packages/kit/src/runtime/server/env_module.js b/packages/kit/src/runtime/server/env_module.js new file mode 100644 index 000000000000..7d37ac6a1481 --- /dev/null +++ b/packages/kit/src/runtime/server/env_module.js @@ -0,0 +1,29 @@ +import { public_env } from '../shared-server.js'; + +/** @type {string} */ +let body; + +/** @type {string} */ +let etag; + +/** @type {Headers} */ +let headers; + +/** + * @param {Request} request + * @returns {Response} + */ +export function get_public_env(request) { + body ??= `export const env=${JSON.stringify(public_env)}`; + etag ??= `W/${Date.now()}`; + headers ??= new Headers({ + 'content-type': 'application/javascript; charset=utf-8', + etag + }); + + if (request.headers.get('if-none-match') === etag) { + return new Response(undefined, { status: 304, headers }); + } + + return new Response(body, { headers }); +} diff --git a/packages/kit/src/runtime/server/fetch.js b/packages/kit/src/runtime/server/fetch.js index d97abcdccafd..e5911209239c 100644 --- a/packages/kit/src/runtime/server/fetch.js +++ b/packages/kit/src/runtime/server/fetch.js @@ -9,7 +9,7 @@ import * as paths from '__sveltekit/paths'; * manifest: import('@sveltejs/kit').SSRManifest; * state: import('types').SSRState; * get_cookie_header: (url: URL, header: string | null) => string; - * set_internal: (name: string, value: string, opts: import('cookie').CookieSerializeOptions) => void; + * set_internal: (name: string, value: string, opts: import('./page/types.js').Cookie['options']) => void; * }} opts * @returns {typeof fetch} */ @@ -134,12 +134,13 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade for (const str of set_cookie_parser.splitCookiesString(set_cookie)) { const { name, value, ...options } = set_cookie_parser.parseString(str); + const path = options.path ?? (url.pathname.split('/').slice(0, -1).join('/') || '/'); + // options.sameSite is string, something more specific is required - type cast is safe - set_internal( - name, - value, - /** @type {import('cookie').CookieSerializeOptions} */ (options) - ); + set_internal(name, value, { + path, + .../** @type {import('cookie').CookieSerializeOptions} */ (options) + }); } } diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js index 607f161b2742..fde088f714b6 100644 --- a/packages/kit/src/runtime/server/index.js +++ b/packages/kit/src/runtime/server/index.js @@ -1,8 +1,18 @@ import { respond } from './respond.js'; -import { set_private_env, set_public_env } from '../shared-server.js'; +import { set_private_env, set_public_env, set_safe_public_env } from '../shared-server.js'; import { options, get_hooks } from '__SERVER__/internal.js'; import { DEV } from 'esm-env'; import { filter_private_env, filter_public_env } from '../../utils/env.js'; +import { building } from '../app/environment.js'; + +/** @type {ProxyHandler<{ type: 'public' | 'private' }>} */ +const prerender_env_handler = { + get({ type }, prop) { + throw new Error( + `Cannot read values from $env/dynamic/${type} while prerendering (attempted to read env.${prop.toString()}). Use $env/static/${type} instead` + ); + } +}; export class Server { /** @type {import('types').SSROptions} */ @@ -27,19 +37,19 @@ export class Server { // Take care: Some adapters may have to call `Server.init` per-request to set env vars, // so anything that shouldn't be rerun should be wrapped in an `if` block to make sure it hasn't // been done already. + // set env, in case it's used in initialisation - set_private_env( - filter_private_env(env, { - public_prefix: this.#options.env_public_prefix, - private_prefix: this.#options.env_private_prefix - }) - ); - set_public_env( - filter_public_env(env, { - public_prefix: this.#options.env_public_prefix, - private_prefix: this.#options.env_private_prefix - }) - ); + const prefixes = { + public_prefix: this.#options.env_public_prefix, + private_prefix: this.#options.env_private_prefix + }; + + const private_env = filter_private_env(env, prefixes); + const public_env = filter_public_env(env, prefixes); + + set_private_env(building ? new Proxy({ type: 'private' }, prerender_env_handler) : private_env); + set_public_env(building ? new Proxy({ type: 'public' }, prerender_env_handler) : public_env); + set_safe_public_env(public_env); if (!this.#options.hooks) { try { @@ -71,13 +81,6 @@ export class Server { * @param {import('types').RequestOptions} options */ async respond(request, options) { - // TODO this should probably have been removed for 1.0 — i think we can get rid of it? - if (!(request instanceof Request)) { - throw new Error( - 'The first argument to server.respond must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details' - ); - } - return respond(request, this.#options, this.#manifest, { ...options, error: false, diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index 0d656815d83d..64db810507a8 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -1,8 +1,8 @@ import * as devalue from 'devalue'; -import { error, json } from '../../../exports/index.js'; -import { normalize_error } from '../../../utils/error.js'; +import { json } from '../../../exports/index.js'; +import { get_status, normalize_error } from '../../../utils/error.js'; import { is_form_content_type, negotiate } from '../../../utils/http.js'; -import { HttpError, Redirect, ActionFailure } from '../../control.js'; +import { HttpError, Redirect, ActionFailure, SvelteKitError } from '../../control.js'; import { handle_error_and_jsonify } from '../utils.js'; /** @param {import('@sveltejs/kit').RequestEvent} event */ @@ -24,8 +24,11 @@ export async function handle_action_json_request(event, options, server) { const actions = server?.actions; if (!actions) { - // TODO should this be a different error altogether? - const no_actions_error = error(405, 'POST method not allowed. No actions exist for this page'); + const no_actions_error = new SvelteKitError( + 405, + 'Method Not Allowed', + 'POST method not allowed. No actions exist for this page' + ); return action_json( { type: 'error', @@ -81,7 +84,7 @@ export async function handle_action_json_request(event, options, server) { error: await handle_error_and_jsonify(event, options, check_incorrect_fail_use(err)) }, { - status: err instanceof HttpError ? err.status : 500 + status: get_status(err) } ); } @@ -139,7 +142,11 @@ export async function handle_action_request(event, server) { }); return { type: 'error', - error: error(405, 'POST method not allowed. No actions exist for this page') + error: new SvelteKitError( + 405, + 'Method Not Allowed', + 'POST method not allowed. No actions exist for this page' + ) }; } @@ -198,7 +205,7 @@ function check_named_default_separate(actions) { /** * @param {import('@sveltejs/kit').RequestEvent} event * @param {NonNullable} actions - * @throws {Redirect | ActionFailure | HttpError | Error} + * @throws {Redirect | HttpError | SvelteKitError | Error} */ async function call_action(event, actions) { const url = new URL(event.request.url); @@ -216,12 +223,16 @@ async function call_action(event, actions) { const action = actions[name]; if (!action) { - throw new Error(`No action with name '${name}' found`); + throw new SvelteKitError(404, 'Not Found', `No action with name '${name}' found`); } if (!is_form_content_type(event.request)) { - throw new Error( - `Actions expect form-encoded data (received ${event.request.headers.get('content-type')})` + throw new SvelteKitError( + 415, + 'Unsupported Media Type', + `Form actions expect form-encoded data — received ${event.request.headers.get( + 'content-type' + )}` ); } @@ -231,13 +242,11 @@ async function call_action(event, actions) { /** @param {any} data */ function validate_action_return(data) { if (data instanceof Redirect) { - throw new Error('Cannot `return redirect(...)` — use `throw redirect(...)` instead'); + throw new Error('Cannot `return redirect(...)` — use `redirect(...)` instead'); } if (data instanceof HttpError) { - throw new Error( - 'Cannot `return error(...)` — use `throw error(...)` or `return fail(...)` instead' - ); + throw new Error('Cannot `return error(...)` — use `error(...)` or `return fail(...)` instead'); } } diff --git a/packages/kit/src/runtime/server/page/csp.spec.js b/packages/kit/src/runtime/server/page/csp.spec.js index 9747053dae67..66ea28085d2c 100644 --- a/packages/kit/src/runtime/server/page/csp.spec.js +++ b/packages/kit/src/runtime/server/page/csp.spec.js @@ -2,8 +2,11 @@ import { webcrypto } from 'node:crypto'; import { assert, beforeAll, test } from 'vitest'; import { Csp } from './csp.js'; -// @ts-expect-error -globalThis.crypto = webcrypto; +// TODO: remove after bumping peer dependency to require Node 20 +if (!globalThis.crypto) { + // @ts-expect-error + globalThis.crypto = webcrypto; +} beforeAll(() => { // @ts-expect-error diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index c1a01e4614d3..067d60585cd9 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -1,8 +1,8 @@ import { text } from '../../../exports/index.js'; import { compact } from '../../../utils/array.js'; -import { normalize_error } from '../../../utils/error.js'; +import { get_status, normalize_error } from '../../../utils/error.js'; import { add_data_suffix } from '../../../utils/url.js'; -import { HttpError, Redirect } from '../../control.js'; +import { Redirect } from '../../control.js'; import { redirect_response, static_error_page, handle_error_and_jsonify } from '../utils.js'; import { handle_action_json_request, @@ -65,8 +65,7 @@ export async function render_page(event, page, options, manifest, state, resolve return redirect_response(action_result.status, action_result.location); } if (action_result?.type === 'error') { - const error = action_result.error; - status = error instanceof HttpError ? error.status : 500; + status = get_status(action_result.error); } if (action_result?.type === 'failure') { status = action_result.status; @@ -78,7 +77,7 @@ export async function render_page(event, page, options, manifest, state, resolve // it's crucial that we do this before returning the non-SSR response, otherwise // SvelteKit will erroneously believe that the path has been prerendered, - // causing functions to be omitted from the manifesst generated later + // causing functions to be omitted from the manifest generated later const should_prerender = get_option(nodes, 'prerender') ?? false; if (should_prerender) { const mod = leaf_node.server; @@ -150,8 +149,7 @@ export async function render_page(event, page, options, manifest, state, resolve if (parent) Object.assign(data, await parent.data); } return data; - }, - track_server_fetches: options.track_server_fetches + } }); } catch (e) { load_error = /** @type {Error} */ (e); @@ -222,7 +220,7 @@ export async function render_page(event, page, options, manifest, state, resolve return redirect_response(err.status, err.location); } - const status = err instanceof HttpError ? err.status : 500; + const status = get_status(err); const error = await handle_error_and_jsonify(event, options, err); while (i--) { diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index cba46a9cadeb..60f7d6570436 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -1,6 +1,5 @@ -import { disable_search, make_trackable } from '../../../utils/url.js'; -import { unwrap_promises } from '../../../utils/promises.js'; import { DEV } from 'esm-env'; +import { disable_search, make_trackable } from '../../../utils/url.js'; import { validate_depends } from '../../shared.js'; /** @@ -10,39 +9,49 @@ import { validate_depends } from '../../shared.js'; * state: import('types').SSRState; * node: import('types').SSRNode | undefined; * parent: () => Promise>; - * track_server_fetches: boolean; * }} opts * @returns {Promise} */ -export async function load_server_data({ - event, - state, - node, - parent, - // TODO 2.0: Remove this - track_server_fetches -}) { +export async function load_server_data({ event, state, node, parent }) { if (!node?.server) return null; let done = false; + let is_tracking = true; const uses = { dependencies: new Set(), params: new Set(), parent: false, route: false, - url: false + url: false, + search_params: new Set() }; - const url = make_trackable(event.url, () => { - if (DEV && done && !uses.url) { - console.warn( - `${node.server_id}: Accessing URL properties in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the URL changes` - ); - } + const url = make_trackable( + event.url, + () => { + if (DEV && done && !uses.url) { + console.warn( + `${node.server_id}: Accessing URL properties in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the URL changes` + ); + } - uses.url = true; - }); + if (is_tracking) { + uses.url = true; + } + }, + (param) => { + if (DEV && done && !uses.search_params.has(param)) { + console.warn( + `${node.server_id}: Accessing URL properties in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the URL changes` + ); + } + + if (is_tracking) { + uses.search_params.add(param); + } + } + ); if (state.prerendering) { disable_search(url); @@ -59,11 +68,7 @@ export async function load_server_data({ ); } - // TODO 2.0: Remove this - if (track_server_fetches) { - uses.dependencies.add(url.href); - } - + // Note: server fetches are not added to uses.depends due to security concerns return event.fetch(info, init); }, /** @param {string[]} deps */ @@ -94,7 +99,9 @@ export async function load_server_data({ ); } - uses.params.add(key); + if (is_tracking) { + uses.params.add(key); + } return target[/** @type {string} */ (key)]; } }), @@ -105,7 +112,9 @@ export async function load_server_data({ ); } - uses.parent = true; + if (is_tracking) { + uses.parent = true; + } return parent(); }, route: new Proxy(event.route, { @@ -118,23 +127,32 @@ export async function load_server_data({ ); } - uses.route = true; + if (is_tracking) { + uses.route = true; + } return target[/** @type {'id'} */ (key)]; } }), - url + url, + untrack(fn) { + is_tracking = false; + try { + return fn(); + } finally { + is_tracking = true; + } + } }); - const data = result ? await unwrap_promises(result, node.server_id) : null; if (__SVELTEKIT_DEV__) { - validate_load_response(data, node.server_id); + validate_load_response(result, node.server_id); } done = true; return { type: 'data', - data, + data: result ?? null, uses, slash: node.server.trailingSlash }; @@ -178,15 +196,15 @@ export async function load_data({ fetch: create_universal_fetch(event, state, fetched, csr, resolve_opts), setHeaders: event.setHeaders, depends: () => {}, - parent + parent, + untrack: (fn) => fn() }); - const data = result ? await unwrap_promises(result, node.universal_id) : null; if (__SVELTEKIT_DEV__) { - validate_load_response(data, node.universal_id); + validate_load_response(result, node.universal_id); } - return data; + return result ?? null; } /** diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 2e159d0c297c..fbe8f9d35548 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -8,7 +8,7 @@ import { s } from '../../../utils/misc.js'; import { Csp } from './csp.js'; import { uneval_action_response } from './actions.js'; import { clarify_devalue_error, stringify_uses, handle_error_and_jsonify } from '../utils.js'; -import { public_env } from '../../shared-server.js'; +import { public_env, safe_public_env } from '../../shared-server.js'; import { text } from '../../../exports/index.js'; import { create_async_iterator } from '../../../utils/streaming.js'; import { SVELTE_KIT_ASSETS } from '../../../constants.js'; @@ -95,7 +95,7 @@ export async function render_response({ let base_expression = s(paths.base); // if appropriate, use relative paths for greater portability - if (paths.relative !== false && !state.prerendering?.fallback) { + if (paths.relative && !state.prerendering?.fallback) { const segments = event.url.pathname.slice(paths.base.length).split('/').slice(2); base = segments.map(() => '..').join('/') || '.'; @@ -141,7 +141,8 @@ export async function render_response({ status, url: event.url, data, - form: form_value + form: form_value, + state: {} }; // use relative paths during rendering, so that the resulting HTML is as @@ -276,6 +277,10 @@ export async function render_response({ } if (page_config.csr) { + if (client.uses_env_dynamic_public && state.prerendering) { + modulepreloads.add(`${options.app_dir}/env.js`); + } + const included_modulepreloads = Array.from(modulepreloads, (dep) => prefixed(dep)).filter( (path) => resolve_opts.preload({ type: 'js', path }) ); @@ -295,7 +300,7 @@ export async function render_response({ const properties = [ paths.assets && `assets: ${s(paths.assets)}`, `base: ${base_expression}`, - `env: ${s(public_env)}` + `env: ${!client.uses_env_dynamic_public || state.prerendering ? null : s(public_env)}` ].filter(Boolean); if (chunks) { @@ -431,7 +436,7 @@ export async function render_response({ body, assets, nonce: /** @type {string} */ (csp.nonce), - env: public_env + env: safe_public_env }); // TODO flush chunks as early as we can diff --git a/packages/kit/src/runtime/server/page/respond_with_error.js b/packages/kit/src/runtime/server/page/respond_with_error.js index 59e3697896e1..e320b01f04a4 100644 --- a/packages/kit/src/runtime/server/page/respond_with_error.js +++ b/packages/kit/src/runtime/server/page/respond_with_error.js @@ -2,7 +2,8 @@ import { render_response } from './render.js'; import { load_data, load_server_data } from './load_data.js'; import { handle_error_and_jsonify, static_error_page, redirect_response } from '../utils.js'; import { get_option } from '../../../utils/options.js'; -import { HttpError, Redirect } from '../../control.js'; +import { Redirect } from '../../control.js'; +import { get_status } from '../../../utils/error.js'; /** * @typedef {import('./types.js').Loaded} Loaded @@ -49,8 +50,7 @@ export async function respond_with_error({ event, state, node: default_layout, - parent: async () => ({}), - track_server_fetches: options.track_server_fetches + parent: async () => ({}) }); const server_data = await server_data_promise; @@ -104,7 +104,7 @@ export async function respond_with_error({ return static_error_page( options, - e instanceof HttpError ? e.status : 500, + get_status(e), (await handle_error_and_jsonify(event, options, e)).message ); } diff --git a/packages/kit/src/runtime/server/page/types.d.ts b/packages/kit/src/runtime/server/page/types.d.ts index 3b9fef9c3a3f..7e501b1ab418 100644 --- a/packages/kit/src/runtime/server/page/types.d.ts +++ b/packages/kit/src/runtime/server/page/types.d.ts @@ -32,5 +32,5 @@ export interface CspOpts { export interface Cookie { name: string; value: string; - options: CookieSerializeOptions; + options: CookieSerializeOptions & { path: string }; } diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index f975760c9bb3..567097184bf5 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -18,7 +18,7 @@ import { exec } from '../../utils/routing.js'; import { redirect_json_response, render_data } from './data/index.js'; import { add_cookies_to_headers, get_cookies } from './cookie.js'; import { create_fetch } from './fetch.js'; -import { Redirect, NotFound } from '../control.js'; +import { HttpError, Redirect, SvelteKitError } from '../control.js'; import { validate_layout_exports, validate_layout_server_exports, @@ -27,9 +27,10 @@ import { validate_server_exports } from '../../utils/exports.js'; import { get_option } from '../../utils/options.js'; -import { error, json, text } from '../../exports/index.js'; +import { json, text } from '../../exports/index.js'; import { action_json_redirect, is_action_json_request } from './page/actions.js'; import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM } from '../shared.js'; +import { get_public_env } from './env_module.js'; /* global __SVELTEKIT_ADAPTER_NAME__ */ @@ -67,7 +68,10 @@ export async function respond(request, options, manifest, state) { request.headers.get('origin') !== url.origin; if (forbidden) { - const csrf_error = error(403, `Cross-site ${request.method} form submissions are forbidden`); + const csrf_error = new HttpError( + 403, + `Cross-site ${request.method} form submissions are forbidden` + ); if (request.headers.get('accept') === 'application/json') { return json(csrf_error.body, { status: csrf_error.status }); } @@ -95,6 +99,10 @@ export async function respond(request, options, manifest, state) { decoded = decoded.slice(base.length) || '/'; } + if (decoded === `/${options.app_dir}/env.js`) { + return get_public_env(request); + } + const is_data_request = has_data_suffix(decoded); /** @type {boolean[] | undefined} */ let invalidated_data_nodes; @@ -356,12 +364,6 @@ export async function respond(request, options, manifest, state) { async function resolve(event, opts) { try { if (opts) { - if ('ssr' in opts) { - throw new Error( - 'ssr has been removed, set it in the appropriate +layout.js instead. See the PR for more information: https://github.com/sveltejs/kit/pull/6197' - ); - } - resolve_opts = { transformPageChunk: opts.transformPageChunk || default_transform, filterSerializedResponseHeaders: opts.filterSerializedResponseHeaders || default_filter, @@ -480,7 +482,7 @@ export async function respond(request, options, manifest, state) { manifest, state, status: 404, - error: new NotFound(event.url.pathname), + error: new SvelteKitError(404, 'Not Found', `Not found: ${event.url.pathname}`), resolve_opts }); } diff --git a/packages/kit/src/runtime/server/utils.js b/packages/kit/src/runtime/server/utils.js index 8c11cccd0b4e..12cb49288408 100644 --- a/packages/kit/src/runtime/server/utils.js +++ b/packages/kit/src/runtime/server/utils.js @@ -1,8 +1,8 @@ import { DEV } from 'esm-env'; import { json, text } from '../../exports/index.js'; -import { coalesce_to_error } from '../../utils/error.js'; +import { coalesce_to_error, get_message, get_status } from '../../utils/error.js'; import { negotiate } from '../../utils/http.js'; -import { HttpError, NotFound } from '../control.js'; +import { HttpError } from '../control.js'; import { fix_stack_trace } from '../shared-server.js'; import { ENDPOINT_METHODS } from '../../constants.js'; @@ -70,7 +70,7 @@ export function static_error_page(options, status, message) { */ export async function handle_fatal_error(event, options, error) { error = error instanceof HttpError ? error : coalesce_to_error(error); - const status = error instanceof HttpError ? error.status : 500; + const status = get_status(error); const body = await handle_error_and_jsonify(event, options, error); // ideally we'd use sec-fetch-dest instead, but Safari — quelle surprise — doesn't support it @@ -103,11 +103,10 @@ export async function handle_error_and_jsonify(event, options, error) { fix_stack_trace(error); } - return ( - (await options.hooks.handleError({ error, event })) ?? { - message: event.route.id === null && error instanceof NotFound ? 'Not Found' : 'Internal Error' - } - ); + const status = get_status(error); + const message = get_message(error); + + return (await options.hooks.handleError({ error, event, status, message })) ?? { message }; } /** @@ -149,6 +148,10 @@ export function stringify_uses(node) { uses.push(`"dependencies":${JSON.stringify(Array.from(node.uses.dependencies))}`); } + if (node.uses && node.uses.search_params.size > 0) { + uses.push(`"search_params":${JSON.stringify(Array.from(node.uses.search_params))}`); + } + if (node.uses && node.uses.params.size > 0) { uses.push(`"params":${JSON.stringify(Array.from(node.uses.params))}`); } diff --git a/packages/kit/src/runtime/shared-server.js b/packages/kit/src/runtime/shared-server.js index 778e31aad481..7bd6bde4c234 100644 --- a/packages/kit/src/runtime/shared-server.js +++ b/packages/kit/src/runtime/shared-server.js @@ -1,9 +1,21 @@ -/** @type {Record} */ +/** + * `$env/dynamic/private` + * @type {Record} + */ export let private_env = {}; -/** @type {Record} */ +/** + * `$env/dynamic/public`. When prerendering, this will be a proxy that forbids reads + * @type {Record} + */ export let public_env = {}; +/** + * The same as `public_env`, but without the proxy. Use for `%sveltekit.env.PUBLIC_FOO%` + * @type {Record} + */ +export let safe_public_env = {}; + /** @param {any} error */ export let fix_stack_trace = (error) => error?.stack; @@ -17,6 +29,11 @@ export function set_public_env(environment) { public_env = environment; } +/** @type {(environment: Record) => void} */ +export function set_safe_public_env(environment) { + safe_public_env = environment; +} + /** @param {(error: Error) => string} value */ export function set_fix_stack_trace(value) { fix_stack_trace = value; diff --git a/packages/kit/src/types/ambient.d.ts b/packages/kit/src/types/ambient.d.ts index b7331402a369..fa32a8a0662b 100644 --- a/packages/kit/src/types/ambient.d.ts +++ b/packages/kit/src/types/ambient.d.ts @@ -7,6 +7,7 @@ * // interface Error {} * // interface Locals {} * // interface PageData {} + * // interface PageState {} * // interface Platform {} * } * } @@ -39,6 +40,11 @@ declare namespace App { */ export interface PageData {} + /** + * The shape of the `$page.state` object, which can be manipulated using the [`pushState`](https://kit.svelte.dev/docs/modules#$app-navigation-pushstate) and [`replaceState`](https://kit.svelte.dev/docs/modules#$app-navigation-replacestate) functions from `$app/navigation`. + */ + export interface PageState {} + /** * If your adapter provides [platform-specific context](https://kit.svelte.dev/docs/adapters#platform-specific-context) via `event.platform`, you can specify it here. */ @@ -101,7 +107,7 @@ declare module '__sveltekit/paths' { * > If a value for `config.kit.paths.assets` is specified, it will be replaced with `'/_svelte_kit_assets'` during `vite dev` or `vite preview`, since the assets don't yet live at their eventual URL. */ export let assets: '' | `https://${string}` | `http://${string}` | '/_svelte_kit_assets'; - export let relative: boolean | undefined; // TODO in 2.0, make this a `boolean` that defaults to `true` + export let relative: boolean; export function reset(): void; export function override(paths: { base: string; assets: string }): void; export function set_assets(path: string): void; diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index ea3023245503..2234eca3f4ef 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -31,6 +31,7 @@ export interface ServerInternalModule { set_assets(path: string): void; set_private_env(environment: Record): void; set_public_env(environment: Record): void; + set_safe_public_env(environment: Record): void; set_version(version: string): void; set_fix_stack_trace(fix_stack_trace: (error: unknown) => string): void; } @@ -59,6 +60,7 @@ export interface BuildData { imports: string[]; stylesheets: string[]; fonts: string[]; + uses_env_dynamic_public: boolean; } | null; server_manifest: import('vite').Manifest; } @@ -330,10 +332,10 @@ export interface SSRNode { export type SSRNodeLoader = () => Promise; export interface SSROptions { + app_dir: string; app_template_contains_nonce: boolean; csp: ValidatedConfig['kit']['csp']; csrf_check_origin: boolean; - track_server_fetches: boolean; embedded: boolean; env_public_prefix: string; env_private_prefix: string; @@ -408,6 +410,7 @@ export interface Uses { parent: boolean; route: boolean; url: boolean; + search_params: Set; } export type ValidatedConfig = RecursiveRequired; diff --git a/packages/kit/src/types/synthetic/$env+dynamic+private.md b/packages/kit/src/types/synthetic/$env+dynamic+private.md index 99fabd42485d..eed73d827bd3 100644 --- a/packages/kit/src/types/synthetic/$env+dynamic+private.md +++ b/packages/kit/src/types/synthetic/$env+dynamic+private.md @@ -2,6 +2,8 @@ This module provides access to runtime environment variables, as defined by the This module cannot be imported into client-side code. +Dynamic environment variables cannot be used during prerendering. + ```ts import { env } from '$env/dynamic/private'; console.log(env.DEPLOYMENT_SPECIFIC_VARIABLE); diff --git a/packages/kit/src/types/synthetic/$env+dynamic+public.md b/packages/kit/src/types/synthetic/$env+dynamic+public.md index b70626ba6417..ad1cf54d2fb6 100644 --- a/packages/kit/src/types/synthetic/$env+dynamic+public.md +++ b/packages/kit/src/types/synthetic/$env+dynamic+public.md @@ -2,6 +2,8 @@ Similar to [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dyn Note that public dynamic environment variables must all be sent from the server to the client, causing larger network requests — when possible, use `$env/static/public` instead. +Dynamic environment variables cannot be used during prerendering. + ```ts import { env } from '$env/dynamic/public'; console.log(env.PUBLIC_DEPLOYMENT_SPECIFIC_VARIABLE); diff --git a/packages/kit/src/utils/error.js b/packages/kit/src/utils/error.js index d485dc75ca55..1247b94096aa 100644 --- a/packages/kit/src/utils/error.js +++ b/packages/kit/src/utils/error.js @@ -1,3 +1,5 @@ +import { HttpError, SvelteKitError } from '../runtime/control.js'; + /** * @param {unknown} err * @return {Error} @@ -16,7 +18,21 @@ export function coalesce_to_error(err) { * @param {unknown} error */ export function normalize_error(error) { - return /** @type {import('../runtime/control.js').Redirect | import('../runtime/control.js').HttpError | Error} */ ( + return /** @type {import('../runtime/control.js').Redirect | HttpError | SvelteKitError | Error} */ ( error ); } + +/** + * @param {unknown} error + */ +export function get_status(error) { + return error instanceof HttpError || error instanceof SvelteKitError ? error.status : 500; +} + +/** + * @param {unknown} error + */ +export function get_message(error) { + return error instanceof SvelteKitError ? error.text : 'Internal Error'; +} diff --git a/packages/kit/src/utils/platform.js b/packages/kit/src/utils/platform.js deleted file mode 100644 index e32dd5f5abce..000000000000 --- a/packages/kit/src/utils/platform.js +++ /dev/null @@ -1 +0,0 @@ -export const should_polyfill = typeof Deno === 'undefined' && typeof Bun === 'undefined'; diff --git a/packages/kit/src/utils/promises.js b/packages/kit/src/utils/promises.js deleted file mode 100644 index b03f0999376a..000000000000 --- a/packages/kit/src/utils/promises.js +++ /dev/null @@ -1,61 +0,0 @@ -import { DEV } from 'esm-env'; - -/** @type {Set | null} */ -let warned = null; - -// TODO v2: remove all references to unwrap_promises - -/** - * Given an object, return a new object where all top level values are awaited - * - * @param {Record} object - * @param {string | null} [id] - * @returns {Promise>} - */ -export async function unwrap_promises(object, id) { - if (DEV) { - /** @type {string[]} */ - const promises = []; - - for (const key in object) { - if (typeof object[key]?.then === 'function') { - promises.push(key); - } - } - - if (promises.length > 0) { - if (!warned) warned = new Set(); - - const last = promises.pop(); - - const properties = - promises.length > 0 - ? `${promises.map((p) => `"${p}"`).join(', ')} and "${last}" properties` - : `"${last}" property`; - - const location = id ? `the \`load\` function in ${id}` : 'a `load` function'; - - const description = promises.length > 0 ? 'are promises' : 'is a promise'; - - const message = `The top-level ${properties} returned from ${location} ${description}.`; - - if (!warned.has(message)) { - console.warn( - `\n${message}\n\nIn SvelteKit 2.0, these will no longer be awaited automatically. To get rid of this warning, await all promises included as top-level properties in \`load\` return values.\n` - ); - - warned.add(message); - } - } - } - - for (const key in object) { - if (typeof object[key]?.then === 'function') { - return Object.fromEntries( - await Promise.all(Object.entries(object).map(async ([key, value]) => [key, await value])) - ); - } - } - - return object; -} diff --git a/packages/kit/src/utils/routing.js b/packages/kit/src/utils/routing.js index d72f77d6c181..66a70c5b3469 100644 --- a/packages/kit/src/utils/routing.js +++ b/packages/kit/src/utils/routing.js @@ -214,3 +214,49 @@ function escape(str) { .replace(/[.*+?^${}()|\\]/g, '\\$&') ); } + +const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g; + +/** + * Populate a route ID with params to resolve a pathname. + * @example + * ```js + * resolveRoute( + * `/blog/[slug]/[...somethingElse]`, + * { + * slug: 'hello-world', + * somethingElse: 'something/else' + * } + * ); // `/blog/hello-world/something/else` + * ``` + * @param {string} id + * @param {Record} params + * @returns {string} + */ +export function resolve_route(id, params) { + const segments = get_route_segments(id); + return ( + '/' + + segments + .map((segment) => + segment.replace(basic_param_pattern, (_, optional, rest, name) => { + const param_value = params[name]; + + // This is nested so TS correctly narrows the type + if (!param_value) { + if (optional) return ''; + if (rest && param_value !== undefined) return ''; + throw new Error(`Missing parameter '${name}' in route ${id}`); + } + + if (param_value.startsWith('/') || param_value.endsWith('/')) + throw new Error( + `Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar` + ); + return param_value; + }) + ) + .filter(Boolean) + .join('/') + ); +} diff --git a/packages/kit/src/utils/routing.spec.js b/packages/kit/src/utils/routing.spec.js index 4b8dc6fcda47..e5595a28a4fb 100644 --- a/packages/kit/src/utils/routing.spec.js +++ b/packages/kit/src/utils/routing.spec.js @@ -1,263 +1,326 @@ -import { assert, expect, test } from 'vitest'; -import { exec, parse_route_id } from './routing.js'; +import { assert, expect, test, describe } from 'vitest'; +import { exec, parse_route_id, resolve_route } from './routing.js'; -const tests = { - '/': { - pattern: /^\/$/, - params: [] - }, - '/blog': { - pattern: /^\/blog\/?$/, - params: [] - }, - '/blog.json': { - pattern: /^\/blog\.json\/?$/, - params: [] - }, - '/blog/[slug]': { - pattern: /^\/blog\/([^/]+?)\/?$/, - params: [{ name: 'slug', matcher: undefined, optional: false, rest: false, chained: false }] - }, - '/blog/[slug].json': { - pattern: /^\/blog\/([^/]+?)\.json\/?$/, - params: [{ name: 'slug', matcher: undefined, optional: false, rest: false, chained: false }] - }, - '/blog/[[slug]]': { - pattern: /^\/blog(?:\/([^/]+))?\/?$/, - params: [{ name: 'slug', matcher: undefined, optional: true, rest: false, chained: true }] - }, - '/blog/[[slug=type]]/sub': { - pattern: /^\/blog(?:\/([^/]+))?\/sub\/?$/, - params: [{ name: 'slug', matcher: 'type', optional: true, rest: false, chained: true }] - }, - '/blog/[[slug]].json': { - pattern: /^\/blog\/([^/]*)?\.json\/?$/, - params: [{ name: 'slug', matcher: undefined, optional: true, rest: false, chained: false }] - }, - '/[...catchall]': { - pattern: /^(?:\/(.*))?\/?$/, - params: [{ name: 'catchall', matcher: undefined, optional: false, rest: true, chained: true }] - }, - '/foo/[...catchall]/bar': { - pattern: /^\/foo(?:\/(.*))?\/bar\/?$/, - params: [{ name: 'catchall', matcher: undefined, optional: false, rest: true, chained: true }] - }, - '/matched/[id=uuid]': { - pattern: /^\/matched\/([^/]+?)\/?$/, - params: [{ name: 'id', matcher: 'uuid', optional: false, rest: false, chained: false }] - }, - '/@-symbol/[id]': { - pattern: /^\/@-symbol\/([^/]+?)\/?$/, - params: [{ name: 'id', matcher: undefined, optional: false, rest: false, chained: false }] - } -}; +describe('parse_route_id', () => { + const tests = { + '/': { + pattern: /^\/$/, + params: [] + }, + '/blog': { + pattern: /^\/blog\/?$/, + params: [] + }, + '/blog.json': { + pattern: /^\/blog\.json\/?$/, + params: [] + }, + '/blog/[slug]': { + pattern: /^\/blog\/([^/]+?)\/?$/, + params: [{ name: 'slug', matcher: undefined, optional: false, rest: false, chained: false }] + }, + '/blog/[slug].json': { + pattern: /^\/blog\/([^/]+?)\.json\/?$/, + params: [{ name: 'slug', matcher: undefined, optional: false, rest: false, chained: false }] + }, + '/blog/[[slug]]': { + pattern: /^\/blog(?:\/([^/]+))?\/?$/, + params: [{ name: 'slug', matcher: undefined, optional: true, rest: false, chained: true }] + }, + '/blog/[[slug=type]]/sub': { + pattern: /^\/blog(?:\/([^/]+))?\/sub\/?$/, + params: [{ name: 'slug', matcher: 'type', optional: true, rest: false, chained: true }] + }, + '/blog/[[slug]].json': { + pattern: /^\/blog\/([^/]*)?\.json\/?$/, + params: [{ name: 'slug', matcher: undefined, optional: true, rest: false, chained: false }] + }, + '/[...catchall]': { + pattern: /^(?:\/(.*))?\/?$/, + params: [{ name: 'catchall', matcher: undefined, optional: false, rest: true, chained: true }] + }, + '/foo/[...catchall]/bar': { + pattern: /^\/foo(?:\/(.*))?\/bar\/?$/, + params: [{ name: 'catchall', matcher: undefined, optional: false, rest: true, chained: true }] + }, + '/matched/[id=uuid]': { + pattern: /^\/matched\/([^/]+?)\/?$/, + params: [{ name: 'id', matcher: 'uuid', optional: false, rest: false, chained: false }] + }, + '/@-symbol/[id]': { + pattern: /^\/@-symbol\/([^/]+?)\/?$/, + params: [{ name: 'id', matcher: undefined, optional: false, rest: false, chained: false }] + } + }; + + for (const [key, expected] of Object.entries(tests)) { + test(key, () => { + const actual = parse_route_id(key); -for (const [key, expected] of Object.entries(tests)) { - test(`parse_route_id: "${key}"`, () => { - const actual = parse_route_id(key); + expect(actual.pattern.toString()).toEqual(expected.pattern.toString()); + expect(actual.params).toEqual(expected.params); + }); + } - expect(actual.pattern.toString()).toEqual(expected.pattern.toString()); - expect(actual.params).toEqual(expected.params); + test('errors on bad param name', () => { + assert.throws(() => parse_route_id('abc/[b-c]'), /Invalid param: b-c/); + assert.throws(() => parse_route_id('abc/[bc=d-e]'), /Invalid param: bc=d-e/); }); -} +}); + +describe('exec', () => { + const tests = [ + { + route: '/blog/[[slug]]/sub[[param]]', + path: '/blog/sub', + expected: {} + }, + { + route: '/blog/[[slug]]/sub[[param]]', + path: '/blog/slug/sub', + expected: { slug: 'slug' } + }, + { + route: '/blog/[[slug]]/sub[[param]]', + path: '/blog/slug/subparam', + expected: { slug: 'slug', param: 'param' } + }, + { + route: '/blog/[[slug]]/sub[[param]]', + path: '/blog/subparam', + expected: { param: 'param' } + }, + { + route: '/[[slug]]/[...rest]', + path: '/slug/rest/sub', + expected: { slug: 'slug', rest: 'rest/sub' } + }, + { + route: '/[[slug]]/[...rest]', + path: '/slug/rest', + expected: { slug: 'slug', rest: 'rest' } + }, + { + route: '/[[slug]]/[...rest]', + path: '/slug', + expected: { slug: 'slug', rest: '' } + }, + { + route: '/[[slug]]/[...rest]', + path: '/', + expected: { rest: '' } + }, + { + route: '/[...rest]/path', + path: '/rest/path', + expected: { rest: 'rest' } + }, + { + route: '/[[slug1]]/[[slug2]]', + path: '/slug1/slug2', + expected: { slug1: 'slug1', slug2: 'slug2' } + }, + { + route: '/[[slug1]]/[[slug2]]', + path: '/slug1', + expected: { slug1: 'slug1' } + }, + { + route: '/[[slug1=matches]]', + path: '/', + expected: {} + }, + { + route: '/[[slug1=doesntmatch]]', + path: '/', + expected: {} + }, + { + route: '/[[slug1=matches]]/[[slug2=doesntmatch]]', + path: '/foo', + expected: { slug1: 'foo' } + }, + { + route: '/[[slug1=doesntmatch]]/[[slug2=doesntmatch]]', + path: '/foo', + expected: undefined + }, + { + route: '/[...slug1=matches]', + path: '/', + expected: { slug1: '' } + }, + { + route: '/[...slug1=doesntmatch]', + path: '/', + expected: undefined + }, + { + route: '/[[slug=doesntmatch]]/[...rest]', + path: '/foo', + expected: { rest: 'foo' } + }, + { + route: '/[[slug1=doesntmatch]]/[slug2]/[...rest]', + path: '/foo/bar/baz', + expected: { slug2: 'foo', rest: 'bar/baz' } + }, + { + route: '/[[slug1=doesntmatch]]/[slug2]/[...rest]/baz', + path: '/foo/bar/baz', + expected: { slug2: 'foo', rest: 'bar' } + }, + { + route: '/[[a=doesntmatch]]/[[b=doesntmatch]]/[[c=doesntmatch]]/[...d]', + path: '/a/b/c/d', + expected: { d: 'a/b/c/d' } + }, + { + route: '/[[a=doesntmatch]]/[b]/[...c]/[d]/e', + path: '/foo/bar/baz/qux/e', + expected: { b: 'foo', c: 'bar/baz', d: 'qux' } + }, + { + route: '/[[slug1=doesntmatch]]/[[slug2=doesntmatch]]/[...rest]', + path: '/foo/bar/baz', + expected: { rest: 'foo/bar/baz' } + }, + { + route: '/[[slug1=doesntmatch]]/[[slug2=matches]]/[[slug3=doesntmatch]]/[...rest].json', + path: '/foo/bar/baz.json', + expected: { slug2: 'foo', rest: 'bar/baz' } + }, + { + route: '/[[a=doesntmatch]]/[[b=matches]]/c', + path: '/a/b/c', + expected: undefined + }, + { + route: '/[[slug1=matches]]/[[slug2=matches]]/constant/[[slug3=matches]]', + path: '/a/b/constant/c', + expected: { slug1: 'a', slug2: 'b', slug3: 'c' } + }, + { + route: '/[[slug1=doesntmatch]]/[[slug2=matches]]/constant/[[slug3=matches]]', + path: '/b/constant/c', + expected: { slug2: 'b', slug3: 'c' } + }, + { + route: '/[[slug1=doesntmatch]]/[[slug2=matches]]/[[slug3=matches]]', + path: '/b/c', + expected: { slug2: 'b', slug3: 'c' } + }, + { + route: '/[slug1]/[[lang=doesntmatch]]/[[page=matches]]', + path: '/a/2', + expected: { slug1: 'a', lang: undefined, page: '2' } + }, + { + route: '/[[slug1=doesntmatch]]/[slug2=matches]/[slug3]', + path: '/a/b/c', + expected: undefined + }, + { + route: '/[[lang=doesntmatch]]/[asset=matches]/[[categoryType]]/[...categories]', + path: '/music', + expected: { asset: 'music', categories: '' } + }, + { + route: '/[[lang=doesntmatch]]/[asset=matches]/[[categoryType]]/[...categories]', + path: '/music/genre', + expected: { asset: 'music', categoryType: 'genre', categories: '' } + }, + { + route: '/[[lang=doesntmatch]]/[asset=matches]/[[categoryType]]/[...categories]', + path: '/music/genre/rock', + expected: { asset: 'music', categoryType: 'genre', categories: 'rock' } + }, + { + route: '/[[lang=doesntmatch]]/[asset=matches]/[[categoryType]]/[...categories]', + path: '/sfx/category/car/crash', + expected: { asset: 'sfx', categoryType: 'category', categories: 'car/crash' } + }, + { + route: '/[[lang=matches]]/[asset=matches]/[[categoryType]]/[...categories]', + path: '/es/sfx/category/car/crash', + expected: { lang: 'es', asset: 'sfx', categoryType: 'category', categories: 'car/crash' } + }, + { + route: '/[[slug1=doesntmatch]]/[...slug2=doesntmatch]', + path: '/a/b/c', + expected: undefined + } + ]; -const exec_tests = [ - { - route: '/blog/[[slug]]/sub[[param]]', - path: '/blog/sub', - expected: {} - }, - { - route: '/blog/[[slug]]/sub[[param]]', - path: '/blog/slug/sub', - expected: { slug: 'slug' } - }, - { - route: '/blog/[[slug]]/sub[[param]]', - path: '/blog/slug/subparam', - expected: { slug: 'slug', param: 'param' } - }, - { - route: '/blog/[[slug]]/sub[[param]]', - path: '/blog/subparam', - expected: { param: 'param' } - }, - { - route: '/[[slug]]/[...rest]', - path: '/slug/rest/sub', - expected: { slug: 'slug', rest: 'rest/sub' } - }, - { - route: '/[[slug]]/[...rest]', - path: '/slug/rest', - expected: { slug: 'slug', rest: 'rest' } - }, - { - route: '/[[slug]]/[...rest]', - path: '/slug', - expected: { slug: 'slug', rest: '' } - }, - { - route: '/[[slug]]/[...rest]', - path: '/', - expected: { rest: '' } - }, - { - route: '/[...rest]/path', - path: '/rest/path', - expected: { rest: 'rest' } - }, - { - route: '/[[slug1]]/[[slug2]]', - path: '/slug1/slug2', - expected: { slug1: 'slug1', slug2: 'slug2' } - }, - { - route: '/[[slug1]]/[[slug2]]', - path: '/slug1', - expected: { slug1: 'slug1' } - }, - { - route: '/[[slug1=matches]]', - path: '/', - expected: {} - }, - { - route: '/[[slug1=doesntmatch]]', - path: '/', - expected: {} - }, - { - route: '/[[slug1=matches]]/[[slug2=doesntmatch]]', - path: '/foo', - expected: { slug1: 'foo' } - }, - { - route: '/[[slug1=doesntmatch]]/[[slug2=doesntmatch]]', - path: '/foo', - expected: undefined - }, - { - route: '/[...slug1=matches]', - path: '/', - expected: { slug1: '' } - }, - { - route: '/[...slug1=doesntmatch]', - path: '/', - expected: undefined - }, - { - route: '/[[slug=doesntmatch]]/[...rest]', - path: '/foo', - expected: { rest: 'foo' } - }, - { - route: '/[[slug1=doesntmatch]]/[slug2]/[...rest]', - path: '/foo/bar/baz', - expected: { slug2: 'foo', rest: 'bar/baz' } - }, - { - route: '/[[slug1=doesntmatch]]/[slug2]/[...rest]/baz', - path: '/foo/bar/baz', - expected: { slug2: 'foo', rest: 'bar' } - }, - { - route: '/[[a=doesntmatch]]/[[b=doesntmatch]]/[[c=doesntmatch]]/[...d]', - path: '/a/b/c/d', - expected: { d: 'a/b/c/d' } - }, - { - route: '/[[a=doesntmatch]]/[b]/[...c]/[d]/e', - path: '/foo/bar/baz/qux/e', - expected: { b: 'foo', c: 'bar/baz', d: 'qux' } - }, - { - route: '/[[slug1=doesntmatch]]/[[slug2=doesntmatch]]/[...rest]', - path: '/foo/bar/baz', - expected: { rest: 'foo/bar/baz' } - }, - { - route: '/[[slug1=doesntmatch]]/[[slug2=matches]]/[[slug3=doesntmatch]]/[...rest].json', - path: '/foo/bar/baz.json', - expected: { slug2: 'foo', rest: 'bar/baz' } - }, - { - route: '/[[a=doesntmatch]]/[[b=matches]]/c', - path: '/a/b/c', - expected: undefined - }, - { - route: '/[[slug1=matches]]/[[slug2=matches]]/constant/[[slug3=matches]]', - path: '/a/b/constant/c', - expected: { slug1: 'a', slug2: 'b', slug3: 'c' } - }, - { - route: '/[[slug1=doesntmatch]]/[[slug2=matches]]/constant/[[slug3=matches]]', - path: '/b/constant/c', - expected: { slug2: 'b', slug3: 'c' } - }, - { - route: '/[[slug1=doesntmatch]]/[[slug2=matches]]/[[slug3=matches]]', - path: '/b/c', - expected: { slug2: 'b', slug3: 'c' } - }, - { - route: '/[slug1]/[[lang=doesntmatch]]/[[page=matches]]', - path: '/a/2', - expected: { slug1: 'a', lang: undefined, page: '2' } - }, - { - route: '/[[slug1=doesntmatch]]/[slug2=matches]/[slug3]', - path: '/a/b/c', - expected: undefined - }, - { - route: '/[[lang=doesntmatch]]/[asset=matches]/[[categoryType]]/[...categories]', - path: '/music', - expected: { asset: 'music', categories: '' } - }, - { - route: '/[[lang=doesntmatch]]/[asset=matches]/[[categoryType]]/[...categories]', - path: '/music/genre', - expected: { asset: 'music', categoryType: 'genre', categories: '' } - }, - { - route: '/[[lang=doesntmatch]]/[asset=matches]/[[categoryType]]/[...categories]', - path: '/music/genre/rock', - expected: { asset: 'music', categoryType: 'genre', categories: 'rock' } - }, - { - route: '/[[lang=doesntmatch]]/[asset=matches]/[[categoryType]]/[...categories]', - path: '/sfx/category/car/crash', - expected: { asset: 'sfx', categoryType: 'category', categories: 'car/crash' } - }, - { - route: '/[[lang=matches]]/[asset=matches]/[[categoryType]]/[...categories]', - path: '/es/sfx/category/car/crash', - expected: { lang: 'es', asset: 'sfx', categoryType: 'category', categories: 'car/crash' } - }, - { - route: '/[[slug1=doesntmatch]]/[...slug2=doesntmatch]', - path: '/a/b/c', - expected: undefined + for (const { path, route, expected } of tests) { + test(`exec extracts params correctly for ${path} from ${route}`, () => { + const { pattern, params } = parse_route_id(route); + const match = pattern.exec(path); + if (!match) throw new Error(`Failed to match ${path}`); + const actual = exec(match, params, { + matches: () => true, + doesntmatch: () => false + }); + expect(actual).toEqual(expected); + }); } -]; +}); + +describe('resolve_route', () => { + const from_params_tests = [ + { + route: '/blog/[one]/[two]', + params: { one: 'one', two: 'two' }, + expected: '/blog/one/two' + }, + { + route: '/blog/[one=matcher]/[...two]', + params: { one: 'one', two: 'two/three' }, + expected: '/blog/one/two/three' + }, + { + route: '/blog/[one=matcher]/[[two]]', + params: { one: 'one' }, + expected: '/blog/one' + }, + { + route: '/blog/[one]/[two]-and-[three]', + params: { one: 'one', two: '2', three: '3' }, + expected: '/blog/one/2-and-3' + }, + { + route: '/blog/[...one]', + params: { one: '' }, + expected: '/blog' + }, + { + route: '/blog/[one]/[...two]-not-three', + params: { one: 'one', two: 'two/2' }, + expected: '/blog/one/two/2-not-three' + } + ]; -for (const { path, route, expected } of exec_tests) { - test(`exec extracts params correctly for ${path} from ${route}`, () => { - const { pattern, params } = parse_route_id(route); - const match = pattern.exec(path); - if (!match) throw new Error(`Failed to match ${path}`); - const actual = exec(match, params, { - matches: () => true, - doesntmatch: () => false + for (const { route, params, expected } of from_params_tests) { + test(`resolvePath generates correct path for ${route}`, () => { + const result = resolve_route(route, params); + assert.equal(result, expected); }); - expect(actual).toEqual(expected); + } + + test('resolvePath errors on missing params for required param', () => { + expect(() => resolve_route('/blog/[one]/[two]', { one: 'one' })).toThrow( + "Missing parameter 'two' in route /blog/[one]/[two]" + ); }); -} -test('parse_route_id errors on bad param name', () => { - assert.throws(() => parse_route_id('abc/[b-c]'), /Invalid param: b-c/); - assert.throws(() => parse_route_id('abc/[bc=d-e]'), /Invalid param: bc=d-e/); + test('resolvePath errors on params values starting or ending with slashes', () => { + assert.throws( + () => resolve_route('/blog/[one]/[two]', { one: 'one', two: '/two' }), + "Parameter 'two' in route /blog/[one]/[two] cannot start or end with a slash -- this would cause an invalid route like foo//bar" + ); + assert.throws( + () => resolve_route('/blog/[one]/[two]', { one: 'one', two: 'two/' }), + "Parameter 'two' in route /blog/[one]/[two] cannot start or end with a slash -- this would cause an invalid route like foo//bar" + ); + }); }); diff --git a/packages/kit/src/utils/url.js b/packages/kit/src/utils/url.js index 4fb61b9baaac..9f6391e42486 100644 --- a/packages/kit/src/utils/url.js +++ b/packages/kit/src/utils/url.js @@ -6,38 +6,20 @@ import { BROWSER } from 'esm-env'; */ export const SCHEME = /^[a-z][a-z\d+\-.]+:/i; -const absolute = /^([a-z]+:)?\/?\//; +const internal = new URL('sveltekit-internal://'); /** * @param {string} base * @param {string} path */ export function resolve(base, path) { - if (SCHEME.test(path)) return path; - if (path[0] === '#') return base + path; + // special case + if (path[0] === '/' && path[1] === '/') return path; - const base_match = absolute.exec(base); - const path_match = absolute.exec(path); + let url = new URL(base, internal); + url = new URL(path, url); - if (!base_match) { - throw new Error(`bad base path: "${base}"`); - } - - const baseparts = path_match ? [] : base.slice(base_match[0].length).split('/'); - const pathparts = path_match ? path.slice(path_match[0].length).split('/') : path.split('/'); - - baseparts.pop(); - - for (let i = 0; i < pathparts.length; i += 1) { - const part = pathparts[i]; - if (part === '.') continue; - else if (part === '..') baseparts.pop(); - else baseparts.push(part); - } - - const prefix = (path_match && path_match[0]) || (base_match && base_match[0]) || ''; - - return `${prefix}${baseparts.join('/')}`; + return url.protocol === internal.protocol ? url.pathname + url.search + url.hash : url.href; } /** @param {string} path */ @@ -95,6 +77,14 @@ export function decode_uri(uri) { } } +/** + * Returns everything up to the first `#` in a URL + * @param {{href: string}} url_like + */ +export function strip_hash({ href }) { + return href.split('#')[0]; +} + /** * URL properties that could change during the lifetime of the page, * which excludes things like `origin` @@ -103,7 +93,6 @@ const tracked_url_properties = /** @type {const} */ ([ 'href', 'pathname', 'search', - 'searchParams', 'toString', 'toJSON' ]); @@ -111,10 +100,33 @@ const tracked_url_properties = /** @type {const} */ ([ /** * @param {URL} url * @param {() => void} callback + * @param {(search_param: string) => void} search_params_callback */ -export function make_trackable(url, callback) { +export function make_trackable(url, callback, search_params_callback) { const tracked = new URL(url); + Object.defineProperty(tracked, 'searchParams', { + value: new Proxy(tracked.searchParams, { + get(obj, key) { + if (key === 'get' || key === 'getAll' || key === 'has') { + return (/**@type {string}*/ param) => { + search_params_callback(param); + return obj[key](param); + }; + } + + // if they try to access something different from what is in `tracked_search_params_properties` + // we track the whole url (entries, values, keys etc) + callback(); + + const value = Reflect.get(obj, key); + return typeof value === 'function' ? value.bind(obj) : value; + } + }), + enumerable: true, + configurable: true + }); + for (const property of tracked_url_properties) { Object.defineProperty(tracked, property, { get() { @@ -185,18 +197,24 @@ function allow_nodejs_console_log(url) { } const DATA_SUFFIX = '/__data.json'; +const HTML_DATA_SUFFIX = '.html__data.json'; /** @param {string} pathname */ export function has_data_suffix(pathname) { - return pathname.endsWith(DATA_SUFFIX); + return pathname.endsWith(DATA_SUFFIX) || pathname.endsWith(HTML_DATA_SUFFIX); } /** @param {string} pathname */ export function add_data_suffix(pathname) { + if (pathname.endsWith('.html')) return pathname.replace(/\.html$/, HTML_DATA_SUFFIX); return pathname.replace(/\/$/, '') + DATA_SUFFIX; } /** @param {string} pathname */ export function strip_data_suffix(pathname) { + if (pathname.endsWith(HTML_DATA_SUFFIX)) { + return pathname.slice(0, -HTML_DATA_SUFFIX.length) + '.html'; + } + return pathname.slice(0, -DATA_SUFFIX.length); } diff --git a/packages/kit/src/utils/url.spec.js b/packages/kit/src/utils/url.spec.js index 166448227f2c..7de41b1e04d1 100644 --- a/packages/kit/src/utils/url.spec.js +++ b/packages/kit/src/utils/url.spec.js @@ -57,6 +57,14 @@ describe('resolve', (test) => { test('resolves data: urls', () => { assert.equal(resolve('/a/b/c', 'data:text/plain,hello'), 'data:text/plain,hello'); }); + + test('resolves empty string', () => { + assert.equal(resolve('/a/b/c', ''), '/a/b/c'); + }); + + test('resolves .', () => { + assert.equal(resolve('/a/b/c', '.'), '/a/b/'); + }); }); describe('normalize_path', (test) => { @@ -93,26 +101,62 @@ describe('normalize_path', (test) => { describe('make_trackable', (test) => { test('makes URL properties trackable', () => { let tracked = false; - - const url = make_trackable(new URL('https://kit.svelte.dev/docs'), () => { - tracked = true; - }); + const url = make_trackable( + new URL('https://kit.svelte.dev/docs'), + () => { + tracked = true; + }, + () => {} + ); url.origin; - assert.isNotOk(tracked); + assert.ok(!tracked); url.pathname; assert.ok(tracked); }); test('throws an error when its hash property is accessed', () => { - const url = make_trackable(new URL('https://kit.svelte.dev/docs'), () => {}); + const url = make_trackable( + new URL('https://kit.svelte.dev/docs'), + () => {}, + () => {} + ); assert.throws( () => url.hash, /Cannot access event.url.hash. Consider using `\$page.url.hash` inside a component instead/ ); }); + + test('track each search param separately if accessed directly', () => { + let tracked = false; + const tracked_search_params = new Set(); + const url = make_trackable( + new URL('https://kit.svelte.dev/docs'), + () => { + tracked = true; + }, + (search_param) => { + tracked_search_params.add(search_param); + } + ); + + url.searchParams.get('test'); + assert.ok(!tracked); + assert.ok(tracked_search_params.has('test')); + + url.searchParams.getAll('test-getall'); + assert.ok(!tracked); + assert.ok(tracked_search_params.has('test-getall')); + + url.searchParams.has('test-has'); + assert.ok(!tracked); + assert.ok(tracked_search_params.has('test-has')); + + url.searchParams.entries(); + assert.ok(tracked); + }); }); describe('disable_search', (test) => { diff --git a/packages/kit/test/apps/amp/package.json b/packages/kit/test/apps/amp/package.json index a1a6edbbfe3a..515dd98855f7 100644 --- a/packages/kit/test/apps/amp/package.json +++ b/packages/kit/test/apps/amp/package.json @@ -14,12 +14,13 @@ "devDependencies": { "@sveltejs/amp": "workspace:^", "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "cross-env": "^7.0.3", "dropcss": "^1.0.16", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/apps/basics/package.json b/packages/kit/test/apps/basics/package.json index 828aca08186d..4866372a0361 100644 --- a/packages/kit/test/apps/basics/package.json +++ b/packages/kit/test/apps/basics/package.json @@ -9,18 +9,19 @@ "check": "svelte-kit sync && tsc && svelte-check", "test": "node test/setup.js && pnpm test:dev && pnpm test:build", "test:dev": "node -e \"fs.rmSync('test/errors.json', { force: true })\" && cross-env DEV=true playwright test", - "test:build": "node -e \"fs.rmSync('test/errors.json', { force: true })\" && playwright test", + "test:build": "node -e \"fs.rmSync('test/errors.json', { force: true })\" && cross-env PUBLIC_PRERENDERING=false playwright test", "test:cross-platform:dev": "node test/setup.js && node -e \"fs.rmSync('test/errors.json', { force: true })\" && cross-env DEV=true playwright test test/cross-platform/", "test:cross-platform:build": "node test/setup.js && node -e \"fs.rmSync('test/errors.json', { force: true })\" && playwright test test/cross-platform/" }, "devDependencies": { "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "cross-env": "^7.0.3", - "marked": "^11.0.0", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "marked": "^11.1.0", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/apps/basics/playwright.config.js b/packages/kit/test/apps/basics/playwright.config.js index 33d36b651014..0f7c1458a513 100644 --- a/packages/kit/test/apps/basics/playwright.config.js +++ b/packages/kit/test/apps/basics/playwright.config.js @@ -1 +1,11 @@ -export { config as default } from '../../utils.js'; +import { config } from '../../utils.js'; + +export default { + ...config, + webServer: { + command: process.env.DEV + ? 'cross-env PUBLIC_PRERENDERING=false pnpm dev' + : 'cross-env PUBLIC_PRERENDERING=true pnpm build && pnpm preview', + port: process.env.DEV ? 5173 : 4173 + } +}; diff --git a/packages/kit/test/apps/basics/src/app.d.ts b/packages/kit/test/apps/basics/src/app.d.ts index adba879735d9..16bdf501b907 100644 --- a/packages/kit/test/apps/basics/src/app.d.ts +++ b/packages/kit/test/apps/basics/src/app.d.ts @@ -8,6 +8,10 @@ declare global { url?: URL; } + interface PageState { + active: boolean; + } + interface Platform {} } } diff --git a/packages/kit/test/apps/basics/src/hooks.client.js b/packages/kit/test/apps/basics/src/hooks.client.js index 2dbe1020af0a..8e18bf084c06 100644 --- a/packages/kit/test/apps/basics/src/hooks.client.js +++ b/packages/kit/test/apps/basics/src/hooks.client.js @@ -3,8 +3,8 @@ import { env } from '$env/dynamic/public'; window.PUBLIC_DYNAMIC = env.PUBLIC_DYNAMIC; /** @type{import("@sveltejs/kit").HandleClientError} */ -export function handleError({ error, event }) { +export function handleError({ error, event, status, message }) { return event.url.pathname.endsWith('404-fallback') ? undefined - : { message: /** @type {Error} */ (error).message }; + : { message: `${/** @type {Error} */ (error).message} (${status} ${message})` }; } diff --git a/packages/kit/test/apps/basics/src/hooks.server.js b/packages/kit/test/apps/basics/src/hooks.server.js index 46bac8eeaf56..1251601e35af 100644 --- a/packages/kit/test/apps/basics/src/hooks.server.js +++ b/packages/kit/test/apps/basics/src/hooks.server.js @@ -24,7 +24,7 @@ export function error_to_pojo(error) { } /** @type {import('@sveltejs/kit').HandleServerError} */ -export const handleError = ({ event, error: e }) => { +export const handleError = ({ event, error: e, status, message }) => { const error = /** @type {Error} */ (e); // TODO we do this because there's no other way (that i'm aware of) // to communicate errors back to the test suite. even if we could @@ -35,7 +35,10 @@ export const handleError = ({ event, error: e }) => { : {}; errors[event.url.pathname] = error_to_pojo(error); fs.writeFileSync('test/errors.json', JSON.stringify(errors)); - return event.url.pathname.endsWith('404-fallback') ? undefined : { message: error.message }; + + return event.url.pathname.endsWith('404-fallback') + ? undefined + : { message: `${error.message} (${status} ${message})` }; }; export const handle = sequence( @@ -74,9 +77,12 @@ export const handle = sequence( }, async ({ event, resolve }) => { if (event.url.pathname === '/cookies/serialize') { - event.cookies.set('before', 'before'); + event.cookies.set('before', 'before', { path: '' }); const response = await resolve(event); - response.headers.append('set-cookie', event.cookies.serialize('after', 'after')); + response.headers.append( + 'set-cookie', + event.cookies.serialize('after', 'after', { path: '' }) + ); return response; } return resolve(event); @@ -85,7 +91,7 @@ export const handle = sequence( if (event.url.pathname === '/errors/error-in-handle') { throw new Error('Error in handle'); } else if (event.url.pathname === '/errors/expected-error-in-handle') { - throw error(500, 'Expected error in handle'); + error(500, 'Expected error in handle'); } const response = await resolve(event, { @@ -105,10 +111,10 @@ export const handle = sequence( async ({ event, resolve }) => { if (event.url.pathname.includes('/redirect/in-handle')) { if (event.url.search === '?throw') { - throw redirect(307, event.url.origin + '/redirect/c'); + redirect(307, event.url.origin + '/redirect/c'); } else if (event.url.search.includes('cookies')) { event.cookies.delete(COOKIE_NAME, { path: '/cookies' }); - throw redirect(307, event.url.origin + '/cookies'); + redirect(307, event.url.origin + '/cookies'); } else { return new Response(undefined, { status: 307, headers: { location: '/redirect/c' } }); } @@ -125,7 +131,7 @@ export const handle = sequence( }, async ({ event, resolve }) => { if (event.url.pathname === '/actions/redirect-in-handle' && event.request.method === 'POST') { - throw redirect(303, '/actions/enhance'); + redirect(303, '/actions/enhance'); } return resolve(event); diff --git a/packages/kit/test/apps/basics/src/routes/+layout.server.js b/packages/kit/test/apps/basics/src/routes/+layout.server.js index 5700a931f816..50f99accae43 100644 --- a/packages/kit/test/apps/basics/src/routes/+layout.server.js +++ b/packages/kit/test/apps/basics/src/routes/+layout.server.js @@ -1,5 +1,4 @@ import { error, redirect } from '@sveltejs/kit'; -import { env } from '$env/dynamic/private'; import { SOME_JSON } from '$env/static/private'; // https://github.com/sveltejs/kit/issues/8646 @@ -7,10 +6,6 @@ if (JSON.parse(SOME_JSON).answer !== 42) { throw new Error('failed to parse env var'); } -if (JSON.parse(env.SOME_JSON).answer !== 42) { - throw new Error('failed to parse env var'); -} - /** @type {import('./$types').LayoutServerLoad} */ export async function load({ cookies, locals, fetch }) { if (locals.url?.pathname === '/non-existent-route') { @@ -25,11 +20,11 @@ export async function load({ cookies, locals, fetch }) { if (should_fail) { cookies.delete('fail-type', { path: '/' }); if (should_fail === 'expected') { - throw error(401, 'Not allowed'); + error(401, 'Not allowed'); } else if (should_fail === 'unexpected') { throw new Error('Failed to load'); } else { - throw redirect(307, '/load'); + redirect(307, '/load'); } } // Do NOT make this load function depend on something which would cause it to rerun diff --git a/packages/kit/test/apps/basics/src/routes/actions/enhance/+page.server.js b/packages/kit/test/apps/basics/src/routes/actions/enhance/+page.server.js index 5f0c4ad0025f..a88bd62cccb8 100644 --- a/packages/kit/test/apps/basics/src/routes/actions/enhance/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/actions/enhance/+page.server.js @@ -34,7 +34,7 @@ export const actions = { }; }, error: () => { - throw error(400, 'error'); + error(400, 'error'); }, echo: async ({ request }) => { const data = await request.formData(); diff --git a/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.server.js b/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.server.js deleted file mode 100644 index 4bdf1c67412b..000000000000 --- a/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.server.js +++ /dev/null @@ -1,26 +0,0 @@ -// TODO 2.0: Remove this code and corresponding tests -export const actions = { - form_submit: () => { - return { - form_submit: true - }; - }, - - form_callback: () => { - return { - form_callback: true - }; - }, - - data_submit: () => { - return { - data_submit: true - }; - }, - - data_callback: () => { - return { - data_callback: true - }; - } -}; diff --git a/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.svelte b/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.svelte deleted file mode 100644 index 1768c5d9dc7b..000000000000 --- a/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.svelte +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - -
- -
- -
- -
- -
- -
diff --git a/packages/kit/test/apps/basics/src/routes/actions/form-errors/adjacent-error-boundary/+page.server.js b/packages/kit/test/apps/basics/src/routes/actions/form-errors/adjacent-error-boundary/+page.server.js index 9d3149c3b6c4..1be2d0e1343b 100644 --- a/packages/kit/test/apps/basics/src/routes/actions/form-errors/adjacent-error-boundary/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/actions/form-errors/adjacent-error-boundary/+page.server.js @@ -2,6 +2,6 @@ import { error } from '@sveltejs/kit'; export const actions = { default: async () => { - throw error(502, 'something went wrong'); + error(502, 'something went wrong'); } }; diff --git a/packages/kit/test/apps/basics/src/routes/actions/redirect/+page.server.js b/packages/kit/test/apps/basics/src/routes/actions/redirect/+page.server.js index ff16ad14f254..9ca75b8f58ac 100644 --- a/packages/kit/test/apps/basics/src/routes/actions/redirect/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/actions/redirect/+page.server.js @@ -10,6 +10,6 @@ export function load() { /** @type {import('./$types').Actions} */ export const actions = { default: async () => { - throw redirect(303, '/actions/enhance'); + redirect(303, '/actions/enhance'); } }; diff --git a/packages/kit/test/apps/basics/src/routes/cookies/delete/+server.js b/packages/kit/test/apps/basics/src/routes/cookies/delete/+server.js index 2574d55aa990..42eb2bad89fa 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/delete/+server.js +++ b/packages/kit/test/apps/basics/src/routes/cookies/delete/+server.js @@ -3,6 +3,6 @@ import { COOKIE_NAME } from '../shared'; /** @type {import('@sveltejs/kit').RequestHandler} */ export const GET = (event) => { - event.cookies.delete(COOKIE_NAME); - throw redirect(303, '/cookies'); + event.cookies.delete(COOKIE_NAME, { path: '/cookies' }); + redirect(303, '/cookies'); }; diff --git a/packages/kit/test/apps/basics/src/routes/cookies/encoding/not-decoded-twice/+server.js b/packages/kit/test/apps/basics/src/routes/cookies/encoding/not-decoded-twice/+server.js index e63aae2fb2ac..7ab0d868be08 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/encoding/not-decoded-twice/+server.js +++ b/packages/kit/test/apps/basics/src/routes/cookies/encoding/not-decoded-twice/+server.js @@ -3,6 +3,6 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').RequestHandler} */ export const GET = (event) => { const sneaky = 'teapot%2C%20jane%20austen'; - event.cookies.set('encoding', sneaky); - throw redirect(303, '/cookies/encoding'); + event.cookies.set('encoding', sneaky, { path: '/cookies/encoding' }); + redirect(303, '/cookies/encoding'); }; diff --git a/packages/kit/test/apps/basics/src/routes/cookies/encoding/set/+server.js b/packages/kit/test/apps/basics/src/routes/cookies/encoding/set/+server.js index ebecc2e59f2b..141392352327 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/encoding/set/+server.js +++ b/packages/kit/test/apps/basics/src/routes/cookies/encoding/set/+server.js @@ -3,6 +3,6 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').RequestHandler} */ export const GET = (event) => { const needsEncoding = 'teapot, jane austen'; - event.cookies.set('encoding', needsEncoding); - throw redirect(303, '/cookies/encoding'); + event.cookies.set('encoding', needsEncoding, { path: '/cookies/encoding' }); + redirect(303, '/cookies/encoding'); }; diff --git a/packages/kit/test/apps/basics/src/routes/cookies/enhanced/basic/+page.server.ts b/packages/kit/test/apps/basics/src/routes/cookies/enhanced/basic/+page.server.ts index 2cc60352f57a..b86a80b5dac5 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/enhanced/basic/+page.server.ts +++ b/packages/kit/test/apps/basics/src/routes/cookies/enhanced/basic/+page.server.ts @@ -5,15 +5,15 @@ export const load: import('./$types').PageServerLoad = (event) => { export const actions: import('./$types').Actions = { setTeapot: (event) => { - event.cookies.set('a', 'teapot'); + event.cookies.set('a', 'teapot', { path: '' }); return { lastSet: new Date().valueOf() }; }, setJaneAusten: (event) => { - event.cookies.set('a', 'Jane Austen'); + event.cookies.set('a', 'Jane Austen', { path: '' }); return { lastSet: new Date().valueOf() }; }, delete: (event) => { - event.cookies.delete('a'); + event.cookies.delete('a', { path: '' }); return { lastSet: new Date().valueOf() }; } }; diff --git a/packages/kit/test/apps/basics/src/routes/cookies/forwarded-in-etag/+page.server.js b/packages/kit/test/apps/basics/src/routes/cookies/forwarded-in-etag/+page.server.js index 689539c43d9f..85161f1a5ba7 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/forwarded-in-etag/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/cookies/forwarded-in-etag/+page.server.js @@ -1,4 +1,4 @@ /** @type {import('./$types').PageServerLoad} */ export function load({ cookies }) { - cookies.set('foo', 'bar', { httpOnly: false }); + cookies.set('foo', 'bar', { path: '', httpOnly: false }); } diff --git a/packages/kit/test/apps/basics/src/routes/cookies/nested/a/+page.server.js b/packages/kit/test/apps/basics/src/routes/cookies/nested/a/+page.server.js index 70f20f3a724f..a7438b57bd4c 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/nested/a/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/cookies/nested/a/+page.server.js @@ -3,7 +3,7 @@ import { COOKIE_NAME } from '../../shared'; /** @type {import('./$types').PageServerLoad} */ export function load(event) { event.cookies.set(COOKIE_NAME, 'teapot', { - path: '/cookies/nested/a' + path: '' }); return { diff --git a/packages/kit/test/apps/basics/src/routes/cookies/serialize/+server.js b/packages/kit/test/apps/basics/src/routes/cookies/serialize/+server.js index f464598233e1..a95cd8b44285 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/serialize/+server.js +++ b/packages/kit/test/apps/basics/src/routes/cookies/serialize/+server.js @@ -3,6 +3,6 @@ export const GET = ({ cookies }) => { const response = new Response('success', { status: 200 }); - response.headers.append('set-cookie', cookies.serialize('endpoint', 'endpoint')); + response.headers.append('set-cookie', cookies.serialize('endpoint', 'endpoint', { path: '' })); return response; }; diff --git a/packages/kit/test/apps/basics/src/routes/cookies/set-in-layout/+layout.server.js b/packages/kit/test/apps/basics/src/routes/cookies/set-in-layout/+layout.server.js index f29549c28803..a020962745f6 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/set-in-layout/+layout.server.js +++ b/packages/kit/test/apps/basics/src/routes/cookies/set-in-layout/+layout.server.js @@ -1,4 +1,4 @@ /** @type {import('./$types').LayoutServerLoad} */ export function load(event) { - event.cookies.set('a', 'i was set in the layout load'); + event.cookies.set('a', 'i was set in the layout load', { path: '' }); } diff --git a/packages/kit/test/apps/basics/src/routes/cookies/set-more-than-one/+page.server.js b/packages/kit/test/apps/basics/src/routes/cookies/set-more-than-one/+page.server.js index 8c5360c699e6..68652a350104 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/set-more-than-one/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/cookies/set-more-than-one/+page.server.js @@ -1,7 +1,7 @@ /** @type {import('./$types').PageServerLoad} */ export function load(event) { - event.cookies.set('a', 'teapot'); - event.cookies.set('b', 'jane austen'); + event.cookies.set('a', 'teapot', { path: '' }); + event.cookies.set('b', 'jane austen', { path: '' }); return { a: event.cookies.get('a'), diff --git a/packages/kit/test/apps/basics/src/routes/cookies/set/+server.js b/packages/kit/test/apps/basics/src/routes/cookies/set/+server.js index 978b0e44e50f..e0c47ee1b87f 100644 --- a/packages/kit/test/apps/basics/src/routes/cookies/set/+server.js +++ b/packages/kit/test/apps/basics/src/routes/cookies/set/+server.js @@ -3,6 +3,6 @@ import { COOKIE_NAME } from '../shared'; /** @type {import('@sveltejs/kit').RequestHandler} */ export const GET = (event) => { - event.cookies.set(COOKIE_NAME, 'teapot'); - throw redirect(303, '/cookies'); + event.cookies.set(COOKIE_NAME, 'teapot', { path: '/cookies' }); + redirect(303, '/cookies'); }; diff --git a/packages/kit/test/apps/basics/src/routes/encoded/redirect/+page.js b/packages/kit/test/apps/basics/src/routes/encoded/redirect/+page.js index aa5d615b50e3..567da058a575 100644 --- a/packages/kit/test/apps/basics/src/routes/encoded/redirect/+page.js +++ b/packages/kit/test/apps/basics/src/routes/encoded/redirect/+page.js @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').Load} */ export function load() { - throw redirect(307, 'redirected?embedded=' + encodeURIComponent('/苗条?foo=bar&fizz=buzz')); + redirect(307, 'redirected?embedded=' + encodeURIComponent('/苗条?foo=bar&fizz=buzz')); } diff --git "a/packages/kit/test/apps/basics/src/routes/encoded/\345\217\215\345\272\224/+page.js" "b/packages/kit/test/apps/basics/src/routes/encoded/\345\217\215\345\272\224/+page.js" index 9a25d2560422..3268b6907cce 100644 --- "a/packages/kit/test/apps/basics/src/routes/encoded/\345\217\215\345\272\224/+page.js" +++ "b/packages/kit/test/apps/basics/src/routes/encoded/\345\217\215\345\272\224/+page.js" @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(307, encodeURI('苗条')); + redirect(307, encodeURI('苗条')); } diff --git a/packages/kit/test/apps/basics/src/routes/errors/+layout.js b/packages/kit/test/apps/basics/src/routes/errors/+layout.js index db7cc564dfbc..d23658f5d50d 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/+layout.js +++ b/packages/kit/test/apps/basics/src/routes/errors/+layout.js @@ -4,6 +4,6 @@ import { error } from '@sveltejs/kit'; export async function load({ fetch, url }) { if (url.pathname.startsWith('/errors/error-in-layout')) { const res = await fetch('/errors/error-in-layout/non-existent'); - throw error(res.status); + error(/** @type {404} */ (res.status)); } } diff --git a/packages/kit/test/apps/basics/src/routes/errors/endpoint-shadow-not-ok/+page.server.js b/packages/kit/test/apps/basics/src/routes/errors/endpoint-shadow-not-ok/+page.server.js index f66073b49cb3..ff584cb29bc4 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/endpoint-shadow-not-ok/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/errors/endpoint-shadow-not-ok/+page.server.js @@ -2,5 +2,5 @@ import { error } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').RequestHandler} */ export function load() { - throw error(555, undefined); + error(555, undefined); } diff --git a/packages/kit/test/apps/basics/src/routes/errors/endpoint-throw-error/+server.js b/packages/kit/test/apps/basics/src/routes/errors/endpoint-throw-error/+server.js index 14c9aec1c9bb..38540b4735c3 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/endpoint-throw-error/+server.js +++ b/packages/kit/test/apps/basics/src/routes/errors/endpoint-throw-error/+server.js @@ -1,5 +1,5 @@ import { error } from '@sveltejs/kit'; export function GET() { - throw error(401, 'You shall not pass'); + error(401, 'You shall not pass'); } diff --git a/packages/kit/test/apps/basics/src/routes/errors/endpoint-throw-redirect/+server.js b/packages/kit/test/apps/basics/src/routes/errors/endpoint-throw-redirect/+server.js index 26300742e98d..bf4c9c1ad980 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/endpoint-throw-redirect/+server.js +++ b/packages/kit/test/apps/basics/src/routes/errors/endpoint-throw-redirect/+server.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function GET() { - throw redirect(302, '/'); + redirect(302, '/'); } diff --git a/packages/kit/test/apps/basics/src/routes/errors/load-error-client/+page.js b/packages/kit/test/apps/basics/src/routes/errors/load-error-client/+page.js index 9f6c87d99ce5..bb1908d9166e 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/load-error-client/+page.js +++ b/packages/kit/test/apps/basics/src/routes/errors/load-error-client/+page.js @@ -3,7 +3,7 @@ import { error } from '@sveltejs/kit'; /** @type {import('./$types').PageLoad} */ export async function load() { if (typeof window !== 'undefined') { - throw error(555, 'Not found'); + error(555, 'Not found'); } return {}; diff --git a/packages/kit/test/apps/basics/src/routes/errors/load-error-server/+page.js b/packages/kit/test/apps/basics/src/routes/errors/load-error-server/+page.js index f27960c3bdec..f505c6c5b046 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/load-error-server/+page.js +++ b/packages/kit/test/apps/basics/src/routes/errors/load-error-server/+page.js @@ -2,5 +2,5 @@ import { error } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').Load} */ export async function load() { - throw error(555, 'Not found'); + error(555, 'Not found'); } diff --git a/packages/kit/test/apps/basics/src/routes/errors/load-error-string-server/+page.js b/packages/kit/test/apps/basics/src/routes/errors/load-error-string-server/+page.js index f27960c3bdec..f505c6c5b046 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/load-error-string-server/+page.js +++ b/packages/kit/test/apps/basics/src/routes/errors/load-error-string-server/+page.js @@ -2,5 +2,5 @@ import { error } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').Load} */ export async function load() { - throw error(555, 'Not found'); + error(555, 'Not found'); } diff --git a/packages/kit/test/apps/basics/src/routes/errors/load-status-without-error-client/+page.js b/packages/kit/test/apps/basics/src/routes/errors/load-status-without-error-client/+page.js index e426984dc01d..14939a4c1092 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/load-status-without-error-client/+page.js +++ b/packages/kit/test/apps/basics/src/routes/errors/load-status-without-error-client/+page.js @@ -2,7 +2,7 @@ import { error } from '@sveltejs/kit'; export async function load() { if (typeof window !== 'undefined') { - throw error(401, undefined); + error(401, undefined); } return {}; } diff --git a/packages/kit/test/apps/basics/src/routes/errors/page-endpoint/get-explicit/+page.server.js b/packages/kit/test/apps/basics/src/routes/errors/page-endpoint/get-explicit/+page.server.js index 0a14dc8ba094..768ea1d4975e 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/page-endpoint/get-explicit/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/errors/page-endpoint/get-explicit/+page.server.js @@ -1,5 +1,5 @@ import { error } from '@sveltejs/kit'; export const load = () => { - throw error(400, 'oops'); + error(400, 'oops'); }; diff --git a/packages/kit/test/apps/basics/src/routes/errors/page-endpoint/post-explicit/+page.server.js b/packages/kit/test/apps/basics/src/routes/errors/page-endpoint/post-explicit/+page.server.js index 56ccc82ff691..e6a788cecea6 100644 --- a/packages/kit/test/apps/basics/src/routes/errors/page-endpoint/post-explicit/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/errors/page-endpoint/post-explicit/+page.server.js @@ -3,6 +3,6 @@ import { error } from '@sveltejs/kit'; /** @type {import('./$types').Actions} */ export const actions = { default: () => { - throw error(400, 'oops'); + error(400, 'oops'); } }; diff --git a/packages/kit/test/apps/basics/src/routes/goto/+page.svelte b/packages/kit/test/apps/basics/src/routes/goto/+page.svelte new file mode 100644 index 000000000000..a3920c936119 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/goto/+page.svelte @@ -0,0 +1,17 @@ + + + + +

{message}

diff --git a/packages/kit/test/apps/basics/src/routes/headers/set-cookie/+layout.server.js b/packages/kit/test/apps/basics/src/routes/headers/set-cookie/+layout.server.js index 1c73347b4d50..10b1b6da3f9f 100644 --- a/packages/kit/test/apps/basics/src/routes/headers/set-cookie/+layout.server.js +++ b/packages/kit/test/apps/basics/src/routes/headers/set-cookie/+layout.server.js @@ -1,6 +1,7 @@ /** @type {import('./$types').LayoutServerLoad} */ export function load({ cookies }) { cookies.set('cookie1', 'value1', { + path: '/headers/set-cookie', secure: false // safari }); } diff --git a/packages/kit/test/apps/basics/src/routes/headers/set-cookie/sub/+page.server.js b/packages/kit/test/apps/basics/src/routes/headers/set-cookie/sub/+page.server.js index ef3b8838b86e..3e69d5a89d07 100644 --- a/packages/kit/test/apps/basics/src/routes/headers/set-cookie/sub/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/headers/set-cookie/sub/+page.server.js @@ -1,6 +1,7 @@ /** @type {import('./$types').PageServerLoad} */ export function load({ cookies }) { cookies.set('cookie2', 'value2', { + path: '', secure: false // safari }); } diff --git a/packages/kit/test/apps/basics/src/routes/load/fetch-arraybuffer-b64/+page.js b/packages/kit/test/apps/basics/src/routes/load/fetch-arraybuffer-b64/+page.js index 2549f6bace21..831c029e4781 100644 --- a/packages/kit/test/apps/basics/src/routes/load/fetch-arraybuffer-b64/+page.js +++ b/packages/kit/test/apps/basics/src/routes/load/fetch-arraybuffer-b64/+page.js @@ -7,7 +7,7 @@ export async function load({ fetch }) { }); return { - data: res.arrayBuffer(), - data_long: l.arrayBuffer() + data: await res.arrayBuffer(), + data_long: await l.arrayBuffer() }; } diff --git a/packages/kit/test/apps/basics/src/routes/load/fetch-cache-control/headers-diff/+page.js b/packages/kit/test/apps/basics/src/routes/load/fetch-cache-control/headers-diff/+page.js index b64c9e0a9a68..2122574cd578 100644 --- a/packages/kit/test/apps/basics/src/routes/load/fetch-cache-control/headers-diff/+page.js +++ b/packages/kit/test/apps/basics/src/routes/load/fetch-cache-control/headers-diff/+page.js @@ -3,16 +3,16 @@ export async function load({ fetch, url }) { headers: { 'x-foo': 'a' } - }); + }).then((r) => r.json()); const r2 = await fetch(url.pathname, { headers: { 'x-foo': 'b' } - }); + }).then((r) => r.json()); return { - a: r1.json(), - b: r2.json() + a: r1, + b: r2 }; } diff --git a/packages/kit/test/apps/basics/src/routes/load/invalidation/depends/+page.svelte b/packages/kit/test/apps/basics/src/routes/load/invalidation/depends/+page.svelte index e402d30d518c..b92e5839767e 100644 --- a/packages/kit/test/apps/basics/src/routes/load/invalidation/depends/+page.svelte +++ b/packages/kit/test/apps/basics/src/routes/load/invalidation/depends/+page.svelte @@ -22,3 +22,12 @@ > invalidate server + +

neither

+ diff --git a/packages/kit/test/apps/basics/src/routes/load/invalidation/multiple/+layout.js b/packages/kit/test/apps/basics/src/routes/load/invalidation/multiple/+layout.js index 612afdb02405..e2c7823abfd1 100644 --- a/packages/kit/test/apps/basics/src/routes/load/invalidation/multiple/+layout.js +++ b/packages/kit/test/apps/basics/src/routes/load/invalidation/multiple/+layout.js @@ -8,7 +8,7 @@ export function load({ depends }) { if (get(redirect_state) === 'running') { redirect_state.set('done'); - throw redirect(307, '/load/invalidation/multiple/redirect'); + redirect(307, '/load/invalidation/multiple/redirect'); } return new Promise((resolve) => diff --git a/packages/kit/test/apps/basics/src/routes/load/invalidation/multiple/redirect/+page.js b/packages/kit/test/apps/basics/src/routes/load/invalidation/multiple/redirect/+page.js index db2ffca2ab6a..24c97cb70a7c 100644 --- a/packages/kit/test/apps/basics/src/routes/load/invalidation/multiple/redirect/+page.js +++ b/packages/kit/test/apps/basics/src/routes/load/invalidation/multiple/redirect/+page.js @@ -6,7 +6,7 @@ export async function load({ parent }) { const { redirect_mode } = await parent(); if (redirect_mode === 'start') { redirect_state.set('running'); - throw redirect(307, '/load/invalidation/multiple'); + redirect(307, '/load/invalidation/multiple'); } if (redirect_mode === 'running') { throw new Error('Shouldnt get redirected here with state "running"'); diff --git a/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/server/+page.server.js b/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/server/+page.server.js new file mode 100644 index 000000000000..8d4b3444d839 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/server/+page.server.js @@ -0,0 +1,8 @@ +let count = 0; + +export function load({ url }) { + url.searchParams.get('a'); + return { + count: count++ + }; +} diff --git a/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/server/+page.svelte b/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/server/+page.svelte new file mode 100644 index 000000000000..4ec557e316f1 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/server/+page.svelte @@ -0,0 +1,8 @@ + + +count: {data.count} + +
Change tracked parameter +Change untracked parameter diff --git a/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/universal/+page.js b/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/universal/+page.js new file mode 100644 index 000000000000..8d4b3444d839 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/universal/+page.js @@ -0,0 +1,8 @@ +let count = 0; + +export function load({ url }) { + url.searchParams.get('a'); + return { + count: count++ + }; +} diff --git a/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/universal/+page.svelte b/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/universal/+page.svelte new file mode 100644 index 000000000000..4ec557e316f1 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/load/invalidation/search-params/universal/+page.svelte @@ -0,0 +1,8 @@ + + +count: {data.count} + +Change tracked parameter +Change untracked parameter diff --git a/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/redirect/+page.js b/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/redirect/+page.js index 80f189a06a13..0662014015a7 100644 --- a/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/redirect/+page.js +++ b/packages/kit/test/apps/basics/src/routes/navigation-lifecycle/before-navigate/redirect/+page.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(307, '/navigation-lifecycle/before-navigate/prevent-navigation'); + redirect(307, '/navigation-lifecycle/before-navigate/prevent-navigation'); } diff --git a/packages/kit/test/apps/basics/src/routes/nested-layout/error/+page.js b/packages/kit/test/apps/basics/src/routes/nested-layout/error/+page.js index 9b17193d01e2..ca2552691b9f 100644 --- a/packages/kit/test/apps/basics/src/routes/nested-layout/error/+page.js +++ b/packages/kit/test/apps/basics/src/routes/nested-layout/error/+page.js @@ -1,5 +1,5 @@ import { error } from '@sveltejs/kit'; export function load() { - throw error(500, 'Error'); + error(500, 'Error'); } diff --git a/packages/kit/test/apps/basics/src/routes/prerendering/env/+layout.svelte b/packages/kit/test/apps/basics/src/routes/prerendering/env/+layout.svelte new file mode 100644 index 000000000000..9fd745e3ba79 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/prerendering/env/+layout.svelte @@ -0,0 +1,4 @@ +prerendered +dynamic + + diff --git a/packages/kit/test/apps/basics/src/routes/prerendering/env/dynamic/+page.svelte b/packages/kit/test/apps/basics/src/routes/prerendering/env/dynamic/+page.svelte new file mode 100644 index 000000000000..c0db5dfb5fcb --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/prerendering/env/dynamic/+page.svelte @@ -0,0 +1,5 @@ + + +

prerendering: {env.PUBLIC_PRERENDERING}

diff --git a/packages/kit/test/apps/basics/src/routes/prerendering/env/prerendered/+page.js b/packages/kit/test/apps/basics/src/routes/prerendering/env/prerendered/+page.js new file mode 100644 index 000000000000..189f71e2e1b3 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/prerendering/env/prerendered/+page.js @@ -0,0 +1 @@ +export const prerender = true; diff --git a/packages/kit/test/apps/basics/src/routes/prerendering/env/prerendered/+page.svelte b/packages/kit/test/apps/basics/src/routes/prerendering/env/prerendered/+page.svelte new file mode 100644 index 000000000000..34c62bbc7ead --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/prerendering/env/prerendered/+page.svelte @@ -0,0 +1 @@ +

prerendered

diff --git a/packages/kit/test/apps/basics/src/routes/redirect-on-load/+page.js b/packages/kit/test/apps/basics/src/routes/redirect-on-load/+page.js index be5f4e07fe3c..4250fc057d70 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect-on-load/+page.js +++ b/packages/kit/test/apps/basics/src/routes/redirect-on-load/+page.js @@ -3,7 +3,7 @@ import { browser } from '$app/environment'; export async function load() { if (browser) { - throw redirect(303, '/redirect-on-load/redirected'); + redirect(303, '/redirect-on-load/redirected'); } return {}; diff --git a/packages/kit/test/apps/basics/src/routes/redirect/+page.svelte b/packages/kit/test/apps/basics/src/routes/redirect/+page.svelte index 852940e4edd0..8d0e61c5fd20 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect/+page.svelte +++ b/packages/kit/test/apps/basics/src/routes/redirect/+page.svelte @@ -8,5 +8,5 @@ a (missing-status) b (missing-status) -in-handle (throw redirect) +in-handle (redirect) in-handle (return Response) diff --git a/packages/kit/test/apps/basics/src/routes/redirect/a/+page.js b/packages/kit/test/apps/basics/src/routes/redirect/a/+page.js index 93aaf22b311b..781ea8d637a3 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect/a/+page.js +++ b/packages/kit/test/apps/basics/src/routes/redirect/a/+page.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(307, './b'); + redirect(307, './b'); } diff --git a/packages/kit/test/apps/basics/src/routes/redirect/b/+page.js b/packages/kit/test/apps/basics/src/routes/redirect/b/+page.js index 169eb727728a..4c538468d877 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect/b/+page.js +++ b/packages/kit/test/apps/basics/src/routes/redirect/b/+page.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(307, './c'); + redirect(307, './c'); } diff --git a/packages/kit/test/apps/basics/src/routes/redirect/loopy/a/+page.js b/packages/kit/test/apps/basics/src/routes/redirect/loopy/a/+page.js index 93aaf22b311b..781ea8d637a3 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect/loopy/a/+page.js +++ b/packages/kit/test/apps/basics/src/routes/redirect/loopy/a/+page.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(307, './b'); + redirect(307, './b'); } diff --git a/packages/kit/test/apps/basics/src/routes/redirect/loopy/b/+page.js b/packages/kit/test/apps/basics/src/routes/redirect/loopy/b/+page.js index 98098bf9a4ea..8f2ac56ec09f 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect/loopy/b/+page.js +++ b/packages/kit/test/apps/basics/src/routes/redirect/loopy/b/+page.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(307, './a'); + redirect(307, './a'); } diff --git a/packages/kit/test/apps/basics/src/routes/redirect/missing-status/a/+page.js b/packages/kit/test/apps/basics/src/routes/redirect/missing-status/a/+page.js index 42f945943124..628fd7006813 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect/missing-status/a/+page.js +++ b/packages/kit/test/apps/basics/src/routes/redirect/missing-status/a/+page.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(undefined, './b'); + redirect(undefined, './b'); } diff --git a/packages/kit/test/apps/basics/src/routes/redirect/missing-status/b/+page.js b/packages/kit/test/apps/basics/src/routes/redirect/missing-status/b/+page.js index c269fa152b86..9b59ac48da13 100644 --- a/packages/kit/test/apps/basics/src/routes/redirect/missing-status/b/+page.js +++ b/packages/kit/test/apps/basics/src/routes/redirect/missing-status/b/+page.js @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { // @ts-ignore - throw redirect(555, './a'); + redirect(555, './a'); } diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/error-get/+page.server.js b/packages/kit/test/apps/basics/src/routes/shadowed/error-get/+page.server.js index 1ebbb83f57e6..203870704533 100644 --- a/packages/kit/test/apps/basics/src/routes/shadowed/error-get/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/shadowed/error-get/+page.server.js @@ -1,5 +1,5 @@ import { error } from '@sveltejs/kit'; export function load() { - throw error(404, undefined); + error(404, undefined); } diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/post-success-redirect/+page.server.js b/packages/kit/test/apps/basics/src/routes/shadowed/post-success-redirect/+page.server.js index ac6e97a468fc..261d9a4f6a4d 100644 --- a/packages/kit/test/apps/basics/src/routes/shadowed/post-success-redirect/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/shadowed/post-success-redirect/+page.server.js @@ -3,6 +3,6 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('./$types').Actions} */ export const actions = { default: () => { - throw redirect(303, '/shadowed/post-success-redirect/redirected'); + redirect(303, '/shadowed/post-success-redirect/redirected'); } }; diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get-with-cookie-from-fetch/+page.js b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get-with-cookie-from-fetch/+page.js index dfb3dfaa80e8..d992059c0a16 100644 --- a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get-with-cookie-from-fetch/+page.js +++ b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get-with-cookie-from-fetch/+page.js @@ -3,5 +3,5 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('./$types').PageLoad} */ export async function load({ fetch }) { await fetch('/shadowed/redirect-get-with-cookie-from-fetch/endpoint'); - throw redirect(302, '/shadowed/redirected'); + redirect(302, '/shadowed/redirected'); } diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get-with-cookie/+page.server.js b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get-with-cookie/+page.server.js index 77fe8c5c73fe..1d3f08199337 100644 --- a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get-with-cookie/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get-with-cookie/+page.server.js @@ -3,7 +3,8 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('./$types').PageServerLoad} */ export function load({ cookies }) { cookies.set('shadow-redirect', 'happy', { + path: '/shadowed', secure: false // safari }); - throw redirect(302, '/shadowed/redirected'); + redirect(302, '/shadowed/redirected'); } diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get/+page.server.js b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get/+page.server.js index 2da446ff6757..2378f53f0b5f 100644 --- a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-get/+page.server.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(302, '/shadowed/redirected'); + redirect(302, '/shadowed/redirected'); } diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-post-with-cookie/+page.server.js b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-post-with-cookie/+page.server.js index 3c612ddf1247..945ca55acb0e 100644 --- a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-post-with-cookie/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-post-with-cookie/+page.server.js @@ -4,8 +4,9 @@ import { redirect } from '@sveltejs/kit'; export const actions = { default: ({ cookies }) => { cookies.set('shadow-redirect', 'happy', { + path: '/shadowed', secure: false // safari }); - throw redirect(302, '/shadowed/redirected'); + redirect(302, '/shadowed/redirected'); } }; diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-post/+page.server.js b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-post/+page.server.js index c152db3348d3..beabd8c0e14a 100644 --- a/packages/kit/test/apps/basics/src/routes/shadowed/redirect-post/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/shadowed/redirect-post/+page.server.js @@ -3,6 +3,6 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('./$types').Actions} */ export const actions = { default: () => { - throw redirect(302, '/shadowed/redirected'); + redirect(302, '/shadowed/redirected'); } }; diff --git a/packages/kit/test/apps/basics/src/routes/shadowed/redirect/[a]/+page.server.js b/packages/kit/test/apps/basics/src/routes/shadowed/redirect/[a]/+page.server.js index fd1bb2c6a44f..da2f737b97e3 100644 --- a/packages/kit/test/apps/basics/src/routes/shadowed/redirect/[a]/+page.server.js +++ b/packages/kit/test/apps/basics/src/routes/shadowed/redirect/[a]/+page.server.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(302, '/shadowed/redirect/b'); + redirect(302, '/shadowed/redirect/b'); } diff --git a/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/+layout.svelte b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/+layout.svelte new file mode 100644 index 000000000000..28de28c4ab08 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/+layout.svelte @@ -0,0 +1,5 @@ +push-state +a +b + + diff --git a/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/+page.js b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/+page.js new file mode 100644 index 000000000000..e05ece04e7cd --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/+page.js @@ -0,0 +1,5 @@ +export function load() { + return { + now: Date.now() + }; +} diff --git a/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/+page.svelte b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/+page.svelte new file mode 100644 index 000000000000..40c616c3b2a5 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/+page.svelte @@ -0,0 +1,23 @@ + + +

parent

+ + + + + +

active: {$page.state.active ?? false}

+{data.now} diff --git a/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/a/+page.svelte b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/a/+page.svelte new file mode 100644 index 000000000000..3be7397f2aca --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/a/+page.svelte @@ -0,0 +1,7 @@ + + +

a

+ +

active: {$page.state.active ?? false}

diff --git a/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/b/+page.svelte b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/b/+page.svelte new file mode 100644 index 000000000000..30c06a44b409 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/shallow-routing/push-state/b/+page.svelte @@ -0,0 +1,7 @@ + + +

b

+ +

active: {$page.state.active ?? false}

diff --git a/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/+layout.svelte b/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/+layout.svelte new file mode 100644 index 000000000000..7e6089f7721f --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/+layout.svelte @@ -0,0 +1,5 @@ +replace-state +a +b + + diff --git a/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/+page.svelte b/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/+page.svelte new file mode 100644 index 000000000000..a19674234665 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/+page.svelte @@ -0,0 +1,19 @@ + + +

parent

+ + + + +

active: {$page.state.active ?? false}

diff --git a/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/a/+page.svelte b/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/a/+page.svelte new file mode 100644 index 000000000000..3be7397f2aca --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/a/+page.svelte @@ -0,0 +1,7 @@ + + +

a

+ +

active: {$page.state.active ?? false}

diff --git a/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/b/+page.svelte b/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/b/+page.svelte new file mode 100644 index 000000000000..30c06a44b409 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/shallow-routing/replace-state/b/+page.svelte @@ -0,0 +1,7 @@ + + +

b

+ +

active: {$page.state.active ?? false}

diff --git a/packages/kit/test/apps/basics/src/routes/store/data/[item]/+page.js b/packages/kit/test/apps/basics/src/routes/store/data/[item]/+page.js index fd39f31849ab..492e40233922 100644 --- a/packages/kit/test/apps/basics/src/routes/store/data/[item]/+page.js +++ b/packages/kit/test/apps/basics/src/routes/store/data/[item]/+page.js @@ -3,11 +3,11 @@ import { error } from '@sveltejs/kit'; /** @type {import('./$types').PageLoad} */ export function load({ params }) { if (params.item === 'xxx') { - throw error(500, 'Params = xxx'); + error(500, 'Params = xxx'); } if (params.item === 'yyy') { - throw error(500, 'Params = yyy'); + error(500, 'Params = yyy'); } return { diff --git a/packages/kit/test/apps/basics/src/routes/untrack/server/+layout.server.js b/packages/kit/test/apps/basics/src/routes/untrack/server/+layout.server.js new file mode 100644 index 000000000000..96084b5f4c27 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/untrack/server/+layout.server.js @@ -0,0 +1,5 @@ +export function load({ url }) { + return { + url: url.pathname + }; +} diff --git a/packages/kit/test/apps/basics/src/routes/untrack/server/[x]/+page.server.js b/packages/kit/test/apps/basics/src/routes/untrack/server/[x]/+page.server.js new file mode 100644 index 000000000000..b4ffba554340 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/untrack/server/[x]/+page.server.js @@ -0,0 +1,12 @@ +export function load({ params, parent, url, untrack }) { + untrack(() => { + params.x; + parent(); + url.pathname; + url.search; + }); + + return { + id: Math.random() + }; +} diff --git a/packages/kit/test/apps/basics/src/routes/untrack/server/[x]/+page.svelte b/packages/kit/test/apps/basics/src/routes/untrack/server/[x]/+page.svelte new file mode 100644 index 000000000000..b14eaf830616 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/untrack/server/[x]/+page.svelte @@ -0,0 +1,7 @@ + + +

{data.url}

+

{data.id}

+2 diff --git a/packages/kit/test/apps/basics/src/routes/untrack/universal/+layout.js b/packages/kit/test/apps/basics/src/routes/untrack/universal/+layout.js new file mode 100644 index 000000000000..96084b5f4c27 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/untrack/universal/+layout.js @@ -0,0 +1,5 @@ +export function load({ url }) { + return { + url: url.pathname + }; +} diff --git a/packages/kit/test/apps/basics/src/routes/untrack/universal/[x]/+page.js b/packages/kit/test/apps/basics/src/routes/untrack/universal/[x]/+page.js new file mode 100644 index 000000000000..b4ffba554340 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/untrack/universal/[x]/+page.js @@ -0,0 +1,12 @@ +export function load({ params, parent, url, untrack }) { + untrack(() => { + params.x; + parent(); + url.pathname; + url.search; + }); + + return { + id: Math.random() + }; +} diff --git a/packages/kit/test/apps/basics/src/routes/untrack/universal/[x]/+page.svelte b/packages/kit/test/apps/basics/src/routes/untrack/universal/[x]/+page.svelte new file mode 100644 index 000000000000..f91394c6160b --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/untrack/universal/[x]/+page.svelte @@ -0,0 +1,7 @@ + + +

{data.url}

+

{data.id}

+2 diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js index b10006c34436..fdf76661f67e 100644 --- a/packages/kit/test/apps/basics/test/client.test.js +++ b/packages/kit/test/apps/basics/test/client.test.js @@ -83,7 +83,7 @@ test.describe('Load', () => { test('accessing url.hash from load errors and suggests using page store', async ({ page }) => { await page.goto('/load/url-hash#please-dont-send-me-to-load'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Cannot access event.url.hash. Consider using `$page.url.hash` inside a component instead"' + 'This is your custom error page saying: "Cannot access event.url.hash. Consider using `$page.url.hash` inside a component instead (500 Internal Error)"' ); }); @@ -339,7 +339,7 @@ test.describe('SPA mode / no SSR', () => { }) => { await page.goto('/no-ssr/ssr-page-config/layout/overwrite'); await expect(page.locator('p')).toHaveText( - 'This is your custom error page saying: "document is not defined"' + 'This is your custom error page saying: "document is not defined (500 Internal Error)"' ); }); }); @@ -413,6 +413,30 @@ test.describe('Invalidation', () => { expect(await page.textContent('h1')).toBe('3'); }); + test('load function only re-runs when tracked searchParams change (universal)', async ({ + page, + clicknav + }) => { + await page.goto('/load/invalidation/search-params/universal?tracked=0'); + expect(await page.textContent('span')).toBe('count: 0'); + await clicknav('[data-id="tracked"]'); + expect(await page.textContent('span')).toBe('count: 1'); + await clicknav('[data-id="untracked"]'); + expect(await page.textContent('span')).toBe('count: 1'); + }); + + test('load function only re-runs when tracked searchParams change (server)', async ({ + page, + clicknav + }) => { + await page.goto('/load/invalidation/search-params/server?tracked=0'); + expect(await page.textContent('span')).toBe('count: 0'); + await clicknav('[data-id="tracked"]'); + expect(await page.textContent('span')).toBe('count: 1'); + await clicknav('[data-id="untracked"]'); + expect(await page.textContent('span')).toBe('count: 1'); + }); + test('server-only load functions are re-run following forced invalidation', async ({ page }) => { await page.goto('/load/invalidation/forced'); expect(await page.textContent('h1')).toBe('a: 0, b: 1'); @@ -480,10 +504,16 @@ test.describe('Invalidation', () => { const next_shared = await page.textContent('p.shared'); expect(server).not.toBe(next_server); expect(shared).not.toBe(next_shared); + + await page.click('button.neither'); + await page.evaluate(() => window.promise); + expect(await page.textContent('p.server')).toBe(next_server); + expect(await page.textContent('p.shared')).toBe(next_shared); }); test('fetch in server load cannot be invalidated', async ({ page, app, request }) => { - // TODO 2.0: Can remove this test after `dangerZone.trackServerFetches` and associated code is removed + // legacy behavior was to track server dependencies -- this could leak secrets to the client (see github.com/sveltejs/kit/pull/9945) + // we keep this test just to make sure the behavior stays the same. await request.get('/load/invalidation/server-fetch/count.json?reset'); await page.goto('/load/invalidation/server-fetch'); const selector = '[data-testid="count"]'; @@ -506,6 +536,11 @@ test.describe('Invalidation', () => { const next_shared = await page.textContent('p.shared'); expect(server).toBe(next_server); expect(shared).not.toBe(next_shared); + + await page.click('button.neither'); + await page.evaluate(() => window.promise); + expect(await page.textContent('p.server')).toBe(next_server); + expect(await page.textContent('p.shared')).toBe(next_shared); }); test('Parameter use is tracked even for routes that do not use the parameters', async ({ @@ -701,6 +736,15 @@ test.describe('env', () => { 'accessible anywhere/evaluated at run time' ); }); + + test('uses correct dynamic env when navigating from prerendered page', async ({ + page, + clicknav + }) => { + await page.goto('/prerendering/env/prerendered'); + await clicknav('[href="/prerendering/env/dynamic"]'); + expect(await page.locator('h2')).toHaveText('prerendering: false'); + }); }); test.describe('Snapshots', () => { @@ -756,7 +800,9 @@ test.describe('Streaming', () => { expect(page.locator('p.loadingfail')).toBeVisible(); await expect(page.locator('p.success', { timeout: 15000 })).toHaveText('success'); - await expect(page.locator('p.fail', { timeout: 15000 })).toHaveText('fail'); + await expect(page.locator('p.fail', { timeout: 15000 })).toHaveText( + 'fail (500 Internal Error)' + ); expect(page.locator('p.loadingsuccess')).toBeHidden(); expect(page.locator('p.loadingfail')).toBeHidden(); }); @@ -806,7 +852,7 @@ test.describe('Streaming', () => { expect(page.locator('p.loadingfail')).toBeVisible(); await expect(page.locator('p.success')).toHaveText('success'); - await expect(page.locator('p.fail')).toHaveText('fail'); + await expect(page.locator('p.fail')).toHaveText('fail (500 Internal Error)'); expect(page.locator('p.loadingsuccess')).toBeHidden(); expect(page.locator('p.loadingfail')).toBeHidden(); }); @@ -855,3 +901,123 @@ test.describe('Assets', () => { ).toBe(true); }); }); + +test.describe('goto', () => { + test('goto fails with external URL', async ({ page }) => { + await page.goto('/goto'); + await page.click('button'); + + const message = process.env.DEV + ? 'Cannot use `goto` with an external URL. Use `window.location = "https://example.com/"` instead' + : 'goto: invalid URL'; + await expect(page.locator('p')).toHaveText(message); + }); +}); + +test.describe('untrack', () => { + test('untracks server load function', async ({ page }) => { + await page.goto('/untrack/server/1'); + expect(await page.textContent('p.url')).toBe('/untrack/server/1'); + const id = await page.textContent('p.id'); + await page.click('a[href="/untrack/server/2"]'); + expect(await page.textContent('p.url')).toBe('/untrack/server/2'); + expect(await page.textContent('p.id')).toBe(id); + }); + + test('untracks universal load function', async ({ page }) => { + await page.goto('/untrack/universal/1'); + expect(await page.textContent('p.url')).toBe('/untrack/universal/1'); + const id = await page.textContent('p.id'); + await page.click('a[href="/untrack/universal/2"]'); + expect(await page.textContent('p.url')).toBe('/untrack/universal/2'); + expect(await page.textContent('p.id')).toBe(id); + }); +}); + +test.describe('Shallow routing', () => { + test('Pushes state to the current URL', async ({ page }) => { + await page.goto('/shallow-routing/push-state'); + await expect(page.locator('p')).toHaveText('active: false'); + + await page.locator('[data-id="one"]').click(); + await expect(page.locator('p')).toHaveText('active: true'); + + await page.goBack(); + await expect(page.locator('p')).toHaveText('active: false'); + }); + + test('Pushes state to a new URL', async ({ baseURL, page }) => { + await page.goto('/shallow-routing/push-state'); + await expect(page.locator('p')).toHaveText('active: false'); + + await page.locator('[data-id="two"]').click(); + expect(page.url()).toBe(`${baseURL}/shallow-routing/push-state/a`); + await expect(page.locator('h1')).toHaveText('parent'); + await expect(page.locator('p')).toHaveText('active: true'); + + await page.reload(); + await expect(page.locator('h1')).toHaveText('a'); + await expect(page.locator('p')).toHaveText('active: false'); + + await page.goBack(); + expect(page.url()).toBe(`${baseURL}/shallow-routing/push-state`); + await expect(page.locator('h1')).toHaveText('parent'); + await expect(page.locator('p')).toHaveText('active: false'); + + await page.goForward(); + expect(page.url()).toBe(`${baseURL}/shallow-routing/push-state/a`); + await expect(page.locator('h1')).toHaveText('parent'); + await expect(page.locator('p')).toHaveText('active: true'); + }); + + test('Invalidates the correct route after pushing state to a new URL', async ({ + baseURL, + page + }) => { + await page.goto('/shallow-routing/push-state'); + await expect(page.locator('p')).toHaveText('active: false'); + + const now = await page.locator('span').textContent(); + + await page.locator('[data-id="two"]').click(); + expect(page.url()).toBe(`${baseURL}/shallow-routing/push-state/a`); + + await page.locator('[data-id="invalidate"]').click(); + await expect(page.locator('h1')).toHaveText('parent'); + await expect(page.locator('span')).not.toHaveText(now); + }); + + test('Replaces state on the current URL', async ({ baseURL, page, clicknav }) => { + await page.goto('/shallow-routing/replace-state/b'); + await clicknav('[href="/shallow-routing/replace-state"]'); + + await page.locator('[data-id="one"]').click(); + await expect(page.locator('p')).toHaveText('active: true'); + + await page.goBack(); + expect(page.url()).toBe(`${baseURL}/shallow-routing/replace-state/b`); + await expect(page.locator('h1')).toHaveText('b'); + + await page.goForward(); + expect(page.url()).toBe(`${baseURL}/shallow-routing/replace-state`); + await expect(page.locator('h1')).toHaveText('parent'); + await expect(page.locator('p')).toHaveText('active: true'); + }); + + test('Replaces state on a new URL', async ({ baseURL, page, clicknav }) => { + await page.goto('/shallow-routing/replace-state/b'); + await clicknav('[href="/shallow-routing/replace-state"]'); + + await page.locator('[data-id="two"]').click(); + await expect(page.locator('p')).toHaveText('active: true'); + + await page.goBack(); + expect(page.url()).toBe(`${baseURL}/shallow-routing/replace-state/b`); + await expect(page.locator('h1')).toHaveText('b'); + + await page.goForward(); + expect(page.url()).toBe(`${baseURL}/shallow-routing/replace-state/a`); + await expect(page.locator('h1')).toHaveText('parent'); + await expect(page.locator('p')).toHaveText('active: true'); + }); +}); diff --git a/packages/kit/test/apps/basics/test/cross-platform/client.test.js b/packages/kit/test/apps/basics/test/cross-platform/client.test.js index 598c6e4c356e..f32a42d80bf2 100644 --- a/packages/kit/test/apps/basics/test/cross-platform/client.test.js +++ b/packages/kit/test/apps/basics/test/cross-platform/client.test.js @@ -141,17 +141,6 @@ test.describe('Navigation lifecycle functions', () => { expect(await page.innerHTML('pre')).toBe('1 false goto'); }); - test('beforeNavigate prevents external navigation triggered by goto', async ({ - page, - app, - baseURL - }) => { - await page.goto('/navigation-lifecycle/before-navigate/prevent-navigation'); - await app.goto('https://google.de'); - expect(page.url()).toBe(baseURL + '/navigation-lifecycle/before-navigate/prevent-navigation'); - expect(await page.innerHTML('pre')).toBe('1 true goto'); - }); - test('beforeNavigate prevents navigation triggered by back button', async ({ page, app, @@ -215,8 +204,11 @@ test.describe('Navigation lifecycle functions', () => { }) => { await page.goto('/navigation-lifecycle/before-navigate/prevent-navigation'); await page.click('h1'); // The browsers block attempts to prevent navigation on a frame that's never had a user gesture. - - await app.goto('https://google.de'); + page.on('dialog', async (dialog) => { + await dialog.dismiss(); + }); + await page.close({ runBeforeUnload: true }); + await page.waitForTimeout(100); await app.goto('/navigation-lifecycle/before-navigate/prevent-navigation?x=1'); expect(await page.innerHTML('pre')).toBe('2 false goto'); @@ -465,7 +457,7 @@ test.describe.serial('Errors', () => { expect(await page.textContent('footer')).toBe('Custom layout'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Crashing now"' + 'This is your custom error page saying: "Crashing now (500 Internal Error)"' ); }); @@ -474,7 +466,7 @@ test.describe.serial('Errors', () => { expect(await page.textContent('footer')).toBe('Custom layout'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Crashing now"' + 'This is your custom error page saying: "Crashing now (500 Internal Error)"' ); }); @@ -504,7 +496,7 @@ test.describe.serial('Errors', () => { expect(await page.textContent('h1')).toBe('Error - 500'); expect(await page.textContent('p')).toBe( - 'This is the static error page with the following message: Failed to load' + 'This is the static error page with the following message: Failed to load (500 Internal Error)' ); }); diff --git a/packages/kit/test/apps/basics/test/cross-platform/server.test.js b/packages/kit/test/apps/basics/test/cross-platform/server.test.js new file mode 100644 index 000000000000..678a07d575eb --- /dev/null +++ b/packages/kit/test/apps/basics/test/cross-platform/server.test.js @@ -0,0 +1,15 @@ +import { expect } from '@playwright/test'; +import { test } from '../../../../utils.js'; + +/** @typedef {import('@playwright/test').Response} Response */ + +test.skip(({ javaScriptEnabled }) => javaScriptEnabled); + +test.describe.configure({ mode: 'parallel' }); + +test.describe('Static files', () => { + test('Filenames are case-sensitive', async ({ request }) => { + const response = await request.get('/static.JSON'); + expect(response.status()).toBe(404); + }); +}); diff --git a/packages/kit/test/apps/basics/test/cross-platform/test.js b/packages/kit/test/apps/basics/test/cross-platform/test.js index 1e3b40564fa1..93b38f17302b 100644 --- a/packages/kit/test/apps/basics/test/cross-platform/test.js +++ b/packages/kit/test/apps/basics/test/cross-platform/test.js @@ -197,7 +197,7 @@ test.describe('Shadowed pages', () => { expect(await page.textContent('h1')).toBe('500'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Data returned from `load` while rendering /shadowed/serialization is not serializable: Cannot stringify arbitrary non-POJOs (data.nope)"' + 'This is your custom error page saying: "Data returned from `load` while rendering /shadowed/serialization is not serializable: Cannot stringify arbitrary non-POJOs (data.nope) (500 Internal Error)"' ); }); } @@ -212,7 +212,7 @@ test.describe('Errors', () => { expect(await page.textContent('footer')).toBe('Custom layout'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Crashing now"' + 'This is your custom error page saying: "Crashing now (500 Internal Error)"' ); }); @@ -242,7 +242,7 @@ test.describe('Errors', () => { : 'in src/routes/errors/invalid-load-response/+page.js'; expect(await page.textContent('#message')).toBe( - `This is your custom error page saying: "a load function ${details} returned an array, but must return a plain object at the top level (i.e. \`return {...}\`)"` + `This is your custom error page saying: "a load function ${details} returned an array, but must return a plain object at the top level (i.e. \`return {...}\`) (500 Internal Error)"` ); }); @@ -261,7 +261,7 @@ test.describe('Errors', () => { expect(await page.textContent('footer')).toBe('Custom layout'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "a load function in src/routes/errors/invalid-server-load-response/+page.server.js returned an array, but must return a plain object at the top level (i.e. `return {...}`)"' + 'This is your custom error page saying: "a load function in src/routes/errors/invalid-server-load-response/+page.server.js returned an array, but must return a plain object at the top level (i.e. `return {...}`) (500 Internal Error)"' ); }); } @@ -271,7 +271,7 @@ test.describe('Errors', () => { expect(await page.textContent('footer')).toBe('Custom layout'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Crashing now"' + 'This is your custom error page saying: "Crashing now (500 Internal Error)"' ); expect(await get_computed_style('h1', 'color')).toBe('rgb(255, 0, 0)'); @@ -282,7 +282,7 @@ test.describe('Errors', () => { expect(await page.textContent('footer')).toBe('Custom layout'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Not found: /why/would/anyone/fetch/this/url"' + 'This is your custom error page saying: "Not found: /why/would/anyone/fetch/this/url (404 Not Found)"' ); expect(/** @type {Response} */ (response).status()).toBe(404); }); @@ -319,7 +319,9 @@ test.describe('Errors', () => { } expect(res && res.status()).toBe(500); - expect(await page.textContent('#message')).toBe('This is your custom error page saying: "500"'); + expect(await page.textContent('#message')).toBe( + 'This is your custom error page saying: "500 (500 Internal Error)"' + ); }); test('error in shadow endpoint', async ({ page, read_errors }) => { @@ -335,7 +337,7 @@ test.describe('Errors', () => { expect(res && res.status()).toBe(500); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "nope"' + 'This is your custom error page saying: "nope (500 Internal Error)"' ); }); @@ -357,7 +359,7 @@ test.describe('Errors', () => { expect(await page.textContent('h1')).toBe('500'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Cannot prerender pages with actions"' + 'This is your custom error page saying: "Cannot prerender pages with actions (500 Internal Error)"' ); }); @@ -370,7 +372,7 @@ test.describe('Errors', () => { await clicknav('#get-implicit'); expect(await page.textContent('pre')).toBe( - JSON.stringify({ status: 500, message: 'oops' }, null, ' ') + JSON.stringify({ status: 500, message: 'oops (500 Internal Error)' }, null, ' ') ); const { status, name, message, stack, fancy } = read_errors( @@ -413,7 +415,7 @@ test.describe('Errors', () => { await clicknav('#post-implicit'); expect(await page.textContent('pre')).toBe( - JSON.stringify({ status: 500, message: 'oops' }, null, ' ') + JSON.stringify({ status: 500, message: 'oops (500 Internal Error)' }, null, ' ') ); const { status, name, message, stack, fancy } = read_errors( @@ -480,7 +482,7 @@ test.describe('Redirects', () => { expect(page.url()).toBe(`${baseURL}/redirect/loopy/a`); expect(await page.textContent('h1')).toBe('500'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Redirect loop"' + 'This is your custom error page saying: "Redirect loop (500 Internal Error)"' ); } else { // there's not a lot we can do to handle server-side redirect loops @@ -508,7 +510,7 @@ test.describe('Redirects', () => { expect(page.url()).toBe(`${baseURL}/redirect/missing-status/a`); expect(await page.textContent('h1')).toBe('500'); expect(await page.textContent('#message')).toBe( - `This is your custom error page saying: "${message}"` + `This is your custom error page saying: "${message} (500 Internal Error)"` ); if (!javaScriptEnabled) { @@ -528,7 +530,7 @@ test.describe('Redirects', () => { expect(page.url()).toBe(`${baseURL}/redirect/missing-status/b`); expect(await page.textContent('h1')).toBe('500'); expect(await page.textContent('#message')).toBe( - `This is your custom error page saying: "${message}"` + `This is your custom error page saying: "${message} (500 Internal Error)"` ); }); @@ -559,7 +561,7 @@ test.describe('Redirects', () => { expect(page.url()).toBe(`${baseURL}/redirect`); }); - test('throw redirect in handle hook', async ({ baseURL, clicknav, page }) => { + test('redirect in handle hook', async ({ baseURL, clicknav, page }) => { await page.goto('/redirect'); await clicknav('[href="/redirect/in-handle?throw"]'); @@ -572,11 +574,7 @@ test.describe('Redirects', () => { expect(page.url()).toBe(`${baseURL}/redirect`); }); - test('sets cookies when throw redirect in handle hook', async ({ - page, - app, - javaScriptEnabled - }) => { + test('sets cookies when redirect in handle hook', async ({ page, app, javaScriptEnabled }) => { await page.goto('/cookies/set'); let span = page.locator('#cookie-value'); expect(await span.innerText()).toContain('teapot'); diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index 50f1d47341e0..8f3fe6377bf9 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -1,6 +1,5 @@ import { expect } from '@playwright/test'; import { test } from '../../../utils.js'; -import { fetch } from 'undici'; import { createHash, randomBytes } from 'node:crypto'; /** @typedef {import('@playwright/test').Response} Response */ @@ -290,17 +289,17 @@ test.describe('Errors', () => { test('stack traces are not fixed twice', async ({ page }) => { await page.goto('/errors/stack-trace'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Cannot read properties of undefined (reading \'toUpperCase\')"' + 'This is your custom error page saying: "Cannot read properties of undefined (reading \'toUpperCase\') (500 Internal Error)"' ); // check the stack wasn't mutated await page.goto('/errors/stack-trace'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Cannot read properties of undefined (reading \'toUpperCase\')"' + 'This is your custom error page saying: "Cannot read properties of undefined (reading \'toUpperCase\') (500 Internal Error)"' ); }); - test('throw error(...) in endpoint', async ({ request, read_errors }) => { + test('error(...) in endpoint', async ({ request, read_errors }) => { // HTML { const res = await request.get('/errors/endpoint-throw-error', { @@ -332,7 +331,7 @@ test.describe('Errors', () => { } }); - test('throw redirect(...) in endpoint', async ({ page, read_errors }) => { + test('redirect(...) in endpoint', async ({ page, read_errors }) => { const res = await page.goto('/errors/endpoint-throw-redirect'); expect(res?.status()).toBe(200); // redirects are opaque to the browser @@ -359,7 +358,7 @@ test.describe('Errors', () => { expect(await res_json.json()).toEqual({ type: 'error', error: { - message: 'POST method not allowed. No actions exist for this page' + message: 'POST method not allowed. No actions exist for this page (405 Method Not Allowed)' } }); }); @@ -390,7 +389,7 @@ test.describe('Errors', () => { expect(error.stack).toBe(undefined); expect(res.status()).toBe(500); expect(error).toEqual({ - message: 'Error in handle' + message: 'Error in handle (500 Internal Error)' }); } }); @@ -568,11 +567,6 @@ test.describe('Static files', () => { expect(await r2.json()).toEqual({ works: true }); }); - test('Filenames are case-sensitive', async ({ request }) => { - const response = await request.get('/static.JSON'); - expect(response.status()).toBe(404); - }); - test('Serves symlinked asset', async ({ request }) => { const response = await request.get('/symlink-from/hello.txt'); expect(response.status()).toBe(200); diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index ef87a33f2185..ccfdd3d6ca73 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -586,7 +586,9 @@ test.describe('Nested layouts', () => { expect(await page.$('p#nested')).not.toBeNull(); expect(await page.$('p#nested-foo')).not.toBeNull(); expect(await page.$('p#nested-bar')).not.toBeNull(); - expect(await page.textContent('#nested-error-message')).toBe('error.message: nope'); + expect(await page.textContent('#nested-error-message')).toBe( + 'error.message: nope (500 Internal Error)' + ); }); test('resets layout', async ({ page }) => { @@ -604,7 +606,9 @@ test.describe('Nested layouts', () => { expect(await page.textContent('h1')).toBe('Nested error page'); expect(await page.textContent('#nested-error-status')).toBe('status: 500'); - expect(await page.textContent('#nested-error-message')).toBe('error.message: nope'); + expect(await page.textContent('#nested-error-message')).toBe( + 'error.message: nope (500 Internal Error)' + ); }); }); @@ -664,24 +668,16 @@ test.describe('$app/environment', () => { }); test.describe('$app/paths', () => { - test('includes paths', async ({ page }) => { + test('includes paths', async ({ page, javaScriptEnabled }) => { await page.goto('/paths'); - expect(await page.innerHTML('pre')).toBe( - JSON.stringify({ - base: '', - assets: '' - }) - ); + let base = javaScriptEnabled ? '' : '.'; + expect(await page.innerHTML('pre')).toBe(JSON.stringify({ base, assets: base })); await page.goto('/paths/deeply/nested'); - expect(await page.innerHTML('pre')).toBe( - JSON.stringify({ - base: '', - assets: '' - }) - ); + base = javaScriptEnabled ? '' : '../..'; + expect(await page.innerHTML('pre')).toBe(JSON.stringify({ base, assets: base })); }); // some browsers will re-request assets after a `pushState` @@ -926,69 +922,21 @@ test.describe('Actions', () => { expect(preSubmitContent).not.toBe(postSubmitContent); }); - test('Submitting a form with a file input but no enctype="multipart/form-data" logs a warning', async ({ + test('Submitting a form with a file input but no enctype="multipart/form-data" throws an error', async ({ page, javaScriptEnabled }) => { test.skip(!javaScriptEnabled, 'Skip when JavaScript is disabled'); test.skip(!process.env.DEV, 'Skip when not in dev mode'); await page.goto('/actions/file-without-enctype'); - const log_promise = page.waitForEvent('console'); + const error_promise = page.waitForEvent('pageerror'); await page.click('button'); - const log = await log_promise; - expect(log.text()).toBe( - 'Your form contains fields, but is missing the `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819. This will be upgraded to an error in v2.0.' + const error = await error_promise; + expect(error.message).toBe( + 'Your form contains fields, but is missing the necessary `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819.' ); }); - test('Accessing v2 deprecated properties results in a warning log', async ({ - page, - javaScriptEnabled - }) => { - test.skip(!javaScriptEnabled, 'skip when js is disabled'); - test.skip(!process.env.DEV, 'skip when not in dev mode'); - await page.goto('/actions/enhance/old-property-access'); - - for (const { id, old_name, new_name, call_location } of [ - { - id: 'access-form-in-submit', - old_name: 'form', - new_name: 'formElement', - call_location: 'use:enhance submit function' - }, - { - id: 'access-form-in-callback', - old_name: 'form', - new_name: 'formElement', - call_location: 'callback returned from use:enhance submit function' - }, - { - id: 'access-data-in-submit', - old_name: 'data', - new_name: 'formData', - call_location: 'use:enhance submit function' - }, - { - id: 'access-data-in-callback', - old_name: 'data', - new_name: 'formData', - call_location: 'callback returned from use:enhance submit function' - } - ]) { - await test.step(id, async () => { - const log_promise = page.waitForEvent('console'); - const button = page.locator(`#${id}`); - await button.click(); - await expect(button).toHaveAttribute('data-processed', 'true'); - const log = await log_promise; - expect(log.text()).toBe( - `\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})` - ); - expect(log.type()).toBe('warning'); - }); - } - }); - test('Error props are returned', async ({ page, javaScriptEnabled }) => { await page.goto('/actions/form-errors'); await page.click('button'); @@ -1242,6 +1190,43 @@ test.describe('Actions', () => { await expect(page.locator('pre')).toHaveText('something went wrong'); }); + + test('submitting application/json should return http status code 415', async ({ + baseURL, + page + }) => { + const response = await page.request.fetch(`${baseURL}/actions/form-errors`, { + method: 'POST', + body: JSON.stringify({ foo: 'bar' }), + headers: { + 'Content-Type': 'application/json', + Origin: `${baseURL}` + } + }); + const { type, error } = await response.json(); + expect(type).toBe('error'); + expect(error.message).toBe( + 'Form actions expect form-encoded data — received application/json (415 Unsupported Media Type)' + ); + expect(response.status()).toBe(415); + }); + + test('submitting to a form action that does not exists, should return http status code 404', async ({ + baseURL, + page + }) => { + const response = await page.request.fetch(`${baseURL}/actions/enhance?/doesnt-exist`, { + method: 'POST', + body: 'irrelevant', + headers: { + Origin: `${baseURL}` + } + }); + const { type, error } = await response.json(); + expect(type).toBe('error'); + expect(error.message).toBe("No action with name 'doesnt-exist' found (404 Not Found)"); + expect(response.status()).toBe(404); + }); }); // Run in serial to not pollute the log with (correct) cookie warnings diff --git a/packages/kit/test/apps/dev-only/package.json b/packages/kit/test/apps/dev-only/package.json index 7e39fe7cfe22..4b4efc3f9670 100644 --- a/packages/kit/test/apps/dev-only/package.json +++ b/packages/kit/test/apps/dev-only/package.json @@ -11,11 +11,12 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "cross-env": "^7.0.3", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/apps/embed/package.json b/packages/kit/test/apps/embed/package.json index 149c4af374e3..077d63318c93 100644 --- a/packages/kit/test/apps/embed/package.json +++ b/packages/kit/test/apps/embed/package.json @@ -13,11 +13,12 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "cross-env": "^7.0.3", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/apps/embed/src/routes/embed/+page.js b/packages/kit/test/apps/embed/src/routes/embed/+page.js index 4d321641c6d4..fb43b1061059 100644 --- a/packages/kit/test/apps/embed/src/routes/embed/+page.js +++ b/packages/kit/test/apps/embed/src/routes/embed/+page.js @@ -1,7 +1,7 @@ /** @type {import('@sveltejs/kit').Load} */ export async function load({ fetch }) { return { - a: fetch('/embed/a').then((x) => x.text()), - b: fetch('/embed/b').then((x) => x.text()) + a: await fetch('/embed/a').then((x) => x.text()), + b: await fetch('/embed/b').then((x) => x.text()) }; } diff --git a/packages/kit/test/apps/options-2/package.json b/packages/kit/test/apps/options-2/package.json index 8ff099252595..0ac7e9cc40fb 100644 --- a/packages/kit/test/apps/options-2/package.json +++ b/packages/kit/test/apps/options-2/package.json @@ -14,11 +14,12 @@ "devDependencies": { "@sveltejs/adapter-node": "workspace:^", "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "cross-env": "^7.0.3", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/apps/options/package.json b/packages/kit/test/apps/options/package.json index 8c153d7b5545..bbb5610df5b7 100644 --- a/packages/kit/test/apps/options/package.json +++ b/packages/kit/test/apps/options/package.json @@ -13,11 +13,12 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "cross-env": "^7.0.3", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/apps/options/source/pages/server-fetch-invalidate/+page.server.js b/packages/kit/test/apps/options/source/pages/server-fetch-invalidate/+page.server.js deleted file mode 100644 index fc6a5abe8eac..000000000000 --- a/packages/kit/test/apps/options/source/pages/server-fetch-invalidate/+page.server.js +++ /dev/null @@ -1,6 +0,0 @@ -// TODO 2.0: Delete -/** @type {import('./$types').PageServerLoad} */ -export async function load({ fetch }) { - const res = await fetch('/path-base/server-fetch-invalidate/count.json'); - return res.json(); -} diff --git a/packages/kit/test/apps/options/source/pages/server-fetch-invalidate/+page.svelte b/packages/kit/test/apps/options/source/pages/server-fetch-invalidate/+page.svelte deleted file mode 100644 index 3cadb6924412..000000000000 --- a/packages/kit/test/apps/options/source/pages/server-fetch-invalidate/+page.svelte +++ /dev/null @@ -1,6 +0,0 @@ - - -

{data.count}

diff --git a/packages/kit/test/apps/options/source/pages/server-fetch-invalidate/count.json/+server.js b/packages/kit/test/apps/options/source/pages/server-fetch-invalidate/count.json/+server.js deleted file mode 100644 index 443894c3dcf5..000000000000 --- a/packages/kit/test/apps/options/source/pages/server-fetch-invalidate/count.json/+server.js +++ /dev/null @@ -1,10 +0,0 @@ -// TODO 2.0: Delete -import { json } from '@sveltejs/kit'; - -let count = 0; - -/** @type {import('./$types').RequestHandler} */ -export function GET({ url }) { - if (url.searchParams.has('reset')) count = 0; - return json({ count: count++ }); -} diff --git a/packages/kit/test/apps/options/svelte.config.js b/packages/kit/test/apps/options/svelte.config.js index 465f142e0066..e32d72250a91 100644 --- a/packages/kit/test/apps/options/svelte.config.js +++ b/packages/kit/test/apps/options/svelte.config.js @@ -9,9 +9,6 @@ const config = { 'require-trusted-types-for': ['script'] } }, - dangerZone: { - trackServerFetches: true - }, files: { assets: 'public', lib: 'source/components', diff --git a/packages/kit/test/apps/options/test/test.js b/packages/kit/test/apps/options/test/test.js index cf63507e4ca9..de4135e992b3 100644 --- a/packages/kit/test/apps/options/test/test.js +++ b/packages/kit/test/apps/options/test/test.js @@ -239,7 +239,7 @@ test.describe('trailingSlash', () => { // also wait for network processing to complete, see // https://playwright.dev/docs/network#network-events - await app.preloadData('/path-base/preloading/preloaded'); + await app.preloadCode('/path-base/preloading/preloaded'); // svelte request made is environment dependent if (process.env.DEV) { @@ -248,6 +248,9 @@ test.describe('trailingSlash', () => { expect(requests.filter((req) => req.endsWith('.mjs')).length).toBeGreaterThan(0); } + requests = []; + await app.preloadData('/path-base/preloading/preloaded'); + expect(requests.includes('/path-base/preloading/preloaded/__data.json')).toBe(true); requests = []; @@ -309,22 +312,3 @@ test.describe('Routing', () => { await expect(page.locator('h2')).toHaveText('target: 0'); }); }); - -test.describe('load', () => { - // TODO 2.0: Remove this test - test('fetch in server load can be invalidated when `dangerZone.trackServerFetches` is set', async ({ - page, - app, - request, - javaScriptEnabled - }) => { - test.skip(!javaScriptEnabled, 'JavaScript is disabled'); - await request.get('/path-base/server-fetch-invalidate/count.json?reset'); - await page.goto('/path-base/server-fetch-invalidate'); - const selector = '[data-testid="count"]'; - - expect(await page.textContent(selector)).toBe('1'); - await app.invalidate('/path-base/server-fetch-invalidate/count.json'); - expect(await page.textContent(selector)).toBe('2'); - }); -}); diff --git a/packages/kit/test/apps/writes/package.json b/packages/kit/test/apps/writes/package.json index 9853d0796a92..1d977c1dbce3 100644 --- a/packages/kit/test/apps/writes/package.json +++ b/packages/kit/test/apps/writes/package.json @@ -13,11 +13,12 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "cross-env": "^7.0.3", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch/package.json b/packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch/package.json index b73f1b4fc918..91dbf0a094c0 100644 --- a/packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch/package.json +++ b/packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch/package.json @@ -11,10 +11,11 @@ "devDependencies": { "@sveltejs/adapter-auto": "workspace:^", "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch/tsconfig.json b/packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch/tsconfig.json index 95d9c037df6c..c8c193a57349 100644 --- a/packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch/tsconfig.json +++ b/packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch/tsconfig.json @@ -3,8 +3,6 @@ "allowJs": true, "checkJs": true, "noEmit": true, - "module": "esnext", - "moduleResolution": "node", "paths": { "@sveltejs/kit": ["../../../../types"], "$lib": ["./src/lib"], diff --git a/packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment/package.json b/packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment/package.json index b73f1b4fc918..91dbf0a094c0 100644 --- a/packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment/package.json +++ b/packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment/package.json @@ -11,10 +11,11 @@ "devDependencies": { "@sveltejs/adapter-auto": "workspace:^", "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment/tsconfig.json b/packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment/tsconfig.json index 95d9c037df6c..c8c193a57349 100644 --- a/packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment/tsconfig.json +++ b/packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment/tsconfig.json @@ -3,8 +3,6 @@ "allowJs": true, "checkJs": true, "noEmit": true, - "module": "esnext", - "moduleResolution": "node", "paths": { "@sveltejs/kit": ["../../../../types"], "$lib": ["./src/lib"], diff --git a/packages/kit/test/build-errors/apps/prerenderable-not-prerendered/package.json b/packages/kit/test/build-errors/apps/prerenderable-not-prerendered/package.json index 6f5202120a67..f5783a3d6f33 100644 --- a/packages/kit/test/build-errors/apps/prerenderable-not-prerendered/package.json +++ b/packages/kit/test/build-errors/apps/prerenderable-not-prerendered/package.json @@ -11,10 +11,11 @@ "devDependencies": { "@sveltejs/adapter-auto": "workspace:^", "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/prerenderable-not-prerendered/tsconfig.json b/packages/kit/test/build-errors/apps/prerenderable-not-prerendered/tsconfig.json index 95d9c037df6c..c8c193a57349 100644 --- a/packages/kit/test/build-errors/apps/prerenderable-not-prerendered/tsconfig.json +++ b/packages/kit/test/build-errors/apps/prerenderable-not-prerendered/tsconfig.json @@ -3,8 +3,6 @@ "allowJs": true, "checkJs": true, "noEmit": true, - "module": "esnext", - "moduleResolution": "node", "paths": { "@sveltejs/kit": ["../../../../types"], "$lib": ["./src/lib"], diff --git a/packages/kit/test/build-errors/apps/private-dynamic-env-dynamic-import/package.json b/packages/kit/test/build-errors/apps/private-dynamic-env-dynamic-import/package.json index 734e8cd783ad..b8f82fce09fd 100644 --- a/packages/kit/test/build-errors/apps/private-dynamic-env-dynamic-import/package.json +++ b/packages/kit/test/build-errors/apps/private-dynamic-env-dynamic-import/package.json @@ -11,10 +11,11 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/private-dynamic-env/package.json b/packages/kit/test/build-errors/apps/private-dynamic-env/package.json index ac095b19c257..daf7b524812d 100644 --- a/packages/kit/test/build-errors/apps/private-dynamic-env/package.json +++ b/packages/kit/test/build-errors/apps/private-dynamic-env/package.json @@ -11,10 +11,11 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/private-static-env-dynamic-import/package.json b/packages/kit/test/build-errors/apps/private-static-env-dynamic-import/package.json index 296fabb5bbb6..1964552572a1 100644 --- a/packages/kit/test/build-errors/apps/private-static-env-dynamic-import/package.json +++ b/packages/kit/test/build-errors/apps/private-static-env-dynamic-import/package.json @@ -11,10 +11,11 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/private-static-env/package.json b/packages/kit/test/build-errors/apps/private-static-env/package.json index 704de0d38bc0..69fab02bc21e 100644 --- a/packages/kit/test/build-errors/apps/private-static-env/package.json +++ b/packages/kit/test/build-errors/apps/private-static-env/package.json @@ -11,11 +11,12 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "cross-env": "^7.0.3", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/server-only-folder-dynamic-import/package.json b/packages/kit/test/build-errors/apps/server-only-folder-dynamic-import/package.json index eba3d2c6a38e..b51afc685ae7 100644 --- a/packages/kit/test/build-errors/apps/server-only-folder-dynamic-import/package.json +++ b/packages/kit/test/build-errors/apps/server-only-folder-dynamic-import/package.json @@ -11,10 +11,11 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/server-only-folder/package.json b/packages/kit/test/build-errors/apps/server-only-folder/package.json index 6e7ce6cf3045..1ff1a2613469 100644 --- a/packages/kit/test/build-errors/apps/server-only-folder/package.json +++ b/packages/kit/test/build-errors/apps/server-only-folder/package.json @@ -11,10 +11,11 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/server-only-module-dynamic-import/package.json b/packages/kit/test/build-errors/apps/server-only-module-dynamic-import/package.json index 3c3b2ce1626a..ac934494c690 100644 --- a/packages/kit/test/build-errors/apps/server-only-module-dynamic-import/package.json +++ b/packages/kit/test/build-errors/apps/server-only-module-dynamic-import/package.json @@ -11,10 +11,11 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/server-only-module/package.json b/packages/kit/test/build-errors/apps/server-only-module/package.json index 917800f07955..690c00cc370f 100644 --- a/packages/kit/test/build-errors/apps/server-only-module/package.json +++ b/packages/kit/test/build-errors/apps/server-only-module/package.json @@ -11,10 +11,11 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/apps/syntax-error/package.json b/packages/kit/test/build-errors/apps/syntax-error/package.json index 4b9da3223c89..04f1b343f21e 100644 --- a/packages/kit/test/build-errors/apps/syntax-error/package.json +++ b/packages/kit/test/build-errors/apps/syntax-error/package.json @@ -9,10 +9,11 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/packages/kit/test/build-errors/package.json b/packages/kit/test/build-errors/package.json index fe646c995463..891ef5db6633 100644 --- a/packages/kit/test/build-errors/package.json +++ b/packages/kit/test/build-errors/package.json @@ -8,6 +8,6 @@ }, "type": "module", "devDependencies": { - "vitest": "^0.34.5" + "vitest": "^1.0.4" } } diff --git a/packages/kit/test/prerendering/basics/package.json b/packages/kit/test/prerendering/basics/package.json index 9b6f5fd84105..ba2e8968e4a7 100644 --- a/packages/kit/test/prerendering/basics/package.json +++ b/packages/kit/test/prerendering/basics/package.json @@ -12,11 +12,12 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9", - "vitest": "^0.34.5" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8", + "vitest": "^1.0.4" }, "type": "module" } diff --git a/packages/kit/test/prerendering/basics/src/routes/encoding/redirect/+page.js b/packages/kit/test/prerendering/basics/src/routes/encoding/redirect/+page.js index d40db8a08882..69eaf737efb8 100644 --- a/packages/kit/test/prerendering/basics/src/routes/encoding/redirect/+page.js +++ b/packages/kit/test/prerendering/basics/src/routes/encoding/redirect/+page.js @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').Load} */ export function load() { - throw redirect(307, '/encoding/redirected%20path%20with%20encoded%20spaces'); + redirect(307, '/encoding/redirected%20path%20with%20encoded%20spaces'); } diff --git a/packages/kit/test/prerendering/basics/src/routes/env/+page.server.js b/packages/kit/test/prerendering/basics/src/routes/env/+page.server.js index 617a8542fd21..d0f085387247 100644 --- a/packages/kit/test/prerendering/basics/src/routes/env/+page.server.js +++ b/packages/kit/test/prerendering/basics/src/routes/env/+page.server.js @@ -1,9 +1,7 @@ import { PRIVATE_STATIC } from '$env/static/private'; -import { env } from '$env/dynamic/private'; export function load() { return { - PRIVATE_STATIC, - PRIVATE_DYNAMIC: env.PRIVATE_DYNAMIC + PRIVATE_STATIC }; } diff --git a/packages/kit/test/prerendering/basics/src/routes/env/+page.svelte b/packages/kit/test/prerendering/basics/src/routes/env/+page.svelte index 4ee2f424da67..bb13de1f8f55 100644 --- a/packages/kit/test/prerendering/basics/src/routes/env/+page.svelte +++ b/packages/kit/test/prerendering/basics/src/routes/env/+page.svelte @@ -1,13 +1,9 @@

PRIVATE_STATIC: {data.PRIVATE_STATIC}

-

PRIVATE_DYNAMIC: {data.PRIVATE_DYNAMIC}

-

PUBLIC_STATIC: {PUBLIC_STATIC}

-

PUBLIC_DYNAMIC: {env.PUBLIC_DYNAMIC}

diff --git a/packages/kit/test/prerendering/basics/src/routes/optional-params/[[optional]]/+page.svelte b/packages/kit/test/prerendering/basics/src/routes/optional-params/[[optional]]/+page.svelte new file mode 100644 index 000000000000..3438d28471db --- /dev/null +++ b/packages/kit/test/prerendering/basics/src/routes/optional-params/[[optional]]/+page.svelte @@ -0,0 +1 @@ +Path with Value diff --git a/packages/kit/test/prerendering/basics/src/routes/page.html/+page.server.js b/packages/kit/test/prerendering/basics/src/routes/page.html/+page.server.js new file mode 100644 index 000000000000..f10d94d2ba04 --- /dev/null +++ b/packages/kit/test/prerendering/basics/src/routes/page.html/+page.server.js @@ -0,0 +1,5 @@ +export function load() { + return { + message: 'hello' + }; +} diff --git a/packages/kit/test/prerendering/basics/src/routes/page.html/+page.svelte b/packages/kit/test/prerendering/basics/src/routes/page.html/+page.svelte new file mode 100644 index 000000000000..439e64448c2b --- /dev/null +++ b/packages/kit/test/prerendering/basics/src/routes/page.html/+page.svelte @@ -0,0 +1,5 @@ + + +

{data.message}

diff --git a/packages/kit/test/prerendering/basics/src/routes/redirect-encoded/+page.js b/packages/kit/test/prerendering/basics/src/routes/redirect-encoded/+page.js index 9dfac2b31492..0b5f120e8035 100644 --- a/packages/kit/test/prerendering/basics/src/routes/redirect-encoded/+page.js +++ b/packages/kit/test/prerendering/basics/src/routes/redirect-encoded/+page.js @@ -2,8 +2,5 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').Load} */ export function load() { - throw redirect( - 301, - `https://example.com/redirected?returnTo=${encodeURIComponent('/foo?bar=baz')}` - ); + redirect(301, `https://example.com/redirected?returnTo=${encodeURIComponent('/foo?bar=baz')}`); } diff --git a/packages/kit/test/prerendering/basics/src/routes/redirect-malicious/+page.js b/packages/kit/test/prerendering/basics/src/routes/redirect-malicious/+page.js index 6fd54b56dfda..2f8cbe6b9caa 100644 --- a/packages/kit/test/prerendering/basics/src/routes/redirect-malicious/+page.js +++ b/packages/kit/test/prerendering/basics/src/routes/redirect-malicious/+page.js @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').Load} */ export function load() { - throw redirect(301, 'https://example.com/alert("pwned")'); + redirect(301, 'https://example.com/alert("pwned")'); } diff --git a/packages/kit/test/prerendering/basics/src/routes/redirect-relative/+page.js b/packages/kit/test/prerendering/basics/src/routes/redirect-relative/+page.js index dc685417407a..458b93125f2a 100644 --- a/packages/kit/test/prerendering/basics/src/routes/redirect-relative/+page.js +++ b/packages/kit/test/prerendering/basics/src/routes/redirect-relative/+page.js @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').Load} */ export function load() { - throw redirect(301, '/env'); + redirect(301, '/env'); } diff --git a/packages/kit/test/prerendering/basics/src/routes/redirect-server/+page.server.js b/packages/kit/test/prerendering/basics/src/routes/redirect-server/+page.server.js index 0ed002001e08..c61c65b8d644 100644 --- a/packages/kit/test/prerendering/basics/src/routes/redirect-server/+page.server.js +++ b/packages/kit/test/prerendering/basics/src/routes/redirect-server/+page.server.js @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').Load} */ export function load() { - throw redirect(301, 'https://example.com/redirected'); + redirect(301, 'https://example.com/redirected'); } diff --git a/packages/kit/test/prerendering/basics/src/routes/redirect/+page.js b/packages/kit/test/prerendering/basics/src/routes/redirect/+page.js index 0ed002001e08..c61c65b8d644 100644 --- a/packages/kit/test/prerendering/basics/src/routes/redirect/+page.js +++ b/packages/kit/test/prerendering/basics/src/routes/redirect/+page.js @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; /** @type {import('@sveltejs/kit').Load} */ export function load() { - throw redirect(301, 'https://example.com/redirected'); + redirect(301, 'https://example.com/redirected'); } diff --git a/packages/kit/test/prerendering/basics/test/tests.spec.js b/packages/kit/test/prerendering/basics/test/tests.spec.js index 3a830c97e96e..ecf337c35a76 100644 --- a/packages/kit/test/prerendering/basics/test/tests.spec.js +++ b/packages/kit/test/prerendering/basics/test/tests.spec.js @@ -205,12 +205,8 @@ test('$env - includes environment variables', () => { content, /.*PRIVATE_STATIC: accessible to server-side code\/replaced at build time.*/gs ); - assert.match( - content, - /.*PRIVATE_DYNAMIC: accessible to server-side code\/evaluated at run time.*/gs - ); + assert.match(content, /.*PUBLIC_STATIC: accessible anywhere\/replaced at build time.*/gs); - assert.match(content, /.*PUBLIC_DYNAMIC: accessible anywhere\/evaluated at run time.*/gs); }); test('prerenders a page in a (group)', () => { @@ -244,3 +240,8 @@ test('prerenders responses with immutable Headers', () => { const content = read('immutable-headers'); expect(content).toMatch('foo'); }); + +test('prerenders paths with optional parameters with empty values', () => { + const content = read('optional-params.html'); + expect(content).includes('Path with Value'); +}); diff --git a/packages/kit/test/prerendering/basics/tsconfig.json b/packages/kit/test/prerendering/basics/tsconfig.json index df547741d5bb..858415b26691 100644 --- a/packages/kit/test/prerendering/basics/tsconfig.json +++ b/packages/kit/test/prerendering/basics/tsconfig.json @@ -3,8 +3,6 @@ "allowJs": true, "checkJs": true, "noEmit": true, - "module": "esnext", - "moduleResolution": "node", "paths": { "@sveltejs/kit": ["../../../types"], "$lib": ["./src/lib"], diff --git a/packages/kit/test/prerendering/options/package.json b/packages/kit/test/prerendering/options/package.json index ba0eedf199e6..afe3d118f9ef 100644 --- a/packages/kit/test/prerendering/options/package.json +++ b/packages/kit/test/prerendering/options/package.json @@ -11,11 +11,12 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9", - "vitest": "^0.34.5" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8", + "vitest": "^1.0.4" }, "type": "module" } diff --git a/packages/kit/test/prerendering/options/tsconfig.json b/packages/kit/test/prerendering/options/tsconfig.json index df547741d5bb..858415b26691 100644 --- a/packages/kit/test/prerendering/options/tsconfig.json +++ b/packages/kit/test/prerendering/options/tsconfig.json @@ -3,8 +3,6 @@ "allowJs": true, "checkJs": true, "noEmit": true, - "module": "esnext", - "moduleResolution": "node", "paths": { "@sveltejs/kit": ["../../../types"], "$lib": ["./src/lib"], diff --git a/packages/kit/test/prerendering/paths-base/package.json b/packages/kit/test/prerendering/paths-base/package.json index 31c852503882..0dbebcc6e01c 100644 --- a/packages/kit/test/prerendering/paths-base/package.json +++ b/packages/kit/test/prerendering/paths-base/package.json @@ -11,11 +11,12 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:^", - "svelte": "^4.2.7", - "svelte-check": "^3.4.4", - "typescript": "^4.9.4", - "vite": "^4.4.9", - "vitest": "^0.34.5" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.8", + "vitest": "^1.0.4" }, "type": "module" } diff --git a/packages/kit/test/prerendering/paths-base/src/routes/redirect/+page.js b/packages/kit/test/prerendering/paths-base/src/routes/redirect/+page.js index 84d4247b57a2..d27f8e81c372 100644 --- a/packages/kit/test/prerendering/paths-base/src/routes/redirect/+page.js +++ b/packages/kit/test/prerendering/paths-base/src/routes/redirect/+page.js @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; import { base } from '$app/paths'; export function load() { - throw redirect(301, `${base}/dynamic/foo`); + redirect(301, `${base}/dynamic/foo`); } diff --git a/packages/kit/test/prerendering/paths-base/tsconfig.json b/packages/kit/test/prerendering/paths-base/tsconfig.json index df547741d5bb..858415b26691 100644 --- a/packages/kit/test/prerendering/paths-base/tsconfig.json +++ b/packages/kit/test/prerendering/paths-base/tsconfig.json @@ -3,8 +3,6 @@ "allowJs": true, "checkJs": true, "noEmit": true, - "module": "esnext", - "moduleResolution": "node", "paths": { "@sveltejs/kit": ["../../../types"], "$lib": ["./src/lib"], diff --git a/packages/kit/test/types/actions.test.ts b/packages/kit/test/types/actions.test.ts index 8ca089d18c28..2614452ee8f4 100644 --- a/packages/kit/test/types/actions.test.ts +++ b/packages/kit/test/types/actions.test.ts @@ -1,9 +1,10 @@ -import Kit from '@sveltejs/kit'; +import * as Kit from '@sveltejs/kit'; // Test: Action types inferred correctly and transformed into a union type Actions = { foo: () => Promise; bar: () => Promise<{ success: boolean } | Kit.ActionFailure<{ message: string }>>; + baz: () => Kit.ActionFailure<{ foo: string }> | { status: number; data: string }; }; let form: Kit.AwaitedActions = null as any; @@ -23,3 +24,17 @@ form2.message = ''; form2.success = true; // @ts-expect-error - cannot both be present at the same time form2 = { message: '', success: true }; + +// Test: ActionFailure is correctly infered to be different from the normal return type even if they have the same shape +type Actions3 = { + bar: () => Kit.ActionFailure<{ foo: string }> | { status: number; data: { bar: string } }; +}; +let form3: Kit.AwaitedActions = null as any; +form3.foo = ''; +form3.status = 200; +// @ts-expect-error - cannot both be present at the same time +form3 = { foo: '', status: 200 }; + +let foo: any = null; +// @ts-expect-error ActionFailure is not a class and so you can't do instanceof +foo instanceof Kit.ActionFailure; diff --git a/packages/kit/test/types/load.test.ts b/packages/kit/test/types/load.test.ts index 321d70931bdd..10cc108af530 100644 --- a/packages/kit/test/types/load.test.ts +++ b/packages/kit/test/types/load.test.ts @@ -1,20 +1,12 @@ -import Kit, { Deferred } from '@sveltejs/kit'; +import * as Kit from '@sveltejs/kit'; // Test: Return types inferred correctly and transformed into a union -type LoadReturn1 = { success: true } | { message: Promise }; +type LoadReturn1 = + | { success: true; message?: undefined } + | { success?: undefined; message: string }; -let result1: Kit.AwaitedProperties = null as any; +let result1: Kit.LoadProperties = null as any; result1.message = ''; result1.success = true; // @ts-expect-error - cannot both be present at the same time result1 = { message: '', success: true }; - -// Test: Return types keep promise for Deferred -type LoadReturn2 = { success: true } | Deferred<{ message: Promise; eager: true }>; - -let result2: Kit.AwaitedProperties = null as any; -result2.message = Promise.resolve(''); -result2.eager = true; -result2.success = true; -// @ts-expect-error - cannot both be present at the same time -result2 = { message: '', success: true }; diff --git a/packages/kit/test/utils.js b/packages/kit/test/utils.js index 4eeea4f4416e..05b88c9ce0c6 100644 --- a/packages/kit/test/utils.js +++ b/packages/kit/test/utils.js @@ -1,8 +1,8 @@ import fs from 'node:fs'; -import path from 'node:path'; import http from 'node:http'; -import { test as base, devices } from '@playwright/test'; +import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { test as base, devices } from '@playwright/test'; export const test = base.extend({ app: async ({ page }, use) => { @@ -73,7 +73,7 @@ export const test = base.extend({ /** @param {string} selector */ async function in_view(selector) { const box = await page.locator(selector).boundingBox(); - const view = await page.viewportSize(); + const view = page.viewportSize(); return box && view && box.y < view.height && box.y + box.height > 0; } diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index e9f5a2132375..0e2b7713afbd 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -2,7 +2,7 @@ /// declare module '@sveltejs/kit' { - import type { CompileOptions } from 'svelte/types/compiler/interfaces'; + import type { CompileOptions } from 'svelte/compiler'; import type { PluginOptions } from '@sveltejs/vite-plugin-svelte'; /** * [Adapters](https://kit.svelte.dev/docs/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -19,20 +19,11 @@ declare module '@sveltejs/kit' { adapt(builder: Builder): MaybePromise; } - type AwaitedPropertiesUnion | void> = input extends void + export type LoadProperties | void> = input extends void ? undefined // needs to be undefined, because void will break intellisense : input extends Record - ? { - [key in keyof input]: Awaited; - } - : {} extends input // handles the any case - ? input - : unknown; - - export type AwaitedProperties | void> = - AwaitedPropertiesUnion extends Record - ? OptionalUnion> - : AwaitedPropertiesUnion; + ? input + : unknown; export type AwaitedActions any>> = OptionalUnion< { @@ -47,6 +38,14 @@ declare module '@sveltejs/kit' { A extends keyof U = U extends U ? keyof U : never > = U extends unknown ? { [P in Exclude]?: never } & U : never; + const uniqueSymbol: unique symbol; + + export interface ActionFailure | undefined = undefined> { + status: number; + data: T; + [uniqueSymbol]: true; // necessary or else UnpackValidationError could wrongly unpack objects with the same shape as ActionFailure + } + type UnpackValidationError = T extends ActionFailure ? X : T extends void @@ -84,6 +83,11 @@ declare module '@sveltejs/kit' { */ generateFallback(dest: string): Promise; + /** + * Generate a module exposing build-time environment variables as `$env/dynamic/public`. + */ + generateEnvModule(): void; + /** * Generate a server-side manifest to initialise the SvelteKit [server](https://kit.svelte.dev/docs/types#public-types-server) with. * @param opts a relative path to the base directory of the app and optionally in which format (esm or cjs) the manifest should be generated @@ -192,34 +196,42 @@ declare module '@sveltejs/kit' { * * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. * - * By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. + * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children * @param name the name of the cookie * @param value the cookie value * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - set(name: string, value: string, opts?: import('cookie').CookieSerializeOptions): void; + set( + name: string, + value: string, + opts: import('cookie').CookieSerializeOptions & { path: string } + ): void; /** * Deletes a cookie by setting its value to an empty string and setting the expiry date in the past. * - * By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. + * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children * @param name the name of the cookie * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - delete(name: string, opts?: import('cookie').CookieSerializeOptions): void; + delete(name: string, opts: import('cookie').CookieSerializeOptions & { path: string }): void; /** * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. * * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. * - * By default, the `path` of a cookie is the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. + * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children * * @param name the name of the cookie * @param value the cookie value * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - serialize(name: string, value: string, opts?: import('cookie').CookieSerializeOptions): string; + serialize( + name: string, + value: string, + opts: import('cookie').CookieSerializeOptions & { path: string } + ): string; } export interface KitConfig { @@ -259,7 +271,9 @@ declare module '@sveltejs/kit' { */ alias?: Record; /** - * The directory relative to `paths.assets` where the built JS and CSS (and imported assets) are served from. (The filenames therein contain content-based hashes, meaning they can be cached indefinitely). Must not start or end with `/`. + * The directory where SvelteKit keeps its stuff, including static assets (such as JS and CSS) and internally-used routes. + * + * If `paths.assets` is specified, there will be two app directories — `${paths.assets}/${appDir}` and `${paths.base}/${appDir}`. * @default "_app" */ appDir?: string; @@ -323,16 +337,6 @@ declare module '@sveltejs/kit' { */ checkOrigin?: boolean; }; - /** - * Here be dragons. Enable at your peril. - */ - dangerZone?: { - /** - * Automatically add server-side `fetch`ed URLs to the `dependencies` map of `load` functions. This will expose secrets - * to the client if your URL contains them. - */ - trackServerFetches?: boolean; - }; /** * Whether or not the app is embedded inside a larger app. If `true`, SvelteKit will add its event listeners related to navigation etc on the parent of `%sveltekit.body%` instead of `window`, and will pass `params` from the server rather than inferring them from `location.pathname`. * @default false @@ -453,17 +457,20 @@ declare module '@sveltejs/kit' { */ base?: '' | `/${string}`; /** - * Whether to use relative asset paths. By default, if `paths.assets` is not external, SvelteKit will replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` will be as specified in your config. + * Whether to use relative asset paths. * - * If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in portable HTML. + * If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in more portable HTML. * If `false`, `%sveltekit.assets%` and references to build artifacts will always be root-relative paths, unless `paths.assets` is an external URL * * [Single-page app](https://kit.svelte.dev/docs/single-page-apps) fallback pages will always use absolute paths, regardless of this setting. * * If your app uses a `` element, you should set this to `false`, otherwise asset URLs will incorrectly be resolved against the `` URL rather than the current page. - * @default undefined + * + * In 1.0, `undefined` was a valid value, which was set by default. In that case, if `paths.assets` was not external, SvelteKit would replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` would be as specified in your config. + * + * @default true */ - relative?: boolean | undefined; + relative?: boolean; }; /** * See [Prerendering](https://kit.svelte.dev/docs/page-options#prerender). @@ -480,7 +487,7 @@ declare module '@sveltejs/kit' { */ crawl?: boolean; /** - * An array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all non-dynamic routes (i.e. pages with no `[parameters]`, because SvelteKit doesn't know what value the parameters should have). + * An array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all routes containing no required `[parameters]` with optional parameters included as being empty (since SvelteKit doesn't know what value any parameters should have). * @default ["*"] */ entries?: Array<'*' | `/${string}`>; @@ -632,6 +639,8 @@ declare module '@sveltejs/kit' { export type HandleServerError = (input: { error: unknown; event: RequestEvent; + status: number; + message: string; }) => MaybePromise; /** @@ -643,6 +652,8 @@ declare module '@sveltejs/kit' { export type HandleClientError = (input: { error: unknown; event: NavigationEvent; + status: number; + message: string; }) => MaybePromise; /** @@ -761,7 +772,21 @@ declare module '@sveltejs/kit' { * * ``` */ - depends(...deps: string[]): void; + depends(...deps: Array<`${string}:${string}`>): void; + /** + * Use this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example: + * + * ```js + * /// file: src/routes/+page.server.js + * export async function load({ untrack, url }) { + * // Untrack url.pathname so that path changes don't trigger a rerun + * if (untrack(() => url.pathname === '/')) { + * return { message: 'Welcome!' }; + * } + * } + * ``` + */ + untrack(fn: () => T): T; } export interface NavigationEvent< @@ -828,7 +853,7 @@ declare module '@sveltejs/kit' { /** * The type of navigation: * - `form`: The user submitted a `
` - * - `leave`: The user is leaving the app by closing the tab or using the back/forward buttons to go to a different document + * - `leave`: The app is being left either because the tab is being closed or a navigation to a different document is occurring * - `link`: Navigation was triggered by a link click * - `goto`: Navigation was triggered by a `goto(...)` call or a redirect * - `popstate`: Navigation was triggered by back/forward navigation @@ -932,6 +957,10 @@ declare module '@sveltejs/kit' { * The merged result of all data from all `load` functions on the current page. You can type a common denominator through `App.PageData`. */ data: App.PageData & Record; + /** + * The page state, which can be manipulated using the [`pushState`](https://kit.svelte.dev/docs/modules#$app-navigation-pushstate) and [`replaceState`](https://kit.svelte.dev/docs/modules#$app-navigation-replacestate) functions from `$app/navigation`. + */ + state: App.PageState; /** * Filled only after a form submission. See [form actions](https://kit.svelte.dev/docs/form-actions) for more info. */ @@ -1163,6 +1192,20 @@ declare module '@sveltejs/kit' { * ``` */ depends(...deps: string[]): void; + /** + * Use this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example: + * + * ```js + * /// file: src/routes/+page.js + * export async function load({ untrack, url }) { + * // Untrack url.pathname so that path changes don't trigger a rerun + * if (untrack(() => url.pathname === '/')) { + * return { message: 'Welcome!' }; + * } + * } + * ``` + */ + untrack(fn: () => T): T; } /** @@ -1229,17 +1272,7 @@ declare module '@sveltejs/kit' { Failure extends Record | undefined = Record > = (input: { action: URL; - /** - * use `formData` instead of `data` - * @deprecated - */ - data: FormData; formData: FormData; - /** - * use `formElement` instead of `form` - * @deprecated - */ - form: HTMLFormElement; formElement: HTMLFormElement; controller: AbortController; submitter: HTMLElement | null; @@ -1247,17 +1280,7 @@ declare module '@sveltejs/kit' { }) => MaybePromise< | void | ((opts: { - /** - * use `formData` instead of `data` - * @deprecated - */ - data: FormData; formData: FormData; - /** - * use `formElement` instead of `form` - * @deprecated - */ - form: HTMLFormElement; formElement: HTMLFormElement; action: URL; result: ActionResult; @@ -1504,28 +1527,6 @@ declare module '@sveltejs/kit' { } type TrailingSlash = 'never' | 'always' | 'ignore'; - class HttpError_1 { - - constructor(status: number, body: { - message: string; - } extends App.Error ? (App.Error | string | undefined) : App.Error); - status: number; - body: App.Error; - toString(): string; - } - class Redirect_1 { - - constructor(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string); - status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308; - location: string; - } - - export class ActionFailure | undefined = undefined> { - - constructor(status: number, data?: T | undefined); - status: number; - data: T | undefined; - } interface Asset { file: string; size: number; @@ -1543,6 +1544,7 @@ declare module '@sveltejs/kit' { imports: string[]; stylesheets: string[]; fonts: string[]; + uses_env_dynamic_public: boolean; } | null; server_manifest: import('vite').Manifest; } @@ -1692,17 +1694,51 @@ declare module '@sveltejs/kit' { } type ValidatedConfig = RecursiveRequired; - export function error(status: number, body: App.Error): HttpError_1; - export function error(status: number, body?: { + /** + * Throws an error with a HTTP status code and an optional message. + * When called during request handling, this will cause SvelteKit to + * return an error response without invoking `handleError`. + * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it. + * @param status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. + * @param body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property. + * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. + * @throws {Error} If the provided status is invalid (not between 400 and 599). + */ + export function error(status: NumericRange<400, 599>, body: App.Error): never; + /** + * Throws an error with a HTTP status code and an optional message. + * When called during request handling, this will cause SvelteKit to + * return an error response without invoking `handleError`. + * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it. + * @param status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. + * @param body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property. + * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. + * @throws {Error} If the provided status is invalid (not between 400 and 599). + */ + export function error(status: NumericRange<400, 599>, body?: { message: string; - } extends App.Error ? App.Error | string | undefined : never): HttpError_1; + } extends App.Error ? App.Error | string | undefined : never): never; /** - * Create a `Redirect` object. If thrown during request handling, SvelteKit will return a redirect response. + * Checks whether this is an error thrown by {@link error}. + * @param status The status to filter for. + * */ + export function isHttpError(e: unknown, status?: T | undefined): e is HttpError_1 & { + status: T extends undefined ? never : T; + }; + /** + * Redirect a request. When called during request handling, SvelteKit will return a redirect response. * Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it. * @param status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308. * @param location The location to redirect to. - */ - export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string | URL): Redirect_1; + * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location. + * @throws {Error} If the provided status is invalid. + * */ + export function redirect(status: NumericRange<300, 308>, location: string | URL): never; + /** + * Checks whether this is a redirect thrown by {@link redirect}. + * @param e The object to check. + * */ + export function isRedirect(e: unknown): e is Redirect_1; /** * Create a JSON `Response` object from the supplied data. * @param data The value that will be serialized as JSON. @@ -1718,26 +1754,32 @@ declare module '@sveltejs/kit' { /** * Create an `ActionFailure` object. * @param status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. - * @param data Data associated with the failure (e.g. validation errors) * */ - export function fail | undefined = undefined>(status: number, data?: T | undefined): ActionFailure; + export function fail(status: number): ActionFailure; /** - * @deprecated Use `resolveRoute` from `$app/paths` instead. - * - * Populate a route ID with params to resolve a pathname. - * @example - * ```js - * resolvePath( - * `/blog/[slug]/[...somethingElse]`, - * { - * slug: 'hello-world', - * somethingElse: 'something/else' - * } - * ); // `/blog/hello-world/something/else` - * ``` + * Create an `ActionFailure` object. + * @param status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599. + * @param data Data associated with the failure (e.g. validation errors) * */ - export function resolvePath(id: string, params: Record): string; + export function fail | undefined = undefined>(status: number, data: T): ActionFailure; + export type LessThan = TNumber extends TArray['length'] ? TArray[number] : LessThan; + export type NumericRange = Exclude, LessThan>; export const VERSION: string; + class HttpError_1 { + + constructor(status: number, body: { + message: string; + } extends App.Error ? (App.Error | string | undefined) : App.Error); + status: number; + body: App.Error; + toString(): string; + } + class Redirect_1 { + + constructor(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string); + status: 301 | 302 | 303 | 307 | 308 | 300 | 304 | 305 | 306; + location: string; + } } declare module '@sveltejs/kit/hooks' { @@ -1825,16 +1867,12 @@ declare module '@sveltejs/kit/node/polyfills' { /** * Make various web APIs available as globals: * - `crypto` - * - `fetch` (only in node < 18.11) - * - `Headers` (only in node < 18.11) - * - `Request` (only in node < 18.11) - * - `Response` (only in node < 18.11) + * - `File` */ export function installPolyfills(): void; } declare module '@sveltejs/kit/vite' { - export { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** * Returns the SvelteKit Vite plugins. * */ @@ -1915,15 +1953,12 @@ declare module '$app/navigation' { * * @param url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://kit.svelte.dev/docs/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app. * @param {Object} opts Options related to the navigation - * @param invalidateAll If `true`, all `load` functions of the page will be rerun. See https://kit.svelte.dev/docs/load#rerunning-load-functions for more info on invalidation. - * @param opts.state The state of the new/updated history entry * */ export const goto: (url: string | URL, opts?: { replaceState?: boolean; noScroll?: boolean; keepFocus?: boolean; invalidateAll?: boolean; - state?: any; }) => Promise; /** * Causes any `load` functions belonging to the currently active page to re-run if they depend on the `url` in question, via `fetch` or `depends`. Returns a `Promise` that resolves when the page is subsequently updated. @@ -1954,11 +1989,11 @@ declare module '$app/navigation' { * * This is the same behaviour that SvelteKit triggers when the user taps or mouses over an `` element with `data-sveltekit-preload-data`. * If the next navigation is to `href`, the values returned from load will be used, making navigation instantaneous. - * Returns a Promise that resolves when the preload is complete. + * Returns a Promise that resolves with the result of running the new route's `load` functions once the preload is complete. * * @param href Page to preload * */ - export const preloadData: (href: string) => Promise; + export const preloadData: (href: string) => Promise>; /** * Programmatically imports the code for routes that haven't yet been fetched. * Typically, you might call this to speed up subsequent navigation. @@ -1969,7 +2004,7 @@ declare module '$app/navigation' { * Returns a Promise that resolves when the modules have been imported. * * */ - export const preloadCode: (...urls: string[]) => Promise; + export const preloadCode: (url: string) => Promise; /** * A navigation interceptor that triggers before we navigate to a new URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls. * @@ -1998,6 +2033,16 @@ declare module '$app/navigation' { * `afterNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ export const afterNavigate: (callback: (navigation: import('@sveltejs/kit').AfterNavigate) => void) => void; + /** + * Programmatically create a new history entry with the given `$page.state`. To use the current URL, you can pass `''` as the first argument. Used for [shallow routing](https://kit.svelte.dev/docs/shallow-routing). + * + * */ + export const pushState: (url: string | URL, state: App.PageState) => void; + /** + * Programmatically replace the current history entry with the given `$page.state`. To use the current URL, you can pass `''` as the first argument. Used for [shallow routing](https://kit.svelte.dev/docs/shallow-routing). + * + * */ + export const replaceState: (url: string | URL, state: App.PageState) => void; type MaybePromise = T | Promise; } @@ -2060,6 +2105,7 @@ declare module '$app/stores' { * // interface Error {} * // interface Locals {} * // interface PageData {} + * // interface PageState {} * // interface Platform {} * } * } @@ -2092,6 +2138,11 @@ declare namespace App { */ export interface PageData {} + /** + * The shape of the `$page.state` object, which can be manipulated using the [`pushState`](https://kit.svelte.dev/docs/modules#$app-navigation-pushstate) and [`replaceState`](https://kit.svelte.dev/docs/modules#$app-navigation-replacestate) functions from `$app/navigation`. + */ + export interface PageState {} + /** * If your adapter provides [platform-specific context](https://kit.svelte.dev/docs/adapters#platform-specific-context) via `event.platform`, you can specify it here. */ @@ -2154,7 +2205,7 @@ declare module '__sveltekit/paths' { * > If a value for `config.kit.paths.assets` is specified, it will be replaced with `'/_svelte_kit_assets'` during `vite dev` or `vite preview`, since the assets don't yet live at their eventual URL. */ export let assets: '' | `https://${string}` | `http://${string}` | '/_svelte_kit_assets'; - export let relative: boolean | undefined; // TODO in 2.0, make this a `boolean` that defaults to `true` + export let relative: boolean; export function reset(): void; export function override(paths: { base: string; assets: string }): void; export function set_assets(path: string): void; diff --git a/packages/migrate/migrations/routes/migrate_page_js/index.spec.js b/packages/migrate/migrations/routes/migrate_page_js/index.spec.js index 5e698e739dc1..3ea58066d1aa 100644 --- a/packages/migrate/migrations/routes/migrate_page_js/index.spec.js +++ b/packages/migrate/migrations/routes/migrate_page_js/index.spec.js @@ -1,8 +1,8 @@ import { assert, test } from 'vitest'; -import { read_samples } from '../utils.js'; import { migrate_page } from './index.js'; +import { read_samples } from '../../../utils.js'; -for (const sample of read_samples(import.meta.url)) { +for (const sample of read_samples(new URL('./samples.md', import.meta.url))) { test(sample.description, () => { const actual = migrate_page(sample.before, sample.filename ?? '+page.js'); assert.equal(actual, sample.after); diff --git a/packages/migrate/migrations/routes/migrate_page_server/index.spec.js b/packages/migrate/migrations/routes/migrate_page_server/index.spec.js index e3a4611ccb31..82a0e354b654 100644 --- a/packages/migrate/migrations/routes/migrate_page_server/index.spec.js +++ b/packages/migrate/migrations/routes/migrate_page_server/index.spec.js @@ -1,8 +1,8 @@ import { assert, test } from 'vitest'; -import { read_samples } from '../utils.js'; import { migrate_page_server } from './index.js'; +import { read_samples } from '../../../utils.js'; -for (const sample of read_samples(import.meta.url)) { +for (const sample of read_samples(new URL('./samples.md', import.meta.url))) { test(sample.description, () => { const actual = migrate_page_server(sample.before, sample.filename ?? '+page.server.js'); assert.equal(actual, sample.after); diff --git a/packages/migrate/migrations/routes/migrate_scripts/index.spec.js b/packages/migrate/migrations/routes/migrate_scripts/index.spec.js index 38f9ebcf612a..a52fc7128ff1 100644 --- a/packages/migrate/migrations/routes/migrate_scripts/index.spec.js +++ b/packages/migrate/migrations/routes/migrate_scripts/index.spec.js @@ -1,8 +1,8 @@ import { assert, test } from 'vitest'; -import { read_samples } from '../utils.js'; import { migrate_scripts } from './index.js'; +import { read_samples } from '../../../utils.js'; -for (const sample of read_samples(import.meta.url)) { +for (const sample of read_samples(new URL('./samples.md', import.meta.url))) { test(sample.description, () => { const actual = migrate_scripts( sample.before, diff --git a/packages/migrate/migrations/routes/migrate_server/index.spec.js b/packages/migrate/migrations/routes/migrate_server/index.spec.js index 188ba33b6ae0..8ad424534ef0 100644 --- a/packages/migrate/migrations/routes/migrate_server/index.spec.js +++ b/packages/migrate/migrations/routes/migrate_server/index.spec.js @@ -1,8 +1,8 @@ import { assert, test } from 'vitest'; -import { read_samples } from '../utils.js'; import { migrate_server } from './index.js'; +import { read_samples } from '../../../utils.js'; -for (const sample of read_samples(import.meta.url)) { +for (const sample of read_samples(new URL('./samples.md', import.meta.url))) { test(sample.description, () => { const actual = migrate_server(sample.before); assert.equal(actual, sample.after); diff --git a/packages/migrate/migrations/routes/utils.js b/packages/migrate/migrations/routes/utils.js index ca6c375a9518..0b8073e6c0fc 100644 --- a/packages/migrate/migrations/routes/utils.js +++ b/packages/migrate/migrations/routes/utils.js @@ -1,4 +1,3 @@ -import fs from 'node:fs'; import ts from 'typescript'; import MagicString from 'magic-string'; import { comment, indent_at_line } from '../../utils.js'; @@ -308,35 +307,6 @@ export function parse(content) { } } -/** @param {string} test_file */ -export function read_samples(test_file) { - const markdown = fs.readFileSync(new URL('./samples.md', test_file), 'utf8'); - const samples = markdown - .split(/^##/gm) - .slice(1) - .map((block) => { - const description = block.split('\n')[0]; - const before = /```(js|ts|svelte) before\n([^]*?)\n```/.exec(block); - const after = /```(js|ts|svelte) after\n([^]*?)\n```/.exec(block); - - const match = /> file: (.+)/.exec(block); - - return { - description, - before: before ? before[2] : '', - after: after ? after[2] : '', - filename: match?.[1], - solo: block.includes('> solo') - }; - }); - - if (samples.some((sample) => sample.solo)) { - return samples.filter((sample) => sample.solo); - } - - return samples; -} - /** * @param {ts.Node} node * @param {MagicString} code diff --git a/packages/migrate/migrations/svelte-4/index.js b/packages/migrate/migrations/svelte-4/index.js index 49cd16f7d0e3..fac2bffcb7f8 100644 --- a/packages/migrate/migrations/svelte-4/index.js +++ b/packages/migrate/migrations/svelte-4/index.js @@ -2,8 +2,8 @@ import colors from 'kleur'; import fs from 'node:fs'; import prompts from 'prompts'; import glob from 'tiny-glob/sync.js'; -import { bail, check_git } from '../../utils.js'; -import { update_js_file, update_pkg_json, update_svelte_file } from './migrate.js'; +import { bail, check_git, update_js_file, update_svelte_file } from '../../utils.js'; +import { transform_code, transform_svelte_code, update_pkg_json } from './migrate.js'; export async function migrate() { if (!fs.existsSync('package.json')) { @@ -78,9 +78,11 @@ export async function migrate() { for (const file of files) { if (extensions.some((ext) => file.endsWith(ext))) { if (svelte_extensions.some((ext) => file.endsWith(ext))) { - update_svelte_file(file, migrate_transition.value); + update_svelte_file(file, transform_code, (code) => + transform_svelte_code(code, migrate_transition.value) + ); } else { - update_js_file(file); + update_js_file(file, transform_code); } } } diff --git a/packages/migrate/migrations/svelte-4/migrate.js b/packages/migrate/migrations/svelte-4/migrate.js index e30660918ee7..3bd35914c8d0 100644 --- a/packages/migrate/migrations/svelte-4/migrate.js +++ b/packages/migrate/migrations/svelte-4/migrate.js @@ -1,6 +1,6 @@ import fs from 'node:fs'; import { Project, ts, Node } from 'ts-morph'; -import semver from 'semver'; +import { log_migration, log_on_ts_modification, update_pkg } from '../../utils.js'; export function update_pkg_json() { fs.writeFileSync( @@ -13,93 +13,31 @@ export function update_pkg_json() { * @param {string} content */ export function update_pkg_json_content(content) { - const indent = content.split('\n')[1].match(/^\s+/)?.[0] || ' '; - const pkg = JSON.parse(content); - - /** - * @param {string} name - * @param {string} version - * @param {string} [additional] - */ - function update_pkg(name, version, additional = '') { - if (pkg.dependencies?.[name]) { - const existing_range = pkg.dependencies[name]; - - if (semver.validRange(existing_range) && !semver.subset(existing_range, version)) { - log_migration(`Updated ${name} to ${version} ${additional}`); - pkg.dependencies[name] = version; - } - } - - if (pkg.devDependencies?.[name]) { - const existing_range = pkg.devDependencies[name]; - - if (semver.validRange(existing_range) && !semver.subset(existing_range, version)) { - log_migration(`Updated ${name} to ${version} ${additional}`); - pkg.devDependencies[name] = version; - } - } - } - - update_pkg('svelte', '^4.0.0'); - update_pkg('svelte-check', '^3.4.3'); - update_pkg('svelte-preprocess', '^5.0.3'); - update_pkg('@sveltejs/kit', '^1.20.4'); - update_pkg('@sveltejs/vite-plugin-svelte', '^2.4.1'); - update_pkg( - 'svelte-loader', - '^3.1.8', - ' (if you are still on webpack 4, you need to update to webpack 5)' - ); - update_pkg('rollup-plugin-svelte', '^7.1.5'); - update_pkg('prettier-plugin-svelte', '^2.10.1'); - update_pkg('eslint-plugin-svelte', '^2.30.0'); - update_pkg( - 'eslint-plugin-svelte3', - '^4.0.0', - ' (this package is deprecated, use eslint-plugin-svelte instead. More info: https://svelte.dev/docs/v4-migration-guide#new-eslint-package)' - ); - update_pkg( - 'typescript', - '^5.0.0', - ' (this might introduce new type errors due to breaking changes within TypeScript)' - ); - - return JSON.stringify(pkg, null, indent); -} - -/** - * @param {string} file_path - * @param {boolean} migrate_transition - */ -export function update_svelte_file(file_path, migrate_transition) { - try { - const content = fs.readFileSync(file_path, 'utf-8'); - const updated = content.replace( - /([^]+?)<\/script>(\n*)/g, - (_match, attrs, contents, whitespace) => { - return `${transform_code( - contents, - (attrs.includes('lang=') || attrs.includes('type=')) && - (attrs.includes('ts') || attrs.includes('typescript')) - )}${whitespace}`; - } - ); - fs.writeFileSync(file_path, transform_svelte_code(updated, migrate_transition), 'utf-8'); - } catch (e) { - console.error(`Error updating ${file_path}:`, e); - } -} - -/** @param {string} file_path */ -export function update_js_file(file_path) { - try { - const content = fs.readFileSync(file_path, 'utf-8'); - const updated = transform_code(content, file_path.endsWith('.ts')); - fs.writeFileSync(file_path, updated, 'utf-8'); - } catch (e) { - console.error(`Error updating ${file_path}:`, e); - } + return update_pkg(content, [ + ['svelte', '^4.0.0'], + ['svelte-check', '^3.4.3'], + ['svelte-preprocess', '^5.0.3'], + ['@sveltejs/kit', '^1.20.4'], + ['@sveltejs/vite-plugin-svelte', '^2.4.1'], + [ + 'svelte-loader', + '^3.1.8', + ' (if you are still on webpack 4, you need to update to webpack 5)' + ], + ['rollup-plugin-svelte', '^7.1.5'], + ['prettier-plugin-svelte', '^2.10.1'], + ['eslint-plugin-svelte', '^2.30.0'], + [ + 'eslint-plugin-svelte3', + '^4.0.0', + ' (this package is deprecated, use eslint-plugin-svelte instead. More info: https://svelte.dev/docs/v4-migration-guide#new-eslint-package)' + ], + [ + 'typescript', + '^5.0.0', + ' (this might introduce new type errors due to breaking changes within TypeScript)' + ] + ]); } /** @@ -401,28 +339,3 @@ function replaceInJsDoc(source, replacer) { } }); } - -const logged_migrations = new Set(); - -/** - * @param {import('ts-morph').SourceFile} source - * @param {string} text - */ -function log_on_ts_modification(source, text) { - let logged = false; - const log = () => { - if (!logged) { - logged = true; - log_migration(text); - } - }; - source.onModified(log); - return () => source.onModified(log, false); -} - -/** @param {string} text */ -function log_migration(text) { - if (logged_migrations.has(text)) return; - console.log(text); - logged_migrations.add(text); -} diff --git a/packages/migrate/migrations/sveltekit-2/index.js b/packages/migrate/migrations/sveltekit-2/index.js new file mode 100644 index 000000000000..afeddadafd08 --- /dev/null +++ b/packages/migrate/migrations/sveltekit-2/index.js @@ -0,0 +1,159 @@ +import colors from 'kleur'; +import fs from 'node:fs'; +import prompts from 'prompts'; +import semver from 'semver'; +import glob from 'tiny-glob/sync.js'; +import { bail, check_git, update_js_file, update_svelte_file } from '../../utils.js'; +import { + transform_code, + update_pkg_json, + update_svelte_config, + update_tsconfig +} from './migrate.js'; +import { migrate as migrate_svelte_4 } from '../svelte-4/index.js'; + +export async function migrate() { + if (!fs.existsSync('package.json')) { + bail('Please re-run this script in a directory with a package.json'); + } + + if (!fs.existsSync('svelte.config.js')) { + bail('Please re-run this script in a directory with a svelte.config.js'); + } + + console.log( + colors + .bold() + .yellow( + '\nThis will update files in the current directory\n' + + "If you're inside a monorepo, run this in individual project directories rather than the workspace root.\n" + ) + ); + + const use_git = check_git(); + + const response = await prompts({ + type: 'confirm', + name: 'value', + message: 'Continue?', + initial: false + }); + + if (!response.value) { + process.exit(1); + } + + const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); + const svelte_dep = pkg.devDependencies?.svelte ?? pkg.dependencies?.svelte; + if (svelte_dep === undefined) { + bail('Please install Svelte before continuing'); + } + + if (semver.validRange(svelte_dep) && semver.gtr('4.0.0', svelte_dep)) { + console.log( + colors + .bold() + .yellow( + '\nSvelteKit 2 requires Svelte 4 or newer. We recommend running the `svelte-4` migration first (`npx svelte-migrate svelte-4`).\n' + ) + ); + const response = await prompts({ + type: 'confirm', + name: 'value', + message: 'Run `svelte-4` migration now?', + initial: false + }); + if (!response.value) { + process.exit(1); + } else { + await migrate_svelte_4(); + console.log( + colors + .bold() + .green('`svelte-4` migration complete. Continue with `sveltekit-2` migration?\n') + ); + const response = await prompts({ + type: 'confirm', + name: 'value', + message: 'Continue?', + initial: false + }); + if (!response.value) { + process.exit(1); + } + } + } + + const folders = await prompts({ + type: 'multiselect', + name: 'value', + message: 'Which folders should be migrated?', + choices: fs + .readdirSync('.') + .filter( + (dir) => + fs.statSync(dir).isDirectory() && + dir !== 'node_modules' && + dir !== 'dist' && + !dir.startsWith('.') + ) + .map((dir) => ({ title: dir, value: dir, selected: dir === 'src' })) + }); + + if (!folders.value?.length) { + process.exit(1); + } + + update_pkg_json(); + update_tsconfig(); + update_svelte_config(); + + // const { default: config } = fs.existsSync('svelte.config.js') + // ? await import(pathToFileURL(path.resolve('svelte.config.js')).href) + // : { default: {} }; + + /** @type {string[]} */ + const svelte_extensions = /* config.extensions ?? - disabled because it would break .svx */ [ + '.svelte' + ]; + const extensions = [...svelte_extensions, '.ts', '.js']; + // For some reason {folders.value.join(',')} as part of the glob doesn't work and returns less files + const files = folders.value.flatMap( + /** @param {string} folder */ (folder) => + glob(`${folder}/**`, { filesOnly: true, dot: true }) + .map((file) => file.replace(/\\/g, '/')) + .filter((file) => !file.includes('/node_modules/')) + ); + + for (const file of files) { + if (extensions.some((ext) => file.endsWith(ext))) { + if (svelte_extensions.some((ext) => file.endsWith(ext))) { + update_svelte_file(file, transform_code, (code) => code); + } else { + update_js_file(file, transform_code); + } + } + } + + console.log(colors.bold().green('✔ Your project has been migrated')); + + console.log('\nRecommended next steps:\n'); + + const cyan = colors.bold().cyan; + + const tasks = [ + use_git && cyan('git commit -m "migration to SvelteKit 2"'), + 'Review the migration guide at https://kit.svelte.dev/docs/v2-migration-guide', + 'Read the updated docs at https://kit.svelte.dev/docs' + ].filter(Boolean); + + tasks.forEach((task, i) => { + console.log(` ${i + 1}: ${task}`); + }); + + console.log(''); + + if (use_git) { + console.log(`Run ${cyan('git diff')} to review changes.\n`); + } +} diff --git a/packages/migrate/migrations/sveltekit-2/migrate.js b/packages/migrate/migrations/sveltekit-2/migrate.js new file mode 100644 index 000000000000..c1e6892527ad --- /dev/null +++ b/packages/migrate/migrations/sveltekit-2/migrate.js @@ -0,0 +1,317 @@ +import fs from 'node:fs'; +import { Project, Node, SyntaxKind } from 'ts-morph'; +import { log_migration, log_on_ts_modification, update_pkg } from '../../utils.js'; +import path from 'node:path'; + +export function update_pkg_json() { + fs.writeFileSync( + 'package.json', + update_pkg_json_content(fs.readFileSync('package.json', 'utf8')) + ); +} + +/** + * @param {string} content + */ +export function update_pkg_json_content(content) { + return update_pkg(content, [ + // All other bumps are done as part of the Svelte 4 migration + ['@sveltejs/kit', '^2.0.0'], + ['@sveltejs/adapter-static', '^3.0.0'], + ['vite', '^5.0.0'], + ['vitest', '^1.0.0'], + ['typescript', '^5.0.0'], // should already be done by Svelte 4 migration, but who knows + [ + '@sveltejs/vite-plugin-svelte', + '^3.0.0', + ' (vite-plugin-svelte is a peer dependency of SvelteKit now)', + 'devDependencies' + ] + ]); +} + +export function update_tsconfig() { + fs.writeFileSync( + 'tsconfig.json', + update_tsconfig_content(fs.readFileSync('tsconfig.json', 'utf8')) + ); +} + +/** @param {string} content */ +export function update_tsconfig_content(content) { + if (!content.includes('"extends"')) { + // Don't touch the tsconfig if people opted out of our default config + return content; + } + + let updated = content + .split('\n') + .filter( + (line) => !line.includes('importsNotUsedAsValues') && !line.includes('preserveValueImports') + ) + .join('\n'); + if (updated !== content) { + log_migration( + 'Removed deprecated `importsNotUsedAsValues` and `preserveValueImports`' + + ' from tsconfig.json: https://kit.svelte.dev/docs/v2-migration-guide#updated-dependency-requirements' + ); + } + + content = updated; + updated = content.replace('"moduleResolution": "node"', '"moduleResolution": "bundler"'); + if (updated !== content) { + log_migration( + 'Updated `moduleResolution` to `bundler`' + + ' in tsconfig.json: https://kit.svelte.dev/docs/v2-migration-guide#updated-dependency-requirements' + ); + } + + if (content.includes('"paths":') || content.includes('"baseUrl":')) { + log_migration( + '`paths` and/or `baseUrl` detected in your tsconfig.json - remove it and use `kit.alias` instead: https://kit.svelte.dev/docs/v2-migration-guide#generated-tsconfigjson-is-more-strict' + ); + } + + return updated; +} + +export function update_svelte_config() { + fs.writeFileSync( + 'svelte.config.js', + update_svelte_config_content(fs.readFileSync('svelte.config.js', 'utf8')) + ); +} + +/** + * @param {string} code + */ +export function update_svelte_config_content(code) { + const regex = /\s*dangerZone:\s*{[^}]*},?/g; + const result = code.replace(regex, ''); + if (result !== code) { + log_migration( + 'Removed `dangerZone` from svelte.config.js: https://kit.svelte.dev/docs/v2-migration-guide#server-fetches-are-not-trackable-anymore' + ); + } + + const project = new Project({ useInMemoryFileSystem: true }); + const source = project.createSourceFile('svelte.ts', result); + + const namedImport = get_import(source, '@sveltejs/kit/vite', 'vitePreprocess'); + if (!namedImport) return result; + + const logger = log_on_ts_modification( + source, + 'Changed `vitePreprocess` import: https://kit.svelte.dev/docs/v2-migration-guide#vitepreprocess-is-no-longer-exported-from-sveltejs-kit-vite' + ); + + if (namedImport.getParent().getParent().getNamedImports().length === 1) { + namedImport + .getParent() + .getParent() + .getParent() + .setModuleSpecifier('@sveltejs/vite-plugin-svelte'); + } else { + namedImport.remove(); + const vps = source.getImportDeclaration( + (i) => i.getModuleSpecifierValue() === '@sveltejs/vite-plugin-svelte' + ); + if (vps) { + vps.addNamedImport('vitePreprocess'); + } else { + source.addImportDeclaration({ + moduleSpecifier: '@sveltejs/vite-plugin-svelte', + namedImports: ['vitePreprocess'] + }); + } + } + + logger(); + return source.getFullText(); +} + +/** + * @param {string} code + * @param {boolean} _is_ts + * @param {string} file_path + */ +export function transform_code(code, _is_ts, file_path) { + const project = new Project({ useInMemoryFileSystem: true }); + const source = project.createSourceFile('svelte.ts', code); + remove_throws(source); + add_cookie_note(file_path, source); + replace_resolve_path(source); + return source.getFullText(); +} + +/** + * `throw redirect(..)` -> `redirect(..)` + * @param {import('ts-morph').SourceFile} source + */ +function remove_throws(source) { + const logger = log_on_ts_modification( + source, + 'Removed `throw` from redirect/error functions: https://kit.svelte.dev/docs/v2-migration-guide#redirect-and-error-are-no-longer-thrown-by-you' + ); + + /** @param {string} id */ + function remove_throw(id) { + const namedImport = get_import(source, '@sveltejs/kit', id); + if (!namedImport) return; + for (const id of namedImport.getNameNode().findReferencesAsNodes()) { + const call_expression = id.getParent(); + const throw_stmt = call_expression?.getParent(); + if (Node.isCallExpression(call_expression) && Node.isThrowStatement(throw_stmt)) { + throw_stmt.replaceWithText((writer) => { + writer.setIndentationLevel(0); + writer.write(call_expression.getText() + ';'); + }); + } + } + } + + remove_throw('redirect'); + remove_throw('error'); + + logger(); +} + +/** + * Adds `path` option to `cookies.set/delete/serialize` calls + * @param {string} file_path + * @param {import('ts-morph').SourceFile} source + */ +function add_cookie_note(file_path, source) { + const basename = path.basename(file_path); + if ( + basename !== '+page.js' && + basename !== '+page.ts' && + basename !== '+page.server.js' && + basename !== '+page.server.ts' && + basename !== '+server.js' && + basename !== '+server.ts' && + basename !== 'hooks.server.js' && + basename !== 'hooks.server.ts' + ) { + return; + } + + const logger = log_on_ts_modification( + source, + 'Remember to add the `path` option to `cookies.set/delete/serialize` calls: https://kit.svelte.dev/docs/v2-migration-guide#path-is-now-a-required-option-for-cookies' + ); + + const calls = []; + + for (const call of source.getDescendantsOfKind(SyntaxKind.CallExpression)) { + const expression = call.getExpression(); + if (!Node.isPropertyAccessExpression(expression)) { + continue; + } + + const name = expression.getName(); + if (name !== 'set' && name !== 'delete' && name !== 'serialize') { + continue; + } + + if (call.getText().includes('path')) { + continue; + } + + const options_arg = call.getArguments()[name === 'delete' ? 1 : 2]; + if (options_arg && !Node.isObjectLiteralExpression(options_arg)) { + continue; + } + + const parent_function = call.getFirstAncestor( + /** @returns {ancestor is import('ts-morph').FunctionDeclaration | import('ts-morph').FunctionExpression | import('ts-morph').ArrowFunction} */ + (ancestor) => { + // Check if this is inside a function + const fn_declaration = ancestor.asKind(SyntaxKind.FunctionDeclaration); + const fn_expression = ancestor.asKind(SyntaxKind.FunctionExpression); + const arrow_fn_expression = ancestor.asKind(SyntaxKind.ArrowFunction); + return !!fn_declaration || !!fn_expression || !!arrow_fn_expression; + } + ); + if (!parent_function) { + continue; + } + + const expression_text = expression.getExpression().getText(); + if ( + expression_text !== 'cookies' && + (!expression_text.includes('.') || + !parent_function.getParameter(expression_text.split('.')[0])) + ) { + continue; + } + + const parent = call.getFirstAncestorByKind(SyntaxKind.Block); + if (!parent) { + continue; + } + + calls.push(() => + call.replaceWithText((writer) => { + writer.setIndentationLevel(0); // prevent ts-morph from being unhelpful and adding its own indentation + writer.write('/* @migration task: add path argument */ ' + call.getText()); + }) + ); + } + + for (const call of calls) { + call(); + } + + logger(); +} + +/** + * `resolvePath` from `@sveltejs/kit` -> `resolveRoute` from `$app/paths` + * @param {import('ts-morph').SourceFile} source + */ +function replace_resolve_path(source) { + const namedImport = get_import(source, '@sveltejs/kit', 'resolvePath'); + if (!namedImport) return; + + const logger = log_on_ts_modification( + source, + 'Replaced `resolvePath` with `resolveRoute`: https://kit.svelte.dev/docs/v2-migration-guide#resolvePath-has-been-removed' + ); + + for (const id of namedImport.getNameNode().findReferencesAsNodes()) { + id.replaceWithText('resolveRoute'); + } + if (namedImport.getParent().getParent().getNamedImports().length === 1) { + namedImport.getParent().getParent().getParent().remove(); + } else { + namedImport.remove(); + } + + const paths_import = source.getImportDeclaration( + (i) => i.getModuleSpecifierValue() === '$app/paths' + ); + if (paths_import) { + paths_import.addNamedImport('resolveRoute'); + } else { + source.addImportDeclaration({ + moduleSpecifier: '$app/paths', + namedImports: ['resolveRoute'] + }); + } + + logger(); +} + +/** + * @param {import('ts-morph').SourceFile} source + * @param {string} from + * @param {string} name + */ +function get_import(source, from, name) { + return source + .getImportDeclarations() + .filter((i) => i.getModuleSpecifierValue() === from) + .flatMap((i) => i.getNamedImports()) + .find((i) => i.getName() === name); +} diff --git a/packages/migrate/migrations/sveltekit-2/migrate.spec.js b/packages/migrate/migrations/sveltekit-2/migrate.spec.js new file mode 100644 index 000000000000..a297d947657c --- /dev/null +++ b/packages/migrate/migrations/sveltekit-2/migrate.spec.js @@ -0,0 +1,32 @@ +import { assert, test } from 'vitest'; +import { + transform_code, + update_svelte_config_content, + update_tsconfig_content +} from './migrate.js'; +import { read_samples } from '../../utils.js'; + +for (const sample of read_samples(new URL('./svelte-config-samples.md', import.meta.url))) { + test('svelte.config.js: ' + sample.description, () => { + const actual = update_svelte_config_content(sample.before); + assert.equal(actual, sample.after); + }); +} + +for (const sample of read_samples(new URL('./tsconfig-samples.md', import.meta.url))) { + test('tsconfig.json: ' + sample.description, () => { + const actual = update_tsconfig_content(sample.before); + assert.equal(actual, sample.after); + }); +} + +for (const sample of read_samples(new URL('./tsjs-samples.md', import.meta.url))) { + test('JS/TS file: ' + sample.description, () => { + const actual = transform_code( + sample.before, + sample.filename?.endsWith('.ts') ?? false, + sample.filename ?? '+page.js' + ); + assert.equal(actual, sample.after); + }); +} diff --git a/packages/migrate/migrations/sveltekit-2/svelte-config-samples.md b/packages/migrate/migrations/sveltekit-2/svelte-config-samples.md new file mode 100644 index 000000000000..daa482375f39 --- /dev/null +++ b/packages/migrate/migrations/sveltekit-2/svelte-config-samples.md @@ -0,0 +1,126 @@ +## Removes dangerZone (1) + +```js before +export default { + kit: { + foo: bar, + dangerZone: { + trackServerFetches: true + }, + baz: qux + } +}; +``` + +```js after +export default { + kit: { + foo: bar, + baz: qux + } +}; +``` + +## Removes dangerZone (2) + +```js before +export default { + kit: { + foo: bar, + dangerZone: { + trackServerFetches: true + } + } +}; +``` + + +```js after +export default { + kit: { + foo: bar, + } +}; +``` + +## Replaces vitePreprocess import (1) + +```js before +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/kit/vite'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://kit.svelte.dev/docs/integrations#preprocessors + // for more information about preprocessors + preprocess: vitePreprocess(), + + kit: { + adapter: adapter() + } +}; + +export default config; +``` + +```js after +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://kit.svelte.dev/docs/integrations#preprocessors + // for more information about preprocessors + preprocess: vitePreprocess(), + + kit: { + adapter: adapter() + } +}; + +export default config; +``` + +## Replaces vitePreprocess import (2) + +```js before +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess, foo } from '@sveltejs/kit/vite'; + +export default { + preprocess: vitePreprocess() +}; +``` + + +```js after +import adapter from '@sveltejs/adapter-auto'; +import { foo } from '@sveltejs/kit/vite'; +import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; + +export default { + preprocess: vitePreprocess() +}; +``` + +## Replaces vitePreprocess import (3) + +```js before +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess, foo } from '@sveltejs/kit/vite'; +import { a } from '@sveltejs/vite-plugin-svelte'; + +export default { + preprocess: vitePreprocess() +}; +``` + +```js after +import adapter from '@sveltejs/adapter-auto'; +import { foo } from '@sveltejs/kit/vite'; +import { a, vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +export default { + preprocess: vitePreprocess() +}; +``` diff --git a/packages/migrate/migrations/sveltekit-2/tsconfig-samples.md b/packages/migrate/migrations/sveltekit-2/tsconfig-samples.md new file mode 100644 index 000000000000..93d357fac974 --- /dev/null +++ b/packages/migrate/migrations/sveltekit-2/tsconfig-samples.md @@ -0,0 +1,40 @@ +## Removes importsNotUsedAsValues/preserveValueImports + +```json before +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "importsNotUsedAsValues": "error", + "preserveValueImports": true + } +} +``` + + +```json after +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + } +} +``` + +## Leaves tsconfig alone + +```json before +{ + "compilerOptions": { + "importsNotUsedAsValues": "error", + "preserveValueImports": true + } +} +``` + +```json after +{ + "compilerOptions": { + "importsNotUsedAsValues": "error", + "preserveValueImports": true + } +} +``` diff --git a/packages/migrate/migrations/sveltekit-2/tsjs-samples.md b/packages/migrate/migrations/sveltekit-2/tsjs-samples.md new file mode 100644 index 000000000000..499808ad7b24 --- /dev/null +++ b/packages/migrate/migrations/sveltekit-2/tsjs-samples.md @@ -0,0 +1,162 @@ +## Removes throws + +```js before +import { redirect, error } from '@sveltejs/kit'; + +throw redirect(); +redirect(); +throw error(); +error(); +function x() { + let redirect = true; + throw redirect(); +} +``` + +```js after +import { redirect, error } from '@sveltejs/kit'; + +redirect(); +redirect(); +error(); +error(); +function x() { + let redirect = true; + throw redirect(); +} +``` + +## Leaves redirect/error from other sources alone + +```js before +import { redirect, error } from 'somewhere-else'; + +throw redirect(); +redirect(); +throw error(); +error(); +``` + +```js after +import { redirect, error } from 'somewhere-else'; + +throw redirect(); +redirect(); +throw error(); +error(); +``` + +## Notes cookie migration + +```js before +export function load({ cookies }) { + cookies.set('foo', 'bar'); +} +``` + +```js after +export function load({ cookies }) { + /* @migration task: add path argument */ cookies.set('foo', 'bar'); +} +``` + +## Notes cookie migration with multiple occurences + +```js before +export function load({ cookies }) { + cookies.delete('foo'); + cookies.set('x', 'y', { z: '' }); +} +``` + +```js after +export function load({ cookies }) { + /* @migration task: add path argument */ cookies.delete('foo'); + /* @migration task: add path argument */ cookies.set('x', 'y', { z: '' }); +} +``` + +## Handles non-destructured argument + +```js before +export function load(event) { + event.cookies.set('x', 'y'); +} +``` + +```js after +export function load(event) { + /* @migration task: add path argument */ event.cookies.set('x', 'y'); +} +``` + +## Recognizes cookies false positives + +```js before +export function load({ cookies }) { + cookies.set('foo', 'bar', { path: '/' }); +} + +export function foo(event) { + x.cookies.set('foo', 'bar'); +} + +cookies.set('foo', 'bar'); +``` + +```js after +export function load({ cookies }) { + cookies.set('foo', 'bar', { path: '/' }); +} + +export function foo(event) { + x.cookies.set('foo', 'bar'); +} + +cookies.set('foo', 'bar'); +``` + +## Replaces resolvePath + +```js before +import { resolvePath } from '@sveltejs/kit'; + +resolvePath('x', y); +``` + + +```js after +import { resolveRoute } from "$app/paths"; + +resolveRoute('x', y); +``` + +## Replaces resolvePath taking care of imports + +```js before +import { resolvePath, x } from '@sveltejs/kit'; +import { y } from '$app/paths'; + +resolvePath('x'); +``` + +```js after +import { x } from '@sveltejs/kit'; +import { y, resolveRoute } from '$app/paths'; + +resolveRoute('x'); +``` + +## Doesn't replace resolvePath from other sources + +```js before +import { resolvePath } from 'x'; + +resolvePath('x'); +``` + +```js after +import { resolvePath } from 'x'; + +resolvePath('x'); +``` diff --git a/packages/migrate/package.json b/packages/migrate/package.json index 7578ab10354c..9003b285b42f 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -25,19 +25,19 @@ ], "dependencies": { "kleur": "^4.1.5", - "magic-string": "^0.30.0", + "magic-string": "^0.30.5", "prompts": "^2.4.2", - "semver": "^7.5.3", + "semver": "^7.5.4", "tiny-glob": "^0.2.9", - "ts-morph": "^21.0.0", - "typescript": "^5.0.4" + "ts-morph": "^21.0.1", + "typescript": "^5.3.3" }, "devDependencies": { - "@types/node": "^16.18.6", - "@types/prompts": "^2.4.1", - "@types/semver": "^7.5.0", + "@types/node": "^18.19.3", + "@types/prompts": "^2.4.9", + "@types/semver": "^7.5.6", "prettier": "^3.1.1", - "vitest": "^0.34.5" + "vitest": "^1.0.4" }, "scripts": { "test": "vitest run", diff --git a/packages/migrate/utils.js b/packages/migrate/utils.js index b7e4c775899d..033ec46d7a6f 100644 --- a/packages/migrate/utils.js +++ b/packages/migrate/utils.js @@ -4,6 +4,7 @@ import colors from 'kleur'; import ts from 'typescript'; import MagicString from 'magic-string'; import { execFileSync, execSync } from 'node:child_process'; +import semver from 'semver'; /** @param {string} message */ export function bail(message) { @@ -198,3 +199,146 @@ export function walk(cwd, dirs = false) { export function posixify(str) { return str.replace(/\\/g, '/'); } + +/** + * @param {string} content + * @param {Array<[string, string, string?, ('dependencies' | 'devDependencies')?]>} updates + */ +export function update_pkg(content, updates) { + const indent = content.split('\n')[1].match(/^\s+/)?.[0] || ' '; + const pkg = JSON.parse(content); + + /** + * @param {string} name + * @param {string} version + * @param {string} [additional] + * @param {'dependencies' | 'devDependencies' | undefined} [insert] + */ + function update_pkg(name, version, additional = '', insert) { + if (pkg.dependencies?.[name]) { + const existing_range = pkg.dependencies[name]; + + if (semver.validRange(existing_range) && !semver.subset(existing_range, version)) { + log_migration(`Updated ${name} to ${version} ${additional}`); + pkg.dependencies[name] = version; + } + } + + if (pkg.devDependencies?.[name]) { + const existing_range = pkg.devDependencies[name]; + + if (semver.validRange(existing_range) && !semver.subset(existing_range, version)) { + log_migration(`Updated ${name} to ${version} ${additional}`); + pkg.devDependencies[name] = version; + } + } + + if (insert && !pkg[insert]?.[name]) { + if (!pkg[insert]) pkg[insert] = {}; + pkg[insert][name] = version; + log_migration(`Added ${name} version ${version} ${additional}`); + } + } + + for (const update of updates) { + update_pkg(...update); + } + + return JSON.stringify(pkg, null, indent); +} + +const logged_migrations = new Set(); + +/** + * @param {import('ts-morph').SourceFile} source + * @param {string} text + */ +export function log_on_ts_modification(source, text) { + let logged = false; + const log = () => { + if (!logged) { + logged = true; + log_migration(text); + } + }; + source.onModified(log); + return () => source.onModified(log, false); +} + +/** @param {string} text */ +export function log_migration(text) { + if (logged_migrations.has(text)) return; + console.log(text); + logged_migrations.add(text); +} + +/** + * Parses the scripts contents and invoked `transform_script_code` with it, then runs the result through `transform_svelte_code`. + * The result is written back to disk. + * @param {string} file_path + * @param {(code: string, is_ts: boolean, file_path: string) => string} transform_script_code + * @param {(code: string, file_path: string) => string} transform_svelte_code + */ +export function update_svelte_file(file_path, transform_script_code, transform_svelte_code) { + try { + const content = fs.readFileSync(file_path, 'utf-8'); + const updated = content.replace( + /([^]+?)<\/script>(\n*)/g, + (_match, attrs, contents, whitespace) => { + return `${transform_script_code( + contents, + (attrs.includes('lang=') || attrs.includes('type=')) && + (attrs.includes('ts') || attrs.includes('typescript')), + file_path + )}${whitespace}`; + } + ); + fs.writeFileSync(file_path, transform_svelte_code(updated, file_path), 'utf-8'); + } catch (e) { + console.error(`Error updating ${file_path}:`, e); + } +} + +/** + * Reads the file and invokes `transform_code` with its contents. The result is written back to disk. + * @param {string} file_path + * @param {(code: string, is_ts: boolean, file_path: string) => string} transform_code + */ +export function update_js_file(file_path, transform_code) { + try { + const content = fs.readFileSync(file_path, 'utf-8'); + const updated = transform_code(content, file_path.endsWith('.ts'), file_path); + fs.writeFileSync(file_path, updated, 'utf-8'); + } catch (e) { + console.error(`Error updating ${file_path}:`, e); + } +} + +/** @param {string | URL} test_file */ +export function read_samples(test_file) { + const markdown = fs.readFileSync(test_file, 'utf8').replaceAll('\r\n', '\n'); + const samples = markdown + .split(/^##/gm) + .slice(1) + .map((block) => { + const description = block.split('\n')[0]; + const before = /```(js|ts|svelte) before\n([^]*?)\n```/.exec(block); + const after = /```(js|ts|svelte) after\n([^]*?)\n```/.exec(block); + + const match = /> file: (.+)/.exec(block); + + return { + description, + before: before ? before[2] : '', + after: after ? after[2] : '', + filename: match?.[1], + solo: block.includes('> solo') + }; + }); + + if (samples.some((sample) => sample.solo)) { + return samples.filter((sample) => sample.solo); + } + + return samples; +} diff --git a/packages/package/package.json b/packages/package/package.json index 677dff7d5e3a..f08ae1b5a9c4 100644 --- a/packages/package/package.json +++ b/packages/package/package.json @@ -14,15 +14,16 @@ "chokidar": "^3.5.3", "kleur": "^4.1.5", "sade": "^1.8.1", - "semver": "^7.5.3", - "svelte2tsx": "~0.6.19" + "semver": "^7.5.4", + "svelte2tsx": "~0.6.27" }, "devDependencies": { - "@types/node": "^16.18.6", - "@types/semver": "^7.5.0", - "svelte": "^4.2.7", - "svelte-preprocess": "^5.1.1", - "typescript": "^4.9.4", + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@types/node": "^18.19.3", + "@types/semver": "^7.5.6", + "svelte": "^4.2.8", + "svelte-preprocess": "^5.1.2", + "typescript": "^5.3.3", "uvu": "^0.5.6" }, "peerDependencies": { diff --git a/packages/package/src/typescript.js b/packages/package/src/typescript.js index 5d1e79878f57..5163676082e3 100644 --- a/packages/package/src/typescript.js +++ b/packages/package/src/typescript.js @@ -74,7 +74,7 @@ export async function transpile_ts(filename, source) { compilerOptions: { ...options, module: ts.ModuleKind.ESNext, - moduleResolution: ts.ModuleResolutionKind.NodeJs // switch this to bundler in the next major, although it probably doesn't make a difference + moduleResolution: ts.ModuleResolutionKind.NodeNext }, fileName: filename }).outputText; diff --git a/packages/package/test/fixtures/resolve-alias/svelte.config.js b/packages/package/test/fixtures/resolve-alias/svelte.config.js index 2cb56fa23a8f..e903a3ec1088 100644 --- a/packages/package/test/fixtures/resolve-alias/svelte.config.js +++ b/packages/package/test/fixtures/resolve-alias/svelte.config.js @@ -1,4 +1,4 @@ -import { vitePreprocess } from '../../../../kit/src/exports/vite/index.js'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; import { fileURLToPath } from 'node:url'; import path from 'node:path'; diff --git a/playgrounds/basic/package.json b/playgrounds/basic/package.json index e44c61f0dfad..72babc8b7f31 100644 --- a/playgrounds/basic/package.json +++ b/playgrounds/basic/package.json @@ -10,9 +10,10 @@ "devDependencies": { "@sveltejs/adapter-auto": "workspace:*", "@sveltejs/kit": "workspace:*", - "svelte": "^4.2.7", - "typescript": "^5.0.0", - "vite": "^4.4.9" + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "svelte": "^4.2.8", + "typescript": "^5.3.3", + "vite": "^5.0.8" }, "type": "module" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ff2d797d350e..6a360ffccac8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,38 +9,29 @@ importers: .: devDependencies: '@changesets/cli': - specifier: ^2.26.2 - version: 2.26.2 - '@rollup/plugin-commonjs': - specifier: ^25.0.0 - version: 25.0.0(rollup@3.29.4) - '@rollup/plugin-json': - specifier: ^6.0.0 - version: 6.0.0(rollup@3.29.4) - '@rollup/plugin-node-resolve': - specifier: ^15.0.1 - version: 15.0.1(rollup@3.29.4) + specifier: ^2.27.1 + version: 2.27.1 '@sveltejs/eslint-config': specifier: ^6.0.4 - version: 6.0.4(@typescript-eslint/eslint-plugin@6.0.0)(@typescript-eslint/parser@6.14.0)(eslint-config-prettier@9.0.0)(eslint-plugin-svelte@2.31.0)(eslint-plugin-unicorn@49.0.0)(eslint@8.52.0)(typescript@4.9.4) + version: 6.0.4(@typescript-eslint/eslint-plugin@6.14.0)(@typescript-eslint/parser@6.14.0)(eslint-config-prettier@9.1.0)(eslint-plugin-svelte@2.35.1)(eslint-plugin-unicorn@49.0.0)(eslint@8.55.0)(typescript@5.3.3) '@svitejs/changesets-changelog-github-compact': specifier: ^1.1.0 version: 1.1.0 '@typescript-eslint/eslint-plugin': - specifier: ^6.0.0 - version: 6.0.0(@typescript-eslint/parser@6.14.0)(eslint@8.52.0)(typescript@4.9.4) + specifier: ^6.14.0 + version: 6.14.0(@typescript-eslint/parser@6.14.0)(eslint@8.55.0)(typescript@5.3.3) eslint: - specifier: ^8.52.0 - version: 8.52.0 + specifier: ^8.55.0 + version: 8.55.0 eslint-config-prettier: - specifier: ^9.0.0 - version: 9.0.0(eslint@8.52.0) + specifier: ^9.1.0 + version: 9.1.0(eslint@8.55.0) eslint-plugin-svelte: - specifier: ^2.31.0 - version: 2.31.0(eslint@8.52.0)(svelte@4.2.7) + specifier: ^2.35.1 + version: 2.35.1(eslint@8.55.0)(svelte@4.2.8) eslint-plugin-unicorn: specifier: ^49.0.0 - version: 49.0.0(eslint@8.52.0) + version: 49.0.0(eslint@8.55.0) playwright: specifier: 1.30.0 version: 1.30.0 @@ -51,11 +42,11 @@ importers: specifier: ^3.29.4 version: 3.29.4 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 packages/adapter-auto: dependencies: @@ -66,62 +57,65 @@ importers: '@sveltejs/kit': specifier: workspace:^ version: link:../kit + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 packages/adapter-cloudflare: dependencies: '@cloudflare/workers-types': - specifier: ^4.20230404.0 - version: 4.20230404.0 + specifier: ^4.20231121.0 + version: 4.20231121.0 '@sveltejs/kit': - specifier: ^1.0.0 + specifier: ^1.0.0 || ^2.0.0 version: link:../kit esbuild: - specifier: ^0.18.11 - version: 0.18.11 + specifier: ^0.19.9 + version: 0.19.9 worktop: specifier: 0.8.0-next.15 version: 0.8.0-next.15 devDependencies: '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 '@types/ws': - specifier: ^8.5.3 - version: 8.5.3 + specifier: ^8.5.10 + version: 8.5.10 typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 packages/adapter-cloudflare-workers: dependencies: '@cloudflare/workers-types': - specifier: ^4.20230404.0 - version: 4.20230404.0 + specifier: ^4.20231121.0 + version: 4.20231121.0 '@iarna/toml': specifier: ^2.2.5 version: 2.2.5 '@sveltejs/kit': - specifier: ^1.0.0 + specifier: ^1.0.0 || ^2.0.0 version: link:../kit esbuild: - specifier: ^0.18.11 - version: 0.18.11 + specifier: ^0.19.9 + version: 0.19.9 devDependencies: '@cloudflare/kv-asset-handler': specifier: ^0.3.0 version: 0.3.0 '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 packages/adapter-netlify: dependencies: @@ -129,82 +123,88 @@ importers: specifier: ^2.2.5 version: 2.2.5 esbuild: - specifier: ^0.18.11 - version: 0.18.11 + specifier: ^0.19.9 + version: 0.19.9 set-cookie-parser: specifier: ^2.6.0 version: 2.6.0 devDependencies: '@netlify/functions': - specifier: ^2.0.1 - version: 2.0.2 + specifier: ^2.4.1 + version: 2.4.1 '@rollup/plugin-commonjs': - specifier: ^25.0.0 - version: 25.0.0(rollup@3.29.4) + specifier: ^25.0.7 + version: 25.0.7(rollup@4.8.0) '@rollup/plugin-json': - specifier: ^6.0.0 - version: 6.0.0(rollup@3.29.4) + specifier: ^6.1.0 + version: 6.1.0(rollup@4.8.0) '@rollup/plugin-node-resolve': - specifier: ^15.0.1 - version: 15.0.1(rollup@3.29.4) + specifier: ^15.2.3 + version: 15.2.3(rollup@4.8.0) '@sveltejs/kit': specifier: workspace:^ version: link:../kit + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 '@types/set-cookie-parser': - specifier: ^2.4.2 - version: 2.4.2 + specifier: ^2.4.7 + version: 2.4.7 rollup: - specifier: ^3.29.4 - version: 3.29.4 + specifier: ^4.8.0 + version: 4.8.0 typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/adapter-node: dependencies: '@rollup/plugin-commonjs': - specifier: ^25.0.0 - version: 25.0.0(rollup@3.29.4) + specifier: ^25.0.7 + version: 25.0.7(rollup@4.8.0) '@rollup/plugin-json': - specifier: ^6.0.0 - version: 6.0.0(rollup@3.29.4) + specifier: ^6.1.0 + version: 6.1.0(rollup@4.8.0) '@rollup/plugin-node-resolve': - specifier: ^15.0.1 - version: 15.0.1(rollup@3.29.4) + specifier: ^15.2.3 + version: 15.2.3(rollup@4.8.0) rollup: - specifier: ^3.7.0 - version: 3.29.4 + specifier: ^4.8.0 + version: 4.8.0 devDependencies: '@polka/url': - specifier: ^1.0.0-next.23 - version: 1.0.0-next.23 + specifier: 1.0.0-next.24 + version: 1.0.0-next.24 '@sveltejs/kit': specifier: workspace:^ version: link:../kit + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 c8: - specifier: ^8.0.0 - version: 8.0.0 + specifier: ^8.0.1 + version: 8.0.1 polka: - specifier: ^1.0.0-next.23 - version: 1.0.0-next.23 + specifier: 1.0.0-next.24 + version: 1.0.0-next.24 sirv: specifier: ^2.0.3 version: 2.0.3 typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/adapter-static: devDependencies: @@ -214,36 +214,42 @@ importers: '@sveltejs/kit': specifier: workspace:^ version: link:../kit + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 sirv: specifier: ^2.0.3 version: 2.0.3 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/adapter-static/test/apps/prerendered: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../../kit + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) sirv-cli: specifier: ^2.0.2 version: 2.0.2 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/adapter-static/test/apps/spa: devDependencies: @@ -253,42 +259,48 @@ importers: '@sveltejs/kit': specifier: workspace:^ version: link:../../../../kit + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) sirv-cli: specifier: ^2.0.2 version: 2.0.2 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/adapter-vercel: dependencies: '@vercel/nft': - specifier: ^0.24.0 - version: 0.24.0 + specifier: ^0.24.4 + version: 0.24.4 esbuild: - specifier: ^0.18.11 - version: 0.18.11 + specifier: ^0.19.9 + version: 0.19.9 devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../kit + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/amp: dependencies: '@sveltejs/kit': - specifier: ^1.0.0 + specifier: ^1.0.0 || ^2.0.0 version: link:../kit packages/create-svelte: @@ -304,8 +316,8 @@ importers: specifier: 1.30.0 version: 1.30.0 '@types/gitignore-parser': - specifier: ^0.0.2 - version: 0.0.2 + specifier: ^0.0.3 + version: 0.0.3 gitignore-parser: specifier: ^0.0.2 version: 0.0.2 @@ -313,26 +325,26 @@ importers: specifier: ^3.1.1 version: 3.1.1 prettier-plugin-svelte: - specifier: ^3.0.0 - version: 3.0.3(prettier@3.1.1)(svelte@4.2.7) + specifier: ^3.1.2 + version: 3.1.2(prettier@3.1.1)(svelte@4.2.8) sucrase: - specifier: ^3.29.0 - version: 3.29.0 + specifier: ^3.34.0 + version: 3.34.0 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 tiny-glob: specifier: ^0.2.9 version: 0.2.9 vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/create-svelte/templates/default: dependencies: '@fontsource/fira-mono': - specifier: ^5.0.5 - version: 5.0.5 + specifier: ^5.0.8 + version: 5.0.8 devDependencies: '@neoconfetti/svelte': specifier: ^1.0.0 @@ -343,15 +355,18 @@ importers: '@sveltejs/kit': specifier: workspace:* version: link:../../../kit + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.0 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 typescript: - specifier: ^5.0.0 - version: 5.0.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/create-svelte/templates/skeleton: devDependencies: @@ -362,51 +377,51 @@ importers: packages/enhanced-img: dependencies: magic-string: - specifier: ^0.30.0 + specifier: ^0.30.5 version: 0.30.5 svelte-parse-markup: - specifier: ^0.1.1 - version: 0.1.2(svelte@4.2.7) + specifier: ^0.1.2 + version: 0.1.2(svelte@4.2.8) vite-imagetools: - specifier: ^6.2.4 - version: 6.2.4(rollup@3.29.4) + specifier: ^6.2.7 + version: 6.2.7(rollup@4.8.0) devDependencies: '@types/estree': - specifier: ^1.0.2 - version: 1.0.3 + specifier: ^1.0.5 + version: 1.0.5 '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 estree-walker: specifier: ^3.0.3 version: 3.0.3 + rollup: + specifier: ^4.8.0 + version: 4.8.0 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.2 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) vitest: - specifier: ^0.34.0 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit: dependencies: - '@sveltejs/vite-plugin-svelte': - specifier: ^2.5.0 - version: 2.5.0(svelte@4.2.7)(vite@4.4.9) '@types/cookie': - specifier: ^0.5.1 - version: 0.5.1 + specifier: ^0.6.0 + version: 0.6.0 cookie: - specifier: ^0.5.0 - version: 0.5.0 + specifier: ^0.6.0 + version: 0.6.0 devalue: - specifier: ^4.3.1 - version: 4.3.1 + specifier: ^4.3.2 + version: 4.3.2 esm-env: specifier: ^1.0.0 version: 1.0.0 @@ -414,8 +429,8 @@ importers: specifier: ^4.1.5 version: 4.1.5 magic-string: - specifier: ^0.30.0 - version: 0.30.2 + specifier: ^0.30.5 + version: 0.30.5 mrmime: specifier: ^1.0.1 version: 1.0.1 @@ -426,51 +441,51 @@ importers: specifier: ^2.6.0 version: 2.6.0 sirv: - specifier: ^2.0.2 + specifier: ^2.0.3 version: 2.0.3 tiny-glob: specifier: ^0.2.9 version: 0.2.9 - undici: - specifier: ~5.26.2 - version: 5.26.3 devDependencies: '@playwright/test': specifier: 1.30.0 version: 1.30.0 + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) '@types/connect': - specifier: ^3.4.35 - version: 3.4.35 + specifier: ^3.4.38 + version: 3.4.38 '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 '@types/sade': - specifier: ^1.7.4 - version: 1.7.4 + specifier: ^1.7.8 + version: 1.7.8 '@types/set-cookie-parser': - specifier: ^2.4.2 - version: 2.4.2 + specifier: ^2.4.7 + version: 2.4.7 dts-buddy: - specifier: ^0.2.4 - version: 0.2.4 + specifier: ^0.4.3 + version: 0.4.3(typescript@5.3.3) rollup: - specifier: ^3.29.4 - version: 3.29.4 + specifier: ^4.8.0 + version: 4.8.0 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-preprocess: - specifier: ^5.1.1 - version: 5.1.1(postcss@8.4.31)(svelte@4.2.7)(typescript@4.9.4) + specifier: ^5.1.2 + version: 5.1.2(postcss@8.4.32)(svelte@4.2.8)(typescript@5.3.3) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/apps/amp: devDependencies: @@ -480,6 +495,9 @@ importers: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -487,104 +505,116 @@ importers: specifier: ^1.0.16 version: 1.0.16 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/apps/basics: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) cross-env: specifier: ^7.0.3 version: 7.0.3 marked: - specifier: ^11.0.0 - version: 11.0.0 + specifier: ^11.1.0 + version: 11.1.0 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/apps/dev-only: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) cross-env: specifier: ^7.0.3 version: 7.0.3 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/apps/embed: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) cross-env: specifier: ^7.0.3 version: 7.0.3 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/apps/options: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) cross-env: specifier: ^7.0.3 version: 7.0.3 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/apps/options-2: devDependencies: @@ -594,48 +624,54 @@ importers: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) cross-env: specifier: ^7.0.3 version: 7.0.3 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/apps/writes: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) cross-env: specifier: ^7.0.3 version: 7.0.3 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors: devDependencies: vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch: devDependencies: @@ -645,18 +681,21 @@ importers: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment: devDependencies: @@ -666,18 +705,21 @@ importers: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/prerenderable-not-prerendered: devDependencies: @@ -687,246 +729,285 @@ importers: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/private-dynamic-env: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/private-dynamic-env-dynamic-import: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/private-static-env: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) cross-env: specifier: ^7.0.3 version: 7.0.3 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/private-static-env-dynamic-import: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/server-only-folder: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/server-only-folder-dynamic-import: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/server-only-module: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/server-only-module-dynamic-import: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/build-errors/apps/syntax-error: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/prerendering/basics: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/prerendering/options: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/kit/test/prerendering/paths-base: devDependencies: '@sveltejs/kit': specifier: workspace:^ version: link:../../.. + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-check: - specifier: ^3.4.4 - version: 3.4.4(postcss@8.4.31)(svelte@4.2.7) + specifier: ^3.6.2 + version: 3.6.2(postcss@8.4.32)(svelte@4.2.8) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/migrate: dependencies: @@ -934,39 +1015,39 @@ importers: specifier: ^4.1.5 version: 4.1.5 magic-string: - specifier: ^0.30.0 - version: 0.30.2 + specifier: ^0.30.5 + version: 0.30.5 prompts: specifier: ^2.4.2 version: 2.4.2 semver: - specifier: ^7.5.3 - version: 7.5.3 + specifier: ^7.5.4 + version: 7.5.4 tiny-glob: specifier: ^0.2.9 version: 0.2.9 ts-morph: - specifier: ^21.0.0 + specifier: ^21.0.1 version: 21.0.1 typescript: - specifier: ^5.0.4 - version: 5.0.4 + specifier: ^5.3.3 + version: 5.3.3 devDependencies: '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 '@types/prompts': - specifier: ^2.4.1 - version: 2.4.1 + specifier: ^2.4.9 + version: 2.4.9 '@types/semver': - specifier: ^7.5.0 - version: 7.5.0 + specifier: ^7.5.6 + version: 7.5.6 prettier: specifier: ^3.1.1 version: 3.1.1 vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages/package: dependencies: @@ -980,27 +1061,30 @@ importers: specifier: ^1.8.1 version: 1.8.1 semver: - specifier: ^7.5.3 - version: 7.5.3 + specifier: ^7.5.4 + version: 7.5.4 svelte2tsx: - specifier: ~0.6.19 - version: 0.6.19(svelte@4.2.7)(typescript@4.9.4) + specifier: ~0.6.27 + version: 0.6.27(svelte@4.2.8)(typescript@5.3.3) devDependencies: + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 '@types/semver': - specifier: ^7.5.0 - version: 7.5.0 + specifier: ^7.5.6 + version: 7.5.6 svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 svelte-preprocess: - specifier: ^5.1.1 - version: 5.1.1(postcss@8.4.31)(svelte@4.2.7)(typescript@4.9.4) + specifier: ^5.1.2 + version: 5.1.2(postcss@8.4.32)(svelte@4.2.8)(typescript@5.3.3) typescript: - specifier: ^4.9.4 - version: 4.9.4 + specifier: ^5.3.3 + version: 5.3.3 uvu: specifier: ^0.5.6 version: 0.5.6 @@ -1013,15 +1097,18 @@ importers: '@sveltejs/kit': specifier: workspace:* version: link:../../packages/kit + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 typescript: - specifier: ^5.0.0 - version: 5.0.4 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) sites/kit.svelte.dev: dependencies: @@ -1049,31 +1136,34 @@ importers: version: link:../../packages/kit '@sveltejs/site-kit': specifier: 6.0.0-next.59 - version: 6.0.0-next.59(@sveltejs/kit@packages+kit)(svelte@4.2.7) + version: 6.0.0-next.59(@sveltejs/kit@packages+kit)(svelte@4.2.8) + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.1 + version: 3.0.1(svelte@4.2.8)(vite@5.0.8) '@types/d3-geo': - specifier: ^3.0.4 - version: 3.0.4 + specifier: ^3.1.0 + version: 3.1.0 '@types/node': - specifier: ^16.18.6 - version: 16.18.6 + specifier: ^18.19.3 + version: 18.19.3 browserslist: - specifier: ^4.21.10 - version: 4.21.10 + specifier: ^4.22.2 + version: 4.22.2 flexsearch: specifier: ^0.7.31 version: 0.7.31 lightningcss: - specifier: ^1.21.8 - version: 1.21.8 + specifier: ^1.22.1 + version: 1.22.1 marked: - specifier: ^11.0.0 - version: 11.0.0 + specifier: ^11.1.0 + version: 11.1.0 prettier: specifier: ^3.1.1 version: 3.1.1 prettier-plugin-svelte: - specifier: ^3.0.3 - version: 3.0.3(prettier@3.1.1)(svelte@4.2.7) + specifier: ^3.1.2 + version: 3.1.2(prettier@3.1.1)(svelte@4.2.8) prism-svelte: specifier: ^0.5.0 version: 0.5.0 @@ -1084,8 +1174,8 @@ importers: specifier: ^3.1.2 version: 3.1.2(typescript@5.0.4) svelte: - specifier: ^4.2.7 - version: 4.2.7 + specifier: ^4.2.8 + version: 4.2.8 tiny-glob: specifier: ^0.2.9 version: 0.2.9 @@ -1093,11 +1183,11 @@ importers: specifier: 5.0.4 version: 5.0.4 vite: - specifier: ^4.4.9 - version: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + specifier: ^5.0.8 + version: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) vitest: - specifier: ^0.34.5 - version: 0.34.5(lightningcss@1.21.8)(playwright@1.30.0) + specifier: ^1.0.4 + version: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) packages: @@ -1111,13 +1201,13 @@ packages: engines: {node: '>=6.0.0'} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 - /@babel/code-frame@7.22.10: - resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.22.10 + '@babel/highlight': 7.23.4 chalk: 2.4.2 dev: true @@ -1126,8 +1216,8 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/highlight@7.22.10: - resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==} + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.22.20 @@ -1135,8 +1225,8 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/runtime@7.22.10: - resolution: {integrity: sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==} + /@babel/runtime@7.23.6: + resolution: {integrity: sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 @@ -1146,14 +1236,14 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true - /@changesets/apply-release-plan@6.1.4: - resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} + /@changesets/apply-release-plan@7.0.0: + resolution: {integrity: sha512-vfi69JR416qC9hWmFGSxj7N6wA5J222XNBmezSVATPWDVPIF7gkd4d8CpbEbXmRWbVrkoli3oerGS6dcL/BGsQ==} dependencies: - '@babel/runtime': 7.22.10 - '@changesets/config': 2.3.1 - '@changesets/get-version-range-type': 0.3.2 - '@changesets/git': 2.0.0 - '@changesets/types': 5.2.1 + '@babel/runtime': 7.23.6 + '@changesets/config': 3.0.0 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 fs-extra: 7.0.1 @@ -1164,84 +1254,83 @@ packages: semver: 7.5.4 dev: true - /@changesets/assemble-release-plan@5.2.4: - resolution: {integrity: sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==} + /@changesets/assemble-release-plan@6.0.0: + resolution: {integrity: sha512-4QG7NuisAjisbW4hkLCmGW2lRYdPrKzro+fCtZaILX+3zdUELSvYjpL4GTv0E4aM9Mef3PuIQp89VmHJ4y2bfw==} dependencies: - '@babel/runtime': 7.22.10 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.6 - '@changesets/types': 5.2.1 + '@babel/runtime': 7.23.6 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.0.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 semver: 7.5.4 dev: true - /@changesets/changelog-git@0.1.14: - resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} + /@changesets/changelog-git@0.2.0: + resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} dependencies: - '@changesets/types': 5.2.1 + '@changesets/types': 6.0.0 dev: true - /@changesets/cli@2.26.2: - resolution: {integrity: sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==} + /@changesets/cli@2.27.1: + resolution: {integrity: sha512-iJ91xlvRnnrJnELTp4eJJEOPjgpF3NOh4qeQehM6Ugiz9gJPRZ2t+TsXun6E3AMN4hScZKjqVXl0TX+C7AB3ZQ==} hasBin: true dependencies: - '@babel/runtime': 7.22.10 - '@changesets/apply-release-plan': 6.1.4 - '@changesets/assemble-release-plan': 5.2.4 - '@changesets/changelog-git': 0.1.14 - '@changesets/config': 2.3.1 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.6 - '@changesets/get-release-plan': 3.0.17 - '@changesets/git': 2.0.0 - '@changesets/logger': 0.0.5 - '@changesets/pre': 1.0.14 - '@changesets/read': 0.5.9 - '@changesets/types': 5.2.1 - '@changesets/write': 0.2.3 + '@babel/runtime': 7.23.6 + '@changesets/apply-release-plan': 7.0.0 + '@changesets/assemble-release-plan': 6.0.0 + '@changesets/changelog-git': 0.2.0 + '@changesets/config': 3.0.0 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.0.0 + '@changesets/get-release-plan': 4.0.0 + '@changesets/git': 3.0.0 + '@changesets/logger': 0.1.0 + '@changesets/pre': 2.0.0 + '@changesets/read': 0.6.0 + '@changesets/types': 6.0.0 + '@changesets/write': 0.3.0 '@manypkg/get-packages': 1.1.3 - '@types/is-ci': 3.0.0 - '@types/semver': 7.5.0 + '@types/semver': 7.5.6 ansi-colors: 4.1.3 chalk: 2.4.2 + ci-info: 3.9.0 enquirer: 2.4.1 external-editor: 3.1.0 fs-extra: 7.0.1 human-id: 1.0.2 - is-ci: 3.0.1 meow: 6.1.1 outdent: 0.5.0 p-limit: 2.3.0 - preferred-pm: 3.0.3 + preferred-pm: 3.1.2 resolve-from: 5.0.0 semver: 7.5.4 spawndamnit: 2.0.0 term-size: 2.2.1 - tty-table: 4.2.1 + tty-table: 4.2.3 dev: true - /@changesets/config@2.3.1: - resolution: {integrity: sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==} + /@changesets/config@3.0.0: + resolution: {integrity: sha512-o/rwLNnAo/+j9Yvw9mkBQOZySDYyOr/q+wptRLcAVGlU6djOeP9v1nlalbL9MFsobuBVQbZCTp+dIzdq+CLQUA==} dependencies: - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.6 - '@changesets/logger': 0.0.5 - '@changesets/types': 5.2.1 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.0.0 + '@changesets/logger': 0.1.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 micromatch: 4.0.5 dev: true - /@changesets/errors@0.1.4: - resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==} + /@changesets/errors@0.2.0: + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} dependencies: extendable-error: 0.1.7 dev: true - /@changesets/get-dependents-graph@1.3.6: - resolution: {integrity: sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==} + /@changesets/get-dependents-graph@2.0.0: + resolution: {integrity: sha512-cafUXponivK4vBgZ3yLu944mTvam06XEn2IZGjjKc0antpenkYANXiiE6GExV/yKdsCnE8dXVZ25yGqLYZmScA==} dependencies: - '@changesets/types': 5.2.1 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 chalk: 2.4.2 fs-extra: 7.0.1 @@ -1252,70 +1341,70 @@ packages: resolution: {integrity: sha512-JppheLu7S114aEs157fOZDjFqUDpm7eHdq5E8SSR0gUBTEK0cNSHsrSR5a66xs0z3RWuo46QvA3vawp8BxDHvg==} dependencies: dataloader: 1.4.0 - node-fetch: 2.6.12 + node-fetch: 2.7.0 transitivePeerDependencies: - encoding dev: true - /@changesets/get-release-plan@3.0.17: - resolution: {integrity: sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==} + /@changesets/get-release-plan@4.0.0: + resolution: {integrity: sha512-9L9xCUeD/Tb6L/oKmpm8nyzsOzhdNBBbt/ZNcjynbHC07WW4E1eX8NMGC5g5SbM5z/V+MOrYsJ4lRW41GCbg3w==} dependencies: - '@babel/runtime': 7.22.10 - '@changesets/assemble-release-plan': 5.2.4 - '@changesets/config': 2.3.1 - '@changesets/pre': 1.0.14 - '@changesets/read': 0.5.9 - '@changesets/types': 5.2.1 + '@babel/runtime': 7.23.6 + '@changesets/assemble-release-plan': 6.0.0 + '@changesets/config': 3.0.0 + '@changesets/pre': 2.0.0 + '@changesets/read': 0.6.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 dev: true - /@changesets/get-version-range-type@0.3.2: - resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} + /@changesets/get-version-range-type@0.4.0: + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} dev: true - /@changesets/git@2.0.0: - resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} + /@changesets/git@3.0.0: + resolution: {integrity: sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==} dependencies: - '@babel/runtime': 7.22.10 - '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.1 + '@babel/runtime': 7.23.6 + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 micromatch: 4.0.5 spawndamnit: 2.0.0 dev: true - /@changesets/logger@0.0.5: - resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==} + /@changesets/logger@0.1.0: + resolution: {integrity: sha512-pBrJm4CQm9VqFVwWnSqKEfsS2ESnwqwH+xR7jETxIErZcfd1u2zBSqrHbRHR7xjhSgep9x2PSKFKY//FAshA3g==} dependencies: chalk: 2.4.2 dev: true - /@changesets/parse@0.3.16: - resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==} + /@changesets/parse@0.4.0: + resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} dependencies: - '@changesets/types': 5.2.1 + '@changesets/types': 6.0.0 js-yaml: 3.14.1 dev: true - /@changesets/pre@1.0.14: - resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} + /@changesets/pre@2.0.0: + resolution: {integrity: sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==} dependencies: - '@babel/runtime': 7.22.10 - '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.1 + '@babel/runtime': 7.23.6 + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 dev: true - /@changesets/read@0.5.9: - resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} + /@changesets/read@0.6.0: + resolution: {integrity: sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==} dependencies: - '@babel/runtime': 7.22.10 - '@changesets/git': 2.0.0 - '@changesets/logger': 0.0.5 - '@changesets/parse': 0.3.16 - '@changesets/types': 5.2.1 + '@babel/runtime': 7.23.6 + '@changesets/git': 3.0.0 + '@changesets/logger': 0.1.0 + '@changesets/parse': 0.4.0 + '@changesets/types': 6.0.0 chalk: 2.4.2 fs-extra: 7.0.1 p-filter: 2.1.0 @@ -1325,15 +1414,15 @@ packages: resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} dev: true - /@changesets/types@5.2.1: - resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} + /@changesets/types@6.0.0: + resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} dev: true - /@changesets/write@0.2.3: - resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} + /@changesets/write@0.3.0: + resolution: {integrity: sha512-slGLb21fxZVUYbyea+94uFiD6ntQW0M2hIKNznFizDhZPDgn2c/fv1UzzlW43RVzh1BEDuIqW6hzlJ1OflNmcw==} dependencies: - '@babel/runtime': 7.22.10 - '@changesets/types': 5.2.1 + '@babel/runtime': 7.23.6 + '@changesets/types': 6.0.0 fs-extra: 7.0.1 human-id: 1.0.2 prettier: 2.8.8 @@ -1362,453 +1451,446 @@ packages: mime: 3.0.0 dev: true - /@cloudflare/workers-types@4.20230404.0: - resolution: {integrity: sha512-fG3oaJX1icfsGV74nhx1+AC6opvZsGqnpx6FvrcVqQaBmCNkjKNqDRFrpasXWFiOIvysBXHKQAzsAJkBZgnM+A==} + /@cloudflare/workers-types@4.20231121.0: + resolution: {integrity: sha512-+kWfpCkqiepwAKXyHoE0gnkPgkLhz0/9HOBIGhHRsUvUKvhUtm3mbqqoGRWgF1qcjzrDUBbrrOq4MYHfFtc2RA==} dev: false - /@esbuild/android-arm64@0.18.11: - resolution: {integrity: sha512-snieiq75Z1z5LJX9cduSAjUr7vEI1OdlzFPMw0HH5YI7qQHDd3qs+WZoMrWYDsfRJSq36lIA6mfZBkvL46KoIw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] + /@emnapi/runtime@0.44.0: + resolution: {integrity: sha512-ZX/etZEZw8DR7zAB1eVQT40lNo0jeqpb6dCgOvctB6FIQ5PoXfMuNY8+ayQfu8tNQbAB8gQWSSJupR8NxeiZXw==} requiresBuild: true + dependencies: + tslib: 2.6.2 dev: false optional: true - /@esbuild/android-arm64@0.18.20: - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + /@esbuild/android-arm64@0.19.9: + resolution: {integrity: sha512-q4cR+6ZD0938R19MyEW3jEsMzbb/1rulLXiNAJQADD/XYp7pT+rOS5JGxvpRW8dFDEfjW4wLgC/3FXIw4zYglQ==} engines: {node: '>=12'} cpu: [arm64] os: [android] requiresBuild: true optional: true - /@esbuild/android-arm@0.18.11: - resolution: {integrity: sha512-q4qlUf5ucwbUJZXF5tEQ8LF7y0Nk4P58hOsGk3ucY0oCwgQqAnqXVbUuahCddVHfrxmpyewRpiTHwVHIETYu7Q==} + /@esbuild/android-arm@0.19.9: + resolution: {integrity: sha512-jkYjjq7SdsWuNI6b5quymW0oC83NN5FdRPuCbs9HZ02mfVdAP8B8eeqLSYU3gb6OJEaY5CQabtTFbqBf26H3GA==} engines: {node: '>=12'} cpu: [arm] os: [android] requiresBuild: true - dev: false optional: true - /@esbuild/android-arm@0.18.20: - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-x64@0.18.11: - resolution: {integrity: sha512-iPuoxQEV34+hTF6FT7om+Qwziv1U519lEOvekXO9zaMMlT9+XneAhKL32DW3H7okrCOBQ44BMihE8dclbZtTuw==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: false - optional: true - - /@esbuild/android-x64@0.18.20: - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + /@esbuild/android-x64@0.19.9: + resolution: {integrity: sha512-KOqoPntWAH6ZxDwx1D6mRntIgZh9KodzgNOy5Ebt9ghzffOk9X2c1sPwtM9P+0eXbefnDhqYfkh5PLP5ULtWFA==} engines: {node: '>=12'} cpu: [x64] os: [android] requiresBuild: true optional: true - /@esbuild/darwin-arm64@0.18.11: - resolution: {integrity: sha512-Gm0QkI3k402OpfMKyQEEMG0RuW2LQsSmI6OeO4El2ojJMoF5NLYb3qMIjvbG/lbMeLOGiW6ooU8xqc+S0fgz2w==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: false - optional: true - - /@esbuild/darwin-arm64@0.18.20: - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + /@esbuild/darwin-arm64@0.19.9: + resolution: {integrity: sha512-KBJ9S0AFyLVx2E5D8W0vExqRW01WqRtczUZ8NRu+Pi+87opZn5tL4Y0xT0mA4FtHctd0ZgwNoN639fUUGlNIWw==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@esbuild/darwin-x64@0.18.11: - resolution: {integrity: sha512-N15Vzy0YNHu6cfyDOjiyfJlRJCB/ngKOAvoBf1qybG3eOq0SL2Lutzz9N7DYUbb7Q23XtHPn6lMDF6uWbGv9Fw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: false - optional: true - - /@esbuild/darwin-x64@0.18.20: - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + /@esbuild/darwin-x64@0.19.9: + resolution: {integrity: sha512-vE0VotmNTQaTdX0Q9dOHmMTao6ObjyPm58CHZr1UK7qpNleQyxlFlNCaHsHx6Uqv86VgPmR4o2wdNq3dP1qyDQ==} engines: {node: '>=12'} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@esbuild/freebsd-arm64@0.18.11: - resolution: {integrity: sha512-atEyuq6a3omEY5qAh5jIORWk8MzFnCpSTUruBgeyN9jZq1K/QI9uke0ATi3MHu4L8c59CnIi4+1jDKMuqmR71A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: false - optional: true - - /@esbuild/freebsd-arm64@0.18.20: - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + /@esbuild/freebsd-arm64@0.19.9: + resolution: {integrity: sha512-uFQyd/o1IjiEk3rUHSwUKkqZwqdvuD8GevWF065eqgYfexcVkxh+IJgwTaGZVu59XczZGcN/YMh9uF1fWD8j1g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] requiresBuild: true optional: true - /@esbuild/freebsd-x64@0.18.11: - resolution: {integrity: sha512-XtuPrEfBj/YYYnAAB7KcorzzpGTvOr/dTtXPGesRfmflqhA4LMF0Gh/n5+a9JBzPuJ+CGk17CA++Hmr1F/gI0Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: false - optional: true - - /@esbuild/freebsd-x64@0.18.20: - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + /@esbuild/freebsd-x64@0.19.9: + resolution: {integrity: sha512-WMLgWAtkdTbTu1AWacY7uoj/YtHthgqrqhf1OaEWnZb7PQgpt8eaA/F3LkV0E6K/Lc0cUr/uaVP/49iE4M4asA==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] requiresBuild: true optional: true - /@esbuild/linux-arm64@0.18.11: - resolution: {integrity: sha512-c6Vh2WS9VFKxKZ2TvJdA7gdy0n6eSy+yunBvv4aqNCEhSWVor1TU43wNRp2YLO9Vng2G+W94aRz+ILDSwAiYog==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@esbuild/linux-arm64@0.18.20: - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + /@esbuild/linux-arm64@0.19.9: + resolution: {integrity: sha512-PiPblfe1BjK7WDAKR1Cr9O7VVPqVNpwFcPWgfn4xu0eMemzRp442hXyzF/fSwgrufI66FpHOEJk0yYdPInsmyQ==} engines: {node: '>=12'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-arm@0.18.11: - resolution: {integrity: sha512-Idipz+Taso/toi2ETugShXjQ3S59b6m62KmLHkJlSq/cBejixmIydqrtM2XTvNCywFl3VC7SreSf6NV0i6sRyg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@esbuild/linux-arm@0.18.20: - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + /@esbuild/linux-arm@0.19.9: + resolution: {integrity: sha512-C/ChPohUYoyUaqn1h17m/6yt6OB14hbXvT8EgM1ZWaiiTYz7nWZR0SYmMnB5BzQA4GXl3BgBO1l8MYqL/He3qw==} engines: {node: '>=12'} cpu: [arm] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-ia32@0.18.11: - resolution: {integrity: sha512-S3hkIF6KUqRh9n1Q0dSyYcWmcVa9Cg+mSoZEfFuzoYXXsk6196qndrM+ZiHNwpZKi3XOXpShZZ+9dfN5ykqjjw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@esbuild/linux-ia32@0.18.20: - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + /@esbuild/linux-ia32@0.19.9: + resolution: {integrity: sha512-f37i/0zE0MjDxijkPSQw1CO/7C27Eojqb+r3BbHVxMLkj8GCa78TrBZzvPyA/FNLUMzP3eyHCVkAopkKVja+6Q==} engines: {node: '>=12'} cpu: [ia32] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-loong64@0.18.11: - resolution: {integrity: sha512-MRESANOoObQINBA+RMZW+Z0TJWpibtE7cPFnahzyQHDCA9X9LOmGh68MVimZlM9J8n5Ia8lU773te6O3ILW8kw==} + /@esbuild/linux-loong64@0.19.9: + resolution: {integrity: sha512-t6mN147pUIf3t6wUt3FeumoOTPfmv9Cc6DQlsVBpB7eCpLOqQDyWBP1ymXn1lDw4fNUSb/gBcKAmvTP49oIkaA==} engines: {node: '>=12'} cpu: [loong64] os: [linux] requiresBuild: true - dev: false - optional: true - - /@esbuild/linux-loong64@0.18.20: - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-mips64el@0.18.11: - resolution: {integrity: sha512-qVyPIZrXNMOLYegtD1u8EBccCrBVshxMrn5MkuFc3mEVsw7CCQHaqZ4jm9hbn4gWY95XFnb7i4SsT3eflxZsUg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: false optional: true - /@esbuild/linux-mips64el@0.18.20: - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + /@esbuild/linux-mips64el@0.19.9: + resolution: {integrity: sha512-jg9fujJTNTQBuDXdmAg1eeJUL4Jds7BklOTkkH80ZgQIoCTdQrDaHYgbFZyeTq8zbY+axgptncko3v9p5hLZtw==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-ppc64@0.18.11: - resolution: {integrity: sha512-T3yd8vJXfPirZaUOoA9D2ZjxZX4Gr3QuC3GztBJA6PklLotc/7sXTOuuRkhE9W/5JvJP/K9b99ayPNAD+R+4qQ==} + /@esbuild/linux-ppc64@0.19.9: + resolution: {integrity: sha512-tkV0xUX0pUUgY4ha7z5BbDS85uI7ABw3V1d0RNTii7E9lbmV8Z37Pup2tsLV46SQWzjOeyDi1Q7Wx2+QM8WaCQ==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] requiresBuild: true - dev: false optional: true - /@esbuild/linux-ppc64@0.18.20: - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + /@esbuild/linux-riscv64@0.19.9: + resolution: {integrity: sha512-DfLp8dj91cufgPZDXr9p3FoR++m3ZJ6uIXsXrIvJdOjXVREtXuQCjfMfvmc3LScAVmLjcfloyVtpn43D56JFHg==} engines: {node: '>=12'} - cpu: [ppc64] + cpu: [riscv64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-riscv64@0.18.11: - resolution: {integrity: sha512-evUoRPWiwuFk++snjH9e2cAjF5VVSTj+Dnf+rkO/Q20tRqv+644279TZlPK8nUGunjPAtQRCj1jQkDAvL6rm2w==} + /@esbuild/linux-s390x@0.19.9: + resolution: {integrity: sha512-zHbglfEdC88KMgCWpOl/zc6dDYJvWGLiUtmPRsr1OgCViu3z5GncvNVdf+6/56O2Ca8jUU+t1BW261V6kp8qdw==} engines: {node: '>=12'} - cpu: [riscv64] + cpu: [s390x] os: [linux] requiresBuild: true - dev: false optional: true - /@esbuild/linux-riscv64@0.18.20: - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + /@esbuild/linux-x64@0.19.9: + resolution: {integrity: sha512-JUjpystGFFmNrEHQnIVG8hKwvA2DN5o7RqiO1CVX8EN/F/gkCjkUMgVn6hzScpwnJtl2mPR6I9XV1oW8k9O+0A==} engines: {node: '>=12'} - cpu: [riscv64] + cpu: [x64] os: [linux] requiresBuild: true optional: true - /@esbuild/linux-s390x@0.18.11: - resolution: {integrity: sha512-/SlRJ15XR6i93gRWquRxYCfhTeC5PdqEapKoLbX63PLCmAkXZHY2uQm2l9bN0oPHBsOw2IswRZctMYS0MijFcg==} + /@esbuild/netbsd-x64@0.19.9: + resolution: {integrity: sha512-GThgZPAwOBOsheA2RUlW5UeroRfESwMq/guy8uEe3wJlAOjpOXuSevLRd70NZ37ZrpO6RHGHgEHvPg1h3S1Jug==} engines: {node: '>=12'} - cpu: [s390x] - os: [linux] + cpu: [x64] + os: [netbsd] requiresBuild: true - dev: false optional: true - /@esbuild/linux-s390x@0.18.20: - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + /@esbuild/openbsd-x64@0.19.9: + resolution: {integrity: sha512-Ki6PlzppaFVbLnD8PtlVQfsYw4S9n3eQl87cqgeIw+O3sRr9IghpfSKY62mggdt1yCSZ8QWvTZ9jo9fjDSg9uw==} engines: {node: '>=12'} - cpu: [s390x] - os: [linux] + cpu: [x64] + os: [openbsd] requiresBuild: true optional: true - /@esbuild/linux-x64@0.18.11: - resolution: {integrity: sha512-xcncej+wF16WEmIwPtCHi0qmx1FweBqgsRtEL1mSHLFR6/mb3GEZfLQnx+pUDfRDEM4DQF8dpXIW7eDOZl1IbA==} + /@esbuild/sunos-x64@0.19.9: + resolution: {integrity: sha512-MLHj7k9hWh4y1ddkBpvRj2b9NCBhfgBt3VpWbHQnXRedVun/hC7sIyTGDGTfsGuXo4ebik2+3ShjcPbhtFwWDw==} engines: {node: '>=12'} cpu: [x64] - os: [linux] + os: [sunos] requiresBuild: true - dev: false optional: true - /@esbuild/linux-x64@0.18.20: - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + /@esbuild/win32-arm64@0.19.9: + resolution: {integrity: sha512-GQoa6OrQ8G08guMFgeXPH7yE/8Dt0IfOGWJSfSH4uafwdC7rWwrfE6P9N8AtPGIjUzdo2+7bN8Xo3qC578olhg==} engines: {node: '>=12'} - cpu: [x64] - os: [linux] + cpu: [arm64] + os: [win32] requiresBuild: true optional: true - /@esbuild/netbsd-x64@0.18.11: - resolution: {integrity: sha512-aSjMHj/F7BuS1CptSXNg6S3M4F3bLp5wfFPIJM+Km2NfIVfFKhdmfHF9frhiCLIGVzDziggqWll0B+9AUbud/Q==} + /@esbuild/win32-ia32@0.19.9: + resolution: {integrity: sha512-UOozV7Ntykvr5tSOlGCrqU3NBr3d8JqPes0QWN2WOXfvkWVGRajC+Ym0/Wj88fUgecUCLDdJPDF0Nna2UK3Qtg==} engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] + cpu: [ia32] + os: [win32] requiresBuild: true - dev: false optional: true - /@esbuild/netbsd-x64@0.18.20: - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + /@esbuild/win32-x64@0.19.9: + resolution: {integrity: sha512-oxoQgglOP7RH6iasDrhY+R/3cHrfwIDvRlT4CGChflq6twk8iENeVvMJjmvBb94Ik1Z+93iGO27err7w6l54GQ==} engines: {node: '>=12'} cpu: [x64] - os: [netbsd] + os: [win32] requiresBuild: true optional: true - /@esbuild/openbsd-x64@0.18.11: - resolution: {integrity: sha512-tNBq+6XIBZtht0xJGv7IBB5XaSyvYPCm1PxJ33zLQONdZoLVM0bgGqUrXnJyiEguD9LU4AHiu+GCXy/Hm9LsdQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] + /@eslint-community/eslint-utils@4.4.0(eslint@8.55.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.55.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.0 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.55.0: + resolution: {integrity: sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@fontsource/fira-mono@5.0.8: + resolution: {integrity: sha512-8OJiUK2lzJjvDlkmamEfhtpL1cyFApg1Pk4kE5Pw5UTf1ETF3Yy/pprgwV5I+LQPDjuFvinsinT9xSUZ2b/zuQ==} + dev: false + + /@humanwhocodes/config-array@0.11.13: + resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 2.0.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.1: + resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + dev: true + + /@iarna/toml@2.2.5: + resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} + dev: false + + /@img/sharp-darwin-arm64@0.33.0: + resolution: {integrity: sha512-070tEheekI1LJWTGPC9WlQEa5UoKTXzzlORBHMX4TbfUxMiL336YHR8vBEUNsjse0RJCX8dZ4ZXwT595aEF1ug==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [darwin] requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.0 dev: false optional: true - /@esbuild/openbsd-x64@0.18.20: - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} + /@img/sharp-darwin-x64@0.33.0: + resolution: {integrity: sha512-pu/nvn152F3qbPeUkr+4e9zVvEhD3jhwzF473veQfMPkOYo9aoWXSfdZH/E6F+nYC3qvFjbxbvdDbUtEbghLqw==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] - os: [openbsd] + os: [darwin] requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.0 + dev: false optional: true - /@esbuild/sunos-x64@0.18.11: - resolution: {integrity: sha512-kxfbDOrH4dHuAAOhr7D7EqaYf+W45LsAOOhAet99EyuxxQmjbk8M9N4ezHcEiCYPaiW8Dj3K26Z2V17Gt6p3ng==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] + /@img/sharp-libvips-darwin-arm64@1.0.0: + resolution: {integrity: sha512-VzYd6OwnUR81sInf3alj1wiokY50DjsHz5bvfnsFpxs5tqQxESoHtJO6xyksDs3RIkyhMWq2FufXo6GNSU9BMw==} + engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [darwin] requiresBuild: true dev: false optional: true - /@esbuild/sunos-x64@0.18.20: - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} + /@img/sharp-libvips-darwin-x64@1.0.0: + resolution: {integrity: sha512-dD9OznTlHD6aovRswaPNEy8dKtSAmNo4++tO7uuR4o5VxbVAOoEQ1uSmN4iFAdQneTHws1lkTZeiXPrcCkh6IA==} + engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] - os: [sunos] + os: [darwin] requiresBuild: true + dev: false optional: true - /@esbuild/win32-arm64@0.18.11: - resolution: {integrity: sha512-Sh0dDRyk1Xi348idbal7lZyfSkjhJsdFeuC13zqdipsvMetlGiFQNdO+Yfp6f6B4FbyQm7qsk16yaZk25LChzg==} - engines: {node: '>=12'} + /@img/sharp-libvips-linux-arm64@1.0.0: + resolution: {integrity: sha512-xTYThiqEZEZc0PRU90yVtM3KE7lw1bKdnDQ9kCTHWbqWyHOe4NpPOtMGy27YnN51q0J5dqRrvicfPbALIOeAZA==} + engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] - os: [win32] + os: [linux] requiresBuild: true dev: false optional: true - /@esbuild/win32-arm64@0.18.20: - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] + /@img/sharp-libvips-linux-arm@1.0.0: + resolution: {integrity: sha512-VwgD2eEikDJUk09Mn9Dzi1OW2OJFRQK+XlBTkUNmAWPrtj8Ly0yq05DFgu1VCMx2/DqCGQVi5A1dM9hTmxf3uw==} + engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm] + os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/win32-ia32@0.18.11: - resolution: {integrity: sha512-o9JUIKF1j0rqJTFbIoF4bXj6rvrTZYOrfRcGyL0Vm5uJ/j5CkBD/51tpdxe9lXEDouhRgdr/BYzUrDOvrWwJpg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] + /@img/sharp-libvips-linux-s390x@1.0.0: + resolution: {integrity: sha512-o9E46WWBC6JsBlwU4QyU9578G77HBDT1NInd+aERfxeOPbk0qBZHgoDsQmA2v9TbqJRWzoBPx1aLOhprBMgPjw==} + engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [s390x] + os: [linux] requiresBuild: true dev: false optional: true - /@esbuild/win32-ia32@0.18.20: - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] + /@img/sharp-libvips-linux-x64@1.0.0: + resolution: {integrity: sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==} + engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] requiresBuild: true + dev: false optional: true - /@esbuild/win32-x64@0.18.11: - resolution: {integrity: sha512-rQI4cjLHd2hGsM1LqgDI7oOCYbQ6IBOVsX9ejuRMSze0GqXUG2ekwiKkiBU1pRGSeCqFFHxTrcEydB2Hyoz9CA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] + /@img/sharp-libvips-linuxmusl-arm64@1.0.0: + resolution: {integrity: sha512-OdorplCyvmSAPsoJLldtLh3nLxRrkAAAOHsGWGDYfN0kh730gifK+UZb3dWORRa6EusNqCTjfXV4GxvgJ/nPDQ==} + engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] requiresBuild: true dev: false optional: true - /@esbuild/win32-x64@0.18.20: - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} + /@img/sharp-libvips-linuxmusl-x64@1.0.0: + resolution: {integrity: sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==} + engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] - os: [win32] + os: [linux] requiresBuild: true + dev: false optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.52.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.52.0 - eslint-visitor-keys: 3.4.3 - dev: true - - /@eslint-community/regexpp@4.6.2: - resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true + /@img/sharp-linux-arm64@0.33.0: + resolution: {integrity: sha512-dcomVSrtgF70SyOr8RCOCQ8XGVThXwe71A1d8MGA+mXEVRJ/J6/TrCbBEJh9ddcEIIsrnrkolaEvYSHqVhswQw==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.0 + dev: false + optional: true - /@eslint/eslintrc@2.1.2: - resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.20.0 - ignore: 5.2.4 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true + /@img/sharp-linux-arm@0.33.0: + resolution: {integrity: sha512-4horD3wMFd5a0ddbDY8/dXU9CaOgHjEHALAddXgafoR5oWq5s8X61PDgsSeh4Qupsdo6ycfPPSSNBrfVQnwwrg==} + engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.0 + dev: false + optional: true - /@eslint/js@8.52.0: - resolution: {integrity: sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + /@img/sharp-linux-s390x@0.33.0: + resolution: {integrity: sha512-TiVJbx38J2rNVfA309ffSOB+3/7wOsZYQEOlKqOUdWD/nqkjNGrX+YQGz7nzcf5oy2lC+d37+w183iNXRZNngQ==} + engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [s390x] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.0 + dev: false + optional: true - /@fastify/busboy@2.0.0: - resolution: {integrity: sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==} - engines: {node: '>=14'} + /@img/sharp-linux-x64@0.33.0: + resolution: {integrity: sha512-PaZM4Zi7/Ek71WgTdvR+KzTZpBqrQOFcPe7/8ZoPRlTYYRe43k6TWsf4GVH6XKRLMYeSp8J89RfAhBrSP4itNA==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.0 dev: false + optional: true - /@fontsource/fira-mono@5.0.5: - resolution: {integrity: sha512-R5HaONNjI8zzZgjATOrtDhhl58U19OslqNOanPpiHqXV8XWKmFqRF1hIekrWemLfpSTK1WO3wyNcFMZMwkKhlA==} + /@img/sharp-linuxmusl-arm64@0.33.0: + resolution: {integrity: sha512-1QLbbN0zt+32eVrg7bb1lwtvEaZwlhEsY1OrijroMkwAqlHqFj6R33Y47s2XUv7P6Ie1PwCxK/uFnNqMnkd5kg==} + engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.0 dev: false + optional: true - /@humanwhocodes/config-array@0.11.13: - resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true + /@img/sharp-linuxmusl-x64@0.33.0: + resolution: {integrity: sha512-CecqgB/CnkvCWFhmfN9ZhPGMLXaEBXl4o7WtA6U3Ztrlh/s7FUKX4vNxpMSYLIrWuuzjiaYdfU3+Tdqh1xaHfw==} + engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.0 + dev: false + optional: true - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true + /@img/sharp-wasm32@0.33.0: + resolution: {integrity: sha512-Hn4js32gUX9qkISlemZBUPuMs0k/xNJebUNl/L6djnU07B/HAA2KaxRVb3HvbU5fL242hLOcp0+tR+M8dvJUFw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/runtime': 0.44.0 + dev: false + optional: true - /@humanwhocodes/object-schema@2.0.1: - resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} - dev: true + /@img/sharp-win32-ia32@0.33.0: + resolution: {integrity: sha512-5HfcsCZi3l5nPRF2q3bllMVMDXBqEWI3Q8KQONfzl0TferFE5lnsIG0A1YrntMAGqvkzdW6y1Ci1A2uTvxhfzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true - /@iarna/toml@2.2.5: - resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} + /@img/sharp-win32-x64@0.33.0: + resolution: {integrity: sha512-i3DtP/2ce1yKFj4OzOnOYltOEL/+dp4dc4dJXJBv6god1AFTcmkaA99H/7SwOmkCOBQkbVvA3lCGm3/5nDtf9Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [win32] + requiresBuild: true dev: false + optional: true /@istanbuljs/schema@0.1.3: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} @@ -1828,7 +1910,7 @@ packages: dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 /@jridgewell/resolve-uri@3.1.1: resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} @@ -1842,14 +1924,14 @@ packages: resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} dependencies: '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - /@jridgewell/trace-mapping@0.3.19: - resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + /@jridgewell/trace-mapping@0.3.20: + resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} dependencies: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 @@ -1857,7 +1939,7 @@ packages: /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.6 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 @@ -1866,7 +1948,7 @@ packages: /@manypkg/get-packages@1.1.3: resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.6 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -1881,12 +1963,12 @@ packages: detect-libc: 2.0.2 https-proxy-agent: 5.0.1 make-dir: 3.1.0 - node-fetch: 2.6.12 + node-fetch: 2.7.0 nopt: 5.0.0 npmlog: 5.0.1 rimraf: 3.0.2 semver: 7.5.4 - tar: 6.1.15 + tar: 6.2.0 transitivePeerDependencies: - encoding - supports-color @@ -1896,11 +1978,11 @@ packages: resolution: {integrity: sha512-SmksyaJAdSlMa9cTidVSIqYo1qti+WTsviNDwgjNVm+KQ3DRP2Df9umDIzC4vCcpEYY+chQe0i2IKnLw03AT8Q==} dev: true - /@netlify/functions@2.0.2: - resolution: {integrity: sha512-goWRtaIPUK/q47qLYtfGGj7HgJIRaT0snw7zZ0yeoNTfQfCRwQwvRrMAsXkCsCtq2N2Oo81L26SpkMxEQMk9hg==} + /@netlify/functions@2.4.1: + resolution: {integrity: sha512-sRFYBaz6dJP1MdUtk/5QNmshhg5UDmB+DUssmH6v9WUG85MrwyExEfGfJA5eClXATjXm0coTvO5nLAlyCpK7QQ==} engines: {node: '>=14.0.0'} dependencies: - '@netlify/serverless-functions-api': 1.7.3 + '@netlify/serverless-functions-api': 1.12.3 is-promise: 4.0.0 dev: true @@ -1909,8 +1991,8 @@ packages: engines: {node: ^14.16.0 || >=16.0.0} dev: true - /@netlify/serverless-functions-api@1.7.3: - resolution: {integrity: sha512-n6/7cJlSWvvbBlUOEAbkGyEld80S6KbG/ldQI9OhLfe1lTatgKmrTNIgqVNpaWpUdTgP2OHWFjmFBzkxxBWs5w==} + /@netlify/serverless-functions-api@1.12.3: + resolution: {integrity: sha512-g1AZ78pCvMnalZtbnViVLGfG5ufjKyKoi3plLSUtZqh0wVuMR7ZGegeZHhOoY4wRfkkETVvWfhgfcpLMbGM5Lg==} engines: {node: ^14.18.0 || >=16.0.0} dependencies: '@netlify/node-cookies': 0.1.0 @@ -1940,58 +2022,58 @@ packages: engines: {node: '>=14'} hasBin: true dependencies: - '@types/node': 16.18.6 + '@types/node': 18.19.3 playwright-core: 1.30.0 dev: true - /@polka/url@1.0.0-next.23: - resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==} + /@polka/url@1.0.0-next.24: + resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==} - /@rollup/plugin-commonjs@25.0.0(rollup@3.29.4): - resolution: {integrity: sha512-hoho2Kay9TZrLu0bnDsTTCaj4Npa+THk9snajP/XDNb9a9mmjTjh52EQM9sKl3HD1LsnihX7js+eA2sd2uKAhw==} + /@rollup/plugin-commonjs@25.0.7(rollup@4.8.0): + resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^2.68.0||^3.0.0 + rollup: ^2.68.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2(rollup@3.29.4) + '@rollup/pluginutils': 5.1.0(rollup@4.8.0) commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.1.0 is-reference: 1.2.1 - magic-string: 0.27.0 - rollup: 3.29.4 + magic-string: 0.30.5 + rollup: 4.8.0 - /@rollup/plugin-json@6.0.0(rollup@3.29.4): - resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==} + /@rollup/plugin-json@6.1.0(rollup@4.8.0): + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2(rollup@3.29.4) - rollup: 3.29.4 + '@rollup/pluginutils': 5.1.0(rollup@4.8.0) + rollup: 4.8.0 - /@rollup/plugin-node-resolve@15.0.1(rollup@3.29.4): - resolution: {integrity: sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==} + /@rollup/plugin-node-resolve@15.2.3(rollup@4.8.0): + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^2.78.0||^3.0.0 + rollup: ^2.78.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2(rollup@3.29.4) + '@rollup/pluginutils': 5.1.0(rollup@4.8.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-builtin-module: 3.2.1 is-module: 1.0.0 - resolve: 1.22.4 - rollup: 3.29.4 + resolve: 1.22.8 + rollup: 4.8.0 /@rollup/pluginutils@4.2.1: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} @@ -2001,40 +2083,116 @@ packages: picomatch: 2.3.1 dev: false - /@rollup/pluginutils@5.0.2(rollup@3.29.4): - resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} + /@rollup/pluginutils@5.1.0(rollup@4.8.0): + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 3.29.4 + rollup: 4.8.0 - /@rollup/pluginutils@5.0.4(rollup@3.29.4): - resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@types/estree': 1.0.3 - estree-walker: 2.0.2 - picomatch: 2.3.1 - rollup: 3.29.4 - dev: false + /@rollup/rollup-android-arm-eabi@4.8.0: + resolution: {integrity: sha512-zdTObFRoNENrdPpnTNnhOljYIcOX7aI7+7wyrSpPFFIOf/nRdedE6IYsjaBE7tjukphh1tMTojgJ7p3lKY8x6Q==} + cpu: [arm] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-android-arm64@4.8.0: + resolution: {integrity: sha512-aiItwP48BiGpMFS9Znjo/xCNQVwTQVcRKkFKsO81m8exrGjHkCBDvm9PHay2kpa8RPnZzzKcD1iQ9KaLY4fPQQ==} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-arm64@4.8.0: + resolution: {integrity: sha512-zhNIS+L4ZYkYQUjIQUR6Zl0RXhbbA0huvNIWjmPc2SL0cB1h5Djkcy+RZ3/Bwszfb6vgwUvcVJYD6e6Zkpsi8g==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-darwin-x64@4.8.0: + resolution: {integrity: sha512-A/FAHFRNQYrELrb/JHncRWzTTXB2ticiRFztP4ggIUAfa9Up1qfW8aG2w/mN9jNiZ+HB0t0u0jpJgFXG6BfRTA==} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.8.0: + resolution: {integrity: sha512-JsidBnh3p2IJJA4/2xOF2puAYqbaczB3elZDT0qHxn362EIoIkq7hrR43Xa8RisgI6/WPfvb2umbGsuvf7E37A==} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.8.0: + resolution: {integrity: sha512-hBNCnqw3EVCkaPB0Oqd24bv8SklETptQWcJz06kb9OtiShn9jK1VuTgi7o4zPSt6rNGWQOTDEAccbk0OqJmS+g==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.8.0: + resolution: {integrity: sha512-Fw9ChYfJPdltvi9ALJ9wzdCdxGw4wtq4t1qY028b2O7GwB5qLNSGtqMsAel1lfWTZvf4b6/+4HKp0GlSYg0ahA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.8.0: + resolution: {integrity: sha512-BH5xIh7tOzS9yBi8dFrCTG8Z6iNIGWGltd3IpTSKp6+pNWWO6qy8eKoRxOtwFbMrid5NZaidLYN6rHh9aB8bEw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.8.0: + resolution: {integrity: sha512-PmvAj8k6EuWiyLbkNpd6BLv5XeYFpqWuRvRNRl80xVfpGXK/z6KYXmAgbI4ogz7uFiJxCnYcqyvZVD0dgFog7Q==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.8.0: + resolution: {integrity: sha512-mdxnlW2QUzXwY+95TuxZ+CurrhgrPAMveDWI97EQlA9bfhR8tw3Pt7SUlc/eSlCNxlWktpmT//EAA8UfCHOyXg==} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.8.0: + resolution: {integrity: sha512-ge7saUz38aesM4MA7Cad8CHo0Fyd1+qTaqoIo+Jtk+ipBi4ATSrHWov9/S4u5pbEQmLjgUjB7BJt+MiKG2kzmA==} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.8.0: + resolution: {integrity: sha512-p9E3PZlzurhlsN5h9g7zIP1DnqKXJe8ZUkFwAazqSvHuWfihlIISPxG9hCHCoA+dOOspL/c7ty1eeEVFTE0UTw==} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.8.0: + resolution: {integrity: sha512-kb4/auKXkYKqlUYTE8s40FcJIj5soOyRLHKd4ugR0dCq0G2EfcF54eYcfQiGkHzjidZ40daB4ulsFdtqNKZtBg==} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true - /@sveltejs/eslint-config@6.0.4(@typescript-eslint/eslint-plugin@6.0.0)(@typescript-eslint/parser@6.14.0)(eslint-config-prettier@9.0.0)(eslint-plugin-svelte@2.31.0)(eslint-plugin-unicorn@49.0.0)(eslint@8.52.0)(typescript@4.9.4): + /@sveltejs/eslint-config@6.0.4(@typescript-eslint/eslint-plugin@6.14.0)(@typescript-eslint/parser@6.14.0)(eslint-config-prettier@9.1.0)(eslint-plugin-svelte@2.35.1)(eslint-plugin-unicorn@49.0.0)(eslint@8.55.0)(typescript@5.3.3): resolution: {integrity: sha512-U9pwmDs+DbmsnCgTfu6Bacdwqn0DuI1IQNSiQqTgzVyYfaaj+zy9ZoQCiJfxFBGXHkklyXuRHp0KMx346N0lcQ==} peerDependencies: '@typescript-eslint/eslint-plugin': '>= 5' @@ -2045,16 +2203,16 @@ packages: eslint-plugin-unicorn: '>= 47' typescript: '>= 4' dependencies: - '@typescript-eslint/eslint-plugin': 6.0.0(@typescript-eslint/parser@6.14.0)(eslint@8.52.0)(typescript@4.9.4) - '@typescript-eslint/parser': 6.14.0(eslint@8.52.0)(typescript@4.9.4) - eslint: 8.52.0 - eslint-config-prettier: 9.0.0(eslint@8.52.0) - eslint-plugin-svelte: 2.31.0(eslint@8.52.0)(svelte@4.2.7) - eslint-plugin-unicorn: 49.0.0(eslint@8.52.0) - typescript: 4.9.4 + '@typescript-eslint/eslint-plugin': 6.14.0(@typescript-eslint/parser@6.14.0)(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.14.0(eslint@8.55.0)(typescript@5.3.3) + eslint: 8.55.0 + eslint-config-prettier: 9.1.0(eslint@8.55.0) + eslint-plugin-svelte: 2.35.1(eslint@8.55.0)(svelte@4.2.8) + eslint-plugin-unicorn: 49.0.0(eslint@8.55.0) + typescript: 5.3.3 dev: true - /@sveltejs/site-kit@6.0.0-next.59(@sveltejs/kit@packages+kit)(svelte@4.2.7): + /@sveltejs/site-kit@6.0.0-next.59(@sveltejs/kit@packages+kit)(svelte@4.2.8): resolution: {integrity: sha512-nAUCuunhN0DmurQBxbsauqvdvv4mL0F/Aluxq0hFf6gB3iSn9WdaUZdPMXoujy+8cy+m6UvKuyhkgApZhmOLvw==} peerDependencies: '@sveltejs/kit': ^1.20.0 @@ -2062,45 +2220,45 @@ packages: dependencies: '@sveltejs/kit': link:packages/kit esm-env: 1.0.0 - svelte: 4.2.7 - svelte-local-storage-store: 0.6.4(svelte@4.2.7) + svelte: 4.2.8 + svelte-local-storage-store: 0.6.4(svelte@4.2.8) dev: true - /@sveltejs/vite-plugin-svelte-inspector@1.0.4(@sveltejs/vite-plugin-svelte@2.5.0)(svelte@4.2.7)(vite@4.4.9): - resolution: {integrity: sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==} - engines: {node: ^14.18.0 || >= 16} + /@sveltejs/vite-plugin-svelte-inspector@2.0.0(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@4.2.8)(vite@5.0.8): + resolution: {integrity: sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==} + engines: {node: ^18.0.0 || >=20} peerDependencies: - '@sveltejs/vite-plugin-svelte': ^2.2.0 - svelte: ^3.54.0 || ^4.0.0 - vite: ^4.0.0 + '@sveltejs/vite-plugin-svelte': ^3.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 dependencies: - '@sveltejs/vite-plugin-svelte': 2.5.0(svelte@4.2.7)(vite@4.4.9) + '@sveltejs/vite-plugin-svelte': 3.0.1(svelte@4.2.8)(vite@5.0.8) debug: 4.3.4 - svelte: 4.2.7 - vite: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + svelte: 4.2.8 + vite: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) transitivePeerDependencies: - supports-color - dev: false + dev: true - /@sveltejs/vite-plugin-svelte@2.5.0(svelte@4.2.7)(vite@4.4.9): - resolution: {integrity: sha512-FxLZLVfFA2soGw7ej8Ohuav7+AOsJILiPlL8FgY5MABDDmDqb637o8Xd/QGkrXLC1qXyG1bnteOw5Z5yrA2lHA==} - engines: {node: ^14.18.0 || >= 16} + /@sveltejs/vite-plugin-svelte@3.0.1(svelte@4.2.8)(vite@5.0.8): + resolution: {integrity: sha512-CGURX6Ps+TkOovK6xV+Y2rn8JKa8ZPUHPZ/NKgCxAmgBrXReavzFl8aOSCj3kQ1xqT7yGJj53hjcV/gqwDAaWA==} + engines: {node: ^18.0.0 || >=20} peerDependencies: - svelte: ^3.54.0 || ^4.0.0 || ^5.0.0-next.0 - vite: ^4.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 1.0.4(@sveltejs/vite-plugin-svelte@2.5.0)(svelte@4.2.7)(vite@4.4.9) + '@sveltejs/vite-plugin-svelte-inspector': 2.0.0(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@4.2.8)(vite@5.0.8) debug: 4.3.4 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.5 - svelte: 4.2.7 - svelte-hmr: 0.15.3(svelte@4.2.7) - vite: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) - vitefu: 0.2.4(vite@4.4.9) + svelte: 4.2.8 + svelte-hmr: 0.15.3(svelte@4.2.8) + vite: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) + vitefu: 0.2.5(vite@5.0.8) transitivePeerDependencies: - supports-color - dev: false + dev: true /@svitejs/changesets-changelog-github-compact@1.1.0: resolution: {integrity: sha512-qhUGGDHcpbY2zpjW3SwqchuW8J/5EzlPFud7xNntHKA7f3a/mx5+g+ruJKFHSAiVZYo30PALt+AyhmPUNKH/Og==} @@ -2121,113 +2279,101 @@ packages: path-browserify: 1.0.1 dev: false - /@types/chai-subset@1.3.3: - resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/chai': 4.3.6 + '@types/node': 18.19.3 dev: true - /@types/chai@4.3.6: - resolution: {integrity: sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==} - dev: true - - /@types/connect@3.4.35: - resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} - dependencies: - '@types/node': 16.18.6 - dev: true - - /@types/cookie@0.5.1: - resolution: {integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==} + /@types/cookie@0.6.0: + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} dev: false - /@types/d3-geo@3.0.4: - resolution: {integrity: sha512-kmUK8rVVIBPKJ1/v36bk2aSgwRj2N/ZkjDT+FkMT5pgedZoPlyhaG62J+9EgNIgUXE6IIL0b7bkLxCzhE6U4VQ==} + /@types/d3-geo@3.1.0: + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} dependencies: - '@types/geojson': 7946.0.10 + '@types/geojson': 7946.0.13 dev: true - /@types/estree@1.0.3: - resolution: {integrity: sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ==} - - /@types/geojson@7946.0.10: - resolution: {integrity: sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==} - dev: true + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - /@types/gitignore-parser@0.0.2: - resolution: {integrity: sha512-T1yLXu5BQ5Wet3gYfXBA+Nj1fTZp1ijl8EMMKPdAOy3WDVDJGXNmHTF7LMXS+FVYG+919bdil0LwLjPtX8w8Tg==} + /@types/geojson@7946.0.13: + resolution: {integrity: sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==} dev: true - /@types/is-ci@3.0.0: - resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} - dependencies: - ci-info: 3.8.0 + /@types/gitignore-parser@0.0.3: + resolution: {integrity: sha512-sbdu1sG2pQcwjEYWTsX78OqJo5pKnonwC4FV3m2JeQRE2xYb3q0icHHopCHEvpn4uIBuvWBTpJUCJ76ISK24CA==} dev: true - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} dev: true - /@types/json-schema@7.0.12: - resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true - /@types/minimist@1.2.2: - resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} + /@types/minimist@1.2.5: + resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} dev: true - /@types/mri@1.1.1: - resolution: {integrity: sha512-nJOuiTlsvmClSr3+a/trTSx4DTuY/VURsWGKSf/eeavh0LRMqdsK60ti0TlwM5iHiGOK3/Ibkxsbr7i9rzGreA==} + /@types/mri@1.1.5: + resolution: {integrity: sha512-C6NscC1RO9iz1YmvqPlFdbo/q8krKwrvWsciw2MG+pH+WUgxWKv1VFpY/Y2AAZubzUpA4FH6d+FDtroboN9xMw==} dev: true /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: true - /@types/node@16.18.6: - resolution: {integrity: sha512-vmYJF0REqDyyU0gviezF/KHq/fYaUbFhkcNbQCuPGFQj6VTbXuHZoxs/Y7mutWe73C8AC6l9fFu8mSYiBAqkGA==} + /@types/node@18.19.3: + resolution: {integrity: sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==} + dependencies: + undici-types: 5.26.5 + dev: true - /@types/normalize-package-data@2.4.1: - resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + /@types/normalize-package-data@2.4.4: + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true - /@types/prompts@2.4.1: - resolution: {integrity: sha512-1Mqzhzi9W5KlooNE4o0JwSXGUDeQXKldbGn9NO4tpxwZbHXYd+WcKpCksG2lbhH7U9I9LigfsdVsP2QAY0lNPA==} + /@types/prompts@2.4.9: + resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} dependencies: - '@types/node': 16.18.6 + '@types/node': 18.19.3 + kleur: 3.0.3 dev: true - /@types/pug@2.0.6: - resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==} + /@types/pug@2.0.10: + resolution: {integrity: sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==} dev: true /@types/resolve@1.20.2: resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - /@types/sade@1.7.4: - resolution: {integrity: sha512-6ys13kmtlY0aIOz4KtMdeBD9BHs6vSE3aRcj4vAZqXjypT2el8WZt6799CMjElVgh1cbOH/t3vrpQ4IpwytcPA==} + /@types/sade@1.7.8: + resolution: {integrity: sha512-WGEWfxQ8VHLm3JS4ljRR3MSPqVjY0JMo6zsbBywOjFIxP8Cizxx1p6r6FxOnAOZpUn4VOFoRRTXFmaOLD/+VOQ==} dependencies: - '@types/mri': 1.1.1 + '@types/mri': 1.1.5 dev: true - /@types/semver@7.5.0: - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + /@types/semver@7.5.6: + resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} dev: true - /@types/set-cookie-parser@2.4.2: - resolution: {integrity: sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==} + /@types/set-cookie-parser@2.4.7: + resolution: {integrity: sha512-+ge/loa0oTozxip6zmhRIk8Z/boU51wl9Q6QdLZcokIGMzY5lFXYy/x7Htj2HTC6/KZP1hUbZ1ekx8DYXICvWg==} dependencies: - '@types/node': 16.18.6 + '@types/node': 18.19.3 dev: true - /@types/ws@8.5.3: - resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} + /@types/ws@8.5.10: + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 16.18.6 + '@types/node': 18.19.3 dev: true - /@typescript-eslint/eslint-plugin@6.0.0(@typescript-eslint/parser@6.14.0)(eslint@8.52.0)(typescript@4.9.4): - resolution: {integrity: sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==} + /@typescript-eslint/eslint-plugin@6.14.0(@typescript-eslint/parser@6.14.0)(eslint@8.55.0)(typescript@5.3.3): + resolution: {integrity: sha512-1ZJBykBCXaSHG94vMMKmiHoL0MhNHKSVlcHVYZNw+BKxufhqQVTOawNpwwI1P5nIFZ/4jLVop0mcY6mJJDFNaw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -2237,27 +2383,25 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 6.14.0(eslint@8.52.0)(typescript@4.9.4) - '@typescript-eslint/scope-manager': 6.0.0 - '@typescript-eslint/type-utils': 6.0.0(eslint@8.52.0)(typescript@4.9.4) - '@typescript-eslint/utils': 6.0.0(eslint@8.52.0)(typescript@4.9.4) - '@typescript-eslint/visitor-keys': 6.0.0 + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 6.14.0(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.14.0 + '@typescript-eslint/type-utils': 6.14.0(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.14.0(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.14.0 debug: 4.3.4 - eslint: 8.52.0 - grapheme-splitter: 1.0.4 + eslint: 8.55.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.0 natural-compare: 1.4.0 - natural-compare-lite: 1.4.0 semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@4.9.4) - typescript: 4.9.4 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.14.0(eslint@8.52.0)(typescript@4.9.4): + /@typescript-eslint/parser@6.14.0(eslint@8.55.0)(typescript@5.3.3): resolution: {integrity: sha512-QjToC14CKacd4Pa7JK4GeB/vHmWFJckec49FR4hmIRf97+KXole0T97xxu9IFiPxVQ1DBWrQ5wreLwAGwWAVQA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2269,23 +2413,15 @@ packages: dependencies: '@typescript-eslint/scope-manager': 6.14.0 '@typescript-eslint/types': 6.14.0 - '@typescript-eslint/typescript-estree': 6.14.0(typescript@4.9.4) + '@typescript-eslint/typescript-estree': 6.14.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.14.0 debug: 4.3.4 - eslint: 8.52.0 - typescript: 4.9.4 + eslint: 8.55.0 + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@6.0.0: - resolution: {integrity: sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.0.0 - '@typescript-eslint/visitor-keys': 6.0.0 - dev: true - /@typescript-eslint/scope-manager@6.14.0: resolution: {integrity: sha512-VT7CFWHbZipPncAZtuALr9y3EuzY1b1t1AEkIq2bTXUPKw+pHoXflGNG5L+Gv6nKul1cz1VH8fz16IThIU0tdg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2294,8 +2430,8 @@ packages: '@typescript-eslint/visitor-keys': 6.14.0 dev: true - /@typescript-eslint/type-utils@6.0.0(eslint@8.52.0)(typescript@4.9.4): - resolution: {integrity: sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==} + /@typescript-eslint/type-utils@6.14.0(eslint@8.55.0)(typescript@5.3.3): + resolution: {integrity: sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -2304,48 +2440,22 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.0.0(typescript@4.9.4) - '@typescript-eslint/utils': 6.0.0(eslint@8.52.0)(typescript@4.9.4) + '@typescript-eslint/typescript-estree': 6.14.0(typescript@5.3.3) + '@typescript-eslint/utils': 6.14.0(eslint@8.55.0)(typescript@5.3.3) debug: 4.3.4 - eslint: 8.52.0 - ts-api-utils: 1.0.1(typescript@4.9.4) - typescript: 4.9.4 + eslint: 8.55.0 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@6.0.0: - resolution: {integrity: sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==} - engines: {node: ^16.0.0 || >=18.0.0} - dev: true - /@typescript-eslint/types@6.14.0: resolution: {integrity: sha512-uty9H2K4Xs8E47z3SnXEPRNDfsis8JO27amp2GNCnzGETEW3yTqEIVg5+AI7U276oGF/tw6ZA+UesxeQ104ceA==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.0.0(typescript@4.9.4): - resolution: {integrity: sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 6.0.0 - '@typescript-eslint/visitor-keys': 6.0.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@4.9.4) - typescript: 4.9.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/typescript-estree@6.14.0(typescript@4.9.4): + /@typescript-eslint/typescript-estree@6.14.0(typescript@5.3.3): resolution: {integrity: sha512-yPkaLwK0yH2mZKFE/bXkPAkkFgOv15GJAUzgUVonAbv0Hr4PK/N2yaA/4XQbTZQdygiDkpt5DkxPELqHguNvyw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2360,40 +2470,31 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@4.9.4) - typescript: 4.9.4 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.0.0(eslint@8.52.0)(typescript@4.9.4): - resolution: {integrity: sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==} + /@typescript-eslint/utils@6.14.0(eslint@8.55.0)(typescript@5.3.3): + resolution: {integrity: sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) - '@types/json-schema': 7.0.12 - '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 6.0.0 - '@typescript-eslint/types': 6.0.0 - '@typescript-eslint/typescript-estree': 6.0.0(typescript@4.9.4) - eslint: 8.52.0 - eslint-scope: 5.1.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.6 + '@typescript-eslint/scope-manager': 6.14.0 + '@typescript-eslint/types': 6.14.0 + '@typescript-eslint/typescript-estree': 6.14.0(typescript@5.3.3) + eslint: 8.55.0 semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@6.0.0: - resolution: {integrity: sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.0.0 - eslint-visitor-keys: 3.4.3 - dev: true - /@typescript-eslint/visitor-keys@6.14.0: resolution: {integrity: sha512-fB5cw6GRhJUz03MrROVuj5Zm/Q+XWlVdIsFj+Zb1Hvqouc8t+XP2H5y53QYU/MGtd2dPg6/vJJlhoX3xc2ehfw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2432,62 +2533,62 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vercel/nft@0.24.0: - resolution: {integrity: sha512-6TaZleggfN0zsT8QVyOGStYAfKgvfinhpj8jEcdN6Hx6BSWpfkipoM7IVmQd4rCnEgPUFx9zLU2Di6iA0nstUA==} + /@vercel/nft@0.24.4: + resolution: {integrity: sha512-KjYAZty7boH5fi5udp6p+lNu6nawgs++pHW+3koErMgbRkkHuToGX/FwjN5clV1FcaM3udfd4zW/sUapkMgpZw==} engines: {node: '>=16'} hasBin: true dependencies: '@mapbox/node-pre-gyp': 1.0.11 '@rollup/pluginutils': 4.2.1 - acorn: 8.10.0 + acorn: 8.11.2 async-sema: 3.1.1 bindings: 1.5.0 estree-walker: 2.0.2 glob: 7.2.3 graceful-fs: 4.2.11 micromatch: 4.0.5 - node-gyp-build: 4.6.0 + node-gyp-build: 4.7.1 resolve-from: 5.0.0 transitivePeerDependencies: - encoding - supports-color dev: false - /@vitest/expect@0.34.5: - resolution: {integrity: sha512-/3RBIV9XEH+nRpRMqDJBufKIOQaYUH2X6bt0rKSCW0MfKhXFLYsR5ivHifeajRSTsln0FwJbitxLKHSQz/Xwkw==} + /@vitest/expect@1.0.4: + resolution: {integrity: sha512-/NRN9N88qjg3dkhmFcCBwhn/Ie4h064pY3iv7WLRsDJW7dXnEgeoa8W9zy7gIPluhz6CkgqiB3HmpIXgmEY5dQ==} dependencies: - '@vitest/spy': 0.34.5 - '@vitest/utils': 0.34.5 - chai: 4.3.8 + '@vitest/spy': 1.0.4 + '@vitest/utils': 1.0.4 + chai: 4.3.10 dev: true - /@vitest/runner@0.34.5: - resolution: {integrity: sha512-RDEE3ViVvl7jFSCbnBRyYuu23XxmvRTSZWW6W4M7eC5dOsK75d5LIf6uhE5Fqf809DQ1+9ICZZNxhIolWHU4og==} + /@vitest/runner@1.0.4: + resolution: {integrity: sha512-rhOQ9FZTEkV41JWXozFM8YgOqaG9zA7QXbhg5gy6mFOVqh4PcupirIJ+wN7QjeJt8S8nJRYuZH1OjJjsbxAXTQ==} dependencies: - '@vitest/utils': 0.34.5 - p-limit: 4.0.0 + '@vitest/utils': 1.0.4 + p-limit: 5.0.0 pathe: 1.1.1 dev: true - /@vitest/snapshot@0.34.5: - resolution: {integrity: sha512-+ikwSbhu6z2yOdtKmk/aeoDZ9QPm2g/ZO5rXT58RR9Vmu/kB2MamyDSx77dctqdZfP3Diqv4mbc/yw2kPT8rmA==} + /@vitest/snapshot@1.0.4: + resolution: {integrity: sha512-vkfXUrNyNRA/Gzsp2lpyJxh94vU2OHT1amoD6WuvUAA12n32xeVZQ0KjjQIf8F6u7bcq2A2k969fMVxEsxeKYA==} dependencies: magic-string: 0.30.5 pathe: 1.1.1 pretty-format: 29.7.0 dev: true - /@vitest/spy@0.34.5: - resolution: {integrity: sha512-epsicsfhvBjRjCMOC/3k00mP/TBGQy8/P0DxOFiWyLt55gnZ99dqCfCiAsKO17BWVjn4eZRIjKvcqNmSz8gvmg==} + /@vitest/spy@1.0.4: + resolution: {integrity: sha512-9ojTFRL1AJVh0hvfzAQpm0QS6xIS+1HFIw94kl/1ucTfGCaj1LV/iuJU4Y6cdR03EzPDygxTHwE1JOm+5RCcvA==} dependencies: - tinyspy: 2.1.1 + tinyspy: 2.2.0 dev: true - /@vitest/utils@0.34.5: - resolution: {integrity: sha512-ur6CmmYQoeHMwmGb0v+qwkwN3yopZuZyf4xt1DBBSGBed8Hf9Gmbm/5dEWqgpLPdRx6Av6jcWXrjcKfkTzg/pw==} + /@vitest/utils@1.0.4: + resolution: {integrity: sha512-gsswWDXxtt0QvtK/y/LWukN7sGMYmnCcv1qv05CsY6cU/Y1zpGX1QuvLs+GO1inczpE6Owixeel3ShkjhYtGfA==} dependencies: diff-sequences: 29.6.3 - loupe: 2.3.6 + loupe: 2.3.7 pretty-format: 29.7.0 dev: true @@ -2495,21 +2596,21 @@ packages: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} dev: false - /acorn-jsx@5.3.2(acorn@8.10.0): + /acorn-jsx@5.3.2(acorn@8.11.2): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.10.0 + acorn: 8.11.2 dev: true - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + /acorn-walk@8.3.1: + resolution: {integrity: sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==} engines: {node: '>=0.4.0'} dev: true - /acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + /acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true @@ -2600,7 +2701,7 @@ packages: /array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 is-array-buffer: 3.0.2 dev: true @@ -2609,24 +2710,25 @@ packages: engines: {node: '>=8'} dev: true - /array.prototype.flat@1.3.1: - resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 - es-shim-unscopables: 1.0.0 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 dev: true - /arraybuffer.prototype.slice@1.0.1: - resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==} + /arraybuffer.prototype.slice@1.0.2: + resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 - call-bind: 1.0.2 - define-properties: 1.2.0 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 dev: true @@ -2654,17 +2756,9 @@ packages: dependencies: dequal: 2.0.3 - /b4a@1.6.4: - resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} - dev: false - /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: false - /better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -2682,14 +2776,6 @@ packages: file-uri-to-path: 1.0.0 dev: false - /bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - dev: false - /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -2713,34 +2799,27 @@ packages: wcwidth: 1.0.1 dev: true - /browserslist@4.21.10: - resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} + /browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001519 - electron-to-chromium: 1.4.488 - node-releases: 2.0.13 - update-browserslist-db: 1.0.11(browserslist@4.21.10) + caniuse-lite: 1.0.30001568 + electron-to-chromium: 1.4.611 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) dev: true /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} dev: true - /buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - dev: false - /builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} - /c8@8.0.0: - resolution: {integrity: sha512-XHA5vSfCLglAc0Xt8eLBZMv19lgiBSjnb1FLAQgnwkuhJYEonpilhEB4Ea3jPAbm0FhD6VVJrc0z73jPe7JyGQ==} + /c8@8.0.1: + resolution: {integrity: sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==} engines: {node: '>=12'} hasBin: true dependencies: @@ -2748,14 +2827,14 @@ packages: '@istanbuljs/schema': 0.1.3 find-up: 5.0.0 foreground-child: 2.0.0 - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.1.6 rimraf: 3.0.2 test-exclude: 6.0.0 - v8-to-istanbul: 9.1.0 - yargs: 16.2.0 - yargs-parser: 20.2.9 + v8-to-istanbul: 9.2.0 + yargs: 17.7.2 + yargs-parser: 21.1.1 dev: true /cac@6.7.14: @@ -2763,11 +2842,12 @@ packages: engines: {node: '>=8'} dev: true - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 dev: true /callsites@3.1.0: @@ -2789,19 +2869,19 @@ packages: engines: {node: '>=6'} dev: true - /caniuse-lite@1.0.30001519: - resolution: {integrity: sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==} + /caniuse-lite@1.0.30001568: + resolution: {integrity: sha512-vSUkH84HontZJ88MiNrOau1EBrCqEQYgkC5gIySiDlpsm8sGVrhU7Kx4V6h0tnqaHzIHZv08HlJIwPbL4XL9+A==} dev: true - /chai@4.3.8: - resolution: {integrity: sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==} + /chai@4.3.10: + resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==} engines: {node: '>=4'} dependencies: assertion-error: 1.1.0 - check-error: 1.0.2 + check-error: 1.0.3 deep-eql: 4.1.3 - get-func-name: 2.0.0 - loupe: 2.3.6 + get-func-name: 2.0.2 + loupe: 2.3.7 pathval: 1.1.1 type-detect: 4.0.8 dev: true @@ -2827,8 +2907,10 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true - /check-error@1.0.2: - resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 dev: true /chokidar@3.5.3: @@ -2845,17 +2927,13 @@ packages: optionalDependencies: fsevents: 2.3.3 - /chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - dev: false - /chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} dev: false - /ci-info@3.8.0: - resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} dev: true @@ -2874,14 +2952,6 @@ packages: wrap-ansi: 6.2.0 dev: true - /cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2900,12 +2970,12 @@ packages: resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} dev: false - /code-red@1.0.3: - resolution: {integrity: sha512-kVwJELqiILQyG5aeuyKFbdsI1fmQy1Cmf7dQ8eGmVuJoaRVdwey7WaMknr2ZFeVSYSKT0rExsa8EGw0aoI/1QQ==} + /code-red@1.0.4: + resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - '@types/estree': 1.0.3 - acorn: 8.10.0 + '@types/estree': 1.0.5 + acorn: 8.11.2 estree-walker: 3.0.3 periscopic: 3.1.0 @@ -2977,12 +3047,12 @@ packages: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} dev: false - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true - /cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + /cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} dev: false @@ -3098,13 +3168,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - dependencies: - mimic-response: 3.1.0 - dev: false - /dedent-js@1.0.1: resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} dev: false @@ -3116,11 +3179,6 @@ packages: type-detect: 4.0.8 dev: true - /deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - dev: false - /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true @@ -3135,11 +3193,21 @@ packages: clone: 1.0.4 dev: true - /define-properties@1.2.0: - resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} engines: {node: '>= 0.4'} dependencies: - has-property-descriptors: 1.0.0 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + has-property-descriptors: 1.0.1 object-keys: 1.1.1 dev: true @@ -3160,14 +3228,15 @@ packages: resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} engines: {node: '>=0.10'} hasBin: true + dev: true /detect-libc@2.0.2: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} dev: false - /devalue@4.3.1: - resolution: {integrity: sha512-Kc0TSP9IUU9eg55au5Q3YtqaYI2cgntVpunJV9Exbm9nvlBeTE5p2NqYHfpuXK6+VF2hF5PI+BPFPUti7e2N1g==} + /devalue@4.3.2: + resolution: {integrity: sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==} dev: false /diff-sequences@29.6.3: @@ -3203,9 +3272,11 @@ packages: resolution: {integrity: sha512-QgA6BUh2SoBYE/dSuMmeGhNdoGtGewt3Rn66xKyXoGNyjrKRXf163wuM+xeQ83p87l/3ALoB6Il1dgKyGS5pEw==} dev: true - /dts-buddy@0.2.4: - resolution: {integrity: sha512-41d7aGv2DXJYlzeKSKHf0GtpCC8OdpEHhz+aqjylKV5aP3fl4APzNmQ5hL5vSKZMaO/lrkrKWC+HQrxl+mcgUw==} + /dts-buddy@0.4.3(typescript@5.3.3): + resolution: {integrity: sha512-vytwDCQAj8rqYPbGsrjiOCRv3O2ipwyUwSc5/II1MpS/Eq6KNZNkGU1djOA31nL7jh7092W/nwbwZHCKedf8Vw==} hasBin: true + peerDependencies: + typescript: '>=5.0.4 <5.4' dependencies: '@jridgewell/source-map': 0.3.5 '@jridgewell/sourcemap-codec': 1.4.15 @@ -3215,23 +3286,17 @@ packages: magic-string: 0.30.5 sade: 1.8.1 tiny-glob: 0.2.9 - ts-api-utils: 1.0.2(typescript@5.0.4) - typescript: 5.0.4 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 dev: true - /electron-to-chromium@1.4.488: - resolution: {integrity: sha512-Dv4sTjiW7t/UWGL+H8ZkgIjtUAVZDgb/PwGWvMsCT7jipzUV/u5skbLXPFKb6iV0tiddVi/bcS2/kUrczeWgIQ==} + /electron-to-chromium@1.4.611: + resolution: {integrity: sha512-ZtRpDxrjHapOwxtv+nuth5ByB8clyn8crVynmRNGO3wG3LOp8RTcyZDqwaI6Ng6y8FCK2hVZmJoqwCskKbNMaw==} dev: true /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - /end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - dependencies: - once: 1.4.0 - dev: false - /enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -3246,26 +3311,26 @@ packages: is-arrayish: 0.2.1 dev: true - /es-abstract@1.22.1: - resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==} + /es-abstract@1.22.3: + resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 - arraybuffer.prototype.slice: 1.0.1 + arraybuffer.prototype.slice: 1.0.2 available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - es-set-tostringtag: 2.0.1 + call-bind: 1.0.5 + es-set-tostringtag: 2.0.2 es-to-primitive: 1.2.1 - function.prototype.name: 1.1.5 - get-intrinsic: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.2 get-symbol-description: 1.0.0 globalthis: 1.0.3 gopd: 1.0.1 - has: 1.0.3 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.1 has-proto: 1.0.1 has-symbols: 1.0.3 - internal-slot: 1.0.5 + hasown: 2.0.0 + internal-slot: 1.0.6 is-array-buffer: 3.0.2 is-callable: 1.2.7 is-negative-zero: 2.0.2 @@ -3274,36 +3339,36 @@ packages: is-string: 1.0.7 is-typed-array: 1.1.12 is-weakref: 1.0.2 - object-inspect: 1.12.3 + object-inspect: 1.13.1 object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.0 - safe-array-concat: 1.0.0 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.1 + safe-array-concat: 1.0.1 safe-regex-test: 1.0.0 - string.prototype.trim: 1.2.7 - string.prototype.trimend: 1.0.6 - string.prototype.trimstart: 1.0.6 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 typed-array-buffer: 1.0.0 typed-array-byte-length: 1.0.0 typed-array-byte-offset: 1.0.0 typed-array-length: 1.0.4 unbox-primitive: 1.0.2 - which-typed-array: 1.1.11 + which-typed-array: 1.1.13 dev: true - /es-set-tostringtag@2.0.1: - resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + /es-set-tostringtag@2.0.2: + resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 - has: 1.0.3 + get-intrinsic: 1.2.2 has-tostringtag: 1.0.0 + hasown: 2.0.0 dev: true - /es-shim-unscopables@1.0.0: - resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} dependencies: - has: 1.0.3 + hasown: 2.0.0 dev: true /es-to-primitive@1.2.1: @@ -3319,64 +3384,34 @@ packages: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} dev: true - /esbuild@0.18.11: - resolution: {integrity: sha512-i8u6mQF0JKJUlGR3OdFLKldJQMMs8OqM9Cc3UCi9XXziJ9WERM5bfkHaEAy0YAvPRMgqSW55W7xYn84XtEFTtA==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.18.11 - '@esbuild/android-arm64': 0.18.11 - '@esbuild/android-x64': 0.18.11 - '@esbuild/darwin-arm64': 0.18.11 - '@esbuild/darwin-x64': 0.18.11 - '@esbuild/freebsd-arm64': 0.18.11 - '@esbuild/freebsd-x64': 0.18.11 - '@esbuild/linux-arm': 0.18.11 - '@esbuild/linux-arm64': 0.18.11 - '@esbuild/linux-ia32': 0.18.11 - '@esbuild/linux-loong64': 0.18.11 - '@esbuild/linux-mips64el': 0.18.11 - '@esbuild/linux-ppc64': 0.18.11 - '@esbuild/linux-riscv64': 0.18.11 - '@esbuild/linux-s390x': 0.18.11 - '@esbuild/linux-x64': 0.18.11 - '@esbuild/netbsd-x64': 0.18.11 - '@esbuild/openbsd-x64': 0.18.11 - '@esbuild/sunos-x64': 0.18.11 - '@esbuild/win32-arm64': 0.18.11 - '@esbuild/win32-ia32': 0.18.11 - '@esbuild/win32-x64': 0.18.11 - dev: false - - /esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + /esbuild@0.19.9: + resolution: {integrity: sha512-U9CHtKSy+EpPsEBa+/A2gMs/h3ylBC0H0KSqIg7tpztHerLi6nrrcoUJAkNCEPumx8yJ+Byic4BVwHgRbN0TBg==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 + '@esbuild/android-arm': 0.19.9 + '@esbuild/android-arm64': 0.19.9 + '@esbuild/android-x64': 0.19.9 + '@esbuild/darwin-arm64': 0.19.9 + '@esbuild/darwin-x64': 0.19.9 + '@esbuild/freebsd-arm64': 0.19.9 + '@esbuild/freebsd-x64': 0.19.9 + '@esbuild/linux-arm': 0.19.9 + '@esbuild/linux-arm64': 0.19.9 + '@esbuild/linux-ia32': 0.19.9 + '@esbuild/linux-loong64': 0.19.9 + '@esbuild/linux-mips64el': 0.19.9 + '@esbuild/linux-ppc64': 0.19.9 + '@esbuild/linux-riscv64': 0.19.9 + '@esbuild/linux-s390x': 0.19.9 + '@esbuild/linux-x64': 0.19.9 + '@esbuild/netbsd-x64': 0.19.9 + '@esbuild/openbsd-x64': 0.19.9 + '@esbuild/sunos-x64': 0.19.9 + '@esbuild/win32-arm64': 0.19.9 + '@esbuild/win32-ia32': 0.19.9 + '@esbuild/win32-x64': 0.19.9 /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} @@ -3393,53 +3428,64 @@ packages: engines: {node: '>=10'} dev: true - /eslint-config-prettier@9.0.0(eslint@8.52.0): - resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} + /eslint-compat-utils@0.1.2(eslint@8.55.0): + resolution: {integrity: sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + eslint: 8.55.0 + dev: true + + /eslint-config-prettier@9.1.0(eslint@8.55.0): + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.52.0 + eslint: 8.55.0 dev: true - /eslint-plugin-svelte@2.31.0(eslint@8.52.0)(svelte@4.2.7): - resolution: {integrity: sha512-Q70jPFRraTkc/giPSfY7yuatmJcb5fPelWNplevqd45gfaJDjc3qXRtWQ6m9U5tWVVYERU9dcdUod294vwD8Gw==} + /eslint-plugin-svelte@2.35.1(eslint@8.55.0)(svelte@4.2.8): + resolution: {integrity: sha512-IF8TpLnROSGy98Z3NrsKXWDSCbNY2ReHDcrYTuXZMbfX7VmESISR78TWgO9zdg4Dht1X8coub5jKwHzP0ExRug==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0-0 - svelte: ^3.37.0 || ^4.0.0-0 + svelte: ^3.37.0 || ^4.0.0 peerDependenciesMeta: svelte: optional: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) '@jridgewell/sourcemap-codec': 1.4.15 debug: 4.3.4 - eslint: 8.52.0 + eslint: 8.55.0 + eslint-compat-utils: 0.1.2(eslint@8.55.0) esutils: 2.0.3 - known-css-properties: 0.27.0 - postcss: 8.4.31 - postcss-load-config: 3.1.4(postcss@8.4.31) - postcss-safe-parser: 6.0.0(postcss@8.4.31) + known-css-properties: 0.29.0 + postcss: 8.4.32 + postcss-load-config: 3.1.4(postcss@8.4.32) + postcss-safe-parser: 6.0.0(postcss@8.4.32) postcss-selector-parser: 6.0.13 - svelte: 4.2.7 - svelte-eslint-parser: 0.31.0(svelte@4.2.7) + semver: 7.5.4 + svelte: 4.2.8 + svelte-eslint-parser: 0.33.1(svelte@4.2.8) transitivePeerDependencies: - supports-color - ts-node dev: true - /eslint-plugin-unicorn@49.0.0(eslint@8.52.0): + /eslint-plugin-unicorn@49.0.0(eslint@8.55.0): resolution: {integrity: sha512-0fHEa/8Pih5cmzFW5L7xMEfUTvI9WKeQtjmKpTUmY+BiFCDxkxrTdnURJOHKykhtwIeyYsxnecbGvDCml++z4Q==} engines: {node: '>=16'} peerDependencies: eslint: '>=8.52.0' dependencies: '@babel/helper-validator-identifier': 7.22.20 - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) - ci-info: 3.8.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) + ci-info: 3.9.0 clean-regexp: 1.0.0 - eslint: 8.52.0 + eslint: 8.55.0 esquery: 1.5.0 indent-string: 4.0.0 is-builtin-module: 3.2.1 @@ -3452,14 +3498,6 @@ packages: strip-indent: 3.0.0 dev: true - /eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: 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} @@ -3473,15 +3511,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.52.0: - resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==} + /eslint@8.55.0: + resolution: {integrity: sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) - '@eslint-community/regexpp': 4.6.2 - '@eslint/eslintrc': 2.1.2 - '@eslint/js': 8.52.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.55.0 '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -3501,9 +3539,9 @@ packages: file-entry-cache: 6.0.1 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.20.0 + globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -3527,8 +3565,8 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) + acorn: 8.11.2 + acorn-jsx: 5.3.2(acorn@8.11.2) eslint-visitor-keys: 3.4.3 dev: true @@ -3552,11 +3590,6 @@ packages: estraverse: 5.3.0 dev: true - /estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true - /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -3568,17 +3601,27 @@ packages: /estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} dev: true - /expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - dev: false + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true /extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} @@ -3597,21 +3640,6 @@ packages: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true - /fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - dev: false - - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -3621,7 +3649,6 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: false /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -3645,7 +3672,7 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flat-cache: 3.0.4 + flat-cache: 3.2.0 dev: true /file-uri-to-path@1.0.0: @@ -3681,16 +3708,17 @@ packages: pkg-dir: 4.2.0 dev: true - /flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flatted: 3.2.7 + flatted: 3.2.9 + keyv: 4.5.4 rimraf: 3.0.2 dev: true - /flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + /flatted@3.2.9: + resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} dev: true /flexsearch@0.7.31: @@ -3711,10 +3739,6 @@ packages: signal-exit: 3.0.7 dev: true - /fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - dev: false - /fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -3750,16 +3774,16 @@ packages: requiresBuild: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - /function.prototype.name@1.1.5: - resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 functions-have-names: 1.2.3 dev: true @@ -3787,17 +3811,17 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-func-name@2.0.0: - resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: true - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: - function-bind: 1.1.1 - has: 1.0.3 + function-bind: 1.1.2 has-proto: 1.0.1 has-symbols: 1.0.3 + hasown: 2.0.0 dev: true /get-port@3.2.0: @@ -3805,18 +3829,19 @@ packages: engines: {node: '>=4'} dev: true + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 dev: true - /github-from-package@0.0.0: - resolution: {integrity: sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=} - dev: false - /gitignore-parser@0.0.2: resolution: {integrity: sha512-X6mpqUv59uWLGD4n3hZ8Cu8KbF2PMWPSFYmxZjdkpm3yOU7hSUYnzTkZI1mcWqchphvqyuz3/BhgBR4E/JtkCg==} engines: {node: '>=0.10.0'} @@ -3866,8 +3891,8 @@ packages: minimatch: 5.1.6 once: 1.4.0 - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + /globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 @@ -3877,7 +3902,7 @@ packages: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} dependencies: - define-properties: 1.2.0 + define-properties: 1.2.1 dev: true /globalyzer@0.1.0: @@ -3889,8 +3914,8 @@ packages: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 + fast-glob: 3.3.2 + ignore: 5.3.0 merge2: 1.4.1 slash: 3.0.0 dev: true @@ -3901,7 +3926,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true /graceful-fs@4.2.11: @@ -3934,10 +3959,10 @@ packages: engines: {node: '>=8'} dev: true - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true /has-proto@1.0.1: @@ -3961,11 +3986,11 @@ packages: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} dev: false - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -3989,6 +4014,11 @@ packages: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -3996,20 +4026,16 @@ packages: safer-buffer: 2.1.2 dev: true - /ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: false - - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + /ignore@5.3.0: + resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} dev: true - /imagetools-core@6.0.0: - resolution: {integrity: sha512-oH6Rng1AJSwaJnQ0nJBKvEPyz0u5tXHy4dN0ujvf7hMljVBh/Dp/qoDU1gGR26eR13VgyVKiy8XzXEBCwgHtCw==} + /imagetools-core@6.0.3: + resolution: {integrity: sha512-3J7Dww03g0dZU5NLbuDRqCqH/AnedR0T3mOl7AP0Curqt/OEtghiDw7Py+Dwa17xL7yJ0uemdEutWkOZm6CnaQ==} engines: {node: '>=12.0.0'} dependencies: - sharp: 0.32.6 + sharp: 0.33.0 dev: false /import-fresh@3.3.0: @@ -4043,16 +4069,12 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - /ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - dev: false - - /internal-slot@1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + /internal-slot@1.0.6: + resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 - has: 1.0.3 + get-intrinsic: 1.2.2 + hasown: 2.0.0 side-channel: 1.0.4 dev: true @@ -4064,8 +4086,8 @@ packages: /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-typed-array: 1.1.12 dev: true @@ -4093,7 +4115,7 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true @@ -4108,17 +4130,10 @@ packages: engines: {node: '>= 0.4'} dev: true - /is-ci@3.0.1: - resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} - hasBin: true - dependencies: - ci-info: 3.8.0 - dev: true - - /is-core-module@2.13.0: - resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: - has: 1.0.3 + hasown: 2.0.0 /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -4177,25 +4192,30 @@ packages: /is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 - /is-reference@3.0.1: - resolution: {integrity: sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==} + /is-reference@3.0.2: + resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 + dev: true + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true /is-string@1.0.7: @@ -4223,13 +4243,13 @@ packages: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} dependencies: - which-typed-array: 1.1.11 + which-typed-array: 1.1.13 dev: true /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 dev: true /is-windows@1.0.2: @@ -4245,8 +4265,8 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} dev: true @@ -4254,7 +4274,7 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} dependencies: - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 dev: true @@ -4297,6 +4317,10 @@ packages: hasBin: true dev: true + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: true @@ -4319,6 +4343,12 @@ packages: graceful-fs: 4.2.11 dev: true + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -4327,14 +4357,13 @@ packages: /kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} - dev: false /kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} - /known-css-properties@0.27.0: - resolution: {integrity: sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==} + /known-css-properties@0.29.0: + resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} dev: true /levn@0.4.1: @@ -4345,93 +4374,103 @@ packages: type-check: 0.4.0 dev: true - /lightningcss-darwin-arm64@1.21.8: - resolution: {integrity: sha512-BOMoGfcgkk2f4ltzsJqmkjiqRtlZUK+UdwhR+P6VgIsnpQBV3G01mlL6GzYxYqxq+6/3/n/D+4oy2NeknmADZw==} + /lightningcss-darwin-arm64@1.22.1: + resolution: {integrity: sha512-ldvElu+R0QimNTjsKpaZkUv3zf+uefzLy/R1R19jtgOfSRM+zjUCUgDhfEDRmVqJtMwYsdhMI2aJtJChPC6Osg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] requiresBuild: true + dev: true optional: true - /lightningcss-darwin-x64@1.21.8: - resolution: {integrity: sha512-YhF64mcVDPKKufL4aNFBnVH7uvzE0bW3YUsPXdP4yUcT/8IXChypOZ/PE1pmt2RlbmsyVuuIIeZU4zTyZe5Amw==} + /lightningcss-darwin-x64@1.22.1: + resolution: {integrity: sha512-5p2rnlVTv6Gpw4PlTLq925nTVh+HFh4MpegX8dPDYJae+NFVjQ67gY7O6iHIzQjLipDiYejFF0yHrhjU3XgLBQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] requiresBuild: true + dev: true optional: true - /lightningcss-freebsd-x64@1.21.8: - resolution: {integrity: sha512-CV6A/vTG2Ryd3YpChEgfWWv4TXCAETo9TcHSNx0IP0dnKcnDEiAko4PIKhCqZL11IGdN1ZLBCVPw+vw5ZYwzfA==} + /lightningcss-freebsd-x64@1.22.1: + resolution: {integrity: sha512-1FaBtcFrZqB2hkFbAxY//Pnp8koThvyB6AhjbdVqKD4/pu13Rl91fKt2N9qyeQPUt3xy7ORUvSO+dPk3J6EjXg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] requiresBuild: true + dev: true optional: true - /lightningcss-linux-arm-gnueabihf@1.21.8: - resolution: {integrity: sha512-9PMbqh8n/Xq0F4/j2NR/hHM2HRDiFXFSF0iOvV67pNWKJkHIO6mR8jBw/88Aro5Ye/ILsX5OuWsxIVJDFv0NXA==} + /lightningcss-linux-arm-gnueabihf@1.22.1: + resolution: {integrity: sha512-6rub98tYGfE5I5j0BP8t/2d4BZyu1S7Iz9vUkm0H26snAFHYxLfj3RbQn0xHHIePSetjLnhcg3QlfwUAkD/FYg==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] requiresBuild: true + dev: true optional: true - /lightningcss-linux-arm64-gnu@1.21.8: - resolution: {integrity: sha512-JTM/TuMMllkzaXV7/eDjG4IJKLlCl+RfYZwtsVmC82gc0QX0O37csGAcY2OGleiuA4DnEo/Qea5WoFfZUNC6zg==} + /lightningcss-linux-arm64-gnu@1.22.1: + resolution: {integrity: sha512-nYO5qGtb/1kkTZu3FeTiM+2B2TAb7m2DkLCTgQIs2bk2o9aEs7I96fwySKcoHWQAiQDGR9sMux9vkV4KQXqPaQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] requiresBuild: true + dev: true optional: true - /lightningcss-linux-arm64-musl@1.21.8: - resolution: {integrity: sha512-01gWShXrgoIb8urzShpn1RWtZuaSyKSzF2hfO+flzlTPoACqcO3rgcu/3af4Cw54e8vKzL5hPRo4kROmgaOMLg==} + /lightningcss-linux-arm64-musl@1.22.1: + resolution: {integrity: sha512-MCV6RuRpzXbunvzwY644iz8cw4oQxvW7oer9xPkdadYqlEyiJJ6wl7FyJOH7Q6ZYH4yjGAUCvxDBxPbnDu9ZVg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] requiresBuild: true + dev: true optional: true - /lightningcss-linux-x64-gnu@1.21.8: - resolution: {integrity: sha512-yVB5vYJjJb/Aku0V9QaGYIntvK/1TJOlNB9GmkNpXX5bSSP2pYW4lWW97jxFMHO908M0zjEt1qyOLMyqojHL+Q==} + /lightningcss-linux-x64-gnu@1.22.1: + resolution: {integrity: sha512-RjNgpdM20VUXgV7us/VmlO3Vn2ZRiDnc3/bUxCVvySZWPiVPprpqW/QDWuzkGa+NCUf6saAM5CLsZLSxncXJwg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] requiresBuild: true + dev: true optional: true - /lightningcss-linux-x64-musl@1.21.8: - resolution: {integrity: sha512-TYi+KNtBVK0+FZvxTX/d5XJb+tw3Jq+2Rr9hW359wp1afsi1Vkg+uVGgbn+m2dipa5XwpCseQq81ylMlXuyfPw==} + /lightningcss-linux-x64-musl@1.22.1: + resolution: {integrity: sha512-ZgO4C7Rd6Hv/5MnyY2KxOYmIlzk4rplVolDt3NbkNR8DndnyX0Q5IR4acJWNTBICQ21j3zySzKbcJaiJpk/4YA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] requiresBuild: true + dev: true optional: true - /lightningcss-win32-x64-msvc@1.21.8: - resolution: {integrity: sha512-mww+kqbPx0/C44l2LEloECtRUuOFDjq9ftp+EHTPiCp2t+avy0sh8MaFwGsrKkj2XfZhaRhi4CPVKBoqF1Qlwg==} + /lightningcss-win32-x64-msvc@1.22.1: + resolution: {integrity: sha512-4pozV4eyD0MDET41ZLHAeBo+H04Nm2UEYIk5w/ts40231dRFV7E0cjwbnZvSoc1DXFgecAhiC0L16ruv/ZDCpg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] requiresBuild: true + dev: true optional: true - /lightningcss@1.21.8: - resolution: {integrity: sha512-jEqaL7m/ZckZJjlMAfycr1Kpz7f93k6n7KGF5SJjuPSm6DWI6h3ayLZmgRHgy1OfrwoCed6h4C/gHYPOd1OFMA==} + /lightningcss@1.22.1: + resolution: {integrity: sha512-Fy45PhibiNXkm0cK5FJCbfO8Y6jUpD/YcHf/BtuI+jvYYqSXKF4muk61jjE8YxCR9y+hDYIWSzHTc+bwhDE6rQ==} engines: {node: '>= 12.0.0'} dependencies: detect-libc: 1.0.3 optionalDependencies: - lightningcss-darwin-arm64: 1.21.8 - lightningcss-darwin-x64: 1.21.8 - lightningcss-freebsd-x64: 1.21.8 - lightningcss-linux-arm-gnueabihf: 1.21.8 - lightningcss-linux-arm64-gnu: 1.21.8 - lightningcss-linux-arm64-musl: 1.21.8 - lightningcss-linux-x64-gnu: 1.21.8 - lightningcss-linux-x64-musl: 1.21.8 - lightningcss-win32-x64-msvc: 1.21.8 + lightningcss-darwin-arm64: 1.22.1 + lightningcss-darwin-x64: 1.22.1 + lightningcss-freebsd-x64: 1.22.1 + lightningcss-linux-arm-gnueabihf: 1.22.1 + lightningcss-linux-arm64-gnu: 1.22.1 + lightningcss-linux-arm64-musl: 1.22.1 + lightningcss-linux-x64-gnu: 1.22.1 + lightningcss-linux-x64-musl: 1.22.1 + lightningcss-win32-x64-msvc: 1.22.1 + dev: true /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} @@ -4457,9 +4496,12 @@ packages: engines: {node: '>=6'} dev: true - /local-pkg@0.4.3: - resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} + dependencies: + mlly: 1.4.2 + pkg-types: 1.0.3 dev: true /locate-character@3.0.0: @@ -4487,16 +4529,16 @@ packages: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} dev: true - /loupe@2.3.6: - resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} dependencies: - get-func-name: 2.0.0 + get-func-name: 2.0.2 dev: true /lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: - tslib: 2.6.1 + tslib: 2.6.2 dev: false /lru-cache@4.1.5: @@ -4522,19 +4564,6 @@ packages: engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - - /magic-string@0.30.2: - resolution: {integrity: sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - dev: false - - /magic-string@0.30.3: - resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 dev: true /magic-string@0.30.5: @@ -4567,8 +4596,8 @@ packages: engines: {node: '>=8'} dev: true - /marked@11.0.0: - resolution: {integrity: sha512-2GsW34uXaFEGTQ/+3rCnNC6vUYTAgFuDLGl70v/aWinA5mIJtTrrFAmfbLOfVvgPyxXuDVL9He/7reCK+6j3Sw==} + /marked@11.1.0: + resolution: {integrity: sha512-fvKJWAPEafVj1dwGwcPI5mBB/0pvViL6NlCbNDG1HOIRwwAU/jeMoFxfbRLuirO1wRH7m4yPvBqD/O1wyWvayw==} engines: {node: '>= 18'} hasBin: true dev: true @@ -4580,7 +4609,7 @@ packages: resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} engines: {node: '>=8'} dependencies: - '@types/minimist': 1.2.2 + '@types/minimist': 1.2.5 camelcase-keys: 6.2.2 decamelize-keys: 1.1.1 hard-rejection: 2.1.0 @@ -4593,6 +4622,10 @@ packages: yargs-parser: 18.1.3 dev: true + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -4610,10 +4643,10 @@ packages: hasBin: true dev: true - /mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - dev: false + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} @@ -4649,6 +4682,7 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true /minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} @@ -4670,15 +4704,11 @@ packages: yallist: 4.0.0 dev: false - /mixme@0.5.9: - resolution: {integrity: sha512-VC5fg6ySUscaWUpI4gxCBTQMH2RdUpNrk+MsbpCYtIvf9SBJdiUey4qE7BXviJsJR4nDQxCZ+3yaYNW3guz/Pw==} + /mixme@0.5.10: + resolution: {integrity: sha512-5H76ANWinB1H3twpJ6JY8uvAtpmFvHNArpilJAjXRKXSDDLPIMoZArw5SH0q9z+lLs8IrMw7Q2VWpWimFKFT1Q==} engines: {node: '>= 8.0.0'} dev: true - /mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - dev: false - /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -4701,10 +4731,10 @@ packages: /mlly@1.4.2: resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} dependencies: - acorn: 8.10.0 + acorn: 8.11.2 pathe: 1.1.1 pkg-types: 1.0.3 - ufo: 1.3.0 + ufo: 1.3.2 dev: true /mri@1.2.0: @@ -4726,17 +4756,10 @@ packages: thenify-all: 1.6.0 dev: true - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - - /napi-build-utils@1.0.2: - resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} - dev: false - - /natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true /natural-compare@1.4.0: @@ -4747,22 +4770,11 @@ packages: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} dependencies: lower-case: 2.0.2 - tslib: 2.6.1 - dev: false - - /node-abi@3.47.0: - resolution: {integrity: sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==} - engines: {node: '>=10'} - dependencies: - semver: 7.5.4 + tslib: 2.6.2 dev: false - /node-addon-api@6.1.0: - resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} - dev: false - - /node-fetch@2.6.12: - resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} peerDependencies: encoding: ^0.1.0 @@ -4772,13 +4784,13 @@ packages: dependencies: whatwg-url: 5.0.0 - /node-gyp-build@4.6.0: - resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} + /node-gyp-build@4.7.1: + resolution: {integrity: sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==} hasBin: true dev: false - /node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} dev: true /nopt@5.0.0: @@ -4793,7 +4805,7 @@ packages: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.4 + resolve: 1.22.8 semver: 5.7.2 validate-npm-package-license: 3.0.4 dev: true @@ -4802,6 +4814,13 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + /npm-run-path@5.1.0: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + /npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} dependencies: @@ -4815,8 +4834,8 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} dev: true /object-keys@1.1.1: @@ -4824,12 +4843,12 @@ packages: engines: {node: '>= 0.4'} dev: true - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 + call-bind: 1.0.5 + define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 dev: true @@ -4839,6 +4858,13 @@ packages: dependencies: wrappy: 1.0.2 + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -4881,9 +4907,9 @@ packages: yocto-queue: 0.1.0 dev: true - /p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + /p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} dependencies: yocto-queue: 1.0.0 dev: true @@ -4923,7 +4949,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.23.5 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -4933,7 +4959,7 @@ packages: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} dependencies: no-case: 3.0.4 - tslib: 2.6.1 + tslib: 2.6.2 dev: false /path-browserify@1.0.1: @@ -4954,6 +4980,11 @@ packages: engines: {node: '>=8'} dev: true + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -4973,9 +5004,9 @@ packages: /periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} dependencies: - '@types/estree': 1.0.3 + '@types/estree': 1.0.5 estree-walker: 3.0.3 - is-reference: 3.0.1 + is-reference: 3.0.2 /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -5029,15 +5060,15 @@ packages: engines: {node: '>=4'} dev: true - /polka@1.0.0-next.23: - resolution: {integrity: sha512-19z2ny2aGdx+dns3icsQy6G7sWe0Dg7QTqSGE4B010EFbxvGzjjn37gBBjM8T0K2p6rthZ6+oXoBF3DcFceOPA==} + /polka@1.0.0-next.24: + resolution: {integrity: sha512-i0EB3KPaALOLBC8K27UhPzzDyhsrn6KxDu0+agIz6ZgA2oNqqQjxBn+z9w2Ba4obV/PoqEJtyfzBkYgqKEJYiA==} engines: {node: '>=8'} dependencies: - '@polka/url': 1.0.0-next.23 - trouter: 3.2.1 + '@polka/url': 1.0.0-next.24 + trouter: 4.0.0 dev: true - /postcss-load-config@3.1.4(postcss@8.4.31): + /postcss-load-config@3.1.4(postcss@8.4.32): resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} peerDependencies: @@ -5050,26 +5081,26 @@ packages: optional: true dependencies: lilconfig: 2.1.0 - postcss: 8.4.31 + postcss: 8.4.32 yaml: 1.10.2 dev: true - /postcss-safe-parser@6.0.0(postcss@8.4.31): + /postcss-safe-parser@6.0.0(postcss@8.4.32): resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.3.3 dependencies: - postcss: 8.4.31 + postcss: 8.4.32 dev: true - /postcss-scss@4.0.6(postcss@8.4.31): - resolution: {integrity: sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==} + /postcss-scss@4.0.9(postcss@8.4.32): + resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} engines: {node: '>=12.0'} peerDependencies: - postcss: ^8.4.19 + postcss: ^8.4.29 dependencies: - postcss: 8.4.31 + postcss: 8.4.32 dev: true /postcss-selector-parser@6.0.13: @@ -5080,35 +5111,17 @@ packages: util-deprecate: 1.0.2 dev: true - /postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + /postcss@8.4.32: + resolution: {integrity: sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.6 + nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.0.2 + dev: true - /prebuild-install@7.1.1: - resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - detect-libc: 2.0.2 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 1.0.2 - node-abi: 3.47.0 - pump: 3.0.0 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.1 - tunnel-agent: 0.6.0 - dev: false - - /preferred-pm@3.0.3: - resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} + /preferred-pm@3.1.2: + resolution: {integrity: sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q==} engines: {node: '>=10'} dependencies: find-up: 5.0.0 @@ -5122,14 +5135,14 @@ packages: engines: {node: '>= 0.8.0'} dev: true - /prettier-plugin-svelte@3.0.3(prettier@3.1.1)(svelte@4.2.7): - resolution: {integrity: sha512-dLhieh4obJEK1hnZ6koxF+tMUrZbV5YGvRpf2+OADyanjya5j0z1Llo8iGwiHmFWZVG/hLEw/AJD5chXd9r3XA==} + /prettier-plugin-svelte@3.1.2(prettier@3.1.1)(svelte@4.2.8): + resolution: {integrity: sha512-7xfMZtwgAWHMT0iZc8jN4o65zgbAQ3+O32V6W7pXrqNvKnHnkoyQCGCbKeUyXKZLbYE0YhFRnamfxfkEGxm8qA==} peerDependencies: prettier: ^3.0.0 - svelte: ^3.2.0 || ^4.0.0-next.0 + svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 dependencies: prettier: 3.1.1 - svelte: 4.2.7 + svelte: 4.2.8 dev: true /prettier@2.8.8: @@ -5174,40 +5187,19 @@ packages: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} dev: true - /pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - dev: false - - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: true /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - /queue-tick@1.0.1: - resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} - dev: false - /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} dev: true - /rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - dev: false - /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true @@ -5225,7 +5217,7 @@ packages: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} dependencies: - '@types/normalize-package-data': 2.4.1 + '@types/normalize-package-data': 2.4.4 normalize-package-data: 2.5.0 parse-json: 5.2.0 type-fest: 0.6.0 @@ -5273,25 +5265,25 @@ packages: hasBin: true dev: true - /regexp.prototype.flags@1.5.0: - resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - functions-have-names: 1.2.3 - dev: true - - /regexparam@1.3.0: - resolution: {integrity: sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==} - engines: {node: '>=6'} + call-bind: 1.0.5 + define-properties: 1.2.1 + set-function-name: 2.0.1 dev: true - /regexparam@2.0.1: - resolution: {integrity: sha512-zRgSaYemnNYxUv+/5SeoHI0eJIgTL/A2pUtXUPLHQxUldagouJ9p+K6IbIZ/JiQuCEv2E2B1O11SjVQy3aMCkw==} + /regexparam@2.0.2: + resolution: {integrity: sha512-A1PeDEYMrkLrfyOwv2jwihXbo9qxdGD3atBYQA9JJgreAx8/7rC6IUkWOw2NQlOxLp2wL0ifQbh1HuidDfYA6w==} engines: {node: '>=8'} dev: false + /regexparam@3.0.0: + resolution: {integrity: sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==} + engines: {node: '>=8'} + dev: true + /regjsparser@0.10.0: resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} hasBin: true @@ -5317,11 +5309,11 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - /resolve@1.22.4: - resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true dependencies: - is-core-module: 2.13.0 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -5348,6 +5340,27 @@ packages: hasBin: true optionalDependencies: fsevents: 2.3.3 + dev: true + + /rollup@4.8.0: + resolution: {integrity: sha512-NpsklK2fach5CdI+PScmlE5R4Ao/FSWtF7LkoIrHDxPACY/xshNasPsbpG0VVHxUTbf74tJbVT4PrP8JsJ6ZDA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.8.0 + '@rollup/rollup-android-arm64': 4.8.0 + '@rollup/rollup-darwin-arm64': 4.8.0 + '@rollup/rollup-darwin-x64': 4.8.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.8.0 + '@rollup/rollup-linux-arm64-gnu': 4.8.0 + '@rollup/rollup-linux-arm64-musl': 4.8.0 + '@rollup/rollup-linux-riscv64-gnu': 4.8.0 + '@rollup/rollup-linux-x64-gnu': 4.8.0 + '@rollup/rollup-linux-x64-musl': 4.8.0 + '@rollup/rollup-win32-arm64-msvc': 4.8.0 + '@rollup/rollup-win32-ia32-msvc': 4.8.0 + '@rollup/rollup-win32-x64-msvc': 4.8.0 + fsevents: 2.3.3 /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -5360,12 +5373,12 @@ packages: dependencies: mri: 1.2.0 - /safe-array-concat@1.0.0: - resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==} + /safe-array-concat@1.0.1: + resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} engines: {node: '>=0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 has-symbols: 1.0.3 isarray: 2.0.5 dev: true @@ -5377,8 +5390,8 @@ packages: /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-regex: 1.1.4 dev: true @@ -5410,14 +5423,6 @@ packages: hasBin: true dev: false - /semver@7.5.3: - resolution: {integrity: sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: false - /semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} engines: {node: '>=10'} @@ -5432,19 +5437,53 @@ packages: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} dev: false - /sharp@0.32.6: - resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} - engines: {node: '>=14.15.0'} + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /set-function-name@2.0.1: + resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.1 + dev: true + + /sharp@0.33.0: + resolution: {integrity: sha512-99DZKudjm/Rmz+M0/26t4DKpXyywAOJaayGS9boEn7FvgtG0RYBi46uPE2c+obcJRtA3AZa0QwJot63gJQ1F0Q==} + engines: {libvips: '>=8.15.0', node: ^18.17.0 || ^20.3.0 || >=21.0.0} requiresBuild: true dependencies: color: 4.2.3 detect-libc: 2.0.2 - node-addon-api: 6.1.0 - prebuild-install: 7.1.1 semver: 7.5.4 - simple-get: 4.0.1 - tar-fs: 3.0.4 - tunnel-agent: 0.6.0 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.0 + '@img/sharp-darwin-x64': 0.33.0 + '@img/sharp-libvips-darwin-arm64': 1.0.0 + '@img/sharp-libvips-darwin-x64': 1.0.0 + '@img/sharp-libvips-linux-arm': 1.0.0 + '@img/sharp-libvips-linux-arm64': 1.0.0 + '@img/sharp-libvips-linux-s390x': 1.0.0 + '@img/sharp-libvips-linux-x64': 1.0.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.0 + '@img/sharp-libvips-linuxmusl-x64': 1.0.0 + '@img/sharp-linux-arm': 0.33.0 + '@img/sharp-linux-arm64': 0.33.0 + '@img/sharp-linux-s390x': 0.33.0 + '@img/sharp-linux-x64': 0.33.0 + '@img/sharp-linuxmusl-arm64': 0.33.0 + '@img/sharp-linuxmusl-x64': 0.33.0 + '@img/sharp-wasm32': 0.33.0 + '@img/sharp-win32-ia32': 0.33.0 + '@img/sharp-win32-x64': 0.33.0 dev: false /shebang-command@1.2.0: @@ -5496,9 +5535,9 @@ packages: /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 dev: true /siginfo@2.0.0: @@ -5508,17 +5547,10 @@ packages: /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - /simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - dev: false - - /simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - dev: false + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true /simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -5545,7 +5577,7 @@ packages: resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==} engines: {node: '>= 10'} dependencies: - '@polka/url': 1.0.0-next.23 + '@polka/url': 1.0.0-next.24 mrmime: 1.0.1 totalist: 3.0.1 @@ -5563,7 +5595,7 @@ packages: engines: {node: '>=6'} hasBin: true dependencies: - array.prototype.flat: 1.3.1 + array.prototype.flat: 1.3.2 breakword: 1.0.6 grapheme-splitter: 1.0.4 strip-ansi: 6.0.1 @@ -5596,7 +5628,7 @@ packages: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.13 + spdx-license-ids: 3.0.16 dev: true /spdx-exceptions@2.3.0: @@ -5607,11 +5639,11 @@ packages: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} dependencies: spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.13 + spdx-license-ids: 3.0.16 dev: true - /spdx-license-ids@3.0.13: - resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} + /spdx-license-ids@3.0.16: + resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} dev: true /sprintf-js@1.0.3: @@ -5622,23 +5654,16 @@ packages: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true - /std-env@3.3.3: - resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} + /std-env@3.6.0: + resolution: {integrity: sha512-aFZ19IgVmhdB2uX599ve2kE6BIE3YMnQ6Gp6BURhW/oIzpXGKr878TQfAQZn1+i0Flcc/UKUy1gOlcfaUBCryg==} dev: true /stream-transform@2.1.3: resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} dependencies: - mixme: 0.5.9 + mixme: 0.5.10 dev: true - /streamx@2.15.1: - resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} - dependencies: - fast-fifo: 1.3.2 - queue-tick: 1.0.1 - dev: false - /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -5647,29 +5672,29 @@ packages: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - /string.prototype.trim@1.2.7: - resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 dev: true - /string.prototype.trimend@1.0.6: - resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 dev: true - /string.prototype.trimstart@1.0.6: - resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 dev: true /string_decoder@1.3.0: @@ -5689,6 +5714,11 @@ packages: engines: {node: '>=4'} dev: true + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + /strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -5696,11 +5726,6 @@ packages: min-indent: 1.0.1 dev: true - /strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - dev: false - /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -5709,14 +5734,15 @@ packages: /strip-literal@1.3.0: resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} dependencies: - acorn: 8.10.0 + acorn: 8.11.2 dev: true - /sucrase@3.29.0: - resolution: {integrity: sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==} + /sucrase@3.34.0: + resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} engines: {node: '>=8'} hasBin: true dependencies: + '@jridgewell/gen-mapping': 0.3.3 commander: 4.1.1 glob: 7.1.6 lines-and-columns: 1.2.4 @@ -5743,21 +5769,21 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /svelte-check@3.4.4(postcss@8.4.31)(svelte@4.2.7): - resolution: {integrity: sha512-Uys9+R65cj8TmP8f5UpS7B2xKpNLYNxEWJsA5ZoKcWq/uwvABFF7xS6iPQGLoa7hxz0DS6xU60YFpmq06E4JxA==} + /svelte-check@3.6.2(postcss@8.4.32)(svelte@4.2.8): + resolution: {integrity: sha512-E6iFh4aUCGJLRz6QZXH3gcN/VFfkzwtruWSRmlKrLWQTiO6VzLsivR6q02WYLGNAGecV3EocqZuCDrC2uttZ0g==} hasBin: true peerDependencies: - svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0 + svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0 dependencies: - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.20 chokidar: 3.5.3 - fast-glob: 3.3.1 + fast-glob: 3.3.2 import-fresh: 3.3.0 picocolors: 1.0.0 sade: 1.8.1 - svelte: 4.2.7 - svelte-preprocess: 5.0.4(postcss@8.4.31)(svelte@4.2.7)(typescript@5.0.4) - typescript: 5.0.4 + svelte: 4.2.8 + svelte-preprocess: 5.1.2(postcss@8.4.32)(svelte@4.2.8)(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - '@babel/core' - coffeescript @@ -5770,11 +5796,11 @@ packages: - sugarss dev: true - /svelte-eslint-parser@0.31.0(svelte@4.2.7): - resolution: {integrity: sha512-/31RpBf/e3YjoFphjsyo3JRyN1r4UalGAGafXrZ6EJK4h4COOO0rbfBoen5byGsXnIJKsrlC1lkEd2Vzpq2IDg==} + /svelte-eslint-parser@0.33.1(svelte@4.2.8): + resolution: {integrity: sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: - svelte: ^3.37.0 || ^4.0.0-0 + svelte: ^3.37.0 || ^4.0.0 peerDependenciesMeta: svelte: optional: true @@ -5782,87 +5808,39 @@ packages: eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - postcss: 8.4.31 - postcss-scss: 4.0.6(postcss@8.4.31) - svelte: 4.2.7 + postcss: 8.4.32 + postcss-scss: 4.0.9(postcss@8.4.32) + svelte: 4.2.8 dev: true - /svelte-hmr@0.15.3(svelte@4.2.7): + /svelte-hmr@0.15.3(svelte@4.2.8): resolution: {integrity: sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==} engines: {node: ^12.20 || ^14.13.1 || >= 16} peerDependencies: svelte: ^3.19.0 || ^4.0.0 dependencies: - svelte: 4.2.7 - dev: false + svelte: 4.2.8 + dev: true - /svelte-local-storage-store@0.6.4(svelte@4.2.7): + /svelte-local-storage-store@0.6.4(svelte@4.2.8): resolution: {integrity: sha512-45WoY2vSGPQM1sIQJ9jTkPPj20hYeqm+af6mUGRFSPP5WglZf36YYoZqwmZZ8Dt/2SU8lem+BTA8/Z/8TkqNLg==} engines: {node: '>=0.14'} peerDependencies: svelte: ^3.48.0 || >4.0.0 dependencies: - svelte: 4.2.7 + svelte: 4.2.8 dev: true - /svelte-parse-markup@0.1.2(svelte@4.2.7): + /svelte-parse-markup@0.1.2(svelte@4.2.8): resolution: {integrity: sha512-DycY7DJr7VqofiJ63ut1/NEG92HrWWL56VWITn/cJCu+LlZhMoBkBXT4opUitPEEwbq1nMQbv4vTKUfbOqIW1g==} peerDependencies: svelte: ^3.0.0 || ^4.0.0 dependencies: - svelte: 4.2.7 + svelte: 4.2.8 dev: false - /svelte-preprocess@5.0.4(postcss@8.4.31)(svelte@4.2.7)(typescript@5.0.4): - resolution: {integrity: sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==} - engines: {node: '>= 14.10.0'} - requiresBuild: true - peerDependencies: - '@babel/core': ^7.10.2 - coffeescript: ^2.5.1 - less: ^3.11.3 || ^4.0.0 - postcss: ^7 || ^8 - postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 - pug: ^3.0.0 - sass: ^1.26.8 - stylus: ^0.55.0 - sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0 - svelte: ^3.23.0 || ^4.0.0-next.0 || ^4.0.0 - typescript: '>=3.9.5 || ^4.0.0 || ^5.0.0' - peerDependenciesMeta: - '@babel/core': - optional: true - coffeescript: - optional: true - less: - optional: true - postcss: - optional: true - postcss-load-config: - optional: true - pug: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - typescript: - optional: true - dependencies: - '@types/pug': 2.0.6 - detect-indent: 6.1.0 - magic-string: 0.27.0 - postcss: 8.4.31 - sorcery: 0.11.0 - strip-indent: 3.0.0 - svelte: 4.2.7 - typescript: 5.0.4 - dev: true - - /svelte-preprocess@5.1.1(postcss@8.4.31)(svelte@4.2.7)(typescript@4.9.4): - resolution: {integrity: sha512-p/Dp4hmrBW5mrCCq29lEMFpIJT2FZsRlouxEc5qpbOmXRbaFs7clLs8oKPwD3xCFyZfv1bIhvOzpQkhMEVQdMw==} + /svelte-preprocess@5.1.2(postcss@8.4.32)(svelte@4.2.8)(typescript@5.3.3): + resolution: {integrity: sha512-XF0aliMAcYnP4hLETvB6HRAMnaL09ASYT1Z2I1Gwu0nz6xbdg/dSgAEthtFZJA4AKrNhFDFdmUDO+H9d/6xg5g==} engines: {node: '>= 14.10.0'} requiresBuild: true peerDependencies: @@ -5870,7 +5848,7 @@ packages: coffeescript: ^2.5.1 less: ^3.11.3 || ^4.0.0 postcss: ^7 || ^8 - postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 + postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 pug: ^3.0.0 sass: ^1.26.8 stylus: ^0.55.0 @@ -5899,84 +5877,48 @@ packages: typescript: optional: true dependencies: - '@types/pug': 2.0.6 + '@types/pug': 2.0.10 detect-indent: 6.1.0 magic-string: 0.27.0 - postcss: 8.4.31 + postcss: 8.4.32 sorcery: 0.11.0 strip-indent: 3.0.0 - svelte: 4.2.7 - typescript: 4.9.4 + svelte: 4.2.8 + typescript: 5.3.3 dev: true - /svelte2tsx@0.6.19(svelte@4.2.7)(typescript@4.9.4): - resolution: {integrity: sha512-h3b5OtcO8zyVL/RiB2zsDwCopeo/UH+887uyhgb2mjnewOFwiTxu+4IGuVwrrlyuh2onM2ktfUemNrNmQwXONQ==} + /svelte2tsx@0.6.27(svelte@4.2.8)(typescript@5.3.3): + resolution: {integrity: sha512-E1uPW1o6VsbRz+nUk3fznZ2lSmCITAJoNu8AYefWSvIwE2pSB01i5sId4RMbWNzfcwCQl1DcgGShCPcldl4rvg==} peerDependencies: - svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 + svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 typescript: ^4.9.4 || ^5.0.0 dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 - svelte: 4.2.7 - typescript: 4.9.4 + svelte: 4.2.8 + typescript: 5.3.3 dev: false - /svelte@4.2.7: - resolution: {integrity: sha512-UExR1KS7raTdycsUrKLtStayu4hpdV3VZQgM0akX8XbXgLBlosdE/Sf3crOgyh9xIjqSYB3UEBuUlIQKRQX2hg==} + /svelte@4.2.8: + resolution: {integrity: sha512-hU6dh1MPl8gh6klQZwK/n73GiAHiR95IkFsesLPbMeEZi36ydaXL/ZAb4g9sayT0MXzpxyZjR28yderJHxcmYA==} engines: {node: '>=16'} dependencies: '@ampproject/remapping': 2.2.1 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.19 - acorn: 8.10.0 + '@jridgewell/trace-mapping': 0.3.20 + acorn: 8.11.2 aria-query: 5.3.0 axobject-query: 3.2.1 - code-red: 1.0.3 + code-red: 1.0.4 css-tree: 2.3.1 estree-walker: 3.0.3 - is-reference: 3.0.1 + is-reference: 3.0.2 locate-character: 3.0.0 magic-string: 0.30.5 periscopic: 3.1.0 - /tar-fs@2.1.1: - resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 2.2.0 - dev: false - - /tar-fs@3.0.4: - resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==} - dependencies: - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 3.1.6 - dev: false - - /tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - dev: false - - /tar-stream@3.1.6: - resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} - dependencies: - b4a: 1.6.4 - fast-fifo: 1.3.2 - streamx: 2.15.1 - dev: false - - /tar@6.1.15: - resolution: {integrity: sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==} + /tar@6.2.0: + resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} engines: {node: '>=10'} dependencies: chownr: 2.0.0 @@ -6024,8 +5966,8 @@ packages: globalyzer: 0.1.0 globrex: 0.1.2 - /tinybench@2.5.0: - resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} + /tinybench@2.5.1: + resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==} dev: true /tinydate@1.3.0: @@ -6033,13 +5975,13 @@ packages: engines: {node: '>=4'} dev: true - /tinypool@0.7.0: - resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + /tinypool@0.8.1: + resolution: {integrity: sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==} engines: {node: '>=14.0.0'} dev: true - /tinyspy@2.1.1: - resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} + /tinyspy@2.2.0: + resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==} engines: {node: '>=14.0.0'} dev: true @@ -6075,38 +6017,20 @@ packages: engines: {node: '>=8'} dev: true - /trouter@3.2.1: - resolution: {integrity: sha512-oY3CmIiEYOe1YMEzh++I67lrNOUldtCeuLL0vRPydvQLHZpSJ03B5dgDFlpFsiriMq6e//NDjjopjUzXOztHow==} + /trouter@4.0.0: + resolution: {integrity: sha512-bwwr76BThfiVwAFZqks5cJ+VoKNM3/2Yg1ZwJslkdmAUQ6S0UNoCoGYFDxdw+u1skfexggdmD2p35kW5Td4Cug==} engines: {node: '>=6'} dependencies: - regexparam: 1.3.0 - dev: true - - /ts-api-utils@1.0.1(typescript@4.9.4): - resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} - engines: {node: '>=16.13.0'} - peerDependencies: - typescript: '>=4.2.0' - dependencies: - typescript: 4.9.4 - dev: true - - /ts-api-utils@1.0.2(typescript@5.0.4): - resolution: {integrity: sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==} - engines: {node: '>=16.13.0'} - peerDependencies: - typescript: '>=4.2.0' - dependencies: - typescript: 5.0.4 + regexparam: 3.0.0 dev: true - /ts-api-utils@1.0.3(typescript@4.9.4): + /ts-api-utils@1.0.3(typescript@5.3.3): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 4.9.4 + typescript: 5.3.3 dev: true /ts-interface-checker@0.1.13: @@ -6120,12 +6044,12 @@ packages: code-block-writer: 12.0.0 dev: false - /tslib@2.6.1: - resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: false - /tty-table@4.2.1: - resolution: {integrity: sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==} + /tty-table@4.2.3: + resolution: {integrity: sha512-Fs15mu0vGzCrj8fmJNP7Ynxt5J7praPXqFN0leZeZBXJwkMxv9cb2D454k1ltrtUSJbZ4yH4e0CynsHLxmUfFA==} engines: {node: '>=8.0.0'} hasBin: true dependencies: @@ -6138,12 +6062,6 @@ packages: yargs: 17.7.2 dev: true - /tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - dependencies: - safe-buffer: 5.2.1 - dev: false - /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -6180,8 +6098,8 @@ packages: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-typed-array: 1.1.12 dev: true @@ -6189,7 +6107,7 @@ packages: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -6200,7 +6118,7 @@ packages: engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -6209,53 +6127,51 @@ packages: /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 is-typed-array: 1.1.12 dev: true - /typescript@4.9.4: - resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} - engines: {node: '>=4.2.0'} - hasBin: true - /typescript@5.0.4: resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} engines: {node: '>=12.20'} hasBin: true + dev: true + + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true - /ufo@1.3.0: - resolution: {integrity: sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==} + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} dev: true /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 dev: true - /undici@5.26.3: - resolution: {integrity: sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw==} - engines: {node: '>=14.0'} - dependencies: - '@fastify/busboy': 2.0.0 - dev: false + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} dev: true - /update-browserslist-db@1.0.11(browserslist@4.21.10): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + /update-browserslist-db@1.0.13(browserslist@4.22.2): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.21.10 + browserslist: 4.22.2 escalade: 3.1.1 picocolors: 1.0.0 dev: true @@ -6263,7 +6179,7 @@ packages: /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: true /urlpattern-polyfill@8.0.2: @@ -6284,13 +6200,13 @@ packages: sade: 1.8.1 dev: true - /v8-to-istanbul@9.1.0: - resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} + /v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} engines: {node: '>=10.12.0'} dependencies: - '@jridgewell/trace-mapping': 0.3.19 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 + '@jridgewell/trace-mapping': 0.3.20 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 dev: true /validate-npm-package-license@3.0.4: @@ -6300,27 +6216,26 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /vite-imagetools@6.2.4(rollup@3.29.4): - resolution: {integrity: sha512-ZeWDekJPb+N7WvdmyEcyvs9uLjjhjcQt7pO5LZrKcUan0V6+XizLJ/J1h4nSHduAb8+xpzfl7tPyf9rkk3ujBA==} + /vite-imagetools@6.2.7(rollup@4.8.0): + resolution: {integrity: sha512-7rE6xM93kf7OIVUSrQBIP363fSToUHpIwnuxdqHuVU6SdysksQF06g8SBezIsFegZY+OJgW1e3dprcBalEtRTg==} engines: {node: '>=12.0.0'} dependencies: - '@rollup/pluginutils': 5.0.4(rollup@3.29.4) - imagetools-core: 6.0.0 + '@rollup/pluginutils': 5.1.0(rollup@4.8.0) + imagetools-core: 6.0.3 transitivePeerDependencies: - rollup dev: false - /vite-node@0.34.5(@types/node@16.18.6)(lightningcss@1.21.8): - resolution: {integrity: sha512-RNZ+DwbCvDoI5CbCSQSyRyzDTfFvFauvMs6Yq4ObJROKlIKuat1KgSX/Ako5rlDMfVCyMcpMRMTkJBxd6z8YRA==} - engines: {node: '>=v14.18.0'} + /vite-node@1.0.4(@types/node@18.19.3)(lightningcss@1.22.1): + resolution: {integrity: sha512-9xQQtHdsz5Qn8hqbV7UKqkm8YkJhzT/zr41Dmt5N7AlD8hJXw/Z7y0QiD5I8lnTthV9Rvcvi0QW7PI0Fq83ZPg==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4 - mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) + vite: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) transitivePeerDependencies: - '@types/node' - less @@ -6332,12 +6247,12 @@ packages: - terser dev: true - /vite@4.4.9(@types/node@16.18.6)(lightningcss@1.21.8): - resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==} - engines: {node: ^14.18.0 || >=16.0.0} + /vite@5.0.8(@types/node@18.19.3)(lightningcss@1.22.1): + resolution: {integrity: sha512-jYMALd8aeqR3yS9xlHd0OzQJndS9fH5ylVgWdB+pxTwxLKdO1pgC5Dlb398BUxpfaBxa4M9oT7j1g503Gaj5IQ==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': '>= 14' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' lightningcss: ^1.21.0 sass: '*' @@ -6360,41 +6275,42 @@ packages: terser: optional: true dependencies: - '@types/node': 16.18.6 - esbuild: 0.18.20 - lightningcss: 1.21.8 - postcss: 8.4.31 - rollup: 3.29.4 + '@types/node': 18.19.3 + esbuild: 0.19.9 + lightningcss: 1.22.1 + postcss: 8.4.32 + rollup: 4.8.0 optionalDependencies: fsevents: 2.3.3 + dev: true - /vitefu@0.2.4(vite@4.4.9): - resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} + /vitefu@0.2.5(vite@5.0.8): + resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} peerDependencies: - vite: ^3.0.0 || ^4.0.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: vite: optional: true dependencies: - vite: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) - dev: false + vite: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) + dev: true - /vitest@0.34.5(lightningcss@1.21.8)(playwright@1.30.0): - resolution: {integrity: sha512-CPI68mmnr2DThSB3frSuE5RLm9wo5wU4fbDrDwWQQB1CWgq9jQVoQwnQSzYAjdoBOPoH2UtXpOgHVge/uScfZg==} - engines: {node: '>=v14.18.0'} + /vitest@1.0.4(@types/node@18.19.3)(lightningcss@1.22.1): + resolution: {integrity: sha512-s1GQHp/UOeWEo4+aXDOeFBJwFzL6mjycbQwwKWX2QcYfh/7tIerS59hWQ20mxzupTJluA2SdwiBuWwQHH67ckg==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': ^1.0.0 + '@vitest/ui': ^1.0.0 happy-dom: '*' jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true + '@types/node': + optional: true '@vitest/browser': optional: true '@vitest/ui': @@ -6403,37 +6319,28 @@ packages: optional: true jsdom: optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true dependencies: - '@types/chai': 4.3.6 - '@types/chai-subset': 1.3.3 - '@types/node': 16.18.6 - '@vitest/expect': 0.34.5 - '@vitest/runner': 0.34.5 - '@vitest/snapshot': 0.34.5 - '@vitest/spy': 0.34.5 - '@vitest/utils': 0.34.5 - acorn: 8.10.0 - acorn-walk: 8.2.0 + '@types/node': 18.19.3 + '@vitest/expect': 1.0.4 + '@vitest/runner': 1.0.4 + '@vitest/snapshot': 1.0.4 + '@vitest/spy': 1.0.4 + '@vitest/utils': 1.0.4 + acorn-walk: 8.3.1 cac: 6.7.14 - chai: 4.3.8 + chai: 4.3.10 debug: 4.3.4 - local-pkg: 0.4.3 - magic-string: 0.30.3 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.5 pathe: 1.1.1 picocolors: 1.0.0 - playwright: 1.30.0 - std-env: 3.3.3 + std-env: 3.6.0 strip-literal: 1.3.0 - tinybench: 2.5.0 - tinypool: 0.7.0 - vite: 4.4.9(@types/node@16.18.6)(lightningcss@1.21.8) - vite-node: 0.34.5(@types/node@16.18.6)(lightningcss@1.21.8) + tinybench: 2.5.1 + tinypool: 0.8.1 + vite: 5.0.8(@types/node@18.19.3)(lightningcss@1.22.1) + vite-node: 1.0.4(@types/node@18.19.3)(lightningcss@1.22.1) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -6490,12 +6397,12 @@ packages: path-exists: 4.0.0 dev: true - /which-typed-array@1.1.11: - resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 @@ -6536,7 +6443,7 @@ packages: engines: {node: '>=12'} dependencies: mrmime: 1.0.1 - regexparam: 2.0.1 + regexparam: 2.0.2 dev: false /wrap-ansi@6.2.0: @@ -6589,11 +6496,6 @@ packages: decamelize: 1.2.0 dev: true - /yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - dev: true - /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -6616,19 +6518,6 @@ packages: yargs-parser: 18.1.3 dev: true - /yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - dev: true - /yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} diff --git a/sites/kit.svelte.dev/package.json b/sites/kit.svelte.dev/package.json index 4b17d9ac3d2d..de4e0a26a534 100644 --- a/sites/kit.svelte.dev/package.json +++ b/sites/kit.svelte.dev/package.json @@ -18,22 +18,23 @@ "@sveltejs/enhanced-img": "workspace:^", "@sveltejs/kit": "workspace:^", "@sveltejs/site-kit": "6.0.0-next.59", - "@types/d3-geo": "^3.0.4", - "@types/node": "^16.18.6", - "browserslist": "^4.21.10", + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@types/d3-geo": "^3.1.0", + "@types/node": "^18.19.3", + "browserslist": "^4.22.2", "flexsearch": "^0.7.31", - "lightningcss": "^1.21.8", - "marked": "^11.0.0", + "lightningcss": "^1.22.1", + "marked": "^11.1.0", "prettier": "^3.1.1", - "prettier-plugin-svelte": "^3.0.3", + "prettier-plugin-svelte": "^3.1.2", "prism-svelte": "^0.5.0", "prismjs": "^1.29.0", "shiki-twoslash": "^3.1.2", - "svelte": "^4.2.7", + "svelte": "^4.2.8", "tiny-glob": "^0.2.9", "typescript": "5.0.4", - "vite": "^4.4.9", - "vitest": "^0.34.5" + "vite": "^5.0.8", + "vitest": "^1.0.4" }, "type": "module", "dependencies": { diff --git a/sites/kit.svelte.dev/src/routes/+layout.server.js b/sites/kit.svelte.dev/src/routes/+layout.server.js index 8f2a04f03415..274c04f7f124 100644 --- a/sites/kit.svelte.dev/src/routes/+layout.server.js +++ b/sites/kit.svelte.dev/src/routes/+layout.server.js @@ -8,8 +8,8 @@ export const load = async ({ url, fetch }) => { return { nav_title: get_nav_title(url), - nav_links, - banner + nav_links: await nav_links, + banner: await banner }; }; diff --git a/sites/kit.svelte.dev/src/routes/docs/+page.js b/sites/kit.svelte.dev/src/routes/docs/+page.js index ba2ed3ac9607..875f26286eee 100644 --- a/sites/kit.svelte.dev/src/routes/docs/+page.js +++ b/sites/kit.svelte.dev/src/routes/docs/+page.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export function load() { - throw redirect(307, `./docs/introduction`); + redirect(307, `./docs/introduction`); } diff --git a/sites/kit.svelte.dev/src/routes/docs/[slug]/+page.server.js b/sites/kit.svelte.dev/src/routes/docs/[slug]/+page.server.js index 2d06cbb987ee..fb156a880399 100644 --- a/sites/kit.svelte.dev/src/routes/docs/[slug]/+page.server.js +++ b/sites/kit.svelte.dev/src/routes/docs/[slug]/+page.server.js @@ -6,7 +6,7 @@ export const prerender = true; export async function load({ params }) { const processed_page = await get_parsed_docs(await get_docs_data(), params.slug); - if (!processed_page) throw error(404); + if (!processed_page) error(404); return { page: processed_page }; } diff --git a/sites/kit.svelte.dev/src/routes/faq/+page.js b/sites/kit.svelte.dev/src/routes/faq/+page.js index aa05ba684c44..950b7316700e 100644 --- a/sites/kit.svelte.dev/src/routes/faq/+page.js +++ b/sites/kit.svelte.dev/src/routes/faq/+page.js @@ -1,5 +1,5 @@ import { redirect } from '@sveltejs/kit'; export const load = ({}) => { - throw redirect(301, '/docs/faq'); + redirect(301, '/docs/faq'); };