diff --git a/.changeset/chatty-knives-confess.md b/.changeset/chatty-knives-confess.md new file mode 100644 index 000000000000..7f07eb893c13 --- /dev/null +++ b/.changeset/chatty-knives-confess.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Removes the misleading log message telling that a custom renderer is not recognized while it clearly is and works. diff --git a/.changeset/little-rules-relate.md b/.changeset/little-rules-relate.md new file mode 100644 index 000000000000..b0b01a87bad1 --- /dev/null +++ b/.changeset/little-rules-relate.md @@ -0,0 +1,5 @@ +--- +'@astrojs/upgrade': patch +--- + +Fixes an issue where running `upgrade` in a directory without `astro` installed shows a false success message diff --git a/.changeset/rare-cooks-battle.md b/.changeset/rare-cooks-battle.md new file mode 100644 index 000000000000..cc6955fa490f --- /dev/null +++ b/.changeset/rare-cooks-battle.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes an issue where the `experimental.svg` had incorrect type, resulting in some errors in the editors. diff --git a/.changeset/red-emus-repair.md b/.changeset/red-emus-repair.md new file mode 100644 index 000000000000..e0dbf68d9a2c --- /dev/null +++ b/.changeset/red-emus-repair.md @@ -0,0 +1,5 @@ +--- +'@astrojs/db': patch +--- + +Fixes a bug that caused an error to be logged about invalid entrypoints diff --git a/.changeset/six-toes-sort.md b/.changeset/six-toes-sort.md new file mode 100644 index 000000000000..3124986c512e --- /dev/null +++ b/.changeset/six-toes-sort.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Correctly handles images in content collections with uppercase file extensions diff --git a/.github/ISSUE_TEMPLATE/---01-bug-report.yml b/.github/ISSUE_TEMPLATE/---01-bug-report.yml index 3a2ec98666d6..9f9bb166dea5 100644 --- a/.github/ISSUE_TEMPLATE/---01-bug-report.yml +++ b/.github/ISSUE_TEMPLATE/---01-bug-report.yml @@ -42,7 +42,7 @@ body: id: bug-reproduction attributes: label: Link to Minimal Reproducible Example - description: 'Use [astro.new](https://astro.new) to create a minimal reproduction of the problem. **A minimal reproduction is required** so that others can help debug your issue. If a report is vague (e.g. just a generic error message) and has no reproduction, it may be auto-closed. Not sure how to create a minimal example? [Read our guide](https://docs.astro.build/en/guides/troubleshooting/#creating-minimal-reproductions)' + description: 'Use [StackBlitz](https://astro.new/repro) to create a minimal reproduction of the problem. **A minimal reproduction is required** so that others can help debug your issue. If a report is vague (e.g. just a generic error message) and has no reproduction, it may be auto-closed. Not sure how to create a minimal example? [Read our guide](https://docs.astro.build/en/guides/troubleshooting/#creating-minimal-reproductions)' placeholder: 'https://stackblitz.com/abcd1234' validations: required: true diff --git a/.github/workflows/continuous_benchmark.yml b/.github/workflows/continuous_benchmark.yml index a1d48bb8d910..1b382f8dc6fc 100644 --- a/.github/workflows/continuous_benchmark.yml +++ b/.github/workflows/continuous_benchmark.yml @@ -50,6 +50,7 @@ jobs: uses: CodSpeedHQ/action@513a19673a831f139e8717bf45ead67e47f00044 # v3.2.0 timeout-minutes: 30 with: - run: pnpm benchmark codspeed + working-directory: ./benchmark + run: pnpm bench token: ${{ secrets.CODSPEED_TOKEN }} diff --git a/.github/workflows/issue-labeled.yml b/.github/workflows/issue-labeled.yml index 8723639c7ff7..b0a0e80c7767 100644 --- a/.github/workflows/issue-labeled.yml +++ b/.github/workflows/issue-labeled.yml @@ -26,5 +26,5 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} body: | - Hello @${{ github.event.issue.user.login }}. Please provide a [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) using a GitHub repository or [StackBlitz](https://astro.new). Issues marked with `needs repro` will be closed if they have no activity within 3 days. + Hello @${{ github.event.issue.user.login }}. Please provide a [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) using a GitHub repository or [StackBlitz](https://astro.new/repro). Issues marked with `needs repro` will be closed if they have no activity within 3 days. labels: "needs triage" diff --git a/benchmark/bench/_util.js b/benchmark/bench/_util.js index b16a16e1ce36..d9dfe5b19076 100644 --- a/benchmark/bench/_util.js +++ b/benchmark/bench/_util.js @@ -19,3 +19,14 @@ export function calculateStat(numbers) { const max = Math.max(...numbers); return { avg, stdev, max }; } + +export async function makeProject(name) { + console.log('Making project:', name); + const projectDir = new URL(`../projects/${name}/`, import.meta.url); + + const makeProjectMod = await import(`../make-project/${name}.js`); + await makeProjectMod.run(projectDir); + + console.log('Finished making project:', name); + return projectDir; +} diff --git a/benchmark/bench/codspeed.bench.js b/benchmark/bench/codspeed.bench.js new file mode 100644 index 000000000000..4073ebed856a --- /dev/null +++ b/benchmark/bench/codspeed.bench.js @@ -0,0 +1,48 @@ +import { fileURLToPath } from 'node:url'; +import { exec } from 'tinyexec'; +import { beforeAll, bench, describe } from 'vitest'; +import { astroBin, makeProject } from './_util.js'; +let streamingApp; +let nonStreamingApp; +beforeAll(async () => { + const render = await makeProject('render-bench'); + const root = fileURLToPath(render); + await exec(astroBin, ['build'], { + nodeOptions: { + cwd: root, + stdio: 'inherit', + }, + }); + const entry = new URL('./dist/server/entry.mjs', `file://${root}`); + const { manifest, createApp } = await import(entry); + streamingApp = createApp(manifest, true); + nonStreamingApp = createApp(manifest, false); +}, 900000); + +describe('Bench rendering', () => { + bench('Rendering: streaming [true], .astro file', async () => { + const request = new Request(new URL('http://exmpale.com/astro')); + await streamingApp.render(request); + }); + bench('Rendering: streaming [true], .md file', async () => { + const request = new Request(new URL('http://exmpale.com/md')); + await streamingApp.render(request); + }); + bench('Rendering: streaming [true], .mdx file', async () => { + const request = new Request(new URL('http://exmpale.com/mdx')); + await streamingApp.render(request); + }); + + bench('Rendering: streaming [false], .astro file', async () => { + const request = new Request(new URL('http://exmpale.com/astro')); + await nonStreamingApp.render(request); + }); + bench('Rendering: streaming [false], .md file', async () => { + const request = new Request(new URL('http://exmpale.com/md')); + await nonStreamingApp.render(request); + }); + bench('Rendering: streaming [false], .mdx file', async () => { + const request = new Request(new URL('http://exmpale.com/mdx')); + await nonStreamingApp.render(request); + }); +}); diff --git a/benchmark/bench/codspeed.js b/benchmark/bench/codspeed.js deleted file mode 100644 index 2643b1ec8a5f..000000000000 --- a/benchmark/bench/codspeed.js +++ /dev/null @@ -1,64 +0,0 @@ -import path from 'node:path'; -import { withCodSpeed } from '@codspeed/tinybench-plugin'; -import { Bench } from 'tinybench'; -import { exec } from 'tinyexec'; -import { astroBin } from './_util.js'; - -export async function run({ memory: _memory, render, stress: _stress }) { - const options = { - iterations: 10, - }; - const bench = process.env.CODSPEED ? withCodSpeed(new Bench(options)) : new Bench(options); - await exec(astroBin, ['build'], { - nodeOptions: { - cwd: render.root, - stdio: 'inherit', - }, - }); - - const entry = new URL('./dist/server/entry.mjs', `file://${render.root}`); - const { manifest, createApp } = await import(entry); - const streamingApp = createApp(manifest, true); - const nonStreamingApp = createApp(manifest, false); - bench - .add('Rendering: streaming [true], .astro file', async () => { - console.info('Start task.'); - const request = new Request(new URL('http://exmpale.com/astro')); - await streamingApp.render(request); - console.info('Finish task.'); - }) - .add('Rendering: streaming [true], .md file', async () => { - console.info('Start task.'); - const request = new Request(new URL('http://exmpale.com/md')); - await streamingApp.render(request); - console.info('Finish task.'); - }) - .add('Rendering: streaming [true], .mdx file', async () => { - console.info('Start task.'); - const request = new Request(new URL('http://exmpale.com/mdx')); - await streamingApp.render(request); - console.info('Finish task.'); - }) - - .add('Rendering: streaming [false], .astro file', async () => { - console.info('Start task.'); - const request = new Request(new URL('http://exmpale.com/astro')); - await nonStreamingApp.render(request); - console.info('Finish task.'); - }) - .add('Rendering: streaming [false], .md file', async () => { - console.info('Start task.'); - const request = new Request(new URL('http://exmpale.com/md')); - await nonStreamingApp.render(request); - console.info('Finish task.'); - }) - .add('Rendering: streaming [false], .mdx file', async () => { - console.info('Start task.'); - const request = new Request(new URL('http://exmpale.com/mdx')); - await nonStreamingApp.render(request); - console.info('Finish task.'); - }); - - await bench.run(); - console.table(bench.table()); -} diff --git a/benchmark/index.js b/benchmark/index.js index 2f2846e1db5c..956b9c3afa0c 100755 --- a/benchmark/index.js +++ b/benchmark/index.js @@ -1,7 +1,8 @@ -import mri from 'mri'; import fs from 'node:fs/promises'; import path from 'node:path'; -import {fileURLToPath, pathToFileURL} from 'node:url'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import mri from 'mri'; +import { makeProject } from './bench/_util.js'; const args = mri(process.argv.slice(2)); @@ -14,7 +15,6 @@ Command memory Run build memory and speed test render Run rendering speed test server-stress Run server stress test - codspeed Run codspeed test cli-startup Run CLI startup speed test Options @@ -30,7 +30,6 @@ const benchmarks = { render: () => import('./bench/render.js'), 'server-stress': () => import('./bench/server-stress.js'), 'cli-startup': () => import('./bench/cli-startup.js'), - codspeed: () => import('./bench/codspeed.js') }; if (commandName && !(commandName in benchmarks)) { @@ -39,26 +38,12 @@ if (commandName && !(commandName in benchmarks)) { } if (commandName) { - if (commandName === 'codspeed') { - const render = await makeProject('render-bench'); - const rootRender = fileURLToPath(render); - const bench = benchmarks[commandName]; - const benchMod = await bench(); - const payload = { - render: { - root: rootRender, - output: await getOutputFile('render') - }, - }; - await benchMod.run(payload); - } else { - // Run single benchmark - const bench = benchmarks[commandName]; - const benchMod = await bench(); - const projectDir = await makeProject(args.project || benchMod.defaultProject); - const outputFile = await getOutputFile(commandName); - await benchMod.run(projectDir, outputFile); - } + // Run single benchmark + const bench = benchmarks[commandName]; + const benchMod = await bench(); + const projectDir = await makeProject(args.project || benchMod.defaultProject); + const outputFile = await getOutputFile(commandName); + await benchMod.run(projectDir, outputFile); } else { // Run all benchmarks for (const name in benchmarks) { @@ -70,21 +55,10 @@ if (commandName) { } } -export async function makeProject(name) { - console.log('Making project:', name); - const projectDir = new URL(`./projects/${name}/`, import.meta.url); - - const makeProjectMod = await import(`./make-project/${name}.js`); - await makeProjectMod.run(projectDir); - - console.log('Finished making project:', name); - return projectDir; -} - /** * @param {string} benchmarkName */ -async function getOutputFile(benchmarkName) { +export async function getOutputFile(benchmarkName) { let file; if (args.output) { file = pathToFileURL(path.resolve(args.output)); diff --git a/benchmark/make-project/markdown-cc1.js b/benchmark/make-project/markdown-cc1.js index 6c83959601e3..1e3aaa51779b 100644 --- a/benchmark/make-project/markdown-cc1.js +++ b/benchmark/make-project/markdown-cc1.js @@ -8,11 +8,13 @@ export async function run(projectDir) { await fs.rm(projectDir, { recursive: true, force: true }); await fs.mkdir(new URL('./src/pages/blog', projectDir), { recursive: true }); await fs.mkdir(new URL('./src/content/blog', projectDir), { recursive: true }); - await fs.copyFile(new URL('./image.jpg', import.meta.url), new URL('./src/image.jpg', projectDir)); + await fs.copyFile( + new URL('./image.jpg', import.meta.url), + new URL('./src/image.jpg', projectDir), + ); const promises = []; - for (let i = 0; i < 10000; i++) { const content = `\ # Article ${i} @@ -24,11 +26,10 @@ ${loremIpsumMd} `; promises.push( - fs.writeFile(new URL(`./src/content/blog/article-${i}.md`, projectDir), content, 'utf-8') + fs.writeFile(new URL(`./src/content/blog/article-${i}.md`, projectDir), content, 'utf-8'), ); } - await fs.writeFile( new URL(`./src/pages/blog/[...slug].astro`, projectDir), `\ @@ -46,7 +47,7 @@ const { Content } = await entry.render();

