diff options
258 files changed, 2702 insertions, 1439 deletions
diff --git a/.changeset/afraid-apricots-develop.md b/.changeset/afraid-apricots-develop.md new file mode 100644 index 000000000..acf897149 --- /dev/null +++ b/.changeset/afraid-apricots-develop.md @@ -0,0 +1,7 @@ +--- +'astro': minor +--- + +Adds a new variant `sync` for the `astro:config:setup` hook's `command` property. This value is set when calling the command `astro sync`. + +If your integration previously relied on knowing how many variants existed for the `command` property, you must update your logic to account for this new option. diff --git a/.changeset/blue-pens-divide.md b/.changeset/blue-pens-divide.md new file mode 100644 index 000000000..a295fe7b1 --- /dev/null +++ b/.changeset/blue-pens-divide.md @@ -0,0 +1,22 @@ +--- +'astro': patch +--- + +Fixes a bug in the logic of `Astro.rewrite()` which led to the value for `base`, if configured, being automatically prepended to the rewrite URL passed. This was unintended behavior and has been corrected, and Astro now processes the URLs exactly as passed. + +If you use the `rewrite()` function on a project that has `base` configured, you must now prepend the base to your existing rewrite URL: + +```js +// astro.config.mjs +export default defineConfig({ + base: '/blog' +}) +``` + +```diff +// src/middleware.js +export function onRequest(ctx, next) { +- return ctx.rewrite("/about") ++ return ctx.rewrite("/blog/about") +} +``` diff --git a/.changeset/clever-emus-roll.md b/.changeset/clever-emus-roll.md new file mode 100644 index 000000000..5b9b2ee69 --- /dev/null +++ b/.changeset/clever-emus-roll.md @@ -0,0 +1,11 @@ +--- +'astro': minor +--- + +Adds a new, optional property `timeout` for the `client:idle` directive. + +This value allows you to specify a maximum time to wait, in milliseconds, before hydrating a UI framework component, even if the page is not yet done with its initial load. This means you can delay hydration for lower-priority UI elements with more control to ensure your element is interactive within a specified time frame. + +```astro +<ShowHideButton client:idle={{timeout: 500}} /> +``` diff --git a/.changeset/eight-balloons-cover.md b/.changeset/eight-balloons-cover.md new file mode 100644 index 000000000..ea6364668 --- /dev/null +++ b/.changeset/eight-balloons-cover.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Uses `magicast` to update the config for `astro add` diff --git a/.changeset/fair-rats-fail.md b/.changeset/fair-rats-fail.md deleted file mode 100644 index b93bc8a2b..000000000 --- a/.changeset/fair-rats-fail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Deprecates the Squoosh image service, to be removed in Astro 5.0. We recommend migrating to the default Sharp service. diff --git a/.changeset/four-beans-remember.md b/.changeset/four-beans-remember.md new file mode 100644 index 000000000..cdef7197d --- /dev/null +++ b/.changeset/four-beans-remember.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Replaces `execa` with `tinyexec` internally diff --git a/.changeset/healthy-boxes-poke.md b/.changeset/healthy-boxes-poke.md new file mode 100644 index 000000000..d4c1e4302 --- /dev/null +++ b/.changeset/healthy-boxes-poke.md @@ -0,0 +1,14 @@ +--- +'@astrojs/db': minor +--- + +Adds support for connecting Astro DB to any remote LibSQL server. This allows Astro DB to be used with self-hosting and air-gapped deployments. + +To connect Astro DB to a remote LibSQL server instead of Studio, set the following environment variables: + +- `ASTRO_DB_REMOTE_URL`: the connection URL to your LibSQL server +- `ASTRO_DB_APP_TOKEN`: the auth token to your LibSQL server + +Details of the LibSQL connection can be configured using the connection URL. For example, `memory:?syncUrl=libsql%3A%2F%2Fdb-server.example.com` would create an in-memory embedded replica for the LibSQL DB on `libsql://db-server.example.com`. + +For more details, please visit [the Astro DB documentation](https://docs.astro.build/en/guides/astro-db/#libsql) diff --git a/.changeset/lazy-feet-join.md b/.changeset/lazy-feet-join.md new file mode 100644 index 000000000..e2b0a4077 --- /dev/null +++ b/.changeset/lazy-feet-join.md @@ -0,0 +1,32 @@ +--- +'astro': minor +--- + +Adds a new option `fallbackType` to `i18n.routing` configuration that allows you to control how fallback pages are handled. + +When `i18n.fallback` is configured, this new routing option controls whether to [redirect](https://docs.astro.build/en/guides/routing/#redirects) to the fallback page, or to [rewrite](https://docs.astro.build/en/guides/routing/#rewrites) the fallback page's content in place. + +The `"redirect"` option is the default value and matches the current behavior of the existing fallback system. + +The option `"rewrite"` uses the new [rewriting system](https://docs.astro.build/en/guides/routing/#rewrites) to create fallback pages that render content on the original, requested URL without a browser refresh. + +For example, the following configuration will generate a page `/fr/index.html` that will contain the same HTML rendered by the page `/en/index.html` when `src/pages/fr/index.astro` does not exist. + +```js +// astro.config.mjs +export default defineConfig({ + i18n: { + locals: ["en", "fr"], + defaultLocale: "en", + routing: { + prefixDefaultLocale: true, + fallbackType: "rewrite" + }, + fallback: { + fr: "en" + }, + } +}) +``` + + diff --git a/.changeset/long-months-burn.md b/.changeset/long-months-burn.md deleted file mode 100644 index 4b11c58a1..000000000 --- a/.changeset/long-months-burn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Changes messages logged when using unsupported, deprecated, or experimental adapter features for clarity diff --git a/.changeset/mighty-trees-teach.md b/.changeset/mighty-trees-teach.md deleted file mode 100644 index 289a41816..000000000 --- a/.changeset/mighty-trees-teach.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@astrojs/mdx': patch ---- - -Fixes stack trace location when failed to parse an MDX file with frontmatter diff --git a/.changeset/new-monkeys-sit.md b/.changeset/new-monkeys-sit.md new file mode 100644 index 000000000..b147b593f --- /dev/null +++ b/.changeset/new-monkeys-sit.md @@ -0,0 +1,32 @@ +--- +'astro': minor +--- + +Adds a new object `swapFunctions` to expose the necessary utility functions on `astro:transitions/client` that allow you to build custom swap functions to be used with view transitions. + +The example below uses these functions to replace Astro's built-in default `swap` function with one that only swaps the `<main>` part of the page: + +```astro +<script> +import { swapFunctions } from 'astro:transitions/client'; + +document.addEventListener('astro:before-swap', (e) => { e.swap = () => swapMainOnly(e.newDocument) }); + +function swapMainOnly(doc: Document) { + swapFunctions.deselectScripts(doc); + swapFunctions.swapRootAttributes(doc); + swapFunctions.swapHeadElements(doc); + const restoreFocusFunction = swapFunctions.saveFocus(); + const newMain = doc.querySelector('main'); + const oldMain = document.querySelector('main'); + if (newMain && oldMain) { + swapFunctions.swapBodyElement(newMain, oldMain); + } else { + swapFunctions.swapBodyElement(doc.body, document.body); + } + restoreFocusFunction(); +}; +<script> +``` + +See the [view transitions guide](https://docs.astro.build/en/guides/view-transitions/#astrobefore-swap) for more information about hooking into the `astro:before-swap` lifecycle event and adding a custom swap implementation. diff --git a/.changeset/new-pillows-kick.md b/.changeset/new-pillows-kick.md deleted file mode 100644 index ccc705d67..000000000 --- a/.changeset/new-pillows-kick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Prints prerender dynamic value usage warning only if it's used diff --git a/.changeset/odd-donuts-impress.md b/.changeset/odd-donuts-impress.md deleted file mode 100644 index 7dd8d6b1b..000000000 --- a/.changeset/odd-donuts-impress.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fixes the path returned by `injectTypes` diff --git a/.changeset/smart-comics-doubt.md b/.changeset/smart-comics-doubt.md deleted file mode 100644 index 0582ebd91..000000000 --- a/.changeset/smart-comics-doubt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'create-astro': patch ---- - -Fixes initial git commit when initializing git diff --git a/.changeset/smooth-melons-cough.md b/.changeset/smooth-melons-cough.md deleted file mode 100644 index 0a4a3ea9d..000000000 --- a/.changeset/smooth-melons-cough.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@astrojs/vercel': patch ---- - -Prevent race condition with Node 18 - -Using Node 18 there can be a race condition where polyfill for the `crypto` global is not applied in time. This change ensures the polyfills run first. diff --git a/.changeset/spicy-houses-fry.md b/.changeset/spicy-houses-fry.md deleted file mode 100644 index 41f376a35..000000000 --- a/.changeset/spicy-houses-fry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Simplifies path operations of `astro sync` diff --git a/.changeset/tiny-lamps-lick.md b/.changeset/tiny-lamps-lick.md deleted file mode 100644 index 865994afa..000000000 --- a/.changeset/tiny-lamps-lick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fixes an error thrown by `astro sync` when an `astro:env` virtual module is imported inside the Content Collections config diff --git a/.changeset/weak-dancers-beam.md b/.changeset/weak-dancers-beam.md deleted file mode 100644 index 6d4667815..000000000 --- a/.changeset/weak-dancers-beam.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -'@astrojs/vercel': minor ---- - -Deprecates the `functionPerRoute` option - -This option is now deprecated, and will be removed entirely in Astro v5.0. We suggest removing this option from your configuration as soon as you are able to: - -```diff -import { defineConfig } from 'astro/config'; -import vercel from '@astrojs/vercel/serverless'; - -export default defineConfig({ - // ... - output: 'server', - adapter: vercel({ -- functionPerRoute: true, - }), -}); -``` diff --git a/.changeset/weak-masks-do.md b/.changeset/weak-masks-do.md deleted file mode 100644 index 96aa4a1db..000000000 --- a/.changeset/weak-masks-do.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'astro': patch -'@astrojs/db': patch ---- - -Disables the WebSocket server when creating a Vite server for loading config files diff --git a/.github/workflows/dispatch-event.yml b/.github/workflows/dispatch-event.yml new file mode 100644 index 000000000..5283fab4e --- /dev/null +++ b/.github/workflows/dispatch-event.yml @@ -0,0 +1,61 @@ +name: Dispatch event + +on: + workflow_dispatch: + push: + branches: + - main + tags: + - '!**' + +permissions: + contents: read + actions: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + ASTRO_ADAPTERS_REPO: withastro/adapters + ASTRO_STARLIGHT_REPO: withastro/starlight + ASTRO_PUSH_MAIN_EVENT: astro-push-main-event + +jobs: + repository-dispatch: + name: Repository dispatch + runs-on: ubuntu-latest + steps: + - name: Dispatch event on push - adapters + if: ${{ github.event_name == 'push' }} + uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3 + with: + token: ${{ secrets.ASTRO_REPOSITORY_DISPATCH }} + repository: ${{ env.ASTRO_ADAPTERS_REPO }} + event-type: ${{ env.ASTRO_PUSH_MAIN_EVENT }} + client-payload: '{"event": ${{ toJson(github.event) }}}' + - name: Dispatch event on push - starlight + if: ${{ github.event_name == 'push' }} + uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3 + with: + token: ${{ secrets.ASTRO_REPOSITORY_DISPATCH }} + repository: ${{ env.ASTRO_STARLIGHT_REPO }} + event-type: ${{ env.ASTRO_PUSH_MAIN_EVENT }} + client-payload: '{"event": ${{ toJson(github.event) }}}' + # For testing only, the payload is mocked + - name: Dispatch event on workflow dispatch - adapters + if: ${{ github.event_name == 'workflow_dispatch' }} + uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3 + with: + token: ${{ secrets.ASTRO_REPOSITORY_DISPATCH }} + repository: ${{ env.ASTRO_ADAPTERS_REPO }} + event-type: ${{ env.ASTRO_PUSH_MAIN_EVENT }} + client-payload: '{"event": {"head_commit": {"id": "${{ env.GITHUB_SHA }}"}}}' + - name: Dispatch event on workflow dispatch - starlight + if: ${{ github.event_name == 'workflow_dispatch' }} + uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3 + with: + token: ${{ secrets.ASTRO_REPOSITORY_DISPATCH }} + repository: ${{ env.ASTRO_STARLIGHT_REPO }} + event-type: ${{ env.ASTRO_PUSH_MAIN_EVENT }} + client-payload: '{"event": {"head_commit": {"id": "${{ env.GITHUB_SHA }}"}}}' diff --git a/.github/workflows/preview-comment.yml b/.github/workflows/preview-comment.yml new file mode 100644 index 000000000..7ed6bdf6f --- /dev/null +++ b/.github/workflows/preview-comment.yml @@ -0,0 +1,19 @@ +name: Add continuous release label + +on: + issue_comment: + types: [created] + +permissions: + pull-requests: write + +jobs: + label: + if: ${{ github.repository_owner == 'withastro' && startsWith(github.event.comment.body, '!preview') }} + runs-on: ubuntu-latest + + steps: + - run: | + gh issue edit ${{ github.event.issue.number }} --add-label "pr: preview" --repo ${{ github.repository }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/preview-release.yml b/.github/workflows/preview-release.yml new file mode 100644 index 000000000..df6a44f48 --- /dev/null +++ b/.github/workflows/preview-release.yml @@ -0,0 +1,60 @@ +name: Preview release + +on: + pull_request: + branches: [main] + types: [opened, synchronize, labeled, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.number }} + cancel-in-progress: true + +permissions: + contents: read + actions: write + +env: + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ secrets.TURBO_TEAM }} + FORCE_COLOR: true + ASTRO_TELEMETRY_DISABLED: true + # 7 GiB by default on GitHub, setting to 6 GiB + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources + NODE_OPTIONS: --max-old-space-size=6144 + +jobs: + preview: + if: | + ${{ github.repository_owner == 'withastro' && github.event.issue.pull_request && contains(github.event.pull_request.labels.*.name, 'pr: preview') }} + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + issues: write + pull-requests: write + name: Publish preview release + timeout-minutes: 5 + steps: + - name: Disable git crlf + run: git config --global core.autocrlf false + + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PNPM + uses: pnpm/action-setup@v3 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 18 + cache: "pnpm" + + - name: Install dependencies + run: pnpm install + + - name: Build Packages + run: pnpm run build + + - name: Publish packages + run: pnpx pkg-pr-new publish --pnpm './packages/*' './packages/integrations/*' diff --git a/.gitignore b/.gitignore index 2783aac56..8e6d78354 100644 --- a/.gitignore +++ b/.gitignore @@ -16,9 +16,6 @@ package-lock.json .eslintcache .pnpm-store -# ignore top-level vscode settings -/.vscode/settings.json - # do not commit .env files or any files that end with `.env` *.env @@ -37,3 +34,8 @@ packages/**/e2e/**/fixtures/**/.astro/ packages/**/e2e/**/fixtures/**/env.d.ts examples/**/.astro/ examples/**/env.d.ts + +# make it easy for people to add project-specific Astro settings that they don't +# want to share with others (see +# https://github.com/withastro/astro/pull/11759#discussion_r1721444711) +*.code-workspace diff --git a/.vscode/extensions.json b/.vscode/extensions.json index d8411afe0..ea69b5c70 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,7 +3,8 @@ "astro-build.astro-vscode", "esbenp.prettier-vscode", "editorconfig.editorconfig", - "dbaeumer.vscode-eslint" + "dbaeumer.vscode-eslint", + "biomejs.biome" ], "unwantedRecommendations": [] } diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..b3e10e7bc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "quickFix.biome": true, + "source.fixAll.biome": true + } +} diff --git a/benchmark/bench/cli-startup.js b/benchmark/bench/cli-startup.js index aa8880554..6f2555499 100644 --- a/benchmark/bench/cli-startup.js +++ b/benchmark/bench/cli-startup.js @@ -1,5 +1,5 @@ import { fileURLToPath } from 'node:url'; -import { execaCommand } from 'execa'; +import { exec } from 'tinyexec'; import { markdownTable } from 'markdown-table'; import { astroBin, calculateStat } from './_util.js'; @@ -14,11 +14,11 @@ export async function run(projectDir, outputFile) { const root = fileURLToPath(projectDir); console.log('Benchmarking `astro --help`...'); - const helpStat = await benchmarkCommand(`node ${astroBin} --help`, root); + const helpStat = await benchmarkCommand('node', [astroBin, '--help'], root); console.log('Done'); - console.log('Benchmarking `astro info`...'); - const infoStat = await benchmarkCommand(`node ${astroBin} info`, root); + console.log('Benchmarking `astro preferences list`...'); + const infoStat = await benchmarkCommand('node', [astroBin, 'preferences', 'list'], root); console.log('Done'); console.log('Result preview:'); @@ -35,16 +35,17 @@ export async function run(projectDir, outputFile) { /** * @param {string} command + * @param {string[]} args * @param {string} root * @returns {Promise<import('./_util.js').Stat>} */ -async function benchmarkCommand(command, root) { +async function benchmarkCommand(command, args, root) { /** @type {number[]} */ const durations = []; for (let i = 0; i < 10; i++) { const start = performance.now(); - await execaCommand(command, { cwd: root }); + await exec(command, args, { nodeOptions: { cwd: root } }); durations.push(performance.now() - start); } diff --git a/benchmark/bench/memory.js b/benchmark/bench/memory.js index 3a437b3fe..f1846204f 100644 --- a/benchmark/bench/memory.js +++ b/benchmark/bench/memory.js @@ -1,4 +1,4 @@ -import { execaCommand } from 'execa'; +import { exec } from 'tinyexec'; import { markdownTable } from 'markdown-table'; import fs from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; @@ -18,11 +18,13 @@ export async function run(projectDir, outputFile) { const outputFilePath = fileURLToPath(outputFile); console.log('Building and benchmarking...'); - await execaCommand(`node --expose-gc --max_old_space_size=10000 ${astroBin} build --silent`, { - cwd: root, - stdio: 'inherit', - env: { - ASTRO_TIMER_PATH: outputFilePath, + await exec('node', ['--expose-gc', '--max_old_space_size=10000', astroBin, 'build'], { + nodeOptions: { + cwd: root, + stdio: 'inherit', + env: { + ASTRO_TIMER_PATH: outputFilePath, + }, }, }); diff --git a/benchmark/bench/render.js b/benchmark/bench/render.js index 20c9abb0f..aee04f2b5 100644 --- a/benchmark/bench/render.js +++ b/benchmark/bench/render.js @@ -1,4 +1,4 @@ -import { execaCommand } from 'execa'; +import { exec } from 'tinyexec'; import { markdownTable } from 'markdown-table'; import fs from 'node:fs/promises'; import http from 'node:http'; @@ -20,15 +20,19 @@ export async function run(projectDir, outputFile) { const root = fileURLToPath(projectDir); console.log('Building...'); - await execaCommand(`${astroBin} build`, { - cwd: root, - stdio: 'inherit', + await exec(astroBin, ['build'], { + nodeOptions: { + cwd: root, + stdio: 'inherit', + }, }); console.log('Previewing...'); - const previewProcess = execaCommand(`${astroBin} preview --port ${port}`, { - cwd: root, - stdio: 'inherit', + const previewProcess = exec(astroBin, ['preview', '--port', port], { + nodeOptions: { + cwd: root, + stdio: 'inherit', + }, }); console.log('Waiting for server ready...'); diff --git a/benchmark/bench/server-stress.js b/benchmark/bench/server-stress.js index ca165e239..18b31c71c 100644 --- a/benchmark/bench/server-stress.js +++ b/benchmark/bench/server-stress.js @@ -1,5 +1,5 @@ import autocannon from 'autocannon'; -import { execaCommand } from 'execa'; +import { exec } from 'tinyexec'; import { markdownTable } from 'markdown-table'; import fs from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; @@ -19,9 +19,11 @@ export async function run(projectDir, outputFile) { const root = fileURLToPath(projectDir); console.log('Building...'); - await execaCommand(`${astroBin} build`, { - cwd: root, - stdio: 'inherit', + await exec(astroBin, ['build'], { + nodeOptions: { + cwd: root, + stdio: 'inherit', + }, }); console.log('Previewing...'); diff --git a/benchmark/package.json b/benchmark/package.json index d56a6d1b0..60c8621d2 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -12,11 +12,11 @@ "@benchmark/timer": "workspace:*", "astro": "workspace:*", "autocannon": "^7.15.0", - "execa": "^8.0.1", "markdown-table": "^3.0.3", "mri": "^1.2.0", "port-authority": "^2.0.1", "pretty-bytes": "^6.1.1", - "sharp": "^0.33.3" + "sharp": "^0.33.3", + "tinyexec": "^0.3.0" } } diff --git a/benchmark/packages/timer/package.json b/benchmark/packages/timer/package.json index a4a3b8df1..7e3e2065b 100644 --- a/benchmark/packages/timer/package.json +++ b/benchmark/packages/timer/package.json @@ -29,7 +29,7 @@ "astro": "workspace:*" }, "devDependencies": { - "@types/server-destroy": "^1.0.3", + "@types/server-destroy": "^1.0.4", "astro": "workspace:*", "astro-scripts": "workspace:*" } diff --git a/biome.json b/biome.json index 20653e941..33f9070b9 100644 --- a/biome.json +++ b/biome.json @@ -31,7 +31,8 @@ "rules": { "recommended": false, "style": { - "useNodejsImportProtocol": "error" + "useNodejsImportProtocol": "error", + "useImportType": "error" } } }, diff --git a/examples/container-with-vitest/package.json b/examples/container-with-vitest/package.json index d3bfa492e..3c0bfef50 100644 --- a/examples/container-with-vitest/package.json +++ b/examples/container-with-vitest/package.json @@ -19,7 +19,7 @@ "vitest": "^2.0.5" }, "devDependencies": { - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0" } } diff --git a/examples/framework-multiple/package.json b/examples/framework-multiple/package.json index d8401e1ea..61c2fec76 100644 --- a/examples/framework-multiple/package.json +++ b/examples/framework-multiple/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "@astrojs/preact": "^3.5.1", + "@astrojs/preact": "^3.5.2", "@astrojs/react": "^3.6.2", "@astrojs/solid-js": "^4.4.1", "@astrojs/svelte": "^6.0.0-alpha.0", @@ -22,8 +22,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/examples/framework-preact/package.json b/examples/framework-preact/package.json index 3378f2176..e345e7d72 100644 --- a/examples/framework-preact/package.json +++ b/examples/framework-preact/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "@astrojs/preact": "^3.5.1", + "@astrojs/preact": "^3.5.2", "@preact/signals": "^1.3.0", "astro": "^5.0.0-alpha.1", "preact": "^10.23.2" diff --git a/examples/framework-react/package.json b/examples/framework-react/package.json index 2169c8d1b..c8a80cbdc 100644 --- a/examples/framework-react/package.json +++ b/examples/framework-react/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@astrojs/react": "^3.6.2", - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "astro": "^5.0.0-alpha.1", "react": "^18.3.1", diff --git a/examples/server-islands/package.json b/examples/server-islands/package.json index 72b53fda8..7413e3bc0 100644 --- a/examples/server-islands/package.json +++ b/examples/server-islands/package.json @@ -15,7 +15,7 @@ "@astrojs/tailwind": "^6.0.0-alpha.0", "@fortawesome/fontawesome-free": "^6.6.0", "@tailwindcss/forms": "^0.5.7", - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "astro": "^5.0.0-alpha.1", "postcss": "^8.4.41", diff --git a/examples/with-nanostores/package.json b/examples/with-nanostores/package.json index 801e23b91..078e9b4a2 100644 --- a/examples/with-nanostores/package.json +++ b/examples/with-nanostores/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "@astrojs/preact": "^3.5.1", + "@astrojs/preact": "^3.5.2", "@nanostores/preact": "^0.5.2", "astro": "^5.0.0-alpha.1", "nanostores": "^0.11.2", diff --git a/package.json b/package.json index bec7377aa..a5cfe218c 100644 --- a/package.json +++ b/package.json @@ -58,16 +58,16 @@ "@changesets/cli": "^2.27.7", "@types/node": "^18.17.8", "esbuild": "^0.21.5", - "eslint": "^9.9.0", + "eslint": "^9.9.1", "eslint-plugin-no-only-tests": "^3.3.0", "eslint-plugin-regexp": "^2.6.0", "globby": "^14.0.2", "only-allow": "^1.2.1", "prettier": "^3.3.3", "prettier-plugin-astro": "^0.14.1", - "turbo": "^2.0.14", + "turbo": "^2.1.0", "typescript": "~5.5.4", - "typescript-eslint": "^8.1.0" + "typescript-eslint": "^8.3.0" }, "pnpm": { "peerDependencyRules": { diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index cbd3aedc0..3b6c119e8 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -53,7 +53,6 @@ </script> ``` - - [#11788](https://github.com/withastro/astro/pull/11788) [`7c0ccfc`](https://github.com/withastro/astro/commit/7c0ccfc26947b178584e3476584bcaa490c6ba86) Thanks [@ematipico](https://github.com/ematipico)! - Updates the default value of `security.checkOrigin` to `true`, which enables Cross-Site Request Forgery (CSRF) protection by default for pages rendered on demand. If you had previously configured `security.checkOrigin: true`, you no longer need this set in your Astro config. This is now the default and it is safe to remove. @@ -109,6 +108,42 @@ If you are using this service, and cannot migrate to the base Sharp image service, a third-party extraction of the previous service is available here: https://github.com/Princesseuh/astro-image-service-squoosh +## 4.14.6 + +### Patch Changes + +- [#11847](https://github.com/withastro/astro/pull/11847) [`45b599c`](https://github.com/withastro/astro/commit/45b599c4d40ded6a3e03881181b441ae494cbfcf) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes a case where Vite would be imported by the SSR runtime, causing bundling errors and bloat. + +- [#11822](https://github.com/withastro/astro/pull/11822) [`6fcaab8`](https://github.com/withastro/astro/commit/6fcaab84de1044ff4d186b2dfa5831964460062d) Thanks [@bluwy](https://github.com/bluwy)! - Marks internal `vite-plugin-fileurl` plugin with `enforce: 'pre'` + +- [#11713](https://github.com/withastro/astro/pull/11713) [`497324c`](https://github.com/withastro/astro/commit/497324c4e87538dc1dc13aea3ced9bd3642d9ba6) Thanks [@voidfill](https://github.com/voidfill)! - Prevents prefetching of the same urls with different hashes. + +- [#11814](https://github.com/withastro/astro/pull/11814) [`2bb72c6`](https://github.com/withastro/astro/commit/2bb72c63969f8f21dd279fa927c32f192ff79a3f) Thanks [@eduardocereto](https://github.com/eduardocereto)! - Updates the documentation for experimental Content Layer API with a corrected code example + +- [#11842](https://github.com/withastro/astro/pull/11842) [`1ffaae0`](https://github.com/withastro/astro/commit/1ffaae04cf790390f730bf900b9722b99642adc1) Thanks [@stephan281094](https://github.com/stephan281094)! - Fixes a typo in the `MissingImageDimension` error message + +- [#11828](https://github.com/withastro/astro/pull/11828) [`20d47aa`](https://github.com/withastro/astro/commit/20d47aa85a3a0d7ac3390f749715d92de830cf3e) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Improves error message when invalid data is returned by an Action. + +## 4.14.5 + +### Patch Changes + +- [#11809](https://github.com/withastro/astro/pull/11809) [`62e97a2`](https://github.com/withastro/astro/commit/62e97a20f72bacb017c633ddcb776abc89167660) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fixes usage of `.transform()`, `.refine()`, `.passthrough()`, and other effects on Action form inputs. + +- [#11812](https://github.com/withastro/astro/pull/11812) [`260c4be`](https://github.com/withastro/astro/commit/260c4be050f91353bc5ba6af073e7bc17429d552) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Exposes `ActionAPIContext` type from the `astro:actions` module. + +- [#11813](https://github.com/withastro/astro/pull/11813) [`3f7630a`](https://github.com/withastro/astro/commit/3f7630afd697809b1d4fbac6edd18153983c70ac) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fixes unexpected `undefined` value when calling an action from the client without a return value. + +## 4.14.4 + +### Patch Changes + +- [#11794](https://github.com/withastro/astro/pull/11794) [`3691a62`](https://github.com/withastro/astro/commit/3691a626fb67d617e5f8bd057443cd2ff6caa054) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fixes unexpected warning log when using Actions on "hybrid" rendered projects. + +- [#11801](https://github.com/withastro/astro/pull/11801) [`9f943c1`](https://github.com/withastro/astro/commit/9f943c1344671b569a0d1ddba683b3cca0068adc) Thanks [@delucis](https://github.com/delucis)! - Fixes a bug where the `filePath` property was not available on content collection entries when using the content layer `file()` loader with a JSON file that contained an object instead of an array. This was breaking use of the `image()` schema utility among other things. + +## 4.14.3 + ### Patch Changes - [#11780](https://github.com/withastro/astro/pull/11780) [`c6622ad`](https://github.com/withastro/astro/commit/c6622adaeb405e961b12c91f0e5d02c7333d01cf) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Deprecates the Squoosh image service, to be removed in Astro 5.0. We recommend migrating to the default Sharp service. @@ -127,6 +162,16 @@ - [#11774](https://github.com/withastro/astro/pull/11774) [`c6400ab`](https://github.com/withastro/astro/commit/c6400ab99c5e5f4477bc6ef7e801b7869b0aa9ab) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Fixes the path returned by `injectTypes` +- [#11790](https://github.com/withastro/astro/pull/11790) [`41c3fcb`](https://github.com/withastro/astro/commit/41c3fcb6189709450a67ea8f726071d5f3cdc80e) Thanks [@sarah11918](https://github.com/sarah11918)! - Updates the documentation for experimental `astro:env` with a corrected link to the RFC proposal + +- [#11773](https://github.com/withastro/astro/pull/11773) [`86a3391`](https://github.com/withastro/astro/commit/86a33915ff41b23ff6b35bcfb1805fefc0760ca7) Thanks [@ematipico](https://github.com/ematipico)! - Changes messages logged when using unsupported, deprecated, or experimental adapter features for clarity + +- [#11745](https://github.com/withastro/astro/pull/11745) [`89bab1e`](https://github.com/withastro/astro/commit/89bab1e70786123fbe933a9d7a1b80c9334dcc5f) Thanks [@bluwy](https://github.com/bluwy)! - Prints prerender dynamic value usage warning only if it's used + +- [#11774](https://github.com/withastro/astro/pull/11774) [`c6400ab`](https://github.com/withastro/astro/commit/c6400ab99c5e5f4477bc6ef7e801b7869b0aa9ab) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Fixes the path returned by `injectTypes` + +- [#11730](https://github.com/withastro/astro/pull/11730) [`2df49a6`](https://github.com/withastro/astro/commit/2df49a6fb4f6d92fe45f7429430abe63defeacd6) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Simplifies path operations of `astro sync` + - [#11771](https://github.com/withastro/astro/pull/11771) [`49650a4`](https://github.com/withastro/astro/commit/49650a45550af46c70c6cf3f848b7b529103a649) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Fixes an error thrown by `astro sync` when an `astro:env` virtual module is imported inside the Content Collections config - [#11744](https://github.com/withastro/astro/pull/11744) [`b677429`](https://github.com/withastro/astro/commit/b67742961a384c10e5cd04cf5b02d0f014ea7362) Thanks [@bluwy](https://github.com/bluwy)! - Disables the WebSocket server when creating a Vite server for loading config files diff --git a/packages/astro/client.d.ts b/packages/astro/client.d.ts index 8a61150c7..060b25b8f 100644 --- a/packages/astro/client.d.ts +++ b/packages/astro/client.d.ts @@ -145,6 +145,9 @@ declare module 'astro:transitions/client' { import('./dist/virtual-modules/transitions-events.js').TransitionBeforeSwapEvent; export const isTransitionBeforePreparationEvent: EventModule['isTransitionBeforePreparationEvent']; export const isTransitionBeforeSwapEvent: EventModule['isTransitionBeforeSwapEvent']; + type TransitionSwapFunctionModule = + typeof import('./dist/virtual-modules/transitions-swap-functions.js'); + export const swapFunctions: TransitionSwapFunctionModule['swapFunctions']; } declare module 'astro:prefetch' { diff --git a/packages/astro/e2e/actions-blog.test.js b/packages/astro/e2e/actions-blog.test.js index e3a8c7cf8..d9c1bc1df 100644 --- a/packages/astro/e2e/actions-blog.test.js +++ b/packages/astro/e2e/actions-blog.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; -import { testFactory } from './test-utils.js'; +import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/actions-blog/' }); +const test = testFactory(import.meta.url, { root: './fixtures/actions-blog/' }); let devServer; @@ -23,6 +23,7 @@ test.describe('Astro Actions - Blog', () => { await page.goto(astro.resolveUrl('/blog/first-post/')); const likeButton = page.getByLabel('Like'); + await waitForHydrate(page, likeButton); await expect(likeButton, 'like button starts with 10 likes').toContainText('10'); await likeButton.click(); await expect(likeButton, 'like button should increment likes').toContainText('11'); @@ -125,4 +126,13 @@ test.describe('Astro Actions - Blog', () => { await expect(comments).toBeVisible(); await expect(comments).toContainText(body); }); + + test('Logout action redirects', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/blog/first-post/')); + + const logoutButton = page.getByTestId('logout-button'); + await waitForHydrate(page, logoutButton); + await logoutButton.click(); + await expect(page).toHaveURL(astro.resolveUrl('/blog/')); + }); }); diff --git a/packages/astro/e2e/actions-react-19.test.js b/packages/astro/e2e/actions-react-19.test.js index 5ce72a419..3298db1e3 100644 --- a/packages/astro/e2e/actions-react-19.test.js +++ b/packages/astro/e2e/actions-react-19.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; -import { testFactory } from './test-utils.js'; +import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/actions-react-19/' }); +const test = testFactory(import.meta.url, { root: './fixtures/actions-react-19/' }); let devServer; @@ -23,10 +23,12 @@ test.describe('Astro Actions - React 19', () => { await page.goto(astro.resolveUrl('/blog/first-post/')); const likeButton = page.getByLabel('likes-client'); + await waitForHydrate(page, likeButton); + await expect(likeButton).toBeVisible(); await likeButton.click(); await expect(likeButton, 'like button should be disabled when pending').toBeDisabled(); - await expect(likeButton).not.toBeDisabled({ timeout: 5000 }); + await expect(likeButton).not.toBeDisabled(); }); test('Like action - server progressive enhancement', async ({ page, astro }) => { @@ -43,6 +45,8 @@ test.describe('Astro Actions - React 19', () => { await page.goto(astro.resolveUrl('/blog/first-post/')); const likeButton = page.getByLabel('likes-action-client'); + await waitForHydrate(page, likeButton); + await expect(likeButton).toBeVisible(); await likeButton.click(); diff --git a/packages/astro/e2e/astro-component.test.js b/packages/astro/e2e/astro-component.test.js index b77cbffa1..3a3c738b3 100644 --- a/packages/astro/e2e/astro-component.test.js +++ b/packages/astro/e2e/astro-component.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ root: './fixtures/astro-component/' }); +const test = testFactory(import.meta.url, { root: './fixtures/astro-component/' }); let devServer; diff --git a/packages/astro/e2e/astro-envs.test.js b/packages/astro/e2e/astro-envs.test.js index f6f3c5031..60baa65a0 100644 --- a/packages/astro/e2e/astro-envs.test.js +++ b/packages/astro/e2e/astro-envs.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/astro-envs/', devToolbar: { enabled: false, diff --git a/packages/astro/e2e/client-idle-timeout.test.js b/packages/astro/e2e/client-idle-timeout.test.js new file mode 100644 index 000000000..a39870619 --- /dev/null +++ b/packages/astro/e2e/client-idle-timeout.test.js @@ -0,0 +1,33 @@ +import { expect } from '@playwright/test'; +import { testFactory, waitForHydrate } from './test-utils.js'; + +const test = testFactory(import.meta.url, { root: './fixtures/client-idle-timeout/' }); + +let devServer; + +test.beforeAll(async ({ astro }) => { + devServer = await astro.startDevServer(); +}); + +test.afterAll(async () => { + await devServer.stop(); +}); + +test.describe('Client idle timeout', () => { + test('React counter', async ({ astro, page }) => { + await page.goto(astro.resolveUrl('/')); + + const counter = page.locator('#react-counter'); + await expect(counter, 'component is visible').toBeVisible(); + + const count = counter.locator('pre'); + await expect(count, 'initial count is 0').toHaveText('0'); + + await waitForHydrate(page, counter); + + const inc = counter.locator('.increment'); + await inc.click(); + + await expect(count, 'count incremented by 1').toHaveText('1'); + }); +}); diff --git a/packages/astro/e2e/client-only.test.js b/packages/astro/e2e/client-only.test.js index 08c5fb3ac..62a05f8dc 100644 --- a/packages/astro/e2e/client-only.test.js +++ b/packages/astro/e2e/client-only.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ root: './fixtures/client-only/' }); +const test = testFactory(import.meta.url, { root: './fixtures/client-only/' }); let devServer; diff --git a/packages/astro/e2e/content-collections.test.js b/packages/astro/e2e/content-collections.test.js index 63c5077c9..fdb8d5e00 100644 --- a/packages/astro/e2e/content-collections.test.js +++ b/packages/astro/e2e/content-collections.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ root: './fixtures/content-collections/' }); +const test = testFactory(import.meta.url, { root: './fixtures/content-collections/' }); let devServer; diff --git a/packages/astro/e2e/css.test.js b/packages/astro/e2e/css.test.js index fd4de700e..f865969f7 100644 --- a/packages/astro/e2e/css.test.js +++ b/packages/astro/e2e/css.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/css/', devToolbar: { enabled: false, diff --git a/packages/astro/e2e/custom-client-directives.test.js b/packages/astro/e2e/custom-client-directives.test.js index ef9de808a..8f90916f2 100644 --- a/packages/astro/e2e/custom-client-directives.test.js +++ b/packages/astro/e2e/custom-client-directives.test.js @@ -2,7 +2,7 @@ import { expect } from '@playwright/test'; import testAdapter from '../test/test-adapter.js'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/custom-client-directives/', }); diff --git a/packages/astro/e2e/dev-toolbar-audits.test.js b/packages/astro/e2e/dev-toolbar-audits.test.js index 6ef63cc1e..d0c5da847 100644 --- a/packages/astro/e2e/dev-toolbar-audits.test.js +++ b/packages/astro/e2e/dev-toolbar-audits.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/dev-toolbar/', }); diff --git a/packages/astro/e2e/dev-toolbar.test.js b/packages/astro/e2e/dev-toolbar.test.js index ae8b6ef5c..628b3af3a 100644 --- a/packages/astro/e2e/dev-toolbar.test.js +++ b/packages/astro/e2e/dev-toolbar.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/dev-toolbar/', }); diff --git a/packages/astro/e2e/error-cyclic.test.js b/packages/astro/e2e/error-cyclic.test.js index 84f4d1d1d..62b502fab 100644 --- a/packages/astro/e2e/error-cyclic.test.js +++ b/packages/astro/e2e/error-cyclic.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { getErrorOverlayContent, testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/error-cyclic/', }); diff --git a/packages/astro/e2e/error-sass.test.js b/packages/astro/e2e/error-sass.test.js index 11862fb86..05774220e 100644 --- a/packages/astro/e2e/error-sass.test.js +++ b/packages/astro/e2e/error-sass.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { getErrorOverlayContent, testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/error-sass/', }); diff --git a/packages/astro/e2e/errors.test.js b/packages/astro/e2e/errors.test.js index 34cecd816..f64a22b5c 100644 --- a/packages/astro/e2e/errors.test.js +++ b/packages/astro/e2e/errors.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { getErrorOverlayContent, testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/errors/', // Only test the error overlay, don't print to console vite: { diff --git a/packages/astro/e2e/fixtures/actions-blog/package.json b/packages/astro/e2e/fixtures/actions-blog/package.json index 04685b810..545ae2d37 100644 --- a/packages/astro/e2e/fixtures/actions-blog/package.json +++ b/packages/astro/e2e/fixtures/actions-blog/package.json @@ -14,7 +14,7 @@ "@astrojs/db": "workspace:*", "@astrojs/node": "workspace:*", "@astrojs/react": "workspace:*", - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "astro": "workspace:*", "react": "^18.3.1", diff --git a/packages/astro/e2e/fixtures/actions-blog/src/actions/index.ts b/packages/astro/e2e/fixtures/actions-blog/src/actions/index.ts index 0588f626c..7b640be51 100644 --- a/packages/astro/e2e/fixtures/actions-blog/src/actions/index.ts +++ b/packages/astro/e2e/fixtures/actions-blog/src/actions/index.ts @@ -3,11 +3,16 @@ import { ActionError, defineAction, z } from 'astro:actions'; import { getCollection } from 'astro:content'; export const server = { + logout: defineAction({ + handler: async () => { + await new Promise((r) => setTimeout(r, 500)); + }, + }), blog: { like: defineAction({ input: z.object({ postId: z.string() }), handler: async ({ postId }) => { - await new Promise((r) => setTimeout(r, 1000)); + await new Promise((r) => setTimeout(r, 500)); const { likes } = await db .update(Likes) @@ -30,7 +35,7 @@ export const server = { body: z.string().min(10), }), handler: async ({ postId, author, body }) => { - if (!(await getCollection('blog')).find(b => b.id === postId)) { + if (!(await getCollection('blog')).find((b) => b.id === postId)) { throw new ActionError({ code: 'NOT_FOUND', message: 'Post not found', diff --git a/packages/astro/e2e/fixtures/actions-blog/src/components/Logout.tsx b/packages/astro/e2e/fixtures/actions-blog/src/components/Logout.tsx new file mode 100644 index 000000000..737718d91 --- /dev/null +++ b/packages/astro/e2e/fixtures/actions-blog/src/components/Logout.tsx @@ -0,0 +1,16 @@ +import { actions } from 'astro:actions'; +import { navigate } from 'astro:transitions/client'; + +export function Logout() { + return ( + <button + data-testid="logout-button" + onClick={async () => { + const { error } = await actions.logout(); + if (!error) navigate('/blog/'); + }} + > + Logout + </button> + ); +} diff --git a/packages/astro/e2e/fixtures/actions-blog/src/pages/blog/[...slug].astro b/packages/astro/e2e/fixtures/actions-blog/src/pages/blog/[...slug].astro index fe97a8de1..ad4aea521 100644 --- a/packages/astro/e2e/fixtures/actions-blog/src/pages/blog/[...slug].astro +++ b/packages/astro/e2e/fixtures/actions-blog/src/pages/blog/[...slug].astro @@ -1,6 +1,7 @@ --- import { type CollectionEntry, getCollection, getEntry } from 'astro:content'; import BlogPost from '../../layouts/BlogPost.astro'; +import { Logout } from '../../components/Logout'; import { db, eq, Comment, Likes } from 'astro:db'; import { Like } from '../../components/Like'; import { PostComment } from '../../components/PostComment'; @@ -17,14 +18,13 @@ export async function getStaticPaths() { })); } - type Props = CollectionEntry<'blog'>; const post = await getEntry('blog', Astro.params.slug)!; const { Content } = await post.render(); if (Astro.url.searchParams.has('like')) { - await Astro.callAction(actions.blog.like.orThrow, {postId: post.id}); + await Astro.callAction(actions.blog.like.orThrow, { postId: post.id }); } const comment = Astro.getActionResult(actions.blog.comment); @@ -40,6 +40,8 @@ const commentPostIdOverride = Astro.url.searchParams.get('commentPostIdOverride' <BlogPost {...post.data}> <Like postId={post.id} initial={initialLikes?.likes ?? 0} client:load /> + <Logout client:load /> + <form> <input type="hidden" name="like" /> <button type="submit" aria-label="get-request">Like GET request</button> @@ -57,17 +59,17 @@ const commentPostIdOverride = Astro.url.searchParams.get('commentPostIdOverride' /> <form method="POST" data-testid="progressive-fallback" action={actions.blog.comment.queryString}> <input type="hidden" name="postId" value={post.id} /> - <label for="fallback-author"> - Author - </label> - <input id="fallback-author" type="text" name="author" required /> - <label for="fallback-body" class="sr-only"> - Comment - </label> + <label for="fallback-author"> Author </label> + <input id="fallback-author" type="text" name="author" required /> + <label for="fallback-body" class="sr-only"> Comment </label> <textarea id="fallback-body" rows={10} name="body" required></textarea> - {isInputError(comment?.error) && comment.error.fields.body && ( - <p class="error" data-error="body">{comment.error.fields.body.toString()}</p> - )} + { + isInputError(comment?.error) && comment.error.fields.body && ( + <p class="error" data-error="body"> + {comment.error.fields.body.toString()} + </p> + ) + } <button type="submit">Post Comment</button> </form> <div data-testid="server-comments"> diff --git a/packages/astro/e2e/fixtures/client-idle-timeout/astro.config.mjs b/packages/astro/e2e/fixtures/client-idle-timeout/astro.config.mjs new file mode 100644 index 000000000..02dccb978 --- /dev/null +++ b/packages/astro/e2e/fixtures/client-idle-timeout/astro.config.mjs @@ -0,0 +1,9 @@ +import react from '@astrojs/react'; +import { defineConfig } from 'astro/config'; + +// https://astro.build/config +export default defineConfig({ + integrations: [ + react(), + ], +}); diff --git a/packages/astro/e2e/fixtures/client-idle-timeout/package.json b/packages/astro/e2e/fixtures/client-idle-timeout/package.json new file mode 100644 index 000000000..af4c41605 --- /dev/null +++ b/packages/astro/e2e/fixtures/client-idle-timeout/package.json @@ -0,0 +1,13 @@ +{ + "name": "@e2e/client-idle-timeout", + "version": "0.0.0", + "private": true, + "devDependencies": { + "@astrojs/react": "workspace:*", + "astro": "workspace:*" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + } +} diff --git a/packages/astro/e2e/fixtures/client-idle-timeout/src/components/Counter.jsx b/packages/astro/e2e/fixtures/client-idle-timeout/src/components/Counter.jsx new file mode 100644 index 000000000..9d2212b0c --- /dev/null +++ b/packages/astro/e2e/fixtures/client-idle-timeout/src/components/Counter.jsx @@ -0,0 +1,18 @@ +import React, { useState } from 'react'; + +export default function Counter({ children, count: initialCount = 0, id }) { + const [count, setCount] = useState(initialCount); + const add = () => setCount((i) => i + 1); + const subtract = () => setCount((i) => i - 1); + + return ( + <> + <div id={id} className="counter"> + <button className="decrement" onClick={subtract}>-</button> + <pre>{count}</pre> + <button className="increment" onClick={add}>+</button> + </div> + <div className="counter-message">{children}</div> + </> + ); +} diff --git a/packages/astro/e2e/fixtures/client-idle-timeout/src/pages/index.astro b/packages/astro/e2e/fixtures/client-idle-timeout/src/pages/index.astro new file mode 100644 index 000000000..0045ca55c --- /dev/null +++ b/packages/astro/e2e/fixtures/client-idle-timeout/src/pages/index.astro @@ -0,0 +1,16 @@ +--- +import Counter from '../components/Counter.jsx'; +--- + +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + <link rel="icon" type="image/x-icon" href="/favicon.ico" /> + </head> + <body> + <main> + <Counter id="react-counter" client:idle={{timeout: 200}}></Counter> + </main> + </body> +</html> diff --git a/packages/astro/e2e/fixtures/client-only/package.json b/packages/astro/e2e/fixtures/client-only/package.json index 4c9903c7b..d89fe7898 100644 --- a/packages/astro/e2e/fixtures/client-only/package.json +++ b/packages/astro/e2e/fixtures/client-only/package.json @@ -14,8 +14,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/e2e/fixtures/errors/package.json b/packages/astro/e2e/fixtures/errors/package.json index 1d01a376f..ab47d7da8 100644 --- a/packages/astro/e2e/fixtures/errors/package.json +++ b/packages/astro/e2e/fixtures/errors/package.json @@ -13,8 +13,8 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "sass": "^1.77.8", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/e2e/fixtures/multiple-frameworks/package.json b/packages/astro/e2e/fixtures/multiple-frameworks/package.json index 810e503f7..f90d9725d 100644 --- a/packages/astro/e2e/fixtures/multiple-frameworks/package.json +++ b/packages/astro/e2e/fixtures/multiple-frameworks/package.json @@ -16,8 +16,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/e2e/fixtures/nested-in-preact/package.json b/packages/astro/e2e/fixtures/nested-in-preact/package.json index 339cdcbc1..c5f10cd43 100644 --- a/packages/astro/e2e/fixtures/nested-in-preact/package.json +++ b/packages/astro/e2e/fixtures/nested-in-preact/package.json @@ -14,8 +14,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/e2e/fixtures/nested-in-react/package.json b/packages/astro/e2e/fixtures/nested-in-react/package.json index 9573ef266..bac0d1bae 100644 --- a/packages/astro/e2e/fixtures/nested-in-react/package.json +++ b/packages/astro/e2e/fixtures/nested-in-react/package.json @@ -14,8 +14,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/e2e/fixtures/nested-in-solid/package.json b/packages/astro/e2e/fixtures/nested-in-solid/package.json index 6e71432f0..4a2748eb5 100644 --- a/packages/astro/e2e/fixtures/nested-in-solid/package.json +++ b/packages/astro/e2e/fixtures/nested-in-solid/package.json @@ -14,8 +14,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/e2e/fixtures/nested-in-svelte/package.json b/packages/astro/e2e/fixtures/nested-in-svelte/package.json index 1f319d028..a98e441f5 100644 --- a/packages/astro/e2e/fixtures/nested-in-svelte/package.json +++ b/packages/astro/e2e/fixtures/nested-in-svelte/package.json @@ -14,8 +14,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/e2e/fixtures/nested-in-vue/package.json b/packages/astro/e2e/fixtures/nested-in-vue/package.json index bd44589f3..1702f98bf 100644 --- a/packages/astro/e2e/fixtures/nested-in-vue/package.json +++ b/packages/astro/e2e/fixtures/nested-in-vue/package.json @@ -14,8 +14,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/e2e/fixtures/nested-recursive/package.json b/packages/astro/e2e/fixtures/nested-recursive/package.json index ab809a3a3..d35cf0eb5 100644 --- a/packages/astro/e2e/fixtures/nested-recursive/package.json +++ b/packages/astro/e2e/fixtures/nested-recursive/package.json @@ -14,8 +14,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" }, "scripts": { diff --git a/packages/astro/e2e/fixtures/solid-circular/package.json b/packages/astro/e2e/fixtures/solid-circular/package.json index 21a0b66ba..aba997250 100644 --- a/packages/astro/e2e/fixtures/solid-circular/package.json +++ b/packages/astro/e2e/fixtures/solid-circular/package.json @@ -7,6 +7,6 @@ "astro": "workspace:*" }, "devDependencies": { - "solid-js": "^1.8.21" + "solid-js": "^1.8.22" } } diff --git a/packages/astro/e2e/fixtures/solid-circular/src/env.d.ts b/packages/astro/e2e/fixtures/solid-circular/src/env.d.ts deleted file mode 100644 index 8c34fb45e..000000000 --- a/packages/astro/e2e/fixtures/solid-circular/src/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// <reference types="astro/client" />
\ No newline at end of file diff --git a/packages/astro/e2e/fixtures/solid-component/package.json b/packages/astro/e2e/fixtures/solid-component/package.json index 850a41587..86269a915 100644 --- a/packages/astro/e2e/fixtures/solid-component/package.json +++ b/packages/astro/e2e/fixtures/solid-component/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/solid-js": "workspace:*", "astro": "workspace:*", - "solid-js": "^1.8.21" + "solid-js": "^1.8.22" } } diff --git a/packages/astro/e2e/fixtures/solid-recurse/package.json b/packages/astro/e2e/fixtures/solid-recurse/package.json index aa51ebe5d..a7d97b39c 100644 --- a/packages/astro/e2e/fixtures/solid-recurse/package.json +++ b/packages/astro/e2e/fixtures/solid-recurse/package.json @@ -7,6 +7,6 @@ "astro": "workspace:*" }, "devDependencies": { - "solid-js": "^1.8.21" + "solid-js": "^1.8.22" } } diff --git a/packages/astro/e2e/fixtures/svelte-component/package.json b/packages/astro/e2e/fixtures/svelte-component/package.json index e5d238f74..04acc35e7 100644 --- a/packages/astro/e2e/fixtures/svelte-component/package.json +++ b/packages/astro/e2e/fixtures/svelte-component/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/e2e/fixtures/svelte-component/src/env.d.ts b/packages/astro/e2e/fixtures/svelte-component/src/env.d.ts deleted file mode 100644 index 8c34fb45e..000000000 --- a/packages/astro/e2e/fixtures/svelte-component/src/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// <reference types="astro/client" />
\ No newline at end of file diff --git a/packages/astro/e2e/fixtures/view-transitions/package.json b/packages/astro/e2e/fixtures/view-transitions/package.json index b5460ebcd..0a0ad81f2 100644 --- a/packages/astro/e2e/fixtures/view-transitions/package.json +++ b/packages/astro/e2e/fixtures/view-transitions/package.json @@ -10,7 +10,7 @@ "astro": "workspace:*", "react": "^18.3.1", "react-dom": "^18.3.1", - "svelte": "^4.2.18", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/keep-style-one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/keep-style-one.astro index 413a404d7..f71898d81 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/keep-style-one.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/keep-style-one.astro @@ -7,22 +7,22 @@ import Layout from '../components/Layout.astro'; </Layout> <script> - import { deselectScripts, saveFocus, swapBodyElement, swapHeadElements, swapRootAttributes } from '../../node_modules/astro/dist/transitions/swap-functions' + import { swapFunctions } from 'astro:transitions/client'; document.addEventListener('astro:before-swap', (e) => { e.swap = () => keepStyle(e.newDocument) }); function keepStyle(doc: Document) { - deselectScripts(doc); - swapRootAttributes(doc); + swapFunctions.deselectScripts(doc); + swapFunctions.swapRootAttributes(doc); { const dynamicStyle = document.head.querySelector('style:not(:empty)'); - swapHeadElements(doc); + swapFunctions.swapHeadElements(doc); dynamicStyle && document.head.insertAdjacentElement('afterbegin', dynamicStyle); } - const restoreFocusFunction = saveFocus(); - swapBodyElement(doc.body, document.body) + const restoreFocusFunction = swapFunctions.saveFocus(); + swapFunctions.swapBodyElement(doc.body, document.body) restoreFocusFunction(); } </script> diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/keep-theme-one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/keep-theme-one.astro index a4c942d58..18ae0221f 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/keep-theme-one.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/keep-theme-one.astro @@ -6,18 +6,18 @@ import Layout from '../components/Layout.astro'; <a id="click" href="/keep-two">go to next page</a> </Layout> <script> - import { deselectScripts, saveFocus, swapBodyElement, swapHeadElements, swapRootAttributes } from '../../node_modules/astro/dist/transitions/swap-functions' + import { swapFunctions } from 'astro:transitions/client'; function keepTheme(doc:Document) { - deselectScripts(doc); + swapFunctions.deselectScripts(doc); { const theme = document.documentElement.getAttribute('data-theme')!; - swapRootAttributes(doc); + swapFunctions.swapRootAttributes(doc); document.documentElement.setAttribute('data-theme', theme); } - swapHeadElements(doc); - const restoreFocusFunction = saveFocus(); - swapBodyElement(doc.body, document.body) + swapFunctions.swapHeadElements(doc); + const restoreFocusFunction = swapFunctions.saveFocus(); + swapFunctions.swapBodyElement(doc.body, document.body) restoreFocusFunction(); } diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/replace-main-one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/replace-main-one.astro index 1709661e8..c43ce78a9 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/replace-main-one.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/replace-main-one.astro @@ -9,24 +9,24 @@ import Layout from '../components/Layout.astro'; <a id="click" href="/keep-two">go to next page</a> </Layout> <script> - import { deselectScripts, saveFocus, swapBodyElement, swapHeadElements, swapRootAttributes } from "../../node_modules/astro/dist/transitions/swap-functions" + import { swapFunctions } from 'astro:transitions/client'; document.addEventListener('astro:before-swap', (e) => { e.swap = () => replaceMain(e.newDocument) }); function replaceMain(doc:Document){ - deselectScripts(doc); - swapRootAttributes(doc); - swapHeadElements(doc); - const restoreFocusFunction = saveFocus(); + swapFunctions.deselectScripts(doc); + swapFunctions.swapRootAttributes(doc); + swapFunctions.swapHeadElements(doc); + const restoreFocusFunction = swapFunctions.saveFocus(); { const newMain = doc.body.querySelector('main section'); const oldMain = document.body.querySelector('main section'); if (newMain && oldMain) { - swapBodyElement(newMain, oldMain); + swapFunctions.swapBodyElement(newMain, oldMain); } else { - swapBodyElement(doc.body, document.body); + swapFunctions.swapBodyElement(doc.body, document.body); } } restoreFocusFunction(); diff --git a/packages/astro/e2e/hmr.test.js b/packages/astro/e2e/hmr.test.js index 72eaf8375..1f0cda2c4 100644 --- a/packages/astro/e2e/hmr.test.js +++ b/packages/astro/e2e/hmr.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/hmr/', devToolbar: { enabled: false, diff --git a/packages/astro/e2e/hydration-race.test.js b/packages/astro/e2e/hydration-race.test.js index 0ee578243..95469fe73 100644 --- a/packages/astro/e2e/hydration-race.test.js +++ b/packages/astro/e2e/hydration-race.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/hydration-race/', }); diff --git a/packages/astro/e2e/i18n.test.js b/packages/astro/e2e/i18n.test.js index e7d74a551..88d3a0b08 100644 --- a/packages/astro/e2e/i18n.test.js +++ b/packages/astro/e2e/i18n.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/i18n/', devToolbar: { enabled: false, diff --git a/packages/astro/e2e/multiple-frameworks.test.js b/packages/astro/e2e/multiple-frameworks.test.js index 08a2fb648..4b52dfd4c 100644 --- a/packages/astro/e2e/multiple-frameworks.test.js +++ b/packages/astro/e2e/multiple-frameworks.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ root: './fixtures/multiple-frameworks/' }); +const test = testFactory(import.meta.url, { root: './fixtures/multiple-frameworks/' }); let devServer; diff --git a/packages/astro/e2e/namespaced-component.test.js b/packages/astro/e2e/namespaced-component.test.js index 58c00713a..1212e0ce1 100644 --- a/packages/astro/e2e/namespaced-component.test.js +++ b/packages/astro/e2e/namespaced-component.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/namespaced-component/', }); diff --git a/packages/astro/e2e/nested-in-preact.test.js b/packages/astro/e2e/nested-in-preact.test.js index f2bc4d728..2ad62e95f 100644 --- a/packages/astro/e2e/nested-in-preact.test.js +++ b/packages/astro/e2e/nested-in-preact.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/nested-in-preact/' }); +const test = testFactory(import.meta.url, { root: './fixtures/nested-in-preact/' }); let devServer; diff --git a/packages/astro/e2e/nested-in-react.test.js b/packages/astro/e2e/nested-in-react.test.js index db9eeb0dd..7dee69937 100644 --- a/packages/astro/e2e/nested-in-react.test.js +++ b/packages/astro/e2e/nested-in-react.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/nested-in-react/' }); +const test = testFactory(import.meta.url, { root: './fixtures/nested-in-react/' }); let devServer; diff --git a/packages/astro/e2e/nested-in-solid.test.js b/packages/astro/e2e/nested-in-solid.test.js index 0fab17468..2d9deade1 100644 --- a/packages/astro/e2e/nested-in-solid.test.js +++ b/packages/astro/e2e/nested-in-solid.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/nested-in-solid/' }); +const test = testFactory(import.meta.url, { root: './fixtures/nested-in-solid/' }); let devServer; diff --git a/packages/astro/e2e/nested-in-svelte.test.js b/packages/astro/e2e/nested-in-svelte.test.js index 88aa826a8..eeecb0442 100644 --- a/packages/astro/e2e/nested-in-svelte.test.js +++ b/packages/astro/e2e/nested-in-svelte.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/nested-in-svelte/' }); +const test = testFactory(import.meta.url, { root: './fixtures/nested-in-svelte/' }); let devServer; diff --git a/packages/astro/e2e/nested-in-vue.test.js b/packages/astro/e2e/nested-in-vue.test.js index deed309c7..7e25e4747 100644 --- a/packages/astro/e2e/nested-in-vue.test.js +++ b/packages/astro/e2e/nested-in-vue.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/nested-in-vue/' }); +const test = testFactory(import.meta.url, { root: './fixtures/nested-in-vue/' }); let devServer; diff --git a/packages/astro/e2e/nested-recursive.test.js b/packages/astro/e2e/nested-recursive.test.js index 262cd6772..d9f612642 100644 --- a/packages/astro/e2e/nested-recursive.test.js +++ b/packages/astro/e2e/nested-recursive.test.js @@ -3,7 +3,7 @@ import { loadFixture, waitForHydrate } from './test-utils.js'; const test = base.extend({ astro: async ({}, use) => { - const fixture = await loadFixture({ root: './fixtures/nested-recursive/' }); + const fixture = await loadFixture(import.meta.url, { root: './fixtures/nested-recursive/' }); await use(fixture); }, }); diff --git a/packages/astro/e2e/nested-styles.test.js b/packages/astro/e2e/nested-styles.test.js index c482570f0..1a3aeb0e0 100644 --- a/packages/astro/e2e/nested-styles.test.js +++ b/packages/astro/e2e/nested-styles.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/nested-styles/', devToolbar: { enabled: false, diff --git a/packages/astro/e2e/pass-js.test.js b/packages/astro/e2e/pass-js.test.js index 0db9895d1..91e3b5c5e 100644 --- a/packages/astro/e2e/pass-js.test.js +++ b/packages/astro/e2e/pass-js.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/pass-js/', }); diff --git a/packages/astro/e2e/preact-compat-component.test.js b/packages/astro/e2e/preact-compat-component.test.js index e1b603e7f..83831c9e7 100644 --- a/packages/astro/e2e/preact-compat-component.test.js +++ b/packages/astro/e2e/preact-compat-component.test.js @@ -1,6 +1,8 @@ import { prepareTestFactory } from './shared-component-tests.js'; -const { test, createTests } = prepareTestFactory({ root: './fixtures/preact-compat-component/' }); +const { test, createTests } = prepareTestFactory(import.meta.url, { + root: './fixtures/preact-compat-component/', +}); const config = { counterComponentFilePath: './src/components/Counter.jsx', diff --git a/packages/astro/e2e/preact-component.test.js b/packages/astro/e2e/preact-component.test.js index d808b4890..3beb14da3 100644 --- a/packages/astro/e2e/preact-component.test.js +++ b/packages/astro/e2e/preact-component.test.js @@ -1,6 +1,8 @@ import { prepareTestFactory } from './shared-component-tests.js'; -const { test, createTests } = prepareTestFactory({ root: './fixtures/preact-component/' }); +const { test, createTests } = prepareTestFactory(import.meta.url, { + root: './fixtures/preact-component/', +}); const config = { counterComponentFilePath: './src/components/Counter.jsx', diff --git a/packages/astro/e2e/preact-lazy-component.test.js b/packages/astro/e2e/preact-lazy-component.test.js index 585d2d347..ce0e3afec 100644 --- a/packages/astro/e2e/preact-lazy-component.test.js +++ b/packages/astro/e2e/preact-lazy-component.test.js @@ -1,6 +1,8 @@ import { prepareTestFactory } from './shared-component-tests.js'; -const { test, createTests } = prepareTestFactory({ root: './fixtures/preact-lazy-component/' }); +const { test, createTests } = prepareTestFactory(import.meta.url, { + root: './fixtures/preact-lazy-component/', +}); const config = { counterComponentFilePath: './src/components/Counter.jsx', diff --git a/packages/astro/e2e/prefetch.test.js b/packages/astro/e2e/prefetch.test.js index 84ead590c..2da44189a 100644 --- a/packages/astro/e2e/prefetch.test.js +++ b/packages/astro/e2e/prefetch.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ +const test = testFactory(import.meta.url, { root: './fixtures/prefetch/', }); diff --git a/packages/astro/e2e/react-component.test.js b/packages/astro/e2e/react-component.test.js index 361ee8d69..4585887ad 100644 --- a/packages/astro/e2e/react-component.test.js +++ b/packages/astro/e2e/react-component.test.js @@ -1,7 +1,9 @@ import { expect } from '@playwright/test'; import { prepareTestFactory } from './shared-component-tests.js'; -const { test, createTests } = prepareTestFactory({ root: './fixtures/react-component/' }); +const { test, createTests } = prepareTestFactory(import.meta.url, { + root: './fixtures/react-component/', +}); const config = { counterComponentFilePath: './src/components/Counter.jsx', diff --git a/packages/astro/e2e/server-islands.test.js b/packages/astro/e2e/server-islands.test.js index b45a58cd8..24ac7b918 100644 --- a/packages/astro/e2e/server-islands.test.js +++ b/packages/astro/e2e/server-islands.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ root: './fixtures/server-islands/' }); +const test = testFactory(import.meta.url, { root: './fixtures/server-islands/' }); test.describe('Server islands', () => { test.describe('Development', () => { diff --git a/packages/astro/e2e/shared-component-tests.js b/packages/astro/e2e/shared-component-tests.js index 024f1aade..ea45da13b 100644 --- a/packages/astro/e2e/shared-component-tests.js +++ b/packages/astro/e2e/shared-component-tests.js @@ -1,8 +1,8 @@ import { expect } from '@playwright/test'; import { scrollToElement, testFactory, waitForHydrate } from './test-utils.js'; -export function prepareTestFactory(opts, { canReplayClicks = false } = {}) { - const test = testFactory(opts); +export function prepareTestFactory(testFile, opts, { canReplayClicks = false } = {}) { + const test = testFactory(testFile, opts); let devServer; @@ -120,6 +120,7 @@ export function prepareTestFactory(opts, { canReplayClicks = false } = {}) { await page.goto(astro.resolveUrl(pageUrl)); const label = page.locator('#client-only'); + await waitForHydrate(page, label); await expect(label, 'component is visible').toBeVisible(); await expect(label, 'slot text is visible').toHaveText('Framework client:only component'); diff --git a/packages/astro/e2e/solid-circular.test.js b/packages/astro/e2e/solid-circular.test.js index 5dd0e8b80..796800a21 100644 --- a/packages/astro/e2e/solid-circular.test.js +++ b/packages/astro/e2e/solid-circular.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ root: './fixtures/solid-circular/' }); +const test = testFactory(import.meta.url, { root: './fixtures/solid-circular/' }); let devServer; diff --git a/packages/astro/e2e/solid-component.test.js b/packages/astro/e2e/solid-component.test.js index b998d1873..6a934b1c4 100644 --- a/packages/astro/e2e/solid-component.test.js +++ b/packages/astro/e2e/solid-component.test.js @@ -1,6 +1,7 @@ import { prepareTestFactory } from './shared-component-tests.js'; const { test, createTests } = prepareTestFactory( + import.meta.url, { root: './fixtures/solid-component/' }, { canReplayClicks: true, diff --git a/packages/astro/e2e/solid-recurse.test.js b/packages/astro/e2e/solid-recurse.test.js index de3759e98..eb0fa3770 100644 --- a/packages/astro/e2e/solid-recurse.test.js +++ b/packages/astro/e2e/solid-recurse.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/solid-recurse/' }); +const test = testFactory(import.meta.url, { root: './fixtures/solid-recurse/' }); let devServer; diff --git a/packages/astro/e2e/svelte-component.test.js b/packages/astro/e2e/svelte-component.test.js index 01c7aa41d..d72235797 100644 --- a/packages/astro/e2e/svelte-component.test.js +++ b/packages/astro/e2e/svelte-component.test.js @@ -2,7 +2,9 @@ import { expect } from '@playwright/test'; import { prepareTestFactory } from './shared-component-tests.js'; import { waitForHydrate } from './test-utils.js'; -const { test, createTests } = prepareTestFactory({ root: './fixtures/svelte-component/' }); +const { test, createTests } = prepareTestFactory(import.meta.url, { + root: './fixtures/svelte-component/', +}); const config = { componentFilePath: './src/components/SvelteComponent.svelte', diff --git a/packages/astro/e2e/tailwindcss.test.js b/packages/astro/e2e/tailwindcss.test.js index e58e10dfd..c86d01b0e 100644 --- a/packages/astro/e2e/tailwindcss.test.js +++ b/packages/astro/e2e/tailwindcss.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory } from './test-utils.js'; -const test = testFactory({ root: './fixtures/tailwindcss/' }); +const test = testFactory(import.meta.url, { root: './fixtures/tailwindcss/' }); let devServer; diff --git a/packages/astro/e2e/test-utils.js b/packages/astro/e2e/test-utils.js index 48fcd17bd..933186a71 100644 --- a/packages/astro/e2e/test-utils.js +++ b/packages/astro/e2e/test-utils.js @@ -14,30 +14,40 @@ const testFileToPort = new Map(); for (let i = 0; i < testFiles.length; i++) { const file = testFiles[i]; if (file.endsWith('.test.js')) { - testFileToPort.set(file.slice(0, -8), 4000 + i); + testFileToPort.set(file, 4000 + i); } } -export function loadFixture(inlineConfig) { +export function loadFixture(testFile, inlineConfig) { if (!inlineConfig?.root) throw new Error("Must provide { root: './fixtures/...' }"); + const port = testFileToPort.get(path.basename(testFile)); + // resolve the relative root (i.e. "./fixtures/tailwindcss") to a full filepath // without this, the main `loadFixture` helper will resolve relative to `packages/astro/test` return baseLoadFixture({ ...inlineConfig, root: fileURLToPath(new URL(inlineConfig.root, import.meta.url)), server: { - port: testFileToPort.get(path.basename(inlineConfig.root)), + ...inlineConfig?.server, + port, + }, + vite: { + ...inlineConfig?.vite, + server: { + ...inlineConfig?.vite?.server, + strictPort: true, + }, }, }); } -export function testFactory(inlineConfig) { +export function testFactory(testFile, inlineConfig) { let fixture; const test = testBase.extend({ astro: async ({}, use) => { - fixture = fixture || (await loadFixture(inlineConfig)); + fixture = fixture || (await loadFixture(testFile, inlineConfig)); await use(fixture); }, }); diff --git a/packages/astro/e2e/ts-resolution.test.js b/packages/astro/e2e/ts-resolution.test.js index d2d3fcfe8..256269542 100644 --- a/packages/astro/e2e/ts-resolution.test.js +++ b/packages/astro/e2e/ts-resolution.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/ts-resolution/' }); +const test = testFactory(import.meta.url, { root: './fixtures/ts-resolution/' }); function runTest(it) { it('client:idle', async ({ page, astro }) => { diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index 135ec5571..181994cfa 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import { testFactory, waitForHydrate } from './test-utils.js'; -const test = testFactory({ root: './fixtures/view-transitions/' }); +const test = testFactory(import.meta.url, { root: './fixtures/view-transitions/' }); let devServer; @@ -447,7 +447,9 @@ test.describe('View Transitions', () => { expect(consoleCount).toEqual(1); // forward '' to 'hash' (no transition) - await page.goForward(); + // NOTE: the networkidle below is needed for Firefox to consistently + // pass the `#longpage` viewport check below + await page.goForward({ waitUntil: 'networkidle' }); locator = page.locator('#click-one-again'); await expect(locator).toBeInViewport(); expect(consoleCount).toEqual(1); @@ -1445,7 +1447,7 @@ test.describe('View Transitions', () => { await page.click('#click'); await expect(page.locator('#name'), 'should have content').toHaveText('Keep 2'); - const styleElement = await page.$('head > style'); + const styleElement = await page.$('head > style:nth-child(1)'); const styleContent = await page.evaluate((style) => style.innerHTML, styleElement); expect(styleContent).toBe('body { background-color: purple; }'); }); diff --git a/packages/astro/e2e/vue-component.test.js b/packages/astro/e2e/vue-component.test.js index 3be31af85..034fe5a6e 100644 --- a/packages/astro/e2e/vue-component.test.js +++ b/packages/astro/e2e/vue-component.test.js @@ -1,6 +1,8 @@ import { expect } from '@playwright/test'; import { prepareTestFactory } from './shared-component-tests.js'; -const { test, createTests } = prepareTestFactory({ root: './fixtures/vue-component/' }); +const { test, createTests } = prepareTestFactory(import.meta.url, { + root: './fixtures/vue-component/', +}); const config = { componentFilePath: './src/components/VueComponent.vue', diff --git a/packages/astro/package.json b/packages/astro/package.json index c15d9aba2..a448146ee 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -125,10 +125,9 @@ "@astrojs/internal-helpers": "workspace:*", "@astrojs/markdown-remark": "workspace:*", "@astrojs/telemetry": "workspace:*", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/traverse": "^7.25.3", - "@babel/types": "^7.25.2", + "@babel/core": "^7.25.2", + "@babel/plugin-transform-react-jsx": "^7.25.2", + "@babel/types": "^7.25.4", "@oslojs/encoding": "^0.4.1", "@rollup/pluginutils": "^5.1.0", "@types/cookie": "^0.6.0", @@ -150,7 +149,6 @@ "es-module-lexer": "^1.5.4", "esbuild": "^0.21.5", "estree-walker": "^3.0.3", - "execa": "^8.0.1", "fast-glob": "^3.3.2", "flattie": "^1.1.1", "github-slugger": "^2.0.0", @@ -160,10 +158,11 @@ "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.11", - "micromatch": "^4.0.7", + "magicast": "^0.3.5", + "micromatch": "^4.0.8", "mrmime": "^2.0.0", "neotraverse": "^0.6.18", - "ora": "^8.0.1", + "ora": "^8.1.0", "p-limit": "^6.1.0", "p-queue": "^8.0.1", "path-to-regexp": "^6.2.2", @@ -174,10 +173,11 @@ "shiki": "^1.14.1", "string-width": "^7.2.0", "strip-ansi": "^7.1.0", + "tinyexec": "^0.3.0", "tsconfck": "^3.1.1", "unist-util-visit": "^5.0.0", - "vfile": "^6.0.2", - "vite": "^5.4.1", + "vfile": "^6.0.3", + "vite": "^5.4.2", "vitefu": "^0.2.5", "which-pm": "^3.0.0", "xxhash-wasm": "^1.0.2", @@ -212,9 +212,10 @@ "astro-scripts": "workspace:*", "cheerio": "1.0.0", "eol": "^0.9.1", - "expect-type": "^0.19.0", + "execa": "^8.0.1", + "expect-type": "^0.20.0", "mdast-util-mdx": "^3.0.0", - "mdast-util-mdx-jsx": "^3.1.2", + "mdast-util-mdx-jsx": "^3.1.3", "memfs": "^4.11.1", "node-mocks-http": "^1.15.1", "parse-srcset": "^1.0.2", @@ -222,9 +223,9 @@ "rehype-slug": "^6.0.0", "rehype-toc": "^3.0.2", "remark-code-titles": "^0.1.2", - "rollup": "^4.21.0", + "rollup": "^4.21.1", "sass": "^1.77.8", - "undici": "^6.19.7", + "undici": "^6.19.8", "unified": "^11.0.5" }, "engines": { diff --git a/packages/astro/performance/fixtures/md/package.json b/packages/astro/performance/fixtures/md/package.json index d51beb903..90db727e4 100644 --- a/packages/astro/performance/fixtures/md/package.json +++ b/packages/astro/performance/fixtures/md/package.json @@ -16,7 +16,7 @@ "dependencies": { "@astrojs/react": "workspace:*", "@performance/utils": "workspace:*", - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "astro": "workspace:*", "react": "^18.3.1", diff --git a/packages/astro/performance/fixtures/mdoc/package.json b/packages/astro/performance/fixtures/mdoc/package.json index 406c9b1d4..5bcd443ae 100644 --- a/packages/astro/performance/fixtures/mdoc/package.json +++ b/packages/astro/performance/fixtures/mdoc/package.json @@ -17,7 +17,7 @@ "@astrojs/markdoc": "workspace:*", "@astrojs/react": "workspace:*", "@performance/utils": "workspace:*", - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "astro": "workspace:*", "react": "^18.3.1", diff --git a/packages/astro/performance/fixtures/mdoc/src/env.d.ts b/packages/astro/performance/fixtures/mdoc/src/env.d.ts deleted file mode 100644 index acef35f17..000000000 --- a/packages/astro/performance/fixtures/mdoc/src/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// <reference path="../.astro/types.d.ts" /> -/// <reference types="astro/client" /> diff --git a/packages/astro/performance/fixtures/mdx/package.json b/packages/astro/performance/fixtures/mdx/package.json index 973bfd530..e1fc69d0d 100644 --- a/packages/astro/performance/fixtures/mdx/package.json +++ b/packages/astro/performance/fixtures/mdx/package.json @@ -17,7 +17,7 @@ "@astrojs/mdx": "workspace:*", "@astrojs/react": "workspace:*", "@performance/utils": "workspace:*", - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "astro": "workspace:*", "react": "^18.3.1", diff --git a/packages/astro/performance/fixtures/mdx/src/env.d.ts b/packages/astro/performance/fixtures/mdx/src/env.d.ts deleted file mode 100644 index acef35f17..000000000 --- a/packages/astro/performance/fixtures/mdx/src/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// <reference path="../.astro/types.d.ts" /> -/// <reference types="astro/client" /> diff --git a/packages/astro/playwright.config.js b/packages/astro/playwright.config.js index 5aacd6d01..26572c66c 100644 --- a/packages/astro/playwright.config.js +++ b/packages/astro/playwright.config.js @@ -1,4 +1,5 @@ import { defineConfig } from '@playwright/test'; + // NOTE: Sometimes, tests fail with `TypeError: process.stdout.clearLine is not a function` // for some reason. This comes from Vite, and is conditionally called based on `isTTY`. // We set it to false here to skip this odd behavior. @@ -6,35 +7,16 @@ process.stdout.isTTY = false; export default defineConfig({ testMatch: 'e2e/*.test.js', - /* Maximum time one test can run for. */ - timeout: 40 * 1000, - expect: { - /** - * Maximum time expect() should wait for the condition to be met. - * For example in `await expect(locator).toHaveText();` - */ - timeout: 4 * 1000, - }, - /* Fail the build on CI if you accidentally left test in the source code. */ + timeout: 40000, forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 3 : 0, - /* Opt out of parallel tests on CI. */ - workers: 1, - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ - actionTimeout: 0, - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', - }, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, projects: [ { name: 'Chrome Stable', use: { browserName: 'chromium', channel: 'chrome', - args: ['--use-gl=egl'], }, }, ], diff --git a/packages/astro/playwright.firefox.config.js b/packages/astro/playwright.firefox.config.js index 537bb4099..00b82d999 100644 --- a/packages/astro/playwright.firefox.config.js +++ b/packages/astro/playwright.firefox.config.js @@ -1,43 +1,24 @@ +import { defineConfig } from '@playwright/test'; + // NOTE: Sometimes, tests fail with `TypeError: process.stdout.clearLine is not a function` // for some reason. This comes from Vite, and is conditionally called based on `isTTY`. // We set it to false here to skip this odd behavior. process.stdout.isTTY = false; -const config = { +export default defineConfig({ // TODO: add more tests like view transitions and audits, and fix them. Some of them are failing. testMatch: ['e2e/css.test.js', 'e2e/prefetch.test.js', 'e2e/view-transitions.test.js'], - /* Maximum time one test can run for. */ - timeout: 40 * 1000, - expect: { - /** - * Maximum time expect() should wait for the condition to be met. - * For example in `await expect(locator).toHaveText();` - */ - timeout: 4 * 1000, - }, - /* Fail the build on CI if you accidentally left test in the source code. */ + timeout: 40000, forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 3 : 0, - /* Opt out of parallel tests on CI. */ - workers: 1, - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ - actionTimeout: 0, - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', - }, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, projects: [ { name: 'Firefox Stable', use: { browserName: 'firefox', channel: 'firefox', - args: ['--use-gl=egl'], }, }, ], -}; - -export default config; +}); diff --git a/packages/astro/src/actions/runtime/middleware.ts b/packages/astro/src/actions/runtime/middleware.ts index b6f3221b5..b7cb4861c 100644 --- a/packages/astro/src/actions/runtime/middleware.ts +++ b/packages/astro/src/actions/runtime/middleware.ts @@ -23,8 +23,18 @@ export type Locals = { }; export const onRequest = defineMiddleware(async (context, next) => { + if ((context as any)._isPrerendered) { + if (context.request.method === 'POST') { + // eslint-disable-next-line no-console + console.warn( + yellow('[astro:actions]'), + 'POST requests should not be sent to prerendered pages. If you\'re using Actions, disable prerendering with `export const prerender = "false".', + ); + } + return next(); + } + const locals = context.locals as Locals; - const { request } = context; // Actions middleware may have run already after a path rewrite. // See https://github.com/withastro/roadmap/blob/feat/reroute/proposals/0047-rerouting.md#ctxrewrite // `_actionPayload` is the same for every page, @@ -39,16 +49,6 @@ export const onRequest = defineMiddleware(async (context, next) => { return renderResult({ context, next, ...actionPayload }); } - // Heuristic: If body is null, Astro might've reset this for prerendering. - if (import.meta.env.DEV && request.method === 'POST' && request.body === null) { - // eslint-disable-next-line no-console - console.warn( - yellow('[astro:actions]'), - 'POST requests should not be sent to prerendered pages. If you\'re using Actions, disable prerendering with `export const prerender = "false".', - ); - return next(); - } - const actionName = context.url.searchParams.get(ACTION_QUERY_PARAMS.actionName); if (context.request.method === 'POST' && actionName) { @@ -93,7 +93,11 @@ async function handlePost({ context, next, actionName, -}: { context: APIContext; next: MiddlewareNext; actionName: string }) { +}: { + context: APIContext; + next: MiddlewareNext; + actionName: string; +}) { const { request } = context; const baseAction = await getAction(actionName); diff --git a/packages/astro/src/actions/runtime/utils.ts b/packages/astro/src/actions/runtime/utils.ts index 199809d4e..d8b339a09 100644 --- a/packages/astro/src/actions/runtime/utils.ts +++ b/packages/astro/src/actions/runtime/utils.ts @@ -10,7 +10,10 @@ export function hasContentType(contentType: string, expected: string[]) { return expected.some((t) => type === t); } -export type ActionAPIContext = Omit<APIContext, 'getActionResult' | 'callAction' | 'props'>; +export type ActionAPIContext = Omit< + APIContext, + 'getActionResult' | 'callAction' | 'props' | 'redirect' +>; export type MaybePromise<T> = T | Promise<T>; /** diff --git a/packages/astro/src/actions/runtime/virtual/server.ts b/packages/astro/src/actions/runtime/virtual/server.ts index 9bc387d6b..fcb0dc603 100644 --- a/packages/astro/src/actions/runtime/virtual/server.ts +++ b/packages/astro/src/actions/runtime/virtual/server.ts @@ -9,9 +9,6 @@ export * from './shared.js'; export { z } from 'zod'; export type ActionAccept = 'form' | 'json'; -export type ActionInputSchema<T extends ActionAccept | undefined> = T extends 'form' - ? z.AnyZodObject | z.ZodType<FormData> - : z.ZodType; export type ActionHandler<TInputSchema, TOutput> = TInputSchema extends z.ZodType ? (input: z.infer<TInputSchema>, context: ActionAPIContext) => MaybePromise<TOutput> @@ -22,7 +19,7 @@ export type ActionReturnType<T extends ActionHandler<any, any>> = Awaited<Return export type ActionClient< TOutput, TAccept extends ActionAccept | undefined, - TInputSchema extends ActionInputSchema<TAccept> | undefined, + TInputSchema extends z.ZodType | undefined, > = TInputSchema extends z.ZodType ? (( input: TAccept extends 'form' ? FormData : z.input<TInputSchema>, @@ -46,7 +43,7 @@ export type ActionClient< export function defineAction< TOutput, TAccept extends ActionAccept | undefined = undefined, - TInputSchema extends ActionInputSchema<ActionAccept> | undefined = TAccept extends 'form' + TInputSchema extends z.ZodType | undefined = TAccept extends 'form' ? // If `input` is omitted, default to `FormData` for forms and `any` for JSON. z.ZodType<FormData> : undefined, @@ -83,7 +80,7 @@ export function defineAction< return safeServerHandler as ActionClient<TOutput, TAccept, TInputSchema> & string; } -function getFormServerHandler<TOutput, TInputSchema extends ActionInputSchema<'form'>>( +function getFormServerHandler<TOutput, TInputSchema extends z.ZodType>( handler: ActionHandler<TInputSchema, TOutput>, inputSchema?: TInputSchema, ) { @@ -95,9 +92,14 @@ function getFormServerHandler<TOutput, TInputSchema extends ActionInputSchema<'f }); } - if (!(inputSchema instanceof z.ZodObject)) return await handler(unparsedInput, context); + if (!inputSchema) return await handler(unparsedInput, context); - const parsed = await inputSchema.safeParseAsync(formDataToObject(unparsedInput, inputSchema)); + const baseSchema = unwrapSchemaEffects(inputSchema); + const parsed = await inputSchema.safeParseAsync( + baseSchema instanceof z.ZodObject + ? formDataToObject(unparsedInput, baseSchema) + : unparsedInput, + ); if (!parsed.success) { throw new ActionInputError(parsed.error.issues); } @@ -105,7 +107,7 @@ function getFormServerHandler<TOutput, TInputSchema extends ActionInputSchema<'f }; } -function getJsonServerHandler<TOutput, TInputSchema extends ActionInputSchema<'json'>>( +function getJsonServerHandler<TOutput, TInputSchema extends z.ZodType>( handler: ActionHandler<TInputSchema, TOutput>, inputSchema?: TInputSchema, ) { @@ -131,7 +133,8 @@ export function formDataToObject<T extends z.AnyZodObject>( formData: FormData, schema: T, ): Record<string, unknown> { - const obj: Record<string, unknown> = {}; + const obj: Record<string, unknown> = + schema._def.unknownKeys === 'passthrough' ? Object.fromEntries(formData.entries()) : {}; for (const [key, baseValidator] of Object.entries(schema.shape)) { let validator = baseValidator; @@ -189,3 +192,15 @@ function handleFormDataGet( } return validator instanceof z.ZodNumber ? Number(value) : value; } + +function unwrapSchemaEffects(schema: z.ZodType) { + while (schema instanceof z.ZodEffects || schema instanceof z.ZodPipeline) { + if (schema instanceof z.ZodEffects) { + schema = schema._def.schema; + } + if (schema instanceof z.ZodPipeline) { + schema = schema._def.in; + } + } + return schema; +} diff --git a/packages/astro/src/actions/runtime/virtual/shared.ts b/packages/astro/src/actions/runtime/virtual/shared.ts index d792a9af5..01f9bd4e6 100644 --- a/packages/astro/src/actions/runtime/virtual/shared.ts +++ b/packages/astro/src/actions/runtime/virtual/shared.ts @@ -1,8 +1,16 @@ import { parse as devalueParse, stringify as devalueStringify } from 'devalue'; import type { z } from 'zod'; +import { REDIRECT_STATUS_CODES } from '../../../core/constants.js'; +import { ActionsReturnedInvalidDataError } from '../../../core/errors/errors-data.js'; +import { AstroError } from '../../../core/errors/errors.js'; import { ACTION_QUERY_PARAMS as _ACTION_QUERY_PARAMS } from '../../consts.js'; -import type { ErrorInferenceObject, MaybePromise } from '../utils.js'; +import type { + ErrorInferenceObject, + MaybePromise, + ActionAPIContext as _ActionAPIContext, +} from '../utils.js'; +export type ActionAPIContext = _ActionAPIContext; export const ACTION_QUERY_PARAMS = _ACTION_QUERY_PARAMS; export const ACTION_ERROR_CODES = [ @@ -232,14 +240,30 @@ export function serializeActionResult(res: SafeResult<any, any>): SerializedActi status: 204, }; } + let body; + try { + body = devalueStringify(res.data, { + // Add support for URL objects + URL: (value) => value instanceof URL && value.href, + }); + } catch (e) { + let hint = ActionsReturnedInvalidDataError.hint; + if (res.data instanceof Response) { + hint = REDIRECT_STATUS_CODES.includes(res.data.status as any) + ? 'If you need to redirect when the action succeeds, trigger a redirect where the action is called. See the Actions guide for server and client redirect examples: https://docs.astro.build/en/guides/actions.' + : 'If you need to return a Response object, try using a server endpoint instead. See https://docs.astro.build/en/guides/endpoints/#server-endpoints-api-routes'; + } + throw new AstroError({ + ...ActionsReturnedInvalidDataError, + message: ActionsReturnedInvalidDataError.message(String(e)), + hint, + }); + } return { type: 'data', status: 200, contentType: 'application/json+devalue', - body: devalueStringify(res.data, { - // Add support for URL objects - URL: (value) => value instanceof URL && value.href, - }), + body, }; } diff --git a/packages/astro/src/cli/add/babel.ts b/packages/astro/src/cli/add/babel.ts deleted file mode 100644 index facaabd54..000000000 --- a/packages/astro/src/cli/add/babel.ts +++ /dev/null @@ -1,16 +0,0 @@ -import generator from '@babel/generator'; -import parser from '@babel/parser'; -import traverse from '@babel/traverse'; -import * as t from '@babel/types'; - -export const visit = traverse.default; -export { t }; - -export async function generate(ast: t.File) { - const astToText = generator.default; - const { code } = astToText(ast); - return code; -} - -export const parse = (code: string) => - parser.parse(code, { sourceType: 'unambiguous', plugins: ['typescript'] }); diff --git a/packages/astro/src/cli/add/imports.ts b/packages/astro/src/cli/add/imports.ts deleted file mode 100644 index 375ca1dd8..000000000 --- a/packages/astro/src/cli/add/imports.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { t, visit } from './babel.js'; - -export function ensureImport(root: t.File, importDeclaration: t.ImportDeclaration) { - let specifiersToFind = [...importDeclaration.specifiers]; - - visit(root, { - ImportDeclaration(path) { - if (path.node.source.value === importDeclaration.source.value) { - path.node.specifiers.forEach((specifier) => - specifiersToFind.forEach((specifierToFind, i) => { - if (specifier.type !== specifierToFind.type) return; - if (specifier.local.name === specifierToFind.local.name) { - specifiersToFind.splice(i, 1); - } - }), - ); - } - }, - }); - - if (specifiersToFind.length === 0) return; - - visit(root, { - Program(path) { - const declaration = t.importDeclaration(specifiersToFind, importDeclaration.source); - const latestImport = path - .get('body') - .filter((statement) => statement.isImportDeclaration()) - .pop(); - - if (latestImport) latestImport.insertAfter(declaration); - else path.unshiftContainer('body', declaration); - }, - }); -} diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts index f710184d2..2b230048c 100644 --- a/packages/astro/src/cli/add/index.ts +++ b/packages/astro/src/cli/add/index.ts @@ -3,12 +3,14 @@ import path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import boxen from 'boxen'; import { diffWords } from 'diff'; -import { execa } from 'execa'; import { bold, cyan, dim, green, magenta, red, yellow } from 'kleur/colors'; +import { type ASTNode, type ProxifiedModule, builders, generateCode, loadFile } from 'magicast'; +import { getDefaultExportOptions } from 'magicast/helpers'; import ora from 'ora'; import preferredPM from 'preferred-pm'; import prompts from 'prompts'; import maxSatisfying from 'semver/ranges/max-satisfying.js'; +import { exec } from 'tinyexec'; import { loadTSConfig, resolveConfig, @@ -30,9 +32,6 @@ import { ensureProcessNodeEnv, parseNpmName } from '../../core/util.js'; import { eventCliSession, telemetry } from '../../events/index.js'; import { type Flags, createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js'; import { fetchPackageJson, fetchPackageVersions } from '../install-package.js'; -import { generate, parse, t, visit } from './babel.js'; -import { ensureImport } from './imports.js'; -import { wrapDefaultExport } from './wrapper.js'; interface AddOptions { flags: Flags; @@ -261,29 +260,26 @@ export async function add(names: string[], { flags }: AddOptions) { await fs.writeFile(fileURLToPath(configURL), STUBS.ASTRO_CONFIG, { encoding: 'utf-8' }); } - let ast: t.File | null = null; + let mod: ProxifiedModule<any> | undefined; try { - ast = await parseAstroConfig(configURL); - + mod = await loadFile(fileURLToPath(configURL)); logger.debug('add', 'Parsed astro config'); - const defineConfig = t.identifier('defineConfig'); - ensureImport( - ast, - t.importDeclaration( - [t.importSpecifier(defineConfig, defineConfig)], - t.stringLiteral('astro/config'), - ), - ); - wrapDefaultExport(ast, defineConfig); - + if (mod.exports.default.$type !== 'function-call') { + // ensure config is wrapped with `defineConfig` + mod.imports.$prepend({ imported: 'defineConfig', from: 'astro/config' }); + mod.exports.default = builders.functionCall('defineConfig', mod.exports.default); + } else if (mod.exports.default.$args[0] == null) { + // ensure first argument of `defineConfig` is not empty + mod.exports.default.$args[0] = {}; + } logger.debug('add', 'Astro config ensured `defineConfig`'); for (const integration of integrations) { if (isAdapter(integration)) { const officialExportName = OFFICIAL_ADAPTER_TO_IMPORT_MAP[integration.id]; if (officialExportName) { - await setAdapter(ast, integration, officialExportName); + setAdapter(mod, integration); } else { logger.info( 'SKIP_FORMAT', @@ -295,7 +291,7 @@ export async function add(names: string[], { flags }: AddOptions) { ); } } else { - await addIntegration(ast, integration); + addIntegration(mod, integration); } logger.debug('add', `Astro config added integration ${integration.id}`); } @@ -306,11 +302,11 @@ export async function add(names: string[], { flags }: AddOptions) { let configResult: UpdateResult | undefined; - if (ast) { + if (mod) { try { configResult = await updateAstroConfig({ configURL, - ast, + mod, flags, logger, logAdapterInstructions: integrations.some(isAdapter), @@ -390,17 +386,6 @@ function isAdapter( return integration.type === 'adapter'; } -async function parseAstroConfig(configURL: URL): Promise<t.File> { - const source = await fs.readFile(fileURLToPath(configURL), { encoding: 'utf-8' }); - const result = parse(source); - - if (!result) throw new Error('Unknown error parsing astro config'); - if (result.errors.length > 0) - throw new Error('Error parsing astro config: ' + JSON.stringify(result.errors)); - - return result; -} - // Convert an arbitrary NPM package name into a JS identifier // Some examples: // - @astrojs/image => image @@ -437,130 +422,47 @@ Documentation: https://docs.astro.build/en/guides/integrations-guide/`; return err; } -async function addIntegration(ast: t.File, integration: IntegrationInfo) { - const integrationId = t.identifier(toIdent(integration.id)); - - ensureImport( - ast, - t.importDeclaration( - [t.importDefaultSpecifier(integrationId)], - t.stringLiteral(integration.packageName), - ), - ); +function addIntegration(mod: ProxifiedModule<any>, integration: IntegrationInfo) { + const config = getDefaultExportOptions(mod); + const integrationId = toIdent(integration.id); - visit(ast, { - // eslint-disable-next-line @typescript-eslint/no-shadow - ExportDefaultDeclaration(path) { - if (!t.isCallExpression(path.node.declaration)) return; - - const configObject = path.node.declaration.arguments[0]; - if (!t.isObjectExpression(configObject)) return; - - let integrationsProp = configObject.properties.find((prop) => { - if (prop.type !== 'ObjectProperty') return false; - if (prop.key.type === 'Identifier') { - if (prop.key.name === 'integrations') return true; - } - if (prop.key.type === 'StringLiteral') { - if (prop.key.value === 'integrations') return true; - } - return false; - }) as t.ObjectProperty | undefined; - - const integrationCall = t.callExpression(integrationId, []); - - if (!integrationsProp) { - configObject.properties.push( - t.objectProperty(t.identifier('integrations'), t.arrayExpression([integrationCall])), - ); - return; - } - - if (integrationsProp.value.type !== 'ArrayExpression') - throw new Error('Unable to parse integrations'); - - const existingIntegrationCall = integrationsProp.value.elements.find( - (expr) => - t.isCallExpression(expr) && - t.isIdentifier(expr.callee) && - expr.callee.name === integrationId.name, - ); - - if (existingIntegrationCall) return; + if (!mod.imports.$items.some((imp) => imp.local === integrationId)) { + mod.imports.$append({ imported: integrationId, from: integration.packageName }); + } - integrationsProp.value.elements.push(integrationCall); - }, - }); + config.integrations ??= []; + if ( + !config.integrations.$ast.elements.some( + (el: ASTNode) => + el.type === 'CallExpression' && + el.callee.type === 'Identifier' && + el.callee.name === integrationId, + ) + ) { + config.integrations.push(builders.functionCall(integrationId)); + } } -async function setAdapter(ast: t.File, adapter: IntegrationInfo, exportName: string) { - const adapterId = t.identifier(toIdent(adapter.id)); +export function setAdapter(mod: ProxifiedModule<any>, adapter: IntegrationInfo) { + const config = getDefaultExportOptions(mod); + const adapterId = toIdent(adapter.id); - ensureImport( - ast, - t.importDeclaration([t.importDefaultSpecifier(adapterId)], t.stringLiteral(exportName)), - ); - - visit(ast, { - // eslint-disable-next-line @typescript-eslint/no-shadow - ExportDefaultDeclaration(path) { - if (!t.isCallExpression(path.node.declaration)) return; - - const configObject = path.node.declaration.arguments[0]; - if (!t.isObjectExpression(configObject)) return; - - let outputProp = configObject.properties.find((prop) => { - if (prop.type !== 'ObjectProperty') return false; - if (prop.key.type === 'Identifier') { - if (prop.key.name === 'output') return true; - } - if (prop.key.type === 'StringLiteral') { - if (prop.key.value === 'output') return true; - } - return false; - }) as t.ObjectProperty | undefined; - - if (!outputProp) { - configObject.properties.push( - t.objectProperty(t.identifier('output'), t.stringLiteral('server')), - ); - } - - let adapterProp = configObject.properties.find((prop) => { - if (prop.type !== 'ObjectProperty') return false; - if (prop.key.type === 'Identifier') { - if (prop.key.name === 'adapter') return true; - } - if (prop.key.type === 'StringLiteral') { - if (prop.key.value === 'adapter') return true; - } - return false; - }) as t.ObjectProperty | undefined; - - let adapterCall; - switch (adapter.id) { - // the node adapter requires a mode - case 'node': { - adapterCall = t.callExpression(adapterId, [ - t.objectExpression([ - t.objectProperty(t.identifier('mode'), t.stringLiteral('standalone')), - ]), - ]); - break; - } - default: { - adapterCall = t.callExpression(adapterId, []); - } - } + if (!mod.imports.$items.some((imp) => imp.local === adapterId)) { + mod.imports.$append({ imported: adapterId, from: adapter.packageName }); + } - if (!adapterProp) { - configObject.properties.push(t.objectProperty(t.identifier('adapter'), adapterCall)); - return; - } + if (!config.output) { + config.output = 'server'; + } - adapterProp.value = adapterCall; - }, - }); + switch (adapter.id) { + case 'node': + config.adapter = builders.functionCall(adapterId, { mode: 'standalone' }); + break; + default: + config.adapter = builders.functionCall(adapterId); + break; + } } const enum UpdateResult { @@ -572,23 +474,25 @@ const enum UpdateResult { async function updateAstroConfig({ configURL, - ast, + mod, flags, logger, logAdapterInstructions, }: { configURL: URL; - ast: t.File; + mod: ProxifiedModule<any>; flags: Flags; logger: Logger; logAdapterInstructions: boolean; }): Promise<UpdateResult> { const input = await fs.readFile(fileURLToPath(configURL), { encoding: 'utf-8' }); - let output = await generate(ast); - const comment = '// https://astro.build/config'; - const defaultExport = 'export default defineConfig'; - output = output.replace(`\n${comment}`, ''); - output = output.replace(`${defaultExport}`, `\n${comment}\n${defaultExport}`); + const output = generateCode(mod, { + format: { + objectCurlySpacing: true, + useTabs: false, + tabWidth: 2, + }, + }).code; if (input === output) { return UpdateResult.none; @@ -755,7 +659,7 @@ async function tryToInstallIntegrations({ if (await askToContinue({ flags })) { const spinner = ora('Installing dependencies...').start(); try { - await execa( + await exec( installCommand.pm, [ installCommand.command, @@ -764,9 +668,11 @@ async function tryToInstallIntegrations({ ...installCommand.dependencies, ], { - cwd, - // reset NODE_ENV to ensure install command run in dev mode - env: { NODE_ENV: undefined }, + nodeOptions: { + cwd, + // reset NODE_ENV to ensure install command run in dev mode + env: { NODE_ENV: undefined }, + }, }, ); spinner.succeed(); diff --git a/packages/astro/src/cli/add/wrapper.ts b/packages/astro/src/cli/add/wrapper.ts deleted file mode 100644 index c86e87698..000000000 --- a/packages/astro/src/cli/add/wrapper.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { t, visit } from './babel.js'; - -export function wrapDefaultExport(ast: t.File, functionIdentifier: t.Identifier) { - visit(ast, { - ExportDefaultDeclaration(path) { - if (!t.isExpression(path.node.declaration)) return; - if ( - t.isCallExpression(path.node.declaration) && - t.isIdentifier(path.node.declaration.callee) && - path.node.declaration.callee.name === functionIdentifier.name - ) - return; - path.node.declaration = t.callExpression(functionIdentifier, [path.node.declaration]); - }, - }); -} diff --git a/packages/astro/src/cli/docs/open.ts b/packages/astro/src/cli/docs/open.ts index 3913ccec4..6f2fe4c82 100644 --- a/packages/astro/src/cli/docs/open.ts +++ b/packages/astro/src/cli/docs/open.ts @@ -1,5 +1,4 @@ -import type { ExecaChildProcess } from 'execa'; -import { execa } from 'execa'; +import { type Result, exec } from 'tinyexec'; /** * Credit: Azhar22 @@ -26,7 +25,7 @@ const getPlatformSpecificCommand = (): [string] | [string, string[]] => { } }; -export async function openInBrowser(url: string): Promise<ExecaChildProcess> { +export async function openInBrowser(url: string): Promise<Result> { const [command, args = []] = getPlatformSpecificCommand(); - return execa(command, [...args, encodeURI(url)]); + return exec(command, [...args, encodeURI(url)]); } diff --git a/packages/astro/src/cli/install-package.ts b/packages/astro/src/cli/install-package.ts index 637390ef3..d61a752de 100644 --- a/packages/astro/src/cli/install-package.ts +++ b/packages/astro/src/cli/install-package.ts @@ -1,11 +1,11 @@ import { createRequire } from 'node:module'; import boxen from 'boxen'; import ci from 'ci-info'; -import { execa } from 'execa'; import { bold, cyan, dim, magenta } from 'kleur/colors'; import ora from 'ora'; import preferredPM from 'preferred-pm'; import prompts from 'prompts'; +import { exec } from 'tinyexec'; import whichPm from 'which-pm'; import type { Logger } from '../core/logger/core.js'; @@ -141,10 +141,10 @@ async function installPackage( if (Boolean(response)) { const spinner = ora('Installing dependencies...').start(); try { - await execa( + await exec( installCommand.pm, [installCommand.command, ...installCommand.flags, ...installCommand.dependencies], - { cwd: cwd }, + { nodeOptions: { cwd: cwd } }, ); spinner.succeed(); @@ -203,8 +203,8 @@ async function getRegistry(): Promise<string> { const fallback = 'https://registry.npmjs.org'; const packageManager = (await preferredPM(process.cwd()))?.name || 'npm'; try { - const { stdout } = await execa(packageManager, ['config', 'get', 'registry']); - _registry = stdout?.trim()?.replace(/\/$/, '') || fallback; + const { stdout } = await exec(packageManager, ['config', 'get', 'registry']); + _registry = stdout.trim()?.replace(/\/$/, '') || fallback; // Detect cases where the shell command returned a non-URL (e.g. a warning) if (!new URL(_registry).host) _registry = fallback; } catch { diff --git a/packages/astro/src/container/pipeline.ts b/packages/astro/src/container/pipeline.ts index 73caa4ecd..167285158 100644 --- a/packages/astro/src/container/pipeline.ts +++ b/packages/astro/src/container/pipeline.ts @@ -1,4 +1,4 @@ -import { type HeadElements, Pipeline } from '../core/base-pipeline.js'; +import { type HeadElements, Pipeline, type TryRewriteResult } from '../core/base-pipeline.js'; import type { SinglePageBuiltModule } from '../core/build/types.js'; import { createModuleScriptElement, @@ -64,11 +64,8 @@ export class ContainerPipeline extends Pipeline { return { links, styles, scripts }; } - async tryRewrite( - payload: RewritePayload, - request: Request, - ): Promise<[RouteData, ComponentInstance, URL]> { - const [foundRoute, finalUrl] = findRouteToRewrite({ + async tryRewrite(payload: RewritePayload, request: Request): Promise<TryRewriteResult> { + const { newUrl, pathname, routeData } = findRouteToRewrite({ payload, request, routes: this.manifest?.routes.map((r) => r.routeData), @@ -77,8 +74,8 @@ export class ContainerPipeline extends Pipeline { base: this.manifest.base, }); - const componentInstance = await this.getComponentByRoute(foundRoute); - return [foundRoute, componentInstance, finalUrl]; + const componentInstance = await this.getComponentByRoute(routeData); + return { componentInstance, routeData, newUrl, pathname }; } insertRoute(route: RouteData, componentInstance: ComponentInstance): void { diff --git a/packages/astro/src/content/loaders/file.ts b/packages/astro/src/content/loaders/file.ts index cbc684a99..75e5e214d 100644 --- a/packages/astro/src/content/loaders/file.ts +++ b/packages/astro/src/content/loaders/file.ts @@ -26,6 +26,8 @@ export function file(fileName: string): Loader { return; } + const normalizedFilePath = posixRelative(fileURLToPath(settings.config.root), filePath); + if (Array.isArray(json)) { if (json.length === 0) { logger.warn(`No items found in ${fileName}`); @@ -39,11 +41,7 @@ export function file(fileName: string): Loader { continue; } const data = await parseData({ id, data: rawItem, filePath }); - store.set({ - id, - data, - filePath: posixRelative(fileURLToPath(settings.config.root), filePath), - }); + store.set({ id, data, filePath: normalizedFilePath }); } } else if (typeof json === 'object') { const entries = Object.entries<Record<string, unknown>>(json); @@ -51,7 +49,7 @@ export function file(fileName: string): Loader { store.clear(); for (const [id, rawItem] of entries) { const data = await parseData({ id, data: rawItem, filePath }); - store.set({ id, data }); + store.set({ id, data, filePath: normalizedFilePath }); } } else { logger.error(`Invalid data in ${fileName}. Must be an array or object.`); diff --git a/packages/astro/src/content/utils.ts b/packages/astro/src/content/utils.ts index 27b0e1915..ba76d5e11 100644 --- a/packages/astro/src/content/utils.ts +++ b/packages/astro/src/content/utils.ts @@ -4,12 +4,13 @@ import { fileURLToPath, pathToFileURL } from 'node:url'; import { slug as githubSlug } from 'github-slugger'; import matter from 'gray-matter'; import type { PluginContext } from 'rollup'; -import { type ViteDevServer, normalizePath } from 'vite'; +import type { ViteDevServer } from 'vite'; import xxhash from 'xxhash-wasm'; import { z } from 'zod'; import { AstroError, AstroErrorData, MarkdownError, errorMap } from '../core/errors/index.js'; import { isYAMLException } from '../core/errors/utils.js'; import type { Logger } from '../core/logger/core.js'; +import { normalizePath } from '../core/viteUtils.js'; import type { AstroSettings } from '../types/astro.js'; import type { AstroConfig } from '../types/public/config.js'; import type { ContentEntryType, DataEntryType } from '../types/public/content.js'; diff --git a/packages/astro/src/core/app/pipeline.ts b/packages/astro/src/core/app/pipeline.ts index d42472f50..43ff91fdd 100644 --- a/packages/astro/src/core/app/pipeline.ts +++ b/packages/astro/src/core/app/pipeline.ts @@ -1,7 +1,7 @@ import type { ComponentInstance, ManifestData } from '../../types/astro.js'; import type { RewritePayload } from '../../types/public/common.js'; import type { RouteData, SSRElement, SSRResult } from '../../types/public/internal.js'; -import { Pipeline } from '../base-pipeline.js'; +import { Pipeline, type TryRewriteResult } from '../base-pipeline.js'; import type { SinglePageBuiltModule } from '../build/types.js'; import { RedirectSinglePageBuiltModule } from '../redirects/component.js'; import { createModuleScriptElement, createStylesheetElementSet } from '../render/ssr-element.js'; @@ -89,8 +89,8 @@ export class AppPipeline extends Pipeline { payload: RewritePayload, request: Request, _sourceRoute: RouteData, - ): Promise<[RouteData, ComponentInstance, URL]> { - const [foundRoute, finalUrl] = findRouteToRewrite({ + ): Promise<TryRewriteResult> { + const { newUrl, pathname, routeData } = findRouteToRewrite({ payload, request, routes: this.manifest?.routes.map((r) => r.routeData), @@ -99,8 +99,8 @@ export class AppPipeline extends Pipeline { base: this.manifest.base, }); - const componentInstance = await this.getComponentByRoute(foundRoute); - return [foundRoute, componentInstance, finalUrl]; + const componentInstance = await this.getComponentByRoute(routeData); + return { newUrl, pathname, componentInstance, routeData }; } async getModuleForRoute(route: RouteData): Promise<SinglePageBuiltModule> { diff --git a/packages/astro/src/core/app/types.ts b/packages/astro/src/core/app/types.ts index 66140e778..4bf2a350e 100644 --- a/packages/astro/src/core/app/types.ts +++ b/packages/astro/src/core/app/types.ts @@ -74,6 +74,7 @@ export type SSRManifest = { export type SSRManifestI18n = { fallback: Record<string, string> | undefined; + fallbackType: 'redirect' | 'rewrite'; strategy: RoutingStrategies; locales: Locales; defaultLocale: string; diff --git a/packages/astro/src/core/base-pipeline.ts b/packages/astro/src/core/base-pipeline.ts index 9d772de9d..2c8199446 100644 --- a/packages/astro/src/core/base-pipeline.ts +++ b/packages/astro/src/core/base-pipeline.ts @@ -94,7 +94,7 @@ export abstract class Pipeline { rewritePayload: RewritePayload, request: Request, sourceRoute: RouteData, - ): Promise<[RouteData, ComponentInstance, URL]>; + ): Promise<TryRewriteResult>; /** * Tells the pipeline how to retrieve a component give a `RouteData` @@ -105,3 +105,10 @@ export abstract class Pipeline { // eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface HeadElements extends Pick<SSRResult, 'scripts' | 'styles' | 'links'> {} + +export interface TryRewriteResult { + routeData: RouteData; + componentInstance: ComponentInstance; + newUrl: URL; + pathname: string; +} diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index b2fed3763..0a33d554c 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -14,7 +14,7 @@ import { removeLeadingForwardSlash, removeTrailingForwardSlash, } from '../../core/path.js'; -import { toRoutingStrategy } from '../../i18n/utils.js'; +import { toFallbackType, toRoutingStrategy } from '../../i18n/utils.js'; import { runHookBuildGenerated } from '../../integrations/hooks.js'; import { getOutputDirectory } from '../../prerender/utils.js'; import type { AstroSettings, ComponentInstance } from '../../types/astro.js'; @@ -504,6 +504,7 @@ function createBuildManifest( if (settings.config.i18n) { i18nManifest = { fallback: settings.config.i18n.fallback, + fallbackType: toFallbackType(settings.config.i18n.routing), strategy: toRoutingStrategy(settings.config.i18n.routing, settings.config.i18n.domains), defaultLocale: settings.config.i18n.defaultLocale, locales: settings.config.i18n.locales, diff --git a/packages/astro/src/core/build/pipeline.ts b/packages/astro/src/core/build/pipeline.ts index 02be5df9f..55cc0d456 100644 --- a/packages/astro/src/core/build/pipeline.ts +++ b/packages/astro/src/core/build/pipeline.ts @@ -9,6 +9,7 @@ import type { } from '../../types/public/internal.js'; import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js'; import type { SSRManifest } from '../app/types.js'; +import type { TryRewriteResult } from '../base-pipeline.js'; import { routeIsFallback, routeIsRedirect } from '../redirects/helpers.js'; import { RedirectSinglePageBuiltModule } from '../redirects/index.js'; import { Pipeline } from '../render/index.js'; @@ -265,8 +266,8 @@ export class BuildPipeline extends Pipeline { payload: RewritePayload, request: Request, _sourceRoute: RouteData, - ): Promise<[RouteData, ComponentInstance, URL]> { - const [foundRoute, finalUrl] = findRouteToRewrite({ + ): Promise<TryRewriteResult> { + const { routeData, pathname, newUrl } = findRouteToRewrite({ payload, request, routes: this.options.manifest.routes, @@ -275,8 +276,8 @@ export class BuildPipeline extends Pipeline { base: this.config.base, }); - const componentInstance = await this.getComponentByRoute(foundRoute); - return [foundRoute, componentInstance, finalUrl]; + const componentInstance = await this.getComponentByRoute(routeData); + return { routeData, componentInstance, newUrl, pathname }; } async retrieveSsrEntry(route: RouteData, filePath: string): Promise<SinglePageBuiltModule> { diff --git a/packages/astro/src/core/build/plugins/plugin-content.ts b/packages/astro/src/core/build/plugins/plugin-content.ts index 5fe0b6792..3482657fb 100644 --- a/packages/astro/src/core/build/plugins/plugin-content.ts +++ b/packages/astro/src/core/build/plugins/plugin-content.ts @@ -22,7 +22,7 @@ import { import { isContentCollectionsCacheEnabled } from '../../util.js'; import { addRollupInput } from '../add-rollup-input.js'; import { CHUNKS_PATH, CONTENT_PATH } from '../consts.js'; -import { type BuildInternals } from '../internal.js'; +import type { BuildInternals } from '../internal.js'; import type { AstroBuildPlugin } from '../plugin.js'; import { copyFiles } from '../static-build.js'; import type { StaticBuildOptions } from '../types.js'; diff --git a/packages/astro/src/core/build/plugins/plugin-manifest.ts b/packages/astro/src/core/build/plugins/plugin-manifest.ts index ef8eb0915..6259d1526 100644 --- a/packages/astro/src/core/build/plugins/plugin-manifest.ts +++ b/packages/astro/src/core/build/plugins/plugin-manifest.ts @@ -4,7 +4,7 @@ import type { OutputChunk } from 'rollup'; import type { Plugin as VitePlugin } from 'vite'; import { getAssetsPrefix } from '../../../assets/utils/getAssetsPrefix.js'; import { normalizeTheLocale } from '../../../i18n/index.js'; -import { toRoutingStrategy } from '../../../i18n/utils.js'; +import { toFallbackType, toRoutingStrategy } from '../../../i18n/utils.js'; import { runHookBuildSsr } from '../../../integrations/hooks.js'; import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../../vite-plugin-scripts/index.js'; import type { @@ -244,6 +244,7 @@ function buildManifest( if (settings.config.i18n) { i18nManifest = { fallback: settings.config.i18n.fallback, + fallbackType: toFallbackType(settings.config.i18n.routing), strategy: toRoutingStrategy(settings.config.i18n.routing, settings.config.i18n.domains), locales: settings.config.i18n.locales, defaultLocale: settings.config.i18n.defaultLocale, diff --git a/packages/astro/src/core/build/plugins/plugin-pages.ts b/packages/astro/src/core/build/plugins/plugin-pages.ts index 2dc400a6c..6996e3342 100644 --- a/packages/astro/src/core/build/plugins/plugin-pages.ts +++ b/packages/astro/src/core/build/plugins/plugin-pages.ts @@ -1,7 +1,7 @@ import type { Plugin as VitePlugin } from 'vite'; import { routeIsRedirect } from '../../redirects/index.js'; import { addRollupInput } from '../add-rollup-input.js'; -import { type BuildInternals } from '../internal.js'; +import type { BuildInternals } from '../internal.js'; import type { AstroBuildPlugin } from '../plugin.js'; import type { StaticBuildOptions } from '../types.js'; import { RENDERERS_MODULE_ID } from './plugin-renderers.js'; diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts index 5a2f0a611..e52eb560b 100644 --- a/packages/astro/src/core/config/schema.ts +++ b/packages/astro/src/core/config/schema.ts @@ -400,6 +400,7 @@ export const AstroConfigSchema = z.object({ .object({ prefixDefaultLocale: z.boolean().optional().default(false), redirectToDefaultLocale: z.boolean().optional().default(true), + fallbackType: z.enum(['redirect', 'rewrite']).optional().default('redirect'), }) .refine( ({ prefixDefaultLocale, redirectToDefaultLocale }) => { diff --git a/packages/astro/src/core/constants.ts b/packages/astro/src/core/constants.ts index 8e9f5ac74..274f86797 100644 --- a/packages/astro/src/core/constants.ts +++ b/packages/astro/src/core/constants.ts @@ -46,6 +46,11 @@ export const DEFAULT_404_COMPONENT = 'astro-default-404.astro'; export const DEFAULT_500_COMPONENT = 'astro-default-500.astro'; /** + * A response with one of these status codes will create a redirect response. + */ +export const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308, 300, 304] as const; + +/** * A response with one of these status codes will be rewritten * with the result of rendering the respective error page. */ diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts index 6a5995e3f..471f8f4f1 100644 --- a/packages/astro/src/core/create-vite.ts +++ b/packages/astro/src/core/create-vite.ts @@ -149,7 +149,7 @@ export async function createVite( astroPrefetch({ settings }), astroTransitions({ settings }), astroDevToolbar({ settings, logger }), - vitePluginFileURL({}), + vitePluginFileURL(), astroInternationalization({ settings }), settings.config.experimental.serverIslands && vitePluginServerIslands({ settings }), astroContainer(), diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index 475acdbbf..382c025d3 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -541,7 +541,7 @@ export const MissingImageDimension = { message: (missingDimension: 'width' | 'height' | 'both', imageURL: string) => `Missing ${ missingDimension === 'both' ? 'width and height attributes' : `${missingDimension} attribute` - } for ${imageURL}. When using remote images, both dimensions are required unless in order to avoid CLS.`, + } for ${imageURL}. When using remote images, both dimensions are required in order to avoid CLS.`, hint: 'If your image is inside your `src` folder, you probably meant to import it instead. See [the Imports guide for more information](https://docs.astro.build/en/guides/imports/#other-assets). You can also use `inferSize={true}` for remote images to get the original dimensions.', } satisfies ErrorData; /** @@ -1670,6 +1670,7 @@ export const ActionsWithoutServerOutputError = { * - [Actions RFC](https://github.com/withastro/roadmap/blob/actions/proposals/0046-actions.md) * @description * Action was called from a form using a GET request, but only POST requests are supported. This often occurs if `method="POST"` is missing on the form. + * @deprecated Deprecated since version 4.13.2. */ export const ActionsUsedWithForGetError = { name: 'ActionsUsedWithForGetError', @@ -1684,6 +1685,21 @@ export const ActionsUsedWithForGetError = { * @see * - [Actions RFC](https://github.com/withastro/roadmap/blob/actions/proposals/0046-actions.md) * @description + * Action handler returned invalid data. Handlers should return serializable data types, and cannot return a Response object. + */ +export const ActionsReturnedInvalidDataError = { + name: 'ActionsReturnedInvalidDataError', + title: 'Action handler returned invalid data.', + message: (error: string) => + `Action handler returned invalid data. Handlers should return serializable data types like objects, arrays, strings, and numbers. Parse error: ${error}`, + hint: 'See the devalue library for all supported types: https://github.com/rich-harris/devalue', +} satisfies ErrorData; + +/** + * @docs + * @see + * - [Actions RFC](https://github.com/withastro/roadmap/blob/actions/proposals/0046-actions.md) + * @description * The server received the query string `?_astroAction=name`, but could not find an action with that name. Use the action function's `.queryString` property to retrieve the form `action` URL. */ export const ActionQueryStringInvalidError = { diff --git a/packages/astro/src/core/render-context.ts b/packages/astro/src/core/render-context.ts index 1c0017c30..7c75df4f3 100644 --- a/packages/astro/src/core/render-context.ts +++ b/packages/astro/src/core/render-context.ts @@ -37,7 +37,7 @@ import { type Pipeline, Slots, getParams, getProps } from './render/index.js'; export class RenderContext { // The first route that this instance of the context attempts to render originalRoute: RouteData; - + // The component pattern to send to the users routePattern: string; @@ -111,6 +111,8 @@ export class RenderContext { const { cookies, middleware, pipeline } = this; const { logger, serverLike, streaming, manifest } = pipeline; + const isPrerendered = !serverLike || this.routeData.prerender; + const props = Object.keys(this.props).length > 0 ? this.props @@ -123,7 +125,7 @@ export class RenderContext { serverLike, base: manifest.base, }); - const apiContext = this.createAPIContext(props); + const apiContext = this.createAPIContext(props, isPrerendered); this.counter++; if (this.counter === 4) { @@ -138,13 +140,13 @@ export class RenderContext { if (payload) { pipeline.logger.debug('router', 'Called rewriting to:', payload); // we intentionally let the error bubble up - const [routeData, component] = await pipeline.tryRewrite( + const { routeData, componentInstance: newComponent } = await pipeline.tryRewrite( payload, this.request, this.originalRoute, ); this.routeData = routeData; - componentInstance = component; + componentInstance = newComponent; this.isRewriting = true; this.status = 200; } @@ -210,18 +212,27 @@ export class RenderContext { return response; } - createAPIContext(props: APIContext['props']): APIContext { + createAPIContext(props: APIContext['props'], isPrerendered: boolean): APIContext { const context = this.createActionAPIContext(); + const redirect = (path: string, status = 302) => + new Response(null, { status, headers: { Location: path } }); + return Object.assign(context, { props, + redirect, getActionResult: createGetActionResult(context.locals), callAction: createCallAction(context), + // Used internally by Actions middleware. + // TODO: discuss exposing this information from APIContext. + // middleware runs on prerendered routes in the dev server, + // so this is useful information to have. + _isPrerendered: isPrerendered, }); } async #executeRewrite(reroutePayload: RewritePayload) { this.pipeline.logger.debug('router', 'Calling rewrite: ', reroutePayload); - const [routeData, component, newURL] = await this.pipeline.tryRewrite( + const { routeData, componentInstance, newUrl, pathname } = await this.pipeline.tryRewrite( reroutePayload, this.request, this.originalRoute, @@ -230,25 +241,22 @@ export class RenderContext { if (reroutePayload instanceof Request) { this.request = reroutePayload; } else { - this.request = this.#copyRequest(newURL, this.request); + this.request = this.#copyRequest(newUrl, this.request); } this.url = new URL(this.request.url); this.cookies = new AstroCookies(this.request); - this.params = getParams(routeData, this.url.pathname); - this.pathname = this.url.pathname; + this.params = getParams(routeData, pathname); + this.pathname = pathname; this.isRewriting = true; // we found a route and a component, we can change the status code to 200 this.status = 200; - this.routePattern = getAstroRoutePattern(routeData.component); - return await this.render(component); + return await this.render(componentInstance); } createActionAPIContext(): ActionAPIContext { const renderContext = this; const { cookies, params, pipeline, url } = this; const generator = `Astro v${ASTRO_VERSION}`; - const redirect = (path: string, status = 302) => - new Response(null, { status, headers: { Location: path } }); const rewrite = async (reroutePayload: RewritePayload) => { return await this.#executeRewrite(reroutePayload); @@ -285,7 +293,6 @@ export class RenderContext { get preferredLocaleList() { return renderContext.computePreferredLocaleList(); }, - redirect, rewrite, request: this.request, site: pipeline.site, @@ -580,25 +587,27 @@ export class RenderContext { * @param component */ function getAstroRoutePattern(component: RouteData['component']): string { - let splitComponent = component.split("/"); + let splitComponent = component.split('/'); while (true) { const currentPart = splitComponent.shift(); - if (!currentPart) {break} - + if (!currentPart) { + break; + } + // "pages" isn't configurable, so it's safe to stop here - if (currentPart === "pages") { - break + if (currentPart === 'pages') { + break; } } - - const pathWithoutPages = splitComponent.join("/"); + + const pathWithoutPages = splitComponent.join('/'); // This covers cases where routes don't have extensions, so they can be: [slug] or [...slug] - if (pathWithoutPages.endsWith("]")) { + if (pathWithoutPages.endsWith(']')) { return pathWithoutPages; } - splitComponent = splitComponent.join("/").split("."); + splitComponent = splitComponent.join('/').split('.'); // this should remove the extension splitComponent.pop(); - return "/" + splitComponent.join("/"); + return '/' + splitComponent.join('/'); } diff --git a/packages/astro/src/core/routing/rewrite.ts b/packages/astro/src/core/routing/rewrite.ts index a6fce3354..3ad6a9bd2 100644 --- a/packages/astro/src/core/routing/rewrite.ts +++ b/packages/astro/src/core/routing/rewrite.ts @@ -14,6 +14,17 @@ export type FindRouteToRewrite = { base: AstroConfig['base']; }; +export interface FindRouteToRewriteResult { + routeData: RouteData; + newUrl: URL; + pathname: string; +} + +/** + * Shared logic to retrieve the rewritten route. It returns a tuple that represents: + * 1. The new `Request` object. It contains `base` + * 2. + */ export function findRouteToRewrite({ payload, routes, @@ -21,23 +32,25 @@ export function findRouteToRewrite({ trailingSlash, buildFormat, base, -}: FindRouteToRewrite): [RouteData, URL] { - let finalUrl: URL | undefined = undefined; +}: FindRouteToRewrite): FindRouteToRewriteResult { + let newUrl: URL | undefined = undefined; if (payload instanceof URL) { - finalUrl = payload; + newUrl = payload; } else if (payload instanceof Request) { - finalUrl = new URL(payload.url); + newUrl = new URL(payload.url); } else { - finalUrl = new URL(payload, new URL(request.url).origin); + newUrl = new URL(payload, new URL(request.url).origin); + } + let pathname = newUrl.pathname; + if (base !== '/' && newUrl.pathname.startsWith(base)) { + pathname = shouldAppendForwardSlash(trailingSlash, buildFormat) + ? appendForwardSlash(newUrl.pathname) + : removeTrailingForwardSlash(newUrl.pathname); + pathname = pathname.slice(base.length); } let foundRoute; for (const route of routes) { - const pathname = shouldAppendForwardSlash(trailingSlash, buildFormat) - ? appendForwardSlash(finalUrl.pathname) - : base !== '/' - ? removeTrailingForwardSlash(finalUrl.pathname) - : finalUrl.pathname; if (route.pattern.test(decodeURI(pathname))) { foundRoute = route; break; @@ -45,13 +58,17 @@ export function findRouteToRewrite({ } if (foundRoute) { - return [foundRoute, finalUrl]; + return { + routeData: foundRoute, + newUrl, + pathname, + }; } else { const custom404 = routes.find((route) => route.route === '/404'); if (custom404) { - return [custom404, finalUrl]; + return { routeData: custom404, newUrl, pathname }; } else { - return [DEFAULT_404_ROUTE, finalUrl]; + return { routeData: DEFAULT_404_ROUTE, newUrl, pathname }; } } } diff --git a/packages/astro/src/core/sync/index.ts b/packages/astro/src/core/sync/index.ts index c9769443e..9b2973233 100644 --- a/packages/astro/src/core/sync/index.ts +++ b/packages/astro/src/core/sync/index.ts @@ -58,7 +58,7 @@ export default async function sync( } let settings = await createSettings(astroConfig, inlineConfig.root); settings = await runHookConfigSetup({ - command: 'build', + command: 'sync', settings, logger, }); diff --git a/packages/astro/src/core/viteUtils.ts b/packages/astro/src/core/viteUtils.ts index bfe1eaadc..46c59d25d 100644 --- a/packages/astro/src/core/viteUtils.ts +++ b/packages/astro/src/core/viteUtils.ts @@ -1,10 +1,18 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { normalizePath } from 'vite'; -import { prependForwardSlash } from '../core/path.js'; +import { prependForwardSlash, slash } from '../core/path.js'; import type { ModuleLoader } from './module-loader/index.js'; import { VALID_ID_PREFIX, resolveJsToTs, unwrapId, viteID } from './util.js'; +const isWindows = typeof process !== 'undefined' && process.platform === 'win32'; + +/** + * Re-implementation of Vite's normalizePath that can be used without Vite + */ +export function normalizePath(id: string) { + return path.posix.normalize(isWindows ? slash(id) : id); +} + /** * Resolve the hydration paths so that it can be imported in the client */ diff --git a/packages/astro/src/i18n/index.ts b/packages/astro/src/i18n/index.ts index c7e676f75..af08db408 100644 --- a/packages/astro/src/i18n/index.ts +++ b/packages/astro/src/i18n/index.ts @@ -278,6 +278,7 @@ export type MiddlewarePayload = { defaultLocale: string; domains: Record<string, string> | undefined; fallback: Record<string, string> | undefined; + fallbackType: 'redirect' | 'rewrite'; }; // NOTE: public function exported to the users via `astro:i18n` module @@ -328,7 +329,7 @@ export function notFound({ base, locales }: MiddlewarePayload) { } // NOTE: public function exported to the users via `astro:i18n` module -export type RedirectToFallback = (context: APIContext, response: Response) => Response; +export type RedirectToFallback = (context: APIContext, response: Response) => Promise<Response>; export function redirectToFallback({ fallback, @@ -336,8 +337,9 @@ export function redirectToFallback({ defaultLocale, strategy, base, + fallbackType, }: MiddlewarePayload) { - return function (context: APIContext, response: Response): Response { + return async function (context: APIContext, response: Response): Promise<Response> { if (response.status >= 300 && fallback) { const fallbackKeys = fallback ? Object.keys(fallback) : []; // we split the URL using the `/`, and then check in the returned array we have the locale @@ -371,7 +373,12 @@ export function redirectToFallback({ } else { newPathname = context.url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`); } - return context.redirect(newPathname); + + if (fallbackType === 'rewrite') { + return await context.rewrite(newPathname); + } else { + return context.redirect(newPathname); + } } } return response; diff --git a/packages/astro/src/i18n/utils.ts b/packages/astro/src/i18n/utils.ts index 98a44a19c..5dc58908a 100644 --- a/packages/astro/src/i18n/utils.ts +++ b/packages/astro/src/i18n/utils.ts @@ -215,3 +215,12 @@ export function toRoutingStrategy( return strategy; } + +export function toFallbackType( + routing: NonNullable<AstroConfig['i18n']>['routing'], +): 'redirect' | 'rewrite' { + if (routing === 'manual') { + return 'rewrite'; + } + return routing.fallbackType; +} diff --git a/packages/astro/src/integrations/hooks.ts b/packages/astro/src/integrations/hooks.ts index 1dc681db6..8f3e62b8c 100644 --- a/packages/astro/src/integrations/hooks.ts +++ b/packages/astro/src/integrations/hooks.ts @@ -119,7 +119,7 @@ export async function runHookConfigSetup({ fs = fsMod, }: { settings: AstroSettings; - command: 'dev' | 'build' | 'preview'; + command: 'dev' | 'build' | 'preview' | 'sync'; logger: Logger; isRestart?: boolean; fs?: typeof fsMod; diff --git a/packages/astro/src/prefetch/index.ts b/packages/astro/src/prefetch/index.ts index 177945f37..3eb8cd570 100644 --- a/packages/astro/src/prefetch/index.ts +++ b/packages/astro/src/prefetch/index.ts @@ -215,6 +215,9 @@ export interface PrefetchOptions { * @param opts Additional options for prefetching. */ export function prefetch(url: string, opts?: PrefetchOptions) { + // Remove url hash to avoid prefetching the same URL multiple times + url = url.replace(/#.*/, ''); + const ignoreSlowConnection = opts?.ignoreSlowConnection ?? false; if (!canPrefetchUrl(url, ignoreSlowConnection)) return; prefetchedUrls.add(url); diff --git a/packages/astro/src/runtime/client/dev-toolbar/toolbar.ts b/packages/astro/src/runtime/client/dev-toolbar/toolbar.ts index e24698d43..c089664da 100644 --- a/packages/astro/src/runtime/client/dev-toolbar/toolbar.ts +++ b/packages/astro/src/runtime/client/dev-toolbar/toolbar.ts @@ -3,7 +3,7 @@ import type { ResolvedDevToolbarApp as DevToolbarAppDefinition } from '../../../ import { type ToolbarAppEventTarget, serverHelpers } from './helpers.js'; import { settings } from './settings.js'; import { type Icon, getIconElement, isDefinedIcon } from './ui-library/icons.js'; -import { type Placement } from './ui-library/window.js'; +import type { Placement } from './ui-library/window.js'; export type DevToolbarApp = DevToolbarAppDefinition & { builtIn: boolean; diff --git a/packages/astro/src/runtime/client/idle.ts b/packages/astro/src/runtime/client/idle.ts index e32b1a42f..801e1c983 100644 --- a/packages/astro/src/runtime/client/idle.ts +++ b/packages/astro/src/runtime/client/idle.ts @@ -1,14 +1,22 @@ import type { ClientDirective } from '../../types/public/integrations.js'; -const idleDirective: ClientDirective = (load) => { +const idleDirective: ClientDirective = (load, options) => { const cb = async () => { const hydrate = await load(); await hydrate(); }; + + const rawOptions = + typeof options.value === 'object' ? (options.value as IdleRequestOptions) : undefined; + + const idleOptions: IdleRequestOptions = { + timeout: rawOptions?.timeout, + }; + if ('requestIdleCallback' in window) { - (window as any).requestIdleCallback(cb); + (window as any).requestIdleCallback(cb, idleOptions); } else { - setTimeout(cb, 200); + setTimeout(cb, idleOptions.timeout || 200); } }; diff --git a/packages/astro/src/transitions/swap-functions.ts b/packages/astro/src/transitions/swap-functions.ts index 4c8db82ee..e2d8557f5 100644 --- a/packages/astro/src/transitions/swap-functions.ts +++ b/packages/astro/src/transitions/swap-functions.ts @@ -133,6 +133,14 @@ const shouldCopyProps = (el: HTMLElement): boolean => { return persistProps == null || persistProps === 'false'; }; +export const swapFunctions = { + deselectScripts, + swapRootAttributes, + swapHeadElements, + swapBodyElement, + saveFocus, +}; + export const swap = (doc: Document) => { deselectScripts(doc); swapRootAttributes(doc); diff --git a/packages/astro/src/transitions/vite-plugin-transitions.ts b/packages/astro/src/transitions/vite-plugin-transitions.ts index 56f086a06..e8122cac4 100644 --- a/packages/astro/src/transitions/vite-plugin-transitions.ts +++ b/packages/astro/src/transitions/vite-plugin-transitions.ts @@ -42,6 +42,7 @@ export default function astroTransitions({ settings }: { settings: AstroSettings TRANSITION_BEFORE_SWAP, isTransitionBeforeSwapEvent, TransitionBeforeSwapEvent, TRANSITION_AFTER_SWAP, TRANSITION_PAGE_LOAD } from "astro/virtual-modules/transitions-events.js"; + export { swapFunctions } from "astro/virtual-modules/transitions-swap-functions.js"; `; } }, diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index b429104e4..9630313ec 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -1298,6 +1298,43 @@ export interface AstroUserConfig { redirectToDefaultLocale?: boolean; /** + * @docs + * @name i18n.routing.fallbackType + * @kind h4 + * @type {"redirect" | "rewrite"} + * @default `"redirect"` + * @version 4.15.0 + * @description + * + * When [`i18n.fallback`](#i18nfallback) is configured to avoid showing a 404 page for missing page routes, this option controls whether to [redirect](https://docs.astro.build/en/guides/routing/#redirects) to the fallback page, or to [rewrite](https://docs.astro.build/en/guides/routing/#rewrites) the fallback page's content in place. + * + * By default, Astro's i18n routing creates pages that redirect your visitors to a new destination based on your fallback configuration. The browser will refresh and show the destination address in the URL bar. + * + * When `i18n.routing.fallback: "rewrite"` is configured, Astro will create pages that render the contents of the fallback page on the original, requested URL. + * + * With the following configuration, if you have the file `src/pages/en/about.astro` but not `src/pages/fr/about.astro`, the `astro build` command will generate `dist/fr/about.html` with the same content as the `dist/en/index.html` page. + * Your site visitor will see the English version of the page at `https://example.com/fr/about/` and will not be redirected. + * + * ```js + * //astro.config.mjs + * export default defineConfig({ + * i18n: { + * defaultLocale: "en", + * locales: ["en", "fr"], + * routing: { + * prefixDefaultLocale: false, + * fallbackType: "rewrite", + * }, + * fallback: { + * fr: "en", + * } + * }, + * }) + * ``` + */ + fallbackType: 'redirect' | 'rewrite'; + + /** * @name i18n.routing.strategy * @type {"pathname"} * @default `"pathname"` @@ -1775,7 +1812,7 @@ export interface AstroUserConfig { * ``` * * :::note - * Loaders will not automatically [exclude files prefaced with an `_`](/en/guides/routing/#excluding-pages). Use a regular expression such as `pattern: '**\/[^_]*.md` in your loader to ignore these files. + * Loaders will not automatically [exclude files prefaced with an `_`](/en/guides/routing/#excluding-pages). Use a regular expression such as `pattern: '**\/[^_]*.md'` in your loader to ignore these files. * ::: * * #### Querying and rendering with the Content Layer API @@ -1807,7 +1844,7 @@ export interface AstroUserConfig { * * const post = await getEntry('blog', Astro.params.slug); * - * const { Content, headings } = await render(entry); + * const { Content, headings } = await render(post); * --- * * <Content /> diff --git a/packages/astro/src/virtual-modules/i18n.ts b/packages/astro/src/virtual-modules/i18n.ts index 927d479aa..8f85ae5f6 100644 --- a/packages/astro/src/virtual-modules/i18n.ts +++ b/packages/astro/src/virtual-modules/i18n.ts @@ -3,7 +3,7 @@ import { IncorrectStrategyForI18n } from '../core/errors/errors-data.js'; import { AstroError } from '../core/errors/index.js'; import * as I18nInternals from '../i18n/index.js'; import type { RedirectToFallback } from '../i18n/index.js'; -import { toRoutingStrategy } from '../i18n/utils.js'; +import { toFallbackType, toRoutingStrategy } from '../i18n/utils.js'; import type { I18nInternalConfig } from '../i18n/vite-plugin-i18n.js'; import type { MiddlewareHandler } from '../types/public/common.js'; import type { AstroConfig, ValidRedirectStatus } from '../types/public/config.js'; @@ -18,6 +18,7 @@ const { defaultLocale, locales, domains, fallback, routing } = i18n!; const base = import.meta.env.BASE_URL; let strategy = toRoutingStrategy(routing, domains); +let fallbackType = toFallbackType(routing); export type GetLocaleOptions = I18nInternals.GetLocaleOptions; @@ -264,6 +265,7 @@ if (i18n?.routing === 'manual') { strategy, domains, fallback, + fallbackType, }); } else { redirectToDefaultLocale = noop('redirectToDefaultLocale'); @@ -292,6 +294,7 @@ if (i18n?.routing === 'manual') { strategy, domains, fallback, + fallbackType, }); } else { notFound = noop('notFound'); @@ -314,7 +317,7 @@ if (i18n?.routing === 'manual') { * Allows to use the build-in fallback system of Astro * * @param {APIContext} context The context passed to the middleware - * @param {Response} response An optional `Response` in case you're handling a `Response` coming from the `next` function. + * @param {Promise<Response>} response An optional `Response` in case you're handling a `Response` coming from the `next` function. */ export let redirectToFallback: RedirectToFallback; @@ -328,6 +331,7 @@ if (i18n?.routing === 'manual') { strategy, domains, fallback, + fallbackType, }); } else { redirectToFallback = noop('useFallback'); @@ -371,11 +375,13 @@ export let middleware: (customOptions: NewAstroRoutingConfigWithoutManual) => Mi if (i18n?.routing === 'manual') { middleware = (customOptions: NewAstroRoutingConfigWithoutManual) => { strategy = toRoutingStrategy(customOptions, {}); + fallbackType = toFallbackType(customOptions); const manifest: SSRManifest['i18n'] = { ...i18n, fallback: undefined, strategy, domainLookupTable: {}, + fallbackType, }; return I18nInternals.createMiddleware(manifest, base, trailingSlash, format); }; diff --git a/packages/astro/src/virtual-modules/transitions-swap-functions.ts b/packages/astro/src/virtual-modules/transitions-swap-functions.ts new file mode 100644 index 000000000..5947533e3 --- /dev/null +++ b/packages/astro/src/virtual-modules/transitions-swap-functions.ts @@ -0,0 +1 @@ +export * from '../transitions/swap-functions.js'; diff --git a/packages/astro/src/vite-plugin-astro-server/pipeline.ts b/packages/astro/src/vite-plugin-astro-server/pipeline.ts index 63384f87b..b22a3653d 100644 --- a/packages/astro/src/vite-plugin-astro-server/pipeline.ts +++ b/packages/astro/src/vite-plugin-astro-server/pipeline.ts @@ -1,6 +1,6 @@ import { fileURLToPath } from 'node:url'; import { getInfoOutput } from '../cli/info/index.js'; -import { type HeadElements } from '../core/base-pipeline.js'; +import type { HeadElements, TryRewriteResult } from '../core/base-pipeline.js'; import { ASTRO_VERSION } from '../core/constants.js'; import { enhanceViteSSRError } from '../core/errors/dev/index.js'; import { AggregateError, CSSError, MarkdownError } from '../core/errors/index.js'; @@ -197,11 +197,11 @@ export class DevPipeline extends Pipeline { payload: RewritePayload, request: Request, _sourceRoute: RouteData, - ): Promise<[RouteData, ComponentInstance, URL]> { + ): Promise<TryRewriteResult> { if (!this.manifestData) { throw new Error('Missing manifest data. This is an internal error, please file an issue.'); } - const [foundRoute, finalUrl] = findRouteToRewrite({ + const { routeData, pathname, newUrl } = findRouteToRewrite({ payload, request, routes: this.manifestData?.routes, @@ -210,8 +210,8 @@ export class DevPipeline extends Pipeline { base: this.config.base, }); - const componentInstance = await this.getComponentByRoute(foundRoute); - return [foundRoute, componentInstance, finalUrl]; + const componentInstance = await this.getComponentByRoute(routeData); + return { newUrl, pathname, componentInstance, routeData }; } setManifestData(manifestData: ManifestData) { diff --git a/packages/astro/src/vite-plugin-astro-server/plugin.ts b/packages/astro/src/vite-plugin-astro-server/plugin.ts index 414034561..f1cfa16ba 100644 --- a/packages/astro/src/vite-plugin-astro-server/plugin.ts +++ b/packages/astro/src/vite-plugin-astro-server/plugin.ts @@ -11,7 +11,7 @@ import type { Logger } from '../core/logger/core.js'; import { createViteLoader } from '../core/module-loader/index.js'; import { injectDefaultRoutes } from '../core/routing/default.js'; import { createRouteManifest } from '../core/routing/index.js'; -import { toRoutingStrategy } from '../i18n/utils.js'; +import { toFallbackType, toRoutingStrategy } from '../i18n/utils.js'; import type { AstroSettings, ManifestData } from '../types/astro.js'; import { baseMiddleware } from './base.js'; import { createController } from './controller.js'; @@ -128,6 +128,7 @@ export function createDevelopmentManifest(settings: AstroSettings): SSRManifest defaultLocale: settings.config.i18n.defaultLocale, locales: settings.config.i18n.locales, domainLookupTable: {}, + fallbackType: toFallbackType(settings.config.i18n.routing), }; } diff --git a/packages/astro/src/vite-plugin-fileurl/index.ts b/packages/astro/src/vite-plugin-fileurl/index.ts index 4a14323a0..73132f3af 100644 --- a/packages/astro/src/vite-plugin-fileurl/index.ts +++ b/packages/astro/src/vite-plugin-fileurl/index.ts @@ -1,8 +1,9 @@ import type { Plugin as VitePlugin } from 'vite'; -export default function vitePluginFileURL({}): VitePlugin { +export default function vitePluginFileURL(): VitePlugin { return { name: 'astro:vite-plugin-file-url', + enforce: 'pre', resolveId(source, importer) { if (source.startsWith('file://')) { const rest = source.slice(7); diff --git a/packages/astro/src/vite-plugin-scanner/index.ts b/packages/astro/src/vite-plugin-scanner/index.ts index 2633743ae..5923377a4 100644 --- a/packages/astro/src/vite-plugin-scanner/index.ts +++ b/packages/astro/src/vite-plugin-scanner/index.ts @@ -2,7 +2,7 @@ import { extname } from 'node:path'; import { bold } from 'kleur/colors'; import type { Plugin as VitePlugin } from 'vite'; import { normalizePath } from 'vite'; -import { type Logger } from '../core/logger/core.js'; +import type { Logger } from '../core/logger/core.js'; import { isEndpoint, isPage, isServerLikeOutput } from '../core/util.js'; import { rootRelativePath } from '../core/viteUtils.js'; import { runHookRouteSetup } from '../integrations/hooks.js'; diff --git a/packages/astro/templates/actions.mjs b/packages/astro/templates/actions.mjs index 823699e15..3ff65cecf 100644 --- a/packages/astro/templates/actions.mjs +++ b/packages/astro/templates/actions.mjs @@ -93,7 +93,9 @@ async function handleAction(param, path, context) { body, headers, }); - if (rawResult.status === 204) return; + if (rawResult.status === 204) { + return deserializeActionResult({ type: 'empty', status: 204 }); + } return deserializeActionResult({ type: rawResult.ok ? 'data' : 'error', diff --git a/packages/astro/test/actions.test.js b/packages/astro/test/actions.test.js index 341e7c8d6..3c803972c 100644 --- a/packages/astro/test/actions.test.js +++ b/packages/astro/test/actions.test.js @@ -2,6 +2,8 @@ import assert from 'node:assert/strict'; import { after, before, describe, it } from 'node:test'; import * as cheerio from 'cheerio'; import * as devalue from 'devalue'; +import { serializeActionResult } from '../dist/actions/runtime/virtual/shared.js'; +import { REDIRECT_STATUS_CODES } from '../dist/core/constants.js'; import testAdapter from './test-adapter.js'; import { loadFixture } from './test-utils.js'; @@ -25,6 +27,28 @@ describe('Astro Actions', () => { await devServer.stop(); }); + it('Does not process middleware cookie for prerendered routes', async () => { + const cookie = new URLSearchParams(); + cookie.append( + '_astroActionPayload', + JSON.stringify({ + actionName: 'subscribe', + actionResult: serializeActionResult({ + data: { channel: 'bholmesdev', subscribeButtonState: 'smashed' }, + error: undefined, + }), + }), + ); + const res = await fixture.fetch('/subscribe-prerendered', { + headers: { + Cookie: cookie.toString(), + }, + }); + const html = await res.text(); + const $ = cheerio.load(html); + assert.equal($('body').text().trim(), 'No cookie found.'); + }); + it('Exposes subscribe action', async () => { const res = await fixture.fetch('/_actions/subscribe', { method: 'POST', @@ -217,6 +241,71 @@ describe('Astro Actions', () => { assert.ok($('#user')); }); + it('Supports effects on form input validators', async () => { + const formData = new FormData(); + formData.set('password', 'benisawesome'); + formData.set('confirmPassword', 'benisveryawesome'); + + const req = new Request('http://example.com/_actions/validatePassword', { + method: 'POST', + body: formData, + }); + + const res = await app.render(req); + + assert.equal(res.ok, false); + assert.equal(res.status, 400); + assert.equal(res.headers.get('Content-Type'), 'application/json'); + + const data = await res.json(); + assert.equal(data.type, 'AstroActionInputError'); + assert.equal(data.issues?.[0]?.message, 'Passwords do not match'); + }); + + it('Supports complex chained effects on form input validators', async () => { + const formData = new FormData(); + formData.set('currentPassword', 'benisboring'); + formData.set('newPassword', 'benisawesome'); + formData.set('confirmNewPassword', 'benisawesome'); + + const req = new Request('http://example.com/_actions/validatePasswordComplex', { + method: 'POST', + body: formData, + }); + + const res = await app.render(req); + + assert.equal(res.ok, true); + assert.equal(res.headers.get('Content-Type'), 'application/json+devalue'); + + const data = devalue.parse(await res.text()); + assert.equal(Object.keys(data).length, 2, 'More keys than expected'); + assert.deepEqual(data, { + currentPassword: 'benisboring', + newPassword: 'benisawesome', + }); + }); + + it('Supports input form data transforms', async () => { + const formData = new FormData(); + formData.set('name', 'ben'); + formData.set('age', '42'); + + const req = new Request('http://example.com/_actions/transformFormInput', { + method: 'POST', + body: formData, + }); + + const res = await app.render(req); + + assert.equal(res.ok, true); + assert.equal(res.headers.get('Content-Type'), 'application/json+devalue'); + + const data = devalue.parse(await res.text()); + assert.equal(data?.name, 'ben'); + assert.equal(data?.age, '42'); + }); + describe('legacy', () => { it('Response middleware fallback', async () => { const formData = new FormData(); @@ -348,8 +437,6 @@ describe('Astro Actions', () => { }); }); -const validRedirectStatuses = new Set([301, 302, 303, 304, 307, 308]); - /** * Follow an expected redirect response. * @@ -360,7 +447,7 @@ const validRedirectStatuses = new Set([301, 302, 303, 304, 307, 308]); async function followExpectedRedirect(req, app) { const redirect = await app.render(req, { addCookieHeader: true }); assert.ok( - validRedirectStatuses.has(redirect.status), + REDIRECT_STATUS_CODES.includes(redirect.status), `Expected redirect status, got ${redirect.status}`, ); diff --git a/packages/astro/test/fixtures/0-css/package.json b/packages/astro/test/fixtures/0-css/package.json index 394045795..782bddc06 100644 --- a/packages/astro/test/fixtures/0-css/package.json +++ b/packages/astro/test/fixtures/0-css/package.json @@ -9,7 +9,7 @@ "astro": "workspace:*", "react": "^18.3.1", "react-dom": "^18.3.1", - "svelte": "^4.2.18", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/test/fixtures/actions/src/actions/index.ts b/packages/astro/test/fixtures/actions/src/actions/index.ts index bc61ade3a..881656994 100644 --- a/packages/astro/test/fixtures/actions/src/actions/index.ts +++ b/packages/astro/test/fixtures/actions/src/actions/index.ts @@ -1,5 +1,10 @@ import { defineAction, ActionError, z } from 'astro:actions'; +const passwordSchema = z + .string() + .min(8, 'Password should be at least 8 chars length') + .max(128, 'Password length exceeded. Max 128 chars.'); + export const server = { subscribe: defineAction({ input: z.object({ channel: z.string() }), @@ -44,7 +49,56 @@ export const server = { accept: 'form', handler: async (_, { locals }) => { return locals.user; - } + }, + }), + validatePassword: defineAction({ + accept: 'form', + input: z + .object({ password: z.string(), confirmPassword: z.string() }) + .refine((data) => data.password === data.confirmPassword, { + message: 'Passwords do not match', + }), + handler: async ({ password }) => { + return password; + }, + }), + validatePasswordComplex: defineAction({ + accept: 'form', + input: z + .object({ + currentPassword: passwordSchema, + newPassword: passwordSchema, + confirmNewPassword: passwordSchema, + }) + .required() + .refine( + ({ newPassword, confirmNewPassword }) => newPassword === confirmNewPassword, + 'The new password confirmation does not match', + ) + .refine( + ({ currentPassword, newPassword }) => currentPassword !== newPassword, + 'The old password and the new password must not match', + ) + .transform((input) => ({ + currentPassword: input.currentPassword, + newPassword: input.newPassword, + })) + .pipe( + z.object({ + currentPassword: passwordSchema, + newPassword: passwordSchema, + }), + ), + handler: async (data) => { + return data; + }, + }), + transformFormInput: defineAction({ + accept: 'form', + input: z.instanceof(FormData).transform((formData) => Object.fromEntries(formData.entries())), + handler: async (data) => { + return data; + }, }), getUserOrThrow: defineAction({ accept: 'form', @@ -57,22 +111,22 @@ export const server = { }); } return locals.user; - } + }, }), fireAndForget: defineAction({ handler: async () => { return; - } + }, }), zero: defineAction({ handler: async () => { return 0; - } + }, }), false: defineAction({ handler: async () => { return false; - } + }, }), complexValues: defineAction({ handler: async () => { @@ -80,7 +134,7 @@ export const server = { date: new Date(), set: new Set(), url: new URL('https://example.com'), - } - } - }) + }; + }, + }), }; diff --git a/packages/astro/test/fixtures/actions/src/pages/subscribe-prerendered.astro b/packages/astro/test/fixtures/actions/src/pages/subscribe-prerendered.astro new file mode 100644 index 000000000..3d3b37772 --- /dev/null +++ b/packages/astro/test/fixtures/actions/src/pages/subscribe-prerendered.astro @@ -0,0 +1,17 @@ +--- +import { actions } from 'astro:actions'; + +export const prerender = true; + +const result = Astro.getActionResult(actions.subscribe); +--- + +<!doctype html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Document</title> + </head> + <body>{result?.data?.subscribeButtonState ?? 'No cookie found.'}</body> +</html> diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json index 6a6cb3491..0ae8cb82c 100644 --- a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/alias-tsconfig/package.json b/packages/astro/test/fixtures/alias-tsconfig/package.json index 56047eede..833a0a068 100644 --- a/packages/astro/test/fixtures/alias-tsconfig/package.json +++ b/packages/astro/test/fixtures/alias-tsconfig/package.json @@ -6,6 +6,6 @@ "@astrojs/svelte": "workspace:*", "@test/namespace-package": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/alias/package.json b/packages/astro/test/fixtures/alias/package.json index 06d4c32ac..bd0599c5d 100644 --- a/packages/astro/test/fixtures/alias/package.json +++ b/packages/astro/test/fixtures/alias/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/astro-children/package.json b/packages/astro/test/fixtures/astro-children/package.json index d2e7a6d5e..038487d67 100644 --- a/packages/astro/test/fixtures/astro-children/package.json +++ b/packages/astro/test/fixtures/astro-children/package.json @@ -8,7 +8,7 @@ "@astrojs/vue": "workspace:*", "astro": "workspace:*", "preact": "^10.23.2", - "svelte": "^4.2.18", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/test/fixtures/astro-client-only/package.json b/packages/astro/test/fixtures/astro-client-only/package.json index 02eae8101..e6f71f353 100644 --- a/packages/astro/test/fixtures/astro-client-only/package.json +++ b/packages/astro/test/fixtures/astro-client-only/package.json @@ -9,6 +9,6 @@ "astro": "workspace:*", "react": "^18.3.1", "react-dom": "^18.3.1", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/astro-dynamic/package.json b/packages/astro/test/fixtures/astro-dynamic/package.json index 30c80157b..3d606041a 100644 --- a/packages/astro/test/fixtures/astro-dynamic/package.json +++ b/packages/astro/test/fixtures/astro-dynamic/package.json @@ -8,6 +8,6 @@ "astro": "workspace:*", "react": "^18.3.1", "react-dom": "^18.3.1", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/astro-slots-nested/package.json b/packages/astro/test/fixtures/astro-slots-nested/package.json index 229bd2560..4f3ed29e0 100644 --- a/packages/astro/test/fixtures/astro-slots-nested/package.json +++ b/packages/astro/test/fixtures/astro-slots-nested/package.json @@ -12,8 +12,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/test/fixtures/component-library/package.json b/packages/astro/test/fixtures/component-library/package.json index a8b89e9ee..96f5cecac 100644 --- a/packages/astro/test/fixtures/component-library/package.json +++ b/packages/astro/test/fixtures/component-library/package.json @@ -11,6 +11,6 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/css-dangling-references/package.json b/packages/astro/test/fixtures/css-dangling-references/package.json index 2b9a90cb6..be0392db0 100644 --- a/packages/astro/test/fixtures/css-dangling-references/package.json +++ b/packages/astro/test/fixtures/css-dangling-references/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } }
\ No newline at end of file diff --git a/packages/astro/test/fixtures/error-bad-js/src/env.d.ts b/packages/astro/test/fixtures/error-bad-js/src/env.d.ts deleted file mode 100644 index f964fe0cf..000000000 --- a/packages/astro/test/fixtures/error-bad-js/src/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// <reference types="astro/client" /> diff --git a/packages/astro/test/fixtures/error-build-location/src/env.d.ts b/packages/astro/test/fixtures/error-build-location/src/env.d.ts deleted file mode 100644 index f964fe0cf..000000000 --- a/packages/astro/test/fixtures/error-build-location/src/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// <reference types="astro/client" /> diff --git a/packages/astro/test/fixtures/error-non-error/src/env.d.ts b/packages/astro/test/fixtures/error-non-error/src/env.d.ts deleted file mode 100644 index f964fe0cf..000000000 --- a/packages/astro/test/fixtures/error-non-error/src/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// <reference types="astro/client" /> diff --git a/packages/astro/test/fixtures/fetch/package.json b/packages/astro/test/fixtures/fetch/package.json index 52f60a20f..97aa25a78 100644 --- a/packages/astro/test/fixtures/fetch/package.json +++ b/packages/astro/test/fixtures/fetch/package.json @@ -8,7 +8,7 @@ "@astrojs/vue": "workspace:*", "astro": "workspace:*", "preact": "^10.23.2", - "svelte": "^4.2.18", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/test/fixtures/jsx/package.json b/packages/astro/test/fixtures/jsx/package.json index 2e45e6575..6d32dffe4 100644 --- a/packages/astro/test/fixtures/jsx/package.json +++ b/packages/astro/test/fixtures/jsx/package.json @@ -15,8 +15,8 @@ "preact": "^10.23.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/test/fixtures/large-array/package.json b/packages/astro/test/fixtures/large-array/package.json index 9f1f25828..0bf422b67 100644 --- a/packages/astro/test/fixtures/large-array/package.json +++ b/packages/astro/test/fixtures/large-array/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/solid-js": "workspace:*", "astro": "workspace:*", - "solid-js": "^1.8.21" + "solid-js": "^1.8.22" } } diff --git a/packages/astro/test/fixtures/postcss/package.json b/packages/astro/test/fixtures/postcss/package.json index 7ea4f8378..fad256924 100644 --- a/packages/astro/test/fixtures/postcss/package.json +++ b/packages/astro/test/fixtures/postcss/package.json @@ -9,8 +9,8 @@ "astro": "workspace:*", "autoprefixer": "^10.4.20", "postcss": "^8.4.41", - "solid-js": "^1.8.21", - "svelte": "^4.2.18", + "solid-js": "^1.8.22", + "svelte": "^4.2.19", "vue": "^3.4.38" }, "devDependencies": { diff --git a/packages/astro/test/fixtures/preact-component/src/components/SignalsInArray.jsx b/packages/astro/test/fixtures/preact-component/src/components/SignalsInArray.jsx new file mode 100644 index 000000000..69940f730 --- /dev/null +++ b/packages/astro/test/fixtures/preact-component/src/components/SignalsInArray.jsx @@ -0,0 +1,8 @@ +import { h } from 'preact'; + +export default ({ signalsArray }) => { + return <div class="preact-signal-array"> + <h1>{signalsArray[0]} {signalsArray[3]}</h1> + <p>{signalsArray[1].value}-{signalsArray[2].value}-{signalsArray[4].value}</p> + </div> +} diff --git a/packages/astro/test/fixtures/preact-component/src/components/SignalsInObject.jsx b/packages/astro/test/fixtures/preact-component/src/components/SignalsInObject.jsx new file mode 100644 index 000000000..6187ce8c5 --- /dev/null +++ b/packages/astro/test/fixtures/preact-component/src/components/SignalsInObject.jsx @@ -0,0 +1,8 @@ +import { h } from 'preact'; + +export default ({ signalsObject }) => { + return <div class="preact-signal-object"> + <h1>{signalsObject.title}</h1> + <p>{signalsObject.counter.value}</p> + </div> +} diff --git a/packages/astro/test/fixtures/preact-component/src/pages/signals.astro b/packages/astro/test/fixtures/preact-component/src/pages/signals.astro index b68fde36d..37b43a73c 100644 --- a/packages/astro/test/fixtures/preact-component/src/pages/signals.astro +++ b/packages/astro/test/fixtures/preact-component/src/pages/signals.astro @@ -1,7 +1,10 @@ --- import { signal } from '@preact/signals'; import Signals from '../components/Signals'; +import SignalsInArray from '../components/SignalsInArray'; +import SignalsInObject from '../components/SignalsInObject'; const count = signal(1); +const secondCount = signal(2); --- <html> <head> @@ -10,5 +13,7 @@ const count = signal(1); <body> <Signals client:load count={count} /> <Signals client:load count={count} /> + <SignalsInArray client:load signalsArray={["I'm not a signal", count, count, 12345, secondCount]} /> + <SignalsInObject client:load signalsObject={{title:'I am a title', counter: count}} /> </body> </html> diff --git a/packages/astro/test/fixtures/react-and-solid/package.json b/packages/astro/test/fixtures/react-and-solid/package.json index dbb45a68f..5df316b51 100644 --- a/packages/astro/test/fixtures/react-and-solid/package.json +++ b/packages/astro/test/fixtures/react-and-solid/package.json @@ -7,6 +7,6 @@ "astro": "workspace:*", "react": "^18.3.1", "react-dom": "^18.3.1", - "solid-js": "^1.8.21" + "solid-js": "^1.8.22" } } diff --git a/packages/astro/test/fixtures/rewrite-server/src/pages/[slug]/title.astro b/packages/astro/test/fixtures/rewrite-server/src/pages/[slug]/title.astro index d468d103b..bbc1a2d9e 100644 --- a/packages/astro/test/fixtures/rewrite-server/src/pages/[slug]/title.astro +++ b/packages/astro/test/fixtures/rewrite-server/src/pages/[slug]/title.astro @@ -1,6 +1,5 @@ --- const { slug } = Astro.params; -console.log("is it here???", Astro.params) export const prerender = false; --- <html> diff --git a/packages/astro/test/fixtures/rewrite-trailing-slash-never/src/pages/foo.astro b/packages/astro/test/fixtures/rewrite-trailing-slash-never/src/pages/foo.astro index 70ce07395..f7e38bbc5 100644 --- a/packages/astro/test/fixtures/rewrite-trailing-slash-never/src/pages/foo.astro +++ b/packages/astro/test/fixtures/rewrite-trailing-slash-never/src/pages/foo.astro @@ -1,3 +1,3 @@ --- -return Astro.rewrite("/") +return Astro.rewrite("/base") --- diff --git a/packages/astro/test/fixtures/server-islands/hybrid/package.json b/packages/astro/test/fixtures/server-islands/hybrid/package.json index fdb447b0e..03e184e63 100644 --- a/packages/astro/test/fixtures/server-islands/hybrid/package.json +++ b/packages/astro/test/fixtures/server-islands/hybrid/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/server-islands/ssr/package.json b/packages/astro/test/fixtures/server-islands/ssr/package.json index fa6e000dd..16e044fe3 100644 --- a/packages/astro/test/fixtures/server-islands/ssr/package.json +++ b/packages/astro/test/fixtures/server-islands/ssr/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/slots-solid/package.json b/packages/astro/test/fixtures/slots-solid/package.json index 55d2cfa32..59ebea174 100644 --- a/packages/astro/test/fixtures/slots-solid/package.json +++ b/packages/astro/test/fixtures/slots-solid/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/solid-js": "workspace:*", "astro": "workspace:*", - "solid-js": "^1.8.21" + "solid-js": "^1.8.22" } } diff --git a/packages/astro/test/fixtures/slots-svelte/package.json b/packages/astro/test/fixtures/slots-svelte/package.json index 94d15cad2..ddfa80d33 100644 --- a/packages/astro/test/fixtures/slots-svelte/package.json +++ b/packages/astro/test/fixtures/slots-svelte/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/solid-component/deps/solid-jsx-component/package.json b/packages/astro/test/fixtures/solid-component/deps/solid-jsx-component/package.json index 32042224f..976ba6604 100644 --- a/packages/astro/test/fixtures/solid-component/deps/solid-jsx-component/package.json +++ b/packages/astro/test/fixtures/solid-component/deps/solid-jsx-component/package.json @@ -10,6 +10,6 @@ } }, "dependencies": { - "solid-js": "^1.8.21" + "solid-js": "^1.8.22" } } diff --git a/packages/astro/test/fixtures/solid-component/package.json b/packages/astro/test/fixtures/solid-component/package.json index f1f87f2b2..2dc56f6cc 100644 --- a/packages/astro/test/fixtures/solid-component/package.json +++ b/packages/astro/test/fixtures/solid-component/package.json @@ -7,6 +7,6 @@ "@solidjs/router": "^0.14.3", "@test/solid-jsx-component": "file:./deps/solid-jsx-component", "astro": "workspace:*", - "solid-js": "^1.8.21" + "solid-js": "^1.8.22" } } diff --git a/packages/astro/test/fixtures/ssr-prerender-chunks/package.json b/packages/astro/test/fixtures/ssr-prerender-chunks/package.json index 8c8adac13..c386358b8 100644 --- a/packages/astro/test/fixtures/ssr-prerender-chunks/package.json +++ b/packages/astro/test/fixtures/ssr-prerender-chunks/package.json @@ -5,7 +5,7 @@ "dependencies": { "@astrojs/react": "workspace:*", "@test/ssr-prerender-chunks-test-adapter": "link:./deps/test-adapter", - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "astro": "workspace:*", "react": "^18.3.1", diff --git a/packages/astro/test/fixtures/svelte-component/package.json b/packages/astro/test/fixtures/svelte-component/package.json index 42b4ca310..830d980b7 100644 --- a/packages/astro/test/fixtures/svelte-component/package.json +++ b/packages/astro/test/fixtures/svelte-component/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18" + "svelte": "^4.2.19" } } diff --git a/packages/astro/test/fixtures/vue-with-multi-renderer/package.json b/packages/astro/test/fixtures/vue-with-multi-renderer/package.json index 65be000bf..f91b6a9c3 100644 --- a/packages/astro/test/fixtures/vue-with-multi-renderer/package.json +++ b/packages/astro/test/fixtures/vue-with-multi-renderer/package.json @@ -6,7 +6,7 @@ "@astrojs/svelte": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "svelte": "^4.2.18", + "svelte": "^4.2.19", "vue": "^3.4.38" } } diff --git a/packages/astro/test/i18n-routing.test.js b/packages/astro/test/i18n-routing.test.js index df8083b81..ddb31762f 100644 --- a/packages/astro/test/i18n-routing.test.js +++ b/packages/astro/test/i18n-routing.test.js @@ -1929,3 +1929,106 @@ describe('SSR fallback from missing locale index to default locale index', () => assert.equal(response.headers.get('location'), '/'); }); }); + +describe('Fallback rewrite dev server', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + let devServer; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing-fallback/', + i18n: { + defaultLocale: 'en', + locales: ['en', 'fr'], + routing: { + prefixDefaultLocale: false, + }, + fallback: { + fr: 'en', + }, + fallbackType: 'rewrite', + }, + }); + devServer = await fixture.startDevServer(); + }); + after(async () => { + devServer.stop(); + }); + + it('should correctly rewrite to en', async () => { + const html = await fixture.fetch('/fr').then((res) => res.text()); + assert.match(html, /Hello/); + // assert.fail() + }); +}); + +describe('Fallback rewrite SSG', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing-fallback/', + i18n: { + defaultLocale: 'en', + locales: ['en', 'fr'], + routing: { + prefixDefaultLocale: false, + fallbackType: 'rewrite', + }, + fallback: { + fr: 'en', + }, + }, + }); + await fixture.build(); + // app = await fixture.loadTestAdapterApp(); + }); + + it('should correctly rewrite to en', async () => { + const html = await fixture.readFile('/fr/index.html'); + assert.match(html, /Hello/); + // assert.fail() + }); +}); + +describe('Fallback rewrite SSR', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + let app; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/i18n-routing-fallback/', + output: 'server', + outDir: './dist/i18n-routing-fallback', + build: { + client: './dist/i18n-routing-fallback/client', + server: './dist/i18n-routing-fallback/server', + }, + adapter: testAdapter(), + i18n: { + defaultLocale: 'en', + locales: ['en', 'fr'], + routing: { + prefixDefaultLocale: false, + fallbackType: 'rewrite', + }, + fallback: { + fr: 'en', + }, + }, + }); + await fixture.build(); + app = await fixture.loadTestAdapterApp(); + }); + + it('should correctly rewrite to en', async () => { + const request = new Request('http://example.com/fr'); + const response = await app.render(request); + assert.equal(response.status, 200); + const html = await response.text(); + assert.match(html, /Hello/); + }); +}); diff --git a/packages/astro/test/preact-component.test.js b/packages/astro/test/preact-component.test.js index e8c89d5bf..f5b5c7233 100644 --- a/packages/astro/test/preact-component.test.js +++ b/packages/astro/test/preact-component.test.js @@ -100,4 +100,44 @@ describe('Preact component', () => { assert.notEqual(sigs1.count, undefined); assert.equal(sigs1.count, sigs2.count); }); + + it('Can use signals in array', async () => { + const html = await fixture.readFile('/signals/index.html'); + const $ = cheerio.load(html); + const element = $('.preact-signal-array'); + assert.equal(element.length, 1); + + const sigs1Raw = $($('astro-island')[2]).attr('data-preact-signals'); + + const sigs1 = JSON.parse(sigs1Raw); + + assert.deepEqual(sigs1, { + signalsArray: [ + ['p0', 1], + ['p0', 2], + ['p1', 4], + ], + }); + + assert.equal(element.find('h1').text(), "I'm not a signal 12345"); + assert.equal(element.find('p').text(), '1-1-2'); + }); + + it('Can use signals in object', async () => { + const html = await fixture.readFile('/signals/index.html'); + const $ = cheerio.load(html); + const element = $('.preact-signal-object'); + assert.equal(element.length, 1); + + const sigs1Raw = $($('astro-island')[3]).attr('data-preact-signals'); + + const sigs1 = JSON.parse(sigs1Raw); + + assert.deepEqual(sigs1, { + signalsObject: [['p0', 'counter']], + }); + + assert.equal(element.find('h1').text(), 'I am a title'); + assert.equal(element.find('p').text(), '1'); + }); }); diff --git a/packages/astro/test/rewrite.test.js b/packages/astro/test/rewrite.test.js index 7839e7d33..10d7c70d2 100644 --- a/packages/astro/test/rewrite.test.js +++ b/packages/astro/test/rewrite.test.js @@ -104,7 +104,7 @@ describe('Dev rewrite, trailing slash -> never, with base', () => { }); it('should rewrite to the homepage', async () => { - const html = await fixture.fetch('/foo').then((res) => res.text()); + const html = await fixture.fetch('/base/foo').then((res) => res.text()); const $ = cheerioLoad(html); assert.equal($('h1').text(), 'Index'); diff --git a/packages/astro/test/units/actions/form-data-to-object.test.js b/packages/astro/test/units/actions/form-data-to-object.test.js index 136909305..e9f52a13f 100644 --- a/packages/astro/test/units/actions/form-data-to-object.test.js +++ b/packages/astro/test/units/actions/form-data-to-object.test.js @@ -192,4 +192,22 @@ describe('formDataToObject', () => { assert.equal(res.files instanceof Array, true); assert.deepEqual(res.files, [file1, file2]); }); + + it('should allow object passthrough when chaining .passthrough() on root object', () => { + const formData = new FormData(); + formData.set('expected', '42'); + formData.set('unexpected', '42'); + + const input = z + .object({ + expected: z.number(), + }) + .passthrough(); + + const res = formDataToObject(formData, input); + assert.deepEqual(res, { + expected: 42, + unexpected: '42', + }); + }); }); diff --git a/packages/create-astro/CHANGELOG.md b/packages/create-astro/CHANGELOG.md index e658c7850..ebde2e51f 100644 --- a/packages/create-astro/CHANGELOG.md +++ b/packages/create-astro/CHANGELOG.md @@ -1,6 +1,6 @@ # create-astro -## 4.8.4-alpha.0 +## 4.8.4 ### Patch Changes diff --git a/packages/db/CHANGELOG.md b/packages/db/CHANGELOG.md index dc8d6ac8a..87c2df6e1 100644 --- a/packages/db/CHANGELOG.md +++ b/packages/db/CHANGELOG.md @@ -1,6 +1,6 @@ # @astrojs/db -## 0.13.2-alpha.0 +## 0.13.2 ### Patch Changes diff --git a/packages/db/package.json b/packages/db/package.json index 7ed5c756d..9751d18f5 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -70,7 +70,7 @@ }, "dependencies": { "@astrojs/studio": "workspace:*", - "@libsql/client": "^0.9.0", + "@libsql/client": "^0.10.0", "async-listen": "^3.0.1", "deep-diff": "^1.0.2", "drizzle-orm": "^0.31.2", @@ -78,7 +78,7 @@ "kleur": "^4.1.5", "nanoid": "^5.0.7", "open": "^10.1.0", - "ora": "^8.0.1", + "ora": "^8.1.0", "prompts": "^2.4.2", "strip-ansi": "^7.1.0", "yargs-parser": "^21.1.1", @@ -92,6 +92,6 @@ "astro-scripts": "workspace:*", "cheerio": "1.0.0", "typescript": "^5.5.4", - "vite": "^5.4.1" + "vite": "^5.4.2" } } diff --git a/packages/db/src/core/cli/commands/link/index.ts b/packages/db/src/core/cli/commands/link/index.ts index d39b8c09a..525dacce0 100644 --- a/packages/db/src/core/cli/commands/link/index.ts +++ b/packages/db/src/core/cli/commands/link/index.ts @@ -12,7 +12,7 @@ import { bgRed, cyan } from 'kleur/colors'; import ora from 'ora'; import prompts from 'prompts'; import { safeFetch } from '../../../../runtime/utils.js'; -import { type Result } from '../../../utils.js'; +import type { Result } from '../../../utils.js'; export async function cmd() { const sessionToken = await getSessionIdFromFile(); diff --git a/packages/db/src/core/cli/commands/push/index.ts b/packages/db/src/core/cli/commands/push/index.ts index ecd101ece..0efa7ebcb 100644 --- a/packages/db/src/core/cli/commands/push/index.ts +++ b/packages/db/src/core/cli/commands/push/index.ts @@ -1,11 +1,13 @@ import { getManagedAppTokenOrExit } from '@astrojs/studio'; import type { AstroConfig } from 'astro'; +import { sql } from 'drizzle-orm'; import prompts from 'prompts'; import type { Arguments } from 'yargs-parser'; +import { createRemoteDatabaseClient } from '../../../../runtime/index.js'; import { safeFetch } from '../../../../runtime/utils.js'; import { MIGRATION_VERSION } from '../../../consts.js'; -import { type DBConfig, type DBSnapshot } from '../../../types.js'; -import { type Result, getRemoteDatabaseUrl } from '../../../utils.js'; +import type { DBConfig, DBSnapshot } from '../../../types.js'; +import { type Result, getRemoteDatabaseInfo } from '../../../utils.js'; import { createCurrentSnapshot, createEmptySnapshot, @@ -87,7 +89,7 @@ async function pushSchema({ isDryRun: boolean; currentSnapshot: DBSnapshot; }) { - const requestBody = { + const requestBody: RequestBody = { snapshot: currentSnapshot, sql: statements, version: MIGRATION_VERSION, @@ -96,7 +98,47 @@ async function pushSchema({ console.info('[DRY RUN] Batch query:', JSON.stringify(requestBody, null, 2)); return new Response(null, { status: 200 }); } - const url = new URL('/db/push', getRemoteDatabaseUrl()); + + const dbInfo = getRemoteDatabaseInfo(); + + return dbInfo.type === 'studio' + ? pushToStudio(requestBody, appToken, dbInfo.url) + : pushToDb(requestBody, appToken, dbInfo.url); +} + +type RequestBody = { + snapshot: DBSnapshot; + sql: string[]; + version: string; +}; + +async function pushToDb(requestBody: RequestBody, appToken: string, remoteUrl: string) { + const client = createRemoteDatabaseClient({ + dbType: 'libsql', + appToken, + remoteUrl, + }); + + await client.run(sql`create table if not exists _astro_db_snapshot ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + version TEXT, + snapshot BLOB + );`); + + await client.transaction(async (tx) => { + for (const stmt of requestBody.sql) { + await tx.run(sql.raw(stmt)); + } + + await tx.run(sql`insert into _astro_db_snapshot (version, snapshot) values ( + ${requestBody.version}, + ${JSON.stringify(requestBody.snapshot)} + )`); + }); +} + +async function pushToStudio(requestBody: RequestBody, appToken: string, remoteUrl: string) { + const url = new URL('/db/push', remoteUrl); const response = await safeFetch( url, { diff --git a/packages/db/src/core/cli/commands/shell/index.ts b/packages/db/src/core/cli/commands/shell/index.ts index e0a1a6086..0b5c2c2f0 100644 --- a/packages/db/src/core/cli/commands/shell/index.ts +++ b/packages/db/src/core/cli/commands/shell/index.ts @@ -10,7 +10,7 @@ import { normalizeDatabaseUrl } from '../../../../runtime/index.js'; import { DB_PATH } from '../../../consts.js'; import { SHELL_QUERY_MISSING_ERROR } from '../../../errors.js'; import type { DBConfigInput } from '../../../types.js'; -import { getAstroEnv, getRemoteDatabaseUrl } from '../../../utils.js'; +import { getAstroEnv, getRemoteDatabaseInfo } from '../../../utils.js'; export async function cmd({ flags, @@ -25,9 +25,14 @@ export async function cmd({ console.error(SHELL_QUERY_MISSING_ERROR); process.exit(1); } + const dbInfo = getRemoteDatabaseInfo(); if (flags.remote) { const appToken = await getManagedAppTokenOrExit(flags.token); - const db = createRemoteDatabaseClient(appToken.token, getRemoteDatabaseUrl()); + const db = createRemoteDatabaseClient({ + dbType: dbInfo.type, + remoteUrl: dbInfo.url, + appToken: appToken.token, + }); const result = await db.run(sql.raw(query)); await appToken.destroy(); console.log(result); @@ -37,7 +42,7 @@ export async function cmd({ ASTRO_DATABASE_FILE, new URL(DB_PATH, astroConfig.root).href, ); - const db = createLocalDatabaseClient({ dbUrl }); + const db = createLocalDatabaseClient({ dbUrl, enableTransations: dbInfo.type === 'libsql' }); const result = await db.run(sql.raw(query)); console.log(result); } diff --git a/packages/db/src/core/cli/migration-queries.ts b/packages/db/src/core/cli/migration-queries.ts index 894c1d66f..5c4a23557 100644 --- a/packages/db/src/core/cli/migration-queries.ts +++ b/packages/db/src/core/cli/migration-queries.ts @@ -1,9 +1,11 @@ import deepDiff from 'deep-diff'; +import { sql } from 'drizzle-orm'; import { SQLiteAsyncDialect } from 'drizzle-orm/sqlite-core'; import * as color from 'kleur/colors'; import { customAlphabet } from 'nanoid'; import stripAnsi from 'strip-ansi'; import { hasPrimaryKey } from '../../runtime/index.js'; +import { createRemoteDatabaseClient } from '../../runtime/index.js'; import { isSerializedSQL } from '../../runtime/types.js'; import { safeFetch } from '../../runtime/utils.js'; import { MIGRATION_VERSION } from '../consts.js'; @@ -18,22 +20,22 @@ import { schemaTypeToSqlType, } from '../queries.js'; import { columnSchema } from '../schemas.js'; -import { - type BooleanColumn, - type ColumnType, - type DBColumn, - type DBColumns, - type DBConfig, - type DBSnapshot, - type DateColumn, - type JsonColumn, - type NumberColumn, - type ResolvedDBTable, - type ResolvedDBTables, - type ResolvedIndexes, - type TextColumn, +import type { + BooleanColumn, + ColumnType, + DBColumn, + DBColumns, + DBConfig, + DBSnapshot, + DateColumn, + JsonColumn, + NumberColumn, + ResolvedDBTable, + ResolvedDBTables, + ResolvedIndexes, + TextColumn, } from '../types.js'; -import { type Result, getRemoteDatabaseUrl } from '../utils.js'; +import { type Result, getRemoteDatabaseInfo } from '../utils.js'; const sqlite = new SQLiteAsyncDialect(); const genTempTableName = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10); @@ -422,12 +424,49 @@ function hasRuntimeDefault(column: DBColumn): column is DBColumnWithDefault { return !!(column.schema.default && isSerializedSQL(column.schema.default)); } -export async function getProductionCurrentSnapshot({ - appToken, -}: { +export function getProductionCurrentSnapshot(options: { appToken: string; }): Promise<DBSnapshot | undefined> { - const url = new URL('/db/schema', getRemoteDatabaseUrl()); + const dbInfo = getRemoteDatabaseInfo(); + + return dbInfo.type === 'studio' + ? getStudioCurrentSnapshot(options.appToken, dbInfo.url) + : getDbCurrentSnapshot(options.appToken, dbInfo.url); +} + +async function getDbCurrentSnapshot( + appToken: string, + remoteUrl: string, +): Promise<DBSnapshot | undefined> { + const client = createRemoteDatabaseClient({ + dbType: 'libsql', + appToken, + remoteUrl, + }); + + try { + const res = await client.get<{ snapshot: string }>( + // Latest snapshot + sql`select snapshot from _astro_db_snapshot order by id desc limit 1;`, + ); + + return JSON.parse(res.snapshot); + } catch (error: any) { + if (error.code === 'SQLITE_UNKNOWN') { + // If the schema was never pushed to the database yet the table won't exist. + // Treat a missing snapshot table as an empty table. + return; + } + + throw error; + } +} + +async function getStudioCurrentSnapshot( + appToken: string, + remoteUrl: string, +): Promise<DBSnapshot | undefined> { + const url = new URL('/db/schema', remoteUrl); const response = await safeFetch( url, diff --git a/packages/db/src/core/integration/file-url.ts b/packages/db/src/core/integration/file-url.ts index 72e49004e..76ce70cb9 100644 --- a/packages/db/src/core/integration/file-url.ts +++ b/packages/db/src/core/integration/file-url.ts @@ -12,7 +12,7 @@ async function copyFile(toDir: URL, fromUrl: URL, toUrl: URL) { export function fileURLIntegration(): AstroIntegration { const fileNames: string[] = []; - function createVitePlugin(command: 'build' | 'preview' | 'dev'): VitePlugin { + function createVitePlugin(command: 'build' | 'preview' | 'dev' | 'sync'): VitePlugin { let referenceIds: string[] = []; return { name: '@astrojs/db/file-url', diff --git a/packages/db/src/core/integration/index.ts b/packages/db/src/core/integration/index.ts index de8eb6169..263fa250a 100644 --- a/packages/db/src/core/integration/index.ts +++ b/packages/db/src/core/integration/index.ts @@ -58,7 +58,7 @@ function astroDBIntegration(): AstroIntegration { inProgress: false, }; - let command: 'dev' | 'build' | 'preview'; + let command: 'dev' | 'build' | 'preview' | 'sync'; let output: AstroConfig['output'] = 'server'; return { name: 'astro:db', diff --git a/packages/db/src/core/integration/vite-plugin-db.ts b/packages/db/src/core/integration/vite-plugin-db.ts index 05cfa3ef0..c00a99f3b 100644 --- a/packages/db/src/core/integration/vite-plugin-db.ts +++ b/packages/db/src/core/integration/vite-plugin-db.ts @@ -9,7 +9,12 @@ import { DB_PATH, RUNTIME_IMPORT, RUNTIME_VIRTUAL_IMPORT, VIRTUAL_MODULE_ID } fr import { getResolvedFileUrl } from '../load-file.js'; import { SEED_DEV_FILE_NAME, getCreateIndexQueries, getCreateTableQuery } from '../queries.js'; import type { DBTables } from '../types.js'; -import { type VitePlugin, getAstroEnv, getDbDirectoryUrl, getRemoteDatabaseUrl } from '../utils.js'; +import { + type VitePlugin, + getAstroEnv, + getDbDirectoryUrl, + getRemoteDatabaseInfo, +} from '../utils.js'; export const resolved = { module: '\0' + VIRTUAL_MODULE_ID, @@ -119,12 +124,13 @@ export function getLocalVirtualModContents({ tables: DBTables; root: URL; }) { + const dbInfo = getRemoteDatabaseInfo(); const dbUrl = new URL(DB_PATH, root); return ` import { asDrizzleTable, createLocalDatabaseClient, normalizeDatabaseUrl } from ${RUNTIME_IMPORT}; const dbUrl = normalizeDatabaseUrl(import.meta.env.ASTRO_DATABASE_FILE, ${JSON.stringify(dbUrl)}); -export const db = createLocalDatabaseClient({ dbUrl }); +export const db = createLocalDatabaseClient({ dbUrl, enableTransactions: ${dbInfo.url === 'libsql'} }); export * from ${RUNTIME_VIRTUAL_IMPORT}; @@ -142,14 +148,17 @@ export function getStudioVirtualModContents({ isBuild: boolean; output: AstroConfig['output']; }) { + const dbInfo = getRemoteDatabaseInfo(); + function appTokenArg() { if (isBuild) { + const envPrefix = dbInfo.type === 'studio' ? 'ASTRO_STUDIO' : 'ASTRO_DB'; if (output === 'server') { // In production build, always read the runtime environment variable. - return 'process.env.ASTRO_STUDIO_APP_TOKEN'; + return `process.env.${envPrefix}_APP_TOKEN`; } else { // Static mode or prerendering needs the local app token. - return `process.env.ASTRO_STUDIO_APP_TOKEN ?? ${JSON.stringify(appToken)}`; + return `process.env.${envPrefix}_APP_TOKEN ?? ${JSON.stringify(appToken)}`; } } else { return JSON.stringify(appToken); @@ -157,15 +166,22 @@ export function getStudioVirtualModContents({ } function dbUrlArg() { - const dbStr = JSON.stringify(getRemoteDatabaseUrl()); + const dbStr = JSON.stringify(dbInfo.url); + // Allow overriding, mostly for testing - return `import.meta.env.ASTRO_STUDIO_REMOTE_DB_URL ?? ${dbStr}`; + return dbInfo.type === 'studio' + ? `import.meta.env.ASTRO_STUDIO_REMOTE_DB_URL ?? ${dbStr}` + : `import.meta.env.ASTRO_DB_REMOTE_URL ?? ${dbStr}`; } return ` import {asDrizzleTable, createRemoteDatabaseClient} from ${RUNTIME_IMPORT}; -export const db = await createRemoteDatabaseClient(${appTokenArg()}, ${dbUrlArg()}); +export const db = await createRemoteDatabaseClient({ + dbType: ${JSON.stringify(dbInfo.type)}, + remoteUrl: ${dbUrlArg()}, + appToken: ${appTokenArg()}, +}); export * from ${RUNTIME_VIRTUAL_IMPORT}; @@ -187,9 +203,10 @@ function getStringifiedTableExports(tables: DBTables) { const sqlite = new SQLiteAsyncDialect(); async function recreateTables({ tables, root }: { tables: LateTables; root: URL }) { + const dbInfo = getRemoteDatabaseInfo(); const { ASTRO_DATABASE_FILE } = getAstroEnv(); const dbUrl = normalizeDatabaseUrl(ASTRO_DATABASE_FILE, new URL(DB_PATH, root).href); - const db = createLocalDatabaseClient({ dbUrl }); + const db = createLocalDatabaseClient({ dbUrl, enableTransations: dbInfo.type === 'libsql' }); const setupQueries: SQL[] = []; for (const [name, table] of Object.entries(tables.get() ?? {})) { const dropQuery = sql.raw(`DROP TABLE IF EXISTS ${sqlite.escapeName(name)}`); diff --git a/packages/db/src/core/load-file.ts b/packages/db/src/core/load-file.ts index b9fb0136c..027deaa60 100644 --- a/packages/db/src/core/load-file.ts +++ b/packages/db/src/core/load-file.ts @@ -146,6 +146,7 @@ export async function bundleFile({ metafile: true, define: { 'import.meta.env.ASTRO_STUDIO_REMOTE_DB_URL': 'undefined', + 'import.meta.env.ASTRO_DB_REMOTE_DB_URL': 'undefined', 'import.meta.env.ASTRO_DATABASE_FILE': JSON.stringify(ASTRO_DATABASE_FILE ?? ''), }, plugins: [ diff --git a/packages/db/src/core/queries.ts b/packages/db/src/core/queries.ts index 705205ee4..cf472d423 100644 --- a/packages/db/src/core/queries.ts +++ b/packages/db/src/core/queries.ts @@ -1,4 +1,4 @@ -import { type SQL } from 'drizzle-orm'; +import type { SQL } from 'drizzle-orm'; import { SQLiteAsyncDialect } from 'drizzle-orm/sqlite-core'; import { bold } from 'kleur/colors'; import { diff --git a/packages/db/src/core/utils.ts b/packages/db/src/core/utils.ts index 6229cb070..cf3e37535 100644 --- a/packages/db/src/core/utils.ts +++ b/packages/db/src/core/utils.ts @@ -10,9 +10,31 @@ export function getAstroEnv(envMode = ''): Record<`ASTRO_${string}`, string> { return env; } -export function getRemoteDatabaseUrl(): string { - const env = getAstroStudioEnv(); - return env.ASTRO_STUDIO_REMOTE_DB_URL || 'https://db.services.astro.build'; +export type RemoteDatabaseInfo = { + type: 'libsql' | 'studio'; + url: string; +}; + +export function getRemoteDatabaseInfo(): RemoteDatabaseInfo { + const astroEnv = getAstroEnv(); + const studioEnv = getAstroStudioEnv(); + + if (studioEnv.ASTRO_STUDIO_REMOTE_DB_URL) + return { + type: 'studio', + url: studioEnv.ASTRO_STUDIO_REMOTE_DB_URL, + }; + + if (astroEnv.ASTRO_DB_REMOTE_URL) + return { + type: 'libsql', + url: astroEnv.ASTRO_DB_REMOTE_URL, + }; + + return { + type: 'studio', + url: 'https://db.services.astro.build', + }; } export function getDbDirectoryUrl(root: URL | string) { diff --git a/packages/db/src/runtime/db-client.ts b/packages/db/src/runtime/db-client.ts index 55c1dd087..d667ecbb2 100644 --- a/packages/db/src/runtime/db-client.ts +++ b/packages/db/src/runtime/db-client.ts @@ -1,5 +1,5 @@ import type { InStatement } from '@libsql/client'; -import { createClient } from '@libsql/client'; +import { type Config as LibSQLConfig, createClient } from '@libsql/client'; import type { LibSQLDatabase } from 'drizzle-orm/libsql'; import { drizzle as drizzleLibsql } from 'drizzle-orm/libsql'; import { type SqliteRemoteDatabase, drizzle as drizzleProxy } from 'drizzle-orm/sqlite-proxy'; @@ -18,12 +18,19 @@ function applyTransactionNotSupported(db: SqliteRemoteDatabase) { }); } -export function createLocalDatabaseClient({ dbUrl }: { dbUrl: string }): LibSQLDatabase { - const url = isWebContainer ? 'file:content.db' : dbUrl; +type LocalDbClientOptions = { + dbUrl: string; + enableTransations: boolean; +}; + +export function createLocalDatabaseClient(options: LocalDbClientOptions): LibSQLDatabase { + const url = isWebContainer ? 'file:content.db' : options.dbUrl; const client = createClient({ url }); const db = drizzleLibsql(client); - applyTransactionNotSupported(db); + if (!options.enableTransations) { + applyTransactionNotSupported(db); + } return db; } @@ -35,7 +42,33 @@ const remoteResultSchema = z.object({ lastInsertRowid: z.unknown().optional(), }); -export function createRemoteDatabaseClient(appToken: string, remoteDbURL: string) { +type RemoteDbClientOptions = { + dbType: 'studio' | 'libsql'; + appToken: string; + remoteUrl: string | URL; +}; + +export function createRemoteDatabaseClient(options: RemoteDbClientOptions) { + const remoteUrl = new URL(options.remoteUrl); + + return options.dbType === 'studio' + ? createStudioDatabaseClient(options.appToken, remoteUrl) + : createRemoteLibSQLClient(options.appToken, remoteUrl); +} + +function createRemoteLibSQLClient(appToken: string, remoteDbURL: URL) { + const options: Partial<LibSQLConfig> = Object.fromEntries(remoteDbURL.searchParams.entries()); + remoteDbURL.search = ''; + + const client = createClient({ + ...options, + authToken: appToken, + url: remoteDbURL.protocol === 'memory:' ? ':memory:' : remoteDbURL.toString(), + }); + return drizzleLibsql(client); +} + +function createStudioDatabaseClient(appToken: string, remoteDbURL: URL) { if (appToken == null) { throw new Error(`Cannot create a remote client: missing app token.`); } diff --git a/packages/db/src/runtime/index.ts b/packages/db/src/runtime/index.ts index 9e882843a..fb8579459 100644 --- a/packages/db/src/runtime/index.ts +++ b/packages/db/src/runtime/index.ts @@ -1,5 +1,5 @@ import { type ColumnBuilderBaseConfig, type ColumnDataType, sql } from 'drizzle-orm'; -import { type LibSQLDatabase } from 'drizzle-orm/libsql'; +import type { LibSQLDatabase } from 'drizzle-orm/libsql'; import { type IndexBuilder, type SQLiteColumnBuilderBase, diff --git a/packages/db/test/fixtures/ticketing-example/package.json b/packages/db/test/fixtures/ticketing-example/package.json index b4c67a310..9386c7f96 100644 --- a/packages/db/test/fixtures/ticketing-example/package.json +++ b/packages/db/test/fixtures/ticketing-example/package.json @@ -14,7 +14,7 @@ "@astrojs/db": "workspace:*", "@astrojs/node": "workspace:*", "@astrojs/react": "^3.6.2", - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "astro": "workspace:*", "open-props": "^1.7.5", diff --git a/packages/db/test/static-remote.test.js b/packages/db/test/static-remote.test.js index 39e4eda0c..ddfe735e5 100644 --- a/packages/db/test/static-remote.test.js +++ b/packages/db/test/static-remote.test.js @@ -39,4 +39,31 @@ describe('astro:db', () => { assert.match($('#row').text(), /1/); }); }); + + describe('static build --remote with custom LibSQL', () => { + let remoteDbServer; + + before(async () => { + process.env.ASTRO_DB_REMOTE_URL = `memory:`; + await fixture.build(); + }); + + after(async () => { + await remoteDbServer?.stop(); + }); + + it('Can render page', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerioLoad(html); + + assert.equal($('li').length, 1); + }); + + it('Returns correct shape from db.run()', async () => { + const html = await fixture.readFile('/run/index.html'); + const $ = cheerioLoad(html); + + assert.match($('#row').text(), /1/); + }); + }); }); diff --git a/packages/integrations/alpinejs/package.json b/packages/integrations/alpinejs/package.json index 7cd4e3ac0..acb14e240 100644 --- a/packages/integrations/alpinejs/package.json +++ b/packages/integrations/alpinejs/package.json @@ -41,7 +41,7 @@ "@playwright/test": "1.46.1", "astro": "workspace:*", "astro-scripts": "workspace:*", - "vite": "^5.4.1" + "vite": "^5.4.2" }, "publishConfig": { "provenance": true diff --git a/packages/integrations/markdoc/CHANGELOG.md b/packages/integrations/markdoc/CHANGELOG.md index a968e5911..558b524e8 100644 --- a/packages/integrations/markdoc/CHANGELOG.md +++ b/packages/integrations/markdoc/CHANGELOG.md @@ -8,6 +8,12 @@ - astro@5.0.0-alpha.0 - @astrojs/markdown-remark@6.0.0-alpha.0 +## 0.11.4 + +### Patch Changes + +- [#11846](https://github.com/withastro/astro/pull/11846) [`ed7bbd9`](https://github.com/withastro/astro/commit/ed7bbd990f80cacf9c5ec2a70ad7501631b92d3f) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes an issue preventing to use Astro components as Markdoc tags and nodes when configured using the `extends` property. + ## 0.11.3 ### Patch Changes diff --git a/packages/integrations/markdoc/package.json b/packages/integrations/markdoc/package.json index 71cce6fd0..cf35f0f0c 100644 --- a/packages/integrations/markdoc/package.json +++ b/packages/integrations/markdoc/package.json @@ -80,7 +80,7 @@ "astro-scripts": "workspace:*", "devalue": "^5.0.0", "linkedom": "^0.18.4", - "vite": "^5.4.1" + "vite": "^5.4.2" }, "engines": { "node": "^18.17.1 || ^20.3.0 || >=21.0.0" diff --git a/packages/integrations/markdoc/src/content-entry-type.ts b/packages/integrations/markdoc/src/content-entry-type.ts index 791def315..303251d66 100644 --- a/packages/integrations/markdoc/src/content-entry-type.ts +++ b/packages/integrations/markdoc/src/content-entry-type.ts @@ -78,13 +78,13 @@ export async function getContentEntryType({ // Only include component imports for tags used in the document. // Avoids style and script bleed. for (const tag of usedTags) { - const render = userMarkdocConfig.tags?.[tag]?.render; + const render = markdocConfig.tags?.[tag]?.render; if (isComponentConfig(render)) { componentConfigByTagMap[tag] = render; } } let componentConfigByNodeMap: Record<string, ComponentConfig> = {}; - for (const [nodeType, schema] of Object.entries(userMarkdocConfig.nodes ?? {})) { + for (const [nodeType, schema] of Object.entries(markdocConfig.nodes ?? {})) { const render = schema?.render; if (isComponentConfig(render)) { componentConfigByNodeMap[nodeType] = render; diff --git a/packages/integrations/markdoc/src/runtime.ts b/packages/integrations/markdoc/src/runtime.ts index 31ddf4c64..f62bcec1a 100644 --- a/packages/integrations/markdoc/src/runtime.ts +++ b/packages/integrations/markdoc/src/runtime.ts @@ -7,7 +7,7 @@ import Markdoc, { } from '@markdoc/markdoc'; import type { AstroInstance } from 'astro'; import { createComponent, renderComponent } from 'astro/runtime/server/index.js'; -import { type AstroMarkdocConfig } from './config.js'; +import type { AstroMarkdocConfig } from './config.js'; import { setupHeadingConfig } from './heading-ids.js'; import { htmlTag } from './html/tagdefs/html.tag.js'; import type { MarkdocIntegrationOptions } from './options.js'; diff --git a/packages/integrations/markdoc/test/fixtures/render-with-extends-components/astro.config.mjs b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/astro.config.mjs new file mode 100644 index 000000000..1bd8ba93f --- /dev/null +++ b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/astro.config.mjs @@ -0,0 +1,7 @@ +import markdoc from '@astrojs/markdoc'; +import { defineConfig } from 'astro/config'; + +// https://astro.build/config +export default defineConfig({ + integrations: [markdoc()], +}); diff --git a/packages/integrations/markdoc/test/fixtures/render-with-extends-components/markdoc.config.ts b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/markdoc.config.ts new file mode 100644 index 000000000..8daba3746 --- /dev/null +++ b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/markdoc.config.ts @@ -0,0 +1,31 @@ +import { component, defineMarkdocConfig } from '@astrojs/markdoc/config'; + +export default defineMarkdocConfig({ + extends: [preset()], +}); + +function preset() { + return { + nodes: { + fence: { + render: component('./src/components/Code.astro'), + attributes: { + language: { type: String }, + content: { type: String }, + }, + }, + }, + tags: { + 'marquee-element': { + render: component('./src/components/CustomMarquee.astro'), + attributes: { + direction: { + type: String, + default: 'left', + matches: ['left', 'right', 'up', 'down'], + }, + }, + }, + }, + } +} diff --git a/packages/integrations/markdoc/test/fixtures/render-with-extends-components/package.json b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/package.json new file mode 100644 index 000000000..962a2b8a7 --- /dev/null +++ b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/package.json @@ -0,0 +1,9 @@ +{ + "name": "@test/markdoc-render-with-extends-components", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/markdoc": "workspace:*", + "astro": "workspace:*" + } +} diff --git a/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/components/Code.astro b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/components/Code.astro new file mode 100644 index 000000000..18bf1399f --- /dev/null +++ b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/components/Code.astro @@ -0,0 +1,12 @@ +--- +import { Code } from 'astro/components'; + +type Props = { + content: string; + language: string; +} + +const { content, language } = Astro.props as Props; +--- + +<Code lang={language} code={content} /> diff --git a/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/components/CustomMarquee.astro b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/components/CustomMarquee.astro new file mode 100644 index 000000000..3108b9973 --- /dev/null +++ b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/components/CustomMarquee.astro @@ -0,0 +1 @@ +<marquee data-custom-marquee {...Astro.props}><slot /></marquee> diff --git a/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/content/blog/with-components.mdoc b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/content/blog/with-components.mdoc new file mode 100644 index 000000000..61f404a97 --- /dev/null +++ b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/content/blog/with-components.mdoc @@ -0,0 +1,17 @@ +--- +title: Post with components +--- + +## Post with components + +This uses a custom marquee component with a shortcode: + +{% marquee-element direction="right" %} +I'm a marquee too! +{% /marquee-element %} + +And a code component for code blocks: + +```js +const isRenderedWithShiki = true; +``` diff --git a/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/pages/index.astro b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/pages/index.astro new file mode 100644 index 000000000..52239acce --- /dev/null +++ b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/pages/index.astro @@ -0,0 +1,19 @@ +--- +import { getEntryBySlug } from "astro:content"; + +const post = await getEntryBySlug('blog', 'with-components'); +const { Content } = await post.render(); +--- + +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Content</title> +</head> +<body> + <Content /> +</body> +</html> diff --git a/packages/integrations/markdoc/test/render-extends-components.test.js b/packages/integrations/markdoc/test/render-extends-components.test.js new file mode 100644 index 000000000..8d1778d3e --- /dev/null +++ b/packages/integrations/markdoc/test/render-extends-components.test.js @@ -0,0 +1,64 @@ +import assert from 'node:assert/strict'; +import { after, before, describe, it } from 'node:test'; +import { parseHTML } from 'linkedom'; +import { loadFixture } from '../../../astro/test/test-utils.js'; + +const root = new URL('./fixtures/render-with-extends-components/', import.meta.url); + +describe('Markdoc - render components defined in `extends`', () => { + let fixture; + + before(async () => { + fixture = await loadFixture({ + root, + }); + }); + + describe('dev', () => { + let devServer; + + before(async () => { + devServer = await fixture.startDevServer(); + }); + + after(async () => { + await devServer.stop(); + }); + + it('renders content - with components', async () => { + const res = await fixture.fetch('/'); + const html = await res.text(); + + renderComponentsChecks(html); + }); + }); + + describe('build', () => { + before(async () => { + await fixture.build(); + }); + + it('renders content - with components', async () => { + const html = await fixture.readFile('/index.html'); + + renderComponentsChecks(html); + }); + }); +}); + +/** @param {string} html */ +function renderComponentsChecks(html) { + const { document } = parseHTML(html); + const h2 = document.querySelector('h2'); + assert.equal(h2.textContent, 'Post with components'); + + // Renders custom shortcode component + const marquee = document.querySelector('marquee'); + assert.notEqual(marquee, null); + assert.equal(marquee.hasAttribute('data-custom-marquee'), true); + + // Renders Astro Code component + const pre = document.querySelector('pre'); + assert.notEqual(pre, null); + assert.equal(pre.className, 'astro-code github-dark'); +} diff --git a/packages/integrations/mdx/CHANGELOG.md b/packages/integrations/mdx/CHANGELOG.md index 3087b7a27..b8d718d1e 100644 --- a/packages/integrations/mdx/CHANGELOG.md +++ b/packages/integrations/mdx/CHANGELOG.md @@ -10,14 +10,22 @@ ## 4.0.0-alpha.0 -### Patch Changes - -- [#11717](https://github.com/withastro/astro/pull/11717) [`423614e`](https://github.com/withastro/astro/commit/423614ebb6ddb76cc8d11f3e3b6ae111a4a82662) Thanks [@bluwy](https://github.com/bluwy)! - Fixes stack trace location when failed to parse an MDX file with frontmatter - - Updated dependencies [[`b6fbdaa`](https://github.com/withastro/astro/commit/b6fbdaa94a9ecec706a99e1938fbf5cd028c72e0), [`89bab1e`](https://github.com/withastro/astro/commit/89bab1e70786123fbe933a9d7a1b80c9334dcc5f), [`d74617c`](https://github.com/withastro/astro/commit/d74617cbd3278feba05909ec83db2d73d57a153e), [`83a2a64`](https://github.com/withastro/astro/commit/83a2a648418ad30f4eb781d1c1b5f2d8a8ac846e), [`e90f559`](https://github.com/withastro/astro/commit/e90f5593d23043579611452a84b9e18ad2407ef9), [`2df49a6`](https://github.com/withastro/astro/commit/2df49a6fb4f6d92fe45f7429430abe63defeacd6), [`8a53517`](https://github.com/withastro/astro/commit/8a5351737d6a14fc55f1dafad8f3b04079e81af6)]: - astro@5.0.0-alpha.0 - @astrojs/markdown-remark@6.0.0-alpha.0 +## 3.1.5 + +### Patch Changes + +- [#11818](https://github.com/withastro/astro/pull/11818) [`88ef1d0`](https://github.com/withastro/astro/commit/88ef1d0e774e8ab8798b9912da1b069f97736623) Thanks [@bluwy](https://github.com/bluwy)! - Fixes CSS in the layout component to be ordered first before any other components in the MDX file + +## 3.1.4 + +### Patch Changes + +- [#11717](https://github.com/withastro/astro/pull/11717) [`423614e`](https://github.com/withastro/astro/commit/423614ebb6ddb76cc8d11f3e3b6ae111a4a82662) Thanks [@bluwy](https://github.com/bluwy)! - Fixes stack trace location when failed to parse an MDX file with frontmatter + ## 3.1.3 ### Patch Changes diff --git a/packages/integrations/mdx/package.json b/packages/integrations/mdx/package.json index 7b45756f6..6a6e4b1bd 100644 --- a/packages/integrations/mdx/package.json +++ b/packages/integrations/mdx/package.json @@ -40,14 +40,14 @@ "es-module-lexer": "^1.5.4", "estree-util-visit": "^2.0.0", "gray-matter": "^4.0.3", - "hast-util-to-html": "^9.0.1", + "hast-util-to-html": "^9.0.2", "kleur": "^4.1.5", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", "remark-smartypants": "^3.0.2", "source-map": "^0.7.4", "unist-util-visit": "^5.0.0", - "vfile": "^6.0.2" + "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0-alpha.0" @@ -61,7 +61,7 @@ "cheerio": "1.0.0", "linkedom": "^0.18.4", "mdast-util-mdx": "^3.0.0", - "mdast-util-mdx-jsx": "^3.1.2", + "mdast-util-mdx-jsx": "^3.1.3", "mdast-util-to-string": "^4.0.0", "rehype-mathjax": "^6.0.0", "rehype-pretty-code": "^0.13.2", @@ -71,7 +71,7 @@ "remark-toc": "^9.0.0", "shiki": "^1.14.1", "unified": "^11.0.5", - "vite": "^5.4.1" + "vite": "^5.4.2" }, "engines": { "node": "^18.17.1 || ^20.3.0 || >=21.0.0" diff --git a/packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts b/packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts index 7fa7f69ef..1b981a68e 100644 --- a/packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts +++ b/packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts @@ -17,30 +17,28 @@ export function rehypeApplyFrontmatterExport() { jsToTreeNode(`export const frontmatter = ${JSON.stringify(frontmatter)};`), ]; if (frontmatter.layout) { - // NOTE(bholmesdev) 08-22-2022 - // Using an async layout import (i.e. `const Layout = (await import...)`) - // Preserves the dev server import cache when globbing a large set of MDX files - // Full explanation: 'https://github.com/withastro/astro/pull/4428' exportNodes.unshift( jsToTreeNode( + // NOTE: Use `__astro_*` import names to prevent conflicts with user code /** @see 'vite-plugin-markdown' for layout props reference */ - `import { jsx as layoutJsx } from 'astro/jsx-runtime'; + `\ +import { jsx as __astro_layout_jsx__ } from 'astro/jsx-runtime'; +import __astro_layout_component__ from ${JSON.stringify(frontmatter.layout)}; - export default async function ({ children }) { - const Layout = (await import(${JSON.stringify(frontmatter.layout)})).default; - const { layout, ...content } = frontmatter; - content.file = file; - content.url = url; - return layoutJsx(Layout, { - file, - url, - content, - frontmatter: content, - headings: getHeadings(), - 'server:root': true, - children, - }); - };`, +export default function ({ children }) { + const { layout, ...content } = frontmatter; + content.file = file; + content.url = url; + return __astro_layout_jsx__(__astro_layout_component__, { + file, + url, + content, + frontmatter: content, + headings: getHeadings(), + 'server:root': true, + children, + }); +};`, ), ); } diff --git a/packages/integrations/node/package.json b/packages/integrations/node/package.json index 1528a0f3e..23bb3a6d1 100644 --- a/packages/integrations/node/package.json +++ b/packages/integrations/node/package.json @@ -42,7 +42,7 @@ "devDependencies": { "@types/node": "^18.17.8", "@types/send": "^0.17.4", - "@types/server-destroy": "^1.0.3", + "@types/server-destroy": "^1.0.4", "astro": "workspace:*", "astro-scripts": "workspace:*", "cheerio": "1.0.0", diff --git a/packages/integrations/partytown/CHANGELOG.md b/packages/integrations/partytown/CHANGELOG.md index c6802c3c9..35b24feb1 100644 --- a/packages/integrations/partytown/CHANGELOG.md +++ b/packages/integrations/partytown/CHANGELOG.md @@ -1,5 +1,11 @@ # @astrojs/partytown +## 2.1.2 + +### Patch Changes + +- [#11829](https://github.com/withastro/astro/pull/11829) [`f1df1b3`](https://github.com/withastro/astro/commit/f1df1b3b462309444a9a50ecbf229840dff8c9d0) Thanks [@oosawy](https://github.com/oosawy)! - Prevent Partytown integration from inserting a 'null' string into the body + ## 2.1.1 ### Patch Changes diff --git a/packages/integrations/partytown/package.json b/packages/integrations/partytown/package.json index c90a8a131..e8fd6e5e6 100644 --- a/packages/integrations/partytown/package.json +++ b/packages/integrations/partytown/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/partytown", "description": "Use Partytown to move scripts into a web worker in your Astro project", - "version": "2.1.1", + "version": "2.1.2", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", diff --git a/packages/integrations/partytown/src/index.ts b/packages/integrations/partytown/src/index.ts index 739ff0e4b..05a1b4c11 100644 --- a/packages/integrations/partytown/src/index.ts +++ b/packages/integrations/partytown/src/index.ts @@ -26,7 +26,7 @@ export default function createPlugin(options?: PartytownOptions): AstroIntegrati hooks: { 'astro:config:setup': ({ config: _config, command, injectScript }) => { const lib = `${appendForwardSlash(_config.base)}~partytown/`; - const recreateIFrameScript = `;(e=>{e.addEventListener("astro:before-swap",e=>{let r=document.body.querySelector("iframe[src*='${lib}']");e.newDocument.body.append(r)})})(document);`; + const recreateIFrameScript = `;(e=>{e.addEventListener("astro:before-swap",e=>{let r=document.body.querySelector("iframe[src*='${lib}']");if(r)e.newDocument.body.append(r)})})(document);`; const partytownConfig = { lib, ...options?.config, diff --git a/packages/integrations/preact/CHANGELOG.md b/packages/integrations/preact/CHANGELOG.md index e714d2471..43330b468 100644 --- a/packages/integrations/preact/CHANGELOG.md +++ b/packages/integrations/preact/CHANGELOG.md @@ -1,5 +1,11 @@ # @astrojs/preact +## 3.5.2 + +### Patch Changes + +- [#11834](https://github.com/withastro/astro/pull/11834) [`5f2536b`](https://github.com/withastro/astro/commit/5f2536b51df93bfd51098c48220d647e7ad3954c) Thanks [@ph1p](https://github.com/ph1p)! - Preact signals are now serialized correctly in arrays when they are given to components. + ## 3.5.1 ### Patch Changes diff --git a/packages/integrations/preact/package.json b/packages/integrations/preact/package.json index 9bd21fc73..d7fb6b47a 100644 --- a/packages/integrations/preact/package.json +++ b/packages/integrations/preact/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/preact", "description": "Use Preact components within Astro", - "version": "3.5.1", + "version": "3.5.2", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", diff --git a/packages/integrations/preact/src/client.ts b/packages/integrations/preact/src/client.ts index 3fb36d22a..32fdc9888 100644 --- a/packages/integrations/preact/src/client.ts +++ b/packages/integrations/preact/src/client.ts @@ -18,13 +18,34 @@ export default (element: HTMLElement) => let signalsRaw = element.dataset.preactSignals; if (signalsRaw) { const { signal } = await import('@preact/signals'); - let signals: Record<string, string> = JSON.parse(element.dataset.preactSignals!); + let signals: Record<string, string | [string, number][]> = JSON.parse( + element.dataset.preactSignals!, + ); for (const [propName, signalId] of Object.entries(signals)) { - if (!sharedSignalMap.has(signalId)) { - const signalValue = signal(props[propName]); - sharedSignalMap.set(signalId, signalValue); + if (Array.isArray(signalId)) { + signalId.forEach(([id, indexOrKeyInProps]) => { + const mapValue = props[propName][indexOrKeyInProps]; + let valueOfSignal = mapValue; + + // not an property key + if (typeof indexOrKeyInProps !== 'string') { + valueOfSignal = mapValue[0]; + indexOrKeyInProps = mapValue[1]; + } + + if (!sharedSignalMap.has(id)) { + const signalValue = signal(valueOfSignal); + sharedSignalMap.set(id, signalValue); + } + props[propName][indexOrKeyInProps] = sharedSignalMap.get(id); + }); + } else { + if (!sharedSignalMap.has(signalId)) { + const signalValue = signal(props[propName]); + sharedSignalMap.set(signalId, signalValue); + } + props[propName] = sharedSignalMap.get(signalId); } - props[propName] = sharedSignalMap.get(signalId); } } diff --git a/packages/integrations/preact/src/signals.ts b/packages/integrations/preact/src/signals.ts index ea022b422..7b797f385 100644 --- a/packages/integrations/preact/src/signals.ts +++ b/packages/integrations/preact/src/signals.ts @@ -1,6 +1,13 @@ import type { Context } from './context.js'; import { incrementId } from './context.js'; -import type { AstroPreactAttrs, PropNameToSignalMap, SignalLike } from './types.js'; +import type { + ArrayObjectMapping, + AstroPreactAttrs, + PropNameToSignalMap, + SignalLike, + SignalToKeyOrIndexMap, + Signals, +} from './types.js'; function isSignal(x: any): x is SignalLike { return x != null && typeof x === 'object' && typeof x.peek === 'function' && 'value' in x; @@ -28,22 +35,38 @@ export function serializeSignals( map: PropNameToSignalMap, ) { // Check for signals - const signals: Record<string, string> = {}; + const signals: Signals = {}; for (const [key, value] of Object.entries(props)) { - if (isSignal(value)) { + const isPropArray = Array.isArray(value); + const isPropObject = !isSignal(value) && typeof props[key] === 'object' && !isPropArray; + + if (isPropObject || isPropArray) { + const values = isPropObject ? Object.keys(props[key]) : value; + values.forEach((valueKey: number | string, valueIndex: number) => { + const signal = isPropObject ? props[key][valueKey] : valueKey; + if (isSignal(signal)) { + const keyOrIndex = isPropObject ? valueKey.toString() : valueIndex; + + props[key] = isPropObject + ? Object.assign({}, props[key], { [keyOrIndex]: signal.peek() }) + : props[key].map((v: SignalLike, i: number) => + i === valueIndex ? [signal.peek(), i] : v, + ); + + const currentMap = (map.get(key) || []) as SignalToKeyOrIndexMap; + map.set(key, [...currentMap, [signal, keyOrIndex]]); + + const currentSignals = (signals[key] || []) as ArrayObjectMapping; + signals[key] = [...currentSignals, [getSignalId(ctx, signal), keyOrIndex]]; + } + }); + } else if (isSignal(value)) { // Set the value to the current signal value // This mutates the props on purpose, so that it will be serialized correct. props[key] = value.peek(); map.set(key, value); - let id: string; - if (ctx.signals.has(value)) { - id = ctx.signals.get(value)!; - } else { - id = incrementId(ctx); - ctx.signals.set(value, id); - } - signals[key] = id; + signals[key] = getSignalId(ctx, value); } } @@ -51,3 +74,13 @@ export function serializeSignals( attrs['data-preact-signals'] = JSON.stringify(signals); } } + +function getSignalId(ctx: Context, item: SignalLike) { + let id = ctx.signals.get(item); + if (!id) { + id = incrementId(ctx); + ctx.signals.set(item, id); + } + + return id; +} diff --git a/packages/integrations/preact/src/types.ts b/packages/integrations/preact/src/types.ts index 93f65bbc2..e1c56ca30 100644 --- a/packages/integrations/preact/src/types.ts +++ b/packages/integrations/preact/src/types.ts @@ -7,7 +7,11 @@ export type SignalLike = { peek(): any; }; -export type PropNameToSignalMap = Map<string, SignalLike>; +export type ArrayObjectMapping = [string, number | string][]; +export type Signals = Record<string, string | ArrayObjectMapping>; + +export type SignalToKeyOrIndexMap = [SignalLike, number | string][]; +export type PropNameToSignalMap = Map<string, SignalLike | SignalToKeyOrIndexMap>; export type AstroPreactAttrs = { ['data-preact-signals']?: string; diff --git a/packages/integrations/react/package.json b/packages/integrations/react/package.json index a927eeabe..4e7901bff 100644 --- a/packages/integrations/react/package.json +++ b/packages/integrations/react/package.json @@ -59,14 +59,14 @@ "ultrahtml": "^1.5.3" }, "devDependencies": { - "@types/react": "^18.3.3", + "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", "astro": "workspace:*", "astro-scripts": "workspace:*", "cheerio": "1.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "vite": "^5.4.1" + "vite": "^5.4.2" }, "peerDependencies": { "@types/react": "^17.0.50 || ^18.0.21", diff --git a/packages/integrations/solid/package.json b/packages/integrations/solid/package.json index 5fcab7ca4..5219c3e00 100644 --- a/packages/integrations/solid/package.json +++ b/packages/integrations/solid/package.json @@ -40,8 +40,8 @@ "devDependencies": { "astro": "workspace:*", "astro-scripts": "workspace:*", - "solid-js": "^1.8.21", - "vite": "^5.4.1" + "solid-js": "^1.8.22", + "vite": "^5.4.2" }, "peerDependencies": { "solid-devtools": "^0.30.1", diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index 0c0ccdba8..92a08c01f 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -50,14 +50,14 @@ "dev": "astro-scripts dev \"src/**/*.ts\"" }, "dependencies": { - "@sveltejs/vite-plugin-svelte": "^3.1.1", - "svelte2tsx": "^0.7.15" + "@sveltejs/vite-plugin-svelte": "^3.1.2", + "svelte2tsx": "^0.7.16" }, "devDependencies": { "astro": "workspace:*", "astro-scripts": "workspace:*", - "svelte": "^4.2.18", - "vite": "^5.4.1" + "svelte": "^4.2.19", + "vite": "^5.4.2" }, "peerDependencies": { "astro": "^5.0.0-alpha.0", diff --git a/packages/integrations/tailwind/package.json b/packages/integrations/tailwind/package.json index 236134069..242989272 100644 --- a/packages/integrations/tailwind/package.json +++ b/packages/integrations/tailwind/package.json @@ -41,7 +41,7 @@ "astro": "workspace:*", "astro-scripts": "workspace:*", "tailwindcss": "^3.4.10", - "vite": "^5.4.1" + "vite": "^5.4.2" }, "peerDependencies": { "astro": "^5.0.0-alpha.0", diff --git a/packages/integrations/vercel/CHANGELOG.md b/packages/integrations/vercel/CHANGELOG.md index bd284a12b..6250bfcc6 100644 --- a/packages/integrations/vercel/CHANGELOG.md +++ b/packages/integrations/vercel/CHANGELOG.md @@ -43,6 +43,13 @@ Given this, the feature has been removed from Astro. +### Patch Changes + +- Updated dependencies [[`b6fbdaa`](https://github.com/withastro/astro/commit/b6fbdaa94a9ecec706a99e1938fbf5cd028c72e0), [`89bab1e`](https://github.com/withastro/astro/commit/89bab1e70786123fbe933a9d7a1b80c9334dcc5f), [`d74617c`](https://github.com/withastro/astro/commit/d74617cbd3278feba05909ec83db2d73d57a153e), [`e90f559`](https://github.com/withastro/astro/commit/e90f5593d23043579611452a84b9e18ad2407ef9), [`2df49a6`](https://github.com/withastro/astro/commit/2df49a6fb4f6d92fe45f7429430abe63defeacd6), [`8a53517`](https://github.com/withastro/astro/commit/8a5351737d6a14fc55f1dafad8f3b04079e81af6)]: + - astro@5.0.0-alpha.0 + +## 7.8.0 + ### Minor Changes - [#11728](https://github.com/withastro/astro/pull/11728) [`5ea02b1`](https://github.com/withastro/astro/commit/5ea02b12fdb9b8ca45b1229bb9d04bc3d1270e0f) Thanks [@matthewp](https://github.com/matthewp)! - Deprecates the `functionPerRoute` option @@ -64,8 +71,9 @@ ### Patch Changes -- Updated dependencies [[`b6fbdaa`](https://github.com/withastro/astro/commit/b6fbdaa94a9ecec706a99e1938fbf5cd028c72e0), [`89bab1e`](https://github.com/withastro/astro/commit/89bab1e70786123fbe933a9d7a1b80c9334dcc5f), [`d74617c`](https://github.com/withastro/astro/commit/d74617cbd3278feba05909ec83db2d73d57a153e), [`e90f559`](https://github.com/withastro/astro/commit/e90f5593d23043579611452a84b9e18ad2407ef9), [`2df49a6`](https://github.com/withastro/astro/commit/2df49a6fb4f6d92fe45f7429430abe63defeacd6), [`8a53517`](https://github.com/withastro/astro/commit/8a5351737d6a14fc55f1dafad8f3b04079e81af6)]: - - astro@5.0.0-alpha.0 +- [#11783](https://github.com/withastro/astro/pull/11783) [`fc81b01`](https://github.com/withastro/astro/commit/fc81b01bcdd43646bcc615b16bf0400a646445c8) Thanks [@matthewp](https://github.com/matthewp)! - Prevent race condition with Node 18 + + Using Node 18 there can be a race condition where polyfill for the `crypto` global is not applied in time. This change ensures the polyfills run first. ## 7.7.2 diff --git a/packages/integrations/vercel/test/hosted/hosted-astro-project/src/env.d.ts b/packages/integrations/vercel/test/hosted/hosted-astro-project/src/env.d.ts deleted file mode 100644 index f964fe0cf..000000000 --- a/packages/integrations/vercel/test/hosted/hosted-astro-project/src/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// <reference types="astro/client" /> diff --git a/packages/integrations/vue/package.json b/packages/integrations/vue/package.json index d66c36aad..99f14492e 100644 --- a/packages/integrations/vue/package.json +++ b/packages/integrations/vue/package.json @@ -47,14 +47,14 @@ "@vitejs/plugin-vue": "^5.1.2", "@vitejs/plugin-vue-jsx": "^4.0.1", "@vue/compiler-sfc": "^3.4.38", - "vite-plugin-vue-devtools": "^7.3.8" + "vite-plugin-vue-devtools": "^7.3.9" }, "devDependencies": { "astro": "workspace:*", "astro-scripts": "workspace:*", "cheerio": "1.0.0", "linkedom": "^0.18.4", - "vite": "^5.4.1", + "vite": "^5.4.2", "vue": "^3.4.38" }, "peerDependencies": { diff --git a/packages/markdown/remark/package.json b/packages/markdown/remark/package.json index 82d928b85..aec4b0cfc 100644 --- a/packages/markdown/remark/package.json +++ b/packages/markdown/remark/package.json @@ -35,7 +35,7 @@ "dependencies": { "@astrojs/prism": "workspace:*", "github-slugger": "^2.0.0", - "hast-util-from-html": "^2.0.1", + "hast-util-from-html": "^2.0.2", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "mdast-util-definitions": "^6.0.0", @@ -50,7 +50,7 @@ "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", - "vfile": "^6.0.2" + "vfile": "^6.0.3" }, "devDependencies": { "@types/estree": "^1.0.5", diff --git a/packages/studio/package.json b/packages/studio/package.json index 830ec85af..dccf824b9 100644 --- a/packages/studio/package.json +++ b/packages/studio/package.json @@ -36,12 +36,12 @@ "dependencies": { "ci-info": "^4.0.0", "kleur": "^4.1.5", - "ora": "^8.0.1" + "ora": "^8.1.0" }, "devDependencies": { "astro": "workspace:*", "astro-scripts": "workspace:*", "typescript": "^5.5.4", - "vite": "^5.4.1" + "vite": "^5.4.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dc60101fd..7b8fca2d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,14 +31,14 @@ importers: specifier: ^0.21.5 version: 0.21.5 eslint: - specifier: ^9.9.0 - version: 9.9.0(jiti@1.21.0) + specifier: ^9.9.1 + version: 9.9.1(jiti@1.21.0) eslint-plugin-no-only-tests: specifier: ^3.3.0 version: 3.3.0 eslint-plugin-regexp: specifier: ^2.6.0 - version: 2.6.0(eslint@9.9.0(jiti@1.21.0)) + version: 2.6.0(eslint@9.9.1(jiti@1.21.0)) globby: specifier: ^14.0.2 version: 14.0.2 @@ -52,14 +52,14 @@ importers: specifier: ^0.14.1 version: 0.14.1 turbo: - specifier: ^2.0.14 - version: 2.0.14 + specifier: ^2.1.0 + version: 2.1.0 typescript: specifier: ~5.5.4 version: 5.5.4 typescript-eslint: - specifier: ^8.1.0 - version: 8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4) + specifier: ^8.3.0 + version: 8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4) benchmark: dependencies: @@ -78,9 +78,6 @@ importers: autocannon: specifier: ^7.15.0 version: 7.15.0 - execa: - specifier: ^8.0.1 - version: 8.0.1 markdown-table: specifier: ^3.0.3 version: 3.0.3 @@ -96,6 +93,9 @@ importers: sharp: specifier: ^0.33.3 version: 0.33.3 + tinyexec: + specifier: ^0.3.0 + version: 0.3.0 benchmark/packages/timer: dependencies: @@ -104,8 +104,8 @@ importers: version: 1.0.1 devDependencies: '@types/server-destroy': - specifier: ^1.0.3 - version: 1.0.3 + specifier: ^1.0.4 + version: 1.0.4 astro: specifier: workspace:* version: link:../../../packages/astro @@ -159,8 +159,8 @@ importers: version: 2.0.5(@types/node@18.19.31)(jsdom@23.2.0)(sass@1.77.8) devDependencies: '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -183,7 +183,7 @@ importers: examples/framework-multiple: dependencies: '@astrojs/preact': - specifier: ^3.5.1 + specifier: ^3.5.2 version: link:../../packages/integrations/preact '@astrojs/react': specifier: ^3.6.2 @@ -199,7 +199,7 @@ importers: version: link:../../packages/integrations/vue '@types/react': specifier: ^18.3.3 - version: 18.3.3 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -216,11 +216,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -228,7 +228,7 @@ importers: examples/framework-preact: dependencies: '@astrojs/preact': - specifier: ^3.5.1 + specifier: ^3.5.2 version: link:../../packages/integrations/preact '@preact/signals': specifier: ^1.3.0 @@ -246,8 +246,8 @@ importers: specifier: ^3.6.2 version: link:../../packages/integrations/react '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -271,7 +271,7 @@ importers: version: link:../../packages/astro solid-js: specifier: ^1.8.21 - version: 1.8.21 + version: 1.8.22 examples/framework-svelte: dependencies: @@ -283,7 +283,7 @@ importers: version: link:../../packages/astro svelte: specifier: ^4.2.18 - version: 4.2.18 + version: 4.2.19 examples/framework-vue: dependencies: @@ -364,8 +364,8 @@ importers: specifier: ^0.5.7 version: 0.5.7(tailwindcss@3.4.10) '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -398,7 +398,7 @@ importers: version: link:../../packages/astro svelte: specifier: ^4.2.18 - version: 4.2.18 + version: 4.2.19 examples/starlog: dependencies: @@ -487,17 +487,17 @@ importers: examples/with-nanostores: dependencies: '@astrojs/preact': - specifier: ^3.5.1 + specifier: ^3.5.2 version: link:../../packages/integrations/preact '@nanostores/preact': specifier: ^0.5.2 - version: 0.5.2(nanostores@0.11.2)(preact@10.23.2) + version: 0.5.2(nanostores@0.11.3)(preact@10.23.2) astro: specifier: ^5.0.0-alpha.1 version: link:../../packages/astro nanostores: specifier: ^0.11.2 - version: 0.11.2 + version: 0.11.3 preact: specifier: ^10.23.2 version: 10.23.2 @@ -552,24 +552,21 @@ importers: '@astrojs/telemetry': specifier: workspace:* version: link:../telemetry - '@babel/generator': - specifier: ^7.25.0 - version: 7.25.0 - '@babel/parser': - specifier: ^7.25.3 - version: 7.25.3 - '@babel/traverse': - specifier: ^7.25.3 - version: 7.25.3 - '@babel/types': + '@babel/core': specifier: ^7.25.2 version: 7.25.2 + '@babel/plugin-transform-react-jsx': + specifier: ^7.25.2 + version: 7.25.2(@babel/core@7.25.2) + '@babel/types': + specifier: ^7.25.4 + version: 7.25.4 '@oslojs/encoding': specifier: ^0.4.1 version: 0.4.1 '@rollup/pluginutils': specifier: ^5.1.0 - version: 5.1.0(rollup@4.21.0) + version: 5.1.0(rollup@4.21.1) '@types/cookie': specifier: ^0.6.0 version: 0.6.0 @@ -627,9 +624,6 @@ importers: estree-walker: specifier: ^3.0.3 version: 3.0.3 - execa: - specifier: ^8.0.1 - version: 8.0.1 fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -657,9 +651,12 @@ importers: magic-string: specifier: ^0.30.11 version: 0.30.11 + magicast: + specifier: ^0.3.5 + version: 0.3.5 micromatch: - specifier: ^4.0.7 - version: 4.0.7 + specifier: ^4.0.8 + version: 4.0.8 mrmime: specifier: ^2.0.0 version: 2.0.0 @@ -667,8 +664,8 @@ importers: specifier: ^0.6.18 version: 0.6.18 ora: - specifier: ^8.0.1 - version: 8.0.1 + specifier: ^8.1.0 + version: 8.1.0 p-limit: specifier: ^6.1.0 version: 6.1.0 @@ -699,6 +696,9 @@ importers: strip-ansi: specifier: ^7.1.0 version: 7.1.0 + tinyexec: + specifier: ^0.3.0 + version: 0.3.0 tsconfck: specifier: ^3.1.1 version: 3.1.1(typescript@5.5.4) @@ -706,14 +706,14 @@ importers: specifier: ^5.0.0 version: 5.0.0 vfile: - specifier: ^6.0.2 - version: 6.0.2 + specifier: ^6.0.3 + version: 6.0.3 vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) vitefu: specifier: ^0.2.5 - version: 0.2.5(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + version: 0.2.5(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) which-pm: specifier: ^3.0.0 version: 3.0.0 @@ -803,15 +803,18 @@ importers: eol: specifier: ^0.9.1 version: 0.9.1 + execa: + specifier: ^8.0.1 + version: 8.0.1 expect-type: - specifier: ^0.19.0 - version: 0.19.0 + specifier: ^0.20.0 + version: 0.20.0 mdast-util-mdx: specifier: ^3.0.0 version: 3.0.0 mdast-util-mdx-jsx: - specifier: ^3.1.2 - version: 3.1.2 + specifier: ^3.1.3 + version: 3.1.3 memfs: specifier: ^4.11.1 version: 4.11.1 @@ -834,14 +837,14 @@ importers: specifier: ^0.1.2 version: 0.1.2 rollup: - specifier: ^4.21.0 - version: 4.21.0 + specifier: ^4.21.1 + version: 4.21.1 sass: specifier: ^1.77.8 version: 1.77.8 undici: - specifier: ^6.19.7 - version: 6.19.7 + specifier: ^6.19.8 + version: 6.19.8 unified: specifier: ^11.0.5 version: 11.0.5 @@ -902,8 +905,8 @@ importers: specifier: workspace:* version: link:../../../../integrations/react '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -980,6 +983,22 @@ importers: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) + packages/astro/e2e/fixtures/client-idle-timeout: + dependencies: + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@astrojs/react': + specifier: workspace:* + version: link:../../../../integrations/react + astro: + specifier: workspace:* + version: link:../../.. + packages/astro/e2e/fixtures/client-only: dependencies: preact: @@ -992,11 +1011,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1116,11 +1135,11 @@ importers: specifier: ^1.77.8 version: 1.77.8 solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1170,11 +1189,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1226,11 +1245,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1266,11 +1285,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1306,11 +1325,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1346,11 +1365,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1386,11 +1405,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1426,11 +1445,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1573,8 +1592,8 @@ importers: version: link:../../.. devDependencies: solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 packages/astro/e2e/fixtures/solid-component: dependencies: @@ -1588,8 +1607,8 @@ importers: specifier: workspace:* version: link:../../.. solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 packages/astro/e2e/fixtures/solid-recurse: dependencies: @@ -1601,8 +1620,8 @@ importers: version: link:../../.. devDependencies: solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 packages/astro/e2e/fixtures/svelte-component: dependencies: @@ -1616,8 +1635,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/e2e/fixtures/tailwindcss: dependencies: @@ -1676,8 +1695,8 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1712,8 +1731,8 @@ importers: specifier: workspace:* version: link:../utils '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -1739,8 +1758,8 @@ importers: specifier: workspace:* version: link:../utils '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -1766,8 +1785,8 @@ importers: specifier: workspace:* version: link:../utils '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -1814,8 +1833,8 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -1835,8 +1854,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/alias-tsconfig: dependencies: @@ -1850,8 +1869,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/alias-tsconfig-baseurl-only: dependencies: @@ -1862,8 +1881,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/alias-tsconfig/deps/namespace-package: {} @@ -1987,8 +2006,8 @@ importers: specifier: ^10.23.2 version: 10.23.2 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -2020,8 +2039,8 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/astro-client-only/pkg: {} @@ -2112,8 +2131,8 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/astro-env: dependencies: @@ -2439,11 +2458,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -2526,8 +2545,8 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/component-library-shared: dependencies: @@ -2829,8 +2848,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/css-import-as-inline: dependencies: @@ -3081,8 +3100,8 @@ importers: specifier: ^10.23.2 version: 10.23.2 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -3276,11 +3295,11 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -3316,8 +3335,8 @@ importers: specifier: workspace:* version: link:../../.. solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 packages/astro/test/fixtures/lazy-layout: dependencies: @@ -3449,11 +3468,11 @@ importers: specifier: ^8.4.41 version: 8.4.41 solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -3522,8 +3541,8 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 packages/astro/test/fixtures/react-jsx-export: dependencies: @@ -3646,8 +3665,8 @@ importers: specifier: workspace:* version: link:../../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/server-islands/ssr: dependencies: @@ -3658,8 +3677,8 @@ importers: specifier: workspace:* version: link:../../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/set-html: dependencies: @@ -3712,8 +3731,8 @@ importers: specifier: workspace:* version: link:../../.. solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 packages/astro/test/fixtures/slots-svelte: dependencies: @@ -3727,8 +3746,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/slots-vue: dependencies: @@ -3752,7 +3771,7 @@ importers: version: link:../../../../integrations/solid '@solidjs/router': specifier: ^0.14.3 - version: 0.14.3(solid-js@1.8.21) + version: 0.14.3(solid-js@1.8.22) '@test/solid-jsx-component': specifier: file:./deps/solid-jsx-component version: link:deps/solid-jsx-component @@ -3760,14 +3779,14 @@ importers: specifier: workspace:* version: link:../../.. solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 packages/astro/test/fixtures/solid-component/deps/solid-jsx-component: dependencies: solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 packages/astro/test/fixtures/sourcemap: dependencies: @@ -3895,8 +3914,8 @@ importers: specifier: link:./deps/test-adapter version: link:deps/test-adapter '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -4052,8 +4071,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 packages/astro/test/fixtures/tailwindcss: dependencies: @@ -4175,8 +4194,8 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -4229,8 +4248,8 @@ importers: specifier: workspace:* version: link:../studio '@libsql/client': - specifier: ^0.9.0 - version: 0.9.0 + specifier: ^0.10.0 + version: 0.10.0 async-listen: specifier: ^3.0.1 version: 3.0.1 @@ -4239,7 +4258,7 @@ importers: version: 1.0.2 drizzle-orm: specifier: ^0.31.2 - version: 0.31.4(@libsql/client@0.9.0)(@types/react@18.3.3)(react@18.3.1) + version: 0.31.4(@libsql/client@0.10.0)(@types/react@18.3.4)(react@18.3.1) github-slugger: specifier: ^2.0.0 version: 2.0.0 @@ -4253,8 +4272,8 @@ importers: specifier: ^10.1.0 version: 10.1.0 ora: - specifier: ^8.0.1 - version: 8.0.1 + specifier: ^8.1.0 + version: 8.1.0 prompts: specifier: ^2.4.2 version: 2.4.2 @@ -4290,8 +4309,8 @@ importers: specifier: ^5.5.4 version: 5.5.4 vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) packages/db/test/fixtures/basics: dependencies: @@ -4398,8 +4417,8 @@ importers: specifier: ^3.6.2 version: link:../../../../integrations/react '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -4437,8 +4456,8 @@ importers: specifier: workspace:* version: link:../../../scripts vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) packages/integrations/alpinejs/test/fixtures/basics: dependencies: @@ -4500,7 +4519,7 @@ importers: version: link:../../astro-prism '@markdoc/markdoc': specifier: ^0.4.0 - version: 0.4.0(@types/react@18.3.3)(react@18.3.1) + version: 0.4.0(@types/react@18.3.4)(react@18.3.1) esbuild: specifier: ^0.21.5 version: 0.21.5 @@ -4530,8 +4549,8 @@ importers: specifier: ^0.18.4 version: 0.18.4 vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) packages/integrations/markdoc/test/fixtures/content-collections: dependencies: @@ -4656,6 +4675,15 @@ importers: specifier: workspace:* version: link:../../../../../astro + packages/integrations/markdoc/test/fixtures/render-with-extends-components: + dependencies: + '@astrojs/markdoc': + specifier: workspace:* + version: link:../../.. + astro: + specifier: workspace:* + version: link:../../../../../astro + packages/integrations/markdoc/test/fixtures/render-with-indented-components: dependencies: '@astrojs/markdoc': @@ -4695,8 +4723,8 @@ importers: specifier: ^4.0.3 version: 4.0.3 hast-util-to-html: - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^9.0.2 + version: 9.0.2 kleur: specifier: ^4.1.5 version: 4.1.5 @@ -4716,8 +4744,8 @@ importers: specifier: ^5.0.0 version: 5.0.0 vfile: - specifier: ^6.0.2 - version: 6.0.2 + specifier: ^6.0.3 + version: 6.0.3 devDependencies: '@types/estree': specifier: ^1.0.5 @@ -4744,8 +4772,8 @@ importers: specifier: ^3.0.0 version: 3.0.0 mdast-util-mdx-jsx: - specifier: ^3.1.2 - version: 3.1.2 + specifier: ^3.1.3 + version: 3.1.3 mdast-util-to-string: specifier: ^4.0.0 version: 4.0.0 @@ -4774,8 +4802,8 @@ importers: specifier: ^11.0.5 version: 11.0.5 vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) packages/integrations/mdx/test/fixtures/css-head-mdx: dependencies: @@ -4951,8 +4979,8 @@ importers: specifier: ^0.17.4 version: 0.17.4 '@types/server-destroy': - specifier: ^1.0.3 - version: 1.0.3 + specifier: ^1.0.4 + version: 1.0.4 astro: specifier: workspace:* version: link:../../astro @@ -5121,7 +5149,7 @@ importers: version: 7.24.7(@babel/core@7.25.2) '@preact/preset-vite': specifier: 2.8.2 - version: 2.8.2(@babel/core@7.25.2)(preact@10.23.2)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + version: 2.8.2(@babel/core@7.25.2)(preact@10.23.2)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) '@preact/signals': specifier: ^1.3.0 version: 1.3.0(preact@10.23.2) @@ -5146,14 +5174,14 @@ importers: dependencies: '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.1(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + version: 4.3.1(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) ultrahtml: specifier: ^1.5.3 version: 1.5.3 devDependencies: '@types/react': - specifier: ^18.3.3 - version: 18.3.3 + specifier: ^18.3.4 + version: 18.3.4 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 @@ -5173,8 +5201,8 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) packages/integrations/react/test/fixtures/react-component: dependencies: @@ -5262,7 +5290,7 @@ importers: dependencies: vite-plugin-solid: specifier: ^2.10.2 - version: 2.10.2(solid-js@1.8.21)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + version: 2.10.2(solid-js@1.8.22)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) devDependencies: astro: specifier: workspace:* @@ -5271,20 +5299,20 @@ importers: specifier: workspace:* version: link:../../../scripts solid-js: - specifier: ^1.8.21 - version: 1.8.21 + specifier: ^1.8.22 + version: 1.8.22 vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) packages/integrations/svelte: dependencies: '@sveltejs/vite-plugin-svelte': - specifier: ^3.1.1 - version: 3.1.1(svelte@4.2.18)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + specifier: ^3.1.2 + version: 3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) svelte2tsx: - specifier: ^0.7.15 - version: 0.7.15(svelte@4.2.18)(typescript@5.5.4) + specifier: ^0.7.16 + version: 0.7.16(svelte@4.2.19)(typescript@5.5.4) devDependencies: astro: specifier: workspace:* @@ -5293,11 +5321,11 @@ importers: specifier: workspace:* version: link:../../../scripts svelte: - specifier: ^4.2.18 - version: 4.2.18 + specifier: ^4.2.19 + version: 4.2.19 vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) packages/integrations/tailwind: dependencies: @@ -5321,8 +5349,8 @@ importers: specifier: ^3.4.10 version: 3.4.10 vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) packages/integrations/tailwind/test/fixtures/basic: dependencies: @@ -5551,16 +5579,16 @@ importers: dependencies: '@vitejs/plugin-vue': specifier: ^5.1.2 - version: 5.1.2(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) + version: 5.1.2(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) '@vitejs/plugin-vue-jsx': specifier: ^4.0.1 - version: 4.0.1(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) + version: 4.0.1(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) '@vue/compiler-sfc': specifier: ^3.4.38 version: 3.4.38 vite-plugin-vue-devtools: - specifier: ^7.3.8 - version: 7.3.8(rollup@4.21.0)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) + specifier: ^7.3.9 + version: 7.3.9(rollup@4.21.1)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) devDependencies: astro: specifier: workspace:* @@ -5575,8 +5603,8 @@ importers: specifier: ^0.18.4 version: 0.18.4 vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) vue: specifier: ^3.4.38 version: 3.4.38(typescript@5.5.4) @@ -5711,8 +5739,8 @@ importers: specifier: ^2.0.0 version: 2.0.0 hast-util-from-html: - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^2.0.2 + version: 2.0.2 hast-util-to-text: specifier: ^4.0.2 version: 4.0.2 @@ -5756,8 +5784,8 @@ importers: specifier: ^6.0.1 version: 6.0.1 vfile: - specifier: ^6.0.2 - version: 6.0.2 + specifier: ^6.0.3 + version: 6.0.3 devDependencies: '@types/estree': specifier: ^1.0.5 @@ -5790,8 +5818,8 @@ importers: specifier: ^4.1.5 version: 4.1.5 ora: - specifier: ^8.0.1 - version: 8.0.1 + specifier: ^8.1.0 + version: 8.1.0 devDependencies: astro: specifier: workspace:* @@ -5803,8 +5831,8 @@ importers: specifier: ^5.5.4 version: 5.5.4 vite: - specifier: ^5.4.1 - version: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + specifier: ^5.4.2 + version: 5.4.2(@types/node@18.19.31)(sass@1.77.8) packages/telemetry: dependencies: @@ -5891,9 +5919,6 @@ importers: esbuild-plugin-copy: specifier: ^2.1.1 version: 2.1.1(esbuild@0.21.5) - execa: - specifier: ^8.0.1 - version: 8.0.1 fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -5903,6 +5928,9 @@ importers: p-limit: specifier: ^6.1.0 version: 6.1.0 + tinyexec: + specifier: ^0.3.0 + version: 0.3.0 tsconfck: specifier: ^3.1.1 version: 3.1.1(typescript@5.5.4) @@ -5996,8 +6024,8 @@ packages: resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.25.0': - resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} + '@babel/generator@7.25.5': + resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.24.7': @@ -6090,8 +6118,8 @@ packages: resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.25.3': - resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} + '@babel/parser@7.25.4': + resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==} engines: {node: '>=6.0.0'} hasBin: true @@ -6168,12 +6196,12 @@ packages: resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.25.3': - resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} + '@babel/traverse@7.25.4': + resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==} engines: {node: '>=6.9.0'} - '@babel/types@7.25.2': - resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} + '@babel/types@7.25.4': + resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==} engines: {node: '>=6.9.0'} '@biomejs/biome@1.8.3': @@ -6719,16 +6747,16 @@ packages: resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.17.1': - resolution: {integrity: sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==} + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.1.0': resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.9.0': - resolution: {integrity: sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==} + '@eslint/js@9.9.1': + resolution: {integrity: sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.4': @@ -6910,11 +6938,11 @@ packages: peerDependencies: tslib: '2' - '@libsql/client@0.9.0': - resolution: {integrity: sha512-mT+91wtb8pxK9SWd566D5W2VUCemksUMqICRBtf0WXiS7XzNcQhWyrwYOnVrVmTSze/SCCsNNEKIkCRwk/pr2Q==} + '@libsql/client@0.10.0': + resolution: {integrity: sha512-2ERn08T4XOVx34yBtUPq0RDjAdd9TJ5qNH/izugr208ml2F94mk92qC64kXyDVQINodWJvp3kAdq6P4zTtCZ7g==} - '@libsql/core@0.9.0': - resolution: {integrity: sha512-rCsS/EC32K8ARjDQJGqauGZmkR6orOOY4I7898PyQ/mmltAkMwRgz5kjEmYRZ42o7mP0ayJfbw28qgv7SRFEgg==} + '@libsql/core@0.10.0': + resolution: {integrity: sha512-rqynAXGaiSpTsykOZdBtI1N4z4O+KZ6mt33K/aHeXAY0gSIfK/ctxuWa0Y1Bjo4FMz1idBTCXz4Ps5kITOvZZw==} '@libsql/darwin-arm64@0.3.19': resolution: {integrity: sha512-rmOqsLcDI65zzxlUOoEiPJLhqmbFsZF6p4UJQ2kMqB+Kc0Rt5/A1OAdOZ/Wo8fQfJWjR1IbkbpEINFioyKf+nQ==} @@ -7107,83 +7135,83 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.21.0': - resolution: {integrity: sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==} + '@rollup/rollup-android-arm-eabi@4.21.1': + resolution: {integrity: sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.21.0': - resolution: {integrity: sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==} + '@rollup/rollup-android-arm64@4.21.1': + resolution: {integrity: sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.21.0': - resolution: {integrity: sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==} + '@rollup/rollup-darwin-arm64@4.21.1': + resolution: {integrity: sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.21.0': - resolution: {integrity: sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==} + '@rollup/rollup-darwin-x64@4.21.1': + resolution: {integrity: sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.21.0': - resolution: {integrity: sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==} + '@rollup/rollup-linux-arm-gnueabihf@4.21.1': + resolution: {integrity: sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.21.0': - resolution: {integrity: sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==} + '@rollup/rollup-linux-arm-musleabihf@4.21.1': + resolution: {integrity: sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.21.0': - resolution: {integrity: sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==} + '@rollup/rollup-linux-arm64-gnu@4.21.1': + resolution: {integrity: sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.21.0': - resolution: {integrity: sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==} + '@rollup/rollup-linux-arm64-musl@4.21.1': + resolution: {integrity: sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.21.0': - resolution: {integrity: sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==} + '@rollup/rollup-linux-powerpc64le-gnu@4.21.1': + resolution: {integrity: sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.21.0': - resolution: {integrity: sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==} + '@rollup/rollup-linux-riscv64-gnu@4.21.1': + resolution: {integrity: sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.21.0': - resolution: {integrity: sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==} + '@rollup/rollup-linux-s390x-gnu@4.21.1': + resolution: {integrity: sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.21.0': - resolution: {integrity: sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==} + '@rollup/rollup-linux-x64-gnu@4.21.1': + resolution: {integrity: sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.21.0': - resolution: {integrity: sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==} + '@rollup/rollup-linux-x64-musl@4.21.1': + resolution: {integrity: sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.21.0': - resolution: {integrity: sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==} + '@rollup/rollup-win32-arm64-msvc@4.21.1': + resolution: {integrity: sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.21.0': - resolution: {integrity: sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==} + '@rollup/rollup-win32-ia32-msvc@4.21.1': + resolution: {integrity: sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.21.0': - resolution: {integrity: sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==} + '@rollup/rollup-win32-x64-msvc@4.21.1': + resolution: {integrity: sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==} cpu: [x64] os: [win32] @@ -7207,8 +7235,8 @@ packages: svelte: ^4.0.0 || ^5.0.0-next.0 vite: ^5.0.0 - '@sveltejs/vite-plugin-svelte@3.1.1': - resolution: {integrity: sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==} + '@sveltejs/vite-plugin-svelte@3.1.2': + resolution: {integrity: sha512-Txsm1tJvtiYeLUVRNqxZGKR/mI+CzuIQuc2gn+YCs9rMTowpNZ2Nqt53JdL8KF9bLhAf2ruR/dr9eZCwdTriRA==} engines: {node: ^18.0.0 || >=20} peerDependencies: svelte: ^4.0.0 || ^5.0.0-next.0 @@ -7376,8 +7404,8 @@ packages: '@types/react-dom@18.3.0': resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} - '@types/react@18.3.3': - resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} + '@types/react@18.3.4': + resolution: {integrity: sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==} '@types/relateurl@0.2.33': resolution: {integrity: sha512-bTQCKsVbIdzLqZhLkF5fcJQreE4y1ro4DIyVrlDNSCJRRwHhB8Z+4zXXa8jN6eDvc2HbRsEYgbvrnGvi54EpSw==} @@ -7394,8 +7422,8 @@ packages: '@types/serve-static@1.15.7': resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} - '@types/server-destroy@1.0.3': - resolution: {integrity: sha512-Qq0fn70C7TLDG1W9FCblKufNWW1OckQ41dVKV2Dku5KdZF7bexezG4e2WBaBKhdwL3HZ+cYCEIKwg2BRgzrWmA==} + '@types/server-destroy@1.0.4': + resolution: {integrity: sha512-+x8oAQ4Xp1wtDi2Hlmi7gUNXZNVhB5EoSQpi0qEmINdDN5Ab724WLGAalEdT1SudVY/NzMhbfZO7vU+klT0R+A==} '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -7424,8 +7452,8 @@ packages: '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@typescript-eslint/eslint-plugin@8.1.0': - resolution: {integrity: sha512-LlNBaHFCEBPHyD4pZXb35mzjGkuGKXU5eeCA1SxvHfiRES0E82dOounfVpL4DCqYvJEKab0bZIA0gCRpdLKkCw==} + '@typescript-eslint/eslint-plugin@8.3.0': + resolution: {integrity: sha512-FLAIn63G5KH+adZosDYiutqkOkYEx0nvcwNNfJAf+c7Ae/H35qWwTYvPZUKFj5AS+WfHG/WJJfWnDnyNUlp8UA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -7435,8 +7463,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.1.0': - resolution: {integrity: sha512-U7iTAtGgJk6DPX9wIWPPOlt1gO57097G06gIcl0N0EEnNw8RGD62c+2/DiP/zL7KrkqnnqF7gtFGR7YgzPllTA==} + '@typescript-eslint/parser@8.3.0': + resolution: {integrity: sha512-h53RhVyLu6AtpUzVCYLPhZGL5jzTD9fZL+SYf/+hYOx2bDkyQXztXSc4tbvKYHzfMXExMLiL9CWqJmVz6+78IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -7445,12 +7473,12 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@8.1.0': - resolution: {integrity: sha512-DsuOZQji687sQUjm4N6c9xABJa7fjvfIdjqpSIIVOgaENf2jFXiM9hIBZOL3hb6DHK9Nvd2d7zZnoMLf9e0OtQ==} + '@typescript-eslint/scope-manager@8.3.0': + resolution: {integrity: sha512-mz2X8WcN2nVu5Hodku+IR8GgCOl4C0G/Z1ruaWN4dgec64kDBabuXyPAr+/RgJtumv8EEkqIzf3X2U5DUKB2eg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.1.0': - resolution: {integrity: sha512-oLYvTxljVvsMnldfl6jIKxTaU7ok7km0KDrwOt1RHYu6nxlhN3TIx8k5Q52L6wR33nOwDgM7VwW1fT1qMNfFIA==} + '@typescript-eslint/type-utils@8.3.0': + resolution: {integrity: sha512-wrV6qh//nLbfXZQoj32EXKmwHf4b7L+xXLrP3FZ0GOUU72gSvLjeWUl5J5Ue5IwRxIV1TfF73j/eaBapxx99Lg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -7458,12 +7486,12 @@ packages: typescript: optional: true - '@typescript-eslint/types@8.1.0': - resolution: {integrity: sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==} + '@typescript-eslint/types@8.3.0': + resolution: {integrity: sha512-y6sSEeK+facMaAyixM36dQ5NVXTnKWunfD1Ft4xraYqxP0lC0POJmIaL/mw72CUMqjY9qfyVfXafMeaUj0noWw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.1.0': - resolution: {integrity: sha512-NTHhmufocEkMiAord/g++gWKb0Fr34e9AExBRdqgWdVBaKoei2dIyYKD9Q0jBnvfbEA5zaf8plUFMUH6kQ0vGg==} + '@typescript-eslint/typescript-estree@8.3.0': + resolution: {integrity: sha512-Mq7FTHl0R36EmWlCJWojIC1qn/ZWo2YiWYc1XVtasJ7FIgjo0MVv9rZWXEE7IK2CGrtwe1dVOxWwqXUdNgfRCA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -7471,14 +7499,14 @@ packages: typescript: optional: true - '@typescript-eslint/utils@8.1.0': - resolution: {integrity: sha512-ypRueFNKTIFwqPeJBfeIpxZ895PQhNyH4YID6js0UoBImWYoSjBsahUn9KMiJXh94uOjVBgHD9AmkyPsPnFwJA==} + '@typescript-eslint/utils@8.3.0': + resolution: {integrity: sha512-F77WwqxIi/qGkIGOGXNBLV7nykwfjLsdauRB/DOFPdv6LTF3BHHkBpq81/b5iMPSF055oO2BiivDJV4ChvNtXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@8.1.0': - resolution: {integrity: sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==} + '@typescript-eslint/visitor-keys@8.3.0': + resolution: {integrity: sha512-RmZwrTbQ9QveF15m/Cl28n0LXD6ea2CjkhH5rQ55ewz3H24w+AMCJHPVYaZ8/0HoG8Z3cLLFFycRXxeO2tz9FA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript/twoslash@3.1.0': @@ -7604,16 +7632,16 @@ packages: '@vue/compiler-ssr@3.4.38': resolution: {integrity: sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==} - '@vue/devtools-core@7.3.8': - resolution: {integrity: sha512-mEwsR7GMklWuPOBH/++DiJe0GWqQ0syDtWP0HhU8m9tebs5zQtujMXrgu+cgBAKquJAWnBz0PwNzBgBD2P+M9A==} + '@vue/devtools-core@7.3.9': + resolution: {integrity: sha512-B5zAl9ulNjI6nknSnGNRzmP/ldR9ADUwwT8HkI8Hejo1W00uK9ABUahbfrXzME296rBfmwhQuCFwJ6t9KFdbXQ==} peerDependencies: vue: ^3.0.0 - '@vue/devtools-kit@7.3.8': - resolution: {integrity: sha512-HYy3MQP1nZ6GbE4vrgJ/UB+MvZnhYmEwCa/UafrEpdpwa+jNCkz1ZdUrC5I7LpkH1ShREEV2/pZlAQdBj+ncLQ==} + '@vue/devtools-kit@7.3.9': + resolution: {integrity: sha512-Gr17nA+DaQzqyhNx1DUJr1CJRzTRfbIuuC80ZgU8MD/qNO302tv9la+ROi+Uaw+ULVwU9T71GnwLy4n8m9Lspg==} - '@vue/devtools-shared@7.3.8': - resolution: {integrity: sha512-1NiJbn7Yp47nPDWhFZyEKpB2+5/+7JYv8IQnU0ccMrgslPR2dL7u1DIyI7mLqy4HN1ll36gQy0k8GqBYSFgZJw==} + '@vue/devtools-shared@7.3.9': + resolution: {integrity: sha512-CdfMRZKXyI8vw+hqOcQIiLihB6Hbbi7WNZGp7LsuH1Qe4aYAFmTaKjSciRZ301oTnwmU/knC/s5OGuV6UNiNoA==} '@vue/reactivity@3.1.5': resolution: {integrity: sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==} @@ -7992,6 +8020,10 @@ packages: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} @@ -8521,8 +8553,8 @@ packages: resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.9.0: - resolution: {integrity: sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==} + eslint@9.9.1: + resolution: {integrity: sha512-dHvhrbfr4xFQ9/dq+jcVneZMyRYLjggWjk6RVsIiHsP8Rz6yZ8LvZ//iU4TrZF+SXWG+JkNF2OyiZRvzgRDqMg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -8592,8 +8624,8 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - expect-type@0.19.0: - resolution: {integrity: sha512-piv9wz3IrAG4Wnk2A+n2VRCHieAyOSxrRLU872Xo6nyn39kYXKDALk4OcqnvLRnFvkz659CnWC8MWZLuuQnoqg==} + expect-type@0.20.0: + resolution: {integrity: sha512-uHaC9LYNv6BcW+8SvXcwUUDCrrUxt3GSa61DFvTHj8JC+M0hekMFBwMlCarLQDk5bbpZ2vStpnQPIwRuV98YMw==} engines: {node: '>=12.0.0'} express@4.19.2: @@ -8858,8 +8890,8 @@ packages: hast-util-from-dom@5.0.0: resolution: {integrity: sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==} - hast-util-from-html@2.0.1: - resolution: {integrity: sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==} + hast-util-from-html@2.0.2: + resolution: {integrity: sha512-HwOHwxdt2zC5KQ/CNoybBntRook2zJvfZE/u5/Ap7aLPe22bDqen7KwGkOqOyzL5zIqKwiYX/OTtE0FWgr6XXA==} hast-util-from-parse5@8.0.1: resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==} @@ -8885,8 +8917,8 @@ packages: hast-util-to-estree@3.1.0: resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==} - hast-util-to-html@9.0.1: - resolution: {integrity: sha512-hZOofyZANbyWo+9RP75xIDV/gq+OUKx+T46IlwERnKmfpwp81XBFbT9mi26ws+SJchA4RVUQwIBJpqEOBhMzEQ==} + hast-util-to-html@9.0.2: + resolution: {integrity: sha512-RP5wNpj5nm1Z8cloDv4Sl4RS8jH5HYa0v93YB6Wb4poEzgMo/dAAL0KcT4974dCjcNG5pkLqTImeFHHCwwfY3g==} hast-util-to-jsx-runtime@2.3.0: resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==} @@ -9348,6 +9380,9 @@ packages: resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -9413,8 +9448,8 @@ packages: mdast-util-mdx-expression@2.0.0: resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} - mdast-util-mdx-jsx@3.1.2: - resolution: {integrity: sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==} + mdast-util-mdx-jsx@3.1.3: + resolution: {integrity: sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==} mdast-util-mdx@3.0.0: resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} @@ -9583,8 +9618,8 @@ packages: micromark@4.0.0: resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} - micromatch@4.0.7: - resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} mime-db@1.52.0: @@ -9608,6 +9643,10 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + mini-svg-data-uri@1.4.4: resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} hasBin: true @@ -9682,8 +9721,8 @@ packages: engines: {node: ^18 || >=20} hasBin: true - nanostores@0.11.2: - resolution: {integrity: sha512-6bucNxMJA5rNV554WQl+MWGng0QVMzlRgpKTHHfIbVLrhQ+yRXBychV9ECGVuuUfCMQPjfIG9bj8oJFZ9hYP/Q==} + nanostores@0.11.3: + resolution: {integrity: sha512-TUes3xKIX33re4QzdxwZ6tdbodjmn3tWXCEc1uokiEmo14sI1EaGYNs2k3bU2pyyGNmBqFGAVl6jAGWd06AVIg==} engines: {node: ^18.0.0 || >=20.0.0} natural-compare@1.4.0: @@ -9805,6 +9844,10 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + only-allow@1.2.1: resolution: {integrity: sha512-M7CJbmv7UCopc0neRKdzfoGWaVZC+xC1925GitKH9EAqYFzX9//25Q7oX4+jw0tiCCj+t5l6VZh8UPH23NZkMA==} hasBin: true @@ -9820,8 +9863,8 @@ packages: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} - ora@8.0.1: - resolution: {integrity: sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==} + ora@8.1.0: + resolution: {integrity: sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==} engines: {node: '>=18'} os-tmpdir@1.0.2: @@ -10447,6 +10490,10 @@ packages: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + retext-latin@4.0.0: resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} @@ -10474,8 +10521,8 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rollup@4.21.0: - resolution: {integrity: sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==} + rollup@4.21.1: + resolution: {integrity: sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -10653,8 +10700,8 @@ packages: resolution: {integrity: sha512-TzobUYoEft/xBtb2voRPryAUIvYguG0V7Tt3de79I1WfXgCwelqVsGuZSnu3GFGRZhXR90AeEYIM+icuB/S06Q==} hasBin: true - solid-js@1.8.21: - resolution: {integrity: sha512-FHUGdoo7GVa1BTpGh/4UtwIISde0vSXoqNB6KFpHiTgkIY959tmCJ7NYQAWDfScBfnpoMGZR8lFz0DiwW/gFlw==} + solid-js@1.8.22: + resolution: {integrity: sha512-VBzN5j+9Y4rqIKEnK301aBk+S7fvFSTs9ljg+YEdFxjNjH0hkjXPiQRcws9tE5fUzMznSS6KToL5hwMfHDgpLA==} solid-refresh@0.6.3: resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==} @@ -10803,14 +10850,14 @@ packages: peerDependencies: svelte: ^3.19.0 || ^4.0.0 - svelte2tsx@0.7.15: - resolution: {integrity: sha512-91RbLJI448FR1UEZqXSS3ucVMERuWo8ACOhxfkBPK1CL2ocGMOC5bwc8tzFvb/Ji8NqZ7wmSGfvRebcUsiauKA==} + svelte2tsx@0.7.16: + resolution: {integrity: sha512-faI3t1N5I7RkrXGMLfUdfWg6DTPi8RisfES/00QzXh+faU2pQ3r/W2dUD0ENGh+qNzltIcjbfCW9PES9JkaSXg==} peerDependencies: svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 typescript: ^4.9.4 || ^5.0.0 - svelte@4.2.18: - resolution: {integrity: sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==} + svelte@4.2.19: + resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==} engines: {node: '>=16'} svg-tags@1.0.0: @@ -10864,6 +10911,9 @@ packages: tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} + tinyexec@0.3.0: + resolution: {integrity: sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==} + tinypool@1.0.0: resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -10944,38 +10994,38 @@ packages: tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - turbo-darwin-64@2.0.14: - resolution: {integrity: sha512-kwfDmjNwlNfvtrvT29+ZBg5n1Wvxl891bFHchMJyzMoR0HOE9N1NSNdSZb9wG3e7sYNIu4uDkNk+VBEqJW0HzQ==} + turbo-darwin-64@2.1.0: + resolution: {integrity: sha512-gHwpDk2gyB7qZ57gUUwDIS/IkglqEjjVtPZCTxmCRg28Tiwjui0azsLVKrnHP9UZHllozwbi28x8HXLXLEFF1w==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.0.14: - resolution: {integrity: sha512-m3LXYEshCx3wc4ZClM6gb01KYpFmtjQ9IBF3A7ofjb6ahux3xlYZJZ3uFCLAGHuvGLuJ3htfiPbwlDPTdknqqw==} + turbo-darwin-arm64@2.1.0: + resolution: {integrity: sha512-GLaqGetNC6eS4eqXgsheLOHic/OcnGCGDi5boVf+TFZTXYH6YE15L4ugZha4xHXCr1KouCLILHh+f8EHEmWylg==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.0.14: - resolution: {integrity: sha512-7vBzCPdoTtR92SNn2JMgj1FlMmyonGmpMaQdgAB1OVYtuQ6NVGoh7/lODfaILqXjpvmFSVbpBIDrKOT6EvcprQ==} + turbo-linux-64@2.1.0: + resolution: {integrity: sha512-VzBOsj7JyGoZtiNZZ6brjnY7UehRnClluw7pwznuLPzClkqOOPMd2jOcgkWxnP/xW4NBmOoFANXXrtvKBD4f2w==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.0.14: - resolution: {integrity: sha512-jwH+c0bfjpBf26K/tdEFatmnYyXwGROjbr6bZmNcL8R+IkGAc/cglL+OToqJnQZTgZvH7uDGbeSyUo7IsHyjuA==} + turbo-linux-arm64@2.1.0: + resolution: {integrity: sha512-St7svJnOO5g4F6R7Z32e10I/0M3e6qpNjEYybXwPNul9NSfnUXeky4WoKaALwqNhyJ7nYemoFpZ1d+i8hFQTHg==} cpu: [arm64] os: [linux] - turbo-windows-64@2.0.14: - resolution: {integrity: sha512-w9/XwkHSzvLjmioo6cl3S1yRfI6swxsV1j1eJwtl66JM4/pn0H2rBa855R0n7hZnmI6H5ywLt/nLt6Ae8RTDmw==} + turbo-windows-64@2.1.0: + resolution: {integrity: sha512-iSobNud2MrJ1SZ1upVPlErT8xexsr0MQtKapdfq6z0M0rBnrDGEq5bUCSScWyGu+O4+glB4br9xkTAkGFqaxqQ==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.0.14: - resolution: {integrity: sha512-XaQlyYk+Rf4xS5XWCo8XCMIpssgGGy8blzLfolN6YBp4baElIWMlkLZHDbGyiFmCbNf9I9gJI64XGRG+LVyyjA==} + turbo-windows-arm64@2.1.0: + resolution: {integrity: sha512-d61jN4rjE5PnUfF66GKrKoj8S8Ql4FGXzFFzZz4kjsHpZZzCTtqlzPZBmd1byzGYhDPTorTqG3G1USohbdyohA==} cpu: [arm64] os: [win32] - turbo@2.0.14: - resolution: {integrity: sha512-00JjdCMD/cpsjP0Izkjcm8Oaor5yUCfDwODtaLb+WyblyadkaDEisGhy3Dbd5az9n+5iLSPiUgf+WjPbns6MRg==} + turbo@2.1.0: + resolution: {integrity: sha512-A969/LO/sPHKlapIarY2VVzqQ5JnnW2/1kksZlnMEpsRD6gwOELvVL+ozfMiO7av9RILt3UeN02L17efr6HUCA==} hasBin: true type-check@0.4.0: @@ -11006,8 +11056,8 @@ packages: typescript-auto-import-cache@0.3.3: resolution: {integrity: sha512-ojEC7+Ci1ij9eE6hp8Jl9VUNnsEKzztktP5gtYNRMrTmfXVwA1PITYYAkpxCvvupdSYa/Re51B6KMcv1CTZEUA==} - typescript-eslint@8.1.0: - resolution: {integrity: sha512-prB2U3jXPJLpo1iVLN338Lvolh6OrcCZO+9Yv6AR+tvegPPptYCDBIHiEEUdqRi8gAv2bXNKfMUrgAd2ejn/ow==} + typescript-eslint@8.3.0: + resolution: {integrity: sha512-EvWjwWLwwKDIJuBjk2I6UkV8KEQcwZ0VM10nR1rIunRDIP67QJTZAHBXTX0HW/oI1H10YESF8yWie8fRQxjvFA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -11037,8 +11087,8 @@ packages: undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici@6.19.7: - resolution: {integrity: sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==} + undici@6.19.8: + resolution: {integrity: sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==} engines: {node: '>=18.17'} unicorn-magic@0.1.0: @@ -11157,8 +11207,8 @@ packages: vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - vfile@6.0.2: - resolution: {integrity: sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==} + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} vite-hot-client@0.2.3: resolution: {integrity: sha512-rOGAV7rUlUHX89fP2p2v0A2WWvV3QMX2UYq0fRqsWSvFvev4atHWqjwGoKaZT1VTKyLGk533ecu3eyd0o59CAg==} @@ -11190,8 +11240,8 @@ packages: '@testing-library/jest-dom': optional: true - vite-plugin-vue-devtools@7.3.8: - resolution: {integrity: sha512-b5t4wxCb5g5cjh+odNpgnB7iX7gA6FJnKugFqX2/YZX9I4fvMjlj1bUnCKnvPlmwnFxClYgdmgZcCh2RyhZgvw==} + vite-plugin-vue-devtools@7.3.9: + resolution: {integrity: sha512-ybDV2kepW0NpusvtfbRKHs0pvyrReNcFtL572gyZ6Alox6u5uebYefd2eAG/7mJSU3NPI5UxUH1e/Mof5exdlw==} engines: {node: '>=v14.21.3'} peerDependencies: vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 @@ -11206,8 +11256,8 @@ packages: peerDependencies: vue: '>=3.2.13' - vite@5.4.1: - resolution: {integrity: sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==} + vite@5.4.2: + resolution: {integrity: sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -11689,14 +11739,14 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.0 + '@babel/generator': 7.25.5 '@babel/helper-compilation-targets': 7.25.2 '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) '@babel/helpers': 7.25.0 - '@babel/parser': 7.25.3 + '@babel/parser': 7.25.4 '@babel/template': 7.25.0 - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 convert-source-map: 2.0.0 debug: 4.3.6 gensync: 1.0.0-beta.2 @@ -11705,16 +11755,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.25.0': + '@babel/generator@7.25.5': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 '@babel/helper-annotate-as-pure@7.24.7': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@babel/helper-compilation-targets@7.25.2': dependencies: @@ -11741,32 +11791,32 @@ snapshots: '@babel/helper-environment-visitor@7.24.7': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@babel/helper-function-name@7.24.7': dependencies: '@babel/template': 7.25.0 - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@babel/helper-member-expression-to-functions@7.24.7': dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.18.6': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@babel/helper-module-imports@7.22.15': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@babel/helper-module-imports@7.24.7': dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 transitivePeerDependencies: - supports-color @@ -11776,13 +11826,13 @@ snapshots: '@babel/helper-module-imports': 7.24.7 '@babel/helper-simple-access': 7.24.7 '@babel/helper-validator-identifier': 7.24.7 - '@babel/traverse': 7.25.3 + '@babel/traverse': 7.25.4 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.24.7': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@babel/helper-plugin-utils@7.24.8': {} @@ -11797,21 +11847,21 @@ snapshots: '@babel/helper-simple-access@7.24.7': dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.24.7': dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 transitivePeerDependencies: - supports-color '@babel/helper-split-export-declaration@7.24.7': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@babel/helper-string-parser@7.24.8': {} @@ -11822,7 +11872,7 @@ snapshots: '@babel/helpers@7.25.0': dependencies: '@babel/template': 7.25.0 - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@babel/highlight@7.24.7': dependencies: @@ -11831,9 +11881,9 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.0.1 - '@babel/parser@7.25.3': + '@babel/parser@7.25.4': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@babel/plugin-proposal-decorators@7.24.1(@babel/core@7.25.2)': dependencies: @@ -11893,7 +11943,7 @@ snapshots: '@babel/helper-module-imports': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 transitivePeerDependencies: - supports-color @@ -11914,22 +11964,22 @@ snapshots: '@babel/template@7.25.0': dependencies: '@babel/code-frame': 7.24.7 - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 + '@babel/parser': 7.25.4 + '@babel/types': 7.25.4 - '@babel/traverse@7.25.3': + '@babel/traverse@7.25.4': dependencies: '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.0 - '@babel/parser': 7.25.3 + '@babel/generator': 7.25.5 + '@babel/parser': 7.25.4 '@babel/template': 7.25.0 - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 debug: 4.3.6 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.25.2': + '@babel/types@7.25.4': dependencies: '@babel/helper-string-parser': 7.24.8 '@babel/helper-validator-identifier': 7.24.7 @@ -12054,7 +12104,7 @@ snapshots: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - micromatch: 4.0.7 + micromatch: 4.0.8 '@changesets/errors@0.2.0': dependencies: @@ -12094,7 +12144,7 @@ snapshots: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 - micromatch: 4.0.7 + micromatch: 4.0.8 spawndamnit: 2.0.0 '@changesets/logger@0.1.0': @@ -12492,14 +12542,14 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.9.0(jiti@1.21.0))': + '@eslint-community/eslint-utils@4.4.0(eslint@9.9.1(jiti@1.21.0))': dependencies: - eslint: 9.9.0(jiti@1.21.0) + eslint: 9.9.1(jiti@1.21.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.11.0': {} - '@eslint/config-array@0.17.1': + '@eslint/config-array@0.18.0': dependencies: '@eslint/object-schema': 2.1.4 debug: 4.3.6 @@ -12521,7 +12571,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.9.0': {} + '@eslint/js@9.9.1': {} '@eslint/object-schema@2.1.4': {} @@ -12654,9 +12704,9 @@ snapshots: dependencies: tslib: 2.6.2 - '@libsql/client@0.9.0': + '@libsql/client@0.10.0': dependencies: - '@libsql/core': 0.9.0 + '@libsql/core': 0.10.0 '@libsql/hrana-client': 0.6.2 js-base64: 3.7.7 libsql: 0.4.1 @@ -12665,7 +12715,7 @@ snapshots: - bufferutil - utf-8-validate - '@libsql/core@0.9.0': + '@libsql/core@0.10.0': dependencies: js-base64: 3.7.7 @@ -12768,10 +12818,10 @@ snapshots: - encoding - supports-color - '@markdoc/markdoc@0.4.0(@types/react@18.3.3)(react@18.3.1)': + '@markdoc/markdoc@0.4.0(@types/react@18.3.4)(react@18.3.1)': optionalDependencies: '@types/markdown-it': 12.2.3 - '@types/react': 18.3.3 + '@types/react': 18.3.4 react: 18.3.1 '@mdx-js/mdx@3.0.1': @@ -12798,13 +12848,13 @@ snapshots: unist-util-position-from-estree: 2.0.0 unist-util-stringify-position: 4.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.2 + vfile: 6.0.3 transitivePeerDependencies: - supports-color - '@nanostores/preact@0.5.2(nanostores@0.11.2)(preact@10.23.2)': + '@nanostores/preact@0.5.2(nanostores@0.11.3)(preact@10.23.2)': dependencies: - nanostores: 0.11.2 + nanostores: 0.11.3 preact: 10.23.2 '@neon-rs/load@0.0.4': {} @@ -12832,12 +12882,12 @@ snapshots: '@polka/url@1.0.0-next.25': {} - '@preact/preset-vite@2.8.2(@babel/core@7.25.2)(preact@10.23.2)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))': + '@preact/preset-vite@2.8.2(@babel/core@7.25.2)(preact@10.23.2)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))': dependencies: '@babel/core': 7.25.2 '@babel/plugin-transform-react-jsx': 7.25.2(@babel/core@7.25.2) '@babel/plugin-transform-react-jsx-development': 7.24.7(@babel/core@7.25.2) - '@prefresh/vite': 2.4.5(preact@10.23.2)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + '@prefresh/vite': 2.4.5(preact@10.23.2)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) '@rollup/pluginutils': 4.2.1 babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.25.2) debug: 4.3.6 @@ -12847,7 +12897,7 @@ snapshots: resolve: 1.22.8 source-map: 0.7.4 stack-trace: 1.0.0-pre2 - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) transitivePeerDependencies: - preact - supports-color @@ -12867,7 +12917,7 @@ snapshots: '@prefresh/utils@1.2.0': {} - '@prefresh/vite@2.4.5(preact@10.23.2)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))': + '@prefresh/vite@2.4.5(preact@10.23.2)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))': dependencies: '@babel/core': 7.25.2 '@prefresh/babel-plugin': 0.5.1 @@ -12875,7 +12925,7 @@ snapshots: '@prefresh/utils': 1.2.0 '@rollup/pluginutils': 4.2.1 preact: 10.23.2 - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) transitivePeerDependencies: - supports-color @@ -12884,60 +12934,60 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 - '@rollup/pluginutils@5.1.0(rollup@4.21.0)': + '@rollup/pluginutils@5.1.0(rollup@4.21.1)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.21.0 + rollup: 4.21.1 - '@rollup/rollup-android-arm-eabi@4.21.0': + '@rollup/rollup-android-arm-eabi@4.21.1': optional: true - '@rollup/rollup-android-arm64@4.21.0': + '@rollup/rollup-android-arm64@4.21.1': optional: true - '@rollup/rollup-darwin-arm64@4.21.0': + '@rollup/rollup-darwin-arm64@4.21.1': optional: true - '@rollup/rollup-darwin-x64@4.21.0': + '@rollup/rollup-darwin-x64@4.21.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.21.0': + '@rollup/rollup-linux-arm-gnueabihf@4.21.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.21.0': + '@rollup/rollup-linux-arm-musleabihf@4.21.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.21.0': + '@rollup/rollup-linux-arm64-gnu@4.21.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.21.0': + '@rollup/rollup-linux-arm64-musl@4.21.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.21.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.21.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.21.0': + '@rollup/rollup-linux-riscv64-gnu@4.21.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.21.0': + '@rollup/rollup-linux-s390x-gnu@4.21.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.21.0': + '@rollup/rollup-linux-x64-gnu@4.21.1': optional: true - '@rollup/rollup-linux-x64-musl@4.21.0': + '@rollup/rollup-linux-x64-musl@4.21.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.21.0': + '@rollup/rollup-win32-arm64-msvc@4.21.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.21.0': + '@rollup/rollup-win32-ia32-msvc@4.21.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.21.0': + '@rollup/rollup-win32-x64-msvc@4.21.1': optional: true '@shikijs/core@1.14.1': @@ -12946,30 +12996,30 @@ snapshots: '@sindresorhus/merge-streams@2.3.0': {} - '@solidjs/router@0.14.3(solid-js@1.8.21)': + '@solidjs/router@0.14.3(solid-js@1.8.22)': dependencies: - solid-js: 1.8.21 + solid-js: 1.8.22 - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)))(svelte@4.2.18)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@4.2.18)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) debug: 4.3.6 - svelte: 4.2.18 - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + svelte: 4.2.19 + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)))(svelte@4.2.18)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) debug: 4.3.6 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.11 - svelte: 4.2.18 - svelte-hmr: 0.16.0(svelte@4.2.18) - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) - vitefu: 0.2.5(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + svelte: 4.2.19 + svelte-hmr: 0.16.0(svelte@4.2.19) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) + vitefu: 0.2.5(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) transitivePeerDependencies: - supports-color @@ -12990,24 +13040,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 + '@babel/parser': 7.25.4 + '@babel/types': 7.25.4 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 + '@babel/parser': 7.25.4 + '@babel/types': 7.25.4 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 '@types/body-parser@1.19.5': dependencies: @@ -13143,9 +13193,9 @@ snapshots: '@types/react-dom@18.3.0': dependencies: - '@types/react': 18.3.3 + '@types/react': 18.3.4 - '@types/react@18.3.3': + '@types/react@18.3.4': dependencies: '@types/prop-types': 15.7.12 csstype: 3.1.3 @@ -13169,7 +13219,7 @@ snapshots: '@types/node': 18.19.31 '@types/send': 0.17.4 - '@types/server-destroy@1.0.3': + '@types/server-destroy@1.0.4': dependencies: '@types/node': 18.19.31 @@ -13197,15 +13247,15 @@ snapshots: '@types/yargs-parser@21.0.3': {} - '@typescript-eslint/eslint-plugin@8.1.0(@typescript-eslint/parser@8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4))(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4)': + '@typescript-eslint/eslint-plugin@8.3.0(@typescript-eslint/parser@8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4)': dependencies: '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4) - '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/type-utils': 8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4) - '@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4) - '@typescript-eslint/visitor-keys': 8.1.0 - eslint: 9.9.0(jiti@1.21.0) + '@typescript-eslint/parser': 8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4) + '@typescript-eslint/scope-manager': 8.3.0 + '@typescript-eslint/type-utils': 8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4) + '@typescript-eslint/utils': 8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 8.3.0 + eslint: 9.9.1(jiti@1.21.0) graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 @@ -13215,28 +13265,28 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4)': + '@typescript-eslint/parser@8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4)': dependencies: - '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.5.4) - '@typescript-eslint/visitor-keys': 8.1.0 + '@typescript-eslint/scope-manager': 8.3.0 + '@typescript-eslint/types': 8.3.0 + '@typescript-eslint/typescript-estree': 8.3.0(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 8.3.0 debug: 4.3.6 - eslint: 9.9.0(jiti@1.21.0) + eslint: 9.9.1(jiti@1.21.0) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.1.0': + '@typescript-eslint/scope-manager@8.3.0': dependencies: - '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/visitor-keys': 8.1.0 + '@typescript-eslint/types': 8.3.0 + '@typescript-eslint/visitor-keys': 8.3.0 - '@typescript-eslint/type-utils@8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4)': + '@typescript-eslint/type-utils@8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4)': dependencies: - '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 8.3.0(typescript@5.5.4) + '@typescript-eslint/utils': 8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4) debug: 4.3.6 ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: @@ -13245,14 +13295,14 @@ snapshots: - eslint - supports-color - '@typescript-eslint/types@8.1.0': {} + '@typescript-eslint/types@8.3.0': {} - '@typescript-eslint/typescript-estree@8.1.0(typescript@5.5.4)': + '@typescript-eslint/typescript-estree@8.3.0(typescript@5.5.4)': dependencies: - '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/visitor-keys': 8.1.0 + '@typescript-eslint/types': 8.3.0 + '@typescript-eslint/visitor-keys': 8.3.0 debug: 4.3.6 - globby: 11.1.0 + fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.4 semver: 7.6.3 @@ -13262,20 +13312,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4)': + '@typescript-eslint/utils@8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0(jiti@1.21.0)) - '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.5.4) - eslint: 9.9.0(jiti@1.21.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.0)) + '@typescript-eslint/scope-manager': 8.3.0 + '@typescript-eslint/types': 8.3.0 + '@typescript-eslint/typescript-estree': 8.3.0(typescript@5.5.4) + eslint: 9.9.1(jiti@1.21.0) transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@8.1.0': + '@typescript-eslint/visitor-keys@8.3.0': dependencies: - '@typescript-eslint/types': 8.1.0 + '@typescript-eslint/types': 8.3.0 eslint-visitor-keys: 3.4.3 '@typescript/twoslash@3.1.0': @@ -13319,37 +13369,37 @@ snapshots: estree-walker: 2.0.2 glob: 7.2.3 graceful-fs: 4.2.11 - micromatch: 4.0.7 + micromatch: 4.0.8 node-gyp-build: 4.8.0 resolve-from: 5.0.0 transitivePeerDependencies: - encoding - supports-color - '@vitejs/plugin-react@4.3.1(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))': + '@vitejs/plugin-react@4.3.1(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))': dependencies: '@babel/core': 7.25.2 '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.25.2) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.0.1(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4))': + '@vitejs/plugin-vue-jsx@4.0.1(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4))': dependencies: '@babel/core': 7.25.2 '@babel/plugin-transform-typescript': 7.24.7(@babel/core@7.25.2) '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.25.2) - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) vue: 3.4.38(typescript@5.5.4) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.1.2(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4))': + '@vitejs/plugin-vue@5.1.2(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4))': dependencies: - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) vue: 3.4.38(typescript@5.5.4) '@vitest/expect@2.0.5': @@ -13443,8 +13493,8 @@ snapshots: '@babel/helper-plugin-utils': 7.24.8 '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) '@babel/template': 7.25.0 - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 '@vue/babel-helper-vue-transform-on': 1.2.2 '@vue/babel-plugin-resolve-type': 1.2.2(@babel/core@7.25.2) camelcase: 6.3.0 @@ -13461,12 +13511,12 @@ snapshots: '@babel/core': 7.25.2 '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.24.8 - '@babel/parser': 7.25.3 + '@babel/parser': 7.25.4 '@vue/compiler-sfc': 3.4.38 '@vue/compiler-core@3.4.38': dependencies: - '@babel/parser': 7.25.3 + '@babel/parser': 7.25.4 '@vue/shared': 3.4.38 entities: 4.5.0 estree-walker: 2.0.2 @@ -13479,7 +13529,7 @@ snapshots: '@vue/compiler-sfc@3.4.38': dependencies: - '@babel/parser': 7.25.3 + '@babel/parser': 7.25.4 '@vue/compiler-core': 3.4.38 '@vue/compiler-dom': 3.4.38 '@vue/compiler-ssr': 3.4.38 @@ -13494,21 +13544,21 @@ snapshots: '@vue/compiler-dom': 3.4.38 '@vue/shared': 3.4.38 - '@vue/devtools-core@7.3.8(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4))': + '@vue/devtools-core@7.3.9(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4))': dependencies: - '@vue/devtools-kit': 7.3.8 - '@vue/devtools-shared': 7.3.8 + '@vue/devtools-kit': 7.3.9 + '@vue/devtools-shared': 7.3.9 mitt: 3.0.1 nanoid: 3.3.7 pathe: 1.1.2 - vite-hot-client: 0.2.3(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + vite-hot-client: 0.2.3(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) vue: 3.4.38(typescript@5.5.4) transitivePeerDependencies: - vite - '@vue/devtools-kit@7.3.8': + '@vue/devtools-kit@7.3.9': dependencies: - '@vue/devtools-shared': 7.3.8 + '@vue/devtools-shared': 7.3.9 birpc: 0.2.17 hookable: 5.5.3 mitt: 3.0.1 @@ -13516,7 +13566,7 @@ snapshots: speakingurl: 14.0.1 superjson: 2.2.1 - '@vue/devtools-shared@7.3.8': + '@vue/devtools-shared@7.3.9': dependencies: rfdc: 1.4.1 @@ -13731,7 +13781,7 @@ snapshots: '@babel/core': 7.25.2 '@babel/helper-module-imports': 7.18.6 '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/types': 7.25.2 + '@babel/types': 7.25.4 html-entities: 2.3.3 validate-html-nesting: 1.2.2 @@ -13915,7 +13965,7 @@ snapshots: parse5: 7.1.2 parse5-htmlparser2-tree-adapter: 7.0.0 parse5-parser-stream: 7.1.2 - undici: 6.19.7 + undici: 6.19.8 whatwg-mimetype: 4.0.0 chokidar@3.6.0: @@ -13950,6 +14000,10 @@ snapshots: dependencies: restore-cursor: 4.0.0 + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + cli-spinners@2.9.2: {} cli-table3@0.6.4: @@ -14222,10 +14276,10 @@ snapshots: dotenv@8.6.0: {} - drizzle-orm@0.31.4(@libsql/client@0.9.0)(@types/react@18.3.3)(react@18.3.1): + drizzle-orm@0.31.4(@libsql/client@0.10.0)(@types/react@18.3.4)(react@18.3.1): optionalDependencies: - '@libsql/client': 0.9.0 - '@types/react': 18.3.3 + '@libsql/client': 0.10.0 + '@types/react': 18.3.4 react: 18.3.1 dset@3.1.3: {} @@ -14319,12 +14373,12 @@ snapshots: eslint-plugin-no-only-tests@3.3.0: {} - eslint-plugin-regexp@2.6.0(eslint@9.9.0(jiti@1.21.0)): + eslint-plugin-regexp@2.6.0(eslint@9.9.1(jiti@1.21.0)): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0(jiti@1.21.0)) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.0)) '@eslint-community/regexpp': 4.11.0 comment-parser: 1.4.1 - eslint: 9.9.0(jiti@1.21.0) + eslint: 9.9.1(jiti@1.21.0) jsdoc-type-pratt-parser: 4.0.0 refa: 0.12.1 regexp-ast-analysis: 0.7.1 @@ -14339,13 +14393,13 @@ snapshots: eslint-visitor-keys@4.0.0: {} - eslint@9.9.0(jiti@1.21.0): + eslint@9.9.1(jiti@1.21.0): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0(jiti@1.21.0)) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.0)) '@eslint-community/regexpp': 4.11.0 - '@eslint/config-array': 0.17.1 + '@eslint/config-array': 0.18.0 '@eslint/eslintrc': 3.1.0 - '@eslint/js': 9.9.0 + '@eslint/js': 9.9.1 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.3.0 '@nodelib/fs.walk': 1.2.8 @@ -14448,7 +14502,7 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - expect-type@0.19.0: {} + expect-type@0.20.0: {} express@4.19.2: dependencies: @@ -14508,7 +14562,7 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.7 + micromatch: 4.0.8 fast-json-stable-stringify@2.1.0: {} @@ -14567,7 +14621,7 @@ snapshots: find-yarn-workspace-root2@1.2.16: dependencies: - micromatch: 4.0.7 + micromatch: 4.0.8 pkg-dir: 4.2.0 flat-cache@4.0.1: @@ -14769,13 +14823,13 @@ snapshots: hastscript: 8.0.0 web-namespaces: 2.0.1 - hast-util-from-html@2.0.1: + hast-util-from-html@2.0.2: dependencies: '@types/hast': 3.0.4 devlop: 1.1.0 hast-util-from-parse5: 8.0.1 parse5: 7.1.2 - vfile: 6.0.2 + vfile: 6.0.3 vfile-message: 4.0.2 hast-util-from-parse5@8.0.1: @@ -14785,7 +14839,7 @@ snapshots: devlop: 1.1.0 hastscript: 8.0.0 property-information: 6.5.0 - vfile: 6.0.2 + vfile: 6.0.3 vfile-location: 5.0.2 web-namespaces: 2.0.1 @@ -14817,7 +14871,7 @@ snapshots: parse5: 7.1.2 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.2 + vfile: 6.0.3 web-namespaces: 2.0.1 zwitch: 2.0.4 @@ -14851,7 +14905,7 @@ snapshots: estree-util-is-identifier-name: 3.0.0 hast-util-whitespace: 3.0.0 mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.1.2 + mdast-util-mdx-jsx: 3.1.3 mdast-util-mdxjs-esm: 2.0.1 property-information: 6.5.0 space-separated-tokens: 2.0.2 @@ -14861,13 +14915,12 @@ snapshots: transitivePeerDependencies: - supports-color - hast-util-to-html@9.0.1: + hast-util-to-html@9.0.2: dependencies: '@types/hast': 3.0.4 '@types/unist': 3.0.3 ccount: 2.0.1 comma-separated-tokens: 2.0.3 - hast-util-raw: 9.0.2 hast-util-whitespace: 3.0.0 html-void-elements: 3.0.0 mdast-util-to-hast: 13.1.0 @@ -14886,7 +14939,7 @@ snapshots: estree-util-is-identifier-name: 3.0.0 hast-util-whitespace: 3.0.0 mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.1.2 + mdast-util-mdx-jsx: 3.1.3 mdast-util-mdxjs-esm: 2.0.1 property-information: 6.5.0 space-separated-tokens: 2.0.2 @@ -15377,6 +15430,12 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magicast@0.3.5: + dependencies: + '@babel/parser': 7.25.4 + '@babel/types': 7.25.4 + source-map-js: 1.2.0 + make-dir@3.1.0: dependencies: semver: 6.3.1 @@ -15515,7 +15574,7 @@ snapshots: transitivePeerDependencies: - supports-color - mdast-util-mdx-jsx@3.1.2: + mdast-util-mdx-jsx@3.1.3: dependencies: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 @@ -15527,7 +15586,6 @@ snapshots: mdast-util-to-markdown: 2.1.0 parse-entities: 4.0.1 stringify-entities: 4.0.4 - unist-util-remove-position: 5.0.0 unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 transitivePeerDependencies: @@ -15537,7 +15595,7 @@ snapshots: dependencies: mdast-util-from-markdown: 2.0.0 mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.1.2 + mdast-util-mdx-jsx: 3.1.3 mdast-util-mdxjs-esm: 2.0.1 mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: @@ -15569,7 +15627,7 @@ snapshots: trim-lines: 3.0.1 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.2 + vfile: 6.0.3 mdast-util-to-markdown@2.1.0: dependencies: @@ -15899,7 +15957,7 @@ snapshots: transitivePeerDependencies: - supports-color - micromatch@4.0.7: + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 @@ -15916,6 +15974,8 @@ snapshots: mimic-fn@4.0.0: {} + mimic-function@5.0.1: {} + mini-svg-data-uri@1.4.4: {} minimatch@3.1.2: @@ -15969,7 +16029,7 @@ snapshots: nanoid@5.0.7: {} - nanostores@0.11.2: {} + nanostores@0.11.3: {} natural-compare@1.4.0: {} @@ -16087,6 +16147,10 @@ snapshots: dependencies: mimic-fn: 4.0.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + only-allow@1.2.1: dependencies: which-pm-runs: 1.1.0 @@ -16109,10 +16173,10 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - ora@8.0.1: + ora@8.1.0: dependencies: chalk: 5.3.0 - cli-cursor: 4.0.0 + cli-cursor: 5.0.0 cli-spinners: 2.9.2 is-interactive: 2.0.0 is-unicode-supported: 2.0.0 @@ -16188,7 +16252,7 @@ snapshots: nlcst-to-string: 4.0.0 unist-util-modify-children: 4.0.0 unist-util-visit-children: 3.0.0 - vfile: 6.0.2 + vfile: 6.0.3 parse-numeric-range@1.3.0: {} @@ -16684,7 +16748,7 @@ snapshots: rehype-parse@9.0.0: dependencies: '@types/hast': 3.0.4 - hast-util-from-html: 2.0.1 + hast-util-from-html: 2.0.2 unified: 11.0.5 rehype-pretty-code@0.13.2(shiki@1.14.1): @@ -16701,7 +16765,7 @@ snapshots: dependencies: '@types/hast': 3.0.4 hast-util-raw: 9.0.2 - vfile: 6.0.2 + vfile: 6.0.3 rehype-slug@6.0.0: dependencies: @@ -16714,7 +16778,7 @@ snapshots: rehype-stringify@10.0.0: dependencies: '@types/hast': 3.0.4 - hast-util-to-html: 9.0.1 + hast-util-to-html: 9.0.2 unified: 11.0.5 rehype-toc@3.0.2: @@ -16778,7 +16842,7 @@ snapshots: '@types/mdast': 4.0.4 mdast-util-to-hast: 13.1.0 unified: 11.0.5 - vfile: 6.0.2 + vfile: 6.0.3 remark-shiki-twoslash@3.1.3(typescript@5.5.4): dependencies: @@ -16838,6 +16902,11 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + retext-latin@4.0.0: dependencies: '@types/nlcst': 2.0.3 @@ -16873,26 +16942,26 @@ snapshots: dependencies: glob: 7.2.3 - rollup@4.21.0: + rollup@4.21.1: dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.21.0 - '@rollup/rollup-android-arm64': 4.21.0 - '@rollup/rollup-darwin-arm64': 4.21.0 - '@rollup/rollup-darwin-x64': 4.21.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.21.0 - '@rollup/rollup-linux-arm-musleabihf': 4.21.0 - '@rollup/rollup-linux-arm64-gnu': 4.21.0 - '@rollup/rollup-linux-arm64-musl': 4.21.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.21.0 - '@rollup/rollup-linux-riscv64-gnu': 4.21.0 - '@rollup/rollup-linux-s390x-gnu': 4.21.0 - '@rollup/rollup-linux-x64-gnu': 4.21.0 - '@rollup/rollup-linux-x64-musl': 4.21.0 - '@rollup/rollup-win32-arm64-msvc': 4.21.0 - '@rollup/rollup-win32-ia32-msvc': 4.21.0 - '@rollup/rollup-win32-x64-msvc': 4.21.0 + '@rollup/rollup-android-arm-eabi': 4.21.1 + '@rollup/rollup-android-arm64': 4.21.1 + '@rollup/rollup-darwin-arm64': 4.21.1 + '@rollup/rollup-darwin-x64': 4.21.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.1 + '@rollup/rollup-linux-arm-musleabihf': 4.21.1 + '@rollup/rollup-linux-arm64-gnu': 4.21.1 + '@rollup/rollup-linux-arm64-musl': 4.21.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.1 + '@rollup/rollup-linux-riscv64-gnu': 4.21.1 + '@rollup/rollup-linux-s390x-gnu': 4.21.1 + '@rollup/rollup-linux-x64-gnu': 4.21.1 + '@rollup/rollup-linux-x64-musl': 4.21.1 + '@rollup/rollup-win32-arm64-msvc': 4.21.1 + '@rollup/rollup-win32-ia32-msvc': 4.21.1 + '@rollup/rollup-win32-x64-msvc': 4.21.1 fsevents: 2.3.3 rrweb-cssom@0.6.0: {} @@ -17107,18 +17176,18 @@ snapshots: smartypants@0.2.2: {} - solid-js@1.8.21: + solid-js@1.8.22: dependencies: csstype: 3.1.3 seroval: 1.1.1 seroval-plugins: 1.1.1(seroval@1.1.1) - solid-refresh@0.6.3(solid-js@1.8.21): + solid-refresh@0.6.3(solid-js@1.8.22): dependencies: - '@babel/generator': 7.25.0 + '@babel/generator': 7.25.5 '@babel/helper-module-imports': 7.24.7 - '@babel/types': 7.25.2 - solid-js: 1.8.21 + '@babel/types': 7.25.4 + solid-js: 1.8.22 transitivePeerDependencies: - supports-color @@ -17249,18 +17318,18 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-hmr@0.16.0(svelte@4.2.18): + svelte-hmr@0.16.0(svelte@4.2.19): dependencies: - svelte: 4.2.18 + svelte: 4.2.19 - svelte2tsx@0.7.15(svelte@4.2.18)(typescript@5.5.4): + svelte2tsx@0.7.16(svelte@4.2.19)(typescript@5.5.4): dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 - svelte: 4.2.18 + svelte: 4.2.19 typescript: 5.5.4 - svelte@4.2.18: + svelte@4.2.19: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 @@ -17303,7 +17372,7 @@ snapshots: is-glob: 4.0.3 jiti: 1.21.0 lilconfig: 2.1.0 - micromatch: 4.0.7 + micromatch: 4.0.8 normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.1 @@ -17352,6 +17421,8 @@ snapshots: tinybench@2.8.0: {} + tinyexec@0.3.0: {} + tinypool@1.0.0: {} tinyrainbow@1.2.0: {} @@ -17407,32 +17478,32 @@ snapshots: tslib@2.6.2: {} - turbo-darwin-64@2.0.14: + turbo-darwin-64@2.1.0: optional: true - turbo-darwin-arm64@2.0.14: + turbo-darwin-arm64@2.1.0: optional: true - turbo-linux-64@2.0.14: + turbo-linux-64@2.1.0: optional: true - turbo-linux-arm64@2.0.14: + turbo-linux-arm64@2.1.0: optional: true - turbo-windows-64@2.0.14: + turbo-windows-64@2.1.0: optional: true - turbo-windows-arm64@2.0.14: + turbo-windows-arm64@2.1.0: optional: true - turbo@2.0.14: + turbo@2.1.0: optionalDependencies: - turbo-darwin-64: 2.0.14 - turbo-darwin-arm64: 2.0.14 - turbo-linux-64: 2.0.14 - turbo-linux-arm64: 2.0.14 - turbo-windows-64: 2.0.14 - turbo-windows-arm64: 2.0.14 + turbo-darwin-64: 2.1.0 + turbo-darwin-arm64: 2.1.0 + turbo-linux-64: 2.1.0 + turbo-linux-arm64: 2.1.0 + turbo-windows-64: 2.1.0 + turbo-windows-arm64: 2.1.0 type-check@0.4.0: dependencies: @@ -17449,7 +17520,7 @@ snapshots: types-react-dom@19.0.0-alpha.3: dependencies: - '@types/react': 18.3.3 + '@types/react': 18.3.4 types-react@19.0.0-alpha.3: dependencies: @@ -17461,11 +17532,11 @@ snapshots: dependencies: semver: 7.6.3 - typescript-eslint@8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4): + typescript-eslint@8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4): dependencies: - '@typescript-eslint/eslint-plugin': 8.1.0(@typescript-eslint/parser@8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4))(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4) - '@typescript-eslint/parser': 8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4) - '@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.0))(typescript@5.5.4) + '@typescript-eslint/eslint-plugin': 8.3.0(@typescript-eslint/parser@8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4) + '@typescript-eslint/parser': 8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4) + '@typescript-eslint/utils': 8.3.0(eslint@9.9.1(jiti@1.21.0))(typescript@5.5.4) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: @@ -17484,7 +17555,7 @@ snapshots: undici-types@5.26.5: {} - undici@6.19.7: {} + undici@6.19.8: {} unicorn-magic@0.1.0: {} @@ -17496,7 +17567,7 @@ snapshots: extend: 3.0.2 is-plain-obj: 4.1.0 trough: 2.2.0 - vfile: 6.0.2 + vfile: 6.0.3 unist-util-find-after@5.0.0: dependencies: @@ -17614,22 +17685,21 @@ snapshots: vfile-location@5.0.2: dependencies: '@types/unist': 3.0.3 - vfile: 6.0.2 + vfile: 6.0.3 vfile-message@4.0.2: dependencies: '@types/unist': 3.0.3 unist-util-stringify-position: 4.0.0 - vfile@6.0.2: + vfile@6.0.3: dependencies: '@types/unist': 3.0.3 - unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - vite-hot-client@0.2.3(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)): + vite-hot-client@0.2.3(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)): dependencies: - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) vite-node@2.0.5(@types/node@18.19.31)(sass@1.77.8): dependencies: @@ -17637,7 +17707,7 @@ snapshots: debug: 4.3.6 pathe: 1.1.2 tinyrainbow: 1.2.0 - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) transitivePeerDependencies: - '@types/node' - less @@ -17649,10 +17719,10 @@ snapshots: - supports-color - terser - vite-plugin-inspect@0.8.5(rollup@4.21.0)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)): + vite-plugin-inspect@0.8.5(rollup@4.21.1)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)): dependencies: '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.0(rollup@4.21.0) + '@rollup/pluginutils': 5.1.0(rollup@4.21.1) debug: 4.3.6 error-stack-parser-es: 0.1.5 fs-extra: 11.2.0 @@ -17660,41 +17730,41 @@ snapshots: perfect-debounce: 1.0.0 picocolors: 1.0.1 sirv: 2.0.4 - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) transitivePeerDependencies: - rollup - supports-color - vite-plugin-solid@2.10.2(solid-js@1.8.21)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)): + vite-plugin-solid@2.10.2(solid-js@1.8.22)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)): dependencies: '@babel/core': 7.25.2 '@types/babel__core': 7.20.5 babel-preset-solid: 1.8.16(@babel/core@7.25.2) merge-anything: 5.1.7 - solid-js: 1.8.21 - solid-refresh: 0.6.3(solid-js@1.8.21) - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) - vitefu: 0.2.5(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + solid-js: 1.8.22 + solid-refresh: 0.6.3(solid-js@1.8.22) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) + vitefu: 0.2.5(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) transitivePeerDependencies: - supports-color - vite-plugin-vue-devtools@7.3.8(rollup@4.21.0)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)): + vite-plugin-vue-devtools@7.3.9(rollup@4.21.1)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)): dependencies: - '@vue/devtools-core': 7.3.8(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) - '@vue/devtools-kit': 7.3.8 - '@vue/devtools-shared': 7.3.8 + '@vue/devtools-core': 7.3.9(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) + '@vue/devtools-kit': 7.3.9 + '@vue/devtools-shared': 7.3.9 execa: 8.0.1 sirv: 2.0.4 - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) - vite-plugin-inspect: 0.8.5(rollup@4.21.0)(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) - vite-plugin-vue-inspector: 5.1.3(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) + vite-plugin-inspect: 0.8.5(rollup@4.21.1)(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) + vite-plugin-vue-inspector: 5.1.3(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)) transitivePeerDependencies: - '@nuxt/kit' - rollup - supports-color - vue - vite-plugin-vue-inspector@5.1.3(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)): + vite-plugin-vue-inspector@5.1.3(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)): dependencies: '@babel/core': 7.25.2 '@babel/plugin-proposal-decorators': 7.24.1(@babel/core@7.25.2) @@ -17705,7 +17775,7 @@ snapshots: '@vue/compiler-dom': 3.4.38 kolorist: 1.8.0 magic-string: 0.30.11 - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) transitivePeerDependencies: - supports-color @@ -17714,19 +17784,19 @@ snapshots: svgo: 3.2.0 vue: 3.4.38(typescript@5.5.4) - vite@5.4.1(@types/node@18.19.31)(sass@1.77.8): + vite@5.4.2(@types/node@18.19.31)(sass@1.77.8): dependencies: esbuild: 0.21.5 postcss: 8.4.41 - rollup: 4.21.0 + rollup: 4.21.1 optionalDependencies: '@types/node': 18.19.31 fsevents: 2.3.3 sass: 1.77.8 - vitefu@0.2.5(vite@5.4.1(@types/node@18.19.31)(sass@1.77.8)): + vitefu@0.2.5(vite@5.4.2(@types/node@18.19.31)(sass@1.77.8)): optionalDependencies: - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) vitest@2.0.5(@types/node@18.19.31)(jsdom@23.2.0)(sass@1.77.8): dependencies: @@ -17746,7 +17816,7 @@ snapshots: tinybench: 2.8.0 tinypool: 1.0.0 tinyrainbow: 1.2.0 - vite: 5.4.1(@types/node@18.19.31)(sass@1.77.8) + vite: 5.4.2(@types/node@18.19.31)(sass@1.77.8) vite-node: 2.0.5(@types/node@18.19.31)(sass@1.77.8) why-is-node-running: 2.3.0 optionalDependencies: diff --git a/scripts/package.json b/scripts/package.json index 35bf517a6..bbf3e9706 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -10,10 +10,10 @@ "dependencies": { "esbuild": "^0.21.5", "esbuild-plugin-copy": "^2.1.1", - "execa": "^8.0.1", "fast-glob": "^3.3.2", "kleur": "^4.1.5", "p-limit": "^6.1.0", + "tinyexec": "^0.3.0", "tsconfck": "^3.1.1" } } diff --git a/scripts/smoke/cleanup.js b/scripts/smoke/cleanup.js index 3b03951f9..1bb398d9e 100644 --- a/scripts/smoke/cleanup.js +++ b/scripts/smoke/cleanup.js @@ -2,7 +2,7 @@ // @ts-check -import { execa } from 'execa'; +import { exec } from 'tinyexec'; import { promises as fs } from 'node:fs'; import { fileURLToPath } from 'node:url'; @@ -36,7 +36,9 @@ async function run() { console.log('🤖', 'Resetting', 'pnpm'); - await execa('pnpm', ['install'], { cwd: fileURLToPath(rootDir), stdout: 'inherit', stderr: 'inherit' }); + await exec('pnpm', ['install'], { + nodeOptions: { cwd: fileURLToPath(rootDir), stdio: ['pipe', 'inherit', 'inherit'] }, + }); } /* Functionality diff --git a/scripts/smoke/index.js b/scripts/smoke/index.js index 7ab78e286..49887cd2e 100644 --- a/scripts/smoke/index.js +++ b/scripts/smoke/index.js @@ -2,7 +2,7 @@ // @ts-check -import { execa } from 'execa'; +import { exec } from 'tinyexec'; import { promises as fs } from 'node:fs'; import { fileURLToPath } from 'node:url'; @@ -32,10 +32,12 @@ async function run() { console.log(''); const directories = [...(await getChildDirectories(smokeDir)), ...(await getChildDirectories(exampleDir))]; + /** @type {Partial<import('tinyexec').Options>} */ + const execOptions = { nodeOptions: { cwd: fileURLToPath(rootDir), stdio: 'inherit' }}; console.log('🤖', 'Preparing', 'pnpm'); - - await execa('pnpm', ['install', '--frozen-lockfile=false'], { cwd: fileURLToPath(rootDir), stdio: 'inherit' }); + + await exec('pnpm', ['install', '--frozen-lockfile=false'], execOptions); for (const directory of directories) { const name = directory.pathname.split('/').at(-1) ?? ""; @@ -43,9 +45,9 @@ async function run() { console.log('🤖', 'Testing', name); try { - await execa('pnpm', ['install', '--ignore-scripts', '--frozen-lockfile=false'].filter(x => x), { cwd: fileURLToPath(directory), stdio: 'inherit' }); - await execa('pnpm', ['astro', 'telemetry', 'disable']); - await execa('pnpm', ['run', 'build'], { cwd: fileURLToPath(directory), stdio: 'inherit' }); + await exec('pnpm', ['install', '--ignore-scripts', '--frozen-lockfile=false'], execOptions); + await exec('pnpm', ['astro', 'telemetry', 'disable']); + await exec('pnpm', ['run', 'build'], execOptions); } catch (err) { console.log(err); process.exit(1); |