{entry.data.title}

`, - 'utf-8' + 'utf-8', ); await Promise.all(promises); @@ -58,6 +59,6 @@ import { defineConfig } from 'astro/config'; export default defineConfig({ });`, - 'utf-8' + 'utf-8', ); } diff --git a/benchmark/make-project/markdown-cc2.js b/benchmark/make-project/markdown-cc2.js index 9ce95f0dc248..ba60813c0d4a 100644 --- a/benchmark/make-project/markdown-cc2.js +++ b/benchmark/make-project/markdown-cc2.js @@ -23,7 +23,7 @@ ${loremIpsumMd} `; promises.push( - fs.writeFile(new URL(`./data/blog/article-${i}.md`, projectDir), content, 'utf-8') + fs.writeFile(new URL(`./data/blog/article-${i}.md`, projectDir), content, 'utf-8'), ); } @@ -39,7 +39,7 @@ ${loremIpsumMd} export const collections = { blog } - ` + `, ); await fs.writeFile( @@ -60,7 +60,7 @@ const { Content } = await render(entry);

{entry.data.title}

`, - 'utf-8' + 'utf-8', ); await Promise.all(promises); @@ -71,6 +71,6 @@ const { Content } = await render(entry); import { defineConfig } from 'astro/config'; export default defineConfig({});`, - 'utf-8' + 'utf-8', ); } diff --git a/benchmark/make-project/mdx-cc1.js b/benchmark/make-project/mdx-cc1.js index 98e1495d13e1..a948ce194008 100644 --- a/benchmark/make-project/mdx-cc1.js +++ b/benchmark/make-project/mdx-cc1.js @@ -8,11 +8,13 @@ export async function run(projectDir) { await fs.rm(projectDir, { recursive: true, force: true }); await fs.mkdir(new URL('./src/pages/blog', projectDir), { recursive: true }); await fs.mkdir(new URL('./src/content/blog', projectDir), { recursive: true }); - await fs.copyFile(new URL('./image.jpg', import.meta.url), new URL('./src/image.jpg', projectDir)); + await fs.copyFile( + new URL('./image.jpg', import.meta.url), + new URL('./src/image.jpg', projectDir), + ); const promises = []; - for (let i = 0; i < 10000; i++) { const content = `\ # Article ${i} @@ -24,11 +26,10 @@ ${loremIpsumMd} `; promises.push( - fs.writeFile(new URL(`./src/content/blog/article-${i}.mdx`, projectDir), content, 'utf-8') + fs.writeFile(new URL(`./src/content/blog/article-${i}.mdx`, projectDir), content, 'utf-8'), ); } - await fs.writeFile( new URL(`./src/pages/blog/[...slug].astro`, projectDir), `\ @@ -46,7 +47,7 @@ const { Content } = await entry.render();

{entry.data.title}

`, - 'utf-8' + 'utf-8', ); await Promise.all(promises); @@ -61,6 +62,6 @@ import mdx from '@astrojs/mdx'; export default defineConfig({ integrations: [mdx()], });`, - 'utf-8' + 'utf-8', ); } diff --git a/benchmark/make-project/mdx-cc2.js b/benchmark/make-project/mdx-cc2.js index ab6ddeb3b603..f50b63c9ee38 100644 --- a/benchmark/make-project/mdx-cc2.js +++ b/benchmark/make-project/mdx-cc2.js @@ -23,7 +23,7 @@ ${loremIpsumMd} `; promises.push( - fs.writeFile(new URL(`./data/blog/article-${i}.mdx`, projectDir), content, 'utf-8') + fs.writeFile(new URL(`./data/blog/article-${i}.mdx`, projectDir), content, 'utf-8'), ); } @@ -39,7 +39,7 @@ ${loremIpsumMd} export const collections = { blog } - ` + `, ); await fs.writeFile( @@ -60,7 +60,7 @@ const { Content } = await render(entry);

{entry.data.title}

`, - 'utf-8' + 'utf-8', ); await Promise.all(promises); @@ -75,6 +75,6 @@ import mdx from '@astrojs/mdx'; export default defineConfig({ integrations: [mdx()], });`, - 'utf-8' + 'utf-8', ); } diff --git a/benchmark/make-project/memory-default.js b/benchmark/make-project/memory-default.js index e3652dd5794b..1087c3d4aa84 100644 --- a/benchmark/make-project/memory-default.js +++ b/benchmark/make-project/memory-default.js @@ -20,7 +20,7 @@ const i = ${i}; {i} `; promises.push( - fs.writeFile(new URL(`./src/pages/page-${i}.astro`, projectDir), content, 'utf-8') + fs.writeFile(new URL(`./src/pages/page-${i}.astro`, projectDir), content, 'utf-8'), ); } @@ -31,7 +31,7 @@ const i = ${i}; ${loremIpsum} `; promises.push( - fs.writeFile(new URL(`./src/content/blog/article-${i}.md`, projectDir), content, 'utf-8') + fs.writeFile(new URL(`./src/content/blog/article-${i}.md`, projectDir), content, 'utf-8'), ); } @@ -42,7 +42,7 @@ ${loremIpsum} ${loremIpsum} `; promises.push( - fs.writeFile(new URL(`./src/content/blog/post-${i}.mdx`, projectDir), content, 'utf-8') + fs.writeFile(new URL(`./src/content/blog/post-${i}.mdx`, projectDir), content, 'utf-8'), ); } @@ -63,7 +63,7 @@ const { Content } = await entry.render();

{entry.data.title}

`, - 'utf-8' + 'utf-8', ); await Promise.all(promises); @@ -77,6 +77,6 @@ import mdx from '@astrojs/mdx'; export default defineConfig({ integrations: [mdx()], });`, - 'utf-8' + 'utf-8', ); } diff --git a/benchmark/make-project/render-bench.js b/benchmark/make-project/render-bench.js index 9d10d9bf5f16..e2964fbd232d 100644 --- a/benchmark/make-project/render-bench.js +++ b/benchmark/make-project/render-bench.js @@ -112,7 +112,7 @@ export async function run(projectDir) { await Promise.all( Object.entries(renderFiles).map(([name, content]) => { return fs.writeFile(new URL(`./src/${name}`, projectDir), content, 'utf-8'); - }) + }), ); await fs.writeFile( @@ -127,6 +127,6 @@ export default defineConfig({ output: 'server', adapter: adapter(), });`, - 'utf-8' + 'utf-8', ); } diff --git a/benchmark/make-project/render-default.js b/benchmark/make-project/render-default.js index f42340fd3b64..7ea54b936ed3 100644 --- a/benchmark/make-project/render-default.js +++ b/benchmark/make-project/render-default.js @@ -112,7 +112,7 @@ export async function run(projectDir) { await Promise.all( Object.entries(renderFiles).map(([name, content]) => { return fs.writeFile(new URL(`./src/${name}`, projectDir), content, 'utf-8'); - }) + }), ); await fs.writeFile( @@ -127,6 +127,6 @@ export default defineConfig({ output: 'server', adapter: timer(), });`, - 'utf-8' + 'utf-8', ); } diff --git a/benchmark/make-project/server-stress-default.js b/benchmark/make-project/server-stress-default.js index 79e8b260af6c..1724f8f82593 100644 --- a/benchmark/make-project/server-stress-default.js +++ b/benchmark/make-project/server-stress-default.js @@ -38,13 +38,13 @@ const content = "${loremIpsum}" `, - 'utf-8' + 'utf-8', ); await fs.writeFile( new URL('./src/components/Paragraph.astro', projectDir), `
{Astro.props.num} {Astro.props.str}
`, - 'utf-8' + 'utf-8', ); await fs.writeFile( @@ -57,6 +57,6 @@ export default defineConfig({ output: 'server', adapter: nodejs({ mode: 'standalone' }), });`, - 'utf-8' + 'utf-8', ); } diff --git a/benchmark/package.json b/benchmark/package.json index 428afe56d2cf..708ee14d12dc 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -6,6 +6,9 @@ "bin": { "astro-benchmark": "./index.js" }, + "scripts": { + "bench": "pnpm vitest bench --run" + }, "dependencies": { "@astrojs/mdx": "workspace:*", "@astrojs/node": "^8.3.4", @@ -21,7 +24,7 @@ "tinyexec": "^0.3.1" }, "devDependencies": { - "@codspeed/tinybench-plugin": "^3.1.1", - "tinybench": "^2.9.0" + "@codspeed/vitest-plugin": "3.1.1", + "vitest": "2.1.8" } } diff --git a/benchmark/vitest.config.js b/benchmark/vitest.config.js new file mode 100644 index 000000000000..b8b6e5e52a28 --- /dev/null +++ b/benchmark/vitest.config.js @@ -0,0 +1,7 @@ +import codspeedPlugin from '@codspeed/vitest-plugin'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + plugins: process.env.CODSPEED ? [codspeedPlugin()] : [], + include: ['./bench/codspeed.bench.js'], +}); diff --git a/biome.jsonc b/biome.jsonc index adadd8f5978a..bab1f1a05b61 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -2,7 +2,7 @@ "$schema": "https://biomejs.dev/schemas/1.9.3/schema.json", "files": { "ignore": ["**/smoke/**", "**/fixtures/**", "**/_temp-fixtures/**", "**/vendor/**"], - "include": ["test/**", "e2e/**", "packages/**", "scripts/**", "benchmark/bench"], + "include": ["test/**", "e2e/**", "packages/**", "scripts/**", "benchmark"], }, "vcs": { "enabled": true, diff --git a/examples/basics/package.json b/examples/basics/package.json index f5eea40ff54f..aab51227498d 100644 --- a/examples/basics/package.json +++ b/examples/basics/package.json @@ -10,6 +10,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^5.0.1" + "astro": "^5.0.2" } } diff --git a/examples/basics/src/components/Welcome.astro b/examples/basics/src/components/Welcome.astro index d08955687fb2..6b7b9c70e869 100644 --- a/examples/basics/src/components/Welcome.astro +++ b/examples/basics/src/components/Welcome.astro @@ -27,7 +27,7 @@ import background from '../assets/background.svg'; - + { // Handle normalization of `experimental.svg` config boolean values if (typeof svgConfig === 'boolean') { - return svgConfig ? ASTRO_CONFIG_DEFAULTS.experimental.svg : undefined; + return svgConfig + ? { + mode: 'inline' as SvgRenderMode, + } + : undefined; + } else { + if (!svgConfig.mode) { + return { + mode: 'inline' as SvgRenderMode, + }; + } } return svgConfig; }), diff --git a/packages/astro/src/runtime/server/render/component.ts b/packages/astro/src/runtime/server/render/component.ts index eedbcbee12bd..b3979f831790 100644 --- a/packages/astro/src/runtime/server/render/component.ts +++ b/packages/astro/src/runtime/server/render/component.ts @@ -260,15 +260,6 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr } } else { if (metadata.hydrate === 'only') { - const rendererName = rendererAliases.has(metadata.hydrateArgs) - ? rendererAliases.get(metadata.hydrateArgs) - : metadata.hydrateArgs; - if (!clientOnlyValues.has(rendererName)) { - // warning if provide incorrect client:only directive but find the renderer by guess - console.warn( - `The client:only directive for ${metadata.displayName} is not recognized. The renderer ${renderer.name} will be used. If you intended to use a different renderer, please provide a valid client:only directive.`, - ); - } html = await renderSlotToString(result, slots?.fallback); } else { const componentRenderStartTime = performance.now(); diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index 43aea0743a69..721b5076a096 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -322,7 +322,7 @@ export interface ViteUserConfig extends OriginalViteUserConfig { * @type {string} * @default `"."` (current working directory) * @summary Set the project root. The project root is the directory where your Astro project (and all `src`, `public` and `package.json` files) live. - * @description You should only provide this option if you run the `astro` CLI commands in a directory other than the project root directory. Usually, this option is provided via the CLI instead of the [Astro config file](https://docs.astro.build/en/guides/configuring-astro/#supported-config-file-types), since Astro needs to know your project root before it can locate your config file. + * @description You should only provide this option if you run the `astro` CLI commands in a directory other than the project root directory. Usually, this option is provided via the CLI instead of the Astro config file, since Astro needs to know your project root before it can locate your config file. * * If you provide a relative path (ex: `--root: './my-project'`) Astro will resolve it against your current working directory. * @@ -1940,28 +1940,30 @@ export interface ViteUserConfig extends OriginalViteUserConfig { * For a complete overview, and to give feedback on this experimental API, * see the [Feature RFC](https://github.com/withastro/roadmap/pull/1035). */ - svg?: { - /** - * - * @name experimental.svg.mode - * @type {string} - * @default 'inline' - * - * The default technique for handling imported SVG files. Astro will inline the SVG content into your HTML output if not specified. - * - * - `inline`: Astro will inline the SVG content into your HTML output. - * - `sprite`: Astro will generate a sprite sheet with all imported SVG files. - * - * ```astro - * --- - * import Logo from './path/to/svg/file.svg'; - * --- - * - * - * ``` - */ - mode?: SvgRenderMode; - }; + svg?: + | boolean + | { + /** + * + * @name experimental.svg.mode + * @type {string} + * @default 'inline' + * + * The default technique for handling imported SVG files. Astro will inline the SVG content into your HTML output if not specified. + * + * - `inline`: Astro will inline the SVG content into your HTML output. + * - `sprite`: Astro will generate a sprite sheet with all imported SVG files. + * + * ```astro + * --- + * import Logo from './path/to/svg/file.svg'; + * --- + * + * + * ``` + */ + mode: SvgRenderMode; + }; }; } diff --git a/packages/astro/templates/content/types.d.ts b/packages/astro/templates/content/types.d.ts index 0727ac2e5578..14b57053c37d 100644 --- a/packages/astro/templates/content/types.d.ts +++ b/packages/astro/templates/content/types.d.ts @@ -92,7 +92,9 @@ declare module 'astro:content' { collection: C, id: E, ): E extends keyof DataEntryMap[C] - ? Promise + ? string extends keyof DataEntryMap[C] + ? Promise | undefined + : Promise : Promise | undefined>; /** Resolve an array of entry references from the same collection */ diff --git a/packages/astro/test/content-layer.test.js b/packages/astro/test/content-layer.test.js index 73375b185312..41d2f0fce692 100644 --- a/packages/astro/test/content-layer.test.js +++ b/packages/astro/test/content-layer.test.js @@ -217,6 +217,12 @@ describe('Content Layer', () => { assert.equal(json.entryWithReference.data.heroImage.format, 'jpg'); }); + it('loads images with uppercase extensions', async () => { + assert.ok(json.atlantis.data.heroImage.src.startsWith('/_astro')); + assert.ok(json.atlantis.data.heroImage.src.endsWith('.JPG')); + assert.equal(json.atlantis.data.heroImage.format, 'jpg'); + }); + it('loads images from custom loaders', async () => { assert.ok(json.images[0].data.image.src.startsWith('/_astro')); assert.equal(json.images[0].data.image.format, 'jpg'); diff --git a/packages/astro/test/custom-renderer.test.js b/packages/astro/test/custom-renderer.test.js new file mode 100644 index 000000000000..84f03373ce01 --- /dev/null +++ b/packages/astro/test/custom-renderer.test.js @@ -0,0 +1,42 @@ +import assert from 'node:assert/strict'; +import { after, before, describe, it } from 'node:test'; +import * as cheerio from 'cheerio'; +import { loadFixture } from './test-utils.js'; + +describe('Custom Renderer - SSR', () => { + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/custom-renderer/', + }); + }); + + describe('dev', () => { + let devServer; + + before(async () => { + devServer = await fixture.startDevServer(); + }); + + after(async () => { + await devServer.stop(); + }); + + it('renders /', async () => { + const html = await fixture.fetch('/').then((res) => res.text()); + const $ = cheerio.load(html); + assert.equal($('h1').text(), 'Client Directives'); + }); + + it('renders SSR custom renderer functional components as expected', async () => { + const res = await fixture.fetch('/'); + assert.equal(res.status, 200); + + const html = await res.text(); + const $ = cheerio.load(html); + + assert.equal($('p').length, 5); + }); + }); +}); diff --git a/packages/astro/test/fixtures/content-layer/src/content/space/atlantis.JPG b/packages/astro/test/fixtures/content-layer/src/content/space/atlantis.JPG new file mode 100644 index 000000000000..8468822f8eaa Binary files /dev/null and b/packages/astro/test/fixtures/content-layer/src/content/space/atlantis.JPG differ diff --git a/packages/astro/test/fixtures/content-layer/src/content/space/atlantis.md b/packages/astro/test/fixtures/content-layer/src/content/space/atlantis.md new file mode 100644 index 000000000000..81f4352da179 --- /dev/null +++ b/packages/astro/test/fixtures/content-layer/src/content/space/atlantis.md @@ -0,0 +1,11 @@ +--- +title: Atlantis +description: 'Learn about the Atlantis NASA space shuttle.' +publishedDate: 'Sat May 21 2022 00:00:00 GMT-0400 (Eastern Daylight Time)' +tags: [space, 90s] +heroImage: "./atlantis.JPG" +--- + +**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Space_Shuttle_Atlantis) + +Space Shuttle Atlantis (Orbiter Vehicle Designation: OV-104) is a Space Shuttle orbiter vehicle belonging to the National Aeronautics and Space Administration (NASA), the spaceflight and space exploration agency of the United States. Constructed by the Rockwell International company in Southern California and delivered to the Kennedy Space Center in Eastern Florida in April 1985, Atlantis is the fourth operational and the second-to-last Space Shuttle built. Its maiden flight was STS-51-J from 3 to 7 October 1985. diff --git a/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js b/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js index 5467550d70bb..968dfc24d3c6 100644 --- a/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js +++ b/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js @@ -12,6 +12,7 @@ export async function GET() { const simpleLoader = await getCollection('cats'); const entryWithReference = await getEntry('spacecraft', 'columbia-copy'); + const atlantis = await getEntry('spacecraft', 'atlantis'); const referencedEntry = await getEntry(entryWithReference.data.cat); const entryWithImagePath = await getEntry('spacecraft', 'lunar-module'); @@ -49,6 +50,7 @@ export async function GET() { yamlLoader, tomlLoader, nestedJsonLoader, + atlantis }) ); } diff --git a/packages/astro/test/fixtures/custom-renderer/astro.config.mjs b/packages/astro/test/fixtures/custom-renderer/astro.config.mjs new file mode 100644 index 000000000000..54985f8b53d8 --- /dev/null +++ b/packages/astro/test/fixtures/custom-renderer/astro.config.mjs @@ -0,0 +1,9 @@ +import { defineConfig } from 'astro/config'; + +// in a real-world scenario, this would be provided a separate package +import customRenderer from './src/custom-renderer'; + +// https://astro.build/config +export default defineConfig({ + integrations: [customRenderer()] +}); diff --git a/packages/astro/test/fixtures/custom-renderer/package.json b/packages/astro/test/fixtures/custom-renderer/package.json new file mode 100644 index 000000000000..5e14cccbc473 --- /dev/null +++ b/packages/astro/test/fixtures/custom-renderer/package.json @@ -0,0 +1,11 @@ +{ + "name": "@test/custom-renderer", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*" + }, + "scripts": { + "dev": "astro dev" + } +} diff --git a/packages/astro/test/fixtures/custom-renderer/src/components/CustomRendererTest.ts b/packages/astro/test/fixtures/custom-renderer/src/components/CustomRendererTest.ts new file mode 100644 index 000000000000..f09c6ef751fe --- /dev/null +++ b/packages/astro/test/fixtures/custom-renderer/src/components/CustomRendererTest.ts @@ -0,0 +1,10 @@ +export interface Props { + msg: string; +} + +export default function CustomRendererTest({ msg }: Props) { + return { + tag: "p", + text: msg + } +} \ No newline at end of file diff --git a/packages/astro/test/fixtures/custom-renderer/src/custom-renderer/client.ts b/packages/astro/test/fixtures/custom-renderer/src/custom-renderer/client.ts new file mode 100644 index 000000000000..b1757fc937f6 --- /dev/null +++ b/packages/astro/test/fixtures/custom-renderer/src/custom-renderer/client.ts @@ -0,0 +1,25 @@ +export default (parentElement: HTMLElement) => + + async ( + Component: any, + props: Record, + //{ default: children, ...slotted }: Record, + //{ client }: Record, + ) => { + + // in a real-world scenario, this would be a more complex function + // actually rendering the components return value (which might be an AST/VDOM) + + const vdom = Component(props); + + const node: Node = document.createElement(vdom.tag); + node.textContent = `${vdom.text} (rendered by client.ts)`; + parentElement.appendChild(node); + + // cleanup + parentElement.addEventListener('astro:unmount', () => { + if (node.parentNode) { + node.parentNode.removeChild(node); + } + }, { once: true }); + }; \ No newline at end of file diff --git a/packages/astro/test/fixtures/custom-renderer/src/custom-renderer/index.ts b/packages/astro/test/fixtures/custom-renderer/src/custom-renderer/index.ts new file mode 100644 index 000000000000..2c8654994c43 --- /dev/null +++ b/packages/astro/test/fixtures/custom-renderer/src/custom-renderer/index.ts @@ -0,0 +1,23 @@ +import type { AstroIntegration, AstroRenderer, ContainerRenderer } from 'astro'; + +const getRenderer = (): AstroRenderer => ({ + name: 'custom-renderer', + clientEntrypoint: '@custom-renderer/client', + serverEntrypoint: '@custom-renderer/server', +}) + +export const getContainerRenderer = (): ContainerRenderer => ({ + name: 'custom-renderer', + serverEntrypoint: '@custom-renderer/server', +}) + +export default function (): AstroIntegration { + return { + name: 'custom-renderer', + hooks: { + 'astro:config:setup': ({ addRenderer }) => { + addRenderer(getRenderer()); + }, + }, + }; +} \ No newline at end of file diff --git a/packages/astro/test/fixtures/custom-renderer/src/custom-renderer/server.ts b/packages/astro/test/fixtures/custom-renderer/src/custom-renderer/server.ts new file mode 100644 index 000000000000..e3436c4ce206 --- /dev/null +++ b/packages/astro/test/fixtures/custom-renderer/src/custom-renderer/server.ts @@ -0,0 +1,42 @@ +import type { NamedSSRLoadedRendererValue, SSRResult } from 'astro'; + +type RendererContext = { + result: SSRResult; +}; + +async function check( + this: RendererContext, + Component: any, + //props: Record, + //children: any, +) { + + if (typeof Component !== 'function') return false; + + // in a real-world scenario, this would be a more complex function + // that checks if the component should be rendered + return true; +} + +async function renderToStaticMarkup( + this: RendererContext, + Component: any, + props: Record, + //{ default: children, ...slotted }: Record, + //metadata: AstroComponentMetadata | undefined, +) { + // in a real-world scenario, this would be a more complex function + // actually rendering the components return value (which might be an AST/VDOM) + // and render it as an HTML string + const vdom = Component(props); + return { attrs: {}, html: `<${vdom.tag}>${vdom.text} (rendered by server.ts)` }; +} + +const renderer: NamedSSRLoadedRendererValue = { + name: 'custom-renderer', + check, + renderToStaticMarkup, + supportsAstroStaticSlot: false, +}; + +export default renderer; \ No newline at end of file diff --git a/packages/astro/test/fixtures/custom-renderer/src/pages/index.astro b/packages/astro/test/fixtures/custom-renderer/src/pages/index.astro new file mode 100644 index 000000000000..f241df2d4bb5 --- /dev/null +++ b/packages/astro/test/fixtures/custom-renderer/src/pages/index.astro @@ -0,0 +1,30 @@ +--- +import CustomRendererTest from '../components/CustomRendererTest'; +--- + + + + Custom Framework / Custom Renderer + + +

Client Directives

+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ + diff --git a/packages/astro/test/fixtures/custom-renderer/tsconfig.json b/packages/astro/test/fixtures/custom-renderer/tsconfig.json new file mode 100644 index 000000000000..f1ad59fe06c3 --- /dev/null +++ b/packages/astro/test/fixtures/custom-renderer/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "astro/tsconfigs/base", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@custom-renderer/*": ["src/custom-renderer/*"] + }, + } +} diff --git a/packages/db/src/core/integration/index.ts b/packages/db/src/core/integration/index.ts index b96765870b32..200c7ddc25b2 100644 --- a/packages/db/src/core/integration/index.ts +++ b/packages/db/src/core/integration/index.ts @@ -16,7 +16,7 @@ import { } from 'vite'; import parseArgs from 'yargs-parser'; import { AstroDbError } from '../../runtime/utils.js'; -import { CONFIG_FILE_NAMES, DB_PATH } from '../consts.js'; +import { CONFIG_FILE_NAMES, DB_PATH, VIRTUAL_MODULE_ID } from '../consts.js'; import { EXEC_DEFAULT_EXPORT_ERROR, EXEC_ERROR } from '../errors.js'; import { resolveDbConfig } from '../load-file.js'; import { SEED_DEV_FILE_NAME } from '../queries.js'; @@ -153,7 +153,7 @@ function astroDBIntegration(): AstroIntegration { ); // Eager load astro:db module on startup if (seedFiles.get().length || localSeedPaths.find((path) => existsSync(path))) { - server.ssrLoadModule(resolved.module).catch((e) => { + server.ssrLoadModule(VIRTUAL_MODULE_ID).catch((e) => { logger.error(e instanceof Error ? e.message : String(e)); }); } diff --git a/packages/upgrade/src/actions/verify.ts b/packages/upgrade/src/actions/verify.ts index 193b0477a1d5..384df5134ac4 100644 --- a/packages/upgrade/src/actions/verify.ts +++ b/packages/upgrade/src/actions/verify.ts @@ -24,7 +24,13 @@ export async function verify( } } - await verifyAstroProject(ctx); + const isAstroProject = await verifyAstroProject(ctx); + if (!isAstroProject) { + bannerAbort(); + newline(); + error('error', `Astro installation not found in the current directory.`); + ctx.exit(1); + } const ok = await verifyVersions(ctx, registry); if (!ok) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3c95a53506b6..f87bd6cd9e0d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,12 +100,12 @@ importers: specifier: ^0.3.1 version: 0.3.1 devDependencies: - '@codspeed/tinybench-plugin': - specifier: ^3.1.1 - version: 3.1.1(tinybench@2.9.0) - tinybench: - specifier: ^2.9.0 - version: 2.9.0 + '@codspeed/vitest-plugin': + specifier: 3.1.1 + version: 3.1.1(vite@6.0.1(@types/node@18.19.50)(jiti@1.21.6)(sass@1.81.0)(yaml@2.5.1))(vitest@2.1.8(@types/node@18.19.50)(jsdom@23.2.0)(sass@1.81.0)) + vitest: + specifier: 2.1.8 + version: 2.1.8(@types/node@18.19.50)(jsdom@23.2.0)(sass@1.81.0) benchmark/packages/adapter: dependencies: @@ -142,7 +142,7 @@ importers: examples/basics: dependencies: astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/blog: @@ -157,13 +157,13 @@ importers: specifier: ^3.2.1 version: link:../../packages/integrations/sitemap astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/component: devDependencies: astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/container-with-vitest: @@ -172,7 +172,7 @@ importers: specifier: ^4.0.0 version: link:../../packages/integrations/react astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro react: specifier: ^18.3.1 @@ -203,7 +203,7 @@ importers: specifier: ^3.14.3 version: 3.14.3 astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/framework-multiple: @@ -230,7 +230,7 @@ importers: specifier: ^18.3.1 version: 18.3.1 astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro preact: specifier: ^10.24.3 @@ -260,7 +260,7 @@ importers: specifier: ^1.3.0 version: 1.3.0(preact@10.24.3) astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro preact: specifier: ^10.24.3 @@ -278,7 +278,7 @@ importers: specifier: ^18.3.1 version: 18.3.1 astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro react: specifier: ^18.3.1 @@ -293,7 +293,7 @@ importers: specifier: ^5.0.0 version: link:../../packages/integrations/solid astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro solid-js: specifier: ^1.9.3 @@ -305,7 +305,7 @@ importers: specifier: ^7.0.1 version: link:../../packages/integrations/svelte astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro svelte: specifier: ^5.1.16 @@ -317,7 +317,7 @@ importers: specifier: ^5.0.1 version: link:../../packages/integrations/vue astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro vue: specifier: ^3.5.12 @@ -326,40 +326,40 @@ importers: examples/hackernews: dependencies: '@astrojs/node': - specifier: ^9.0.0-alpha.1 - version: 9.0.0-alpha.1(astro@packages+astro) + specifier: ^9.0.0 + version: 9.0.0(astro@packages+astro) astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/integration: devDependencies: astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/minimal: dependencies: astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/portfolio: dependencies: astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/ssr: dependencies: '@astrojs/node': - specifier: ^9.0.0-alpha.1 - version: 9.0.0-alpha.1(astro@packages+astro) + specifier: ^9.0.0 + version: 9.0.0(astro@packages+astro) '@astrojs/svelte': specifier: ^7.0.1 version: link:../../packages/integrations/svelte astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro svelte: specifier: ^5.1.16 @@ -368,7 +368,7 @@ importers: examples/starlog: dependencies: astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro sass: specifier: ^1.80.6 @@ -380,7 +380,7 @@ importers: examples/toolbar-app: devDependencies: astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/with-markdoc: @@ -389,7 +389,7 @@ importers: specifier: ^0.12.1 version: link:../../packages/integrations/markdoc astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro examples/with-mdx: @@ -401,7 +401,7 @@ importers: specifier: ^4.0.0 version: link:../../packages/integrations/preact astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro preact: specifier: ^10.24.3 @@ -416,7 +416,7 @@ importers: specifier: ^0.5.2 version: 0.5.2(nanostores@0.11.3)(preact@10.24.3) astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro nanostores: specifier: ^0.11.3 @@ -437,7 +437,7 @@ importers: specifier: ^1.6.4 version: 1.6.4 astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro autoprefixer: specifier: ^10.4.20 @@ -455,7 +455,7 @@ importers: examples/with-vitest: dependencies: astro: - specifier: ^5.0.1 + specifier: ^5.0.2 version: link:../../packages/astro vitest: specifier: ^2.1.6 @@ -2942,6 +2942,12 @@ importers: specifier: workspace:* version: link:../../.. + packages/astro/test/fixtures/custom-renderer: + dependencies: + astro: + specifier: workspace:* + version: link:../../.. + packages/astro/test/fixtures/data-collections: dependencies: astro: @@ -5630,11 +5636,6 @@ packages: peerDependencies: astro: ^5.0.0 - '@astrojs/node@9.0.0-alpha.1': - resolution: {integrity: sha512-5KsaJYuAnKP4tmT/skEWLs4UP6FQhtwIVa26MBU5imiS/aL33cIwmZ7Gl2W0rP/t4Wnz9ehf42lXWXLPekhETw==} - peerDependencies: - astro: ^5.0.0-alpha.0 - '@astrojs/yaml2ts@0.2.1': resolution: {integrity: sha512-CBaNwDQJz20E5WxzQh4thLVfhB3JEEGz72wRA+oJp6fQR37QLAqXZJU0mHC+yqMOQ6oj0GfRPJrz6hjf+zm6zA==} @@ -5940,10 +5941,11 @@ packages: '@codspeed/core@3.1.1': resolution: {integrity: sha512-ONhERVDAtkm0nc+FYPivDozoMOlNUP2BWRBFDJYATGA18Iap5Kd2mZ1/Lwz54RB5+g+3YDOpsvotHa4hd3Q+7Q==} - '@codspeed/tinybench-plugin@3.1.1': - resolution: {integrity: sha512-LVF4End0kDU9V7CzuwAcmngSPJNnpduPnr+csOKvcG++FsYwfUuBJ1rvLPtv6yTkvxpUmUEsj6VA7/AEIBGZVw==} + '@codspeed/vitest-plugin@3.1.1': + resolution: {integrity: sha512-/PJUgxIfuRqpBSbaD8bgWXtbXxCqgnW89dzr3220fMkx/LA6z6oUb4tJGjeVsOWAzAgu0VBdSA+8hC+7D9BIuQ==} peerDependencies: - tinybench: ^2.3.0 + vite: ^4.2.0 || ^5.0.0 + vitest: '>=1.2.2' '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} @@ -7333,6 +7335,9 @@ packages: '@vitest/expect@2.1.6': resolution: {integrity: sha512-9M1UR9CAmrhJOMoSwVnPh2rELPKhYo0m/CSgqw9PyStpxtkwhmdM6XYlXGKeYyERY1N6EIuzkQ7e3Lm1WKCoUg==} + '@vitest/expect@2.1.8': + resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} + '@vitest/mocker@2.1.6': resolution: {integrity: sha512-MHZp2Z+Q/A3am5oD4WSH04f9B0T7UvwEb+v5W0kCYMhtXGYbdyl2NUk1wdSMqGthmhpiThPDp/hEoVwu16+u1A==} peerDependencies: @@ -7344,21 +7349,47 @@ packages: vite: optional: true + '@vitest/mocker@2.1.8': + resolution: {integrity: sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + '@vitest/pretty-format@2.1.6': resolution: {integrity: sha512-exZyLcEnHgDMKc54TtHca4McV4sKT+NKAe9ix/yhd/qkYb/TP8HTyXRFDijV19qKqTZM0hPL4753zU/U8L/gAA==} + '@vitest/pretty-format@2.1.8': + resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} + '@vitest/runner@2.1.6': resolution: {integrity: sha512-SjkRGSFyrA82m5nz7To4CkRSEVWn/rwQISHoia/DB8c6IHIhaE/UNAo+7UfeaeJRE979XceGl00LNkIz09RFsA==} + '@vitest/runner@2.1.8': + resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==} + '@vitest/snapshot@2.1.6': resolution: {integrity: sha512-5JTWHw8iS9l3v4/VSuthCndw1lN/hpPB+mlgn1BUhFbobeIUj1J1V/Bj2t2ovGEmkXLTckFjQddsxS5T6LuVWw==} + '@vitest/snapshot@2.1.8': + resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==} + '@vitest/spy@2.1.6': resolution: {integrity: sha512-oTFObV8bd4SDdRka5O+mSh5w9irgx5IetrD5i+OsUUsk/shsBoHifwCzy45SAORzAhtNiprUVaK3hSCCzZh1jQ==} + '@vitest/spy@2.1.8': + resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==} + '@vitest/utils@2.1.6': resolution: {integrity: sha512-ixNkFy3k4vokOUTU2blIUvOgKq/N2PW8vKIjZZYsGJCMX69MRa9J2sKqX5hY/k5O5Gty3YJChepkqZ3KM9LyIQ==} + '@vitest/utils@2.1.8': + resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} + '@volar/kit@2.4.6': resolution: {integrity: sha512-OaMtpmLns6IYD1nOSd0NdG/F5KzJ7Jr4B7TLeb4byPzu+ExuuRVeO56Dn1C7Frnw6bGudUQd90cpQAmxdB+RlQ==} peerDependencies: @@ -10212,10 +10243,6 @@ packages: engines: {node: '>=10'} hasBin: true - send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} - send@0.19.0: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} @@ -10786,6 +10813,11 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true + vite-node@2.1.8: + resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite-plugin-inspect@0.8.7: resolution: {integrity: sha512-/XXou3MVc13A5O9/2Nd6xczjrUwt7ZyI9h8pTnUMkr5SshLcb0PJUOVq2V+XVkdeU4njsqAtmK87THZuO2coGA==} engines: {node: '>=14'} @@ -10822,6 +10854,37 @@ packages: peerDependencies: vue: '>=3.2.13' + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vite@6.0.1: resolution: {integrity: sha512-Ldn6gorLGr4mCdFnmeAOLweJxZ34HjKnDm4HGo6P66IEqTxQb36VEdFJQENKxWjupNfoIjvRUnswjn1hpYEpjQ==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -10895,6 +10958,31 @@ packages: jsdom: optional: true + vitest@2.1.8: + resolution: {integrity: sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.8 + '@vitest/ui': 2.1.8 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + volar-service-css@0.0.61: resolution: {integrity: sha512-Ct9L/w+IB1JU8F4jofcNCGoHy6TF83aiapfZq9A0qYYpq+Kk5dH+ONS+rVZSsuhsunq8UvAuF8Gk6B8IFLfniw==} peerDependencies: @@ -11326,14 +11414,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/node@9.0.0-alpha.1(astro@packages+astro)': - dependencies: - astro: link:packages/astro - send: 0.18.0 - server-destroy: 1.0.1 - transitivePeerDependencies: - - supports-color - '@astrojs/yaml2ts@0.2.1': dependencies: yaml: 2.5.1 @@ -11781,11 +11861,11 @@ snapshots: transitivePeerDependencies: - debug - '@codspeed/tinybench-plugin@3.1.1(tinybench@2.9.0)': + '@codspeed/vitest-plugin@3.1.1(vite@6.0.1(@types/node@18.19.50)(jiti@1.21.6)(sass@1.81.0)(yaml@2.5.1))(vitest@2.1.8(@types/node@18.19.50)(jsdom@23.2.0)(sass@1.81.0))': dependencies: '@codspeed/core': 3.1.1 - stack-trace: 1.0.0-pre2 - tinybench: 2.9.0 + vite: 6.0.1(@types/node@18.19.50)(jiti@1.21.6)(sass@1.81.0)(yaml@2.5.1) + vitest: 2.1.8(@types/node@18.19.50)(jsdom@23.2.0)(sass@1.81.0) transitivePeerDependencies: - debug @@ -13046,6 +13126,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 + '@vitest/expect@2.1.8': + dependencies: + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + tinyrainbow: 1.2.0 + '@vitest/mocker@2.1.6(vite@6.0.1(@types/node@18.19.50)(jiti@1.21.6)(sass@1.81.0)(yaml@2.5.1))': dependencies: '@vitest/spy': 2.1.6 @@ -13054,31 +13141,64 @@ snapshots: optionalDependencies: vite: 6.0.1(@types/node@18.19.50)(jiti@1.21.6)(sass@1.81.0)(yaml@2.5.1) + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@18.19.50)(sass@1.81.0))': + dependencies: + '@vitest/spy': 2.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.14 + optionalDependencies: + vite: 5.4.11(@types/node@18.19.50)(sass@1.81.0) + '@vitest/pretty-format@2.1.6': dependencies: tinyrainbow: 1.2.0 + '@vitest/pretty-format@2.1.8': + dependencies: + tinyrainbow: 1.2.0 + '@vitest/runner@2.1.6': dependencies: '@vitest/utils': 2.1.6 pathe: 1.1.2 + '@vitest/runner@2.1.8': + dependencies: + '@vitest/utils': 2.1.8 + pathe: 1.1.2 + '@vitest/snapshot@2.1.6': dependencies: '@vitest/pretty-format': 2.1.6 magic-string: 0.30.14 pathe: 1.1.2 + '@vitest/snapshot@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + magic-string: 0.30.14 + pathe: 1.1.2 + '@vitest/spy@2.1.6': dependencies: tinyspy: 3.0.2 + '@vitest/spy@2.1.8': + dependencies: + tinyspy: 3.0.2 + '@vitest/utils@2.1.6': dependencies: '@vitest/pretty-format': 2.1.6 loupe: 3.1.2 tinyrainbow: 1.2.0 + '@vitest/utils@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + '@volar/kit@2.4.6(typescript@5.7.2)': dependencies: '@volar/language-service': 2.4.6 @@ -16492,24 +16612,6 @@ snapshots: semver@7.6.3: {} - send@0.18.0: - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - send@0.19.0: dependencies: debug: 2.6.9 @@ -17213,6 +17315,24 @@ snapshots: - tsx - yaml + vite-node@2.1.8(@types/node@18.19.50)(sass@1.81.0): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + es-module-lexer: 1.5.4 + pathe: 1.1.2 + vite: 5.4.11(@types/node@18.19.50)(sass@1.81.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-plugin-inspect@0.8.7(rollup@4.27.4)(vite@6.0.1(@types/node@18.19.50)(jiti@1.21.6)(sass@1.81.0)(yaml@2.5.1)): dependencies: '@antfu/utils': 0.7.10 @@ -17278,6 +17398,16 @@ snapshots: svgo: 3.3.2 vue: 3.5.13(typescript@5.7.2) + vite@5.4.11(@types/node@18.19.50)(sass@1.81.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.27.4 + optionalDependencies: + '@types/node': 18.19.50 + fsevents: 2.3.3 + sass: 1.81.0 + vite@6.0.1(@types/node@18.19.50)(jiti@1.21.6)(sass@1.81.0)(yaml@2.5.1): dependencies: esbuild: 0.24.0 @@ -17333,6 +17463,42 @@ snapshots: - tsx - yaml + vitest@2.1.8(@types/node@18.19.50)(jsdom@23.2.0)(sass@1.81.0): + dependencies: + '@vitest/expect': 2.1.8 + '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@18.19.50)(sass@1.81.0)) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.8 + '@vitest/snapshot': 2.1.8 + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + debug: 4.3.7 + expect-type: 1.1.0 + magic-string: 0.30.14 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.4.11(@types/node@18.19.50)(sass@1.81.0) + vite-node: 2.1.8(@types/node@18.19.50)(sass@1.81.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 18.19.50 + jsdom: 23.2.0 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + volar-service-css@0.0.61(@volar/language-service@2.4.6): dependencies: vscode-css-languageservice: 6.3.1